mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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@ruby-lang.org> Co-Authored-By: John Hawthorn <john@hawthorn.email>
This commit is contained in:
parent
66b0847602
commit
334b69e504
Notes:
git
2021-11-07 12:40:53 +09:00
3 changed files with 66 additions and 1 deletions
|
@ -1502,4 +1502,40 @@ assert_equal "ok", %q{
|
|||
"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']
|
||||
|
|
3
symbol.c
3
symbol.c
|
@ -486,7 +486,8 @@ rb_id_serial_to_id(rb_id_serial_t num)
|
|||
{
|
||||
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;
|
||||
|
|
|
@ -95,6 +95,26 @@ class TestISeq < Test::Unit::TestCase
|
|||
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
|
|||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue