Since it was removed by the parser, the compiler did not know
about it, and m(**{}) was therefore treated as m().
This modifies the parser to not remove the **{}. A simple
approach for this is fairly simple by just removing a few
lines from the parser, but that would cause two hash
allocations every time it was used. The approach taken here
modifies both the parser and the compiler, and results in **{}
not allocating any hashes in the usual case.
The basic idea is we use a literal node in the parser containing
a frozen empty hash literal. In the compiler, we recognize when
that is used, and if it is the only keyword present, we just
push it onto the VM stack (no creation of a new hash or merging
of keywords). If it is the first keyword present, we push a
new empty hash onto the VM stack, so that later keywords can
merge into it. If it is not the first keyword present, we can
ignore it, since the there is no reason to merge an empty hash
into the existing hash.
Make m(**{}) mean call without keywords
Previously, **{} was removed by the parser:
Since it was removed by the parser, the compiler did not know
about it, and
m(**{})
was therefore treated asm()
.This modifies the parser to not remove the
**{}
. A simpleapproach for this is fairly simple by just removing a few
lines from the parser, but that would cause two hash
allocations every time it was used. The approach taken here
modifies both the parser and the compiler, and results in
**{}
not allocating any hashes in the usual case.
The basic idea is we use a literal node in the parser containing
a frozen empty hash literal. In the compiler, we recognize when
that is used, and if it is the only keyword present, we just
push it onto the VM stack (no creation of a new hash or merging
of keywords). If it is the first keyword present, we push a
new empty hash onto the VM stack, so that later keywords can
merge into it. If it is not the first keyword present, we can
ignore it, since the there is no reason to merge an empty hash
into the existing hash.
Example instructions for
m(**{})
Before (note ARGS_SIMPLE):
After (note putobject and KW_SPLAT):
Example instructions for
m(**h, **{})
Before and After (no change):
Example instructions for
m(**{}, **h)
Before:
After (basically the same except for the addition of swap):