Skip to content

Commit 826ef34

Browse files
authored
Provide robustness for upcoming lowering changes (#1011)
Provides fixes that go with JuliaLang/julia#60569 and JuliaLang/julia#61036 Also needs JuliaDebug/LoweredCodeUtils.jl#144
1 parent 87539be commit 826ef34

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

src/lowered.jl

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,16 @@ end
2828
function is_defaultctors(@nospecialize(f))
2929
@assert !isa(f, Core.SSAValue) && !isa(f, JuliaInterpreter.SSAValue)
3030
if isa(f, GlobalRef)
31-
return f.mod === Core && f.name === :_defaultctors
31+
return (f.mod === Core || f.mod === Base) && f.name === :_defaultctors
32+
else
33+
if isa(f, QuoteNode)
34+
f = f.value
35+
end
36+
if isdefined(Core, :_defaultctors) && f === Core._defaultctors
37+
return true
38+
elseif isdefined(Base, :_defaultctors) && f === Base._defaultctors
39+
return true
40+
end
3241
end
3342
return false
3443
end
@@ -416,17 +425,24 @@ function _methods_by_execution!(
416425
# avoid redefining types unless we have to
417426
pc = next_or_nothing!(frame)
418427
else
428+
# If the RHS is a call, unwrap it and dispatch to the call handler
429+
callstmt = LoweredCodeUtils.getrhs(stmt)
430+
if isa(callstmt, Expr) && callstmt.head === :call
431+
@goto call_dispatch
432+
end
419433
pc = step_expr!(interp, frame, stmt, true)
420434
end
421435
elseif head === :call
422-
f = lookup(frame, stmt.args[1])
436+
callstmt = stmt
437+
@label call_dispatch
438+
f = lookup(frame, callstmt.args[1])
423439
if __bpart__ && f === Core._typebody!
424-
analyze_typebody!(exinfo, interp, frame, stmt)
440+
analyze_typebody!(exinfo, interp, frame, callstmt)
425441
pc = step_expr!(interp, frame, stmt, true)
426-
elseif @static(isdefined(Core, :_defaultctors) && true) && f === Core._defaultctors && length(stmt.args) == 3
442+
elseif is_defaultctors(f) && length(callstmt.args) == 3
427443
# Create the constructors for a type (i.e., a method definition)
428-
T = lookup(frame, stmt.args[2])
429-
lnn = lookup(frame, stmt.args[3])
444+
T = lookup(frame, callstmt.args[2])
445+
lnn = lookup(frame, callstmt.args[3])
430446
if T isa Type && lnn isa LineNumberNode
431447
empty!(signatures)
432448
uT = Base.unwrap_unionall(T)::DataType
@@ -450,8 +466,8 @@ function _methods_by_execution!(
450466
end
451467
elseif f === Core.eval
452468
# an @eval or eval block: this may contain method definitions, so intercept it.
453-
evalmod = lookup(interp, frame, stmt.args[2])::Module
454-
evalex = lookup(interp, frame, stmt.args[3])
469+
evalmod = lookup(interp, frame, callstmt.args[2])::Module
470+
evalex = lookup(interp, frame, callstmt.args[3])
455471
local value = nothing
456472
for (newmod, newex) in ExprSplitter(evalmod, evalex)
457473
if is_doc_expr(newex)
@@ -467,11 +483,11 @@ function _methods_by_execution!(
467483
elseif skip_include && (f === modinclude || f === Core.include || f === Base.include)
468484
# include calls need to be managed carefully from several standpoints, including
469485
# path management and parsing new expressions
470-
handle_include!(exinfo, interp, frame, stmt)
486+
handle_include!(exinfo, interp, frame, callstmt)
471487
assign_this!(frame, nothing) # FIXME: the file might return something different from `nothing`
472488
pc = next_or_nothing!(frame)
473489
elseif f === Base.Docs.doc! # && mode !== :eval
474-
fargs = JuliaInterpreter.collect_args(interp, frame, stmt)
490+
fargs = JuliaInterpreter.collect_args(interp, frame, callstmt)
475491
popfirst!(fargs)
476492
length(fargs) == 3 && push!(fargs, Union{}) # add the default sig
477493
dmod::Module, b::Base.Docs.Binding, str::Base.Docs.DocStr, sig = fargs

0 commit comments

Comments
 (0)