Commit Graph

301 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto 90484cac63 codegen.c: skip OP_LOADSELF using OP_SSEND. 2021-10-19 12:13:05 +09:00
Yukihiro "Matz" Matsumoto 0d08f89159 codegen.c: Reduce MRB_CODEGEN_LEVEL_MAX from 1024 to 256.
1024 was too big.  Some deep recursion could not be detected before
actual stack overflow.
2021-10-18 12:01:07 +09:00
Yukihiro "Matz" Matsumoto de2b4bd0dc codegen.c: fixed a bug regarding attribute assignment with kargs. 2021-10-18 08:01:26 +09:00
Yukihiro "Matz" Matsumoto be189ae9f9 codegen.c: forgot to check s2 extensively in super codegen. 2021-10-17 08:03:24 +09:00
Yukihiro "Matz" Matsumoto 36bca25e58 codegen.c: s2 may be NULL.
Since `s2` is `NULL` on top-level, it will be an error. No need to
generate strict bytecode.
2021-10-16 11:09:52 +09:00
Yukihiro "Matz" Matsumoto 6b3b1012ca codegen.c: skip OP_ARGARY before super if the method has no arguments. 2021-10-13 07:06:17 +09:00
Yukihiro "Matz" Matsumoto 5004d9a282 codegen.c: should not assign negative number to ainfo (size_t). 2021-10-12 20:16:36 +09:00
Yukihiro "Matz" Matsumoto dccd66f9ef Support Ruby3.0 keyword arguments.
The Difference

Since Ruby1.9, the keyword arguments were emulated by Ruby using the hash
object at the bottom of the arguments. But we have gradually moved toward
keyword arguments separated from normal (positinal) arguments.

At the same time, we value compatibility, so that Ruby3.0 keyword
arguments are somewhat compromise. Basically, keyword arguments are
separated from positional arguments, except when the method does not
take any formal keyword arguments, given keyword arguments (packed
in the hash object) are considered as the last argument.

And we also allow non symbol keys in the keyword arguments. In that
case, those keys are just passed in the `**` hash (or raise
`ArgumentError` for unknown keys).

The Instruction Changes

We have changed `OP_SEND` instruction. `OP_SEND` instruction used to
take 3 operands, the register, the symbol, the number of (positional)
arguments. The meaning of the third operand has been changed. It is now
considered as `n|(nk<<4)`, where `n` is the number of positional
arguments, and `nk` is the number of keyword arguments, both occupies
4 bits in the operand.

The number `15` in both `n` and `nk` means variable sized arguments are
packed in the object. Positional arguments will be packed in the array,
and keyword arguments will be packed in the hash object. That means
arguments more than 14 values are always packed in the object.

Arguments information for other instructions (`OP_SENDB` and `OP_SUPER`)
are also changed. It works as the third operand of `OP_SEND`. the
difference between `OP_SEND` and `OP_SENDB` is just trivial. It assigns
`nil` to the block hidden arguments (right after arguments).

The instruction `OP_SENDV` and `OP_SENDVB` are removed. Those
instructions are replaced by `OP_SEND` and `OP_SENDB` respectively with
the `15` (variable sized) argument information.

Calling Convention

When calling a method, the stack elements shall be in the order of the
receiver of the method, positional arguments, keyword arguments and the
block argument. If the number of positional or keyword arugument (`n` or
`nk`) is zero, corresponding arguments will be empty. So when `n=0` and
`nk=0` the stack layout (from bottom to top) will be:

+-----------------------+
| recv | block (or nil) |
+-----------------------+

The last elements `block` should be explicitly filled before `OP_SEND`
or assigned to `nil` by `OP_SENDB` internally. In other words, the
following have exactly same behavior:

OP_SENDB clears `block` implicitly:

```
OP_SENDB reg sym 0
```

OP_SEND clears `block` implicitly:

```
OP_LOADNIL  R2
OP_SEND     R2 sym 0
```

When calling a method with only positional arguments (n=0..14) without
keyword arguments, the stack layout will be like following:

+--------------------------------------------+
| recv | arg1 | ... | arg_n | block (or nil) |
+--------------------------------------------+

When calling a method with arguments packed in the array (n=15) which
means argument splat (*) is used in the actual arguments, or more than
14 arguments are passed the stack layout will be like following:

+-------------------------------+
| recv | array | block (or nil) |
+-------------------------------+

The number of the actual arguments is determined by the length of the
argument array.

When keyword arguments are given (nk>0), keyword arguments are passed
between positional arguments and the block argument. For example, when
we pass one positional argument `1` and one keyword argument `a: 2`,
the stack layout will be like:

+------------------------------------+
| recv | 1 | :a | 2 | block (or nil) |
+------------------------------------+

Note that keyword arguments consume `2*nk` elements in the stack when
`nk=0..14` (unpacked).

When calling a method with keyword arguments packed in the hash object
(nk=15) which means keyword argument splat (**) is used or more than
14 keyword arguments in the actual arguments, the stack layout will
be like:

+------------------------------+
| recv | hash | block (or nil) |
+------------------------------+

Note for mruby/c

When mruby/c authors try to support new keyword arguments, they need
to handle the new meaning of the argument information operand. If they
choose not to support keyword arguments in mruby/c, it just raise
error when `nk` (taken by `(c>>4)&0xf`) is not zero. And combine
`OP_SENDV` behavior with `OP_SEND` when `n` is `15`.

If they want to support keyword arguments seriously, contact me at
<matz@ruby.or.jp> or `@yukihiro_matz`. I can help you.
2021-10-12 20:16:36 +09:00
Yukihiro "Matz" Matsumoto 87b673fc9a codegen.c: peephole optimization OP_MOVE after OP_AREF. 2021-10-09 13:31:07 +09:00
Yukihiro "Matz" Matsumoto fd6d911b53 codegen.c: peephole optimize OP_MOVE after OP_ARRAY or OP_HASH.
When the length operand is zero, we don't need `OP_MOVE` but adjust the
destination operand instead.
2021-10-08 12:09:05 +09:00
Yukihiro "Matz" Matsumoto ab1047b445 codegen.c: no OP_ARGARY is needed here. 2021-10-04 07:45:46 +09:00
Yukihiro "Matz" Matsumoto 09336c5d49 mruby/ops.h: add new instructions OP_GETIDX and OP_SETIDX.
Which represent `obj[int]` and `obj[int]=val` respectively where `obj`
is either `string`, `array` or `hash`, so that index access could be
faster. When `obj` is not assumed type or `R(a+1)` is not integer, the
instructions fallback to method calls.
2021-10-03 17:14:00 +09:00
Yukihiro "Matz" Matsumoto 368e8ce3d5 codegen.c: should not loop_push() before constant folding.
Otherwise, the following code will crash:

```ruby
1.times{{}until 1; break}
```
2021-09-26 16:58:40 +09:00
Yukihiro "Matz" Matsumoto ab54ca272a codegen.c: refactor NODE_WHILE and NODE_UNTIL. 2021-09-24 11:39:00 +09:00
Yukihiro "Matz" Matsumoto 7c6c4ebb56 codegen.c: add short circuit constant folding for NODE_AND, NODE_OR. 2021-09-24 11:38:02 +09:00
Yukihiro "Matz" Matsumoto 863671c89f codegen.c: refactor NODE_IF generation for boolean constants.
In addition, add `NODE_SYM` for always true expression.
2021-09-24 11:36:27 +09:00
Yukihiro "Matz" Matsumoto a844f89655 codegen.c: need to check no_peephole() before constant folding. 2021-09-23 21:19:36 +09:00
Yukihiro "Matz" Matsumoto 4c196dbba5 codegen.c: separate maximum stack size from GEN_LIT_ARY_MAX. 2021-09-23 20:11:30 +09:00
Yukihiro "Matz" Matsumoto c29822f80c codegen.c (gen_addsub): use mrb_int_sub_overflow(). 2021-09-20 17:32:38 +09:00
Yukihiro "Matz" Matsumoto 0455313a9b codegen.c: avoid constant folding OP_LOADI16 across branch target. 2021-09-20 17:30:14 +09:00
Yukihiro "Matz" Matsumoto ca7228ad42 codegen.c: gen_move should generate proper OP_LOADI16. 2021-09-20 16:58:27 +09:00
Yukihiro "Matz" Matsumoto 1baf08f174 codegen.c: rename loopinfo->acc to reg.
`acc` meant `accumulator` but it is not an accumulator but just a
register position.
2021-09-20 10:40:30 +09:00
Yukihiro "Matz" Matsumoto 2083d99392 codegen.c: check no_peephole(s) before mrb_last_insn(s). 2021-09-20 10:37:11 +09:00
Yukihiro "Matz" Matsumoto f85c50543b codegen.c (mrb_last_insn): no previous instruction on top. 2021-09-20 10:35:01 +09:00
Yukihiro "Matz" Matsumoto 8bfa99975c codegen.c: unify OP_ARYPUSH and OP_ARYPUSH_N.
- `OP_ARYPUSH` now takes operand for the number of pushing elements
- the code generator consume the stack no more than `64` for `mruby/c`
2021-09-19 09:07:20 +09:00
Yukihiro "Matz" Matsumoto 7c99df8416 ops.h: add OP_ARYPUSH_N instruction.
Add n elements at once. Reduces instructions for huge array
initialization. In addition, `gen_value` function in `codegen.c` was
refactored and clarified.
2021-09-17 07:49:47 +09:00
Yukihiro "Matz" Matsumoto cd0ffd6f1c codegen.c: fixed gen_setxv bug with taking assignment value; fix #5550 2021-09-10 15:39:24 +09:00
Yukihiro "Matz" Matsumoto 69da192eec codegen.c: gen_move refactoring. 2021-09-10 15:38:51 +09:00
Yukihiro "Matz" Matsumoto 28b5c30b96 ops.h: add OP_SYMBOL instruction.
It generates a symbol by interning from the pool string.
2021-09-10 10:23:28 +09:00
Yukihiro "Matz" Matsumoto b34713304a fixup! codegen.c: resurrect s->lastpc to reduce iseq scans. 2021-09-10 10:22:49 +09:00
Yukihiro "Matz" Matsumoto 5fbea87fe5 codegen.c: resurrect s->lastpc to reduce iseq scans.
When parsing scripts frequent scans could cost too much.
2021-09-10 10:15:55 +09:00
Yukihiro "Matz" Matsumoto 6fc6880f1f codegen.c: improve exception handling in generate_code.
- remove `mrb_jmpbuf` from `codegen_scope`
- unify exception handling of `mrb_state` and `codegen_scope`
2021-09-07 07:33:28 +09:00
Yukihiro "Matz" Matsumoto 7552b9322a codegen.c: avoid integer overflow. 2021-09-05 09:25:44 +09:00
dearblue 5a57602860 Organize the include of header files
- `#include <math.h>` is done in `mruby.h`.
  Eliminate the need to worry about the `MRB_NO_FLOAT` macro.

- Include mruby header files before standard header files.
  If the standard header file is already placed before `mruby.h`, the standard header file added in the future tends to be placed before `mruby.h`.

This change should some reduce the chances of macros that must be defined becoming undefined in C++ or including problematic header files in a particular mruby build configuration.
2021-08-21 15:42:57 +09:00
Yukihiro "Matz" Matsumoto 9e74aad43c codegen.c: fixed a bug in mrb_decode_insn(). 2021-08-13 12:38:10 +09:00
Yukihiro "Matz" Matsumoto 7907c184be codegen.c: add a comment that notice rewind_pc calling convention.
`rewind_pc` should not be called when `s->pc` is `0` (top).
2021-08-13 10:11:36 +09:00
Yukihiro "Matz" Matsumoto 9c3d305530 codegen.c: refactor mrb_last_insn().
Last commit made `mrb_decode_insn()` to take `NULL` as `pc`.
2021-08-13 10:10:17 +09:00
Yukihiro "Matz" Matsumoto cbdc4f2c5c codegen.c: mrb_prev_pc can return NULL at the top of iseq. 2021-08-13 10:02:01 +09:00
Yukihiro "Matz" Matsumoto e1b170160b codegen.c: avoid signedness warning of int comparison. 2021-08-11 16:10:32 +09:00
Yukihiro "Matz" Matsumoto a85f2299c0 codegen.c: avoid cross initialization of mrb_insn_data. 2021-08-11 16:09:51 +09:00
Yukihiro "Matz" Matsumoto b1b9b157f8 codegen.c: more peephole optimization.
`a=10; a+=1` to generate:

```
    1 000 OP_LOADI      R1      11              ; R1:a
```

instead of:

```
    1 000 OP_LOADI      R1      10              ; R1:a
    1 003 OP_MOVE       R2      R1              ; R1:a
    1 006 OP_ADDI       R2      1
    1 009 OP_MOVE       R1      R2              ; R1:a
```
2021-08-11 10:48:18 +09:00
Yukihiro "Matz" Matsumoto 06f49b3f84 codegen.c: need to push the value when the loop was eliminated. 2021-08-07 12:11:38 +09:00
Yukihiro "Matz" Matsumoto 37dbb91b96 codegen.c: -9223372036854775808 % -1 overflows 64 bit integer. 2021-08-06 10:35:06 +09:00
Yukihiro "Matz" Matsumoto 7ecc16f97a codegen.c: remove code duplication from NODE_ARRAY. 2021-08-05 16:59:32 +09:00
Yukihiro "Matz" Matsumoto 9cb44f5ae3 codegen.c: detect integer overflow in division.
`MRB_INT_MIN / -1` overflows.
2021-08-04 12:25:14 +09:00
Yukihiro "Matz" Matsumoto caaa07f2da codegen.c: check zero division before constant folding. 2021-08-03 16:43:50 +09:00
Yukihiro "Matz" Matsumoto 2092bc7fe8 codegen.c: avoid division by zero in constant folding. 2021-08-03 15:57:01 +09:00
Yukihiro "Matz" Matsumoto 4fa24e4ff9 codegen.c: allow constant folding for negative integer modulo. 2021-08-02 16:48:16 +09:00
Yukihiro "Matz" Matsumoto e93642d53f codegen.c: refactor readint() to read MRB_INT_MIN. 2021-08-02 14:10:38 +09:00
Yukihiro "Matz" Matsumoto 9902ab50fc codegen.c: fix a bug in bit shift constant folding. 2021-08-02 08:53:50 +09:00