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

ruby-changes:68283

From: Alan <ko1@a...>
Date: Thu, 7 Oct 2021 04:38:49 +0900 (JST)
Subject: [ruby-changes:68283] 7622819147 (master): Fix Ractor.make_shareable changing locals for Procs

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

From 76228191474c76810043b294a74bbb2f1808b3d9 Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Wed, 6 Oct 2021 15:38:33 -0400
Subject: Fix Ractor.make_shareable changing locals for Procs

env_copy() uses rb_ary_delete_at() with a loop counting up while
iterating through the list of read only locals. rb_ary_delete_at() can
shift elements in the array to an index lesser than the loop index,
causing locals to be missed and set to Qfalse in the returned
environment.

Iterate through the locals in reverse instead, this way the shifting
never happens for locals that are yet to be visited and we process all
the locals in the array.

[Bug #18023]
---
 bootstraptest/test_ractor.rb | 22 ++++++++++++++++++++++
 vm.c                         |  2 +-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index 01d02dce77..4da348df67 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -187,6 +187,28 @@ assert_equal '[:ok, :ok, :ok]', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L187
   }.map(&:take)
 }
 
+# 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] }
+
+  Ractor.make_shareable(closure).call
+}
+
+# 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
+    -> {
+      e, f, g = :e, :f, :g
+      -> { [a, b, c, d, e, f, g] }
+    }.call
+  }.call
+
+  Ractor.make_shareable(closure).call
+}
+
 ###
 ###
 # Ractor still has several memory corruption so skip huge number of tests
diff --git a/vm.c b/vm.c
index 5a1756e33a..d5e984ce61 100644
--- a/vm.c
+++ b/vm.c
@@ -1006,7 +1006,7 @@ env_copy(const VALUE *src_ep, VALUE read_only_variables) https://github.com/ruby/ruby/blob/trunk/vm.c#L1006
     volatile VALUE prev_env = Qnil;
 
     if (read_only_variables) {
-        for (int i=0; i<RARRAY_LENINT(read_only_variables); i++) {
+        for (int i=RARRAY_LENINT(read_only_variables)-1; i>=0; i--) {
             ID id = SYM2ID(rb_str_intern(RARRAY_AREF(read_only_variables, i)));
 
             for (unsigned int j=0; j<src_env->iseq->body->local_table_size; j++) {
-- 
cgit v1.2.1


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

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