Skip to content

Commit f6f8124

Browse files
matzclaude
andcommitted
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 <noreply@anthropic.com>
1 parent 225cdaa commit f6f8124

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

mrbgems/mruby-compiler/core/codegen.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5170,22 +5170,31 @@ codegen_masgn(codegen_scope *s, node *varnode, node *rhs, int sp, int val)
51705170
int regs[16]; /* support up to 16 variables */
51715171
node *lhs = masgn_n->pre;
51725172
node *rhs_elem = t;
5173-
int count = 0;
5173+
int rhs_count = 0, lhs_count = 0;
51745174
mrb_bool all_simple = TRUE;
51755175

5176+
/* Count lhs variables */
5177+
while (lhs && lhs_count < 16) {
5178+
lhs_count++;
5179+
lhs = lhs->cdr;
5180+
}
5181+
51765182
/* Count and check rhs are all simple literals */
5177-
while (rhs_elem && count < 16) {
5183+
while (rhs_elem && rhs_count < 16) {
51785184
if (!is_simple_literal(rhs_elem->car)) {
51795185
all_simple = FALSE;
51805186
break;
51815187
}
5182-
count++;
5188+
rhs_count++;
51835189
rhs_elem = rhs_elem->cdr;
51845190
}
5185-
if (all_simple && count > 0 && all_lvar_pre(s, lhs, regs, count)) {
5191+
/* Only apply when lhs and rhs counts match exactly */
5192+
lhs = masgn_n->pre;
5193+
if (all_simple && lhs_count > 0 && lhs_count == rhs_count &&
5194+
all_lvar_pre(s, lhs, regs, lhs_count)) {
51865195
/* Direct generation: generate literals into target registers */
51875196
rhs_elem = t;
5188-
for (int i = 0; i < count; i++) {
5197+
for (int i = 0; i < lhs_count; i++) {
51895198
gen_literal_to_reg(s, rhs_elem->car, regs[i]);
51905199
rhs_elem = rhs_elem->cdr;
51915200
}

0 commit comments

Comments
 (0)