@@ -28,6 +28,8 @@ use crate::util::storage::AlwaysLiveLocals;
2828
2929pub struct InterpCx < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > {
3030 /// Stores the `Machine` instance.
31+ ///
32+ /// Note: the stack is provided by the machine.
3133 pub machine : M ,
3234
3335 /// The results of the type checker, from rustc.
@@ -39,9 +41,6 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
3941 /// The virtual memory system.
4042 pub memory : Memory < ' mir , ' tcx , M > ,
4143
42- /// The virtual call stack.
43- pub ( crate ) stack : Vec < Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > > ,
44-
4544 /// A cache for deduplicating vtables
4645 pub ( super ) vtables :
4746 FxHashMap < ( Ty < ' tcx > , Option < ty:: PolyExistentialTraitRef < ' tcx > > ) , Pointer < M :: PointerTag > > ,
@@ -297,7 +296,7 @@ pub(super) fn from_known_layout<'tcx>(
297296 }
298297}
299298
300- impl < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > InterpCx < ' mir , ' tcx , M > {
299+ impl < ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > InterpCx < ' mir , ' tcx , M > {
301300 pub fn new (
302301 tcx : TyCtxtAt < ' tcx > ,
303302 param_env : ty:: ParamEnv < ' tcx > ,
@@ -309,7 +308,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
309308 tcx,
310309 param_env,
311310 memory : Memory :: new ( tcx, memory_extra) ,
312- stack : Vec :: new ( ) ,
313311 vtables : FxHashMap :: default ( ) ,
314312 }
315313 }
@@ -349,24 +347,32 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
349347 }
350348
351349 #[ inline( always) ]
352- pub fn stack ( & self ) -> & [ Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > ] {
353- & self . stack
350+ pub ( crate ) fn stack ( & self ) -> & [ Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > ] {
351+ M :: stack ( self )
352+ }
353+
354+ #[ inline( always) ]
355+ pub ( crate ) fn stack_mut (
356+ & mut self ,
357+ ) -> & mut Vec < Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > > {
358+ M :: stack_mut ( self )
354359 }
355360
356361 #[ inline( always) ]
357- pub fn cur_frame ( & self ) -> usize {
358- assert ! ( !self . stack. is_empty( ) ) ;
359- self . stack . len ( ) - 1
362+ pub fn frame_idx ( & self ) -> usize {
363+ let stack = self . stack ( ) ;
364+ assert ! ( !stack. is_empty( ) ) ;
365+ stack. len ( ) - 1
360366 }
361367
362368 #[ inline( always) ]
363369 pub fn frame ( & self ) -> & Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > {
364- self . stack . last ( ) . expect ( "no call frames exist" )
370+ self . stack ( ) . last ( ) . expect ( "no call frames exist" )
365371 }
366372
367373 #[ inline( always) ]
368374 pub fn frame_mut ( & mut self ) -> & mut Frame < ' mir , ' tcx , M :: PointerTag , M :: FrameExtra > {
369- self . stack . last_mut ( ) . expect ( "no call frames exist" )
375+ self . stack_mut ( ) . last_mut ( ) . expect ( "no call frames exist" )
370376 }
371377
372378 #[ inline( always) ]
@@ -596,8 +602,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
596602 return_place : Option < PlaceTy < ' tcx , M :: PointerTag > > ,
597603 return_to_block : StackPopCleanup ,
598604 ) -> InterpResult < ' tcx > {
599- if !self . stack . is_empty ( ) {
600- info ! ( "PAUSING({}) {}" , self . cur_frame ( ) , self . frame( ) . instance) ;
605+ if !self . stack ( ) . is_empty ( ) {
606+ info ! ( "PAUSING({}) {}" , self . frame_idx ( ) , self . frame( ) . instance) ;
601607 }
602608 :: log_settings:: settings ( ) . indentation += 1 ;
603609
@@ -615,7 +621,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
615621 extra : ( ) ,
616622 } ;
617623 let frame = M :: init_frame_extra ( self , pre_frame) ?;
618- self . stack . push ( frame) ;
624+ self . stack_mut ( ) . push ( frame) ;
619625
620626 // don't allocate at all for trivial constants
621627 if body. local_decls . len ( ) > 1 {
@@ -648,9 +654,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
648654 }
649655
650656 M :: after_stack_push ( self ) ?;
651- info ! ( "ENTERING({}) {}" , self . cur_frame ( ) , self . frame( ) . instance) ;
657+ info ! ( "ENTERING({}) {}" , self . frame_idx ( ) , self . frame( ) . instance) ;
652658
653- if self . stack . len ( ) > * self . tcx . sess . recursion_limit . get ( ) {
659+ if self . stack ( ) . len ( ) > * self . tcx . sess . recursion_limit . get ( ) {
654660 throw_exhaust ! ( StackFrameLimitReached )
655661 } else {
656662 Ok ( ( ) )
@@ -705,7 +711,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
705711 pub ( super ) fn pop_stack_frame ( & mut self , unwinding : bool ) -> InterpResult < ' tcx > {
706712 info ! (
707713 "LEAVING({}) {} (unwinding = {})" ,
708- self . cur_frame ( ) ,
714+ self . frame_idx ( ) ,
709715 self . frame( ) . instance,
710716 unwinding
711717 ) ;
@@ -720,7 +726,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
720726 ) ;
721727
722728 :: log_settings:: settings ( ) . indentation -= 1 ;
723- let frame = self . stack . pop ( ) . expect ( "tried to pop a stack frame, but there were none" ) ;
729+ let frame =
730+ self . stack_mut ( ) . pop ( ) . expect ( "tried to pop a stack frame, but there were none" ) ;
724731
725732 // Now where do we jump next?
726733
@@ -735,7 +742,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
735742 } ;
736743
737744 if !cleanup {
738- assert ! ( self . stack. is_empty( ) , "only the topmost frame should ever be leaked" ) ;
745+ assert ! ( self . stack( ) . is_empty( ) , "only the topmost frame should ever be leaked" ) ;
739746 assert ! ( next_block. is_none( ) , "tried to skip cleanup when we have a next block!" ) ;
740747 assert ! ( !unwinding, "tried to skip cleanup during unwinding" ) ;
741748 // Leak the locals, skip validation, skip machine hook.
@@ -784,10 +791,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
784791 }
785792 }
786793
787- if !self . stack . is_empty ( ) {
794+ if !self . stack ( ) . is_empty ( ) {
788795 info ! (
789796 "CONTINUING({}) {} (unwinding = {})" ,
790- self . cur_frame ( ) ,
797+ self . frame_idx ( ) ,
791798 self . frame( ) . instance,
792799 unwinding
793800 ) ;
@@ -895,12 +902,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
895902 Place :: Local { frame, local } => {
896903 let mut allocs = Vec :: new ( ) ;
897904 let mut msg = format ! ( "{:?}" , local) ;
898- if frame != self . cur_frame ( ) {
899- write ! ( msg, " ({} frames up)" , self . cur_frame ( ) - frame) . unwrap ( ) ;
905+ if frame != self . frame_idx ( ) {
906+ write ! ( msg, " ({} frames up)" , self . frame_idx ( ) - frame) . unwrap ( ) ;
900907 }
901908 write ! ( msg, ":" ) . unwrap ( ) ;
902909
903- match self . stack [ frame] . locals [ local] . value {
910+ match self . stack ( ) [ frame] . locals [ local] . value {
904911 LocalValue :: Dead => write ! ( msg, " is dead" ) . unwrap ( ) ,
905912 LocalValue :: Uninitialized => write ! ( msg, " is uninitialized" ) . unwrap ( ) ,
906913 LocalValue :: Live ( Operand :: Indirect ( mplace) ) => match mplace. ptr {
0 commit comments