Commit Graph

1154 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto 3d8ccee7a8 vm.c: optimize cipush/cipop for common cases
CI_PROC_SET: split NULL/non-NULL proc paths so the compiler can
eliminate the CFUNC/ALIAS checks when proc is a compile-time NULL
(8 of 11 cipush call sites).

cipop: add fast path for the common case where no env and no blk
are set. skips ci_env_set, orphan check, and env_unshare entirely.
most simple method calls (no blocks, no closures) take this path.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:32 +09:00
Yukihiro "Matz" Matsumoto f1a6274c34 vm.c: extract vm_call_proc() to consolidate OP_CALL and OP_BLKCALL
both opcodes share identical proc dispatch logic (alias resolution,
callinfo setup, cfunc/irep branching). the only difference is how
nargs is computed (ci_bidx vs operand b).

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:24 +09:00
Yukihiro "Matz" Matsumoto 6a6e2b48ac vm.c: replace mrb_funcall_argv() with goto L_SEND_SYM in OP_MATHILV
avoid re-entrant VM call from C; use the same dispatch pattern as
OP_MATH and OP_MATHI for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:24 +09:00
Yukihiro "Matz" Matsumoto 82bb954c23 vm.c: extract vm_define_method() to consolidate OP_TDEF and OP_SDEF
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:24 +09:00
Yukihiro "Matz" Matsumoto 78658d67e1 vm.c: extract OP_GETIDX, OP_GETIDX0, OP_SETIDX, OP_DIV into static helpers
Phase 2 of opcode handler extraction. these opcodes use
L_SEND_SYM/L_SENDB_SYM fallback for generic method dispatch when
the fast path (Array/Hash/String/Integer/Float) does not apply.
add VM_SEND_SYM and VM_SENDB_SYM return codes. move TYPES2 macro
to file scope for use by vm_op_div.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:22 +09:00
Yukihiro "Matz" Matsumoto 95bfa86160 vm.c: extract OP_ENTER, OP_ARGARY, OP_BLKPUSH into static helpers
extract the three largest self-contained opcode handlers from the
mrb_vm_exec() dispatch loop into static functions. add
__attribute__((flatten)) to mrb_vm_exec() so that the compiler
inlines them back, producing identical binary output while keeping
the source clean.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:22 +09:00
Yukihiro "Matz" Matsumoto 50bc8c6136 vm.c: replace constant cache generation counter with direct invalidation
Remove the per-entry generation field and per-state generation
counter. Invalidation now clears entries directly, removing one
comparison from every OP_GETCONST hot path.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:21 +09:00
Yukihiro "Matz" Matsumoto 7675601b92 vm.c: add constant lookup cache with generation counter
Cache OP_GETCONST results in a global direct-mapped cache (64 entries)
keyed by (irep, sym). Invalidate all entries via a generation counter
bumped on mrb_const_set(), mrb_const_remove(), and
mrb_define_const_id(). ~10% faster on constant-heavy code; disabled
with MRB_NO_CONST_CACHE.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:20 +09:00
Yukihiro "Matz" Matsumoto 7365ed526b Merge pull request #6785 from khasinski/cfunc-proc-aspec 2026-04-23 19:11:35 +09:00
Chris Hasiński 55f0228bf8 Store compressed aspec on cfunc RProc for correct arity/parameters
Compress the 24-bit aspec into 13 free flag bits on RProc (bits 0-6
and 14-19) when wrapping cfunc methods. Field widths: req/opt 3 bits
(max 7), post/key 2 bits (max 3), rest/kdict/block 1 bit each. Values
exceeding the compressed range are clamped and rest is forced to 1.

This enables Proc#arity and Proc#parameters to return correct results
for cfunc-backed Procs (e.g. from Method#to_proc) with zero memory
overhead -- no struct change needed.

Closes #6764
2026-04-13 13:11:27 +02:00
HASUMI Hitoshi d95ebe4a23 Fix stack extension bug causing HardFault
This patch fixes a bug in the stack extension logic that could cause a HardFault on certain configurations when the stack is reallocated to a new address.

## Background

When the mruby VM's stack runs out, stack_extend_alloc() calls mrb_realloc to grow it.
If reallocation moves the block to a new address, envadjust() adjusts all ci->stack pointers to point into the new allocation.

## The bug

The bug happened under the configuration below:

- MRB_INT64 on MRB_32BIT (`sizeof(mrb_value) == 16` because MRB_NO_BOXING is now mandatory)
- Allocator with 8-byte alignment (eg. PICORB_ALLOC_ALIGN=8 in PicoRuby for Raspi Pico)

The delta was computed via mrb_value* pointer subtraction:

```c
ptrdiff_t delta = newbase - oldbase;  // units of sizeof(mrb_value)
```

If :
- Old address: 0x2004c508
- New address: 0x2004c510 (8-byte difference)

The pointer subtraction truncated: 8 / 16 = 0.
envadjust() was misleaded as `delta == 0` and returned early without adjusting any ci->stack pointers.
The stbase was updated to the new address, but all stack pointers still pointed 8 bytes before it.
Every register access was shifted, reading garbage, ultimately causing a HardFault.

## The fix

Byte-level char* calculation instead of mrb_value* calculation:

```c
ptrdiff_t off = (char*)newbase - (char*)oldbase;
// ...
ci->stack = (mrb_value*)((char*)ci->stack + off);
```

This ensures the adjustment is exact regardless of sizeof(mrb_value) and allocator alignment.
2026-03-30 16:25:46 +09:00
dearblue c52faebb7f Don't assign the result of mrb_funcall() directly to regs
There are two reasons:

  - If the mruby call stack is extended, the `ci` variable may become invalid.
  - The C language does not specify the order in which the left-hand and right-hand sides of an assignment expression are evaluated.
    Therefore, if the mruby data stack is extended, `ci->stack` may become invalid.
2026-03-24 21:25:46 +09:00
leviongit e8d0750458 reload ci after mrb_hash_delete_key 2026-03-20 21:35:26 +01:00
leviongit 88e356e7da remove redundant mrb_hash_get call
`mrb_hash_delete` returns the removed element (which is guaranteed to
exist due to the `mrb_hash_key_p` check), this prevents the hash from
being searched twice.
2026-03-20 21:20:18 +01:00
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 72c9e5d027 Merge pull request #6598 from dearblue/method_missing 2026-03-09 16:38:08 +09:00
Yukihiro "Matz" Matsumoto a3861dcb53 vm.c: scope down tc variable from function to block scope
Inline L_DEF_METHOD body into OP_TDEF and OP_SDEF, making `tc`
(target class) a block-local variable in each case. This eliminates
the cross-case goto and frees one register at function scope.

`ch` (catch handler) cannot be scoped down because UNWIND_ENSURE
sets it before goto L_CATCH_TAGGED_BREAK where ch->target is
consumed (cross-goto flow requires function-scope visibility).

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-02 12:04:48 +09:00
Yukihiro "Matz" Matsumoto 06bce53132 fix build for MRB_NO_BOXING + MRB_INT64 on 32-bit
- array.h: disable embedded arrays when MRB_INT64 makes mrb_value
  too large to embed (fixes MRB_ARY_EMBED_LEN_MAX assertion)
- error.h: enable MRB_USE_RBREAK_VALUE_UNION for all 32-bit
  no-boxing builds (MRB_USE_FLOAT32 is irrelevant without
  word/nan boxing)
- gc.c: restrict RVALUE 8-byte alignment padding to
  MRB_WORD_BOXING builds (fixes RVALUE size assertion)
- vm.c: guard direct ary->as.ary access with MRB_ARY_NO_EMBED

Fixes #6722.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-25 15:10:24 +09:00
Yukihiro "Matz" Matsumoto b460554d33 vm.c: generalize pre-dispatch argument count check for C methods
Replace check_method_noarg() with check_argument_count() that validates
min <= argc <= max using the full aspec stored in mrb_method_t.flags.
This catches ArgumentError earlier at dispatch time, before entering
the C function.

The old check only handled the special case of aspec==0 (NOARG).
The new check extracts REQ, OPT, REST, POST, KEY, and KDICT from
the aspec and validates accordingly. Keyword hash is counted as
a positional arg only when the method doesn't accept keywords.

Remove MRB_METHOD_NOARG_P macro from proc.h (subsumed by aspec check).
Fix 15 incorrect aspec declarations across the codebase that were
exposed by the stricter enforcement.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 14:25:48 +09:00
Yukihiro "Matz" Matsumoto 4a097525df proc.h: unify method flag layout; eliminate aspec shifting
Move MRB_METHOD_FUNC_FL to bit 24 and visibility flags to
bits 25-26 so that MRB_ARGS_*() values (bits 0-23) can be
stored directly without shifting. This makes MRB_MT_PRIVATE
and MRB_METHOD_PRIVATE_FL the same value, eliminating the
dual-constant confusion and simplifying the MRB_MT_ENTRY()
macro to a single OR operation.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 13:49:17 +09:00
Yukihiro "Matz" Matsumoto b07518e85c parse.y: implement &nil in formal parameters
`&nil` is recently introduced in CRuby to explicitly declare that
a method does not accept a block. When a block is passed,
ArgumentError "no block accepted" is raised. This is analogous to
`**nil` for keyword arguments.

The noblock flag is encoded in bit 23 of OP_ENTER's aspec operand
(24=n1:m5:o5:r1:m5:k5:d1:b1), avoiding the need for a new opcode.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 16:54:17 +09:00
Yukihiro "Matz" Matsumoto 914d64ef0c vm.c: skip keyword argument hash duplication in OP_ENTER
The keyword argument hash passed to a method is always freshly
constructed at the call site - either by hash_new_from_regs() in
OP_SEND for inline keyword pairs, or by OP_HASH/OP_HASHCAT for
compiler-generated keyword arguments (including the **h splat case
which creates OP_HASH(0)+OP_HASHCAT). Since no caller retains a
reference to this hash, the mrb_hash_dup() was redundant.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-10 23:01:03 +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
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 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 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 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 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 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
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
HASUMI Hitoshi 0a21eef938 Fix mruby-task for PicoRuby Integration
With this PR, I can remove the original task.c in picoruby/picoruby and future development will be much easier.

## Add

### General

- C API functions exported with MRB_API for external integration:
  - mrb_execute_proc_synchronously() for synchronous proc execution
  - Task control APIs (mrb_create_task, mrb_suspend_task, mrb_resume_task, mrb_terminate_task, mrb_stop_task, mrb_task_value, mrb_task_status)
  - Task context management APIs for picoruby-sandbox (mrb_task_init_context, mrb_task_reset_context, mrb_task_proc_set)
  - Task.tick class method to get current tick count
- Comprehensive C API documentation with WASM integration examples

### For PicoRuby.wasm

- WASM/Emscripten support: Disable SIGALRM timer when __EMSCRIPTEN__ is defined, as JavaScript handles tick calls via setInterval
- Scheduler lock mechanism to prevent asynchronous task operations during synchronous execution (scheduler_lock counter in mrb_task_state)
- mrb_task_run_once() for single-step execution (event loop integration)

## Fix

### task.c
- Replace MRB_FIBER_TERMINATED with MRB_TASK_STOPPED just for clarity
- Allow suspending DORMANT and WAITING tasks in mrb_task_suspend (See comment in the source)
- Task context initialization by removing dummy callinfo push/pop

*NOTE*

With the dummy callinfo code that I deleted, IRB in PicoRuby ended SEGV.
If that code is mandatory, we need to discuss how to solve my problem.

### vm.c
- Handle MRB_TASK_CREATED status in VM's NORMAL_RETURN phase to properly stop tasks

----

These changes are necessary to make PicoRuby work.
Nevertheless, even with this patch, MicroRuby for Raspberry Pi Pico 2 is still unstable.
I would like to merge this PR anyway to make development easier by involving the PicoRuby community.
2026-01-11 17:07:04 +09:00
Yukihiro "Matz" Matsumoto ee06bbb417 vm.c: replace type assertions with runtime checks
Replace mrb_assert with mrb_ensure_*_type for VM opcodes that require
specific types:

- OP_ARYCAT: mrb_ensure_array_type
- OP_ARYPUSH: mrb_ensure_array_type
- OP_ASET: mrb_ensure_array_type (also fixed: was checking wrong register)
- OP_INTERN: mrb_ensure_string_type
- OP_HASHCAT: mrb_ensure_hash_type

These checks catch codegen bugs with clear error messages in both
debug and release builds.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-04 15:16:03 +09:00
Yukihiro "Matz" Matsumoto 6b482ee3f8 vm.c: add runtime type check for OP_STRCAT
Replace mrb_assert with mrb_ensure_string_type to catch codegen bugs
even in release builds. This prevents null-dereference crashes when
OP_STRCAT receives a non-string first operand due to compiler bugs.

Consistent with OP_HASH which uses mrb_ensure_hash_type for similar
type safety.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-04 14:09:57 +09:00
Yukihiro "Matz" Matsumoto a263c43adb vm.c, codedump.c: undef CASE macro
Add #undef CASE at end of files to prevent macro redefinition
warnings in amalgamation builds.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-01 12:35:09 +09:00
Yukihiro "Matz" Matsumoto 8a29ab591e vm.c: use mrb_obj_ptr()->c for faster class check in GETIDX/SETIDX
Replace mrb_obj_class() with direct mrb_obj_ptr(va)->c access:

- Skips unnecessary mrb_immediate_p() check (these types are never immediate)
- Skips mrb_class_real() traversal for singleton classes
- Objects with singleton methods now fall back to method dispatch
  (correct behavior since they might have overridden []/[]=)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-25 18:01:44 +09:00
Yukihiro "Matz" Matsumoto 115438aa1e vm.c: optimize OP_SETIDX for Array and Hash; ref #6675
Add inline optimizations for Array#[]= and Hash#[]= in OP_SETIDX,
matching the pattern established for OP_GETIDX:

- Array class: use mrb_ary_set() directly (integer index only)
- Hash class: use mrb_hash_set() directly
- Subclasses: fall back to method dispatch (can override []=)
- String: unchanged (complex 2-3 argument signature)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-25 18:01:44 +09:00
Yukihiro "Matz" Matsumoto 5102ef8022 vm.c: allow String subclasses to override []; ref #6675
Apply the same pattern as the Array/Hash fix: the OP_GETIDX optimization
now only applies to instances of the String class itself. Subclasses
fall back to method dispatch, allowing them to override the [] method.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-25 18:01:44 +09:00
Yukihiro "Matz" Matsumoto d65fb765ef vm.c: allow Array subclasses to override []; ref #6675
Apply the same pattern as the Hash fix: the OP_GETIDX optimization
now only applies to instances of the Array class itself. Subclasses
fall back to method dispatch, allowing them to override the [] method.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-25 18:01:43 +09:00
Yukihiro "Matz" Matsumoto 35af869d7d vm.c: allow Hash subclasses to override []; close #6675
The OP_GETIDX optimization now only applies to instances of the Hash
class itself. Subclasses fall back to method dispatch, allowing them
to override the [] method. This fixes compatibility with libraries
like mruby-hashie that rely on aliasing/overriding [] in subclasses.

Trade-off: Hash#[] cannot be overridden on the Hash class itself
(only on subclasses). This is a reasonable semantic for mruby since
subclassing is the proper pattern for customization.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-25 18:01:43 +09:00
Yukihiro "Matz" Matsumoto 2494a712dd vm.c: extract alias resolution logic to MRB_PROC_RESOLVE_ALIAS macro
reduce code duplication by introducing MRB_PROC_RESOLVE_ALIAS macro
to handle alias proc resolution in a consistent way across 5 locations.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 23:12:36 +09:00
dearblue 50ecc1fd2c Arranging VM dispatch macros
Consolidate duplicate common code.
2025-11-23 14:45:22 +09:00