Skip to content

Commit

Permalink
add a version of code_typed that accepts a function type
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Jun 23, 2020
1 parent be72a57 commit 178d74d
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
26 changes: 24 additions & 2 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,16 @@ function _methods(@nospecialize(f), @nospecialize(t), lim::Int, world::UInt)
return _methods_by_ftype(tt, lim, world)
end

function _methods_ft(@nospecialize(ft::Type), @nospecialize(args), lim::Int, world::UInt)
if isa(args, Type)
u = unwrap_unionall(args)
tt = rewrap_unionall(Tuple{ft, u.parameters...}, args)
else
tt = Tuple{ft, args...}
end
return _methods_by_ftype(tt, lim, world)
end

function _methods_by_ftype(@nospecialize(t), lim::Int, world::UInt)
return _methods_by_ftype(t, lim, world, UInt[typemin(UInt)], UInt[typemax(UInt)])
end
Expand Down Expand Up @@ -1081,10 +1091,18 @@ function code_typed(@nospecialize(f), @nospecialize(types=Tuple);
debuginfo::Symbol=:default,
world = get_world_counter(),
interp = Core.Compiler.NativeInterpreter(world))
ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions")
if isa(f, Core.Builtin)
throw(ArgumentError("argument is not a generic function"))
end
return code_typed_ftype(Core.Typeof(f), types; optimize, debuginfo, world, interp)
end

function code_typed_ftype(@nospecialize(ft), @nospecialize(types=Tuple);
optimize=true,
debuginfo::Symbol=:default,
world = get_world_counter(),
interp = Core.Compiler.NativeInterpreter(world))
ccall(:jl_is_in_pure_context, Bool, ()) && error("code reflection cannot be used from generated functions")
if @isdefined(IRShow)
debuginfo = IRShow.debuginfo(debuginfo)
elseif debuginfo === :default
Expand All @@ -1095,7 +1113,11 @@ function code_typed(@nospecialize(f), @nospecialize(types=Tuple);
end
types = to_tuple_type(types)
asts = []
for x in _methods(f, types, -1, world)
meths = _methods_ft(ft, types, -1, world)
if meths === false
error("function type does not correspond to a generic function")
end
for x in meths
meth = func_for_method_checked(x[3], types, x[2])
(code, ty) = Core.Compiler.typeinf_code(interp, meth, x[1], x[2], optimize)
code === nothing && error("inference not successful") # inference disabled?
Expand Down
4 changes: 4 additions & 0 deletions test/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,10 @@ let
@test !isdefined(mi.cache, :next)
end

# code_typed_ftype
@test Base.code_typed_ftype(Type{<:Val}, ())[1][2] == Val
@test_throws ErrorException("function type does not correspond to a generic function") Base.code_typed_ftype(Any, ())

# New reflection methods in 0.6
struct ReflectionExample{T<:AbstractFloat, N}
x::Tuple{T, N}
Expand Down

0 comments on commit 178d74d

Please sign in to comment.