Commit Graph

866 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto e8a202d461 vm.c: inline callinfo related functions. 2022-07-04 21:15:42 +09:00
Yukihiro "Matz" Matsumoto 580af1cf73 vm.c (mrb_bidx): avoid repeated packing/unpacking argument info. 2022-06-29 07:51:08 +09:00
Yukihiro "Matz" Matsumoto 7319e744ad src/vm.c: move some inline functions from mruby/proc.h; ref #5732
Those functions are seldom called so no need to be inline functions.
2022-06-27 19:04:35 +09:00
Ryan Lopopolo 8a5e6f47f2 Match #if at end of vm.c 2022-06-23 22:25:15 -07:00
Ryan Lopopolo 3af82fbb51 Respect MRB_USE_CXX_ABI #define 2022-06-23 21:54:53 -07:00
Ryan Lopopolo c4c37b2069 Fix mismatched braces in extern "C" blocks when compiling as C++
When compiling mruby with `-DMRB_USE_CXX_EXCEPTION`, clang fails to
compile and emits these warnings:

    vendor/mruby/src/vm.c:3066:1: error: extraneous closing brace ('}')
    } /* end of extern "C" */
    ^
    vendor/mruby/src/vm.c:3072:7: error: expected '}'
    #endif
          ^
    vendor/mruby/src/vm.c:3070:12: note: to match this '{'
    extern "C" {
               ^
    2 errors generated.

Fixup the implementation of the `extern "C"` block in `vm.c`.
2022-06-23 21:38:55 -07:00
Yukihiro "Matz" Matsumoto 92be161b1f vm.c (check_target_class): return Object class if target is NULL.
Since #5272 target_class kept in a Proc may be NULL. It crashes
`iij/mruby-require` gem for example; close #5725
2022-06-23 07:54:04 +09:00
Yukihiro "Matz" Matsumoto 8981b2fb28 vm.c (ary_new_from_regs): stack may be reallocated.
Unlike `hash_new_from_regs`, `ary_new_from_regs` do not call
`mrb_funcall` et al directly or indirectly. But since it may invoke the
garbage collection, and hooks for GC may call `mrb_funcall` etc (although
calling them is not encouraged), we care stack reallocation just for the
safety.
2022-05-30 11:52:12 +09:00
Yukihiro "Matz" Matsumoto aa7f98dedb vm.c (hash_new_from_regs): stack may be reallocated. 2022-05-30 01:18:15 +09:00
dearblue c32cac6e59 Introduce mrb_stack_extend_adjust()
If necessary, adjust the pointer on the VM stack after `mrb_stack_extend()`.
2022-05-04 09:13:56 +09:00
Yukihiro "Matz" Matsumoto 23ce122fc2 vm.c (mrb_funcall_with_block): copy argv before prepare_missing(); fix #5704
Since prepare_missing() may call `missing` method internally.
2022-05-02 18:59:38 +09:00
Yukihiro "Matz" Matsumoto 8bd77ca332 vm.c: target_class should be retrieved from callinfo. 2022-04-24 14:01:59 +09:00
Yukihiro "Matz" Matsumoto a4d97934d5 vm.c: check if target_class is NULL (when prepended). 2022-04-22 08:32:18 +09:00
Yukihiro "Matz" Matsumoto e7d0e6fd5a vm.c: fix integer size mixtures. 2022-04-20 16:18:18 +09:00
Yukihiro "Matz" Matsumoto e14782e8a1 vm.c: fixed wrong compilation condition for MRB_INT32. 2022-04-10 19:03:37 +09:00
Yukihiro "Matz" Matsumoto 17a31efa8a vm.c: adjust size of int types. 2022-04-10 19:03:01 +09:00
Yukihiro "Matz" Matsumoto b22044fca6 vm.c: cipush() to take uint16_t argc. 2022-04-10 17:36:03 +09:00
Yukihiro "Matz" Matsumoto 4260ce83a9 vm.c: avoid bare macro constant reference. wrap it by defined(). 2022-04-09 23:43:03 +09:00
Yukihiro "Matz" Matsumoto dcaf4083d5 src/bigint.c: implement multi-precision integer.
To enable multi-precision integer support, you need to link
`mruby-bigint` mrbgem. The gem itself is empty but it turns on
the "bigint" support.
2022-04-09 17:16:10 +09:00
Yukihiro "Matz" Matsumoto 3cf291f722 vm.c: create break object before clearing GC arena.
Otherwise it possibly cause use-after-free.
2022-04-04 12:26:52 +09:00
Yukihiro "Matz" Matsumoto b99c389ec3 internal.h: aggregate internal functions.
Internal functions can only be called from within the library.
Functions listed in `mruby/internal.h` can be called from:

* core (src/*.c)
* gems (mrbgems/**/*.c)

But not from the application linked with `libmruby`.
2022-04-02 18:25:13 +09:00
Yukihiro "Matz" Matsumoto 00acae117d vm.c: target class may be NULL. 2022-04-01 16:40:06 +09:00
Yukihiro "Matz" Matsumoto 7f5a490d09 vm.c: vm.c: stack may be reallocated in functions calls; aaa28a5
`mrb_range_new()` also calls VM recursively.
2022-03-26 21:06:02 +09:00
Yukihiro "Matz" Matsumoto aaa28a5089 vm.c: stack may be reallocated in functions calls.
Probably due to recursive VM calls via `mrb_funcall()`.
2022-03-25 12:54:45 +09:00
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