@@ -248,6 +248,80 @@ JL_DLLEXPORT jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, ui
248
248
return m ;
249
249
}
250
250
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
+
251
325
JL_DLLEXPORT jl_module_t * jl_new_module (jl_sym_t * name , jl_module_t * parent )
252
326
{
253
327
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,
1171
1245
new_bpart -> min_world = new_world ;
1172
1246
if (kind == BINDING_KIND_IMPLICIT_RECOMPUTE ) {
1173
1247
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 );
1175
1249
}
1176
1250
else
1177
1251
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,
1181
1255
jl_atomic_store_release (& b -> partitions , new_bpart );
1182
1256
jl_gc_wb (b , new_bpart );
1183
1257
1184
-
1185
1258
if (jl_typeinf_world != 1 ) {
1186
1259
jl_task_t * ct = jl_current_task ;
1187
1260
size_t last_world = ct -> world_age ;
0 commit comments