Skip to content

Commit

Permalink
make code_lowered type stable (#53416)
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Feb 22, 2024
1 parent a1db8da commit ccba6c9
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 11 deletions.
4 changes: 2 additions & 2 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function copy(c::CodeInfo)
cnew.slotnames = copy(cnew.slotnames)
cnew.slotflags = copy(cnew.slotflags)
if cnew.slottypes !== nothing
cnew.slottypes = copy(cnew.slottypes)
cnew.slottypes = copy(cnew.slottypes::Vector{Any})
end
cnew.codelocs = copy(cnew.codelocs)
cnew.linetable = copy(cnew.linetable::Union{Vector{Any},Vector{Core.LineInfoNode}})
Expand Down Expand Up @@ -1019,7 +1019,7 @@ function remove_linenums!(@nospecialize ex)
return ex
elseif ex isa CodeInfo
ex.codelocs .= 0
length(ex.linetable) > 1 && resize!(ex.linetable, 1)
length(ex.linetable::Vector) > 1 && resize!(ex.linetable::Vector, 1)
return ex
else
return ex
Expand Down
20 changes: 11 additions & 9 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1127,20 +1127,23 @@ function code_lowered(@nospecialize(f), @nospecialize(t=Tuple); generated::Bool=
end
world = get_world_counter()
world == typemax(UInt) && error("code reflection cannot be used from generated functions")
return map(method_instances(f, t, world)) do m
ret = CodeInfo[]
for m in method_instances(f, t, world)
if generated && hasgenerator(m)
if may_invoke_generator(m)
return ccall(:jl_code_for_staged, Any, (Any, UInt), m, world)::CodeInfo
code = ccall(:jl_code_for_staged, Any, (Any, UInt), m, world)::CodeInfo
else
error("Could not expand generator for `@generated` method ", m, ". ",
"This can happen if the provided argument types (", t, ") are ",
"not leaf types, but the `generated` argument is `true`.")
end
else
code = uncompressed_ir(m.def::Method)
debuginfo === :none && remove_linenums!(code)
end
code = uncompressed_ir(m.def::Method)
debuginfo === :none && remove_linenums!(code)
return code
push!(ret, code)
end
return ret
end

hasgenerator(m::Method) = isdefined(m, :generator)
Expand Down Expand Up @@ -1331,7 +1334,7 @@ function method_instances(@nospecialize(f), @nospecialize(t), world::UInt)
# this make a better error message than the typeassert that follows
world == typemax(UInt) && error("code reflection cannot be used from generated functions")
for match in _methods_by_ftype(tt, -1, world)::Vector
instance = Core.Compiler.specialize_method(match)
instance = Core.Compiler.specialize_method(match::Core.MethodMatch)
push!(results, instance)
end
return results
Expand Down Expand Up @@ -1497,7 +1500,7 @@ function may_invoke_generator(method::Method, @nospecialize(atype), sparams::Sim
gen_mthds isa Vector || return false
length(gen_mthds) == 1 || return false

generator_method = first(gen_mthds).method
generator_method = (first(gen_mthds)::Core.MethodMatch).method
nsparams = length(sparams)
isdefined(generator_method, :source) || return false
code = generator_method.source
Expand Down Expand Up @@ -2459,7 +2462,7 @@ function isambiguous(m1::Method, m2::Method; ambiguous_bottom::Bool=false)
min = Ref{UInt}(typemin(UInt))
max = Ref{UInt}(typemax(UInt))
has_ambig = Ref{Int32}(0)
ms = _methods_by_ftype(ti, nothing, -1, world, true, min, max, has_ambig)::Vector
ms = collect(Core.MethodMatch, _methods_by_ftype(ti, nothing, -1, world, true, min, max, has_ambig)::Vector)
has_ambig[] == 0 && return false
if !ambiguous_bottom
filter!(ms) do m::Core.MethodMatch
Expand All @@ -2472,7 +2475,6 @@ function isambiguous(m1::Method, m2::Method; ambiguous_bottom::Bool=false)
# report the other ambiguous pair)
have_m1 = have_m2 = false
for match in ms
match = match::Core.MethodMatch
m = match.method
m === m1 && (have_m1 = true)
m === m2 && (have_m2 = true)
Expand Down
3 changes: 3 additions & 0 deletions test/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1193,3 +1193,6 @@ end
@test Base.isexported(Mod52812, :b)
@test Base.ispublic(Mod52812, :a)
@test Base.ispublic(Mod52812, :b)

@test Base.infer_return_type(code_lowered, (Any,)) == Vector{Core.CodeInfo}
@test Base.infer_return_type(code_lowered, (Any,Any)) == Vector{Core.CodeInfo}

0 comments on commit ccba6c9

Please sign in to comment.