adjust Miri to needs of changed unwinding strategy
This commit is contained in:
parent
4452843720
commit
b5938adb4d
3 changed files with 19 additions and 26 deletions
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue