1
Fork 0

adjust Miri to needs of changed unwinding strategy

This commit is contained in:
Ralf Jung 2020-03-14 11:51:27 +01:00
parent 4452843720
commit b5938adb4d
3 changed files with 19 additions and 26 deletions

View file

@ -21,7 +21,7 @@ use rustc_span::source_map::{self, Span, DUMMY_SP};
use super::{ use super::{
Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy, Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy,
ScalarMaybeUndef, StackPopInfo, ScalarMaybeUndef, StackPopJump,
}; };
pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
@ -623,23 +623,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
::log_settings::settings().indentation -= 1; ::log_settings::settings().indentation -= 1;
let frame = self.stack.pop().expect("tried to pop a stack frame, but there were none"); let frame = self.stack.pop().expect("tried to pop a stack frame, but there were none");
let stack_pop_info = M::stack_pop(self, frame.extra, unwinding)?;
if let (false, StackPopInfo::StopUnwinding) = (unwinding, stack_pop_info) {
bug!("Attempted to stop unwinding while there is no unwinding!");
}
// Now where do we jump next? // Now where do we jump next?
// Determine if we leave this function normally or via unwinding.
let cur_unwinding =
if let StackPopInfo::StopUnwinding = stack_pop_info { false } else { unwinding };
// Usually we want to clean up (deallocate locals), but in a few rare cases we don't. // Usually we want to clean up (deallocate locals), but in a few rare cases we don't.
// In that case, we return early. We also avoid validation in that case, // In that case, we return early. We also avoid validation in that case,
// because this is CTFE and the final value will be thoroughly validated anyway. // because this is CTFE and the final value will be thoroughly validated anyway.
let (cleanup, next_block) = match frame.return_to_block { let (cleanup, next_block) = match frame.return_to_block {
StackPopCleanup::Goto { ret, unwind } => { StackPopCleanup::Goto { ret, unwind } => {
(true, Some(if cur_unwinding { unwind } else { ret })) (true, Some(if unwinding { unwind } else { ret }))
} }
StackPopCleanup::None { cleanup, .. } => (cleanup, None), StackPopCleanup::None { cleanup, .. } => (cleanup, None),
}; };
@ -647,7 +639,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
if !cleanup { if !cleanup {
assert!(self.stack.is_empty(), "only the topmost frame should ever be leaked"); assert!(self.stack.is_empty(), "only the topmost frame should ever be leaked");
assert!(next_block.is_none(), "tried to skip cleanup when we have a next block!"); assert!(next_block.is_none(), "tried to skip cleanup when we have a next block!");
// Leak the locals, skip validation. assert!(!unwinding, "tried to skip cleanup during unwinding");
// Leak the locals, skip validation, skip machine hook.
return Ok(()); return Ok(());
} }
@ -656,13 +649,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.deallocate_local(local.value)?; self.deallocate_local(local.value)?;
} }
trace!( if M::stack_pop(self, frame.extra, unwinding)? == StackPopJump::NoJump {
"StackPopCleanup: {:?} StackPopInfo: {:?} cur_unwinding = {:?}", // The hook already did everything.
frame.return_to_block, // We want to skip the `trace!` below, hence early return.
stack_pop_info, return Ok(());
cur_unwinding }
); // Normal return.
if cur_unwinding { if unwinding {
// Follow the unwind edge. // Follow the unwind edge.
let unwind = next_block.expect("Encountered StackPopCleanup::None when unwinding!"); let unwind = next_block.expect("Encountered StackPopCleanup::None when unwinding!");
self.unwind_to_block(unwind); self.unwind_to_block(unwind);
@ -697,7 +690,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
"CONTINUING({}) {} (unwinding = {})", "CONTINUING({}) {} (unwinding = {})",
self.cur_frame(), self.cur_frame(),
self.frame().instance, self.frame().instance,
cur_unwinding unwinding
); );
} }

View file

@ -17,16 +17,16 @@ use super::{
/// Data returned by Machine::stack_pop, /// Data returned by Machine::stack_pop,
/// to provide further control over the popping of the stack frame /// to provide further control over the popping of the stack frame
#[derive(Eq, PartialEq, Debug, Copy, Clone)] #[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum StackPopInfo { pub enum StackPopJump {
/// Indicates that no special handling should be /// Indicates that no special handling should be
/// done - we'll either return normally or unwind /// done - we'll either return normally or unwind
/// based on the terminator for the function /// based on the terminator for the function
/// we're leaving. /// we're leaving.
Normal, Normal,
/// Indicates that we should stop unwinding, /// Indicates that we should *not* jump to the return/unwind address, as the callback already
/// as we've reached a catch frame /// took care of everything.
StopUnwinding, NoJump,
} }
/// Whether this kind of memory is allowed to leak /// Whether this kind of memory is allowed to leak
@ -276,9 +276,9 @@ pub trait Machine<'mir, 'tcx>: Sized {
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'mir, 'tcx, Self>,
_extra: Self::FrameExtra, _extra: Self::FrameExtra,
_unwinding: bool, _unwinding: bool,
) -> InterpResult<'tcx, StackPopInfo> { ) -> InterpResult<'tcx, StackPopJump> {
// By default, we do not support unwinding from panics // By default, we do not support unwinding from panics
Ok(StackPopInfo::Normal) Ok(StackPopJump::Normal)
} }
fn int_to_ptr( fn int_to_ptr(

View file

@ -24,7 +24,7 @@ pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind}; pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind};
pub use self::machine::{AllocMap, Machine, MayLeak, StackPopInfo}; pub use self::machine::{AllocMap, Machine, MayLeak, StackPopJump};
pub use self::operand::{ImmTy, Immediate, OpTy, Operand, ScalarMaybeUndef}; pub use self::operand::{ImmTy, Immediate, OpTy, Operand, ScalarMaybeUndef};