Skip to content

Commit 09c4fed

Browse files
vtjnashaviatesk
andauthored
changes to adapt to compressed line table format (#526)
Co-authored-by: Shuhei Kadowaki <aviatesk@gmail.com>
1 parent f3dd6cd commit 09c4fed

5 files changed

Lines changed: 96 additions & 34 deletions

File tree

TypedSyntax/src/node.jl

Lines changed: 79 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ function TypedSyntaxNode(rootnode::SyntaxNode, src::CodeInfo, mappings, symtyps)
7676
# There may be ambiguous assignments back to the source; preserve just the unambiguous ones
7777
node2ssa = IdDict{SyntaxNode,Int}(only(list) => i for (i, list) in pairs(mappings) if length(list) == 1)
7878
# Copy `rootnode`, adding type annotations
79-
trootnode = TypedSyntaxNode(nothing, nothing, TypedSyntaxData(rootnode.data::SyntaxData, src, gettyp(node2ssa, rootnode, src)))
79+
typ = gettyp(node2ssa, rootnode, src)
80+
trootnode = TypedSyntaxNode(nothing, nothing, TypedSyntaxData(rootnode.data::SyntaxData, src, typ))
8081
addchildren!(trootnode, rootnode, src, node2ssa, symtyps, mappings)
8182
# Add argtyps to signature
8283
fnode = get_function_def(trootnode)
@@ -439,6 +440,76 @@ function collect_symbol_nodes!(symlocs::AbstractDict, node)
439440
return symlocs
440441
end
441442

443+
## utility function to extract the line number at a particular program counter (ignoring inlining).
444+
## return <= 0 if there is no line number change caused by this statement
445+
@static if VERSION v"1.12.0-DEV.173"
446+
function getline(lt::Core.DebugInfo, i::Int)
447+
while true
448+
codeloc = Base.IRShow.getdebugidx(lt, i)
449+
line::Int = codeloc[1]
450+
line < 0 && return 0 # broken or disabled debug info?
451+
line == 0 && return 0 # no line number update (though maybe inlining changed)
452+
ltnext = lt.linetable
453+
if ltnext === nothing
454+
return line
455+
end
456+
i = line
457+
lt = ltnext
458+
end
459+
end
460+
function getnextline(lt::Core.DebugInfo, i::Int, Δline)
461+
while true
462+
codeloc = Base.IRShow.getdebugidx(lt, i)
463+
line::Int = codeloc[1]
464+
line < 0 && return typemax(Int) # broken or disabled debug info?
465+
if line == 0
466+
i += 1
467+
continue
468+
end
469+
ltnext = lt.linetable
470+
if ltnext === nothing
471+
break
472+
end
473+
i = line
474+
lt = ltnext
475+
end
476+
# now that we have line i and a list of all lines with code on them lt
477+
# find the next largest line number in this list greater than i, or return typemax(Int)
478+
j = i+1
479+
currline = Base.IRShow.getdebugidx(lt, i)[1]
480+
while j typemax(Int)
481+
codeloc = Base.IRShow.getdebugidx(lt, j)
482+
line::Int = codeloc[1]
483+
line < 0 && break
484+
if line == 0 || currline == line
485+
j += 1
486+
else
487+
return line + Δline
488+
end
489+
end
490+
return typemax(Int)
491+
end
492+
493+
else # VERSION < v"1.12.0-DEV.173"
494+
function getline(lt, j)
495+
linfo = (j == 0 ? first(lt) : lt[j])::Core.LineInfoNode
496+
linfo.inlined_at == 0 && return linfo.line
497+
@assert linfo.method === Symbol("macro expansion")
498+
linfo = lt[linfo.inlined_at]::Core.LineInfoNode
499+
return linfo.line
500+
end
501+
function getnextline(lt, j, Δline)
502+
j == 0 && return typemax(Int)
503+
j += 1
504+
while j <= length(lt)
505+
linfo = lt[j]::Core.LineInfoNode
506+
linfo.inlined_at == 0 && return linfo.line + Δline
507+
j += 1
508+
end
509+
return typemax(Int)
510+
end
511+
end # @static if
512+
442513
# Main logic for mapping `src.code[i]` to node(s) in the SyntaxNode tree
443514
# Success: when we map it to a unique node
444515
# Δline is the (Revise) offset of the line number
@@ -471,8 +542,13 @@ function map_ssas_to_source(src::CodeInfo, mi::MethodInstance, rootnode::SyntaxN
471542
# Append (to `mapped`) all nodes in `targets` that are consistent with the line number of the `i`th stmt
472543
# (Essentially `copy!(mapped, filter(predicate, targets))`)
473544
function append_targets_for_line!(mapped#=::Vector{nodes}=#, i::Int, targets#=::Vector{nodes}=#)
474-
j = src.codelocs[i]
475-
lt = src.linetable::Vector
545+
@static if VERSION v"1.12.0-DEV.173"
546+
j = i
547+
lt = src.debuginfo
548+
else
549+
j = src.codelocs[i]
550+
lt = src.linetable::Vector
551+
end
476552
start = getline(lt, j) + Δline
477553
stop = getnextline(lt, j, Δline) - 1
478554
linerange = start : stop
@@ -853,25 +929,6 @@ function symloc_key(sym::Symbol)
853929
return sym
854930
end
855931

856-
function getline(lt, j)
857-
linfo = (j == 0 ? first(lt) : lt[j])::Core.LineInfoNode
858-
linfo.inlined_at == 0 && return linfo.line
859-
@assert linfo.method === Symbol("macro expansion")
860-
linfo = lt[linfo.inlined_at]::Core.LineInfoNode
861-
return linfo.line
862-
end
863-
864-
function getnextline(lt, j, Δline)
865-
j == 0 && return typemax(Int)
866-
j += 1
867-
while j <= length(lt)
868-
linfo = lt[j]::Core.LineInfoNode
869-
linfo.inlined_at == 0 && return linfo.line + Δline
870-
j += 1
871-
end
872-
return typemax(Int)
873-
end
874-
875932
function find_identifier_or_tuplechild(node::AbstractSyntaxNode, sym)
876933
kind(node) == K"Identifier" && node.val === sym && return node, true
877934
if kind(node) == K"tuple" # tuple destructuring

src/codeview.jl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,6 @@ function cthulhu_typed(io::IO, debuginfo::Symbol,
127127
# We empty the body when filling kwargs
128128
istruncated = isempty(children(body))
129129
idxend = istruncated ? JuliaSyntax.last_byte(sig) : lastindex(tsn.source)
130-
if any(iszero, src.codelocs)
131-
@warn "Some line information is missing, type-assignment may be incomplete"
132-
end
133130
if src.slottypes === nothing
134131
@warn "Inference terminated in an incomplete state due to argument-type changes during recursion"
135132
end

src/interpreter.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ function CC.src_inlining_policy(interp::CthulhuInterpreter,
153153
src::Any, info::CCCallInfo, stmt_flag::UInt32)
154154
end
155155
end
156-
CC.retrieve_ir_for_inlining(cached_result::CodeInstance, src::OptimizedSource) = CC.copy(src.ir)
156+
CC.retrieve_ir_for_inlining(cached_result::CodeInstance, src::OptimizedSource) =
157+
CC.retrieve_ir_for_inlining(cached_result.def, src.ir::IRCode, true)
157158
CC.retrieve_ir_for_inlining(mi::MethodInstance, src::OptimizedSource, preserve_local_sources::Bool) =
158159
CC.retrieve_ir_for_inlining(mi, src.ir, preserve_local_sources)
159160
elseif VERSION v"1.11.0-DEV.879"

src/reflection.jl

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ function find_caller_of(interp::AbstractInterpreter, callee::MethodInstance, cal
309309
callsites, _ = find_callsites(interp′, src, infos, caller, slottypes, optimize)
310310
callsites = allow_unspecialized ? filter(cs->maybe_callsite(cs, callee), callsites) :
311311
filter(cs->is_callsite(cs, callee), callsites)
312-
foreach(cs -> add_sourceline!(locs, src, cs.id), callsites)
312+
foreach(cs -> add_sourceline!(locs, src, cs.id, caller), callsites)
313313
end
314314
# Consolidate by method, but preserve the order
315315
prlookup = Dict{Tuple{Symbol,Symbol},Int}()
@@ -335,17 +335,25 @@ function find_caller_of(interp::AbstractInterpreter, callee::MethodInstance, cal
335335
return ulocs
336336
end
337337

338-
function add_sourceline!(locs, CI, stmtidx::Int)
339-
if isa(CI, IRCode)
340-
stack = Base.IRShow.compute_loc_stack(CI.linetable, CI.stmts.line[stmtidx])
338+
function add_sourceline!(locs::Vector{Tuple{Core.LineInfoNode,Int}}, src::Union{CodeInfo,IRCode}, stmtidx::Int, caller::MethodInstance)
339+
@static if VERSION v"1.12.0-DEV.173"
340+
stack = Base.IRShow.buildLineInfoNode(src.debuginfo, caller, stmtidx)
341+
for (i, di) in enumerate(stack)
342+
loc = Core.LineInfoNode(Main, di.method, di.file, di.line, zero(Int32))
343+
push!(locs, (loc, i-1))
344+
end
345+
else # VERSION < v"1.12.0-DEV.173"
346+
if isa(src, IRCode)
347+
stack = Base.IRShow.compute_loc_stack(src.linetable, src.stmts.line[stmtidx])
341348
for (i, idx) in enumerate(stack)
342-
line = CI.linetable[idx]
349+
line = src.linetable[idx]
343350
line.line == 0 && continue
344-
push!(locs, (CI.linetable[idx], i-1))
351+
push!(locs, (src.linetable[idx], i-1))
345352
end
346353
else
347-
push!(locs, (CI.linetable[CI.codelocs[stmtidx]], 0))
354+
push!(locs, (src.linetable[src.codelocs[stmtidx]], 0))
348355
end
356+
end # @static if
349357
return locs
350358
end
351359

test/test_Cthulhu.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,6 @@ end
814814
@test lines == [line2]
815815
end
816816

817-
818817
@testset "ascend interface" begin
819818
m = Module()
820819
@eval m begin

0 commit comments

Comments
 (0)