The test should be testing RubyVM::InstructionSequence.compile_prism
with a file but it is instead passing the file path (which is a string)
which raises a SyntaxError because it is not Ruby syntax.
- Unless `sizeof(BDIGIT) == 4`, (8-byte integer not available), the
size to be loaded was wrong.
- Since `BDIGIT`s are dumped as raw binary, the loaded byte order was
inverted unless little-endian.
If there is a compilation error, is_entries may not be allocated, but
ic_size could be greater than 0. If we don't have a buffer to iterate
over, just return early. Otherwise GC could segv
[Bug #19173]
This allows for the following syntax:
```ruby
def foo(*)
bar(*)
end
def baz(**)
quux(**)
end
```
This is a natural addition after the introduction of anonymous
block forwarding. Anonymous rest and keyword rest arguments were
already supported in method parameters, this just allows them to
be used as arguments to other methods. The same advantages of
anonymous block forwarding apply to rest and keyword rest argument
forwarding.
This has some minor changes to #parameters output. Now, instead
of `[:rest], [:keyrest]`, you get `[:rest, :*], [:keyrest, :**]`.
These were already used for `...` forwarding, so I think it makes
it more consistent to include them in other cases. If we want to
use `[:rest], [:keyrest]` in both cases, that is also possible.
I don't think the previous behavior of `[:rest], [:keyrest]` in
the non-... case and `[:rest, :*], [:keyrest, :**]` in the ...
case makes sense, but if we did want that behavior, we'll have to
make more substantial changes, such as using a different ID in the
... forwarding case.
Implements [Feature #18351]
`def` (`rb_method_definition_t`) is shared by multiple callable
method entries (cme, `rb_callable_method_entry_t`).
There are two issues:
* old -> young reference: `cme1->def->mandatory_only_cme = monly_cme`
if `cme1` is young and `monly_cme` is young, there is no problem.
Howevr, another old `cme2` can refer `def`, in this case, old `cme2`
points young `monly_cme` and it violates gengc assumption.
* cme can have different `defined_class` but `monly_cme` only has
one `defined_class`. It does not make sense and `monly_cme`
should be created for a cme (not `def`).
To solve these issues, this patch allocates `monly_cme` per `cme`.
`cme` does not have another room to store a pointer to the `monly_cme`,
so this patch introduces `overloaded_cme_table`, which is weak key map
`[cme] -> [monly_cme]`.
`def::body::iseqptr::monly_cme` is deleted.
The first issue is reported by Alan Wu.
20211125T003004Z.log.html.gz
```
[ 4780/21204] TestISeq#test_super_with_anonymous_block/home/chkbuild/chkbuild/tmp/build/20211125T003004Z/ruby/test/ruby/test_iseq.rb:141: warning: method redefined; discarding old touch3
/home/chkbuild/chkbuild/tmp/build/20211125T003004Z/ruby/test/ruby/test_iseq.rb:121: warning: previous definition of touch3 was here
= 0.00 s
```
The parameter being called `req` specifically causes an assertion error:
```
Assertion failed: (key != 0), function hash_table_raw_insert, file id_table.c, line 153.
```
Renaming the parameter or removing the `*` doesn't reproduce.
block to another method without having to provide a name for the
block parameter.
Implements [Feature #11256]
Co-authored-by: Yusuke Endoh mame@ruby-lang.org
Co-authored-by: Nobuyoshi Nakada nobu@ruby-lang.org
20211109T063003Z.log.html.gz
```
[ 9898/21145] TestISeq#test_super_with_block_and_kwrest/home/chkbuild/chkbuild/tmp/build/20211109T063003Z/ruby/test/ruby/test_iseq.rb:1: warning: method redefined; discarding old touch
/home/chkbuild/chkbuild/tmp/build/20211109T063003Z/ruby/test/ruby/test_iseq.rb:1: warning: previous definition of touch was here
= 0.00 s
```
```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 dumps the outer variables table when dumping an iseq to
binary. This fixes a case where Ractors aren't able to tell what outer
variables belong to a lambda after the lambda is loaded via ISeq.load_from_binary
[Bug #18232] [ruby-core:105504]
Before this change, CDHASH operands were built as plain hashes when
loaded from binary. Without setting up the hash with the correct
st_table type, the hash can sometimes be an ar_table. When the hash is
an ar_table, lookups can call the `eql?` method on keys of the hash,
which makes the `opt_case_dispatch` instruction not "leaf" as it
implicitly declares.
The following script trips the stack canary for checking the leaf
attribute for `opt_case_dispatch` on VM_CHECK_MODE > 0 (enabled by
default with RUBY_DEBUG).
rb_vm_iseq = RubyVM::InstructionSequence
iseq = rb_vm_iseq.compile(<<-EOF)
case Class.new(String).new("foo")
when "foo"
42
end
EOF
puts rb_vm_iseq.load_from_binary(iseq.to_binary).eval
This commit changes the binary loading logic to build CDHASH with the
right st_table type. The dumping logic and the dump format stays the
same
This switches the internal function from rb_parser_compile_file_path
to rb_parser_load_file, which is the same internal method that
Kernel#load uses.
Fixes [Bug #17308]
Binary dumping the iseq for `case foo in []; end` used to crash as
there was no handling for these exception classes.
Pattern matching generates these classes as operands to `putobject`.
[Bug #16088]
Closes: https://github.com/ruby/ruby/pull/2325