Skip to content

Commit ea1a4e4

Browse files
committed
fix isconst definition/accessor issues with binding partitions
The problem was that isconst was declaring true when it was actually a back-dated (e.g. mutable) value, which confuses the runtime (e.g. show_datatype) into emitting warnings that are not warranted.
1 parent dc8bc73 commit ea1a4e4

File tree

9 files changed

+33
-29
lines changed

9 files changed

+33
-29
lines changed

src/codegen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3199,7 +3199,7 @@ static jl_cgval_t emit_globalref(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t *
31993199
if (!jl_get_binding_leaf_partitions_restriction_kind(bnd, &rkp, ctx.min_world, ctx.max_world)) {
32003200
return emit_globalref_runtime(ctx, bnd, mod, name);
32013201
}
3202-
if (jl_bkind_is_some_constant(rkp.kind) && rkp.kind != PARTITION_KIND_BACKDATED_CONST) {
3202+
if (jl_bkind_is_real_constant(rkp.kind) || rkp.kind == PARTITION_KIND_UNDEF_CONST) {
32033203
if (rkp.maybe_depwarn) {
32043204
Value *bp = julia_binding_gv(ctx, bnd);
32053205
ctx.builder.CreateCall(prepare_call(jldepcheck_func), { bp });
@@ -3789,7 +3789,7 @@ static jl_cgval_t emit_isdefinedglobal(jl_codectx_t &ctx, jl_module_t *modu, jl_
37893789
jl_binding_t *bnd = allow_import ? jl_get_binding(modu, name) : jl_get_module_binding(modu, name, 0);
37903790
struct restriction_kind_pair rkp = { NULL, NULL, PARTITION_KIND_GUARD, 0 };
37913791
if (allow_import && jl_get_binding_leaf_partitions_restriction_kind(bnd, &rkp, ctx.min_world, ctx.max_world)) {
3792-
if (jl_bkind_is_some_constant(rkp.kind) && rkp.restriction)
3792+
if (jl_bkind_is_real_constant(rkp.kind))
37933793
return mark_julia_const(ctx, jl_true);
37943794
if (rkp.kind == PARTITION_KIND_GLOBAL) {
37953795
Value *bp = julia_binding_gv(ctx, rkp.binding_if_global);

src/gf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ int foreach_mtable_in_module(
771771
if ((void*)b == jl_nothing)
772772
break;
773773
jl_sym_t *name = b->globalref->name;
774-
jl_value_t *v = jl_get_binding_value_if_const(b);
774+
jl_value_t *v = jl_get_latest_binding_value_if_const(b);
775775
if (v) {
776776
jl_value_t *uw = jl_unwrap_unionall(v);
777777
if (jl_is_datatype(uw)) {

src/julia.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,9 +1942,9 @@ JL_DLLEXPORT jl_sym_t *jl_tagged_gensym(const char *str, size_t len);
19421942
JL_DLLEXPORT jl_sym_t *jl_get_root_symbol(void);
19431943
JL_DLLEXPORT jl_value_t *jl_get_binding_value(jl_binding_t *b JL_PROPAGATES_ROOT);
19441944
JL_DLLEXPORT jl_value_t *jl_get_binding_value_in_world(jl_binding_t *b JL_PROPAGATES_ROOT, size_t world);
1945-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_const(jl_binding_t *b JL_PROPAGATES_ROOT);
1946-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_resolved_debug_only(jl_binding_t *b JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT;
1947-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_latest_resolved_and_const_debug_only(jl_binding_t *b JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT;
1945+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_const(jl_binding_t *b JL_PROPAGATES_ROOT);
1946+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_resolved_debug_only(jl_binding_t *b JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT;
1947+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_resolved_and_const_debug_only(jl_binding_t *b JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT;
19481948
JL_DLLEXPORT jl_value_t *jl_declare_const_gf(jl_module_t *mod, jl_sym_t *name);
19491949
JL_DLLEXPORT jl_method_t *jl_method_def(jl_svec_t *argdata, jl_methtable_t *mt, jl_code_info_t *f, jl_module_t *module);
19501950
JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *linfo, size_t world, jl_code_instance_t **cache);

src/julia_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,10 @@ STATIC_INLINE int jl_bkind_is_defined_constant(enum jl_partition_kind kind) JL_N
982982
return kind == PARTITION_KIND_IMPLICIT_CONST || kind == PARTITION_KIND_CONST || kind == PARTITION_KIND_CONST_IMPORT || kind == PARTITION_KIND_BACKDATED_CONST;
983983
}
984984

985+
STATIC_INLINE int jl_bkind_is_real_constant(enum jl_partition_kind kind) JL_NOTSAFEPOINT {
986+
return kind == PARTITION_KIND_IMPLICIT_CONST || kind == PARTITION_KIND_CONST || kind == PARTITION_KIND_CONST_IMPORT;
987+
}
988+
985989
JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition(jl_binding_t *b JL_PROPAGATES_ROOT, size_t world) JL_GLOBALLY_ROOTED;
986990
JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition_with_hint(jl_binding_t *b JL_PROPAGATES_ROOT, jl_binding_partition_t *previous_part, size_t world) JL_GLOBALLY_ROOTED;
987991
JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition_all(jl_binding_t *b JL_PROPAGATES_ROOT, size_t min_world, size_t max_world) JL_GLOBALLY_ROOTED;

src/method.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ static jl_value_t *resolve_definition_effects(jl_value_t *expr, jl_module_t *mod
224224
jl_sym_t *fe_sym = jl_globalref_name(fe);
225225
// look at some known called functions
226226
jl_binding_t *b = jl_get_binding(fe_mod, fe_sym);
227-
if (jl_get_binding_value_if_const(b) == BUILTIN(tuple)) {
227+
if (jl_get_latest_binding_value_if_const(b) == BUILTIN(tuple)) {
228228
size_t j;
229229
for (j = 1; j < nargs; j++) {
230230
if (!jl_is_quotenode(jl_exprarg(e, j)))

src/module.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_leaf_partitions_value_if_const(jl_bindin
461461
struct restriction_kind_pair rkp = { NULL, NULL, PARTITION_KIND_GUARD, 0 };
462462
if (!jl_get_binding_leaf_partitions_restriction_kind(b, &rkp, min_world, max_world))
463463
return NULL;
464-
if (jl_bkind_is_some_constant(rkp.kind) && rkp.kind != PARTITION_KIND_BACKDATED_CONST) {
464+
if (jl_bkind_is_real_constant(rkp.kind)) {
465465
*maybe_depwarn = rkp.maybe_depwarn;
466466
return rkp.restriction;
467467
}
@@ -578,7 +578,7 @@ JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val3(
578578
for (;;) {
579579
enum jl_partition_kind prev_kind = jl_binding_kind(prev_bpart);
580580
if (jl_bkind_is_some_constant(prev_kind) || prev_kind == PARTITION_KIND_GLOBAL ||
581-
(jl_bkind_is_some_import(prev_kind))) {
581+
jl_bkind_is_some_import(prev_kind)) {
582582
need_backdate = 0;
583583
break;
584584
}
@@ -917,22 +917,23 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_seqcst(jl_binding_t *b)
917917
return jl_atomic_load(&b->value);
918918
}
919919

920-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_const(jl_binding_t *b)
920+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_const(jl_binding_t *b)
921921
{
922-
jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age);
923-
jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age);
922+
// See note below. Note that this is for some deprecated uses, and should not be added to new code.
923+
size_t world = jl_atomic_load_relaxed(&jl_world_counter);
924+
jl_binding_partition_t *bpart = jl_get_binding_partition(b, world);
925+
jl_walk_binding_inplace(&b, &bpart, world);
924926
enum jl_partition_kind kind = jl_binding_kind(bpart);
925927
if (jl_bkind_is_some_guard(kind))
926928
return NULL;
927-
if (!jl_bkind_is_some_constant(kind))
929+
if (!jl_bkind_is_real_constant(kind))
928930
return NULL;
929-
check_backdated_binding(b, kind);
930931
return bpart->restriction;
931932
}
932933

933-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_latest_resolved_and_const_debug_only(jl_binding_t *b)
934+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_resolved_and_const_debug_only(jl_binding_t *b)
934935
{
935-
// Unlike jl_get_binding_value_if_const this doesn't try to allocate new binding partitions if they
936+
// Unlike jl_get_latest_binding_value_if_const this doesn't try to allocate new binding partitions if they
936937
// don't already exist, making this JL_NOTSAFEPOINT. However, as a result, this may fail to return
937938
// a value - even if one does exist. It should only be used for reflection/debugging when the integrity
938939
// of the runtime is not guaranteed.
@@ -942,18 +943,17 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_latest_resolved_and_const_debug
942943
if (!bpart)
943944
return NULL;
944945
size_t max_world = jl_atomic_load_relaxed(&bpart->max_world);
945-
if (jl_atomic_load_relaxed(&bpart->min_world) > jl_current_task->world_age || jl_current_task->world_age > max_world)
946+
if (max_world != ~(size_t)0)
946947
return NULL;
947948
enum jl_partition_kind kind = jl_binding_kind(bpart);
948949
if (jl_bkind_is_some_guard(kind))
949950
return NULL;
950-
if (!jl_bkind_is_some_constant(kind))
951+
if (!jl_bkind_is_real_constant(kind))
951952
return NULL;
952-
check_backdated_binding(b, kind);
953953
return bpart->restriction;
954954
}
955955

956-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_resolved_debug_only(jl_binding_t *b)
956+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_resolved_debug_only(jl_binding_t *b)
957957
{
958958
// See note above. Use for debug/reflection purposes only.
959959
if (!b)
@@ -962,15 +962,14 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_resolved_debug_only(jl_binding_
962962
if (!bpart)
963963
return NULL;
964964
size_t max_world = jl_atomic_load_relaxed(&bpart->max_world);
965-
if (jl_atomic_load_relaxed(&bpart->min_world) > jl_current_task->world_age || jl_current_task->world_age > max_world)
965+
if (max_world != ~(size_t)0)
966966
return NULL;
967967
enum jl_partition_kind kind = jl_binding_kind(bpart);
968968
if (jl_bkind_is_some_guard(kind))
969969
return NULL;
970970
if (jl_bkind_is_some_import(kind))
971971
return NULL;
972972
if (jl_bkind_is_some_constant(kind)) {
973-
check_backdated_binding(b, kind);
974973
return bpart->restriction;
975974
}
976975
return jl_atomic_load_relaxed(&b->value);
@@ -1005,6 +1004,7 @@ static jl_module_t *jl_binding_dbgmodule(jl_binding_t *b)
10051004
// along the way.
10061005
JL_DLLEXPORT jl_value_t *jl_get_existing_strong_gf(jl_binding_t *b, size_t new_world)
10071006
{
1007+
assert(new_world > jl_atomic_load_relaxed(&jl_world_counter));
10081008
jl_binding_partition_t *bpart = jl_get_binding_partition(b, new_world);
10091009
enum jl_partition_kind kind = jl_binding_kind(bpart);
10101010
if (jl_bkind_is_some_constant(kind) && kind != PARTITION_KIND_IMPLICIT_CONST)
@@ -1026,7 +1026,7 @@ JL_DLLEXPORT jl_value_t *jl_get_existing_strong_gf(jl_binding_t *b, size_t new_w
10261026
check_safe_newbinding(b->globalref->mod, b->globalref->name);
10271027
return NULL;
10281028
}
1029-
jl_module_t *from = jl_binding_dbgmodule(b);\
1029+
jl_module_t *from = jl_binding_dbgmodule(b);
10301030
assert(from); // Can only be NULL if implicit, which we excluded above
10311031
jl_errorf("invalid method definition in %s: exported function %s.%s does not exist",
10321032
jl_module_debug_name(b->globalref->mod), jl_module_debug_name(from), jl_symbol_name(b->globalref->name));
@@ -1722,7 +1722,7 @@ JL_DLLEXPORT int jl_globalref_is_const(jl_globalref_t *gr)
17221722
b = jl_get_module_binding(gr->mod, gr->name, 1);
17231723
jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age);
17241724
jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age);
1725-
return jl_bkind_is_some_constant(jl_binding_kind(bpart));
1725+
return jl_bkind_is_real_constant(jl_binding_kind(bpart));
17261726
}
17271727

17281728
JL_DLLEXPORT void jl_disable_binding(jl_globalref_t *gr)
@@ -1751,7 +1751,7 @@ JL_DLLEXPORT int jl_is_const(jl_module_t *m, jl_sym_t *var)
17511751
jl_binding_t *b = jl_get_binding(m, var);
17521752
jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age);
17531753
jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age);
1754-
return b && jl_bkind_is_some_constant(jl_binding_kind(bpart));
1754+
return b && jl_bkind_is_real_constant(jl_binding_kind(bpart));
17551755
}
17561756

17571757
// set the deprecated flag for a binding:

src/rtutils.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ JL_DLLEXPORT jl_value_t *jl_stderr_obj(void) JL_NOTSAFEPOINT
579579
if (jl_base_module == NULL)
580580
return NULL;
581581
jl_binding_t *stderr_obj = jl_get_module_binding(jl_base_module, jl_symbol("stderr"), 0);
582-
return stderr_obj ? jl_get_binding_value_if_resolved_debug_only(stderr_obj) : NULL;
582+
return stderr_obj ? jl_get_latest_binding_value_if_resolved_debug_only(stderr_obj) : NULL;
583583
}
584584

585585
// toys for debugging ---------------------------------------------------------
@@ -674,7 +674,7 @@ static int is_globname_binding(jl_value_t *v, jl_datatype_t *dv) JL_NOTSAFEPOINT
674674
jl_sym_t *globname = dv->name->mt != NULL ? dv->name->mt->name : NULL;
675675
if (globname && dv->name->module) {
676676
jl_binding_t *b = jl_get_module_binding(dv->name->module, globname, 0);
677-
jl_value_t *bv = jl_get_binding_value_if_latest_resolved_and_const_debug_only(b);
677+
jl_value_t *bv = jl_get_latest_binding_value_if_resolved_and_const_debug_only(b);
678678
if (bv && ((jl_value_t*)dv == v ? jl_typeof(bv) == v : bv == v))
679679
return 1;
680680
}

src/toplevel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ static void expr_attributes(jl_value_t *v, jl_array_t *body, int *has_ccall, int
417417
jl_module_t *mod = jl_globalref_mod(f);
418418
jl_sym_t *name = jl_globalref_name(f);
419419
jl_binding_t *b = jl_get_binding(mod, name);
420-
called = jl_get_binding_value_if_const(b);
420+
called = jl_get_latest_binding_value_if_const(b);
421421
}
422422
else if (jl_is_quotenode(f)) {
423423
called = jl_quotenode_value(f);

test/syntax.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1939,7 +1939,7 @@ end
19391939
# eval'ing :const exprs
19401940
eval(Expr(:const, :_var_30877))
19411941
@test !isdefined(@__MODULE__, :_var_30877)
1942-
@test isconst(@__MODULE__, :_var_30877)
1942+
@test !isconst(@__MODULE__, :_var_30877)
19431943

19441944
# anonymous kw function in value position at top level
19451945
f30926 = function (;k=0)

0 commit comments

Comments
 (0)