@@ -258,38 +258,88 @@ end
258
258
259
259
# These getters improve inference since fieldtype(CodeInfo, :linetable)
260
260
# and fieldtype(CodeInfo, :codelocs) are both Any
261
- const LineTypes = Union{LineNumberNode,Core. LineInfoNode}
261
+ @static if VERSION ≥ v " 1.12.0-DEV.173"
262
+ const LineTypes = Union{LineNumberNode,Base. IRShow. LineInfoNode}
263
+ else
264
+ const LineTypes = Union{LineNumberNode,Core. LineInfoNode}
265
+ end
262
266
function linetable (arg)
263
267
if isa (arg, Frame)
264
268
arg = arg. framecode
265
269
end
266
270
if isa (arg, FrameCode)
267
271
arg = arg. src
268
272
end
269
- return (arg:: CodeInfo ). linetable:: Union{Vector{Core.LineInfoNode},Vector{Any}} # issue #264
273
+ ci = arg:: CodeInfo
274
+ @static if VERSION ≥ v " 1.12.0-DEV.173"
275
+ return ci. debuginfo
276
+ else # VERSION < v"1.12.0-DEV.173"
277
+ return ci. linetable:: Union{Vector{Core.LineInfoNode},Vector{Any}} # issue #264
278
+ end # @static if
270
279
end
271
- _linetable (list:: Vector , i:: Integer ) = list[i]:: Union{Expr,LineTypes}
272
280
function linetable (arg, i:: Integer ; macro_caller:: Bool = false ):: Union{Expr,LineTypes}
273
281
lt = linetable (arg)
274
- lineinfo = _linetable (lt, i)
282
+ @static if VERSION ≥ v " 1.12.0-DEV.173"
283
+ # TODO : decode the linetable at this frame efficiently by reimplementing this here
284
+ # TODO : get the contextual name from the parent, rather than returning "n/a" (which breaks Cthulhu)
285
+ return Base. IRShow. buildLineInfoNode (lt, :var"n/a" , i)[1 ] # ignore all inlining / macro expansion / etc :(
286
+ else # VERSION < v"1.12.0-DEV.173"
287
+ lin = lt[i]:: Union{Expr,LineTypes}
275
288
if macro_caller
276
- while lineinfo isa Core. LineInfoNode && lineinfo . method === Symbol (" macro expansion" ) && lineinfo . inlined_at != 0
277
- lineinfo = _linetable (lt, lineinfo . inlined_at)
289
+ while lin isa Core. LineInfoNode && lin . method === Symbol (" macro expansion" ) && lin . inlined_at != 0
290
+ lin = lt[lin . inlined_at] :: Union{Expr,LineTypes}
278
291
end
279
292
end
280
- return lineinfo
293
+ return lin
294
+ end # @static if
295
+ end
296
+
297
+ @static if VERSION ≥ v " 1.12.0-DEV.173"
298
+
299
+ function getlastline (arg)
300
+ debuginfo = linetable (arg)
301
+ while true
302
+ ltnext = debuginfo. linetable
303
+ ltnext === nothing && break
304
+ debuginfo = ltnext
305
+ end
306
+ lastline = 0
307
+ for k = 0 : typemax (Int)
308
+ codeloc = Core. Compiler. getdebugidx (debuginfo, k)
309
+ line:: Int = codeloc[1 ]
310
+ line < 0 && break
311
+ lastline = max (lastline, line)
312
+ end
313
+ return lastline
314
+ end
315
+ function codelocs (arg, i:: Integer )
316
+ debuginfo = linetable (arg)
317
+ codeloc = Core. Compiler. getdebugidx (debuginfo, i)
318
+ line:: Int = codeloc[1 ]
319
+ line < 0 && return 0 # broken or disabled debug info?
320
+ if line == 0 && codeloc[2 ] == 0
321
+ return 0 # no line number update
322
+ end
323
+ return i
281
324
end
282
325
326
+ else # VERSION < v"1.12.0-DEV.173"
327
+
328
+ getfirstline (arg) = getline (linetable (arg)[begin ])
329
+ getlastline (arg) = getline (linetable (arg)[end ])
283
330
function codelocs (arg)
284
331
if isa (arg, Frame)
285
332
arg = arg. framecode
286
333
end
287
334
if isa (arg, FrameCode)
288
335
arg = arg. src
289
336
end
290
- return (arg:: CodeInfo ). codelocs:: Vector{Int32}
337
+ ci = arg:: CodeInfo
338
+ return ci. codelocs
291
339
end
292
- codelocs (arg, i:: Integer ) = codelocs (arg)[i] # for consistency with linetable (but no extra benefit here)
340
+ codelocs (arg, i:: Integer ) = codelocs (arg)[i]
341
+
342
+ end # @static if
293
343
294
344
function lineoffset (framecode:: FrameCode )
295
345
offset = 0
@@ -302,9 +352,9 @@ function lineoffset(framecode::FrameCode)
302
352
end
303
353
304
354
function getline (ln:: Union{LineTypes,Expr} )
305
- _getline (ln:: LineTypes ) = ln. line
306
- _getline (ln:: Expr ) = ln. args[1 ] # assuming ln.head === :line
307
- return Int ( _getline (ln)) :: Int
355
+ _getline (ln:: LineTypes ) = Int ( ln. line)
356
+ _getline (ln:: Expr ) = ln. args[1 ]:: Int # assuming ln.head === :line
357
+ return _getline (ln)
308
358
end
309
359
function getfile (ln:: Union{LineTypes,Expr} )
310
360
_getfile (ln:: LineTypes ) = ln. file:: Symbol
@@ -367,7 +417,7 @@ function codelocation(code::CodeInfo, idx::Int)
367
417
idx′ = idx
368
418
# look ahead if we are on a meta line
369
419
while idx′ < length (code. code)
370
- codeloc = codelocs (code)[ idx′]
420
+ codeloc = codelocs (code, idx′)
371
421
codeloc == 0 || return codeloc
372
422
ex = code. code[idx′]
373
423
ex === nothing || isexpr (ex, :meta ) || break
@@ -377,7 +427,7 @@ function codelocation(code::CodeInfo, idx::Int)
377
427
# if zero, look behind until we find where we last might have had a line
378
428
while idx′ > 0
379
429
ex = code. code[idx′]
380
- codeloc = codelocs (code)[ idx′]
430
+ codeloc = codelocs (code, idx′)
381
431
codeloc == 0 || return codeloc
382
432
idx′ -= 1
383
433
end
@@ -390,13 +440,11 @@ function compute_corrected_linerange(method::Method)
390
440
offset = line1 - method. line
391
441
@assert ! is_generated (method)
392
442
src = JuliaInterpreter. get_source (method)
393
- lastline = linetable (src)[ end ] :: LineTypes
394
- return line1: getline ( lastline) + offset
443
+ lastline = getlastline (src)
444
+ return line1: lastline + offset
395
445
end
396
446
397
- function compute_linerange (framecode)
398
- getline (linetable (framecode, 1 )): getline (last (linetable (framecode)))
399
- end
447
+ compute_linerange (framecode) = getfirstline (framecode): getlastline (framecode)
400
448
401
449
function statementnumbers (framecode:: FrameCode , line:: Integer , file:: Symbol )
402
450
# Check to see if this framecode really contains that line. Methods that fill in a default positional argument,
@@ -434,7 +482,6 @@ function statementnumbers(framecode::FrameCode, line::Integer, file::Symbol)
434
482
return stmtidxs
435
483
end
436
484
437
-
438
485
# If the exact line number does not exist in the line table, take the one that is closest after that line
439
486
# restricted to the line range of the current scope.
440
487
scope = framecode. scope
@@ -506,9 +553,7 @@ breakpointchar(framecode, stmtidx) =
506
553
function print_framecode (io:: IO , framecode:: FrameCode ; pc= 0 , range= 1 : nstatements (framecode), kwargs... )
507
554
iscolor = get (io, :color , false )
508
555
ndstmt = ndigits (nstatements (framecode))
509
- lt = linetable (framecode)
510
- offset = lineoffset (framecode)
511
- ndline = isempty (lt) ? 0 : ndigits (getline (lt[end ]) + offset)
556
+ ndline = ndigits (getlastline (framecode) + lineoffset (framecode))
512
557
nullline = " " ^ ndline
513
558
src = copy (framecode. src)
514
559
replace_coretypes! (src; rev= true )
@@ -759,12 +804,11 @@ function Base.StackTraces.StackFrame(frame::Frame)
759
804
Base. StackFrame (
760
805
fname,
761
806
Symbol (getfile (frame)),
762
- @something (linenumber (frame), getline ( linetable ( frame, 1 ) )),
807
+ @something (linenumber (frame), getfirstline ( frame)),
763
808
mi,
764
809
false ,
765
810
false ,
766
- C_NULL
767
- )
811
+ C_NULL )
768
812
end
769
813
770
814
function Base. show_backtrace (io:: IO , frame:: Frame )
0 commit comments