diff --git a/base/boot.jl b/base/boot.jl index 88a4e7438671e..0df0cde64f8c0 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -271,6 +271,8 @@ macro nospecialize(x) end Expr(@nospecialize args...) = _expr(args...) +macro latestworld() Expr(:latestworld) end + _is_internal(__module__) = __module__ === Core # can be used in place of `@assume_effects :total` (supposed to be used for bootstrapping) macro _total_meta() diff --git a/src/ast.c b/src/ast.c index ea1de429a946c..474c0661f5230 100644 --- a/src/ast.c +++ b/src/ast.c @@ -119,6 +119,7 @@ JL_DLLEXPORT jl_sym_t *jl_release_sym; JL_DLLEXPORT jl_sym_t *jl_acquire_release_sym; JL_DLLEXPORT jl_sym_t *jl_sequentially_consistent_sym; JL_DLLEXPORT jl_sym_t *jl_uninferred_sym; +JL_DLLEXPORT jl_sym_t *jl_latestworld_sym; static const uint8_t flisp_system_image[] = { #include @@ -461,6 +462,7 @@ void jl_init_common_symbols(void) jl_acquire_release_sym = jl_symbol("acquire_release"); jl_sequentially_consistent_sym = jl_symbol("sequentially_consistent"); jl_uninferred_sym = jl_symbol("uninferred"); + jl_latestworld_sym = jl_symbol("latestworld"); } JL_DLLEXPORT void jl_lisp_prompt(void) diff --git a/src/interpreter.c b/src/interpreter.c index f9d981687c631..13dc45cf2ae6e 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -643,6 +643,9 @@ static jl_value_t *eval_body(jl_array_t *stmts, interpreter_state *s, size_t ip, jl_eval_const_decl(s->module, jl_exprarg(stmt, 0), val); s->locals[jl_source_nslots(s->src) + s->ip] = jl_nothing; } + else if (head == jl_latestworld_sym) { + ct->world_age = jl_atomic_load_acquire(&jl_world_counter); + } else if (jl_is_toplevel_only_expr(stmt)) { jl_toplevel_eval(s->module, stmt); } diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 7acc8a1954bc5..e82c436e5a730 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -4512,6 +4512,7 @@ f(x) = yt(x) ((struct_type) "\"struct\" expression") ((method) "method definition") ((set_binding_type!) (string "type declaration for global \"" (deparse (cadr e)) "\"")) + ((latestworld) "World age increment") (else (string "\"" h "\" expression")))) (if (not (null? (cadr lam))) (error (string (head-to-text (car e)) " not at top level")))) @@ -4979,8 +4980,13 @@ f(x) = yt(x) (if tail (emit-return tail val)) val)) + ((latestworld-if-toplevel) + (if (null? (cadr lam)) + (emit `(latestworld))) + '(null)) + ;; other top level expressions - ((import using export public) + ((import using export public latestworld) (check-top-level e) (emit e) (let ((have-ret? (and (pair? code) (pair? (car code)) (eq? (caar code) 'return)))) diff --git a/src/julia_internal.h b/src/julia_internal.h index 776fea3b1dbf1..db09477de287b 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -1856,6 +1856,7 @@ extern JL_DLLEXPORT jl_sym_t *jl_release_sym; extern JL_DLLEXPORT jl_sym_t *jl_acquire_release_sym; extern JL_DLLEXPORT jl_sym_t *jl_sequentially_consistent_sym; extern JL_DLLEXPORT jl_sym_t *jl_uninferred_sym; +extern JL_DLLEXPORT jl_sym_t *jl_latestworld_sym; JL_DLLEXPORT enum jl_memory_order jl_get_atomic_order(jl_sym_t *order, char loading, char storing); JL_DLLEXPORT enum jl_memory_order jl_get_atomic_order_checked(jl_sym_t *order, char loading, char storing); diff --git a/src/toplevel.c b/src/toplevel.c index b0163683cf87c..cedc008af5cd0 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -607,7 +607,8 @@ int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT ((jl_expr_t*)e)->head == jl_const_sym || ((jl_expr_t*)e)->head == jl_toplevel_sym || ((jl_expr_t*)e)->head == jl_error_sym || - ((jl_expr_t*)e)->head == jl_incomplete_sym); + ((jl_expr_t*)e)->head == jl_incomplete_sym || + ((jl_expr_t*)e)->head == jl_latestworld_sym); } int jl_needs_lowering(jl_value_t *e) JL_NOTSAFEPOINT