Pass StackPopUnwind to eval_fn_call() and some other functions that are called by eval_fn_call()

This commit is contained in:
hyd-dev 2021-05-23 04:37:17 +08:00
parent 876fdcb9ec
commit 8ef3974007
No known key found for this signature in database
GPG key ID: 74FA7FD5B8DA14B8
4 changed files with 31 additions and 26 deletions

View file

@ -17,7 +17,7 @@ use rustc_target::spec::abi::Abi;
use crate::interpret::{ use crate::interpret::{
self, compile_time_machine, AllocId, Allocation, Frame, ImmTy, InterpCx, InterpResult, Memory, self, compile_time_machine, AllocId, Allocation, Frame, ImmTy, InterpCx, InterpResult, Memory,
OpTy, PlaceTy, Pointer, Scalar, OpTy, PlaceTy, Pointer, Scalar, StackPopUnwind,
}; };
use super::error::*; use super::error::*;
@ -223,7 +223,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
_abi: Abi, _abi: Abi,
args: &[OpTy<'tcx>], args: &[OpTy<'tcx>],
_ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>, _ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>, // unwinding is not supported in consts _unwind: StackPopUnwind, // unwinding is not supported in consts
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> { ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
debug!("find_mir_or_eval_fn: {:?}", instance); debug!("find_mir_or_eval_fn: {:?}", instance);
@ -263,7 +263,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
instance: ty::Instance<'tcx>, instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx>], args: &[OpTy<'tcx>],
ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>, ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>, _unwind: StackPopUnwind,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// Shared intrinsics. // Shared intrinsics.
if ecx.emulate_intrinsic(instance, args, ret)? { if ecx.emulate_intrinsic(instance, args, ret)? {

View file

@ -14,7 +14,7 @@ use rustc_target::spec::abi::Abi;
use super::{ use super::{
AllocId, Allocation, CheckInAllocMsg, Frame, ImmTy, InterpCx, InterpResult, LocalValue, AllocId, Allocation, CheckInAllocMsg, Frame, ImmTy, InterpCx, InterpResult, LocalValue,
MemPlace, Memory, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Scalar, MemPlace, Memory, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Scalar, StackPopUnwind,
}; };
/// Data returned by Machine::stack_pop, /// Data returned by Machine::stack_pop,
@ -163,7 +163,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
abi: Abi, abi: Abi,
args: &[OpTy<'tcx, Self::PointerTag>], args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>, unwind: StackPopUnwind,
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>; ) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>;
/// Execute `fn_val`. It is the hook's responsibility to advance the instruction /// Execute `fn_val`. It is the hook's responsibility to advance the instruction
@ -174,7 +174,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
abi: Abi, abi: Abi,
args: &[OpTy<'tcx, Self::PointerTag>], args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>, unwind: StackPopUnwind,
) -> InterpResult<'tcx>; ) -> InterpResult<'tcx>;
/// Directly process an intrinsic without pushing a stack frame. It is the hook's /// Directly process an intrinsic without pushing a stack frame. It is the hook's
@ -184,7 +184,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
instance: ty::Instance<'tcx>, instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Self::PointerTag>], args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>, ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>, unwind: StackPopUnwind,
) -> InterpResult<'tcx>; ) -> InterpResult<'tcx>;
/// Called to evaluate `Assert` MIR terminators that trigger a panic. /// Called to evaluate `Assert` MIR terminators that trigger a panic.
@ -456,7 +456,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
_abi: Abi, _abi: Abi,
_args: &[OpTy<$tcx>], _args: &[OpTy<$tcx>],
_ret: Option<(&PlaceTy<$tcx>, mir::BasicBlock)>, _ret: Option<(&PlaceTy<$tcx>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>, _unwind: StackPopUnwind,
) -> InterpResult<$tcx> { ) -> InterpResult<$tcx> {
match fn_val {} match fn_val {}
} }

View file

@ -105,7 +105,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
None => None, None => None,
}; };
self.eval_fn_call(fn_val, abi, &args[..], ret, *cleanup, can_unwind)?; self.eval_fn_call(
fn_val,
abi,
&args[..],
ret,
if can_unwind {
cleanup.map_or(StackPopUnwind::Skip, StackPopUnwind::Cleanup)
} else {
StackPopUnwind::NotAllowed
},
)?;
// Sanity-check that `eval_fn_call` either pushed a new frame or // Sanity-check that `eval_fn_call` either pushed a new frame or
// did a jump to another block. // did a jump to another block.
if self.frame_idx() == old_stack && self.frame().loc == old_loc { if self.frame_idx() == old_stack && self.frame().loc == old_loc {
@ -235,8 +245,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
caller_abi: Abi, caller_abi: Abi,
args: &[OpTy<'tcx, M::PointerTag>], args: &[OpTy<'tcx, M::PointerTag>],
ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>, ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>, mut unwind: StackPopUnwind,
can_unwind: bool,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
trace!("eval_fn_call: {:#?}", fn_val); trace!("eval_fn_call: {:#?}", fn_val);
@ -306,22 +315,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
check_abi(callee_abi)?; check_abi(callee_abi)?;
} }
let can_unwind = can_unwind if !matches!(unwind, StackPopUnwind::NotAllowed)
&& self && self
.fn_can_unwind(self.tcx.codegen_fn_attrs(callee_def_id).flags, callee_abi); .fn_can_unwind(self.tcx.codegen_fn_attrs(callee_def_id).flags, callee_abi)
{
unwind = StackPopUnwind::NotAllowed;
}
self.push_stack_frame( self.push_stack_frame(
instance, instance,
body, body,
ret.map(|p| p.0), ret.map(|p| p.0),
StackPopCleanup::Goto { StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind },
ret: ret.map(|p| p.1),
unwind: match (unwind, can_unwind) {
(Some(unwind), true) => StackPopUnwind::Cleanup(unwind),
(None, true) => StackPopUnwind::Skip,
(_, false) => StackPopUnwind::NotAllowed,
},
},
)?; )?;
// If an error is raised here, pop the frame again to get an accurate backtrace. // If an error is raised here, pop the frame again to get an accurate backtrace.
@ -466,7 +471,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
OpTy::from(ImmTy::from_immediate(receiver_place.ptr.into(), this_receiver_ptr)); OpTy::from(ImmTy::from_immediate(receiver_place.ptr.into(), this_receiver_ptr));
trace!("Patched self operand to {:#?}", args[0]); trace!("Patched self operand to {:#?}", args[0]);
// recurse with concrete function // recurse with concrete function
self.eval_fn_call(drop_fn, caller_abi, &args, ret, unwind, can_unwind) self.eval_fn_call(drop_fn, caller_abi, &args, ret, unwind)
} }
} }
} }
@ -505,8 +510,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Abi::Rust, Abi::Rust,
&[arg.into()], &[arg.into()],
Some((&dest.into(), target)), Some((&dest.into(), target)),
unwind, unwind.map_or(StackPopUnwind::Skip, StackPopUnwind::Cleanup),
true,
) )
} }
} }

View file

@ -33,6 +33,7 @@ use crate::interpret::{
self, compile_time_machine, AllocId, Allocation, ConstValue, CtfeValidationMode, Frame, ImmTy, self, compile_time_machine, AllocId, Allocation, ConstValue, CtfeValidationMode, Frame, ImmTy,
Immediate, InterpCx, InterpResult, LocalState, LocalValue, MemPlace, Memory, MemoryKind, OpTy, Immediate, InterpCx, InterpResult, LocalState, LocalValue, MemPlace, Memory, MemoryKind, OpTy,
Operand as InterpOperand, PlaceTy, Pointer, Scalar, ScalarMaybeUninit, StackPopCleanup, Operand as InterpOperand, PlaceTy, Pointer, Scalar, ScalarMaybeUninit, StackPopCleanup,
StackPopUnwind,
}; };
use crate::transform::MirPass; use crate::transform::MirPass;
@ -198,7 +199,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
_abi: Abi, _abi: Abi,
_args: &[OpTy<'tcx>], _args: &[OpTy<'tcx>],
_ret: Option<(&PlaceTy<'tcx>, BasicBlock)>, _ret: Option<(&PlaceTy<'tcx>, BasicBlock)>,
_unwind: Option<BasicBlock>, _unwind: StackPopUnwind,
) -> InterpResult<'tcx, Option<&'mir Body<'tcx>>> { ) -> InterpResult<'tcx, Option<&'mir Body<'tcx>>> {
Ok(None) Ok(None)
} }
@ -208,7 +209,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
_instance: ty::Instance<'tcx>, _instance: ty::Instance<'tcx>,
_args: &[OpTy<'tcx>], _args: &[OpTy<'tcx>],
_ret: Option<(&PlaceTy<'tcx>, BasicBlock)>, _ret: Option<(&PlaceTy<'tcx>, BasicBlock)>,
_unwind: Option<BasicBlock>, _unwind: StackPopUnwind,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
throw_machine_stop_str!("calling intrinsics isn't supported in ConstProp") throw_machine_stop_str!("calling intrinsics isn't supported in ConstProp")
} }