mruby-compiler: handle __except with CALL_MAXARGS fallback

When a hash pattern has 15 or more keys, pack them into an array
before calling __except via OP_SEND with CALL_MAXARGS, since the
OP_SEND instruction can only encode up to 14 direct arguments.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-02-16 18:42:49 +09:00
parent 1b14a3f72a
commit 488aa8630b
+13 -3
View File
@@ -5034,7 +5034,7 @@ codegen_pattern(codegen_scope *s, node *pattern, int target, uint32_t *fail_pos,
gen_move(s, recv, hash_reg, 0);
push();
if (num_keys > 0) {
/* Pass matched keys directly as arguments */
/* Pass matched keys as arguments */
int i = 0;
for (pair = pat_hash->pairs; pair; pair = pair->cdr, i++) {
node *key = pair->car->car;
@@ -5046,8 +5046,18 @@ codegen_pattern(codegen_scope *s, node *pattern, int target, uint32_t *fail_pos,
}
push();
}
genop_3(s, OP_SEND, recv, sym_idx(s, MRB_SYM_2(s->mrb, __except)), num_keys);
for (i = 0; i < num_keys; i++) pop();
if (num_keys < CALL_MAXARGS) {
/* Direct arguments */
genop_3(s, OP_SEND, recv, sym_idx(s, MRB_SYM_2(s->mrb, __except)), num_keys);
for (i = 0; i < num_keys; i++) pop();
}
else {
/* Too many keys: pack into array */
genop_2(s, OP_ARRAY, recv + 1, num_keys);
for (i = 1; i < num_keys; i++) pop();
genop_3(s, OP_SEND, recv, sym_idx(s, MRB_SYM_2(s->mrb, __except)), CALL_MAXARGS);
pop();
}
}
else {
/* No keys to exclude: rest = hash.dup */