[ruby/strscan] Implement Write Barrier

(https://github.com/ruby/strscan/pull/156)

StringScanner holds the string being scanned, and a regex for methods
like `match?`. Triggering the write barrier for those allows us to mark
this as WB protected.

https://github.com/ruby/strscan/commit/32fec70407
This commit is contained in:
Daniel Colson 2025-05-25 17:26:07 -04:00 committed by Hiroshi SHIBATA
parent 1dd8671c46
commit deb70925a2

View File

@ -209,7 +209,7 @@ strscan_memsize(const void *ptr)
static const rb_data_type_t strscanner_type = { static const rb_data_type_t strscanner_type = {
"StringScanner", "StringScanner",
{strscan_mark, strscan_free, strscan_memsize}, {strscan_mark, strscan_free, strscan_memsize},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
}; };
static VALUE static VALUE
@ -273,7 +273,7 @@ strscan_initialize(int argc, VALUE *argv, VALUE self)
p->fixed_anchor_p = false; p->fixed_anchor_p = false;
} }
StringValue(str); StringValue(str);
p->str = str; RB_OBJ_WRITE(self, &p->str, str);
return self; return self;
} }
@ -303,7 +303,7 @@ strscan_init_copy(VALUE vself, VALUE vorig)
orig = check_strscan(vorig); orig = check_strscan(vorig);
if (self != orig) { if (self != orig) {
self->flags = orig->flags; self->flags = orig->flags;
self->str = orig->str; RB_OBJ_WRITE(vself, &self->str, orig->str);
self->prev = orig->prev; self->prev = orig->prev;
self->curr = orig->curr; self->curr = orig->curr;
if (rb_reg_region_copy(&self->regs, &orig->regs)) if (rb_reg_region_copy(&self->regs, &orig->regs))
@ -467,7 +467,7 @@ strscan_set_string(VALUE self, VALUE str)
struct strscanner *p = check_strscan(self); struct strscanner *p = check_strscan(self);
StringValue(str); StringValue(str);
p->str = str; RB_OBJ_WRITE(self, &p->str, str);
p->curr = 0; p->curr = 0;
CLEAR_MATCH_STATUS(p); CLEAR_MATCH_STATUS(p);
return str; return str;
@ -712,7 +712,7 @@ strscan_do_scan(VALUE self, VALUE pattern, int succptr, int getstr, int headonly
if (RB_TYPE_P(pattern, T_REGEXP)) { if (RB_TYPE_P(pattern, T_REGEXP)) {
OnigPosition ret; OnigPosition ret;
p->regex = pattern; RB_OBJ_WRITE(self, &p->regex, pattern);
ret = rb_reg_onig_match(p->regex, ret = rb_reg_onig_match(p->regex,
p->str, p->str,
headonly ? strscan_match : strscan_search, headonly ? strscan_match : strscan_search,