]> git.lizzy.rs Git - rust.git/commitdiff
get rid of FinishStatic hack from stack clenaup; const_eval can do that itself
authorRalf Jung <post@ralfj.de>
Fri, 24 Aug 2018 15:36:18 +0000 (17:36 +0200)
committerRalf Jung <post@ralfj.de>
Mon, 27 Aug 2018 16:12:49 +0000 (18:12 +0200)
src/librustc_mir/const_eval.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/interpret/traits.rs

index 7c1ce21d8f5a62d89a590d5c6ab0a72d7d30a0b8..3f0ab3b8f7cf2dff305b603fdf7b9f2312e0398c 100644 (file)
@@ -157,14 +157,6 @@ fn eval_body_using_ecx<'a, 'mir, 'tcx>(
     let layout = ecx.layout_of(mir.return_ty().subst(tcx, cid.instance.substs))?;
     assert!(!layout.is_unsized());
     let ret = ecx.allocate(layout, MemoryKind::Stack)?;
-    let internally_mutable = !layout.ty.is_freeze(tcx, param_env, mir.span);
-    let is_static = tcx.is_static(cid.instance.def_id());
-    let mutability = if is_static == Some(hir::Mutability::MutMutable) || internally_mutable {
-        Mutability::Mutable
-    } else {
-        Mutability::Immutable
-    };
-    let cleanup = StackPopCleanup::FinishStatic(mutability);
 
     let name = ty::tls::with(|tcx| tcx.item_path_str(cid.instance.def_id()));
     let prom = cid.promoted.map_or(String::new(), |p| format!("::promoted[{:?}]", p));
@@ -175,12 +167,22 @@ fn eval_body_using_ecx<'a, 'mir, 'tcx>(
         mir.span,
         mir,
         Place::Ptr(*ret),
-        cleanup,
+        StackPopCleanup::None { cleanup: false },
     )?;
 
     // The main interpreter loop.
     ecx.run()?;
 
+    // Intern the result
+    let internally_mutable = !layout.ty.is_freeze(tcx, param_env, mir.span);
+    let is_static = tcx.is_static(cid.instance.def_id());
+    let mutability = if is_static == Some(hir::Mutability::MutMutable) || internally_mutable {
+        Mutability::Mutable
+    } else {
+        Mutability::Immutable
+    };
+    ecx.memory.intern_static(ret.ptr.to_ptr()?.alloc_id, mutability)?;
+
     debug!("eval_body_using_ecx done: {:?}", *ret);
     Ok(ret.into())
 }
index 49027683d872754994a6b32754d19c87137fcd7a..dd908acec712584a02773bef24366bd0e4209267 100644 (file)
@@ -32,7 +32,6 @@
 };
 
 use syntax::source_map::{self, Span};
-use syntax::ast::Mutability;
 
 use super::{
     Value, Operand, MemPlace, MPlaceTy, Place, PlaceExtra,
@@ -159,15 +158,14 @@ fn hash<H: Hasher>(&self, state: &mut H) {
 
 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
 pub enum StackPopCleanup {
-    /// The stackframe existed to compute the initial value of a static/constant.
-    /// Call `M::intern_static` on the return value and all allocations it references
-    /// when this is done.  Must have a valid pointer as return place.
-    FinishStatic(Mutability),
     /// Jump to the next block in the caller, or cause UB if None (that's a function
     /// that may never return).
     Goto(Option<mir::BasicBlock>),
-    /// Just do nohing: Used by Main and for the box_alloc hook in miri
-    None,
+    /// Just do nohing: Used by Main and for the box_alloc hook in miri.
+    /// `cleanup` says whether locals are deallocated.  Static computation
+    /// wants them leaked to intern what they need (and just throw away
+    /// the entire `ecx` when it is done).
+    None { cleanup: bool },
 }
 
 // State of a local variable
@@ -631,18 +629,15 @@ pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx> {
             "tried to pop a stack frame, but there were none",
         );
         match frame.return_to_block {
-            StackPopCleanup::FinishStatic(mutability) => {
-                let mplace = frame.return_place.to_mem_place();
-                // to_ptr should be okay here; it is the responsibility of whoever pushed
-                // this frame to make sure that this works.
-                let ptr = mplace.ptr.to_ptr()?;
-                assert_eq!(ptr.offset.bytes(), 0);
-                self.memory.mark_static_initialized(ptr.alloc_id, mutability)?;
-            }
             StackPopCleanup::Goto(block) => {
                 self.goto_block(block)?;
             }
-            StackPopCleanup::None => { }
+            StackPopCleanup::None { cleanup } => {
+                if !cleanup {
+                    // Leak the locals
+                    return Ok(());
+                }
+            }
         }
         // deallocate all locals that are backed by an allocation
         for local in frame.locals {
index e570468a467f818222d07787d6e607d3a2d03e40..85c1ab4edcbd7123173f09dfe06952db9cbd9435 100644 (file)
@@ -570,22 +570,8 @@ fn get_bytes_mut(
 
 /// Reading and writing
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
-    /// mark an allocation pointed to by a static as static and initialized
-    fn mark_inner_allocation_initialized(
-        &mut self,
-        alloc: AllocId,
-        mutability: Mutability,
-    ) -> EvalResult<'tcx> {
-        match self.alloc_map.contains_key(&alloc) {
-            // already interned
-            false => Ok(()),
-            // this still needs work
-            true => self.mark_static_initialized(alloc, mutability),
-        }
-    }
-
     /// mark an allocation as static and initialized, either mutable or not
-    pub fn mark_static_initialized(
+    pub fn intern_static(
         &mut self,
         alloc_id: AllocId,
         mutability: Mutability,
@@ -613,7 +599,10 @@ pub fn mark_static_initialized(
             // at references.  So whenever we follow a reference, we should likely
             // assume immutability -- and we should make sure that the compiler
             // does not permit code that would break this!
-            self.mark_inner_allocation_initialized(alloc, mutability)?;
+            if self.alloc_map.contains_key(&alloc) {
+                // Not yet interned, so proceed recursively
+                self.intern_static(alloc, mutability)?;
+            }
         }
         Ok(())
     }
index 4ce0563749ac6963f203e1cb5b3e8a46a9283cbe..6aea68907ecd10aa76194aa16659ac42aaea2820 100644 (file)
@@ -68,7 +68,7 @@ pub fn get_vtable(
             }
         }
 
-        self.memory.mark_static_initialized(
+        self.memory.intern_static(
             vtable.alloc_id,
             Mutability::Immutable,
         )?;