Pass StackPopUnwind
to eval_fn_call()
and some other functions that are called by eval_fn_call()
This commit is contained in:
parent
876fdcb9ec
commit
8ef3974007
4 changed files with 31 additions and 26 deletions
|
@ -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)? {
|
||||||
|
|
|
@ -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 {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue