Repository navigation
Require the :leaves and :pop_exceptions of required EnterNodes - #172
Merged
Merged
Conversation
`lines_required!` selects an `EnterNode` through `add_control_flow!`
when its `try` block contains required statements, but nothing selects
the `:leave`s exiting it, since `add_ssa_preds!` follows them only
backward to the `EnterNode`. The selective evaluation then stays in
the exception handler, and in the dynamic scope of the `EnterNode` if
any, for the rest of the frame. For example, requiring both
assignments below evaluates `outside` to `1` instead of `0`:
Base.ScopedValues.@with sv => 1 begin
global inside = sv[]
end
global outside = sv[]
Likewise, an error thrown after a `try` block is caught by the handler
left entered, which runs the statements after the `try` block again.
This change adds the `add_handler_exits!` step, which requires the
`:leave`s and `:pop_exception`s referencing a required `EnterNode`, so
that the selective evaluation exits its handler and scope, and
restores the exception stack after its `catch` block.
On Julia 1.10, `:leave`s count the handlers to exit instead of
referencing the `:enter`s, so only the `:pop_exception`s are required
there. Callers with their own selection loops, e.g. JET and
TestRunner, need to call `add_handler_exits!` to get this fix as well.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aviatesk
added a commit
to aviatesk/JET.jl
that referenced
this pull request
Oct 11, 2026
The statement selection for top-level concretization could select an
`EnterNode`, e.g. of a `try` or `@with` block containing definitions,
for the control flow without the `:leave`s exiting it. The code
concretized after the block then ran within the block's exception
handler and dynamic scope:
sv = Base.ScopedValues.ScopedValue(0)
Base.ScopedValues.@with sv => 1 begin
global inside() = 1
end
@eval outside() = $(sv[]) # defined `outside()` returning `1`
An error thrown by such code was also caught by the handler left
entered, so the code after the block ran again.
`select_dependencies!` now calls `LoweredCodeUtils.add_handler_exits!`,
which selects the `:leave`s and `:pop_exception`s of the selected
`EnterNode`s. Since it was added in LoweredCodeUtils 3.10.1
(JuliaDebug/LoweredCodeUtils.jl#172), this change bumps the
LoweredCodeUtils compat accordingly. The new test in
`test/toplevel/test_virtualprocess.jl` covers the example above.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
lines_required!selects anEnterNodethroughadd_control_flow!when itstryblock contains required statements, but nothing selects the:leaves exiting it, sinceadd_ssa_preds!follows them only backward to theEnterNode. The selective evaluation then stays in the exception handler, and in the dynamic scope of theEnterNodeif any, for the rest of the frame. For example, requiring both assignments below evaluatesoutsideto1instead of0:Likewise, an error thrown after a
tryblock is caught by the handler left entered, which runs the statements after thetryblock again.This change adds the
add_handler_exits!step, which requires the:leaves and:pop_exceptions referencing a requiredEnterNode, so that the selective evaluation exits its handler and scope, and restores the exception stack after itscatchblock.On Julia 1.10,
:leaves count the handlers to exit instead of referencing the:enters, so only the:pop_exceptions are required there. Callers with their own selection loops, e.g. JET and TestRunner, need to calladd_handler_exits!to get this fix as well.