[前][次][番号順一覧][スレッド一覧]

ruby-changes:70117

From: Koichi <ko1@a...>
Date: Thu, 9 Dec 2021 16:20:21 +0900 (JST)
Subject: [ruby-changes:70117] cce331272b (master): `Ractor.make_shareable` checks proc's sefl

https://git.ruby-lang.org/ruby.git/commit/?id=cce331272b

From cce331272b07636d536c8227288ab3fbcf24e2aa Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Thu, 9 Dec 2021 03:58:44 +0900
Subject: `Ractor.make_shareable` checks proc's sefl

`Ractor.make_shareable(proc_obj)` raises an `IsolationError`
if the self of `proc_obj` is not a shareable object.

[Bug #18243]
---
 bootstraptest/test_ractor.rb | 32 ++++++++++++++++++++------------
 test/ruby/test_iseq.rb       | 12 ++++++++----
 vm.c                         |  4 ++++
 3 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index ef1e6afcac2..e259684974b 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -190,7 +190,7 @@ assert_equal '[:ok, :ok, :ok]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L190
 # Ractor.make_shareable issue for locals in proc [Bug #18023]
 assert_equal '[:a, :b, :c, :d, :e]', %q{
   v1, v2, v3, v4, v5 = :a, :b, :c, :d, :e
-  closure = Proc.new { [v1, v2, v3, v4, v5] }
+  closure = Ractor.current.instance_eval{ Proc.new { [v1, v2, v3, v4, v5] } }
 
   Ractor.make_shareable(closure).call
 }
@@ -198,13 +198,15 @@ assert_equal '[:a, :b, :c, :d, :e]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L198
 # Ractor.make_shareable issue for locals in proc [Bug #18023]
 assert_equal '[:a, :b, :c, :d, :e, :f, :g]', %q{
   a = :a
-  closure = -> {
-    b, c, d = :b, :c, :d
+  closure = Ractor.current.instance_eval do
     -> {
-      e, f, g = :e, :f, :g
-      -> { [a, b, c, d, e, f, g] }
+      b, c, d = :b, :c, :d
+      -> {
+        e, f, g = :e, :f, :g
+        -> { [a, b, c, d, e, f, g] }
+      }.call
     }.call
-  }.call
+  end
 
   Ractor.make_shareable(closure).call
 }
@@ -1276,9 +1278,13 @@ assert_equal 'true', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L1278
 # Ractor.make_shareable(a_proc) makes a proc shareable.
 assert_equal 'true', %q{
   a = [1, [2, 3], {a: "4"}]
-  pr = Proc.new do
-    a
+
+  pr = Ractor.current.instance_eval do
+    Proc.new do
+      a
+    end
   end
+
   Ractor.make_shareable(a) # referred value should be shareable
   Ractor.make_shareable(pr)
   Ractor.shareable?(pr)
@@ -1326,10 +1332,12 @@ assert_equal '1', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L1332
 # Ractor.make_shareable(a_proc) makes a proc shareable.
 assert_equal 'can not make a Proc shareable because it accesses outer variables (a).', %q{
   a = b = nil
-  pr = Proc.new do
-    c = b # assign to a is okay because c is block local variable
-          # reading b is okay
-    a = b # assign to a is not allowed #=> Ractor::Error
+  pr = Ractor.current.instance_eval do
+    Proc.new do
+      c = b # assign to a is okay because c is block local variable
+      # reading b is okay
+      a = b # assign to a is not allowed #=> Ractor::Error
+    end
   end
 
   begin
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index ac191531dec..aa0bf35b804 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -129,7 +129,7 @@ class TestISeq < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_iseq.rb#L129
   def test_lambda_with_ractor_roundtrip
     iseq = compile(<<~EOF, __LINE__+1)
       x = 42
-      y = lambda { x }
+      y = nil.instance_eval{ lambda { x } }
       Ractor.make_shareable(y)
       y.call
     EOF
@@ -148,16 +148,20 @@ class TestISeq < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_iseq.rb#L148
 
   def test_ractor_unshareable_outer_variable
     name = "\u{2603 26a1}"
-    y = eval("proc {#{name} = nil; proc {|x| #{name} = x}}").call
+    y = nil.instance_eval do
+      eval("proc {#{name} = nil; proc {|x| #{name} = x}}").call
+    end
     assert_raise_with_message(ArgumentError, /\(#{name}\)/) do
       Ractor.make_shareable(y)
     end
-    y = eval("proc {#{name} = []; proc {|x| #{name}}}").call
+    y = nil.instance_eval do
+      eval("proc {#{name} = []; proc {|x| #{name}}}").call
+    end
     assert_raise_with_message(Ractor::IsolationError, /`#{name}'/) do
       Ractor.make_shareable(y)
     end
     obj = Object.new
-    def obj.foo(*) ->{super} end
+    def obj.foo(*) nil.instance_eval{ ->{super} } end
     assert_raise_with_message(Ractor::IsolationError, /hidden variable/) do
       Ractor.make_shareable(obj.foo)
     end
diff --git a/vm.c b/vm.c
index ad687d579ab..73d6cd9d5dc 100644
--- a/vm.c
+++ b/vm.c
@@ -1181,6 +1181,10 @@ rb_proc_ractor_make_shareable(VALUE self) https://github.com/ruby/ruby/blob/trunk/vm.c#L1181
         rb_proc_t *proc = (rb_proc_t *)RTYPEDDATA_DATA(self);
         if (proc->block.type != block_type_iseq) rb_raise(rb_eRuntimeError, "not supported yet");
 
+        if (!rb_ractor_shareable_p(vm_block_self(&proc->block))) {
+            rb_raise(rb_eRactorIsolationError, "Proc's self is not shareable");
+        }
+
         VALUE read_only_variables = Qfalse;
 
         if (iseq->body->outer_variables) {
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]