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

ruby-changes:69621

From: Nobuyoshi <ko1@a...>
Date: Sun, 7 Nov 2021 12:40:41 +0900 (JST)
Subject: [ruby-changes:69621] 334b69e504 (master): rb_id_serial_to_id: return unregistered ID as an internal ID

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

From 334b69e5042f47f89c8780c1d7efa32d70c84786 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Wed, 13 Oct 2021 14:25:34 +0900
Subject: rb_id_serial_to_id: return unregistered ID as an internal ID

```ruby
def foo(*); ->{ super }; end
```

This code makes anonymous parameters which is not registered as an
ID.  The problem is that when Ractors try to scan `getlocal`
instructions, it puts the Symbol corresponding to the parameter
in to a hash.  Since it is not registered, we end up with a
strange exception.  This commit wraps the unregistered ID in an
internal ID so that we get the same exception for `...` as `*`.

Co-Authored-By: Aaron Patterson <tenderlove@r...>
Co-Authored-By: John Hawthorn <john@h...>
---
 bootstraptest/test_ractor.rb | 36 ++++++++++++++++++++++++++++++++++++
 symbol.c                     |  3 ++-
 test/ruby/test_iseq.rb       | 28 ++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index bf80b94cc70..ef1e6afcac2 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -1502,4 +1502,40 @@ assert_equal "ok", %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_ractor.rb#L1502
   "ok"
 }
 
+assert_equal "ok", %q{
+  def foo(*); ->{ super }; end
+  begin
+    Ractor.make_shareable(foo)
+  rescue Ractor::IsolationError
+    "ok"
+  end
+}
+
+assert_equal "ok", %q{
+  def foo(**); ->{ super }; end
+  begin
+    Ractor.make_shareable(foo)
+  rescue Ractor::IsolationError
+    "ok"
+  end
+}
+
+assert_equal "ok", %q{
+  def foo(...); ->{ super }; end
+  begin
+    Ractor.make_shareable(foo)
+  rescue Ractor::IsolationError
+    "ok"
+  end
+}
+
+assert_equal "ok", %q{
+  def foo((x), (y)); ->{ super }; end
+  begin
+    Ractor.make_shareable(foo([], []))
+  rescue Ractor::IsolationError
+    "ok"
+  end
+}
+
 end # if !ENV['GITHUB_WORKFLOW']
diff --git a/symbol.c b/symbol.c
index 1b2a77c7c4a..79ec4de5029 100644
--- a/symbol.c
+++ b/symbol.c
@@ -486,7 +486,8 @@ rb_id_serial_to_id(rb_id_serial_t num) https://github.com/ruby/ruby/blob/trunk/symbol.c#L486
 {
     if (is_notop_id((ID)num)) {
         VALUE sym = get_id_serial_entry(num, 0, ID_ENTRY_SYM);
-	return SYM2ID(sym);
+	if (sym) return SYM2ID(sym);
+	return ((ID)num << ID_SCOPE_SHIFT) | ID_INTERNAL | ID_STATIC_SYM;
     }
     else {
 	return (ID)num;
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index 3a02c182aa2..19357a774d2 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -95,6 +95,26 @@ class TestISeq < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_iseq.rb#L95
     assert_equal(42, ISeq.load_from_binary(iseq.to_binary).eval)
   end
 
+  def test_super_with_block
+    iseq = compile(<<~EOF)
+      def touch(*) # :nodoc:
+        foo { super }
+      end
+      42
+    EOF
+    assert_equal(42, ISeq.load_from_binary(iseq.to_binary).eval)
+  end
+
+  def test_super_with_block_and_kwrest
+    iseq = compile(<<~EOF)
+      def touch(**) # :nodoc:
+        foo { super }
+      end
+      42
+    EOF
+    assert_equal(42, ISeq.load_from_binary(iseq.to_binary).eval)
+  end
+
   def test_lambda_with_ractor_roundtrip
     iseq = compile(<<~EOF)
       x = 42
@@ -340,6 +360,14 @@ class TestISeq < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_iseq.rb#L360
     end
   end
 
+  def anon_star(*); end
+
+  def test_anon_param_in_disasm
+    iseq = RubyVM::InstructionSequence.of(method(:anon_star))
+    param_names = iseq.to_a[iseq.to_a.index(:method) + 1]
+    assert_equal [2], param_names
+  end
+
   def strip_lineno(source)
     source.gsub(/^.*?: /, "")
   end
-- 
cgit v1.2.1


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

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