@@ -553,6 +553,37 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
553553 }
554554 }
555555
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+
556587 /// Pops the current frame from the stack, deallocating the
557588 /// memory for allocated locals.
558589 ///
@@ -628,10 +659,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
628659 if cur_unwinding {
629660 // Follow the unwind edge.
630661 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) ;
635663 } else {
636664 // Follow the normal return edge.
637665 // 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> {
658686
659687 // Jump to new block -- *after* validation so that the spans make more sense.
660688 if let Some ( ret) = next_block {
661- self . goto_block ( ret) ?;
689+ self . return_to_block ( ret) ?;
662690 }
663691 }
664692
0 commit comments