ROM method tables used static mrb_mt_tbl variables shared
across the process. The next pointer in each wrapper was
mutated by mrb_mt_init_rom(), causing cross-state
contamination when multiple mrb_state instances existed.
Allocate mrb_mt_tbl wrappers per-state via mrb_malloc().
The const mrb_mt_entry[] arrays remain static and shared.
Wrappers are tracked in mrb->rom_mt and freed at mrb_close().
Remove MRB_MT_ROM_TAB macro; add MRB_MT_INIT_ROM macro that
auto-computes size and calls the new mrb_mt_init_rom().
Co-authored-by: Claude <noreply@anthropic.com>
Restore MRB_ARGS_* argument specs and ISO section comments to all
709 ROM method table entries. The aspec is encoded in bits 4-27 of
the flags field; MRB_MT_NOARG is now auto-derived from aspec==0.
Add MRB_MT_ENTRY_PRIVATE() macro for private methods (53 entries)
and MRB_MT_ASPEC() accessor for extracting aspec from flags.
Co-authored-by: Claude <noreply@anthropic.com>
Move conditional mrb_define_method_id() calls into ROM entry
arrays using #ifdef guards. With linear search, sizeof in
MRB_MT_ROM_TAB() adjusts automatically after preprocessing.
Cross-class ROM tables (methods a gem defines on a class it does
not own) are reverted to mrb_define_method_id(). Multiple gems
should not add ROM table layers to the same class; each layer
costs a 16-byte mrb_mt_tbl struct in RAM and deepens the lookup
chain. Use mrb_define_method_id() for cross-class methods.
Co-authored-by: Claude <noreply@anthropic.com>
Since ROM table entries are always C functions, have the
MRB_MT_ENTRY() macro set MRB_MT_FUNC automatically. This
simplifies entry definitions across all 32 source files.
Co-authored-by: Claude <noreply@anthropic.com>
Replace binary search with linear scan in mt_get(), mt_put(),
mt_del(), mt_chain_has(), and mrb_mt_foreach(). The method cache
makes repeated lookups O(1), so linear scan on cache misses is
acceptable.
This removes the sorting requirement, allowing ROM entry arrays
to be declared const. On embedded systems, const static data
resides in flash/ROM instead of RAM, saving ~8.4KB for ~700
method entries on 32-bit MCUs.
Co-authored-by: Claude <noreply@anthropic.com>
Replace the parallel-arrays (struct-of-arrays) ROM method table
layout with an array-of-structs layout where each mrb_mt_entry
bundles its function pointer and symbol key together.
New MRB_MT_ENTRY() and MRB_MT_ROM_TAB() macros simplify ROM table
definitions from a 3-part pattern (SIZE define + anonymous struct +
mrb_mt_tbl) to a 2-part pattern (entries array + mrb_mt_tbl).
Internal mt_* functions in class.c are simplified: single memmove/
memcpy operations replace paired key+value operations.
Co-authored-by: Claude <noreply@anthropic.com>
Previously, the identity of the proc object was verified solely based on the identity of irep.
This patch makes the behavior consistent with CRuby.
The reason I noticed this issue was that when adding multiple proc objects with the same irep to a set object, only one was added.
```ruby
p Set.new(Array.new(3) { -> {} }).size
# => 3 (Ruby 4.0)
# => 1 (mruby without this patch)
```
If the block scope is the same, there is only one in CRuby as well.
However, in CRuby, the result of `Proc#to_s` is not affected by the block scope, so it has been changed to be based on the object's address.
The reason no test for `Proc#to_s` was added is that I couldn't determine whether it should be based on `Proc#hash` or the object's address.
```ruby
b = []
t = 3
while t > 0
b << -> {}
t -= 1
end
p Set.new(b).size
# => 1 (Ruby 4.0 and mruby)
p b[0].to_s == b[1].to_s
# => false (Ruby 4.0)
# => true (mruby without this patch)
```
Replace XML-style markup tags in comments with markdown equivalents:
- <code>...</code> to `...` (inline code)
- <tt>...</tt> to `...` (teletype/monospace)
- <i>...</i> to *...* (italics/emphasis)
- +...+ to `...` (parameter/variable references)
Updated 80+ files across core source, headers, mrbgems, and libraries
to use consistent markdown formatting in documentation comments.
Handled edge cases including special characters like <=> operators.
Co-authored-by: Atlassian Rovo Dev
- Add complete call-seq documentation for 4 missing public methods:
* Proc#lambda?: returns true if proc is a lambda, false if regular proc
* Proc#source_location: returns [filename, line] or nil for native procs
* Proc#to_s/inspect: returns string representation with location info
* Kernel#proc: equivalent to Proc.new, creates proc from block
- Add helpful comment for internal mrb_proc_source_location helper function
- Improve TODO comment clarity for cfunc aspec limitation
- Achieves 100% public API documentation coverage (5/5 methods documented)
- Improves code maintainability and follows mruby documentation standards
Co-authored-by: Atlassian Rovo Dev
To mark `MRB_PROC_ORPHAN` we need to keep track of passed block, even
after the assignment to the block argument. And `yield` should use the
original block; #5786, #5791, #6369
Calling the `Method#{parameters,source_location}` method on a static `Proc` object resulted in `SIGSEGV`.
The trigger is https://github.com/mruby/mruby/pull/5402.
The original implementation of the `Method#{parameters,source_location}` method was to temporarily rewrite the object and then call the method of the same name in `Proc`.
Rewriting of objects placed in the ROM section by #5402 above is prohibited by hardware such as the CPU.
This caused a `SIGSEGV`.
- 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.
Instead of including `mruby/presym.h` everywhere, we provided the
fallback `mruby/presym.inc` under `include/mruby` directory, and specify
`-I<build-dir>/include` before `-I<top-dir>/include` in `presym.rake`.
So even when someone drops `-I<build-dir>/include` in compiler options,
it just compiles without failure.
Before this patch:
$ bin/mruby -e 'p proc{}' #=> #<Proc:0x7fd5eb8206d0@-e::1>
After this patch:
$ bin/mruby -e 'p proc{}' #=> #<Proc:0x7fd5eb8206d0@-e:1>
The addresses for packed inline symbols reference `mrb->symbuf` that
could be overridden by the later call of `mrb_sym2name_len`. Since
file names in call stack information are kept as symbols, keeping the
address in the C structures could cause problems like #4342.
This changes small incompatible changes in function prototypes:
* `mrb_parser_get_filename`: return value changed to `mrb_sym`.
* `mrb_debug_get_filename`: add `mrb_state*` as a first argument.
* `mrb_debug_get_line`: ditto.
I believe above functions are almost internal, and no third-party
mrbgem use them.