Skip to content

Commit da2d652

Browse files
matzclaude
andcommitted
codegen.c: fix NODE_MATCH_PAT to push result when val is true
Pattern matching expressions were not pushing a result value in several code paths when used in value context (e.g., string interpolation). This caused crashes when the result was expected on the stack. Fix all code paths in NODE_MATCH_PAT to push the appropriate value: - 'in' pattern returns true/false - '=>' pattern returns nil (matches CRuby behavior) Co-authored-by: Claude <noreply@anthropic.com>
1 parent f6f8124 commit da2d652

File tree

1 file changed

+41
-7
lines changed

1 file changed

+41
-7
lines changed

mrbgems/mruby-compiler/core/codegen.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6520,11 +6520,22 @@ codegen(codegen_scope *s, node *tree, int val)
65206520
codegen(s, mp->value, VAL);
65216521
pop();
65226522
gen_move(s, idx, cursp(), 0); /* peephole optimizes LOADI+MOVE */
6523-
break;
6523+
goto match_pat_push_result;
65246524
}
65256525
}
65266526
/* Wildcard pattern - just evaluate value for side effects */
65276527
codegen(s, mp->value, NOVAL);
6528+
match_pat_push_result:
6529+
if (val) {
6530+
/* 'in' pattern returns true, '=>' pattern returns nil */
6531+
if (mp->raise_on_fail) {
6532+
gen_load_nil(s, 1);
6533+
}
6534+
else {
6535+
genop_1(s, OP_LOADT, cursp());
6536+
push();
6537+
}
6538+
}
65286539
break;
65296540
}
65306541

@@ -6561,10 +6572,15 @@ codegen(codegen_scope *s, node *tree, int val)
65616572
if (fail_pos != JMPLINK_START) {
65626573
goto pattern_fail_handling;
65636574
}
6564-
/* Pattern always matches - for 'in' pattern, return true */
6565-
if (!mp->raise_on_fail && val) {
6566-
genop_1(s, OP_LOADT, cursp());
6567-
push();
6575+
/* Pattern always matches - push result if needed */
6576+
if (val) {
6577+
if (mp->raise_on_fail) {
6578+
gen_load_nil(s, 1); /* '=>' pattern returns nil */
6579+
}
6580+
else {
6581+
genop_1(s, OP_LOADT, cursp()); /* 'in' pattern returns true */
6582+
push();
6583+
}
65686584
}
65696585
break;
65706586
}
@@ -6595,8 +6611,14 @@ codegen(codegen_scope *s, node *tree, int val)
65956611
uint32_t match_pos;
65966612

65976613
if (val) {
6598-
genop_1(s, OP_LOADT, cursp());
6599-
push();
6614+
/* 'in' pattern returns true, '=>' pattern returns nil */
6615+
if (mp->raise_on_fail) {
6616+
gen_load_nil(s, 1);
6617+
}
6618+
else {
6619+
genop_1(s, OP_LOADT, cursp());
6620+
push();
6621+
}
66006622
}
66016623

66026624
/* Optimize: single JMPNOT can be inverted to JMPIF, eliminating JMP */
@@ -6644,6 +6666,18 @@ codegen(codegen_scope *s, node *tree, int val)
66446666
/* End of pattern matching */
66456667
dispatch(s, match_pos);
66466668
}
6669+
else {
6670+
/* Pattern always matches - push result if needed */
6671+
if (val) {
6672+
if (mp->raise_on_fail) {
6673+
gen_load_nil(s, 1); /* '=>' pattern returns nil */
6674+
}
6675+
else {
6676+
genop_1(s, OP_LOADT, cursp()); /* 'in' pattern returns true */
6677+
push();
6678+
}
6679+
}
6680+
}
66476681
}
66486682
break;
66496683

0 commit comments

Comments
 (0)