Skip to content

Commit 526344b

Browse files
afurmtagomoris
authored andcommitted
Fix Box regexp match vars after non-match
1 parent f70c081 commit 526344b

4 files changed

Lines changed: 44 additions & 5 deletions

File tree

internal/variable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ rb_gvar_setter_t *rb_gvar_setter_function_of(ID);
2929
void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_);
3030
void rb_gvar_ractor_local(const char *name);
3131
void rb_gvar_box_ready(const char *name);
32+
void rb_gvar_box_dynamic(const char *name);
3233

3334
/**
3435
* Sets the name of a module.

re.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4900,6 +4900,11 @@ Init_Regexp(void)
49004900
rb_gvar_ractor_local("$`");
49014901
rb_gvar_ractor_local("$'");
49024902
rb_gvar_ractor_local("$+");
4903+
rb_gvar_box_dynamic("$~");
4904+
rb_gvar_box_dynamic("$&");
4905+
rb_gvar_box_dynamic("$`");
4906+
rb_gvar_box_dynamic("$'");
4907+
rb_gvar_box_dynamic("$+");
49034908

49044909
rb_define_virtual_variable("$=", ignorecase_getter, ignorecase_setter);
49054910

test/ruby/test_box.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,26 @@ def test_global_variables
563563
end
564564
end
565565

566+
def test_match_variables_are_not_cached_in_box
567+
assert_separately([ENV_ENABLE_BOX], __FILE__, __LINE__, "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
568+
begin;
569+
/(?<a>foo)/ =~ 'bar'
570+
/(?<b>baz)/ =~ 'baz'
571+
assert_equal "baz", b
572+
assert_equal "baz", $~.to_s
573+
574+
/foo/ =~ 'bar'
575+
assert_nil $~
576+
/(?<word>foo)(bar)?/ =~ 'foo'
577+
assert_equal "foo", word
578+
assert_equal "foo", $~.to_s
579+
assert_equal "foo", $&
580+
assert_equal "", $`
581+
assert_equal "", $'
582+
assert_equal "foo", $+
583+
end;
584+
end
585+
566586
def test_load_path_and_loaded_features
567587
setup_box
568588

variable.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ struct rb_global_variable {
534534
rb_gvar_compact_t *compactor;
535535
struct trace_var *trace;
536536
bool box_ready;
537+
bool box_dynamic;
537538
};
538539

539540
struct rb_global_entry {
@@ -618,6 +619,13 @@ rb_gvar_box_ready(const char *name)
618619
entry->var->box_ready = true;
619620
}
620621

622+
void
623+
rb_gvar_box_dynamic(const char *name)
624+
{
625+
struct rb_global_entry *entry = rb_find_global_entry(rb_intern(name));
626+
entry->var->box_dynamic = true;
627+
}
628+
621629
static void
622630
rb_gvar_undef_compactor(void *var)
623631
{
@@ -646,6 +654,7 @@ rb_global_entry(ID id)
646654
var->block_trace = 0;
647655
var->trace = 0;
648656
var->box_ready = false;
657+
var->box_dynamic = false;
649658
rb_id_table_insert(rb_global_tbl, id, (VALUE)entry);
650659
}
651660
}
@@ -1000,9 +1009,13 @@ rb_gvar_set_entry(struct rb_global_entry *entry, VALUE val)
10001009
return val;
10011010
}
10021011

1003-
#define USE_BOX_GVAR_TBL(ns,entry) \
1004-
(BOX_USER_P(ns) && \
1005-
(!entry || !entry->var->box_ready || entry->var->setter != rb_gvar_readonly_setter))
1012+
static inline bool
1013+
gvar_use_box_tbl(const rb_box_t *box, const struct rb_global_entry *entry)
1014+
{
1015+
return BOX_USER_P(box) &&
1016+
!entry->var->box_dynamic &&
1017+
(!entry->var->box_ready || entry->var->setter != rb_gvar_readonly_setter);
1018+
}
10061019

10071020
VALUE
10081021
rb_gvar_set(ID id, VALUE val)
@@ -1015,7 +1028,7 @@ rb_gvar_set(ID id, VALUE val)
10151028
RB_VM_LOCKING() {
10161029
entry = rb_global_entry(id);
10171030

1018-
if (USE_BOX_GVAR_TBL(box, entry)) {
1031+
if (gvar_use_box_tbl(box, entry)) {
10191032
use_box_tbl = true;
10201033
rb_hash_aset(box->gvar_tbl, rb_id2sym(entry->id), val);
10211034
retval = val;
@@ -1048,7 +1061,7 @@ rb_gvar_get(ID id)
10481061
entry = rb_global_entry(id);
10491062
var = entry->var;
10501063

1051-
if (USE_BOX_GVAR_TBL(box, entry)) {
1064+
if (gvar_use_box_tbl(box, entry)) {
10521065
use_box_tbl = true;
10531066
gvars = box->gvar_tbl;
10541067
key = rb_id2sym(entry->id);

0 commit comments

Comments
 (0)