Skip to content

Commit

Permalink
ir: Add version of compute_trycatch for IRCode (JuliaLang#54035)
Browse files Browse the repository at this point in the history
For ir transform passes that need to be aware of current_scope.
Currently no users in Base, but available for external absint.

---------

Co-authored-by: Shuhei Kadowaki <[email protected]>
  • Loading branch information
Keno and aviatesk authored Apr 11, 2024
1 parent 630f754 commit dc8857a
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion base/compiler/inferencestate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,21 @@ is_inferred(result::InferenceResult) = result.result !== nothing

was_reached(sv::InferenceState, pc::Int) = sv.ssavaluetypes[pc] !== NOT_FOUND

function compute_trycatch(code::Vector{Any}, ip::BitSet)
compute_trycatch(ir::IRCode, ip::BitSet) = compute_trycatch(ir.stmts.stmt, ip, ir.cfg.blocks)

"""
compute_trycatch(code, ip [, bbs]) -> (handler_at, handlers)
Given the code of a function, compute, at every statement, the current
try/catch handler, and the current exception stack top. This function returns
a tuple of:
1. `handler_at`: A statement length vector of tuples `(catch_handler, exception_stack)`,
which are indices into `handlers`
2. `handlers`: A `TryCatchFrame` vector of handlers
"""
function compute_trycatch(code::Vector{Any}, ip::BitSet, bbs::Union{Vector{BasicBlock}, Nothing}=nothing)
# The goal initially is to record the frame like this for the state at exit:
# 1: (enter 3) # == 0
# 3: (expr) # == 1
Expand All @@ -388,6 +402,7 @@ function compute_trycatch(code::Vector{Any}, ip::BitSet)
stmt = code[pc]
if isa(stmt, EnterNode)
l = stmt.catch_dest
(bbs !== nothing) && (l = first(bbs[l].stmts))
push!(handlers, TryCatchFrame(Bottom, isdefined(stmt, :scope) ? Bottom : nothing, pc))
handler_id = length(handlers)
handler_at[pc + 1] = (handler_id, 0)
Expand All @@ -412,8 +427,10 @@ function compute_trycatch(code::Vector{Any}, ip::BitSet)
stmt = code[pc]
if isa(stmt, GotoNode)
pc´ = stmt.label
(bbs !== nothing) && (pc´ = first(bbs[pc´].stmts))
elseif isa(stmt, GotoIfNot)
l = stmt.dest::Int
(bbs !== nothing) && (l = first(bbs[l].stmts))
if handler_at[l] != cur_stacks
@assert handler_at[l][1] == 0 || handler_at[l][1] == cur_stacks[1] "unbalanced try/catch"
handler_at[l] = cur_stacks
Expand All @@ -424,6 +441,7 @@ function compute_trycatch(code::Vector{Any}, ip::BitSet)
break
elseif isa(stmt, EnterNode)
l = stmt.catch_dest
(bbs !== nothing) && (l = first(bbs[l].stmts))
# We assigned a handler number above. Here we just merge that
# with out current handler information.
if l != 0
Expand Down

0 comments on commit dc8857a

Please sign in to comment.