diff options
| author | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2017-07-27 12:02:16 +0200 |
|---|---|---|
| committer | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2017-08-01 09:56:21 +0200 |
| commit | 728bb878acb374d313482cac41a2aa3a60af2a84 (patch) | |
| tree | 8f6dc9f3eb07b780cce64e8aa0e1c41da8792244 /src | |
| parent | 960dca172d1102bb1ff3fded56427bc6e00c521e (diff) | |
| download | rust-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.toml | 1 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/step.rs | 115 |
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); } |
