@@ -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+
162177impl < ' 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 {
@@ -630,6 +646,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
630646 self . frame_mut ( ) . locals = locals;
631647 }
632648
649+ M :: after_stack_push ( self ) ?;
633650 info ! ( "ENTERING({}) {}" , self . cur_frame( ) , self . frame( ) . instance) ;
634651
635652 if self . stack . len ( ) > * self . tcx . sess . recursion_limit . get ( ) {
@@ -725,16 +742,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
725742 }
726743
727744 // Cleanup: deallocate all locals that are backed by an allocation.
728- for local in frame. locals {
745+ for local in & frame. locals {
729746 self . deallocate_local ( local. value ) ?;
730747 }
731748
732- if M :: stack_pop ( self , frame. extra , unwinding) ? == StackPopJump :: NoJump {
749+ let return_place = frame. return_place ;
750+ if M :: after_stack_pop ( self , frame, unwinding) ? == StackPopJump :: NoJump {
733751 // The hook already did everything.
734752 // We want to skip the `info!` below, hence early return.
735753 return Ok ( ( ) ) ;
736754 }
737- // Normal return.
755+ // Normal return, figure out where to jump .
738756 if unwinding {
739757 // Follow the unwind edge.
740758 let unwind = next_block. expect ( "Encountered StackPopCleanup::None when unwinding!" ) ;
@@ -743,7 +761,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
743761 // Follow the normal return edge.
744762 // Validate the return value. Do this after deallocating so that we catch dangling
745763 // references.
746- if let Some ( return_place) = frame . return_place {
764+ if let Some ( return_place) = return_place {
747765 if M :: enforce_validity ( self ) {
748766 // Data got changed, better make sure it matches the type!
749767 // It is still possible that the return place held invalid data while
0 commit comments