diff --git a/test/ruby/test_box.rb b/test/ruby/test_box.rb index abd6a92bff7..cf3c049817d 100644 --- a/test/ruby/test_box.rb +++ b/test/ruby/test_box.rb @@ -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; diff --git a/variable.c b/variable.c index b5249afc554..06f17374487 100644 --- a/variable.c +++ b/variable.c @@ -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); }