@@ -49,15 +49,15 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
4949 pub ( crate ) memory : Memory < ' a , ' mir , ' tcx , M > ,
5050
5151 /// The virtual call stack.
52- pub ( crate ) stack : Vec < Frame < ' mir , ' tcx , M :: PointerTag > > ,
52+ pub ( crate ) stack : Vec < Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > > ,
5353
5454 /// A cache for deduplicating vtables
5555 pub ( super ) vtables : FxHashMap < ( Ty < ' tcx > , ty:: PolyExistentialTraitRef < ' tcx > ) , AllocId > ,
5656}
5757
5858/// A stack frame.
5959#[ derive( Clone ) ]
60- pub struct Frame < ' mir , ' tcx : ' mir , Tag =( ) > {
60+ pub struct Frame < ' mir , ' tcx : ' mir , Tag =( ) , Extra = ( ) > {
6161 ////////////////////////////////////////////////////////////////////////////////
6262 // Function and callsite information
6363 ////////////////////////////////////////////////////////////////////////////////
@@ -96,6 +96,9 @@ pub struct Frame<'mir, 'tcx: 'mir, Tag=()> {
9696
9797 /// The index of the currently evaluated statement.
9898 pub stmt : usize ,
99+
100+ /// Extra data for the machine
101+ pub extra : Extra ,
99102}
100103
101104#[ derive( Clone , Debug , Eq , PartialEq , Hash ) ]
@@ -196,7 +199,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
196199 }
197200
198201 #[ inline( always) ]
199- pub fn stack ( & self ) -> & [ Frame < ' mir , ' tcx , M :: PointerTag > ] {
202+ pub fn stack ( & self ) -> & [ Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > ] {
200203 & self . stack
201204 }
202205
@@ -207,12 +210,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
207210 }
208211
209212 #[ inline( always) ]
210- pub fn frame ( & self ) -> & Frame < ' mir , ' tcx , M :: PointerTag > {
213+ pub fn frame ( & self ) -> & Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > {
211214 self . stack . last ( ) . expect ( "no call frames exist" )
212215 }
213216
214217 #[ inline( always) ]
215- pub fn frame_mut ( & mut self ) -> & mut Frame < ' mir , ' tcx , M :: PointerTag > {
218+ pub fn frame_mut ( & mut self ) -> & mut Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > {
216219 self . stack . last_mut ( ) . expect ( "no call frames exist" )
217220 }
218221
@@ -294,7 +297,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
294297
295298 pub fn layout_of_local (
296299 & self ,
297- frame : & Frame < ' mir , ' tcx , M :: PointerTag > ,
300+ frame : & Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > ,
298301 local : mir:: Local
299302 ) -> EvalResult < ' tcx , TyLayout < ' tcx > > {
300303 let local_ty = frame. mir . local_decls [ local] . ty ;
@@ -424,6 +427,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
424427 :: log_settings:: settings ( ) . indentation += 1 ;
425428
426429 // first push a stack frame so we have access to the local substs
430+ let extra = M :: stack_push ( self ) ?;
427431 self . stack . push ( Frame {
428432 mir,
429433 block : mir:: START_BLOCK ,
@@ -435,6 +439,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
435439 span,
436440 instance,
437441 stmt : 0 ,
442+ extra,
438443 } ) ;
439444
440445 // don't allocate at all for trivial constants
@@ -504,6 +509,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
504509 let frame = self . stack . pop ( ) . expect (
505510 "tried to pop a stack frame, but there were none" ,
506511 ) ;
512+ M :: stack_pop ( self , frame. extra ) ?;
507513 // Abort early if we do not want to clean up: We also avoid validation in that case,
508514 // because this is CTFE and the final value will be thoroughly validated anyway.
509515 match frame. return_to_block {
0 commit comments