If the method being called does not have a positional splat
parameter, there is no point in allocating the array, as
decrementing given_argc is sufficient to ensure the empty keyword
hash is not considered an argument, assuming that we are calling
a method/lambda and not a regular proc.
If the method being called does not have a keyword splat parameter,
there is no point in allocating the hash, because the hash will
be unused (as empty keyword hashes are ignored).
This tests ruby2_keywords flagged methods, as well as passing
ruby2_keywords flagged hashes to other methods.
Some of the behavior here is questionable, such as allocating
different numbers of objects depending on whether a block is
passed or whether YJIT is enabled. I think there are likely ways
to eliminate allocations in certain cases. However, this gives
us a baseline and shows us where it is possible to make
improvements.
At 7afc16aa48, now `BLOCKING_REGION`
contains `setjmp` call in `RB_VM_SAVE_MACHINE_CONTEXT`. By this
change, variables in blocks for this macro may be clobbered.
There's an exhaustive explanation of this in the linked redmine bug, but
the short version is as follows:
blocking_region_begin can spill callee-saved registers to the stack for
its own use. That means they're not saved to ec->machine by the call to
setjmp, since by that point they're already on the stack and new,
different values are in the real registers. ec->machine's end-of-stack
pointer is also bumped to accomodate this, BUT, after
blocking_region_begin returns, that points past the end of the stack!
As far as C is concerned, that's fine; the callee-saved registers are
restored when blocking_region_begin returns. But, if another thread
triggers GC, it is relying on finding references to Ruby objects by
walking the stack region pointed to by ec->machine.
If the C code in exec; subsequently does things that use that stack
memory, then the value will be overwritten and the GC might prematurely
collect something it shouldn't.
[Bug #20493]
* Add types to `tLAMBDA` and `tSTRING_DBEG` to store corresponding
information when returning these tokens.
* Add `enum lex_state_e state` to `%union` for `tSTRING_DBEG`.
In the past, these codes were used by both parser and ripper.
On ripper, the type of LHS is `<val>` then type cast was needed.
However currently these are only used by parser then no need to
cast.