Skip to content

Commit 2b2a4c9

Browse files
committed
Emit latestworld world age increments
For method defs, `latestworld` is produced in desugaring rather than closure conversion for now (our closure conversion doesn't seem to cover the same cases as lisp lowering yet). Covers JuliaLang/julia#56523, JuliaLang/julia#56509, JuliaLang/julia#57299. Also includes changes from JuliaLang/julia#57102 (bpart: Start enforcing minimum world age for const bparts) and JuliaLang/julia#57150 (bpart: Start enforcing min_world for global variable definitions) since the lowering changes from those appear to be amendments to the changes above.
1 parent 3c40664 commit 2b2a4c9

File tree

5 files changed

+45
-8
lines changed

5 files changed

+45
-8
lines changed

src/closure_conversion.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,6 @@ function _convert_closures(ctx::ClosureConversionCtx, ex)
354354
K"globaldecl"
355355
ex[1]
356356
_convert_closures(ctx, ex[2])
357-
# TODO (null)?
358357
]
359358
else
360359
makeleaf(ctx, ex, K"TOMBSTONE")

src/desugaring.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,7 @@ function expand_unionall_def(ctx, srcref, lhs, rhs, is_const=true)
11881188
K"block"
11891189
[K"=" rr [K"where" rhs lhs[2:end]...]]
11901190
[is_const ? K"const" : K"assign_const_if_global" name rr]
1191+
[K"latestworld_if_toplevel"]
11911192
rr
11921193
]
11931194
)
@@ -1246,7 +1247,7 @@ function expand_assignment(ctx, ex, is_const=false)
12461247
K"block"
12471248
sink_assignment(ctx, ex, rr, expand_forms_2(ctx, rhs))
12481249
[K"const" lhs rr]
1249-
# todo latestworld
1250+
[K"latestworld"]
12501251
[K"removable" rr]
12511252
]
12521253
else
@@ -1863,6 +1864,17 @@ function expand_call(ctx, ex)
18631864
expand_forms_2(ctx, farg)
18641865
expand_forms_2(ctx, _wrap_unsplatted_args(ctx, ex, args))...
18651866
]
1867+
elseif kind(farg) == K"Identifier" && farg.name_val == "include"
1868+
# world age special case
1869+
r = ssavar(ctx, ex)
1870+
@ast ctx ex [K"block"
1871+
[K"=" r [K"call"
1872+
expand_forms_2(ctx, farg)
1873+
expand_forms_2(ctx, args)...
1874+
]]
1875+
[K"latestworld_if_toplevel"]
1876+
r
1877+
]
18661878
else
18671879
@ast ctx ex [K"call"
18681880
expand_forms_2(ctx, farg)
@@ -2332,6 +2344,7 @@ function method_def_expr(ctx, srcref, callex_srcref, method_table,
23322344
ret_var # might be `nothing` and hence removed
23332345
]
23342346
]
2347+
[K"latestworld"]
23352348
[K"removable" method_metadata]
23362349
]
23372350
end
@@ -2464,6 +2477,7 @@ function expand_function_generator(ctx, srcref, callex_srcref, func_name, func_n
24642477
[K"method_defs"
24652478
gen_name
24662479
[K"block"
2480+
[K"latestworld_if_toplevel"]
24672481
method_def_expr(ctx, srcref, callex_srcref, nothing, SyntaxList(ctx),
24682482
gen_arg_names, gen_arg_types, gen_body, nothing)
24692483
]
@@ -3102,6 +3116,7 @@ function expand_function_def(ctx, ex, docs, rewrite_call=identity, rewrite_body=
31023116
end
31033117
gen_func_method_defs
31043118
kw_func_method_defs
3119+
[K"latestworld_if_toplevel"]
31053120
[K"scope_block"(scope_type=:hard)
31063121
[K"method_defs"
31073122
isnothing(bare_func_name) ? "nothing"::K"core" : bare_func_name
@@ -3415,6 +3430,7 @@ function expand_abstract_or_primitive_type(ctx, ex)
34153430
nothing_(ctx, ex)
34163431
[K"const" name newtype_var]
34173432
]
3433+
[K"latestworld"]
34183434
nothing_(ctx, ex)
34193435
]
34203436
end
@@ -3965,6 +3981,7 @@ function expand_struct_def(ctx, ex, docs)
39653981
[K"globalref" struct_name]
39663982
struct_name
39673983
]
3984+
[K"latestworld"]
39683985
# Default constructors
39693986
if isempty(inner_defs)
39703987
default_inner_constructors(ctx, ex, global_struct_name,

src/eval.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ function to_lowered_expr(mod, ex, ssa_offset=0)
302302
k == K"const" ? :const :
303303
k == K"leave" ? :leave :
304304
k == K"isdefined" ? :isdefined :
305+
k == K"latestworld" ? :latestworld :
305306
k == K"globaldecl" ? :globaldecl :
306307
k == K"pop_exception" ? :pop_exception :
307308
k == K"captured_local" ? :captured_local :

src/kinds.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ function _register_kinds()
109109
# A local variable captured into a global method. Contains the
110110
# `index` of the associated `Box` in the rewrite list.
111111
"captured_local"
112+
# Causes the linearization pass to conditionally emit a world age increment
113+
"latestworld_if_toplevel"
112114
"END_LOWERING_KINDS"
113115

114116
# The following kinds are emitted by lowering and used in Julia's untyped IR
@@ -142,6 +144,8 @@ function _register_kinds()
142144
"new_opaque_closure"
143145
# Wrapper for the lambda of around opaque closure methods
144146
"opaque_closure_method"
147+
# World age increment
148+
"latestworld"
145149
"END_IR_KINDS"
146150
])
147151
end

src/linear_ir.jl

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ function current_lambda_bindings(ctx::LinearIRContext)
9494
ctx.lambda_bindings
9595
end
9696

97+
function at_top_level(ctx)
98+
# TODO: How do we determine if we're at the top level here? Lisp does
99+
# this by checking that the current lambda takes no arguments (any
100+
# user-defined lambda will take at least one, the closure #self#) That
101+
# doesn't seem to work the same here, and even if it does, it's a bit janky.
102+
isempty(ctx.lambda_bindings.bindings)
103+
end
104+
97105
function is_valid_body_ir_argument(ctx, ex)
98106
if is_valid_ir_argument(ctx, ex)
99107
true
@@ -651,11 +659,7 @@ function compile(ctx::LinearIRContext, ex, needs_value, in_tail_pos)
651659
elseif k == K"=" || k == K"const"
652660
if k == K"const"
653661
check_no_local_bindings(ctx, ex[1], "unsupported `const` declaration on local variable")
654-
# if !at_top_level(ctx)
655-
# TODO: How do we determine this?
656-
# Lisp does this by checking that the current lambda takes no arguments
657-
# throw(LoweringError(ex, "`global const` declaration not allowed inside function"))
658-
# end
662+
# other errors (probably this one too) should be handled in previous passes
659663
end
660664
lhs = ex[1]
661665
if kind(lhs) == K"Placeholder"
@@ -827,11 +831,18 @@ function compile(ctx::LinearIRContext, ex, needs_value, in_tail_pos)
827831
end
828832
elseif k == K"gc_preserve_begin"
829833
makenode(ctx, ex, k, compile_args(ctx, children(ex)))
830-
elseif k == K"gc_preserve_end" || k == K"global"
834+
elseif k == K"gc_preserve_end"
835+
if needs_value
836+
throw(LoweringError(ex, "misplaced kind $k in value position"))
837+
end
838+
emit(ctx, ex)
839+
nothing
840+
elseif k == K"global"
831841
if needs_value
832842
throw(LoweringError(ex, "misplaced kind $k in value position"))
833843
end
834844
emit(ctx, ex)
845+
at_top_level(ctx) && emit(makenode(ctx, ex, K"latestworld"))
835846
nothing
836847
elseif k == K"meta"
837848
emit(ctx, ex)
@@ -889,6 +900,11 @@ function compile(ctx::LinearIRContext, ex, needs_value, in_tail_pos)
889900
emit(ctx, @ast ctx ex [K"=" rr ex[2]])
890901
emit(ctx, @ast ctx ex [K"globaldecl" ex[1] rr])
891902
end
903+
emit(ctx, makenode(ctx, ex, K"latestworld"))
904+
elseif k == K"latestworld"
905+
emit(ctx, makeleaf(ctx, ex, K"latestworld"))
906+
elseif k == K"latestworld_if_toplevel"
907+
at_top_level(ctx) && emit(ctx, makeleaf(ctx, ex, K"latestworld"))
892908
else
893909
throw(LoweringError(ex, "Invalid syntax; $(repr(k))"))
894910
end

0 commit comments

Comments
 (0)