@@ -258,26 +258,74 @@ end
258258
259259# These getters improve inference since fieldtype(CodeInfo, :linetable)
260260# 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 = Base. IRShow. LineInfoNode
263+ else
264+ const LineTypes = Union{LineNumberNode,Core. LineInfoNode}
265+ end
262266function linetable (arg)
263267 if isa (arg, Frame)
264268 arg = arg. framecode
265269 end
266270 if isa (arg, FrameCode)
267271 arg = arg. src
268272 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
277+ return ci. linetable:: Union{Vector{Core.LineInfoNode},Vector{Any}} # issue #264
278+ end
270279end
271280_linetable (list:: Vector , i:: Integer ) = list[i]:: Union{Expr,LineTypes}
272281function linetable (arg, i:: Integer ; macro_caller:: Bool = false ):: Union{Expr,LineTypes}
273282 lt = linetable (arg)
274- lineinfo = _linetable (lt, i)
275- 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)
283+ @static if VERSION ≥ v " 1.12.0-DEV.173"
284+ # TODO : decode the linetable at this frame efficiently by reimplementing this here
285+ # TODO : get the contextual name from the parent, rather than returning "n/a" (which breaks Cthulhu)
286+ return Base. IRShow. buildLineInfoNode (lt, :var"n/a" , i)[1 ] # ignore all inlining / macro expansion / etc :(
287+ else
288+ lineinfo = _linetable (lt, i)
289+ if macro_caller
290+ while lineinfo isa Core. LineInfoNode && lineinfo. method === Symbol (" macro expansion" ) && lineinfo. inlined_at != 0
291+ lineinfo = _linetable (lt, lineinfo. inlined_at)
292+ end
278293 end
294+ return lineinfo
295+ end
296+ end
297+
298+ @static if VERSION ≥ v " 1.12.0-DEV.173"
299+ function linetable_max (lt:: Core.DebugInfo )
300+ while true
301+ ltnext = lt. linetable
302+ ltnext === nothing && break
303+ lt = ltnext
304+ end
305+ lastline = 0
306+ for k = 0 : typemax (Int)
307+ codeloc = Base. IRShow. getdebugidx (lt, k)
308+ line:: Int = codeloc[1 ]
309+ line < 0 && break
310+ lastline = max (lastline, line)
311+ end
312+ return lastline
313+ end
314+ function codelocs (arg, i:: Integer )
315+ lt = linetable (arg)
316+ codeloc = Base. IRShow. getdebugidx (lt, i)
317+ line:: Int = codeloc[1 ]
318+ line < 0 && return 0 # broken or disabled debug info?
319+ if line == 0 && codeloc[2 ] == 0
320+ return 0 # no line number update
279321 end
280- return lineinfo
322+ return Int (i)
323+ end
324+
325+ else # VERSION ≥ v"1.12.0-DEV.173"
326+
327+ function linetable_max (lt:: Vector )
328+ return getline (lt[end ])
281329end
282330
283331function codelocs (arg)
@@ -289,7 +337,8 @@ function codelocs(arg)
289337 end
290338 return (arg:: CodeInfo ). codelocs:: Vector{Int32}
291339end
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+ end # VERSION ≥ v"1.12.0-DEV.173"
293342
294343function lineoffset (framecode:: FrameCode )
295344 offset = 0
@@ -367,7 +416,7 @@ function codelocation(code::CodeInfo, idx::Int)
367416 idx′ = idx
368417 # look ahead if we are on a meta line
369418 while idx′ < length (code. code)
370- codeloc = codelocs (code)[ idx′]
419+ codeloc = codelocs (code, idx′)
371420 codeloc == 0 || return codeloc
372421 ex = code. code[idx′]
373422 ex === nothing || isexpr (ex, :meta ) || break
@@ -377,7 +426,7 @@ function codelocation(code::CodeInfo, idx::Int)
377426 # if zero, look behind until we find where we last might have had a line
378427 while idx′ > 0
379428 ex = code. code[idx′]
380- codeloc = codelocs (code)[ idx′]
429+ codeloc = codelocs (code, idx′)
381430 codeloc == 0 || return codeloc
382431 idx′ -= 1
383432 end
@@ -390,8 +439,8 @@ function compute_corrected_linerange(method::Method)
390439 offset = line1 - method. line
391440 @assert ! is_generated (method)
392441 src = JuliaInterpreter. get_source (method)
393- lastline = linetable (src)[ end ] :: LineTypes
394- return line1: getline ( lastline) + offset
442+ lastline = linetable_max ( linetable (src))
443+ return line1: lastline + offset
395444end
396445
397446function compute_linerange (framecode)
@@ -508,7 +557,7 @@ function print_framecode(io::IO, framecode::FrameCode; pc=0, range=1:nstatements
508557 ndstmt = ndigits (nstatements (framecode))
509558 lt = linetable (framecode)
510559 offset = lineoffset (framecode)
511- ndline = isempty (lt) ? 0 : ndigits (getline (lt[ end ] ) + offset)
560+ ndline = ndigits (linetable_max (lt) + offset)
512561 nullline = " " ^ ndline
513562 src = copy (framecode. src)
514563 replace_coretypes! (src; rev= true )
0 commit comments