Skip to content

Commit ec40e2b

Browse files
authored
Merge pull request #34 from JuliaDebug/teh/apply_iterate
Fix handling of Core._apply_iterate
2 parents 2511b81 + 8f31646 commit ec40e2b

File tree

5 files changed

+55
-8
lines changed

5 files changed

+55
-8
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "LoweredCodeUtils"
22
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
33
authors = ["Tim Holy <[email protected]>"]
4-
version = "1.1.1"
4+
version = "1.1.2"
55

66
[deps]
77
JuliaInterpreter = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"

src/LoweredCodeUtils.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ if ccall(:jl_generating_output, Cint, ()) == 1
4747
@assert precompile(CodeEdges, (CodeInfo,))
4848
@assert precompile(add_links!, (Pair{Union{SSAValue,SlotNumber,NamedVar},Links}, Any, CodeLinks))
4949
@assert precompile(lines_required!, (Vector{Bool}, Set{NamedVar}, CodeInfo, CodeEdges))
50+
51+
precompile(Tuple{typeof(setindex!),Dict{Union{GlobalRef, Symbol},Links},Links,Symbol})
52+
precompile(Tuple{typeof(setindex!),Dict{Union{GlobalRef, Symbol},Variable},Variable,Symbol})
5053
end
5154

5255
end # module

src/signatures.jl

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,16 @@ function identify_framemethod_calls(frame)
164164
if isa(mkey, Symbol)
165165
# Could be a GlobalRef but then it's outside frame
166166
haskey(methodinfos, mkey) && push!(selfcalls, (linetop=i, linebody=j, callee=mkey, caller=key))
167+
elseif is_global_ref(mkey, Core, isdefined(Core, :_apply_iterate) ? :_apply_iterate : :_apply)
168+
ssaref = mstmt.args[end-1]
169+
if isa(ssaref, JuliaInterpreter.SSAValue)
170+
id = ssaref.id
171+
has_self_call(msrc, msrc.code[id]) || continue
172+
end
173+
mkey = mstmt.args[end-2]
174+
if isa(mkey, Symbol)
175+
haskey(methodinfos, mkey) && push!(selfcalls, (linetop=i, linebody=j, callee=mkey, caller=key))
176+
end
167177
end
168178
elseif isexpr(mstmt, :meta) && mstmt.args[1] == :generated
169179
newex = mstmt.args[2]
@@ -529,6 +539,15 @@ function is_self_call(@nospecialize(stmt), slotnames, argno=1)
529539
return false
530540
end
531541

542+
function has_self_call(src, stmt::Expr)
543+
# Check that it has a #self# call
544+
hasself = false
545+
for i = 2:length(stmt.args)
546+
hasself |= is_self_call(stmt, src.slotnames, i)
547+
end
548+
return hasself
549+
end
550+
532551
"""
533552
mbody = bodymethod(m::Method)
534553
@@ -556,12 +575,16 @@ function bodymethod(mkw::Method)
556575
length(src.code) > 1 || return m
557576
stmt = src.code[end-1]
558577
if isexpr(stmt, :call) && (f = stmt.args[1]; isa(f, QuoteNode))
559-
# Check that it has a #self# call
560-
hasself = false
561-
for i = 2:length(stmt.args)
562-
hasself |= is_self_call(stmt, src.slotnames, i)
578+
if f.value === (isdefined(Core, :_apply_iterate) ? Core._apply_iterate : Core._apply)
579+
ssaref = stmt.args[end-1]
580+
if isa(ssaref, JuliaInterpreter.SSAValue)
581+
id = ssaref.id
582+
has_self_call(src, src.code[id]) || return m
583+
end
584+
f = stmt.args[end-2]
585+
else
586+
has_self_call(src, stmt) || return m
563587
end
564-
hasself || return m
565588
f = f.value
566589
mths = methods(f)
567590
if length(mths) == 1
@@ -570,4 +593,3 @@ function bodymethod(mkw::Method)
570593
end
571594
return m
572595
end
573-

src/utils.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ function iscallto(@nospecialize(stmt), name)
1313
if isexpr(stmt, :call)
1414
a = stmt.args[1]
1515
a === name && return true
16-
return is_global_ref(a, Core, :_apply) && stmt.args[2] === name
16+
is_global_ref(a, Core, :_apply) && stmt.args[2] === name && return true
17+
is_global_ref(a, Core, :_apply_iterate) && stmt.args[3] === name && return true
1718
end
1819
return false
1920
end
@@ -27,6 +28,7 @@ function getcallee(@nospecialize(stmt))
2728
if isexpr(stmt, :call)
2829
a = stmt.args[1]
2930
is_global_ref(a, Core, :_apply) && return stmt.args[2]
31+
is_global_ref(a, Core, :_apply_iterate) && return stmt.args[3]
3032
return a
3133
end
3234
error(stmt, " is not a call expression")

test/signatures.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,26 @@ bodymethtest5(x, y=Dict(1=>2)) = 5
260260
# Issue in https://github.com/timholy/CodeTracking.jl/pull/48
261261
mbody = bodymethod(m)
262262
@test mbody != m && mbody.file != :none
263+
# varargs keyword methods
264+
m = which(Base.print_shell_escaped, (IO, AbstractString))
265+
mbody = bodymethod(m)
266+
@test isa(mbody, Method) && mbody != m
267+
268+
ex = quote
269+
function print_shell_escaped(io::IO, cmd::AbstractString, args::AbstractString...;
270+
special::AbstractString="")
271+
print_shell_word(io, cmd, special)
272+
for arg in args
273+
print(io, ' ')
274+
print_shell_word(io, arg, special)
275+
end
276+
end
277+
end
278+
frame = JuliaInterpreter.prepare_thunk(Base, ex)
279+
rename_framemethods!(frame)
280+
empty!(signatures)
281+
methoddefs!(signatures, frame; define=false)
282+
@test length(signatures) >= 3
263283

264284
ex = :(typedsig(x) = 1)
265285
frame = JuliaInterpreter.prepare_thunk(Lowering, ex)

0 commit comments

Comments
 (0)