@@ -3,15 +3,19 @@ export findcallers
33function get_typed_instances! (srcs, @nospecialize (tt), method:: Method , world, interp)
44 # This is essentially taken from code_typed_by_type
55 matches = Base. _methods_by_ftype (tt, - 1 , world)
6- if matches === false
7- error (" signature $(item . specTypes) does not correspond to a generic function" )
6+ if matches === false || matches === nothing
7+ error (" signature $tt does not correspond to a generic function" )
88 end
99 for match in matches
1010 match. method == method || continue
11- meth = Base. func_for_method_checked (match. method, tt, match. sparams)
12- (src, ty) = isdefined (Core. Compiler, :NativeInterpreter ) ?
11+ meth = match. method
12+ if isdefined (Base, :func_for_method_checked )
13+ meth = Base. func_for_method_checked (meth, tt, match. sparams)
14+ end
15+ ret = isdefined (Core. Compiler, :NativeInterpreter ) ?
1316 Core. Compiler. typeinf_code (interp, meth, match. spec_types, match. sparams, false ) :
1417 Core. Compiler. typeinf_code (meth, match. spec_types, match. sparams, false , interp)
18+ src = isa (ret, Tuple) ? ret[1 ] : ret:: CodeInfo
1519 push! (srcs, (src, match. sparams))
1620 end
1721 return srcs
@@ -22,10 +26,10 @@ defaultinterp(world) = isdefined(Core.Compiler, :NativeInterpreter) ?
2226 Core. Compiler. NativeInterpreter (world) :
2327 Core. Compiler. Params (world)
2428
25- function get_typed_instances (mi:: MethodInstance ; world= typemax (UInt ), interp= defaultinterp (world))
29+ function get_typed_instances (mi:: MethodInstance ; world= default_world ( ), interp= defaultinterp (world))
2630 return get_typed_instances! (Tuple{CodeInfo,Core. SimpleVector}[], mi, world, interp)
2731end
28- function get_typed_instances (@nospecialize (tt), method:: Method ; world= typemax (UInt ), interp= defaultinterp (world))
32+ function get_typed_instances (@nospecialize (tt), method:: Method ; world= default_world ( ), interp= defaultinterp (world))
2933 return get_typed_instances! (Tuple{CodeInfo,Core. SimpleVector}[], tt, method, world, interp)
3034end
3135
@@ -95,8 +99,8 @@ callers3 = findcallers(f, argtyps->length(argtyps) == 1 && argtyps[1] === Vector
9599 `findcallers` is not guaranteed to find all calls. Calls can be "obfuscated" by many mechanisms,
96100 including calls from top level, calls where the function is a runtime variable, etc.
97101"""
98- function findcallers (f, argmatch:: Union{Function,Nothing} , mis:: AbstractVector{Core. MethodInstance} ;
99- callhead:: Symbol = :call , world= typemax (UInt ), interp= defaultinterp (world))
102+ function findcallers (f, argmatch:: Union{Function,Nothing} , mis:: AbstractVector{MethodInstance} ;
103+ callhead:: Symbol = :call , world= default_world ( ), interp= defaultinterp (world))
100104 callhead === :call || callhead === :invoke || callhead === :iterate || error (" :call and :invoke are supported, got " , callhead)
101105 # Check that f is not a type with specified parameters
102106 if f isa DataType && ! isempty (f. parameters)
@@ -105,7 +109,7 @@ function findcallers(f, argmatch::Union{Function,Nothing}, mis::AbstractVector{C
105109 # Construct a GlobalRef version of `f`
106110 ref = GlobalRef (parentmodule (f), nameof (f))
107111 callers = CallMatch[]
108- srcs = Tuple{CodeInfo,Core . SimpleVector}[]
112+ srcs = Tuple{CodeInfo,SimpleVector}[]
109113 for item in mis
110114 empty! (srcs)
111115 try
@@ -140,6 +144,9 @@ function findcallers(f, argmatch::Union{Function,Nothing}, mis::AbstractVector{C
140144 throw (err)
141145 end
142146 end
147+ if isa (callee, Core. Const)
148+ callee = callee. val
149+ end
143150 matches = false
144151 if callee === f
145152 matches = true
@@ -188,6 +195,12 @@ function findcallers(f, argmatch::Union{Function,Nothing}, mis::AbstractVector{C
188195 return callers
189196end
190197
198+ @static if isdefined (Base, :get_world_counter )
199+ default_world () = Base. get_world_counter ()
200+ else
201+ default_world () = typemax (UInt)
202+ end
203+
191204isglobalref (@nospecialize (g), mod:: Module , name:: Symbol ) = isa (g, GlobalRef) && g. mod === mod && g. name === name
192205
193206extract (a, sparams) = isa (a, Core. Const) ? Core. Typeof (a. val) :
@@ -203,7 +216,12 @@ function eval_ssa(src, sparams, id)
203216 if stmt. head === :call
204217 callee = stmt. args[1 ]
205218 if isglobalref (callee, Core, :apply_type )
206- return stmt. args[2 ]
219+ ret = stmt. args[2 ]
220+ if isa (ret, Core. SSAValue)
221+ # try one level deeper
222+ ret = eval_ssa (src, sparams, ret. id)
223+ end
224+ return ret
207225 elseif isglobalref (callee, Base, :getproperty )
208226 modg, objq = stmt. args[2 ], stmt. args[3 ]
209227 if isa (modg, Core. SSAValue)
0 commit comments