@@ -219,16 +219,29 @@ const CACHE_MODE_GLOBAL = 0x01 << 0 # cached globally, optimization required
219219const CACHE_MODE_LOCAL = 0x01 << 1 # cached locally, optimization required
220220const CACHE_MODE_VOLATILE = 0x01 << 2 # not cached, optimization required
221221
222- mutable struct TryCatchFrame
222+ abstract type Handler end
223+ get_enter_idx (handler:: Handler ) = get_enter_idx_impl (handler):: Int
224+
225+ mutable struct TryCatchFrame <: Handler
223226 exct
224227 scopet
225228 const enter_idx:: Int
226229 scope_uses:: Vector{Int}
227- TryCatchFrame (@nospecialize (exct), @nospecialize (scopet), enter_idx:: Int ) = new (exct, scopet, enter_idx)
230+ TryCatchFrame (@nospecialize (exct), @nospecialize (scopet), enter_idx:: Int ) =
231+ new (exct, scopet, enter_idx)
232+ end
233+ TryCatchFrame (stmt:: EnterNode , pc:: Int ) =
234+ TryCatchFrame (Bottom, isdefined (stmt, :scope ) ? Bottom : nothing , pc)
235+ get_enter_idx_impl ((; enter_idx):: TryCatchFrame ) = enter_idx
236+
237+ struct SimpleHandler <: Handler
238+ enter_idx:: Int
228239end
240+ SimpleHandler (:: EnterNode , pc:: Int ) = SimpleHandler (pc)
241+ get_enter_idx_impl ((; enter_idx):: SimpleHandler ) = enter_idx
229242
230- struct HandlerInfo
231- handlers:: Vector{TryCatchFrame }
243+ struct HandlerInfo{T <: Handler }
244+ handlers:: Vector{T }
232245 handler_at:: Vector{Tuple{Int,Int}} # tuple of current (handler, exception stack) value at the pc
233246end
234247
@@ -261,7 +274,7 @@ mutable struct InferenceState
261274 currbb:: Int
262275 currpc:: Int
263276 ip:: BitSet #= TODO BoundedMinPrioritySet=# # current active instruction pointers
264- handler_info:: Union{Nothing,HandlerInfo}
277+ handler_info:: Union{Nothing,HandlerInfo{TryCatchFrame} }
265278 ssavalue_uses:: Vector{BitSet} # ssavalue sparsity and restart info
266279 # TODO : Could keep this sparsely by doing structural liveness analysis ahead of time.
267280 bb_vartables:: Vector{Union{Nothing,VarTable}} # nothing if not analyzed yet
@@ -318,7 +331,7 @@ mutable struct InferenceState
318331
319332 currbb = currpc = 1
320333 ip = BitSet (1 ) # TODO BitSetBoundedMinPrioritySet(1)
321- handler_info = compute_trycatch (code)
334+ handler_info = ComputeTryCatch {TryCatchFrame} () (code)
322335 nssavalues = src. ssavaluetypes:: Int
323336 ssavalue_uses = find_ssavalue_uses (code, nssavalues)
324337 nstmts = length (code)
@@ -421,10 +434,16 @@ is_inferred(result::InferenceResult) = result.result !== nothing
421434
422435was_reached (sv:: InferenceState , pc:: Int ) = sv. ssavaluetypes[pc] != = NOT_FOUND
423436
424- compute_trycatch (ir:: IRCode ) = compute_trycatch (ir. stmts. stmt, ir. cfg. blocks)
437+ struct ComputeTryCatch{T<: Handler } end
438+
439+ const compute_trycatch = ComputeTryCatch {SimpleHandler} ()
440+
441+ (compute_trycatch:: ComputeTryCatch{SimpleHandler} )(ir:: IRCode ) =
442+ compute_trycatch (ir. stmts. stmt, ir. cfg. blocks)
425443
426444"""
427- compute_trycatch(code, [, bbs]) -> handler_info::Union{Nothing,HandlerInfo}
445+ (::ComputeTryCatch{Handler})(code, [, bbs]) -> handler_info::Union{Nothing,HandlerInfo{Handler}}
446+ const compute_trycatch = ComputeTryCatch{SimpleHandler}()
428447
429448Given the code of a function, compute, at every statement, the current
430449try/catch handler, and the current exception stack top. This function returns
@@ -433,9 +452,9 @@ a tuple of:
433452 1. `handler_info.handler_at`: A statement length vector of tuples
434453 `(catch_handler, exception_stack)`, which are indices into `handlers`
435454
436- 2. `handler_info.handlers`: A `TryCatchFrame ` vector of handlers
455+ 2. `handler_info.handlers`: A `Handler ` vector of handlers
437456"""
438- function compute_trycatch ( code:: Vector{Any} , bbs:: Union{Vector{BasicBlock},Nothing} = nothing )
457+ function ( :: ComputeTryCatch{Handler} )( code:: Vector{Any} , bbs:: Union{Vector{BasicBlock},Nothing} = nothing ) where Handler
439458 # The goal initially is to record the frame like this for the state at exit:
440459 # 1: (enter 3) # == 0
441460 # 3: (expr) # == 1
@@ -454,10 +473,10 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi
454473 stmt = code[pc]
455474 if isa (stmt, EnterNode)
456475 (;handlers, handler_at) = handler_info =
457- (handler_info === nothing ? HandlerInfo (TryCatchFrame [], fill ((0 , 0 ), n)) : handler_info)
476+ (handler_info === nothing ? HandlerInfo {Handler} (Handler [], fill ((0 , 0 ), n)) : handler_info)
458477 l = stmt. catch_dest
459478 (bbs != = nothing ) && (l = first (bbs[l]. stmts))
460- push! (handlers, TryCatchFrame (Bottom, isdefined ( stmt, :scope ) ? Bottom : nothing , pc))
479+ push! (handlers, Handler ( stmt, pc))
461480 handler_id = length (handlers)
462481 handler_at[pc + 1 ] = (handler_id, 0 )
463482 push! (ip, pc + 1 )
@@ -526,7 +545,7 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi
526545 end
527546 cur_hand = cur_stacks[1 ]
528547 for i = 1 : l
529- cur_hand = handler_at[handlers[cur_hand]. enter_idx ][1 ]
548+ cur_hand = handler_at[get_enter_idx ( handlers[cur_hand]) ][1 ]
530549 end
531550 cur_stacks = (cur_hand, cur_stacks[2 ])
532551 cur_stacks == (0 , 0 ) && break
0 commit comments