Fix global variable aliases in a box

Under RUBY_BOX=1 the box-local gvar table is keyed by the name used for
access, so `alias $b $a` gives the two names separate slots and they
stop being synonyms.  Key it by the ID the shared rb_global_variable
was created with instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hiroshi SHIBATAandClaude Opus 5 committed 2026-09-24 16:04:59 +09:00
1 parent 85fb0e5245
commit ac0debb174
2 files changed
+26 -2
Notes: git 2026-09-24 07:05:35 +00:00

No files matched your search

+22
View File
@@ -720,6 +720,28 @@ class TestBox < Test::Unit::TestCase
end;
end
def test_global_variable_alias_in_box
assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
begin;
$aliased_original = 1
alias $aliased_alias $aliased_original
assert_equal [1, 1], [$aliased_original, $aliased_alias]
$aliased_alias = 2
assert_equal [2, 2], [$aliased_original, $aliased_alias]
in_box = Ruby::Box.new.eval(<<~'CODE')
$aliased_original = 3
seen_through_alias = $aliased_alias
$aliased_alias = 4
alias $aliased_in_box $aliased_original
$aliased_in_box = 5
[seen_through_alias, $aliased_original, $aliased_in_box]
CODE
assert_equal [3, 5, 5], in_box
assert_equal [2, 2], [$aliased_original, $aliased_alias]
end;
end
def test_match_variables_are_not_cached_in_box
assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
begin;
+4 -2
View File
@@ -551,6 +551,7 @@ struct rb_global_variable {
rb_gvar_marker_t *marker;
rb_gvar_compact_t *compactor;
struct trace_var *trace;
ID id;
bool box_ready;
bool box_dynamic;
};
@@ -638,6 +639,7 @@ global_entry_lookup(ID id, bool create_entry, bool *isolation_error)
entry->id = id;
entry->var = var;
entry->ractor_local = false;
var->id = id;
var->counter = 1;
var->data = 0;
var->getter = rb_gvar_undef_getter;
@@ -1064,7 +1066,7 @@ rb_gvar_set(ID id, VALUE val)
if (!isolation_error && gvar_use_box_tbl(box, entry)) {
use_box_tbl = true;
rb_hash_aset(box->gvar_tbl, rb_id2sym(entry->id), val);
rb_hash_aset(box->gvar_tbl, rb_id2sym(entry->var->id), val);
retval = val;
// TODO: think about trace
}
@@ -1104,7 +1106,7 @@ rb_gvar_get(ID id)
if (gvar_use_box_tbl(box, entry)) {
use_box_tbl = true;
gvars = box->gvar_tbl;
key = rb_id2sym(entry->id);
key = rb_id2sym(var->id);
if (RTEST(rb_hash_has_key(gvars, key))) { // this gvar is already cached
retval = rb_hash_aref(gvars, key);
}