Skip to content

Commit 1628ac8

Browse files
vtjnashKristofferC
authored andcommitted
fix isconst definition/accessor issues with binding partitions (#58261)
(cherry picked from commit 58daba4)
1 parent a430f2e commit 1628ac8

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
@@ -3240,7 +3240,7 @@ static jl_cgval_t emit_globalref(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t *
32403240
if (!jl_get_binding_leaf_partitions_restriction_kind(bnd, &rkp, ctx.min_world, ctx.max_world)) {
32413241
return emit_globalref_runtime(ctx, bnd, mod, name);
32423242
}
3243-
if (jl_bkind_is_some_constant(rkp.kind) && rkp.kind != PARTITION_KIND_BACKDATED_CONST) {
3243+
if (jl_bkind_is_real_constant(rkp.kind) || rkp.kind == PARTITION_KIND_UNDEF_CONST) {
32443244
if (rkp.maybe_depwarn) {
32453245
Value *bp = julia_binding_gv(ctx, bnd);
32463246
ctx.builder.CreateCall(prepare_call(jldepcheck_func), { bp });
@@ -3826,7 +3826,7 @@ static jl_cgval_t emit_isdefinedglobal(jl_codectx_t &ctx, jl_module_t *modu, jl_
38263826
jl_binding_t *bnd = allow_import ? jl_get_binding(modu, name) : jl_get_module_binding(modu, name, 0);
38273827
struct restriction_kind_pair rkp = { NULL, NULL, PARTITION_KIND_GUARD, 0 };
38283828
if (allow_import && jl_get_binding_leaf_partitions_restriction_kind(bnd, &rkp, ctx.min_world, ctx.max_world)) {
3829-
if (jl_bkind_is_some_constant(rkp.kind) && rkp.restriction)
3829+
if (jl_bkind_is_real_constant(rkp.kind))
38303830
return mark_julia_const(ctx, jl_true);
38313831
if (rkp.kind == PARTITION_KIND_GLOBAL) {
38323832
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
@@ -780,7 +780,7 @@ int foreach_mtable_in_module(
780780
if ((void*)b == jl_nothing)
781781
break;
782782
jl_sym_t *name = b->globalref->name;
783-
jl_value_t *v = jl_get_binding_value_if_const(b);
783+
jl_value_t *v = jl_get_latest_binding_value_if_const(b);
784784
if (v) {
785785
jl_value_t *uw = jl_unwrap_unionall(v);
786786
if (jl_is_datatype(uw)) {

src/julia.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,9 +1956,9 @@ JL_DLLEXPORT jl_sym_t *jl_tagged_gensym(const char *str, size_t len);
19561956
JL_DLLEXPORT jl_sym_t *jl_get_root_symbol(void);
19571957
JL_DLLEXPORT jl_value_t *jl_get_binding_value(jl_binding_t *b JL_PROPAGATES_ROOT);
19581958
JL_DLLEXPORT jl_value_t *jl_get_binding_value_in_world(jl_binding_t *b JL_PROPAGATES_ROOT, size_t world);
1959-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_const(jl_binding_t *b JL_PROPAGATES_ROOT);
1960-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_resolved_debug_only(jl_binding_t *b JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT;
1961-
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;
1959+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_const(jl_binding_t *b JL_PROPAGATES_ROOT);
1960+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_resolved_debug_only(jl_binding_t *b JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT;
1961+
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;
19621962
JL_DLLEXPORT jl_value_t *jl_declare_const_gf(jl_module_t *mod, jl_sym_t *name);
19631963
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);
19641964
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
@@ -989,6 +989,10 @@ STATIC_INLINE int jl_bkind_is_defined_constant(enum jl_partition_kind kind) JL_N
989989
return kind == PARTITION_KIND_IMPLICIT_CONST || kind == PARTITION_KIND_CONST || kind == PARTITION_KIND_CONST_IMPORT || kind == PARTITION_KIND_BACKDATED_CONST;
990990
}
991991

992+
STATIC_INLINE int jl_bkind_is_real_constant(enum jl_partition_kind kind) JL_NOTSAFEPOINT {
993+
return kind == PARTITION_KIND_IMPLICIT_CONST || kind == PARTITION_KIND_CONST || kind == PARTITION_KIND_CONST_IMPORT;
994+
}
995+
992996
JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition(jl_binding_t *b JL_PROPAGATES_ROOT, size_t world) JL_GLOBALLY_ROOTED;
993997
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;
994998
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
@@ -225,7 +225,7 @@ static jl_value_t *resolve_definition_effects(jl_value_t *expr, jl_module_t *mod
225225
jl_sym_t *fe_sym = jl_globalref_name(fe);
226226
// look at some known called functions
227227
jl_binding_t *b = jl_get_binding(fe_mod, fe_sym);
228-
if (jl_get_binding_value_if_const(b) == jl_builtin_tuple) {
228+
if (jl_get_latest_binding_value_if_const(b) == jl_builtin_tuple) {
229229
size_t j;
230230
for (j = 1; j < nargs; j++) {
231231
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
@@ -463,7 +463,7 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_leaf_partitions_value_if_const(jl_bindin
463463
struct restriction_kind_pair rkp = { NULL, NULL, PARTITION_KIND_GUARD, 0 };
464464
if (!jl_get_binding_leaf_partitions_restriction_kind(b, &rkp, min_world, max_world))
465465
return NULL;
466-
if (jl_bkind_is_some_constant(rkp.kind) && rkp.kind != PARTITION_KIND_BACKDATED_CONST) {
466+
if (jl_bkind_is_real_constant(rkp.kind)) {
467467
*maybe_depwarn = rkp.maybe_depwarn;
468468
return rkp.restriction;
469469
}
@@ -581,7 +581,7 @@ JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val3(
581581
for (;;) {
582582
enum jl_partition_kind prev_kind = jl_binding_kind(prev_bpart);
583583
if (jl_bkind_is_some_constant(prev_kind) || prev_kind == PARTITION_KIND_GLOBAL ||
584-
(jl_bkind_is_some_import(prev_kind))) {
584+
jl_bkind_is_some_import(prev_kind)) {
585585
need_backdate = 0;
586586
break;
587587
}
@@ -923,22 +923,23 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_seqcst(jl_binding_t *b)
923923
return jl_atomic_load(&b->value);
924924
}
925925

926-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_const(jl_binding_t *b)
926+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_const(jl_binding_t *b)
927927
{
928-
jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age);
929-
jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age);
928+
// See note below. Note that this is for some deprecated uses, and should not be added to new code.
929+
size_t world = jl_atomic_load_relaxed(&jl_world_counter);
930+
jl_binding_partition_t *bpart = jl_get_binding_partition(b, world);
931+
jl_walk_binding_inplace(&b, &bpart, world);
930932
enum jl_partition_kind kind = jl_binding_kind(bpart);
931933
if (jl_bkind_is_some_guard(kind))
932934
return NULL;
933-
if (!jl_bkind_is_some_constant(kind))
935+
if (!jl_bkind_is_real_constant(kind))
934936
return NULL;
935-
check_backdated_binding(b, kind);
936937
return bpart->restriction;
937938
}
938939

939-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_latest_resolved_and_const_debug_only(jl_binding_t *b)
940+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_resolved_and_const_debug_only(jl_binding_t *b)
940941
{
941-
// Unlike jl_get_binding_value_if_const this doesn't try to allocate new binding partitions if they
942+
// Unlike jl_get_latest_binding_value_if_const this doesn't try to allocate new binding partitions if they
942943
// don't already exist, making this JL_NOTSAFEPOINT. However, as a result, this may fail to return
943944
// a value - even if one does exist. It should only be used for reflection/debugging when the integrity
944945
// of the runtime is not guaranteed.
@@ -948,18 +949,17 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_latest_resolved_and_const_debug
948949
if (!bpart)
949950
return NULL;
950951
size_t max_world = jl_atomic_load_relaxed(&bpart->max_world);
951-
if (jl_atomic_load_relaxed(&bpart->min_world) > jl_current_task->world_age || jl_current_task->world_age > max_world)
952+
if (max_world != ~(size_t)0)
952953
return NULL;
953954
enum jl_partition_kind kind = jl_binding_kind(bpart);
954955
if (jl_bkind_is_some_guard(kind))
955956
return NULL;
956-
if (!jl_bkind_is_some_constant(kind))
957+
if (!jl_bkind_is_real_constant(kind))
957958
return NULL;
958-
check_backdated_binding(b, kind);
959959
return bpart->restriction;
960960
}
961961

962-
JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_resolved_debug_only(jl_binding_t *b)
962+
JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_resolved_debug_only(jl_binding_t *b)
963963
{
964964
// See note above. Use for debug/reflection purposes only.
965965
if (!b)
@@ -968,15 +968,14 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_resolved_debug_only(jl_binding_
968968
if (!bpart)
969969
return NULL;
970970
size_t max_world = jl_atomic_load_relaxed(&bpart->max_world);
971-
if (jl_atomic_load_relaxed(&bpart->min_world) > jl_current_task->world_age || jl_current_task->world_age > max_world)
971+
if (max_world != ~(size_t)0)
972972
return NULL;
973973
enum jl_partition_kind kind = jl_binding_kind(bpart);
974974
if (jl_bkind_is_some_guard(kind))
975975
return NULL;
976976
if (jl_bkind_is_some_import(kind))
977977
return NULL;
978978
if (jl_bkind_is_some_constant(kind)) {
979-
check_backdated_binding(b, kind);
980979
return bpart->restriction;
981980
}
982981
return jl_atomic_load_relaxed(&b->value);
@@ -1011,6 +1010,7 @@ static jl_module_t *jl_binding_dbgmodule(jl_binding_t *b)
10111010
// along the way.
10121011
JL_DLLEXPORT jl_value_t *jl_get_existing_strong_gf(jl_binding_t *b, size_t new_world)
10131012
{
1013+
assert(new_world > jl_atomic_load_relaxed(&jl_world_counter));
10141014
jl_binding_partition_t *bpart = jl_get_binding_partition(b, new_world);
10151015
enum jl_partition_kind kind = jl_binding_kind(bpart);
10161016
if (jl_bkind_is_some_constant(kind) && kind != PARTITION_KIND_IMPLICIT_CONST)
@@ -1032,7 +1032,7 @@ JL_DLLEXPORT jl_value_t *jl_get_existing_strong_gf(jl_binding_t *b, size_t new_w
10321032
check_safe_newbinding(b->globalref->mod, b->globalref->name);
10331033
return NULL;
10341034
}
1035-
jl_module_t *from = jl_binding_dbgmodule(b);\
1035+
jl_module_t *from = jl_binding_dbgmodule(b);
10361036
assert(from); // Can only be NULL if implicit, which we excluded above
10371037
jl_errorf("invalid method definition in %s: exported function %s.%s does not exist",
10381038
jl_module_debug_name(b->globalref->mod), jl_module_debug_name(from), jl_symbol_name(b->globalref->name));
@@ -1725,7 +1725,7 @@ JL_DLLEXPORT int jl_globalref_is_const(jl_globalref_t *gr)
17251725
b = jl_get_module_binding(gr->mod, gr->name, 1);
17261726
jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age);
17271727
jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age);
1728-
return jl_bkind_is_some_constant(jl_binding_kind(bpart));
1728+
return jl_bkind_is_real_constant(jl_binding_kind(bpart));
17291729
}
17301730

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

17561756
// 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
@@ -1935,7 +1935,7 @@ end
19351935
# eval'ing :const exprs
19361936
eval(Expr(:const, :_var_30877))
19371937
@test !isdefined(@__MODULE__, :_var_30877)
1938-
@test isconst(@__MODULE__, :_var_30877)
1938+
@test !isconst(@__MODULE__, :_var_30877)
19391939

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

0 commit comments

Comments
 (0)