Skip to content

Commit 90f1131

Browse files
committed
Miri Frame: use mir::Location to represent position in function
1 parent 66f7a5d commit 90f1131

File tree

3 files changed

+29
-41
lines changed

3 files changed

+29
-41
lines changed

src/librustc_mir/interpret/eval_context.rs

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,9 @@ pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> {
8181
////////////////////////////////////////////////////////////////////////////////
8282
// Current position within the function
8383
////////////////////////////////////////////////////////////////////////////////
84-
/// The block that is currently executed (or will be executed after the above call stacks
85-
/// return).
8684
/// If this is `None`, we are unwinding and this function doesn't need any clean-up.
8785
/// Just continue the same as with `Resume`.
88-
pub block: Option<mir::BasicBlock>,
89-
90-
/// The index of the currently evaluated statement.
91-
pub stmt: usize,
86+
pub loc: Option<mir::Location>,
9287
}
9388

9489
#[derive(Clone, Eq, PartialEq, Debug, HashStable)] // Miri debug-prints these
@@ -168,8 +163,7 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
168163
return_to_block: self.return_to_block,
169164
return_place: self.return_place,
170165
locals: self.locals,
171-
block: self.block,
172-
stmt: self.stmt,
166+
loc: self.loc,
173167
extra,
174168
}
175169
}
@@ -178,10 +172,10 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
178172
impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> {
179173
/// Return the `SourceInfo` of the current instruction.
180174
pub fn current_source_info(&self) -> Option<mir::SourceInfo> {
181-
self.block.map(|block| {
182-
let block = &self.body.basic_blocks()[block];
183-
if self.stmt < block.statements.len() {
184-
block.statements[self.stmt].source_info
175+
self.loc.map(|loc| {
176+
let block = &self.body.basic_blocks()[loc.block];
177+
if loc.statement_index < block.statements.len() {
178+
block.statements[loc.statement_index].source_info
185179
} else {
186180
block.terminator().source_info
187181
}
@@ -615,14 +609,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
615609
// first push a stack frame so we have access to the local substs
616610
let pre_frame = Frame {
617611
body,
618-
block: Some(mir::START_BLOCK),
612+
loc: Some(mir::Location::START),
619613
return_to_block,
620614
return_place,
621615
// empty local array, we fill it in below, after we are inside the stack frame and
622616
// all methods actually know about the frame
623617
locals: IndexVec::new(),
624618
instance,
625-
stmt: 0,
626619
extra: (),
627620
};
628621
let frame = M::init_frame_extra(self, pre_frame)?;
@@ -671,9 +664,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
671664
/// Jump to the given block.
672665
#[inline]
673666
pub fn go_to_block(&mut self, target: mir::BasicBlock) {
674-
let frame = self.frame_mut();
675-
frame.block = Some(target);
676-
frame.stmt = 0;
667+
self.frame_mut().loc = Some(mir::Location { block: target, statement_index: 0 });
677668
}
678669

679670
/// *Return* to the given `target` basic block.
@@ -695,9 +686,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
695686
/// If `target` is `None`, that indicates the function does not need cleanup during
696687
/// unwinding, and we will just keep propagating that upwards.
697688
pub fn unwind_to_block(&mut self, target: Option<mir::BasicBlock>) {
698-
let frame = self.frame_mut();
699-
frame.block = target;
700-
frame.stmt = 0;
689+
self.frame_mut().loc = target.map(|block| mir::Location { block, statement_index: 0 });
701690
}
702691

703692
/// Pops the current frame from the stack, deallocating the
@@ -724,9 +713,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
724713
// Sanity check `unwinding`.
725714
assert_eq!(
726715
unwinding,
727-
match self.frame().block {
716+
match self.frame().loc {
728717
None => true,
729-
Some(block) => self.body().basic_blocks()[block].is_cleanup,
718+
Some(loc) => self.body().basic_blocks()[loc.block].is_cleanup,
730719
}
731720
);
732721

@@ -987,13 +976,14 @@ where
987976
Tag: HashStable<StableHashingContext<'ctx>>,
988977
{
989978
fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) {
990-
self.body.hash_stable(hcx, hasher);
991-
self.instance.hash_stable(hcx, hasher);
992-
self.return_to_block.hash_stable(hcx, hasher);
993-
self.return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher);
994-
self.locals.hash_stable(hcx, hasher);
995-
self.block.hash_stable(hcx, hasher);
996-
self.stmt.hash_stable(hcx, hasher);
997-
self.extra.hash_stable(hcx, hasher);
979+
// Exhaustive match on fields to make sure we forget no field.
980+
let Frame { body, instance, return_to_block, return_place, locals, loc, extra } = self;
981+
body.hash_stable(hcx, hasher);
982+
instance.hash_stable(hcx, hasher);
983+
return_to_block.hash_stable(hcx, hasher);
984+
return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher);
985+
locals.hash_stable(hcx, hasher);
986+
loc.hash_stable(hcx, hasher);
987+
extra.hash_stable(hcx, hasher);
998988
}
999989
}

src/librustc_mir/interpret/step.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
4646
return Ok(false);
4747
}
4848

49-
let block = match self.frame().block {
50-
Some(block) => block,
49+
let loc = match self.frame().loc {
50+
Some(loc) => loc,
5151
None => {
5252
// We are unwinding and this fn has no cleanup code.
5353
// Just go on unwinding.
@@ -56,13 +56,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
5656
return Ok(true);
5757
}
5858
};
59-
let stmt_id = self.frame().stmt;
60-
let body = self.body();
61-
let basic_block = &body.basic_blocks()[block];
59+
let basic_block = &self.body().basic_blocks()[loc.block];
6260

6361
let old_frames = self.frame_idx();
6462

65-
if let Some(stmt) = basic_block.statements.get(stmt_id) {
63+
if let Some(stmt) = basic_block.statements.get(loc.statement_index) {
6664
assert_eq!(old_frames, self.frame_idx());
6765
self.statement(stmt)?;
6866
return Ok(true);
@@ -126,7 +124,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
126124
LlvmInlineAsm { .. } => throw_unsup_format!("inline assembly is not supported"),
127125
}
128126

129-
self.stack_mut()[frame_idx].stmt += 1;
127+
self.stack_mut()[frame_idx].loc.as_mut().unwrap().statement_index += 1;
130128
Ok(())
131129
}
132130

@@ -279,8 +277,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
279277

280278
self.eval_terminator(terminator)?;
281279
if !self.stack().is_empty() {
282-
if let Some(block) = self.frame().block {
283-
info!("// executing {:?}", block);
280+
if let Some(loc) = self.frame().loc {
281+
info!("// executing {:?}", loc.block);
284282
}
285283
}
286284
Ok(())

src/librustc_mir/interpret/terminator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
5353

5454
Call { ref func, ref args, destination, ref cleanup, .. } => {
5555
let old_stack = self.frame_idx();
56-
let old_bb = self.frame().block;
56+
let old_loc = self.frame().loc;
5757
let func = self.eval_operand(func, None)?;
5858
let (fn_val, abi) = match func.layout.ty.kind {
5959
ty::FnPtr(sig) => {
@@ -80,7 +80,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
8080
self.eval_fn_call(fn_val, abi, &args[..], ret, *cleanup)?;
8181
// Sanity-check that `eval_fn_call` either pushed a new frame or
8282
// did a jump to another block.
83-
if self.frame_idx() == old_stack && self.frame().block == old_bb {
83+
if self.frame_idx() == old_stack && self.frame().loc == old_loc {
8484
span_bug!(terminator.source_info.span, "evaluating this call made no progress");
8585
}
8686
}

0 commit comments

Comments
 (0)