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>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-12-25 02:34:03 +09:00
parent 5102ef8022
commit 115438aa1e
+24 -4
View File
@@ -1923,10 +1923,30 @@ RETRY_TRY_BLOCK:
}
CASE(OP_SETIDX, B) {
c = 2;
mid = MRB_OPSYM(aset);
SET_NIL_VALUE(regs[a+3]);
goto L_SENDB_SYM;
mrb_value va = regs[a], vb = regs[a+1], vc = regs[a+2];
switch (mrb_type(va)) {
case MRB_TT_ARRAY:
/* optimize only for Array class; subclasses may override []= */
if (mrb_obj_class(mrb, va) != mrb->array_class) goto setidx_fallback;
if (!mrb_integer_p(vb)) goto setidx_fallback;
mrb_ary_set(mrb, va, mrb_integer(vb), vc);
ci = mrb->c->ci;
regs[a] = vc;
NEXT;
case MRB_TT_HASH:
/* optimize only for Hash class; subclasses may override []= */
if (mrb_obj_class(mrb, va) != mrb->hash_class) goto setidx_fallback;
mrb_hash_set(mrb, va, vb, vc);
ci = mrb->c->ci;
regs[a] = vc;
NEXT;
default:
setidx_fallback:
c = 2;
mid = MRB_OPSYM(aset);
SET_NIL_VALUE(regs[a+3]);
goto L_SENDB_SYM;
}
}
CASE(OP_GETCONST, BB) {