diff options
-rw-r--r-- | bootstraptest/test_yjit.rb | 20 | ||||
-rw-r--r-- | yjit_codegen.c | 8 |
2 files changed, 25 insertions, 3 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 6d507e17d7..73b87e17fd 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -2018,3 +2018,23 @@ assert_normal_exit %q{ foo([1]) rescue nil foo([1]) rescue nil } + +# test ractor exception on when getting ivar +assert_equal '42', %q{ + class A + def self.foo + _foo = 1 + _bar = 2 + begin + @bar + rescue Ractor::IsolationError + 42 + end + end + end + + A.foo + A.foo + + Ractor.new { A.foo }.take +} diff --git a/yjit_codegen.c b/yjit_codegen.c index e3a23b3bb8..c0c27029ca 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -1571,11 +1571,13 @@ gen_get_ivar(jitstate_t *jit, ctx_t *ctx, const int max_chain_depth, VALUE compt // inside object shapes. if (!RB_TYPE_P(comptime_receiver, T_OBJECT) || rb_get_alloc_func(comptime_val_klass) != rb_class_allocate_instance) { - // General case. Call rb_ivar_get(). No need to reconstruct interpreter - // state since the routine never raises exceptions or allocate objects - // visibile to Ruby. + // General case. Call rb_ivar_get(). // VALUE rb_ivar_get(VALUE obj, ID id) ADD_COMMENT(cb, "call rb_ivar_get()"); + + // The function could raise exceptions. + jit_prepare_routine_call(jit, ctx, REG1); + mov(cb, C_ARG_REGS[0], REG0); mov(cb, C_ARG_REGS[1], imm_opnd((int64_t)ivar_name)); call_ptr(cb, REG1, (void *)rb_ivar_get); |