35 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto 8956c5abb5 mruby.h: include mruby/presym.h for all source files
Since presym is now mandatory, mruby.h includes presym.h so that
MRB_SYM() macros are available everywhere without explicit include.
Remove redundant #include <mruby/presym.h> from all source files.

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-09 16:50:58 +09:00
Yukihiro "Matz" Matsumoto d1e8085a1e mruby-binding: add error helper functions to eliminate goto
Add badname_error() and caller_error() helper functions to replace
goto statements used for error handling. These functions are marked
with mrb_noreturn attribute since they call mrb_raise() which never
returns.

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-12 10:25:36 +09:00
Yukihiro "Matz" Matsumoto 242936a90b mruby-binding: add comprehensive documentation with examples for binding methods
Enhanced documentation for Binding class methods with detailed examples:

- local_variable_defined?: Added examples showing usage within methods and at
  top-level, including interaction with local_variable_set
- local_variable_get: Added examples demonstrating retrieval of different data
  types, variable modification tracking, and NameError behavior
- local_variable_set: Added examples showing variable assignment and creation
- local_variables: Added examples showing array of local variable names
- receiver: Added examples showing bound receiver object access
- binding (Kernel method): Added examples showing binding creation and usage

Co-authored-by: Atlassian Rovo Dev
2025-07-17 12:51:35 +09:00
Yukihiro "Matz" Matsumoto 0fc6288ae2 mruby-binding: make Binding#initialize_copy private 2025-06-16 12:44:06 +09:00
Yukihiro "Matz" Matsumoto 5731fbf17c mruby-binding: add README.md
The document is written by Google Jules.
2025-06-08 16:59:25 +09:00
Yukihiro "Matz" Matsumoto 52403abcf8 mruby-binding: make Kernel#binding private 2025-03-07 17:17:45 +09:00
Yukihiro "Matz" Matsumoto 9fbdf78380 mruby-binding: use presym for initialization 2024-06-14 01:44:49 +09:00
Yukihiro "Matz" Matsumoto 00a874cff6 Merge pull request #6281 from dearblue/binding
Fixes local variables in `mruby-binding`.
2024-05-31 22:56:04 +09:00
dearblue e82b36035e Fixes local variables in mruby-binding.
There are two issues to be fixed:
  - `mrb_irep` could leak if `mrb_calloc()` encountered an out-of-memory exception
  - `mrb_proc_merge_lvar()` allocated one extra variable name.

`irep->lv` can always refer to only one less range than `irep->nlocals`.
Also, when `mrb_proc_merge_lvar()` extends `irep->lv`, `mrb_realloc()` with `NULL` has the same behavior as `mrb_malloc()`.
2024-05-30 21:25:30 +09:00
dearblue 7ab6386cc6 Remove MRB_ENV_CLOSED flag
Set `env->cxt` to `NULL` when it is detached from the call frame.
In other words, we can determine if `env->cxt` is `NULL` or not.

Also, `mruby-binding` had been setting `env->cxt` unnecessarily, so this has been fixed.
2024-05-30 21:09:49 +09:00
dearblue 8ecfacefca Prohibit Class#allocate in a different way
The method introduced by #5979 causes a fault by swapping classes.

```console
% bin/mruby -e 'Method = Proc; p Object.method(:inspect)'
zsh: segmentation fault (core dumped)  bin/mruby -e 'Method = Proc; p Object.method(:inspect)'
```

After applying this patch, a `TypeError` exception will be raised.

```console
% bin/mruby -e 'Method = Proc; p Object.method(:inspect)'
trace (most recent call last):
        [1] -e:1
-e:1:in method: allocation failure of Proc (TypeError)
```

However, if the `mrb_vtype` is the same object, the same care must still be taken as before.

```console
% bin/mruby -e 'Method = Binding; p method(:puts).eval("12345")'
trace (most recent call last):
        [1] -e:1
-e:1:in eval: wrong argument type nil (expected Proc) (TypeError)
```
2023-12-22 21:59:34 +09:00
Yukihiro "Matz" Matsumoto 6fad067ded mruby-binding: raise in upper count check
We count `Proc` upper links then check for upper bounds (default:20),
but now we raise an exception as soon as the count exceeds the limit so
that we can avoid traverse unnecessary upper links.
2023-12-16 12:21:55 +09:00
Yukihiro "Matz" Matsumoto eea72ec84a fix spaces in the type cast expressions (cosmetic changes) 2023-05-18 23:29:16 +09:00
Yukihiro "Matz" Matsumoto 49927a7035 mruby-biding/binding.c: unify get_line and get_filename 2023-05-16 23:40:53 +09:00
Yukihiro "Matz" Matsumoto 68c58eac91 Merge pull request #5981 from dearblue/binding-only-ruby
`Kernel#binding` responds only to calls from Ruby
2023-04-14 01:06:16 +09:00
Yukihiro "Matz" Matsumoto c80db85ed5 Merge pull request #5980 from dearblue/binding-noise
Remove noise in new `mruby-binding`
2023-04-14 01:05:05 +09:00
dearblue 5cb2764279 Kernel#binding responds only to calls from Ruby
This follows the behavior changed in CRuby 3.2.
2023-04-09 21:15:13 +09:00
dearblue 93e07eec1c Remove noise in new mruby-binding
`Binding#eval` should not be defined in `mruby-binding`.
2023-04-09 21:14:33 +09:00
dearblue d3128ce58a Allow Class#allocate to be prohibited
Calling `Class#allocate` with `UnboundMethod#bind_call` usually succeeds without problems.
If this behavior does not make us happy, we can now prohibit it with `MRB_SET_INSTANCE_TT(klass, MRB_TT_UNDEF)`.

At the same time, it applies to the `Binding`, `Complex`, `Data`, `Float`, `Integer`, `Method`, `Rational` and `UnboundMethod` classes.
2023-04-09 21:14:07 +09:00
Yukihiro "Matz" Matsumoto 11af5db1c3 mruby-binding: renamed from mruby-binding-core
The dependency is now:

mruby-binding-eval:

  - mruby-binding
  - mruby-eval

mruby-proc-binding:

  - mruby-binding

mruby-eval:

  - mruby-binding [new]
2023-03-24 12:25:57 +09:00
Yukihiro "Matz" Matsumoto 501b22a2ac mruby-binding-eval: renamed from mruby-binding
Since this gem only provides `Binding#eval`.
2023-03-22 15:25:23 +09:00
Yukihiro "Matz" Matsumoto 0c8404a3e2 mruby-binding: use C implementation of Kernel#eval directly 2023-03-21 16:10:15 +09:00
Yukihiro "Matz" Matsumoto de70014643 mruby-binding/binding.c: add comment for functions from outer gems 2023-03-16 19:02:23 +09:00
Yukihiro "Matz" Matsumoto 0d07af104b internal.h: move function prototypes to <mruby/internal.h> 2023-03-14 11:06:44 +09:00
Yukihiro "Matz" Matsumoto 4107cc95a2 internal.c: move some functions to <mruby/internal.h>.
Ref #5776
2022-08-15 18:13:59 +09:00
Yukihiro "Matz" Matsumoto 37dc1be74b internal.c: move mrb_method_missing prototype to <mruby/internal.h>.
Ref #5776
2022-08-15 17:25:08 +09:00
Yukihiro "Matz" Matsumoto 94585a5902 mruby-binding/bindinc.c: should not mix int and size_t. 2022-04-18 17:47:10 +09:00
Yukihiro "Matz" Matsumoto 00f2b74ab2 kernel.c, binding.c: use MRB_SYM() instead of mrb_intern_lit(). 2022-01-31 16:20:52 +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 22b24d5d76 test/binding.rb: remove a duplicated test. 2021-07-26 10:46:36 +09:00
dearblue c182903ea0 Fixed finding variables from proc in binding.eval failed
Previously the following code did not produce the expected results:
```ruby
bx = binding
block = bx.eval("a = 1; proc { a }")
bx.eval("a = 2")
p block.call  # Expect 2 but return 1 due to a bug
```

The previous implementation of `Binding#eval` evaluated the code and then merged the top layer variables.
This patch will parse and expand the variable space before making a call to `eval`.
This means that the call to `Binding#eval` will do the parsing twice.

In addition, the following changes will be made:
- Make `mrb_parser_foreach_top_variable()`, `mrb_binding_extract_proc()` and `mrb_binding_extract_env()` functions private global functions.
- Remove the `posthook` argument from `mrb_exec_irep()`.
  The `posthook` argument was introduced to implement the `binding` method.
  This patch is unnecessary because it uses a different implementation method.

ref #5362
fixed #5491
2021-06-26 13:43:36 +09:00
dearblue 927615e1f0 Added other methods for Binding
- Added to `mruby-binding-core`
  - `Binding#local_variable_defined?`
  - `Binding#local_variable_get`
  - `Binding#local_variable_set`
  - `Binding#local_variables`
  - `Binding#receiver`
  - `Binding#source_location`
  - `Binding#inspect`
- Added to `mruby-proc-binding`
  - `Proc#binding`

The reason for separating `Proc#binding` is that core-mrbgems has a method that returns a closure object to minimize possible problems with being able to manipulate internal variables.
By separating it as different mrbgem, each user can judge this problem and incorporate it arbitrarily.
2021-02-22 23:32:43 +09:00
dearblue 792f6ac670 Adjustment of the current HEAD and bindings, and separation
Make changes to make `Binding` work.
At the same time, it separates `Binding#eval`, which depends on `mruby-eval`, from `mruby-binding-core`.
2021-02-22 23:32:18 +09:00
dearblue 935ffa46a3 Change mruby-binding to mruby-binding-core 2021-02-22 22:15:46 +09:00
ksss e8988197f2 Try Binding class 2017-02-24 11:06:47 +09:00