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::{
self, compile_time_machine, AllocId, Allocation, Frame, ImmTy, InterpCx, InterpResult, Memory,
OpTy, PlaceTy, Pointer, Scalar,
OpTy, PlaceTy, Pointer, Scalar, StackPopUnwind,
};
use super::error::*;
@ -223,7 +223,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
_abi: Abi,
args: &[OpTy<'tcx>],
_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>>> {
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>,
args: &[OpTy<'tcx>],
ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>,
_unwind: StackPopUnwind,
) -> InterpResult<'tcx> {
// Shared intrinsics.
if ecx.emulate_intrinsic(instance, args, ret)? {

View file

@ -14,7 +14,7 @@ use rustc_target::spec::abi::Abi;
use super::{
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,
@ -163,7 +163,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
abi: Abi,
args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
unwind: StackPopUnwind,
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>;
/// 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,
args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
unwind: StackPopUnwind,
) -> InterpResult<'tcx>;
/// 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>,
args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
unwind: StackPopUnwind,
) -> InterpResult<'tcx>;
/// 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,
_args: &[OpTy<$tcx>],
_ret: Option<(&PlaceTy<$tcx>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>,
_unwind: StackPopUnwind,
) -> InterpResult<$tcx> {
match fn_val {}
}

View file

@ -105,7 +105,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
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
// did a jump to another block.
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,
args: &[OpTy<'tcx, M::PointerTag>],
ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
can_unwind: bool,
mut unwind: StackPopUnwind,
) -> InterpResult<'tcx> {
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)?;
}
let can_unwind = can_unwind
if !matches!(unwind, StackPopUnwind::NotAllowed)
&& 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(
instance,
body,
ret.map(|p| p.0),
StackPopCleanup::Goto {
ret: ret.map(|p| p.1),
unwind: match (unwind, can_unwind) {
(Some(unwind), true) => StackPopUnwind::Cleanup(unwind),
(None, true) => StackPopUnwind::Skip,
(_, false) => StackPopUnwind::NotAllowed,
},
},
StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind },
)?;
// 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));
trace!("Patched self operand to {:#?}", args[0]);
// 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,
&[arg.into()],
Some((&dest.into(), target)),
unwind,
true,
unwind.map_or(StackPopUnwind::Skip, StackPopUnwind::Cleanup),
)
}
}

View file

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