@@ -258,38 +258,88 @@ 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 = Union{LineNumberNode,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 # VERSION < v"1.12.0-DEV.173"
277+ return ci. linetable:: Union{Vector{Core.LineInfoNode},Vector{Any}} # issue #264
278+ end # @static if
270279end
271- _linetable (list:: Vector , i:: Integer ) = list[i]:: Union{Expr,LineTypes}
272280function linetable (arg, i:: Integer ; macro_caller:: Bool = false ):: Union{Expr,LineTypes}
273281 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}
275288 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}
278291 end
279292 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
281324end
282325
326+ else # VERSION < v"1.12.0-DEV.173"
327+
328+ getfirstline (arg) = getline (linetable (arg)[begin ])
329+ getlastline (arg) = getline (linetable (arg)[end ])
283330function codelocs (arg)
284331 if isa (arg, Frame)
285332 arg = arg. framecode
286333 end
287334 if isa (arg, FrameCode)
288335 arg = arg. src
289336 end
290- return (arg:: CodeInfo ). codelocs:: Vector{Int32}
337+ ci = arg:: CodeInfo
338+ return ci. codelocs
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+
342+ end # @static if
293343
294344function lineoffset (framecode:: FrameCode )
295345 offset = 0
@@ -302,9 +352,9 @@ function lineoffset(framecode::FrameCode)
302352end
303353
304354function 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)
308358end
309359function getfile (ln:: Union{LineTypes,Expr} )
310360 _getfile (ln:: LineTypes ) = ln. file:: Symbol
@@ -367,7 +417,7 @@ function codelocation(code::CodeInfo, idx::Int)
367417 idx′ = idx
368418 # look ahead if we are on a meta line
369419 while idx′ < length (code. code)
370- codeloc = codelocs (code)[ idx′]
420+ codeloc = codelocs (code, idx′)
371421 codeloc == 0 || return codeloc
372422 ex = code. code[idx′]
373423 ex === nothing || isexpr (ex, :meta ) || break
@@ -377,7 +427,7 @@ function codelocation(code::CodeInfo, idx::Int)
377427 # if zero, look behind until we find where we last might have had a line
378428 while idx′ > 0
379429 ex = code. code[idx′]
380- codeloc = codelocs (code)[ idx′]
430+ codeloc = codelocs (code, idx′)
381431 codeloc == 0 || return codeloc
382432 idx′ -= 1
383433 end
@@ -390,13 +440,11 @@ function compute_corrected_linerange(method::Method)
390440 offset = line1 - method. line
391441 @assert ! is_generated (method)
392442 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
395445end
396446
397- function compute_linerange (framecode)
398- getline (linetable (framecode, 1 )): getline (last (linetable (framecode)))
399- end
447+ compute_linerange (framecode) = getfirstline (framecode): getlastline (framecode)
400448
401449function statementnumbers (framecode:: FrameCode , line:: Integer , file:: Symbol )
402450 # 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)
434482 return stmtidxs
435483 end
436484
437-
438485 # If the exact line number does not exist in the line table, take the one that is closest after that line
439486 # restricted to the line range of the current scope.
440487 scope = framecode. scope
@@ -506,9 +553,7 @@ breakpointchar(framecode, stmtidx) =
506553function print_framecode (io:: IO , framecode:: FrameCode ; pc= 0 , range= 1 : nstatements (framecode), kwargs... )
507554 iscolor = get (io, :color , false )
508555 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))
512557 nullline = " " ^ ndline
513558 src = copy (framecode. src)
514559 replace_coretypes! (src; rev= true )
@@ -759,12 +804,11 @@ function Base.StackTraces.StackFrame(frame::Frame)
759804 Base. StackFrame (
760805 fname,
761806 Symbol (getfile (frame)),
762- @something (linenumber (frame), getline ( linetable ( frame, 1 ) )),
807+ @something (linenumber (frame), getfirstline ( frame)),
763808 mi,
764809 false ,
765810 false ,
766- C_NULL
767- )
811+ C_NULL )
768812end
769813
770814function Base. show_backtrace (io:: IO , frame:: Frame )
0 commit comments