Commit Graph

18293 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto eea9e30979 mruby-compiler: fix heap-buffer-overflow in pattern alternation codegen
The JMPNOT-to-JMPIF optimization in NODE_PAT_ALT assumed the fail
chain always ends with OP_JMPNOT (format BS), but NODE_PAT_PIN
generates OP_JMP (format S) when the pinned variable is undefined.
Writing OP_JMPIF at left_fail-2 then corrupts the preceding
instruction's operand, causing out-of-bounds pool access at runtime.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-10 11:12:27 +09:00
Yukihiro "Matz" Matsumoto 06d6d0b0a5 bigint.c: fix memory leak in powm with oversized modulus
Barrett and Montgomery reduction compute 2^(2k) internally where k
is the modulus bit length. When this exceeds MRB_BIGINT_BIT_LIMIT,
mrb_raise() via longjmp skips cleanup of allocated temporaries.
Add early modulus size check before any heap allocation.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-10 11:12:26 +09:00
Yukihiro "Matz" Matsumoto edce0a338f bigint.c: fix stack buffer overflow in Montgomery reduction
The work buffer size in mpz_montgomery_reduce() was calculated as
x_len + k + 2, which assumed x_len >= k. However, when R^2 mod n
produces a small result, x_len can be much smaller than k.

The Montgomery reduction loop writes k limbs at work[i] for each
iteration i=0..k-1, so the maximum index accessed is work[2k-1].
This requires at least 2k limbs in the work buffer.

Fixed by ensuring work_size is at least 2*k+2 limbs when x_len < k.

Also initialize b->as.heap before mpz_move in bint_set() to ensure
the destination mpz_t has valid initial state.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-10 11:12:26 +09:00
Yukihiro "Matz" Matsumoto cafbf8ca6b bigint.c: fix memory leak in mpz_mul_sparse and bint_mul
mpz_mul_sparse allocated temporary mpz_t variables (shifted, temp) that
were leaked when an exception was raised (e.g., RangeError from shift
width too large). bint_mul had the same issue with its output mpz_t z.

Wrap both functions with MRB_ENSURE to guarantee cleanup runs regardless
of exceptions, following the existing pattern used by mpz_mul_all_ones.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-10 11:12:26 +09:00
Yukihiro "Matz" Matsumoto 1713d4a2e7 mruby-bin-mirb: syntax highlight result values and hash key symbols
Use syntax highlighter for result values instead of single color.
Add support for hash key symbol syntax (e.g., `a:` in `{a: 1}`).

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-10 11:12:26 +09:00
Yukihiro "Matz" Matsumoto e8e2e76fd6 mruby-bin-mirb: add colored output for results and errors
Result values are shown in cyan, errors in bold red.
The arrow " => " uses gray for subtle appearance.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-10 11:12:26 +09:00
Yukihiro "Matz" Matsumoto db4c8d91ea mruby-bin-mirb: add OSC 11 terminal background color detection
Automatically detect terminal background color using OSC 11 escape
sequence to select appropriate syntax highlighting theme (dark/light).

Detection priority: MIRB_THEME env > OSC 11 > COLORFGBG env > dark default.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-10 11:12:26 +09:00
Yukihiro "Matz" Matsumoto e05bd8f806 symbol.c: use chunk-based pool for symbol string allocation
Replace per-symbol mrb_malloc() with a chunk-based string pool that
batches allocations into 4KB chunks. This reduces malloc call count
by ~12x (e.g. 909 vs 10,887 for 10k dynamic symbols) and eliminates
per-allocation malloc metadata overhead (~16 bytes/symbol).

Pool allocations are rounded up to even size to preserve LSB pointer
tagging used for literal detection.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-10 11:12:25 +09:00
Yukihiro "Matz" Matsumoto 299eebaa23 Merge pull request #6716 from dearblue/proc-identity
Fixes identity for proc object
2026-02-07 18:25:52 +09:00
Yukihiro "Matz" Matsumoto 4fad20c1e1 Merge pull request #6714 from khasinski/fix-op-debug
Fix OP_DEBUG operand type and add NULL check for debug_op_hook
2026-02-07 18:24:38 +09:00
dearblue d94ec9786e Fixes identity for proc object
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)
```
2026-02-07 16:47:39 +09:00
Yukihiro "Matz" Matsumoto 167dc8aa4a Merge pull request #6715 from mruby/dependabot/github_actions/super-linter/super-linter-8.4.0
build(deps): bump super-linter/super-linter from 8.3.2 to 8.4.0
2026-02-05 10:10:24 +09:00
dependabot[bot] a883abe025 build(deps): bump super-linter/super-linter from 8.3.2 to 8.4.0
Bumps [super-linter/super-linter](https://github.com/super-linter/super-linter) from 8.3.2 to 8.4.0.
- [Release notes](https://github.com/super-linter/super-linter/releases)
- [Changelog](https://github.com/super-linter/super-linter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/super-linter/super-linter/compare/v8.3.2...v8.4.0)

---
updated-dependencies:
- dependency-name: super-linter/super-linter
  dependency-version: 8.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-04 14:52:31 +00:00
Yukihiro "Matz" Matsumoto 7d08c6246d codegen.c: fix sign-compare warning in gen_binop()
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 16:03:08 +09:00
Yukihiro "Matz" Matsumoto 661ad9fb03 codegen.c: fix keyword arguments in super and yield
The first keyword argument was dropped because gen_hash() was
called with callargs->keyword_args->cdr instead of
callargs->keyword_args.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 15:59:20 +09:00
Yukihiro "Matz" Matsumoto f78334b3bf parse.y: allow trailing comma in method definition parameters
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 15:20:22 +09:00
Yukihiro "Matz" Matsumoto 32a27216bb test: add parentheses to method calls on assignment RHS
Preparation for future grammar simplification that may
require parentheses for method calls with arguments on
the right-hand side of assignments.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:58:14 +09:00
Yukihiro "Matz" Matsumoto 9123ef46eb vm: add OP_SEND0 and OP_SSEND0 for zero-argument method calls
These opcodes use BB format instead of BBB, saving 1 byte per call.
In the standard library, this saves ~790 bytes (568 SEND0 + 222 SSEND0).

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:27 +09:00
Yukihiro "Matz" Matsumoto f7988c9339 vm.c: use 1.5x stack growth instead of linear
Change default stack growth from linear (+128) to exponential (1.5x).
This reduces reallocation frequency while maintaining reasonable memory
usage. The minimum growth is still MRB_STACK_GROWTH (128) to ensure
small programs don't over-allocate.

MRB_STACK_EXTEND_DOUBLING (2x growth) remains available for maximum
performance when memory is not a concern.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:27 +09:00
Yukihiro "Matz" Matsumoto c68e97bf3c NEWS.md: add commit SHA for OP_RETTRUE/OP_RETFALSE entry
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:27 +09:00
Yukihiro "Matz" Matsumoto 7f13422f2f vm: add OP_RETTRUE and OP_RETFALSE for returning boolean literals
Add single-byte opcodes for returning true/false directly, completing
the set of literal return opcodes (RETSELF, RETNIL, RETTRUE, RETFALSE).

Codegen applies peephole optimization to fuse LOADTRUE/LOADFALSE + RETURN.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:27 +09:00
Yukihiro "Matz" Matsumoto a1567be5da ops.h: rename OP_LOADT/OP_LOADF to OP_LOADTRUE/OP_LOADFALSE
Rename boolean load opcodes for consistency with LOADNIL/LOADSELF.
Backward compatibility aliases are provided in opcode.h.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 60d981dbc8 NEWS.md: add commit SHA for OP_BLKCALL and OP_RETNIL entries
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 0b1af858e2 vm: add OP_RETNIL for returning nil directly
Add a new opcode that returns nil without requiring LOADNIL + RETURN.
This avoids loading nil into a register by setting the return value (v)
directly. The implementation uses a separate label (L_RETURN_NIL) to
bypass v = regs[a], preserving self in regs[0] for ensure blocks.

Codegen applies peephole optimization to fuse LOADNIL + RETURN -> RETNIL.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto a6bf08847a vm.c: refactor OP_TDEF/OP_SDEF to share method definition code
Both opcodes had nearly identical code for creating procs and
defining methods. Now they share a common L_DEF_METHOD label,
reducing code duplication by ~10 lines.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 13bc858dff mrblib: use yield instead of block.call for iteration methods
Replace block.call(x) with yield x in core iteration methods to take
advantage of the new OP_BLKCALL optimization. This improves Integer#times
by 13% and Array#each by 7%.

Methods updated:
- Integer#times, Integer#upto, Integer#downto
- Array#each, Array#each_index

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 52bee49ad2 vm: add OP_BLKCALL for direct block call without method dispatch
Bypass method dispatch when calling blocks via yield. The new OP_BLKCALL
instruction directly invokes the proc without looking up Proc#call,
resulting in 13-17% faster yield performance.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 44f6cf4b4e vm.c: add branch prediction hints for hot paths
Add mrb_likely/mrb_unlikely hints to help CPU branch predictor:
- stack overflow checks (mrb_unlikely)
- exception checks (mrb_unlikely)
- integer type checks in arithmetic (mrb_likely)
- method dispatch fast path (mrb_likely)
- argument validation errors (mrb_unlikely)
- target class checks in method definition (mrb_unlikely)

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 7e3447b29a NEWS.md: document new VM super-instructions
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 7f2e6c190b class.c: make singleton methods always public
Singleton methods should always be public regardless of the
enclosing scope's visibility setting.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 48a88ed79b vm: add OP_TDEF/OP_SDEF for fused method definition
TDEF fuses TCLASS+METHOD+DEF for normal method definitions.
SDEF fuses SCLASS+METHOD+DEF for singleton method definitions.
Saves 4 bytes per method definition (8 bytes -> 4 bytes).
Falls back to unfused instructions if irep index exceeds 255.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 51e8da6614 vm: add OP_GETIDX0 for fast array[0] access
Fuses MOVE+LOADI_0+GETIDX pattern into single instruction.
Saves 4 bytes per arr[0] access (7 bytes -> 3 bytes).

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 5475ea573a vm: add OP_ADDILV/OP_SUBILV for local variable increment
fuse MOVE+ADDI+MOVE and MOVE+SUBI+MOVE patterns into single instructions.
ADDILV/SUBILV add/subtract an immediate to a local variable in-place.
BBB format: a=local, b=working space for method call, c=immediate.

saves 5 bytes per instance (9->4 bytes), 40 occurrences in stdlib.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 724a2e2638 vm: add OP_RETSELF instruction for returning self
Fuse LOADSELF + RETURN sequence into single RETSELF instruction.
Saves 2 bytes per occurrence (3 bytes -> 1 byte).

Found 25 occurrences in mrblib, saving 50 bytes total.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto dece8cb343 vm: fuse JMPIF and MATCHERR into conditional MATCHERR
Change OP_MATCHERR from Z format (unconditional) to B format
(conditional on register). This allows fusing JMPIF + MATCHERR
sequence into a single MATCHERR instruction for simple patterns.

Before: JMPIF R2 target (4 bytes) + MATCHERR (1 byte) = 5 bytes
After:  MATCHERR R2 (2 bytes)

Saves 3 bytes per pattern match with raise_on_fail.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto 2fa99a73c2 vm: add OP_MATCHERR instruction for pattern matching errors
Replace 4-instruction sequence (GETCONST + STRING + SEND + RAISEIF)
with single OP_MATCHERR instruction that raises NoMatchingPatternError
with "pattern not matched" message.

Bump RITE binary format version from 0300 to 0400 due to opcode
number shift.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto 8c99e3dd29 AUTHORS: update entries [ci skip] 2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto a07d9fb62c vm.c: optimize OP_GETIDX with branch hints and reduced checks
- Add mrb_likely/mrb_unlikely macros to common.h for branch prediction
- Optimize OP_GETIDX array fast path:
  - Cache RArray pointer to avoid repeated RARRAY() calls
  - Single ARY_EMBED_P check instead of two (via RARRAY_LEN + RARRAY_PTR)
  - Use unsigned comparison for bounds check
  - Add branch prediction hints for common cases
- Convert switch statement to if-else chain for better branch prediction

Benchmark shows ~3% improvement for array read operations.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto ed84649fbd benchmark: add VM optimization benchmarks
Add comprehensive benchmarks for measuring VM performance:
- vm_optimization_bench.rb: Ruby-level benchmarks covering dispatch,
  arithmetic, method calls, array/hash access, loops, and recursion
- vm_dispatch_bench.c: C-level micro-benchmarks for precise measurement

These benchmarks are designed to measure the effect of potential VM
optimizations such as tail-call threading, register variables,
fused opcodes, and inline caching.

Usage:
  # Ruby benchmark
  ./build/host/bin/mruby benchmark/vm_optimization_bench.rb

  # C benchmark
  cc -O2 -I include -I build/host/include \
     benchmark/vm_dispatch_bench.c \
     build/host/lib/libmruby.a -lm -o vm_dispatch_bench
  ./vm_dispatch_bench

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto 92010e9fe4 Merge pull request #6709 from dearblue/mrb_ensure 2026-01-27 13:49:48 +09:00
Yukihiro "Matz" Matsumoto d690a49112 Merge pull request #6711 from Asmod4n/patch-4 2026-01-27 13:47:13 +09:00
Hendrik c836b096af Add error handling for fdset size limit
This should fix it for Windows.
2026-01-25 16:04:23 +01:00
Hendrik 8769f37868 Improve error handling for file descriptor range 2026-01-25 15:46:56 +01:00
Hendrik 44831711fc Fix out of bounds read and write in IO.select
Added error handling for file descriptors larger than FD_SETSIZE in mrb_hal_io_fdset_set and mrb_hal_io_fdset_isset functions, for posix hal.

I actually don't know how to fix this on windows, or if it needs fixing.
2026-01-25 15:42:17 +01:00
dearblue 5bc08befae Use the specialized MRB_ENSURE() instead of mrb_protect_error() 2026-01-24 11:34:02 +09:00
dearblue da75e4b049 Use MRB_ENSURE() instead of mrb_ensure()
The purpose is to avoid using the `MRB_TT_CPTR` object.
The reasons are as follows:
  - The `MRB_WORD_BOXING` setting involves object creation.
  - If object creation fails, the `ary_set_t` data leaks memory.
2026-01-24 11:32:57 +09:00
dearblue 3ac682b2de Add the MRB_ENSURE() macro 2026-01-24 11:31:32 +09:00
Chris Hasiński d7249ab1de Fix OP_DEBUG operand type and add NULL check for debug_op_hook
1. Change CASE(OP_DEBUG, Z) to CASE(OP_DEBUG, BBB) to match the
   definition in include/mruby/ops.h. The previous code declared Z
   (no operands) but then manually called FETCH_BBB(), which caused
   incorrect behavior with extended opcodes (OP_EXT1/2/3).

2. Add NULL check before calling debug_op_hook, consistent with
   how code_fetch_hook is handled. This prevents crashes when
   MRB_USE_DEBUG_HOOK is enabled but no hook function is set.

Fixes: #5686
2026-01-24 01:24:46 +01:00
Yukihiro "Matz" Matsumoto c25b562256 Merge pull request #6706 from Asmod4n/patch-4 2026-01-20 13:28:25 +09:00
Yukihiro "Matz" Matsumoto aadd23cc70 Merge pull request #6699 from hasumikin/fix/mruby-task 2026-01-20 12:37:29 +09:00