Skip to content

Commit

Permalink
In IR2OC constructor, widenconst OC argtypes
Browse files Browse the repository at this point in the history
The IR argtypes are lattice elements, but OC needs types.
  • Loading branch information
Keno committed Jul 22, 2022
1 parent 6009ae9 commit ce8532f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
2 changes: 1 addition & 1 deletion base/compiler/ssair/legacy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Mainly used for testing or interactive use.
"""
inflate_ir(ci::CodeInfo, linfo::MethodInstance) = inflate_ir!(copy(ci), linfo)
inflate_ir(ci::CodeInfo, sptypes::Vector{Any}, argtypes::Vector{Any}) = inflate_ir!(copy(ci), sptypes, argtypes)
inflate_ir(ci::CodeInfo) = inflate_ir(ci, Any[], Any[ Any for i = 1:length(ci.slotflags) ])
inflate_ir(ci::CodeInfo) = inflate_ir(ci, Any[], Any[ ci.slottypes[i] for i = 1:length(ci.slotflags) ])

function replace_code_newstyle!(ci::CodeInfo, ir::IRCode, nargs::Int)
@assert isempty(ir.new_nodes)
Expand Down
17 changes: 16 additions & 1 deletion base/opaque_closure.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ function compute_ir_rettype(ir::IRCode)
return Core.Compiler.widenconst(rt)
end

function compute_oc_argtypes(ir, nargs, isva)
argtypes = ir.argtypes[2:end]
@assert nargs == length(argtypes)
argtypes = Core.Compiler.anymap(Core.Compiler.widenconst, argtypes)
if isva
lastarg = pop!(argtypes)
if lastarg <: Tuple
append!(argtypes, lastarg.parameters)
else
push!(argtypes, Vararg{Any})
end
end
Tuple{argtypes...}
end

function Core.OpaqueClosure(ir::IRCode, env...;
nargs::Int = length(ir.argtypes)-1,
isva::Bool = false,
Expand All @@ -57,7 +72,7 @@ function Core.OpaqueClosure(ir::IRCode, env...;
# NOTE: we need ir.argtypes[1] == typeof(env)

ccall(:jl_new_opaque_closure_from_code_info, Any, (Any, Any, Any, Any, Any, Cint, Any, Cint, Cint, Any),
Tuple{ir.argtypes[2:end]...}, Union{}, rt, @__MODULE__, src, 0, nothing, nargs, isva, env)
compute_oc_argtypes(ir, nargs, isva), Union{}, rt, @__MODULE__, src, 0, nothing, nargs, isva, env)
end

function Core.OpaqueClosure(src::CodeInfo, env...)
Expand Down
24 changes: 17 additions & 7 deletions test/opaque_closure.jl
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,22 @@ end

let ci = code_typed((x, y...)->(x, y), (Int, Int))[1][1]
ir = Core.Compiler.inflate_ir(ci)
@test OpaqueClosure(ir; nargs=2, isva=true)(40, 2) === (40, (2,))
@test OpaqueClosure(ci)(40, 2) === (40, (2,))
end
let oc = OpaqueClosure(ir; nargs=2, isva=true)
# N.B.: This is not the correct way to use this API. You
# should make sure the ir argtypes are set correctly as
# in the example above.
@test oc(40, 2) === (40, (2,))
# This hits the :new with the wrong type
@test_throws MethodError oc(1,2,3)
end
let oc = OpaqueClosure(ci)
@test oc(40, 2) === (40, (2,))
@test_throws MethodError oc(1,2,3)
end

let ci = code_typed((x, y...)->(x, y), (Int, Int))[1][1]
ir = Core.Compiler.inflate_ir(ci)
@test_throws MethodError OpaqueClosure(ir; nargs=2, isva=true)(1, 2, 3)
@test_throws MethodError OpaqueClosure(ci)(1, 2, 3)
ir = Core.Compiler.inflate_ir(ci, Any[], Any[Tuple{}, Int, Tuple{Int}])
let oc = OpaqueClosure(ir; nargs=2, isva=true)
@test oc(40, 2) === (40, (2,))
@test_throws MethodError oc(1,2,3)
end
end

0 comments on commit ce8532f

Please sign in to comment.