mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: fix pattern matching === operand order bug
When matching array/hash element patterns like `[Integer]` against values, the element register was being overwritten by codegen before the comparison. This caused `[1] in [Integer]|[String]` to incorrectly return false because the bytecode was effectively doing `1.===(Integer)` instead of `Integer.===(1)`. Fix by preserving the element value with push() before calling codegen_pattern, so the element stays at cursp()-1 while the pattern value is generated at cursp(). Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4557,8 +4557,10 @@ codegen_pattern(codegen_scope *s, node *pattern, int target, uint32_t *fail_pos)
|
||||
gen_int(s, cursp(), i);
|
||||
push(); push(); pop(); pop(); pop();
|
||||
genop_3(s, OP_SEND, cursp(), sym_idx(s, MRB_OPSYM_2(s->mrb, aref)), 1);
|
||||
push(); /* Preserve element result for codegen_pattern */
|
||||
/* Match element pattern */
|
||||
codegen_pattern(s, elem->car, cursp(), fail_pos);
|
||||
codegen_pattern(s, elem->car, cursp() - 1, fail_pos);
|
||||
pop(); /* Clean up element slot */
|
||||
}
|
||||
|
||||
/* Bind rest elements if rest is a variable */
|
||||
@@ -4598,8 +4600,10 @@ codegen_pattern(codegen_scope *s, node *pattern, int target, uint32_t *fail_pos)
|
||||
gen_int(s, cursp(), i);
|
||||
push(); push(); pop(); pop(); pop();
|
||||
genop_3(s, OP_SEND, cursp(), sym_idx(s, MRB_OPSYM_2(s->mrb, aref)), 1);
|
||||
push(); /* Preserve element result for codegen_pattern */
|
||||
/* Match element pattern */
|
||||
codegen_pattern(s, elem->car, cursp(), fail_pos);
|
||||
codegen_pattern(s, elem->car, cursp() - 1, fail_pos);
|
||||
pop(); /* Clean up element slot */
|
||||
}
|
||||
|
||||
pop(); /* Pop arr_reg */
|
||||
@@ -4685,8 +4689,10 @@ codegen_pattern(codegen_scope *s, node *pattern, int target, uint32_t *fail_pos)
|
||||
}
|
||||
push(); push(); pop(); pop(); pop();
|
||||
genop_3(s, OP_SEND, cursp(), sym_idx(s, MRB_OPSYM_2(s->mrb, aref)), 1);
|
||||
push(); /* Preserve element result for codegen_pattern */
|
||||
/* Match element pattern - on fail, try next index */
|
||||
codegen_pattern(s, elem->car, cursp(), &match_fail);
|
||||
codegen_pattern(s, elem->car, cursp() - 1, &match_fail);
|
||||
pop(); /* Clean up element slot */
|
||||
}
|
||||
|
||||
/* All elements matched - bind pre and post if named */
|
||||
@@ -4825,9 +4831,11 @@ codegen_pattern(codegen_scope *s, node *pattern, int target, uint32_t *fail_pos)
|
||||
}
|
||||
push(); push(); pop(); pop(); pop();
|
||||
genop_3(s, OP_SEND, cursp(), sym_idx(s, MRB_OPSYM_2(s->mrb, aref)), 1);
|
||||
push(); /* Preserve value for codegen_pattern */
|
||||
|
||||
/* Match pattern against value */
|
||||
codegen_pattern(s, pat, cursp(), fail_pos);
|
||||
codegen_pattern(s, pat, cursp() - 1, fail_pos);
|
||||
pop(); /* Clean up value slot */
|
||||
}
|
||||
|
||||
/* Handle rest pattern */
|
||||
|
||||
Reference in New Issue
Block a user