@@ -553,6 +553,37 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
553
553
}
554
554
}
555
555
556
+ /// Jump to the given block.
557
+ #[ inline]
558
+ pub fn go_to_block ( & mut self , target : mir:: BasicBlock ) {
559
+ let frame = self . frame_mut ( ) ;
560
+ frame. block = Some ( target) ;
561
+ frame. stmt = 0 ;
562
+ }
563
+
564
+ /// *Return* to the given `target` basic block.
565
+ /// Do *not* use for unwinding! Use `unwind_to_block` instead.
566
+ ///
567
+ /// If `target` is `None`, that indicates the function cannot return, so we raise UB.
568
+ pub fn return_to_block ( & mut self , target : Option < mir:: BasicBlock > ) -> InterpResult < ' tcx > {
569
+ if let Some ( target) = target {
570
+ Ok ( self . go_to_block ( target) )
571
+ } else {
572
+ throw_ub ! ( Unreachable )
573
+ }
574
+ }
575
+
576
+ /// *Unwind* to the given `target` basic block.
577
+ /// Do *not* use for returning! Use `return_to_block` instead.
578
+ ///
579
+ /// If `target` is `None`, that indicates the function does not need cleanup during
580
+ /// unwinding, and we will just keep propagating that upwards.
581
+ pub fn unwind_to_block ( & mut self , target : Option < mir:: BasicBlock > ) {
582
+ let frame = self . frame_mut ( ) ;
583
+ frame. block = target;
584
+ frame. stmt = 0 ;
585
+ }
586
+
556
587
/// Pops the current frame from the stack, deallocating the
557
588
/// memory for allocated locals.
558
589
///
@@ -628,10 +659,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
628
659
if cur_unwinding {
629
660
// Follow the unwind edge.
630
661
let unwind = next_block. expect ( "Encounted StackPopCleanup::None when unwinding!" ) ;
631
- let next_frame = self . frame_mut ( ) ;
632
- // If `unwind` is `None`, we'll leave that function immediately again.
633
- next_frame. block = unwind;
634
- next_frame. stmt = 0 ;
662
+ self . unwind_to_block ( unwind) ;
635
663
} else {
636
664
// Follow the normal return edge.
637
665
// Validate the return value. Do this after deallocating so that we catch dangling
@@ -658,7 +686,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
658
686
659
687
// Jump to new block -- *after* validation so that the spans make more sense.
660
688
if let Some ( ret) = next_block {
661
- self . goto_block ( ret) ?;
689
+ self . return_to_block ( ret) ?;
662
690
}
663
691
}
664
692
0 commit comments