]> git.lizzy.rs Git - rust.git/commitdiff
adjust Miri to needs of changed unwinding strategy
authorRalf Jung <post@ralfj.de>
Sat, 14 Mar 2020 10:51:27 +0000 (11:51 +0100)
committerRalf Jung <post@ralfj.de>
Sat, 14 Mar 2020 10:51:27 +0000 (11:51 +0100)
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/machine.rs
src/librustc_mir/interpret/mod.rs

index 9b28b7a20c044ef3779e561566cb22b6e52ff866..0d43e4759f795855e53e2aa518de49687cec782e 100644 (file)
@@ -21,7 +21,7 @@
 
 use super::{
     Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy,
-    ScalarMaybeUndef, StackPopInfo,
+    ScalarMaybeUndef, StackPopJump,
 };
 
 pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
@@ -623,23 +623,15 @@ pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx>
 
         ::log_settings::settings().indentation -= 1;
         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?
 
-        // 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.
         // 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.
         let (cleanup, next_block) = match frame.return_to_block {
             StackPopCleanup::Goto { ret, unwind } => {
-                (true, Some(if cur_unwinding { unwind } else { ret }))
+                (true, Some(if unwinding { unwind } else { ret }))
             }
             StackPopCleanup::None { cleanup, .. } => (cleanup, None),
         };
@@ -647,7 +639,8 @@ pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx>
         if !cleanup {
             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!");
-            // Leak the locals, skip validation.
+            assert!(!unwinding, "tried to skip cleanup during unwinding");
+            // Leak the locals, skip validation, skip machine hook.
             return Ok(());
         }
 
@@ -656,13 +649,13 @@ pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx>
             self.deallocate_local(local.value)?;
         }
 
-        trace!(
-            "StackPopCleanup: {:?} StackPopInfo: {:?} cur_unwinding = {:?}",
-            frame.return_to_block,
-            stack_pop_info,
-            cur_unwinding
-        );
-        if cur_unwinding {
+        if M::stack_pop(self, frame.extra, unwinding)? == StackPopJump::NoJump {
+            // The hook already did everything.
+            // We want to skip the `trace!` below, hence early return.
+            return Ok(());
+        }
+        // Normal return.
+        if unwinding {
             // Follow the unwind edge.
             let unwind = next_block.expect("Encountered StackPopCleanup::None when unwinding!");
             self.unwind_to_block(unwind);
@@ -697,7 +690,7 @@ pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx>
                 "CONTINUING({}) {} (unwinding = {})",
                 self.cur_frame(),
                 self.frame().instance,
-                cur_unwinding
+                unwinding
             );
         }
 
index 366de6e55612a5f2d2c9db85e0e85466a35c0961..0e70e54ad85af12b6e7dbe496c17a807fc897a8d 100644 (file)
 /// Data returned by Machine::stack_pop,
 /// to provide further control over the popping of the stack frame
 #[derive(Eq, PartialEq, Debug, Copy, Clone)]
-pub enum StackPopInfo {
+pub enum StackPopJump {
     /// Indicates that no special handling should be
     /// done - we'll either return normally or unwind
     /// based on the terminator for the function
     /// we're leaving.
     Normal,
 
-    /// Indicates that we should stop unwinding,
-    /// as we've reached a catch frame
-    StopUnwinding,
+    /// Indicates that we should *not* jump to the return/unwind address, as the callback already
+    /// took care of everything.
+    NoJump,
 }
 
 /// Whether this kind of memory is allowed to leak
@@ -276,9 +276,9 @@ fn stack_pop(
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
         _extra: Self::FrameExtra,
         _unwinding: bool,
-    ) -> InterpResult<'tcx, StackPopInfo> {
+    ) -> InterpResult<'tcx, StackPopJump> {
         // By default, we do not support unwinding from panics
-        Ok(StackPopInfo::Normal)
+        Ok(StackPopJump::Normal)
     }
 
     fn int_to_ptr(
index a519f38e712087dc9215a0aa79a71a77c9dc09f6..c3fd968276577241207408783545216fca5fe308 100644 (file)
@@ -24,7 +24,7 @@
 
 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};