@@ -159,6 +159,21 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
159
159
}
160
160
}
161
161
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
+
162
177
impl < ' mir , ' tcx , Tag , Extra > Frame < ' mir , ' tcx , Tag , Extra > {
163
178
/// Return the `SourceInfo` of the current instruction.
164
179
pub fn current_source_info ( & self ) -> Option < mir:: SourceInfo > {
@@ -586,8 +601,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
586
601
:: log_settings:: settings ( ) . indentation += 1 ;
587
602
588
603
// 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 {
591
605
body,
592
606
block : Some ( mir:: START_BLOCK ) ,
593
607
return_to_block,
@@ -597,8 +611,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
597
611
locals : IndexVec :: new ( ) ,
598
612
instance,
599
613
stmt : 0 ,
600
- extra,
601
- } ) ;
614
+ extra : ( ) ,
615
+ } ;
616
+ let frame = M :: init_frame_extra ( self , pre_frame) ?;
617
+ self . stack . push ( frame) ;
602
618
603
619
// don't allocate at all for trivial constants
604
620
if body. local_decls . len ( ) > 1 {
@@ -630,6 +646,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
630
646
self . frame_mut ( ) . locals = locals;
631
647
}
632
648
649
+ M :: after_stack_push ( self ) ?;
633
650
info ! ( "ENTERING({}) {}" , self . cur_frame( ) , self . frame( ) . instance) ;
634
651
635
652
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> {
725
742
}
726
743
727
744
// Cleanup: deallocate all locals that are backed by an allocation.
728
- for local in frame. locals {
745
+ for local in & frame. locals {
729
746
self . deallocate_local ( local. value ) ?;
730
747
}
731
748
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 {
733
751
// The hook already did everything.
734
752
// We want to skip the `info!` below, hence early return.
735
753
return Ok ( ( ) ) ;
736
754
}
737
- // Normal return.
755
+ // Normal return, figure out where to jump .
738
756
if unwinding {
739
757
// Follow the unwind edge.
740
758
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> {
743
761
// Follow the normal return edge.
744
762
// Validate the return value. Do this after deallocating so that we catch dangling
745
763
// references.
746
- if let Some ( return_place) = frame . return_place {
764
+ if let Some ( return_place) = return_place {
747
765
if M :: enforce_validity ( self ) {
748
766
// Data got changed, better make sure it matches the type!
749
767
// It is still possible that the return place held invalid data while
0 commit comments