Skip to content

Commit 1a3bda6

Browse files
committed
Miri: let push_frame hook also access and mutate the rest of the frame data
1 parent a00bd29 commit 1a3bda6

File tree

4 files changed

+44
-18
lines changed

4 files changed

+44
-18
lines changed

src/librustc_mir/const_eval/machine.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use rustc_middle::mir::AssertMessage;
1313
use rustc_span::symbol::Symbol;
1414

1515
use crate::interpret::{
16-
self, AllocId, Allocation, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind, OpTy,
17-
PlaceTy, Pointer, Scalar,
16+
self, AllocId, Allocation, Frame, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind,
17+
OpTy, PlaceTy, Pointer, Scalar,
1818
};
1919

2020
use super::error::*;
@@ -339,8 +339,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
339339
}
340340

341341
#[inline(always)]
342-
fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
343-
Ok(())
342+
fn init_frame_extra(
343+
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
344+
frame: Frame<'mir, 'tcx>,
345+
) -> InterpResult<'tcx, Frame<'mir, 'tcx>> {
346+
Ok(frame)
344347
}
345348

346349
fn before_access_global(

src/librustc_mir/interpret/eval_context.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,21 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
159159
}
160160
}
161161

162+
impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
163+
pub fn with_extra<Extra>(self, extra: Extra) -> Frame<'mir, 'tcx, Tag, Extra> {
164+
Frame {
165+
body: self.body,
166+
instance: self.instance,
167+
return_to_block: self.return_to_block,
168+
return_place: self.return_place,
169+
locals: self.locals,
170+
block: self.block,
171+
stmt: self.stmt,
172+
extra,
173+
}
174+
}
175+
}
176+
162177
impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> {
163178
/// Return the `SourceInfo` of the current instruction.
164179
pub fn current_source_info(&self) -> Option<mir::SourceInfo> {
@@ -586,8 +601,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
586601
::log_settings::settings().indentation += 1;
587602

588603
// first push a stack frame so we have access to the local substs
589-
let extra = M::stack_push(self)?;
590-
self.stack.push(Frame {
604+
let pre_frame = Frame {
591605
body,
592606
block: Some(mir::START_BLOCK),
593607
return_to_block,
@@ -597,8 +611,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
597611
locals: IndexVec::new(),
598612
instance,
599613
stmt: 0,
600-
extra,
601-
});
614+
extra: (),
615+
};
616+
let frame = M::init_frame_extra(self, pre_frame)?;
617+
self.stack.push(frame);
602618

603619
// don't allocate at all for trivial constants
604620
if body.local_decls.len() > 1 {
@@ -725,11 +741,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
725741
}
726742

727743
// Cleanup: deallocate all locals that are backed by an allocation.
728-
for local in frame.locals {
744+
for local in &frame.locals {
729745
self.deallocate_local(local.value)?;
730746
}
731747

732-
if M::stack_pop(self, frame.extra, unwinding)? == StackPopJump::NoJump {
748+
let return_place = frame.return_place;
749+
if M::after_stack_pop(self, frame, unwinding)? == StackPopJump::NoJump {
733750
// The hook already did everything.
734751
// We want to skip the `info!` below, hence early return.
735752
return Ok(());
@@ -743,7 +760,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
743760
// Follow the normal return edge.
744761
// Validate the return value. Do this after deallocating so that we catch dangling
745762
// references.
746-
if let Some(return_place) = frame.return_place {
763+
if let Some(return_place) = return_place {
747764
if M::enforce_validity(self) {
748765
// Data got changed, better make sure it matches the type!
749766
// It is still possible that the return place held invalid data while

src/librustc_mir/interpret/machine.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,16 @@ pub trait Machine<'mir, 'tcx>: Sized {
279279
Ok(())
280280
}
281281

282-
/// Called immediately before a new stack frame got pushed.
283-
fn stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, Self::FrameExtra>;
282+
/// Called immediately before a new stack frame gets pushed.
283+
fn init_frame_extra(
284+
ecx: &mut InterpCx<'mir, 'tcx, Self>,
285+
frame: Frame<'mir, 'tcx, Self::PointerTag>,
286+
) -> InterpResult<'tcx, Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>>;
284287

285-
/// Called immediately after a stack frame gets popped
286-
fn stack_pop(
288+
/// Called immediately after a stack frame got popped, but before jumping back to the caller.
289+
fn after_stack_pop(
287290
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
288-
_extra: Self::FrameExtra,
291+
_frame: Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>,
289292
_unwinding: bool,
290293
) -> InterpResult<'tcx, StackPopJump> {
291294
// By default, we do not support unwinding from panics

src/librustc_mir/transform/const_prop.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
287287
}
288288

289289
#[inline(always)]
290-
fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
291-
Ok(())
290+
fn init_frame_extra(
291+
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
292+
frame: Frame<'mir, 'tcx>,
293+
) -> InterpResult<'tcx, Frame<'mir, 'tcx>> {
294+
Ok(frame)
292295
}
293296
}
294297

0 commit comments

Comments
 (0)