From f6f8124406e69799d97b44b3be67e9847afa1d53 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 29 Dec 2025 18:19:58 +0900 Subject: [PATCH] codegen.c: fix crash in parallel assignment optimization The direct literal generation optimization for parallel assignment was using the RHS count as the loop bound but only filling registers for LHS variables. When RHS has more elements than LHS (e.g., `a,=1,2`), this caused uninitialized register indices to be used, generating garbage opcodes that crashed the VM. Fix by counting LHS variables and only applying the optimization when LHS and RHS counts match exactly. Co-authored-by: Claude --- mrbgems/mruby-compiler/core/codegen.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 4362c9629..20c517e53 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -5170,22 +5170,31 @@ codegen_masgn(codegen_scope *s, node *varnode, node *rhs, int sp, int val) int regs[16]; /* support up to 16 variables */ node *lhs = masgn_n->pre; node *rhs_elem = t; - int count = 0; + int rhs_count = 0, lhs_count = 0; mrb_bool all_simple = TRUE; + /* Count lhs variables */ + while (lhs && lhs_count < 16) { + lhs_count++; + lhs = lhs->cdr; + } + /* Count and check rhs are all simple literals */ - while (rhs_elem && count < 16) { + while (rhs_elem && rhs_count < 16) { if (!is_simple_literal(rhs_elem->car)) { all_simple = FALSE; break; } - count++; + rhs_count++; rhs_elem = rhs_elem->cdr; } - if (all_simple && count > 0 && all_lvar_pre(s, lhs, regs, count)) { + /* Only apply when lhs and rhs counts match exactly */ + lhs = masgn_n->pre; + if (all_simple && lhs_count > 0 && lhs_count == rhs_count && + all_lvar_pre(s, lhs, regs, lhs_count)) { /* Direct generation: generate literals into target registers */ rhs_elem = t; - for (int i = 0; i < count; i++) { + for (int i = 0; i < lhs_count; i++) { gen_literal_to_reg(s, rhs_elem->car, regs[i]); rhs_elem = rhs_elem->cdr; }