diff --git a/depend b/depend index 0fcf5ce652..334bab5684 100644 --- a/depend +++ b/depend @@ -6306,6 +6306,7 @@ imemo.$(OBJEXT): $(top_srcdir)/internal/compilers.h imemo.$(OBJEXT): $(top_srcdir)/internal/gc.h imemo.$(OBJEXT): $(top_srcdir)/internal/imemo.h imemo.$(OBJEXT): $(top_srcdir)/internal/namespace.h +imemo.$(OBJEXT): $(top_srcdir)/internal/object.h imemo.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h imemo.$(OBJEXT): $(top_srcdir)/internal/serial.h imemo.$(OBJEXT): $(top_srcdir)/internal/set_table.h @@ -7159,7 +7160,6 @@ iseq.$(OBJEXT): $(top_srcdir)/prism/pack.h iseq.$(OBJEXT): $(top_srcdir)/prism/parser.h iseq.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h iseq.$(OBJEXT): $(top_srcdir)/prism/prism.h -iseq.$(OBJEXT): $(top_srcdir)/prism/prism.h iseq.$(OBJEXT): $(top_srcdir)/prism/regexp.h iseq.$(OBJEXT): $(top_srcdir)/prism/static_literals.h iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h @@ -11676,7 +11676,6 @@ prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h prism/prism.$(OBJEXT): $(top_srcdir)/prism/version.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/version.h prism/regexp.$(OBJEXT): $(top_srcdir)/prism/ast.h prism/regexp.$(OBJEXT): $(top_srcdir)/prism/defines.h prism/regexp.$(OBJEXT): $(top_srcdir)/prism/encoding.h diff --git a/imemo.c b/imemo.c index fde5b15ad6..2fde22a3db 100644 --- a/imemo.c +++ b/imemo.c @@ -3,6 +3,7 @@ #include "id_table.h" #include "internal.h" #include "internal/imemo.h" +#include "internal/object.h" #include "internal/st.h" #include "vm_callinfo.h" @@ -208,6 +209,8 @@ rb_imemo_fields_clear(VALUE fields_obj) else { RBASIC_SET_SHAPE_ID(fields_obj, ROOT_SHAPE_ID); } + // Invalidate the ec->gen_fields_cache. + RBASIC_CLEAR_CLASS(fields_obj); } /* ========================================================================= diff --git a/test/ruby/test_variable.rb b/test/ruby/test_variable.rb index cc784e7644..3504b9b7dc 100644 --- a/test/ruby/test_variable.rb +++ b/test/ruby/test_variable.rb @@ -447,6 +447,19 @@ class TestVariable < Test::Unit::TestCase assert_equal(%i[α b], b.local_variables) end + def test_genivar_cache + bug21547 = '[Bug #21547]' + klass = Class.new(Array) + instance = klass.new + instance.instance_variable_set(:@a1, 1) + instance.instance_variable_set(:@a2, 2) + Fiber.new do + instance.instance_variable_set(:@a3, 3) + instance.instance_variable_set(:@a4, 4) + end.resume + assert_equal 4, instance.instance_variable_get(:@a4) + end + private def with_kwargs_11(v1:, v2:, v3:, v4:, v5:, v6:, v7:, v8:, v9:, v10:, v11:) local_variables diff --git a/variable.c b/variable.c index 4f0f83d203..1cd1c604c3 100644 --- a/variable.c +++ b/variable.c @@ -1247,7 +1247,7 @@ rb_obj_fields(VALUE obj, ID field_name) generic_fields: { rb_execution_context_t *ec = GET_EC(); - if (ec->gen_fields_cache.obj == obj) { + 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; } else {