Skip to content

Commit 9286471

Browse files
vtjnashgiordano
andauthored
support passing a specific Method to invoke (JuliaLang#56692)
Co-authored-by: Mosè Giordano <[email protected]>
1 parent 9cc21ea commit 9286471

File tree

3 files changed

+37
-26
lines changed

3 files changed

+37
-26
lines changed

src/abstractinterpretation.jl

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -856,8 +856,7 @@ end
856856

857857
struct InvokeCall
858858
types # ::Type
859-
lookupsig # ::Type
860-
InvokeCall(@nospecialize(types), @nospecialize(lookupsig)) = new(types, lookupsig)
859+
InvokeCall(@nospecialize(types)) = new(types)
861860
end
862861

863862
struct ConstCallResult
@@ -2218,34 +2217,46 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
22182217
ft′ = argtype_by_index(argtypes, 2)
22192218
ft = widenconst(ft′)
22202219
ft === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo()))
2221-
(types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false)
2222-
isexact || return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2223-
unwrapped = unwrap_unionall(types)
2224-
types === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo()))
2225-
if !(unwrapped isa DataType && unwrapped.name === Tuple.name)
2226-
return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2227-
end
2228-
argtype = argtypes_to_type(argtype_tail(argtypes, 4))
2229-
nargtype = typeintersect(types, argtype)
2230-
nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2231-
nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below
2232-
isdispatchelem(ft) || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
2233-
ft = ft::DataType
2234-
lookupsig = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type
2235-
nargtype = Tuple{ft, nargtype.parameters...}
2236-
argtype = Tuple{ft, argtype.parameters...}
2237-
matched, valid_worlds = findsup(lookupsig, method_table(interp))
2238-
matched === nothing && return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2239-
update_valid_age!(sv, valid_worlds)
2240-
method = matched.method
2220+
types = argtype_by_index(argtypes, 3)
2221+
if types isa Const && types.val isa Method
2222+
method = types.val::Method
2223+
types = method # argument value
2224+
lookupsig = method.sig # edge kind
2225+
argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft))
2226+
nargtype = typeintersect(lookupsig, argtype)
2227+
nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2228+
nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below
2229+
else
2230+
widenconst(types) >: Method && return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2231+
(types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3), false)
2232+
isexact || return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2233+
unwrapped = unwrap_unionall(types)
2234+
types === Bottom && return Future(CallMeta(Bottom, Any, EFFECTS_THROWS, NoCallInfo()))
2235+
if !(unwrapped isa DataType && unwrapped.name === Tuple.name)
2236+
return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2237+
end
2238+
argtype = argtypes_to_type(argtype_tail(argtypes, 4))
2239+
nargtype = typeintersect(types, argtype)
2240+
nargtype === Bottom && return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo()))
2241+
nargtype isa DataType || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # other cases are not implemented below
2242+
isdispatchelem(ft) || return Future(CallMeta(Any, Any, Effects(), NoCallInfo())) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
2243+
ft = ft::DataType
2244+
lookupsig = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type
2245+
nargtype = Tuple{ft, nargtype.parameters...}
2246+
argtype = Tuple{ft, argtype.parameters...}
2247+
matched, valid_worlds = findsup(lookupsig, method_table(interp))
2248+
matched === nothing && return Future(CallMeta(Any, Any, Effects(), NoCallInfo()))
2249+
update_valid_age!(sv, valid_worlds)
2250+
method = matched.method
2251+
end
22412252
tienv = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
22422253
ti = tienv[1]
22432254
env = tienv[2]::SimpleVector
22442255
mresult = abstract_call_method(interp, method, ti, env, false, si, sv)::Future
22452256
match = MethodMatch(ti, env, method, argtype <: method.sig)
22462257
ft′_box = Core.Box(ft′)
22472258
lookupsig_box = Core.Box(lookupsig)
2248-
invokecall = InvokeCall(types, lookupsig)
2259+
invokecall = InvokeCall(types)
22492260
return Future{CallMeta}(mresult, interp, sv) do result, interp, sv
22502261
(; rt, exct, effects, edge, volatile_inf_result) = result
22512262
local ft′ = ft′_box.contents

src/abstractlattice.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ end
229229
if isa(t, Const)
230230
# don't consider mutable values useful constants
231231
val = t.val
232-
return isa(val, Symbol) || isa(val, Type) || !ismutable(val)
232+
return isa(val, Symbol) || isa(val, Type) || isa(val, Method) || !ismutable(val)
233233
end
234234
isa(t, PartialTypeVar) && return false # this isn't forwardable
235235
return is_const_prop_profitable_arg(widenlattice(𝕃), t)

src/utilities.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ function count_const_size(@nospecialize(x), count_self::Bool = true)
5454
# No definite size
5555
(isa(x, GenericMemory) || isa(x, String) || isa(x, SimpleVector)) &&
5656
return MAX_INLINE_CONST_SIZE + 1
57-
if isa(x, Module)
58-
# We allow modules, because we already assume they are externally
57+
if isa(x, Module) || isa(x, Method)
58+
# We allow modules and methods, because we already assume they are externally
5959
# rooted, so we count their contents as 0 size.
6060
return sizeof(Ptr{Cvoid})
6161
end

0 commit comments

Comments
 (0)