Skip to content

Commit aa9053a

Browse files
authored
Rollup merge of #71475 - RalfJung:miri-frame-loc, r=ecstatic-morse
Miri Frame: use mir::Location to represent position in function I only recently learned that `Location` exists, and it seems to perfectly fit what Miri needs to represent which statement we are currently executing. :) r? @ecstatic-morse
2 parents 715948e + 90f1131 commit aa9053a

File tree

3 files changed

+29
-41
lines changed

3 files changed

+29
-41
lines changed

src/librustc_mir/interpret/eval_context.rs

+20-30
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)?;
@@ -666,9 +659,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
666659
/// Jump to the given block.
667660
#[inline]
668661
pub fn go_to_block(&mut self, target: mir::BasicBlock) {
669-
let frame = self.frame_mut();
670-
frame.block = Some(target);
671-
frame.stmt = 0;
662+
self.frame_mut().loc = Some(mir::Location { block: target, statement_index: 0 });
672663
}
673664

674665
/// *Return* to the given `target` basic block.
@@ -690,9 +681,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
690681
/// If `target` is `None`, that indicates the function does not need cleanup during
691682
/// unwinding, and we will just keep propagating that upwards.
692683
pub fn unwind_to_block(&mut self, target: Option<mir::BasicBlock>) {
693-
let frame = self.frame_mut();
694-
frame.block = target;
695-
frame.stmt = 0;
684+
self.frame_mut().loc = target.map(|block| mir::Location { block, statement_index: 0 });
696685
}
697686

698687
/// Pops the current frame from the stack, deallocating the
@@ -719,9 +708,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
719708
// Sanity check `unwinding`.
720709
assert_eq!(
721710
unwinding,
722-
match self.frame().block {
711+
match self.frame().loc {
723712
None => true,
724-
Some(block) => self.body().basic_blocks()[block].is_cleanup,
713+
Some(loc) => self.body().basic_blocks()[loc.block].is_cleanup,
725714
}
726715
);
727716

@@ -973,13 +962,14 @@ where
973962
Tag: HashStable<StableHashingContext<'ctx>>,
974963
{
975964
fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) {
976-
self.body.hash_stable(hcx, hasher);
977-
self.instance.hash_stable(hcx, hasher);
978-
self.return_to_block.hash_stable(hcx, hasher);
979-
self.return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher);
980-
self.locals.hash_stable(hcx, hasher);
981-
self.block.hash_stable(hcx, hasher);
982-
self.stmt.hash_stable(hcx, hasher);
983-
self.extra.hash_stable(hcx, hasher);
965+
// Exhaustive match on fields to make sure we forget no field.
966+
let Frame { body, instance, return_to_block, return_place, locals, loc, extra } = self;
967+
body.hash_stable(hcx, hasher);
968+
instance.hash_stable(hcx, hasher);
969+
return_to_block.hash_stable(hcx, hasher);
970+
return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher);
971+
locals.hash_stable(hcx, hasher);
972+
loc.hash_stable(hcx, hasher);
973+
extra.hash_stable(hcx, hasher);
984974
}
985975
}

src/librustc_mir/interpret/step.rs

+7-9
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

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
5252

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

0 commit comments

Comments
 (0)