summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2021-09-23 16:27:05 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2021-10-20 18:19:41 -0400
commit8edb29e5a013da5a74fba9c2484bd6d3913bfb4b (patch)
tree14d37ff00962a6a2b95854b58ed856e3d914b729
parentd0a213b30d04372d1a1b5012246ac7da3236db31 (diff)
Reconstruct interpreter state before calling rb_ivar_get()
It could raise ractor exceptions. The included test didn't run properly before this change.
-rw-r--r--bootstraptest/test_yjit.rb20
-rw-r--r--yjit_codegen.c8
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);