@@ -189,11 +189,19 @@ function identify_framemethod_calls(frame)
189
189
key = key:: Union{Symbol,Bool,Nothing}
190
190
for (j, mstmt) in enumerate (msrc. code)
191
191
isa (mstmt, Expr) || continue
192
+ jj = j
192
193
if mstmt. head === :call
193
194
mkey = mstmt. args[1 ]
195
+ if isa (mkey, SSAValue) || isa (mkey, Core. SSAValue)
196
+ refstmt = msrc. code[mkey. id]
197
+ if isa (refstmt, Symbol)
198
+ jj = mkey. id
199
+ mkey = refstmt
200
+ end
201
+ end
194
202
if isa (mkey, Symbol)
195
203
# Could be a GlobalRef but then it's outside frame
196
- haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, j , mkey, key))
204
+ haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj , mkey, key))
197
205
elseif is_global_ref (mkey, Core, isdefined (Core, :_apply_iterate ) ? :_apply_iterate : :_apply )
198
206
ssaref = mstmt. args[end - 1 ]
199
207
if isa (ssaref, JuliaInterpreter. SSAValue)
@@ -202,15 +210,15 @@ function identify_framemethod_calls(frame)
202
210
end
203
211
mkey = mstmt. args[end - 2 ]
204
212
if isa (mkey, Symbol)
205
- haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, j , mkey, key))
213
+ haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj , mkey, key))
206
214
end
207
215
end
208
216
elseif mstmt. head === :meta && mstmt. args[1 ] === :generated
209
217
newex = mstmt. args[2 ]
210
218
if isa (newex, Expr)
211
219
if newex. head === :new && length (newex. args) >= 2 && is_global_ref (newex. args[1 ], Core, :GeneratedFunctionStub )
212
220
mkey = newex. args[2 ]:: Symbol
213
- haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, j , mkey, key))
221
+ haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj , mkey, key))
214
222
end
215
223
end
216
224
end
@@ -356,7 +364,7 @@ function find_name_caller_sig(@nospecialize(recurse), frame, pc, name, parentnam
356
364
end
357
365
if length (body. code) > 1
358
366
bodystmt = body. code[end - 1 ] # the line before the final return
359
- iscallto (bodystmt, name) && return signature_top (frame, stmt, pc), false
367
+ iscallto (bodystmt, name, body ) && return signature_top (frame, stmt, pc), false
360
368
end
361
369
end
362
370
pc = next_or_nothing (frame, pc)
@@ -426,6 +434,9 @@ function get_running_name(@nospecialize(recurse), frame, pc, name, parentname)
426
434
bodystmt = bodyparent. code[end - 1 ]
427
435
@assert isexpr (bodystmt, :call )
428
436
ref = getcallee (bodystmt)
437
+ if isa (ref, SSAValue) || isa (ref, Core. SSAValue)
438
+ ref = bodyparent. code[ref. id]
439
+ end
429
440
isa (ref, GlobalRef) || @show ref typeof (ref)
430
441
@assert isa (ref, GlobalRef)
431
442
@assert ref. mod == moduleof (frame)
@@ -581,7 +592,7 @@ function _methoddefs!(@nospecialize(recurse), signatures, frame::Frame, pc; defi
581
592
return pc
582
593
end
583
594
584
- function is_self_call (@nospecialize (stmt), slotnames, argno= 1 )
595
+ function is_self_call (@nospecialize (stmt), slotnames, argno:: Integer = 1 )
585
596
if isa (stmt, Expr)
586
597
if stmt. head == :call
587
598
a = stmt. args[argno]
@@ -612,44 +623,54 @@ Return the "body method" for a method `m`. `mbody` contains the code of the func
612
623
when `m` was defined.
613
624
"""
614
625
function bodymethod (mkw:: Method )
615
- m = mkw
616
- local src
617
- while true
618
- framecode = JuliaInterpreter. get_framecode (m)
619
- fakeargs = Any[nothing for i = 1 : (framecode. scope:: Method ). nargs]
620
- frame = JuliaInterpreter. prepare_frame (framecode, fakeargs, isa (m. sig, UnionAll) ? sparam_ub (m) : Core. svec ())
621
- src = framecode. src
622
- (length (src. code) > 1 && is_self_call (src. code[end - 1 ], src. slotnames)) || break
623
- # Build the optional arg, so we can get its type
624
- pc = frame. pc
625
- while pc < length (src. code) - 1
626
- pc = step_expr! (frame)
626
+ @static if isdefined (Core, :kwcall )
627
+ Base. unwrap_unionall (mkw. sig). parameters[1 ] != = typeof (Core. kwcall) && isempty (Base. kwarg_decl (mkw)) && return mkw
628
+ mths = methods (Base. bodyfunction (mkw))
629
+ if length (mths) != 1
630
+ @show mkw
631
+ display (mths)
627
632
end
628
- val = pc > 1 ? frame. framedata. ssavalues[pc- 1 ] : (src. code[1 ]:: Expr ). args[end ]
629
- sig = Tuple{(Base. unwrap_unionall (m. sig):: DataType ). parameters... , typeof (val)}
630
- m = whichtt (sig)
631
- end
632
- length (src. code) > 1 || return m
633
- stmt = src. code[end - 1 ]
634
- if isexpr (stmt, :call ) && (f = (stmt:: Expr ). args[1 ]; isa (f, QuoteNode))
635
- if f. value === (isdefined (Core, :_apply_iterate ) ? Core. _apply_iterate : Core. _apply)
636
- ssaref = stmt. args[end - 1 ]
637
- if isa (ssaref, JuliaInterpreter. SSAValue)
638
- id = ssaref. id
639
- has_self_call (src, src. code[id]) || return m
640
- end
641
- f = stmt. args[end - 2 ]
642
- if isa (f, JuliaInterpreter. SSAValue)
643
- f = src. code[f. id]
633
+ return only (mths)
634
+ else
635
+ m = mkw
636
+ local src
637
+ while true
638
+ framecode = JuliaInterpreter. get_framecode (m)
639
+ fakeargs = Any[nothing for i = 1 : (framecode. scope:: Method ). nargs]
640
+ frame = JuliaInterpreter. prepare_frame (framecode, fakeargs, isa (m. sig, UnionAll) ? sparam_ub (m) : Core. svec ())
641
+ src = framecode. src
642
+ (length (src. code) > 1 && is_self_call (src. code[end - 1 ], src. slotnames)) || break
643
+ # Build the optional arg, so we can get its type
644
+ pc = frame. pc
645
+ while pc < length (src. code) - 1
646
+ pc = step_expr! (frame)
644
647
end
645
- else
646
- has_self_call (src, stmt) || return m
648
+ val = pc > 1 ? frame. framedata. ssavalues[pc- 1 ] : (src. code[1 ]:: Expr ). args[end ]
649
+ sig = Tuple{(Base. unwrap_unionall (m. sig):: DataType ). parameters... , typeof (val)}
650
+ m = whichtt (sig)
647
651
end
648
- f = f. value
649
- mths = methods (f)
650
- if length (mths) == 1
651
- return first (mths)
652
+ length (src. code) > 1 || return m
653
+ stmt = src. code[end - 1 ]
654
+ if isexpr (stmt, :call ) && (f = (stmt:: Expr ). args[1 ]; isa (f, QuoteNode))
655
+ if f. value === (isdefined (Core, :_apply_iterate ) ? Core. _apply_iterate : Core. _apply)
656
+ ssaref = stmt. args[end - 1 ]
657
+ if isa (ssaref, JuliaInterpreter. SSAValue)
658
+ id = ssaref. id
659
+ has_self_call (src, src. code[id]) || return m
660
+ end
661
+ f = stmt. args[end - 2 ]
662
+ if isa (f, JuliaInterpreter. SSAValue)
663
+ f = src. code[f. id]
664
+ end
665
+ else
666
+ has_self_call (src, stmt) || return m
667
+ end
668
+ f = f. value
669
+ mths = methods (f)
670
+ if length (mths) == 1
671
+ return first (mths)
672
+ end
652
673
end
674
+ return m
653
675
end
654
- return m
655
676
end
0 commit comments