@@ -248,6 +248,80 @@ JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, ui
248248 return m ;
249249}
250250
251+ // Precondition: world_counter_lock is held
252+ JL_DLLEXPORT jl_binding_partition_t * jl_declare_constant_val3 (
253+ jl_binding_t * b , jl_module_t * mod , jl_sym_t * var , jl_value_t * val ,
254+ enum jl_partition_kind constant_kind , size_t new_world )
255+ {
256+ JL_GC_PUSH1 (& val );
257+ if (!b ) {
258+ b = jl_get_module_binding (mod , var , 1 );
259+ }
260+ jl_binding_partition_t * new_bpart = NULL ;
261+ jl_binding_partition_t * bpart = jl_get_binding_partition (b , new_world );
262+ jl_ptr_kind_union_t pku = jl_atomic_load_relaxed (& bpart -> restriction );
263+ while (!new_bpart ) {
264+ enum jl_partition_kind kind = decode_restriction_kind (pku );
265+ if (jl_bkind_is_some_constant (kind )) {
266+ if (!val ) {
267+ new_bpart = bpart ;
268+ break ;
269+ }
270+ jl_value_t * old = decode_restriction_value (pku );
271+ JL_GC_PROMISE_ROOTED (old );
272+ if (jl_egal (val , old )) {
273+ new_bpart = bpart ;
274+ break ;
275+ }
276+ } else if (jl_bkind_is_some_import (kind ) && kind != BINDING_KIND_IMPLICIT ) {
277+ jl_errorf ("cannot declare %s.%s constant; it was already declared as an import" ,
278+ jl_symbol_name (mod -> name ), jl_symbol_name (var ));
279+ } else if (kind == BINDING_KIND_GLOBAL ) {
280+ jl_errorf ("cannot declare %s.%s constant; it was already declared global" ,
281+ jl_symbol_name (mod -> name ), jl_symbol_name (var ));
282+ }
283+ if (bpart -> min_world == new_world ) {
284+ if (!jl_atomic_cmpswap (& bpart -> restriction , & pku , encode_restriction (val , constant_kind ))) {
285+ continue ;
286+ } else if (val ) {
287+ jl_gc_wb (bpart , val );
288+ }
289+ new_bpart = bpart ;
290+ } else {
291+ new_bpart = jl_replace_binding_locked (b , bpart , val , constant_kind , new_world );
292+ }
293+ int need_backdate = new_world && val ;
294+ if (need_backdate ) {
295+ // We will backdate as long as this partition was never explicitly
296+ // declared const, global, or imported.
297+ jl_binding_partition_t * prev_bpart = bpart ;
298+ for (;;) {
299+ jl_ptr_kind_union_t prev_pku = jl_atomic_load_relaxed (& prev_bpart -> restriction );
300+ enum jl_partition_kind prev_kind = decode_restriction_kind (prev_pku );
301+ if (jl_bkind_is_some_constant (prev_kind ) || prev_kind == BINDING_KIND_GLOBAL ||
302+ (jl_bkind_is_some_import (prev_kind ))) {
303+ need_backdate = 0 ;
304+ break ;
305+ }
306+ if (prev_bpart -> min_world == 0 )
307+ break ;
308+ prev_bpart = jl_get_binding_partition (b , prev_bpart -> min_world - 1 );
309+ }
310+ }
311+ // If backdate is required, create one new binding partition to cover
312+ // the entire backdate range.
313+ if (need_backdate ) {
314+ jl_binding_partition_t * backdate_bpart = new_binding_partition ();
315+ jl_atomic_store_relaxed (& backdate_bpart -> restriction , encode_restriction (val , BINDING_KIND_BACKDATED_CONST ));
316+ jl_atomic_store_relaxed (& backdate_bpart -> max_world , new_world - 1 );
317+ jl_atomic_store_release (& new_bpart -> next , backdate_bpart );
318+ jl_gc_wb (new_bpart , backdate_bpart );
319+ }
320+ }
321+ JL_GC_POP ();
322+ return new_bpart ;
323+ }
324+
251325JL_DLLEXPORT jl_module_t * jl_new_module (jl_sym_t * name , jl_module_t * parent )
252326{
253327 return jl_new_module_ (name , parent , 1 );
@@ -1171,7 +1245,7 @@ JL_DLLEXPORT jl_binding_partition_t *jl_replace_binding_locked(jl_binding_t *b,
11711245 new_bpart -> min_world = new_world ;
11721246 if (kind == BINDING_KIND_IMPLICIT_RECOMPUTE ) {
11731247 assert (!restriction_val );
1174- jl_check_new_binding_implicit (new_bpart , b , NULL , new_world );
1248+ jl_check_new_binding_implicit (new_bpart /* callee rooted */ , b , NULL , new_world );
11751249 }
11761250 else
11771251 jl_atomic_store_relaxed (& new_bpart -> restriction , encode_restriction (restriction_val , kind ));
@@ -1181,7 +1255,6 @@ JL_DLLEXPORT jl_binding_partition_t *jl_replace_binding_locked(jl_binding_t *b,
11811255 jl_atomic_store_release (& b -> partitions , new_bpart );
11821256 jl_gc_wb (b , new_bpart );
11831257
1184-
11851258 if (jl_typeinf_world != 1 ) {
11861259 jl_task_t * ct = jl_current_task ;
11871260 size_t last_world = ct -> world_age ;
0 commit comments