@@ -49,15 +49,15 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
49
49
pub ( crate ) memory : Memory < ' a , ' mir , ' tcx , M > ,
50
50
51
51
/// 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 > > ,
53
53
54
54
/// A cache for deduplicating vtables
55
55
pub ( super ) vtables : FxHashMap < ( Ty < ' tcx > , ty:: PolyExistentialTraitRef < ' tcx > ) , AllocId > ,
56
56
}
57
57
58
58
/// A stack frame.
59
59
#[ derive( Clone ) ]
60
- pub struct Frame < ' mir , ' tcx : ' mir , Tag =( ) > {
60
+ pub struct Frame < ' mir , ' tcx : ' mir , Tag =( ) , Extra = ( ) > {
61
61
////////////////////////////////////////////////////////////////////////////////
62
62
// Function and callsite information
63
63
////////////////////////////////////////////////////////////////////////////////
@@ -96,6 +96,9 @@ pub struct Frame<'mir, 'tcx: 'mir, Tag=()> {
96
96
97
97
/// The index of the currently evaluated statement.
98
98
pub stmt : usize ,
99
+
100
+ /// Extra data for the machine
101
+ pub extra : Extra ,
99
102
}
100
103
101
104
#[ derive( Clone , Debug , Eq , PartialEq , Hash ) ]
@@ -196,7 +199,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
196
199
}
197
200
198
201
#[ inline( always) ]
199
- pub fn stack ( & self ) -> & [ Frame < ' mir , ' tcx , M :: PointerTag > ] {
202
+ pub fn stack ( & self ) -> & [ Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > ] {
200
203
& self . stack
201
204
}
202
205
@@ -207,12 +210,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
207
210
}
208
211
209
212
#[ inline( always) ]
210
- pub fn frame ( & self ) -> & Frame < ' mir , ' tcx , M :: PointerTag > {
213
+ pub fn frame ( & self ) -> & Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > {
211
214
self . stack . last ( ) . expect ( "no call frames exist" )
212
215
}
213
216
214
217
#[ 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 > {
216
219
self . stack . last_mut ( ) . expect ( "no call frames exist" )
217
220
}
218
221
@@ -294,7 +297,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
294
297
295
298
pub fn layout_of_local (
296
299
& self ,
297
- frame : & Frame < ' mir , ' tcx , M :: PointerTag > ,
300
+ frame : & Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > ,
298
301
local : mir:: Local
299
302
) -> EvalResult < ' tcx , TyLayout < ' tcx > > {
300
303
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
424
427
:: log_settings:: settings ( ) . indentation += 1 ;
425
428
426
429
// first push a stack frame so we have access to the local substs
430
+ let extra = M :: stack_push ( self ) ?;
427
431
self . stack . push ( Frame {
428
432
mir,
429
433
block : mir:: START_BLOCK ,
@@ -435,6 +439,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
435
439
span,
436
440
instance,
437
441
stmt : 0 ,
442
+ extra,
438
443
} ) ;
439
444
440
445
// 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
504
509
let frame = self . stack . pop ( ) . expect (
505
510
"tried to pop a stack frame, but there were none" ,
506
511
) ;
512
+ M :: stack_pop ( self , frame. extra ) ?;
507
513
// Abort early if we do not want to clean up: We also avoid validation in that case,
508
514
// because this is CTFE and the final value will be thoroughly validated anyway.
509
515
match frame. return_to_block {
0 commit comments