Commit Graph

842 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto b3416832f4 vm.c: refactor block type checking. 2022-03-10 10:43:51 +09:00
Yukihiro "Matz" Matsumoto a4f740ff9a string.c: use mrb_int instead of size_t. 2022-03-03 08:08:02 +09:00
Yukihiro "Matz" Matsumoto 47068ae07a vm.c: packed arguments length may be zero for send method. 2022-02-18 14:38:07 +09:00
Yukihiro "Matz" Matsumoto ff3a5ebed6 vm.c: should check type before hash access.
Since the operand of double splat (`**`) may not be a hash, simple
assertion (previous code since d42a64e) was not enough for this case.
2022-02-15 18:36:38 +09:00
Yukihiro "Matz" Matsumoto 4e8ab145da vm.c: adjust integer types. 2022-02-08 13:11:44 +09:00
Yukihiro "Matz" Matsumoto d42a64eadf vm.c: add assertion for type of register values.
We used to check them by `mrb_ensure_xxx_type()` functions, but type
errors there should not occur if there's no bug in code generations.
So we use assertion rather than dynamic type checks.
2022-02-06 22:17:53 +09:00
dearblue 6dfc47f5d4 Check the type of the keyword rest argument
If a non-hash object is passed in `OP_SEND` and `OP_SUPER`, an error should occur.

```ruby
kwd = "string"
p(**kwd)  #  => expect raised TypeError
```
2022-02-05 17:41:01 +09:00
dearblue d0e8637e30 Integrate argument normalization for OP_SEND and OP_SUPER 2022-02-05 17:36:23 +09:00
Yukihiro "Matz" Matsumoto 903c5f978a vm.c: check object type before concatenating strings. 2022-02-03 10:41:09 +09:00
Yukihiro "Matz" Matsumoto 9f012724fb vm.c: need to adjust argument after packing keyword args; fix #5632
It was caused by #5628.
2022-01-12 12:44:23 +09:00
dearblue 55b2e45a26 Fixing keyword arguments with super
fix #5627
2022-01-05 16:40:13 +09:00
Yukihiro "Matz" Matsumoto 3de9ddfb39 vm.c: use prepare_missing in mrb_funcall_with_block
Remove code duplication.
2021-12-31 18:15:41 +09:00
Yukihiro "Matz" Matsumoto a42b676ae9 vm.c: fix a half-baked implementation of OP_SETIDX; ref #5608 2021-12-20 17:45:10 +09:00
Yukihiro "Matz" Matsumoto d2a904c884 vm.c (check_method_noarg): the value at kidx may not be a hash. 2021-12-08 16:43:02 +09:00
Yukihiro "Matz" Matsumoto c593e3e30a vm.c: use check_method_noarg() to reduce code duplication; ref #5584 2021-12-08 16:42:23 +09:00
Yukihiro "Matz" Matsumoto 5bad1c7429 vm.c: fix mrb_ci_kidx.
It used to return wrong value for 14 positional arguments.
2021-12-08 16:22:24 +09:00
Yukihiro "Matz" Matsumoto b137eb2678 vm.c: remove duplicate code in VM. 2021-11-29 23:18:57 +09:00
dearblue c4bca7cbb3 Align "wrong number of arguments" messages
Make "N for M" into the form "given N, expected M".

As I worked, I noticed that the `argnum_error()` function had a part to include the method name in the message.
I think this part is no longer needed by https://github.com/mruby/mruby/pull/5394.

  - Before this patch

    ```console
    % bin/mruby -e '[1, 2, 3].each 0'
    trace (most recent call last):
            [1] -e:1
    -e:1:in each: 'each': wrong number of arguments (1 for 0) (ArgumentError)
    ```

  - After this patch

    ```console
    % bin/mruby -e '[1, 2, 3].each 0'
    trace (most recent call last):
            [1] -e:1
    -e:1:in each: wrong number of arguments (given 1, expected 0) (ArgumentError)
    ```
2021-11-28 18:21:29 +09:00
dearblue 668b12e756 Check more MRB_ARGS_NONE()
The `__id__` method implemented in the C function has `MRB_ARGS_NONE()` specified, but it is also effective in the following cases.

```ruby
p nil.__id__ opts: 1 rescue p :a
p nil.method(:__id__).call 1 rescue p :b
p nil.method(:__id__).call opts: 1 rescue p :c
p nil.method(:__id__).to_proc.call 1 rescue p :d
p nil.method(:__id__).to_proc.call opts: 1 rescue p :e
p nil.method(:__id__).unbind.bind_call nil, 1 rescue p :f
p nil.method(:__id__).unbind.bind_call nil, opts: 1 rescue p :g
p nil.__send__ :__id__, 1 rescue p :h
p nil.__send__ :__id__, opts: 1 rescue p :i
```

After applying this patch, all items will output symbols in the same way as CRuby.

For this purpose, add `MRB_PROC_NOARG` to `struct RProc::flags`.
2021-11-26 12:18:41 +09:00
Yukihiro "Matz" Matsumoto 4c28356b71 Merge pull request #5578 from dearblue/OP_SENDB
Fixes keywords are lost with the `OP_SENDB`
2021-11-20 08:50:42 +09:00
dearblue 6fba0dbece Fixed a discrepancy in OP_ASET
There was a discrepancy in the actual behavior, assertions, and documentation.
Therefore, I modified it based on the actual behavior.
2021-11-19 22:53:01 +09:00
dearblue 279e0122da Fixes keywords are lost with the OP_SENDB
If a splat argument was passed, it could write out of range on the VM stack.

```console
% bin/mruby -e 'def m(*args, **opts, &blk) p [args, opts, blk] end; m(*%w(X Y Z), r: 1, g: 2, b: 3) {}'
[["X", "Y", "Z"], {}, #<Proc:0x80077d7d0>]
```
2021-11-19 22:35:47 +09:00
Yukihiro "Matz" Matsumoto 5d5e4f5214 ops.h: add new instructions OP_SSEND and OP_SSENDB.
These instructions call methods of the receiver.
2021-10-19 12:03:12 +09:00
Yukihiro "Matz" Matsumoto 7010ed0f0a vm.c: need to ensure the stack size is sufficient.
Need to add `n` because the stack will be shifted in the `mrb_funcall`.
2021-10-14 22:47:19 +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 8e5d89df7f vm.c: unify mrb_gc_arena_restore and mrb_gc_arena_shrink. 2021-10-10 20:12:11 +09:00
Yukihiro "Matz" Matsumoto 5cdf1eabdd Merge pull request #5555 from dearblue/str-ref-regexp
Partially allow overriding of `String#[]` methods
2021-10-09 14:15:06 +09:00
dearblue e8205ec906 Fix typo for OP_SETIDX 2021-10-09 13:36:19 +09:00
dearblue 8c355ec7e3 Partially allow overriding of String#[] methods
This is for the purpose of supporting `Regexp`.

- configuration and build

  ```console
  % cat regexp_config.rb
  MRuby::Lockfile.disable
  MRuby::Build.new do
    toolchain "clang"
    enable_debug
    gem core: "mruby-bin-mruby"
    gem core: "mruby-print"
    gem mgem: "mruby-onig-regexp"
    #gem mgem: "mruby-regexp-pcre"
  end

  % rake MRUBY_CONFIG=regexp_config.rb
  ```

- mruby HEAD (bec074e)

  ```console
  % build/host/bin/mruby -e 'p "abcdefg"[/.(?=...$)/]'
  -e:1: can't convert OnigRegexp into Integer (TypeError)
  ```

- with this patch

  ```console
  % build/host/bin/mruby -e 'p "abcdefg"[/.(?=...$)/]'
  "d"
  ```
2021-10-09 13:28:10 +09:00
Yukihiro "Matz" Matsumoto bec074e6a3 vm.c: check call stack depth before pushing the frame.
Existing call stack depth checks are unified into this check in
`cipush()`. The maximum depth is now specified by `MRB_CALL_LEVEL_MAX`
(the default is 512).  The older `MRB_FUNCALL_DEPTH_MAX` is no longer
used.
2021-10-08 15:35:33 +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 c70159b356 Revert "vm.c: add assertions instead of mrb_ensure_hash_type()."
This reverts commit 913a0a5a03.
In some cases, `OP_HASHADD` operand may not be `Hash`. We should check
explicitly in those cases.
2021-09-24 17:10:11 +09:00
Yukihiro "Matz" Matsumoto 913a0a5a03 vm.c: add assertions instead of mrb_ensure_hash_type(). 2021-09-21 16:47:55 +09:00
Yukihiro "Matz" Matsumoto 938af8a8ff vm.c: add array assertions. 2021-09-19 23:17:19 +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 8619ba6a38 Use struct initializer instead of memset. 2021-09-15 13:02:15 +09:00
Yukihiro "Matz" Matsumoto 7df31d9451 mruby.h: remove acc from callinfo; add cci instead.
`acc` was used as an index of the receiver (if positive), or a flag for
methods implemented in C. We replace `regs[ci->acc]` by `ci[1].stack[0]`.
And renamed `acc` (originally meant accumulator position) to `cci`
(means callinfo for C implemented method).
2021-09-10 12:39:51 +09:00
Yukihiro "Matz" Matsumoto 3050630b69 vm.c, codedump.c: add IREP_TT_NFLAG assertions.
The pool specified by `OP_STRING` (and `OP_SYMBOL`) should represent a
string, so that `IREP_TT_NFLAG` should be zero.
2021-09-10 10:25:07 +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 3693187beb vm.c: ci->acc (int16_t) may overflow. 2021-09-10 10:15:32 +09:00
Yukihiro "Matz" Matsumoto 5acf7e7cf7 vm.c: remove duplicated calls of mrb_vm_ci_target_class(). 2021-09-04 12:54:04 +09:00
Yukihiro "Matz" Matsumoto e86c9cb57c Do no use return values from mrb_ensure_ functions.
They return the checking argument without modification, so the values
are already there. Maybe we should change the return type to `void` but
keep them unchanged for compatibility.
2021-09-01 07:00:54 +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 43f9901ec2 Revert "Drop unnecessary upper procs linked from class/module/def syntax"
Fix #5528
This reverts commit 59201b59046b9e73c309508350cd3c0fafd20e4d; #5497
2021-08-12 11:42:27 +09:00
Yukihiro "Matz" Matsumoto 966aa476d1 vm.c: fix integer type error in mrb_protect_error. 2021-07-26 10:49:12 +09:00
Yukihiro "Matz" Matsumoto 5c804cf68f Remove redundant include headers.
- stdlib.h
- stddef.h
- stdint.h
- stdarg.h
- limits.h
- float.h
2021-07-25 13:07:10 +09:00
Yukihiro "Matz" Matsumoto d9a8981c26 vm.c: OP_DEF to push a symbol to a register.
The code generator no longer need to emit `OP_LOADSYM` after `OP_DEF`.
`doc/opcode.md` is also updated.
2021-07-03 06:40:05 +09:00
Yukihiro "Matz" Matsumoto a624da6fdb vm.c: need to adjust pc for OP_EXT[123]. 2021-07-02 21:57:52 +09:00
Yukihiro "Matz" Matsumoto 99dbcec89c Revert "Remove OP_EXT[123] from operands."
This reverts commit fd10c72319.

I thought it was OK to restrict index value within 1 byte, but in some
cases index value could be 16 bits (2 bytes). I had several ideas to
address the issue, but reverting `fd10c72` is the easiest way. The
biggest reason is `mruby/c` still supports `OP_EXT[123]`, so that they
don't need any additional work.
2021-06-30 22:41:13 +09:00