Skip to content

Commit c8b5e6e

Browse files
committed
Move the global_item function to the EvalContext
1 parent d28ed4a commit c8b5e6e

File tree

2 files changed

+62
-54
lines changed

2 files changed

+62
-54
lines changed

src/librustc_mir/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ license = "MIT/Apache-2.0"
55
name = "rustc_miri"
66
repository = "https://github.com/solson/miri"
77
version = "0.1.0"
8+
workspace = "../.."
89

910
[lib]
1011
test = false

src/librustc_mir/interpret/step.rs

Lines changed: 61 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,49 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
154154
}
155155
Ok(())
156156
}
157+
158+
/// returns `true` if a stackframe was pushed
159+
fn global_item(
160+
&mut self,
161+
def_id: DefId,
162+
substs: &'tcx Substs<'tcx>,
163+
span: Span,
164+
mutability: Mutability,
165+
) -> EvalResult<'tcx, bool> {
166+
let instance = self.resolve_associated_const(def_id, substs);
167+
let cid = GlobalId { instance, promoted: None };
168+
if self.globals.contains_key(&cid) {
169+
return Ok(false);
170+
}
171+
if self.tcx.has_attr(def_id, "linkage") {
172+
// FIXME: check that it's `#[linkage = "extern_weak"]`
173+
trace!("Initializing an extern global with NULL");
174+
self.globals.insert(cid, Global::initialized(self.tcx.type_of(def_id), Value::ByVal(PrimVal::Bytes(0)), mutability));
175+
return Ok(false);
176+
}
177+
let mir = self.load_mir(instance.def)?;
178+
self.globals.insert(cid, Global::uninitialized(mir.return_ty));
179+
let internally_mutable = !mir.return_ty.is_freeze(
180+
self.tcx,
181+
ty::ParamEnv::empty(Reveal::All),
182+
span);
183+
let mutability = if mutability == Mutability::Mutable || internally_mutable {
184+
Mutability::Mutable
185+
} else {
186+
Mutability::Immutable
187+
};
188+
let cleanup = StackPopCleanup::MarkStatic(mutability);
189+
let name = ty::tls::with(|tcx| tcx.item_path_str(def_id));
190+
trace!("pushing stack frame for global: {}", name);
191+
self.push_stack_frame(
192+
instance,
193+
span,
194+
mir,
195+
Lvalue::Global(cid),
196+
cleanup,
197+
)?;
198+
Ok(true)
199+
}
157200
}
158201

159202
// WARNING: make sure that any methods implemented on this type don't ever access ecx.stack
@@ -169,56 +212,19 @@ struct ConstantExtractor<'a, 'b: 'a, 'tcx: 'b, M: Machine<'tcx> + 'a> {
169212
}
170213

171214
impl<'a, 'b, 'tcx, M: Machine<'tcx>> ConstantExtractor<'a, 'b, 'tcx, M> {
172-
fn global_item(
173-
&mut self,
174-
def_id: DefId,
175-
substs: &'tcx Substs<'tcx>,
176-
span: Span,
177-
mutability: Mutability,
178-
) {
179-
let instance = self.ecx.resolve_associated_const(def_id, substs);
180-
let cid = GlobalId { instance, promoted: None };
181-
if self.ecx.globals.contains_key(&cid) {
182-
return;
183-
}
184-
if self.ecx.tcx.has_attr(def_id, "linkage") {
185-
trace!("Initializing an extern global with NULL");
186-
self.ecx.globals.insert(cid, Global::initialized(self.ecx.tcx.type_of(def_id), Value::ByVal(PrimVal::Bytes(0)), mutability));
187-
return;
188-
}
189-
self.try(|this| {
190-
let mir = this.ecx.load_mir(instance.def)?;
191-
this.ecx.globals.insert(cid, Global::uninitialized(mir.return_ty));
192-
let internally_mutable = !mir.return_ty.is_freeze(
193-
this.ecx.tcx,
194-
ty::ParamEnv::empty(Reveal::All),
195-
span);
196-
let mutability = if mutability == Mutability::Mutable || internally_mutable {
197-
Mutability::Mutable
198-
} else {
199-
Mutability::Immutable
200-
};
201-
let cleanup = StackPopCleanup::MarkStatic(mutability);
202-
let name = ty::tls::with(|tcx| tcx.item_path_str(def_id));
203-
trace!("pushing stack frame for global: {}", name);
204-
this.ecx.push_stack_frame(
205-
instance,
206-
span,
207-
mir,
208-
Lvalue::Global(cid),
209-
cleanup,
210-
)
211-
});
212-
}
213-
214-
fn try<F: FnOnce(&mut Self) -> EvalResult<'tcx>>(&mut self, f: F) {
215-
if let Ok(ref mut n) = *self.new_constants {
216-
*n += 1;
217-
} else {
218-
return;
219-
}
220-
if let Err(e) = f(self) {
221-
*self.new_constants = Err(e);
215+
fn try<F: FnOnce(&mut Self) -> EvalResult<'tcx, bool>>(&mut self, f: F) {
216+
// previous constant errored
217+
let n = match *self.new_constants {
218+
Ok(n) => n,
219+
Err(_) => return,
220+
};
221+
match f(self) {
222+
// everything ok + a new stackframe
223+
Ok(true) => *self.new_constants = Ok(n + 1),
224+
// constant correctly evaluated, but no new stackframe
225+
Ok(false) => {},
226+
// constant eval errored
227+
Err(err) => *self.new_constants = Err(err),
222228
}
223229
}
224230
}
@@ -230,7 +236,7 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
230236
// already computed by rustc
231237
mir::Literal::Value { .. } => {}
232238
mir::Literal::Item { def_id, substs } => {
233-
self.global_item(def_id, substs, constant.span, Mutability::Immutable);
239+
self.try(|this| this.ecx.global_item(def_id, substs, constant.span, Mutability::Immutable));
234240
},
235241
mir::Literal::Promoted { index } => {
236242
let cid = GlobalId {
@@ -250,7 +256,8 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
250256
mir,
251257
Lvalue::Global(cid),
252258
StackPopCleanup::MarkStatic(Mutability::Immutable),
253-
)
259+
)?;
260+
Ok(true)
254261
});
255262
}
256263
}
@@ -270,7 +277,7 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
270277
if let Some(node_item) = self.ecx.tcx.hir.get_if_local(def_id) {
271278
if let hir::map::Node::NodeItem(&hir::Item { ref node, .. }) = node_item {
272279
if let hir::ItemStatic(_, m, _) = *node {
273-
self.global_item(def_id, substs, span, if m == hir::MutMutable { Mutability::Mutable } else { Mutability::Immutable });
280+
self.try(|this| this.ecx.global_item(def_id, substs, span, if m == hir::MutMutable { Mutability::Mutable } else { Mutability::Immutable }));
274281
return;
275282
} else {
276283
bug!("static def id doesn't point to static");
@@ -281,7 +288,7 @@ impl<'a, 'b, 'tcx, M: Machine<'tcx>> Visitor<'tcx> for ConstantExtractor<'a, 'b,
281288
} else {
282289
let def = self.ecx.tcx.describe_def(def_id).expect("static not found");
283290
if let hir::def::Def::Static(_, mutable) = def {
284-
self.global_item(def_id, substs, span, if mutable { Mutability::Mutable } else { Mutability::Immutable });
291+
self.try(|this| this.ecx.global_item(def_id, substs, span, if mutable { Mutability::Mutable } else { Mutability::Immutable }));
285292
} else {
286293
bug!("static found but isn't a static: {:?}", def);
287294
}

0 commit comments

Comments
 (0)