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/