Skip to content

Commit

Permalink
Fix returning from LEAVE to surrounding scope
Browse files Browse the repository at this point in the history
When a LEAVE phaser is run during an unwind, there is no valid
return_address set in the LEAVE phasers caller frame. (It return_address is
actually set to cur_op which is still the one that started the unwind in
some unrelated frame.) Thus when a `return` in a LEAVE happens, the
handler of the outer frame is missed, because `search_frame_handlers_lex()`
validates that the `return_address` lies in the handlers area. Luckily
there is a flag set on the LEAVE's outer frame:
MVM_FRAME_FLAG_EXIT_HAND_RUN. We can simply check for that flag and ignore
the frame handlers area. This is fine to do, because frames that have an
exit handler attached can not be inlined. This fixes:

    sub s() {
        LEAVE return 5;
        return 7;
    }
    s()

which before this fix printed

    Attempt to return outside of any Routine
    in sub s at leave-bug.raku line 2
    in block at leave-bug.raku line 5

Fixes MoarVM#1784
  • Loading branch information
patrickbkr committed Jan 16, 2024
1 parent fde6796 commit 03f2ea8
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/core/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ static MVMint32 search_frame_handlers_lex(MVMThreadContext *tc, MVMFrame *f,
}
if (skipping || !handler_can_handle(f, fh, cat, payload))
continue;
if (pc >= fh->start_offset &&
pc <= fh->end_offset &&
if (((pc >= fh->start_offset && pc <= fh->end_offset) ||
f->flags == MVM_FRAME_FLAG_EXIT_HAND_RUN) &&
!in_handler_stack(tc, fh, f)) {
if (skipping && f->static_info->body.is_thunk)
return 0;
Expand Down

0 comments on commit 03f2ea8

Please sign in to comment.