diff options
author | Aaron Patterson <tenderlove@ruby-lang.org> | 2022-06-06 17:27:56 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2023-04-18 17:16:22 -0700 |
commit | c5fc1ce975ecdf1c6818714e47579c5d3531c4ca (patch) | |
tree | 77a0f348d00a99281f826dac90e1d288c3139051 /internal | |
parent | 3016f30c956413268655dcb25dbe5041684f9528 (diff) | |
download | ruby-c5fc1ce975ecdf1c6818714e47579c5d3531c4ca.tar.gz |
Emit special instruction for array literal + .(hash|min|max)
This commit introduces a new instruction `opt_newarray_send` which is
used when there is an array literal followed by either the `hash`,
`min`, or `max` method.
```
[a, b, c].hash
```
Will emit an `opt_newarray_send` instruction. This instruction falls
back to a method call if the "interested" method has been monkey
patched.
Here are some examples of the instructions generated:
```
$ ./miniruby --dump=insns -e '[@a, @b].max'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 getinstancevariable :@a, <is:0> ( 1)[Li]
0003 getinstancevariable :@b, <is:1>
0006 opt_newarray_send 2, :max
0009 leave
$ ./miniruby --dump=insns -e '[@a, @b].min'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 getinstancevariable :@a, <is:0> ( 1)[Li]
0003 getinstancevariable :@b, <is:1>
0006 opt_newarray_send 2, :min
0009 leave
$ ./miniruby --dump=insns -e '[@a, @b].hash'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,13)> (catch: FALSE)
0000 getinstancevariable :@a, <is:0> ( 1)[Li]
0003 getinstancevariable :@b, <is:1>
0006 opt_newarray_send 2, :hash
0009 leave
```
[Feature #18897] [ruby-core:109147]
Co-authored-by: John Hawthorn <jhawthorn@github.com>
Diffstat (limited to 'internal')
-rw-r--r-- | internal/array.h | 1 | ||||
-rw-r--r-- | internal/basic_operators.h | 1 |
2 files changed, 2 insertions, 0 deletions
diff --git a/internal/array.h b/internal/array.h index 3aeb1be2dd..7e55b66a87 100644 --- a/internal/array.h +++ b/internal/array.h @@ -23,6 +23,7 @@ #define RARRAY_PTR_IN_USE_FLAG FL_USER14 /* array.c */ +VALUE rb_ary_hash_values(long len, const VALUE *elements); VALUE rb_ary_last(int, const VALUE *, VALUE); void rb_ary_set_len(VALUE, long); void rb_ary_delete_same(VALUE, VALUE); diff --git a/internal/basic_operators.h b/internal/basic_operators.h index 12a0475990..a59403631e 100644 --- a/internal/basic_operators.h +++ b/internal/basic_operators.h @@ -31,6 +31,7 @@ enum ruby_basic_operators { BOP_UMINUS, BOP_MAX, BOP_MIN, + BOP_HASH, BOP_CALL, BOP_AND, BOP_OR, |