diff options
| author | John Hawthorn <john@hawthorn.email> | 2025-11-26 13:33:10 -0800 |
|---|---|---|
| committer | John Hawthorn <john@hawthorn.email> | 2025-11-26 16:13:38 -0800 |
| commit | 970b18e9a94ff3e6496fb7324cff0798ffec6f24 (patch) | |
| tree | 1c6649881934e7593c052f1e927fe142809f0a0a /variable.c | |
| parent | db94a79da432bcdb9d48517733f11ccf03c7cd5d (diff) | |
Clear fields obj when removing
This fixes a bug where the gen_fields_cache could become invalid when
the last ivar was removed. Also adds more assertions.
Diffstat (limited to 'variable.c')
| -rw-r--r-- | variable.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/variable.c b/variable.c index d7e04265c4..ae122136ee 100644 --- a/variable.c +++ b/variable.c @@ -1237,6 +1237,18 @@ rb_mark_generic_ivar(VALUE obj) } VALUE +rb_obj_fields_generic_uncached(VALUE obj) +{ + VALUE fields_obj = 0; + RB_VM_LOCKING() { + if (!st_lookup(generic_fields_tbl_, (st_data_t)obj, (st_data_t *)&fields_obj)) { + rb_bug("Object is missing entry in generic_fields_tbl"); + } + } + return fields_obj; +} + +VALUE rb_obj_fields(VALUE obj, ID field_name) { RUBY_ASSERT(!RB_TYPE_P(obj, T_IMEMO)); @@ -1263,13 +1275,10 @@ rb_obj_fields(VALUE obj, ID field_name) rb_execution_context_t *ec = GET_EC(); if (ec->gen_fields_cache.obj == obj && rb_imemo_fields_owner(ec->gen_fields_cache.fields_obj) == obj) { fields_obj = ec->gen_fields_cache.fields_obj; + RUBY_ASSERT(fields_obj == rb_obj_fields_generic_uncached(obj)); } else { - RB_VM_LOCKING() { - if (!st_lookup(generic_fields_tbl_, (st_data_t)obj, (st_data_t *)&fields_obj)) { - rb_bug("Object is missing entry in generic_fields_tbl"); - } - } + fields_obj = rb_obj_fields_generic_uncached(obj); ec->gen_fields_cache.fields_obj = fields_obj; ec->gen_fields_cache.obj = obj; } @@ -1320,7 +1329,9 @@ rb_obj_set_fields(VALUE obj, VALUE fields_obj, ID field_name, VALUE original_fie ivar_ractor_check(obj, field_name); if (!fields_obj) { + RUBY_ASSERT(original_fields_obj); rb_free_generic_ivar(obj); + rb_imemo_fields_clear(original_fields_obj); return; } |
