unify call_intrinsic handling of intruction pointer with other machine hooks

This commit is contained in:
Ralf Jung 2019-11-25 16:23:44 +01:00
parent 7bfed2e32a
commit 5900b32cee
2 changed files with 5 additions and 23 deletions

View file

@ -141,7 +141,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// Returns either the mir to use for the call, or `None` if execution should
/// just proceed (which usually means this hook did all the work that the
/// called function should usually have done). In the latter case, it is
/// this hook's responsibility to call `goto_block(ret)` to advance the instruction pointer!
/// this hook's responsibility to advance the instruction pointer!
/// (This is to support functions like `__rust_maybe_catch_panic` that neither find a MIR
/// nor just jump to `ret`, but instead push their own stack frame.)
/// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them
@ -155,7 +155,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
unwind: Option<mir::BasicBlock>
) -> 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
/// pointer as appropriate.
fn call_extra_fn(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
@ -165,8 +165,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx>;
/// Directly process an intrinsic without pushing a stack frame.
/// If this returns successfully, the engine will take care of jumping to the next block.
/// Directly process an intrinsic without pushing a stack frame. It is the hook's
/// responsibility to advance the instruction pointer as appropriate.
fn call_intrinsic(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
span: Span,

View file

@ -254,25 +254,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match instance.def {
ty::InstanceDef::Intrinsic(..) => {
assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
let old_stack = self.cur_frame();
let old_bb = self.frame().block;
M::call_intrinsic(self, span, instance, args, dest, ret, unwind)?;
// No stack frame gets pushed, the main loop will just act as if the
// call completed.
if ret.is_some() {
self.return_to_block(ret)?;
} else {
// If this intrinsic call doesn't have a ret block,
// then the intrinsic implementation should have
// changed the stack frame (otherwise, we'll end
// up trying to execute this intrinsic call again)
debug_assert!(self.cur_frame() != old_stack || self.frame().block != old_bb);
}
if let Some(dest) = dest {
self.dump_place(*dest)
}
Ok(())
return M::call_intrinsic(self, span, instance, args, dest, ret, unwind);
}
ty::InstanceDef::VtableShim(..) |
ty::InstanceDef::ReifyShim(..) |