Skip to content

Commit

Permalink
Track GlobalRef consistently
Browse files Browse the repository at this point in the history
Companion PR to JuliaDebug/LoweredCodeUtils.jl#107. With both of
these and JuliaDebug/JuliaInterpreter.jl#634, basic Revise functionality
is working for me again on Julia master.
  • Loading branch information
Keno authored and timholy committed Jul 21, 2024
1 parent 54ee94a commit 37d1458
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 15 deletions.
33 changes: 21 additions & 12 deletions src/lowered.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ Since the contents of such expression are difficult to analyze, it is generally
safest to execute all such evals.
"""
function minimal_evaluation!(@nospecialize(predicate), methodinfo, mod::Module, src::Core.CodeInfo, mode::Symbol)
edges = CodeEdges(src)
edges = CodeEdges(mod, src)
# LoweredCodeUtils.print_with_code(stdout, src, edges)
isrequired = fill(false, length(src.code))
namedconstassigned = Dict{Symbol,Bool}()
namedconstassigned = Dict{GlobalRef,Bool}()
evalassign = false
for (i, stmt) in enumerate(src.code)
if !isrequired[i]
Expand All @@ -99,18 +99,24 @@ function minimal_evaluation!(@nospecialize(predicate), methodinfo, mod::Module,
end
end
if isexpr(stmt, :const)
name = stmt.args[1]::Symbol
namedconstassigned[name] = false
name = stmt.args[1]
if isa(name, Symbol)
name = GlobalRef(mod, name)
end
namedconstassigned[name::GlobalRef] = false
elseif isexpr(stmt, :(=))
lhs = (stmt::Expr).args[1]
if isa(lhs, Symbol)
lhs = GlobalRef(mod, name)
end
if isa(lhs, GlobalRef)
if haskey(namedconstassigned, lhs)
namedconstassigned[lhs] = true
end
end
if mode === :evalassign
evalassign = isrequired[i] = true
if isa(lhs, Symbol)
if isa(lhs, GlobalRef)
isrequired[edges.byname[lhs].succs] .= true # mark any `const` statements or other "uses" in this block
end
end
Expand All @@ -119,7 +125,7 @@ function minimal_evaluation!(@nospecialize(predicate), methodinfo, mod::Module,
if mode === :sigs
for (name, isassigned) in namedconstassigned
isassigned || continue
if isdefined(mod, name)
if isdefined(name.mod, name.name)
empty!(edges.byname[name].succs) # avoid redefining `consts` in `:sigs` mode (fixes #789)
end
end
Expand Down Expand Up @@ -225,7 +231,7 @@ function methods_by_execution!(@nospecialize(recurse), methodinfo, docexprs, mod
Core.eval(mod, ex)
catch err
(always_rethrow || isa(err, InterruptException)) && rethrow(err)
loc = location_string(whereis(frame)...)
loc = location_string(whereis(frame))
bt = trim_toplevel!(catch_backtrace())
throw(ReviseEvalException(loc, err, Any[(sf, 1) for sf in stacktrace(bt)]))
end
Expand All @@ -248,7 +254,7 @@ function methods_by_execution!(@nospecialize(recurse), methodinfo, docexprs, mod
methods_by_execution!(recurse, methodinfo, docexprs, frame, isrequired; mode=mode, kwargs...)
catch err
(always_rethrow || isa(err, InterruptException)) && (disablebp && foreach(enable, active_bp_refs); rethrow(err))
loc = location_string(whereis(frame)...)
loc = location_string(whereis(frame))
sfs = [] # crafted for interaction with Base.show_backtrace
frame = JuliaInterpreter.leaf(frame)
while frame !== nothing
Expand Down Expand Up @@ -309,10 +315,13 @@ function methods_by_execution!(@nospecialize(recurse), methodinfo, docexprs, fra
# However, it might have been followed by a thunk that defined a
# method (issue #435), so we still need to check for additions.
if !isempty(signatures)
file, line = whereis(frame.framecode, pc)
lnn = LineNumberNode(Int(line), Symbol(file))
for sig in signatures
add_signature!(methodinfo, sig, lnn)
loc = whereis(frame.framecode, pc)
if loc !== nothing
file, line = loc
lnn = LineNumberNode(Int(line), Symbol(file))
for sig in signatures
add_signature!(methodinfo, sig, lnn)
end
end
end
pc = next_or_nothing!(frame)
Expand Down
2 changes: 1 addition & 1 deletion src/parsing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function process_source!(mod_exprs_sigs::ModuleExprsSigs, ex, filename, mod::Mod
catch err
bt = trim_toplevel!(catch_backtrace())
lnn = firstline(ex)
loc = location_string(lnn.file, lnn.line)
loc = location_string((lnn.file, lnn.line))
throw(ReviseEvalException(loc, err, Any[(sf, 1) for sf in stacktrace(bt)]))
end
end
Expand Down
5 changes: 3 additions & 2 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ firstline(rex::RelocatableExpr) = firstline(rex.ex)

newloc(methloc::LineNumberNode, ln, lno) = fixpath(ln)

location_string(file::AbstractString, line) = abspath(file)*':'*string(line)
location_string(file::Symbol, line) = location_string(string(file), line)
location_string((file, line)::Tuple{AbstractString, Any},) = abspath(file)*':'*string(line)
location_string((file, line)::Tuple{Symbol, Any},) = location_string(string(file), line)
location_string(::Nothing) = "unknown location"

function linediff(la::LineNumberNode, lb::LineNumberNode)
(isa(la.file, Symbol) && isa(lb.file, Symbol) && (la.file::Symbol === lb.file::Symbol)) || return typemax(Int)
Expand Down

0 comments on commit 37d1458

Please sign in to comment.