about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-07-27 12:02:16 +0200
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-08-01 09:56:21 +0200
commit728bb878acb374d313482cac41a2aa3a60af2a84 (patch)
tree8f6dc9f3eb07b780cce64e8aa0e1c41da8792244 /src
parent960dca172d1102bb1ff3fded56427bc6e00c521e (diff)
downloadrust-728bb878acb374d313482cac41a2aa3a60af2a84.tar.gz
rust-728bb878acb374d313482cac41a2aa3a60af2a84.zip
Move the `global_item` function to the `EvalContext`
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/Cargo.toml1
-rw-r--r--src/librustc_mir/interpret/step.rs115
2 files changed, 62 insertions, 54 deletions
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 8e734b4807e..78e8cbeecd7 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -5,6 +5,7 @@ license = "MIT/Apache-2.0"
 name = "rustc_miri"
 repository = "https://github.com/solson/miri"
 version = "0.1.0"
+workspace = "../.."
 
 [lib]
 test = false
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 96879a75618..06d9d8b07fa 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -155,6 +155,49 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
         }
         Ok(())
     }
+
+    /// returns `true` if a stackframe was pushed
+    fn global_item(
+        &mut self,
+        def_id: DefId,
+        substs: &'tcx Substs<'tcx>,
+        span: Span,
+        mutability: Mutability,
+    ) -> EvalResult<'tcx, bool> {
+        let instance = self.resolve_associated_const(def_id, substs);
+        let cid = GlobalId { instance, promoted: None };
+        if self.globals.contains_key(&cid) {
+            return Ok(false);
+        }
+        if self.tcx.has_attr(def_id, "linkage") {
+            // FIXME: check that it's `#[linkage = "extern_weak"]`
+            trace!("Initializing an extern global with NULL");
+            self.globals.insert(cid, Global::initialized(self.tcx.type_of(def_id), Value::ByVal(PrimVal::Bytes(0)), mutability));
+            return Ok(false);
+        }
+        let mir = self.load_mir(instance.def)?;
+        self.globals.insert(cid, Global::uninitialized(mir.return_ty));
+        let internally_mutable = !mir.return_ty.is_freeze(
+                self.tcx,
+                ty::ParamEnv::empty(Reveal::All),
+                span);
+        let mutability = if mutability == Mutability::Mutable || internally_mutable {
+            Mutability::Mutable
+        } else {
+            Mutability::Immutable
+        };
+        let cleanup = StackPopCleanup::MarkStatic(mutability);
+        let name = ty::tls::with(|tcx| tcx.item_path_str(def_id));
+        trace!("pushing stack frame for global: {}", name);
+        self.push_stack_frame(
+            instance,
+            span,
+            mir,
+            Lvalue::Global(cid),
+            cleanup,
+        )?;
+        Ok(true)
+    }
 }
 
 // WARNING: make sure that any methods implemented on this type don't ever access ecx.stack
@@ -170,56 +213,19 @@ struct ConstantExtractor<'a, 'b: 'a, 'tcx: 'b, M: Machine<'tcx> + 'a> {
 }
 
 impl<'a, 'b, 'tcx, M: Machine<'tcx>> ConstantExtractor<'a, 'b, 'tcx, M> {
-    fn global_item(
-        &mut self,
-        def_id: DefId,
-        substs: &'tcx Substs<'tcx>,
-        span: Span,
-        mutability: Mutability,
-    ) {
-        let instance = self.ecx.resolve_associated_const(def_id, substs);
-        let cid = GlobalId { instance, promoted: None };
-        if self.ecx.globals.contains_key(&cid) {
-            return;
-        }
-        if self.ecx.tcx.has_attr(def_id, "linkage") {
-            trace!("Initializing an extern global with NULL");
-            self.ecx.globals.insert(cid, Global::initialized(self.ecx.tcx.type_of(def_id), Value::ByVal(PrimVal::Bytes(0)), mutability));
-            return;
-        }
-        self.try(|this| {
-            let mir = this.ecx.load_mir(instance.def)?;
-            this.ecx.globals.insert(cid, Global::uninitialized(mir.return_ty));
-            let internally_mutable = !mir.return_ty.is_freeze(
-                    this.ecx.tcx,
-                    ty::ParamEnv::empty(Reveal::All),
-                    span);
-            let mutability = if mutability == Mutability::Mutable || internally_mutable {
-                Mutability::Mutable
-            } else {
-                Mutability::Immutable
-            };
-            let cleanup = StackPopCleanup::MarkStatic(mutability);
-            let name = ty::tls::with(|tcx| tcx.item_path_str(def_id));
-            trace!("pushing stack frame for global: {}", name);
-            this.ecx.push_stack_frame(
-                instance,
-                span,
-                mir,
-                Lvalue::Global(cid),
-                cleanup,
-            )
-        });
-    }
-
-    fn try<F: FnOnce(&mut Self) -> EvalResult<'tcx>>(&mut self, f: F) {
-        if let Ok(ref mut n) = *self.new_constants {
-            *n += 1;
-        } else {
-            return;
-        }
-        if let Err(e) = f(self) {
-            *self.new_constants = Err(e);
+    fn try<F: FnOnce(&mut Self) -> EvalResult<'tcx, bool>>(&mut self, f: F) {
+        // previous constant errored
+        let n = match *self.new_constants {
+            Ok(n) => n,
+            Err(_) => return,
+        };
+        match f(self) {
+            // everything ok + a new stackframe
+            Ok(true) => *self.new_constants = Ok(n + 1),
+            // constant correctly evaluated, but no new stackframe
+            Ok(false) => {},
+            // constant eval errored
+            Err(err) => *self.new_constants = Err(err),
         }
     }
 }
@@ -231,7 +237,7 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
             // already computed by rustc
             mir::Literal::Value { .. } => {}
             mir::Literal::Item { def_id, substs } => {
-                self.global_item(def_id, substs, constant.span, Mutability::Immutable);
+                self.try(|this| this.ecx.global_item(def_id, substs, constant.span, Mutability::Immutable));
             },
             mir::Literal::Promoted { index } => {
                 let cid = GlobalId {
@@ -251,7 +257,8 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
                                               mir,
                                               Lvalue::Global(cid),
                                               StackPopCleanup::MarkStatic(Mutability::Immutable),
-                    )
+                    )?;
+                    Ok(true)
                 });
             }
         }
@@ -271,7 +278,7 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
             if let Some(node_item) = self.ecx.tcx.hir.get_if_local(def_id) {
                 if let hir::map::Node::NodeItem(&hir::Item { ref node, .. }) = node_item {
                     if let hir::ItemStatic(_, m, _) = *node {
-                        self.global_item(def_id, substs, span, if m == hir::MutMutable { Mutability::Mutable } else { Mutability::Immutable });
+                        self.try(|this| this.ecx.global_item(def_id, substs, span, if m == hir::MutMutable { Mutability::Mutable } else { Mutability::Immutable }));
                         return;
                     } else {
                         bug!("static def id doesn't point to static");
@@ -282,7 +289,7 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
             } else {
                 let def = self.ecx.tcx.describe_def(def_id).expect("static not found");
                 if let hir::def::Def::Static(_, mutable) = def {
-                    self.global_item(def_id, substs, span, if mutable { Mutability::Mutable } else { Mutability::Immutable });
+                    self.try(|this| this.ecx.global_item(def_id, substs, span, if mutable { Mutability::Mutable } else { Mutability::Immutable }));
                 } else {
                     bug!("static found but isn't a static: {:?}", def);
                 }