@@ -219,16 +219,29 @@ const CACHE_MODE_GLOBAL = 0x01 << 0 # cached globally, optimization required
219
219
const CACHE_MODE_LOCAL = 0x01 << 1 # cached locally, optimization required
220
220
const CACHE_MODE_VOLATILE = 0x01 << 2 # not cached, optimization required
221
221
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
223
226
exct
224
227
scopet
225
228
const enter_idx:: Int
226
229
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
228
239
end
240
+ SimpleHandler (:: EnterNode , pc:: Int ) = SimpleHandler (pc)
241
+ get_enter_idx_impl ((; enter_idx):: SimpleHandler ) = enter_idx
229
242
230
- struct HandlerInfo
231
- handlers:: Vector{TryCatchFrame }
243
+ struct HandlerInfo{T <: Handler }
244
+ handlers:: Vector{T }
232
245
handler_at:: Vector{Tuple{Int,Int}} # tuple of current (handler, exception stack) value at the pc
233
246
end
234
247
@@ -261,7 +274,7 @@ mutable struct InferenceState
261
274
currbb:: Int
262
275
currpc:: Int
263
276
ip:: BitSet #= TODO BoundedMinPrioritySet=# # current active instruction pointers
264
- handler_info:: Union{Nothing,HandlerInfo}
277
+ handler_info:: Union{Nothing,HandlerInfo{TryCatchFrame} }
265
278
ssavalue_uses:: Vector{BitSet} # ssavalue sparsity and restart info
266
279
# TODO : Could keep this sparsely by doing structural liveness analysis ahead of time.
267
280
bb_vartables:: Vector{Union{Nothing,VarTable}} # nothing if not analyzed yet
@@ -318,7 +331,7 @@ mutable struct InferenceState
318
331
319
332
currbb = currpc = 1
320
333
ip = BitSet (1 ) # TODO BitSetBoundedMinPrioritySet(1)
321
- handler_info = compute_trycatch (code)
334
+ handler_info = ComputeTryCatch {TryCatchFrame} () (code)
322
335
nssavalues = src. ssavaluetypes:: Int
323
336
ssavalue_uses = find_ssavalue_uses (code, nssavalues)
324
337
nstmts = length (code)
@@ -421,10 +434,16 @@ is_inferred(result::InferenceResult) = result.result !== nothing
421
434
422
435
was_reached (sv:: InferenceState , pc:: Int ) = sv. ssavaluetypes[pc] != = NOT_FOUND
423
436
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)
425
443
426
444
"""
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}()
428
447
429
448
Given the code of a function, compute, at every statement, the current
430
449
try/catch handler, and the current exception stack top. This function returns
@@ -433,9 +452,9 @@ a tuple of:
433
452
1. `handler_info.handler_at`: A statement length vector of tuples
434
453
`(catch_handler, exception_stack)`, which are indices into `handlers`
435
454
436
- 2. `handler_info.handlers`: A `TryCatchFrame ` vector of handlers
455
+ 2. `handler_info.handlers`: A `Handler ` vector of handlers
437
456
"""
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
439
458
# The goal initially is to record the frame like this for the state at exit:
440
459
# 1: (enter 3) # == 0
441
460
# 3: (expr) # == 1
@@ -454,10 +473,10 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi
454
473
stmt = code[pc]
455
474
if isa (stmt, EnterNode)
456
475
(;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)
458
477
l = stmt. catch_dest
459
478
(bbs != = nothing ) && (l = first (bbs[l]. stmts))
460
- push! (handlers, TryCatchFrame (Bottom, isdefined ( stmt, :scope ) ? Bottom : nothing , pc))
479
+ push! (handlers, Handler ( stmt, pc))
461
480
handler_id = length (handlers)
462
481
handler_at[pc + 1 ] = (handler_id, 0 )
463
482
push! (ip, pc + 1 )
@@ -526,7 +545,7 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi
526
545
end
527
546
cur_hand = cur_stacks[1 ]
528
547
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 ]
530
549
end
531
550
cur_stacks = (cur_hand, cur_stacks[2 ])
532
551
cur_stacks == (0 , 0 ) && break
0 commit comments