-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
return
in LEAVE
misses handler in directly surounding scope
#1784
Comments
patrickbkr
added a commit
to patrickbkr/MoarVM
that referenced
this issue
Jan 16, 2024
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
Is this PR obsolete now? |
@lizmat This is an issue, not a PR. ;-) |
Duh :-) |
patrickbkr
added a commit
to patrickbkr/MoarVM
that referenced
this issue
May 28, 2024
When a LEAVE phaser is run during an unwind, there is no valid return_address set in the LEAVE phasers outer frame. (It's return_address is actually set to interp_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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
gives
I've dug into this a bit.
From what I've understood, the
return 7
starts an unwind. The exit handler ofs()
is found and called viaMVM_frame_dispatch_from_c
. That in turn setscur_frame->return_address
to*(tc->interp_cur_op)
which still points to someplace in&return
. Thereturn 5
then searches for an applicable handler in the call stack, but misses the one ofs()
becausecur_frame->return_address
is then usually outside of the handlers corresponding area.The best idea I could come up with to fix this is setting a sane
cur_frame->return_address
before calling the exit handler. But I don't know what a sane value could be. The value will not be used to return to (we already have a handler we are unwinding to), but needs to meetpc >= fh->start_offset && pc <= fh->end_offset
(that's in exceptions.c search_frame_handlers_lex). I think theLEAVE
doesn't even have a representation in the bytecode.Hm. It's hacky, but something like the following could do the trick:
I do hope for a better idea though.
The text was updated successfully, but these errors were encountered: