Skip to content

Commit 013fe08

Browse files
committed
Parametrize signatures by method table
1 parent c7d1b30 commit 013fe08

File tree

4 files changed

+29
-23
lines changed

4 files changed

+29
-23
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ version = "3.1.0"
77
JuliaInterpreter = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
88

99
[compat]
10-
JuliaInterpreter = "0.9"
10+
JuliaInterpreter = "0.9.45"
1111
julia = "1.10"
1212

1313
[extras]

src/LoweredCodeUtils.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ using JuliaInterpreter
1313
using JuliaInterpreter: SSAValue, SlotNumber, Frame
1414
using JuliaInterpreter: @lookup, moduleof, pc_expr, step_expr!, is_global_ref, is_quotenode_egal, whichtt,
1515
next_until!, finish_and_return!, get_return, nstatements, codelocation, linetable,
16-
is_return, lookup_return
16+
is_return, lookup_return, extract_method_table
1717

1818
include("packagedef.jl")
1919

src/signatures.jl

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ function signature(@nospecialize(recurse), frame::Frame, @nospecialize(stmt), pc
5353
stmt = pc_expr(frame, pc)
5454
end
5555
isa(stmt, Expr) || return nothing, pc
56+
mt = extract_method_table(frame, stmt; eval = false)
5657
sigsv = @lookup(frame, stmt.args[2])::SimpleVector
5758
sigt = signature(sigsv)
58-
return sigt, lastpc
59+
return mt => sigt, lastpc
5960
end
6061
signature(@nospecialize(recurse), frame::Frame, pc) = signature(recurse, frame, pc_expr(frame, pc), pc)
6162
signature(frame::Frame, pc) = signature(finish_and_return!, frame, pc)
@@ -439,9 +440,9 @@ function get_running_name(@nospecialize(recurse), frame, pc, name, parentname)
439440
pctop -= 1
440441
stmt = pc_expr(frame, pctop)
441442
end # end fix
442-
sigtparent, lastpcparent = signature(recurse, frame, pctop)
443+
(mt, sigtparent), lastpcparent = signature(recurse, frame, pctop)
443444
sigtparent === nothing && return name, pc, lastpcparent
444-
methparent = whichtt(sigtparent)
445+
methparent = whichtt(sigtparent, mt)
445446
methparent === nothing && return name, pc, lastpcparent # caller isn't defined, no correction is needed
446447
if isgen
447448
cname = GlobalRef(moduleof(frame), nameof(methparent.generator.gen))
@@ -507,6 +508,8 @@ function skip_until!(predicate, @nospecialize(recurse), frame)
507508
return pc
508509
end
509510

511+
method_table(method::Method) = isdefined(method, :external_mt) ? method.external_mt::MethodTable : nothing
512+
510513
"""
511514
ret = methoddef!(recurse, signatures, frame; define=true)
512515
ret = methoddef!(signatures, frame; define=true)
@@ -536,22 +539,22 @@ function methoddef!(@nospecialize(recurse), signatures, frame::Frame, @nospecial
536539
if ismethod3(stmt)
537540
pc3 = pc
538541
arg1 = stmt.args[1]
539-
sigt, pc = signature(recurse, frame, stmt, pc)
540-
meth = whichtt(sigt)
542+
(mt, sigt), pc = signature(recurse, frame, stmt, pc)
543+
meth = whichtt(sigt, mt)
541544
if isa(meth, Method) && (meth.sig <: sigt && sigt <: meth.sig)
542545
pc = define ? step_expr!(recurse, frame, stmt, true) : next_or_nothing!(recurse, frame)
543546
elseif define
544547
pc = step_expr!(recurse, frame, stmt, true)
545-
meth = whichtt(sigt)
548+
meth = whichtt(sigt, mt)
546549
end
547550
if isa(meth, Method) && (meth.sig <: sigt && sigt <: meth.sig)
548-
push!(signatures, meth.sig)
551+
push!(signatures, mt => meth.sig)
549552
else
550553
if arg1 === false || arg1 === nothing
551554
# If it's anonymous and not defined, define it
552555
pc = step_expr!(recurse, frame, stmt, true)
553-
meth = whichtt(sigt)
554-
isa(meth, Method) && push!(signatures, meth.sig)
556+
meth = whichtt(sigt, mt)
557+
isa(meth, Method) && push!(signatures, mt => meth.sig)
555558
return pc, pc3
556559
else
557560
# guard against busted lookup, e.g., https://github.com/JuliaLang/julia/issues/31112
@@ -592,7 +595,7 @@ function methoddef!(@nospecialize(recurse), signatures, frame::Frame, @nospecial
592595
end
593596
found || return nothing
594597
while true # methods containing inner methods may need multiple trips through this loop
595-
sigt, pc = signature(recurse, frame, stmt, pc)
598+
(mt, sigt), pc = signature(recurse, frame, stmt, pc)
596599
stmt = pc_expr(frame, pc)
597600
while !isexpr(stmt, :method, 3)
598601
pc = next_or_nothing(recurse, frame, pc) # this should not check define, we've probably already done this once
@@ -607,8 +610,8 @@ function methoddef!(@nospecialize(recurse), signatures, frame::Frame, @nospecial
607610
# signature of the active method. So let's get the active signature.
608611
frame.pc = pc
609612
pc = define ? step_expr!(recurse, frame, stmt, true) : next_or_nothing!(recurse, frame)
610-
meth = whichtt(sigt)
611-
isa(meth, Method) && push!(signatures, meth.sig) # inner methods are not visible
613+
meth = whichtt(sigt, mt)
614+
isa(meth, Method) && push!(signatures, mt => meth.sig) # inner methods are not visible
612615
name === name3 && return pc, pc3 # if this was an inner method we should keep going
613616
stmt = pc_expr(frame, pc) # there *should* be more statements in this frame
614617
end

test/signatures.jl

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
9797

9898
# Manually add the signature for the Caller constructor, since that was defined
9999
# outside of manual lowering
100-
push!(signatures, Tuple{Type{Lowering.Caller}})
100+
push!(signatures, nothing => Tuple{Type{Lowering.Caller}})
101101

102102
nms = names(Lowering; all=true)
103103
modeval, modinclude = getfield(Lowering, :eval), getfield(Lowering, :include)
@@ -107,7 +107,7 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
107107
isa(f, Base.Callable) || continue
108108
(f === modeval || f === modinclude) && continue
109109
for m in methods(f)
110-
if m.sig signatures
110+
if (nothing => m.sig) signatures
111111
push!(failed, m.sig)
112112
end
113113
end
@@ -151,7 +151,8 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
151151
rename_framemethods!(frame)
152152
methoddefs!(signatures, frame; define=false)
153153
@test length(signatures) == 1
154-
@test LoweredCodeUtils.whichtt(signatures[1]) == first(methods(Lowering.fouter))
154+
mt, sig = first(signatures)
155+
@test LoweredCodeUtils.whichtt(sig, mt) == first(methods(Lowering.fouter))
155156

156157
# Check output of methoddef!
157158
frame = Frame(Lowering, :(function nomethod end))
@@ -170,7 +171,8 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
170171
signatures = Set{Any}()
171172
methoddef!(signatures, frame; define=false)
172173
@test length(signatures) == 1
173-
@test first(signatures) == which(Base.max_values, Tuple{Type{Int16}}).sig
174+
mt, sig = first(signatures)
175+
@test sig == which(Base.max_values, Tuple{Type{Int16}}).sig
174176

175177
# define
176178
ex = :(fdefine(x) = 1)
@@ -291,7 +293,8 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
291293
JuliaInterpreter.next_until!(LoweredCodeUtils.ismethod3, frame, true)
292294
empty!(signatures)
293295
methoddefs!(signatures, frame; define=true)
294-
@test first(signatures).parameters[end] == Int
296+
mt, sig = first(signatures)
297+
@test sig.parameters[end] == Int
295298

296299
# Multiple keyword arg methods per frame
297300
# (Revise issue #363)
@@ -310,7 +313,7 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
310313
@test kw2sig signatures
311314
pc = methoddefs!(signatures, frame; define=false)
312315
@test pc === nothing
313-
@test kw2sig signatures
316+
@test (nothing => kw2sig) signatures
314317

315318
# Module-scoping
316319
ex = :(Base.@irrational π 3.14159265358979323846 pi)
@@ -336,7 +339,7 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
336339
rename_framemethods!(frame)
337340
empty!(signatures)
338341
methoddefs!(signatures, frame; define=false)
339-
@test Tuple{typeof(Lowering.CustomMS)} signatures
342+
@test (nothing => Tuple{typeof(Lowering.CustomMS)}) signatures
340343

341344
# https://github.com/timholy/Revise.jl/issues/398
342345
ex = quote
@@ -370,7 +373,7 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
370373
frame = Frame(Lowering422, ex)
371374
rename_framemethods!(frame)
372375
pc = methoddefs!(signatures, frame; define=false)
373-
@test typeof(Lowering422.fneg) Set(Base.unwrap_unionall(sig).parameters[1] for sig in signatures)
376+
@test typeof(Lowering422.fneg) Set(Base.unwrap_unionall(sig).parameters[1] for (mt, sig) in signatures)
374377

375378
# Scoped names (https://github.com/timholy/Revise.jl/issues/568)
376379
ex = :(f568() = -1)
@@ -385,7 +388,7 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
385388
pc = JuliaInterpreter.step_expr!(finish_and_return!, frame, true)
386389
end
387390
pc = methoddef!(finish_and_return!, signatures, frame, pc; define=true)
388-
@test Tuple{typeof(Lowering.f568)} signatures
391+
@test (nothing => Tuple{typeof(Lowering.f568)}) signatures
389392
@test Lowering.f568() == -2
390393

391394
# Undefined names

0 commit comments

Comments
 (0)