Skip to content

Commit 947ca1b

Browse files
authored
Fixes for opaque closure method lowering (#34)
opaque_closure_method has special non-evaluated semantics for its argument list, so we need some special non-quoted conversion here for the functionloc argument and the name argument when it's set to the global ref Core.nothing. To fix the globalref, I've chosen to translate `"core"::K"nothing"` into a literal `nothing` in general - this is consistent with how ast.c translates the special flisp `(null)` form.
1 parent f4556c9 commit 947ca1b

File tree

4 files changed

+24
-8
lines changed

4 files changed

+24
-8
lines changed

src/eval.jl

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ function to_lowered_expr(mod, ex, ssa_offset=0)
232232
if name == "cglobal"
233233
# cglobal isn't a true name within core - instead it's a builtin
234234
:cglobal
235+
elseif name == "nothing"
236+
# Translate Core.nothing into literal `nothing`s (flisp uses a
237+
# special form (null) for this during desugaring, etc)
238+
nothing
235239
else
236240
GlobalRef(Core, Symbol(name))
237241
end
@@ -286,9 +290,13 @@ function to_lowered_expr(mod, ex, ssa_offset=0)
286290
Expr(:method, c1, cs[2:end]...)
287291
elseif k == K"newvar"
288292
Core.NewvarNode(to_lowered_expr(mod, ex[1], ssa_offset))
289-
elseif k == K"new_opaque_closure"
293+
elseif k == K"opaque_closure_method"
290294
args = map(e->to_lowered_expr(mod, e, ssa_offset), children(ex))
291-
Expr(:new_opaque_closure, args...)
295+
# opaque_closure_method has special non-evaluated semantics for the
296+
# `functionloc` line number node so we need to undo a level of quoting
297+
@assert args[4] isa QuoteNode
298+
args[4] = args[4].value
299+
Expr(:opaque_closure_method, args...)
292300
elseif k == K"meta"
293301
args = Any[to_lowered_expr(mod, e, ssa_offset) for e in children(ex)]
294302
# Unpack K"Symbol" QuoteNode as `Expr(:meta)` requires an identifier here.
@@ -317,7 +325,7 @@ function to_lowered_expr(mod, ex, ssa_offset=0)
317325
k == K"gc_preserve_end" ? :gc_preserve_end :
318326
k == K"foreigncall" ? :foreigncall :
319327
k == K"cfunction" ? :cfunction :
320-
k == K"opaque_closure_method" ? :opaque_closure_method :
328+
k == K"new_opaque_closure" ? :new_opaque_closure :
321329
nothing
322330
if isnothing(head)
323331
throw(LoweringError(ex, "Unhandled form for kind $k"))

test/closures.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,10 @@ let
235235
end
236236
""") == (3,4,5)
237237

238+
# opaque_closure_method internals
239+
method_ex = lower_str(test_mod, "Base.Experimental.@opaque x -> 2x").args[1].code[3]
240+
@test method_ex.head === :opaque_closure_method
241+
@test method_ex.args[1] === nothing
242+
@test method_ex.args[4] isa LineNumberNode
243+
238244
end

test/misc.jl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,8 @@ cf_float = JuliaLowering.include_string(test_mod, """
4747
@test @ccall($cf_float(2::Float64, 3::Float64)::Float64) == 32.0
4848

4949
@testset "CodeInfo: has_image_globalref" begin
50-
elower(mod, s) = JuliaLowering.to_lowered_expr(
51-
mod, JuliaLowering.lower(
52-
mod, parsestmt(JuliaLowering.SyntaxTree, s)))
53-
@test elower(test_mod, "x + y").args[1].has_image_globalref === false
54-
@test elower(Main, "x + y").args[1].has_image_globalref === true
50+
@test lower_str(test_mod, "x + y").args[1].has_image_globalref === false
51+
@test lower_str(Main, "x + y").args[1].has_image_globalref === true
5552
end
5653

5754
end

test/utils.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ function watch_ir_tests(dir, delay=0.5)
262262
end
263263
end
264264

265+
function lower_str(mod, s)
266+
ex = parsestmt(JuliaLowering.SyntaxTree, s)
267+
return JuliaLowering.to_lowered_expr(mod, JuliaLowering.lower(mod, ex))
268+
end
269+
265270
# See Julia Base tests in "test/docs.jl"
266271
function docstrings_equal(d1, d2; debug=true)
267272
io1 = IOBuffer()

0 commit comments

Comments
 (0)