@@ -121,8 +121,8 @@ MethodInfo(start) = MethodInfo(start, -1, Int[])
121
121
struct SelfCall
122
122
linetop:: Int
123
123
linebody:: Int
124
- callee:: Symbol
125
- caller:: Union{Symbol ,Bool,Nothing}
124
+ callee:: GlobalRef
125
+ caller:: Union{GlobalRef ,Bool,Nothing}
126
126
end
127
127
128
128
"""
@@ -140,14 +140,14 @@ which will correspond to a 3-argument `:method` expression containing a `CodeInf
140
140
`callee` is the Symbol of the called method.
141
141
"""
142
142
function identify_framemethod_calls (frame)
143
- refs = Pair{Symbol ,Int}[]
144
- methodinfos = Dict {Symbol ,MethodInfo} ()
143
+ refs = Pair{GlobalRef ,Int}[]
144
+ methodinfos = Dict {GlobalRef ,MethodInfo} ()
145
145
selfcalls = SelfCall[]
146
146
for (i, stmt) in enumerate (frame. framecode. src. code)
147
147
isa (stmt, Expr) || continue
148
148
if stmt. head === :global && length (stmt. args) == 1
149
- key = stmt. args[1 ]
150
- if isa (key, Symbol )
149
+ key = normalize_defsig ( stmt. args[1 ], frame)
150
+ if isa (key, GlobalRef )
151
151
# We don't know for sure if this is a reference to a method, but let's
152
152
# tentatively cue it
153
153
push! (refs, key=> i)
@@ -159,16 +159,16 @@ function identify_framemethod_calls(frame)
159
159
if is_return (tstmt)
160
160
tex = tstmt. val
161
161
if isa (tex, Expr)
162
- if tex. head === :method && (methname = tex. args[1 ]; isa (methname, Symbol))
163
- push! (refs, methname=> i)
162
+ if tex. head === :method && (methname = tex. args[1 ]; isa (methname, Union{ Symbol, GlobalRef} ))
163
+ push! (refs, normalize_defsig ( methname, frame) => i)
164
164
end
165
165
end
166
166
end
167
167
end
168
168
elseif ismethod1 (stmt)
169
169
key = stmt. args[1 ]
170
170
key = normalize_defsig (key, frame)
171
- key = key:: Symbol
171
+ key = key:: GlobalRef
172
172
mi = get (methodinfos, key, nothing )
173
173
if mi === nothing
174
174
methodinfos[key] = MethodInfo (i)
@@ -178,7 +178,7 @@ function identify_framemethod_calls(frame)
178
178
elseif ismethod3 (stmt)
179
179
key = stmt. args[1 ]
180
180
key = normalize_defsig (key, frame)
181
- if key isa Symbol
181
+ if key isa GlobalRef
182
182
# XXX A temporary hack to fix https://github.com/JuliaDebug/LoweredCodeUtils.jl/issues/80
183
183
# We should revisit it.
184
184
mi = get (methodinfos, key, MethodInfo (1 ))
@@ -188,38 +188,40 @@ function identify_framemethod_calls(frame)
188
188
end
189
189
msrc = stmt. args[3 ]
190
190
if msrc isa CodeInfo
191
- key = key:: Union{Symbol ,Bool,Nothing}
191
+ key = key:: Union{GlobalRef ,Bool,Nothing}
192
192
for (j, mstmt) in enumerate (msrc. code)
193
193
isa (mstmt, Expr) || continue
194
194
jj = j
195
195
if mstmt. head === :call
196
- mkey = mstmt. args[1 ]
196
+ mkey = normalize_defsig ( mstmt. args[1 ], frame)
197
197
if isa (mkey, SSAValue) || isa (mkey, Core. SSAValue)
198
198
refstmt = msrc. code[mkey. id]
199
- if isa (refstmt, Symbol)
199
+ if isa (refstmt, Union{ Symbol, GlobalRef} )
200
200
jj = mkey. id
201
- mkey = refstmt
201
+ mkey = normalize_defsig ( refstmt, frame)
202
202
end
203
203
end
204
- if isa (mkey, Symbol)
205
- # Could be a GlobalRef but then it's outside frame
206
- haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj, mkey, key))
207
- elseif is_global_ref (mkey, Core, isdefined (Core, :_apply_iterate ) ? :_apply_iterate : :_apply )
204
+ if is_global_ref (mkey, Core, isdefined (Core, :_apply_iterate ) ? :_apply_iterate : :_apply )
208
205
ssaref = mstmt. args[end - 1 ]
209
206
if isa (ssaref, JuliaInterpreter. SSAValue)
210
207
id = ssaref. id
211
208
has_self_call (msrc, msrc. code[id]) || continue
212
209
end
213
- mkey = mstmt. args[end - 2 ]
214
- if isa (mkey, Symbol )
210
+ mkey = normalize_defsig ( mstmt. args[end - 2 ], frame)
211
+ if isa (mkey, GlobalRef )
215
212
haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj, mkey, key))
216
213
end
214
+ elseif isa (mkey, GlobalRef)
215
+ haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj, mkey, key))
217
216
end
218
217
elseif mstmt. head === :meta && mstmt. args[1 ] === :generated
219
218
newex = mstmt. args[2 ]
220
219
if isa (newex, Expr)
221
220
if newex. head === :new && length (newex. args) >= 2 && is_global_ref (newex. args[1 ], Core, :GeneratedFunctionStub )
222
- mkey = newex. args[2 ]:: Symbol
221
+ mkey = newex. args[2 ]
222
+ if isa (mkey, Symbol)
223
+ mkey = GlobalRef (moduleof (frame), mkey)
224
+ end
223
225
haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj, mkey, key))
224
226
end
225
227
end
@@ -235,20 +237,22 @@ function identify_framemethod_calls(frame)
235
237
return methodinfos, selfcalls
236
238
end
237
239
238
- # try to normalize `def` to `Symbol ` representation
239
- function normalize_defsig (@nospecialize (def), frame :: Frame )
240
+ # try to normalize `def` to `GlobalRef ` representation
241
+ function normalize_defsig (@nospecialize (def), mod :: Module )
240
242
if def isa QuoteNode
241
243
def = nameof (def. value)
242
- elseif def isa GlobalRef
243
- def = def. name
244
+ end
245
+ if def isa Symbol
246
+ def = GlobalRef (mod, def)
244
247
end
245
248
return def
246
249
end
250
+ normalize_defsig (@nospecialize (def), frame:: Frame ) = normalize_defsig (def, moduleof (frame))
247
251
248
252
function callchain (selfcalls)
249
- calledby = Dict {Symbol ,Union{Symbol ,Bool,Nothing}} ()
253
+ calledby = Dict {GlobalRef ,Union{GlobalRef ,Bool,Nothing}} ()
250
254
for sc in selfcalls
251
- startswith (String (sc. callee), ' #' ) || continue
255
+ startswith (String (sc. callee. name ), ' #' ) || continue
252
256
caller = get (calledby, sc. callee, nothing )
253
257
if caller === nothing
254
258
calledby[sc. callee] = sc. caller
@@ -261,7 +265,7 @@ function callchain(selfcalls)
261
265
end
262
266
263
267
function set_to_running_name! (@nospecialize (recurse), replacements, frame, methodinfos, selfcall, calledby, callee, caller)
264
- if isa (caller, Symbol ) && startswith (String (caller), ' #' )
268
+ if isa (caller, GlobalRef ) && startswith (String (caller. name ), ' #' )
265
269
rep = get (replacements, caller, nothing )
266
270
if rep === nothing
267
271
parentcaller = get (calledby, caller, nothing )
@@ -313,9 +317,9 @@ the same name in the `start:stop` range.
313
317
"""
314
318
function rename_framemethods! (@nospecialize (recurse), frame:: Frame , methodinfos, selfcalls, calledby)
315
319
src = frame. framecode. src
316
- replacements = Dict {Symbol,Symbol } ()
320
+ replacements = Dict {GlobalRef,GlobalRef } ()
317
321
for (callee, caller) in calledby
318
- (! startswith (String (callee), ' #' ) || haskey (replacements, callee)) && continue
322
+ (! startswith (String (callee. name ), ' #' ) || haskey (replacements, callee)) && continue
319
323
idx = findfirst (sc-> sc. callee === callee && sc. caller === caller, selfcalls)
320
324
idx === nothing && continue
321
325
try
@@ -364,7 +368,7 @@ function find_name_caller_sig(@nospecialize(recurse), frame, pc, name, parentnam
364
368
stmt = pc_expr (frame, pc)
365
369
end
366
370
body = stmt. args[3 ]
367
- if stmt. args[1 ] != = name && isa (body, CodeInfo)
371
+ if normalize_defsig ( stmt. args[1 ], frame) != = name && isa (body, CodeInfo)
368
372
# This might be the GeneratedFunctionStub for a @generated method
369
373
for (i, bodystmt) in enumerate (body. code)
370
374
if isexpr (bodystmt, :meta ) && (bodystmt:: Expr ). args[1 ] === :generated
@@ -374,7 +378,7 @@ function find_name_caller_sig(@nospecialize(recurse), frame, pc, name, parentnam
374
378
end
375
379
if length (body. code) > 1
376
380
bodystmt = body. code[end - 1 ] # the line before the final return
377
- iscallto (bodystmt, name, body) && return signature_top (frame, stmt, pc), false
381
+ iscallto (bodystmt, moduleof (frame), name, body) && return signature_top (frame, stmt, pc), false
378
382
end
379
383
end
380
384
pc = next_or_nothing (frame, pc)
@@ -412,6 +416,8 @@ function replacename!(args::AbstractVector, pr)
412
416
replacename! (a. val:: Expr , pr)
413
417
elseif a === oldname
414
418
args[i] = newname
419
+ elseif isa (a, Symbol) && a == oldname. name
420
+ args[i] = newname. name
415
421
end
416
422
end
417
423
return args
@@ -438,7 +444,7 @@ function get_running_name(@nospecialize(recurse), frame, pc, name, parentname)
438
444
methparent = whichtt (sigtparent)
439
445
methparent === nothing && return name, pc, lastpcparent # caller isn't defined, no correction is needed
440
446
if isgen
441
- cname = nameof (methparent. generator. gen)
447
+ cname = GlobalRef ( moduleof (frame), nameof (methparent. generator. gen) )
442
448
else
443
449
bodyparent = Base. uncompressed_ast (methparent)
444
450
bodystmt = bodyparent. code[end - 1 ]
@@ -450,7 +456,7 @@ function get_running_name(@nospecialize(recurse), frame, pc, name, parentname)
450
456
isa (ref, GlobalRef) || @show ref typeof (ref)
451
457
@assert isa (ref, GlobalRef)
452
458
@assert ref. mod == moduleof (frame)
453
- cname = ref. name
459
+ cname = ref
454
460
end
455
461
return cname, pc, lastpcparent
456
462
end
@@ -519,21 +525,20 @@ function methoddef!(@nospecialize(recurse), signatures, frame::Frame, @nospecial
519
525
return pc, pc3
520
526
end
521
527
ismethod1 (stmt) || Base. invokelatest (error, " expected method opening, got " , stmt)
522
- name = stmt. args[1 ]
523
- name = normalize_defsig (name, frame)
528
+ name = normalize_defsig (stmt. args[1 ], frame)
524
529
if isa (name, Bool)
525
530
error (" not valid for anonymous methods" )
526
531
elseif name === missing
527
532
Base. invokelatest (error, " given invalid definition: " , stmt)
528
533
end
529
- name = name:: Symbol
534
+ name = name:: GlobalRef
530
535
# Is there any 3-arg method definition with the same name? If not, avoid risk of executing code that
531
536
# we shouldn't (fixes https://github.com/timholy/Revise.jl/issues/758)
532
537
found = false
533
538
for i = pc+ 1 : length (framecode. src. code)
534
539
newstmt = framecode. src. code[i]
535
540
if ismethod3 (newstmt)
536
- if ismethod_with_name (framecode. src, newstmt, string (name))
541
+ if ismethod_with_name (framecode. src, newstmt, string (name. name ))
537
542
found = true
538
543
break
539
544
end
@@ -550,7 +555,7 @@ function methoddef!(@nospecialize(recurse), signatures, frame::Frame, @nospecial
550
555
end
551
556
pc3 = pc
552
557
stmt = stmt:: Expr
553
- name3 = stmt. args[1 ]
558
+ name3 = normalize_defsig ( stmt. args[1 ], frame)
554
559
sigt === nothing && (error (" expected a signature" ); return next_or_nothing (frame, pc)), pc3
555
560
# Methods like f(x::Ref{<:Real}) that use gensymmed typevars will not have the *exact*
556
561
# signature of the active method. So let's get the active signature.
0 commit comments