mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: fix bytecode corruption in pattern matching optimization
The JMPNOT-to-JMPIF optimization assumed fail_pos always came from a 4-byte JMPNOT instruction. When a pinned variable is undefined, NODE_PAT_PIN generates a 3-byte OP_JMP instead, causing fail_pos - 2 to point into the previous instruction and corrupt its operand. Add a check to verify the instruction at fail_pos - 2 is actually OP_JMPNOT before modifying it. Fixes #6701 Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -6626,10 +6626,12 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
|
||||
/* Optimize: single JMPNOT can be inverted to JMPIF, eliminating JMP */
|
||||
/* Conditions: (1) single entry in fail_pos chain, and
|
||||
* (2) JMPNOT is immediately before current position (no code between) */
|
||||
/* Conditions: (1) single entry in fail_pos chain,
|
||||
* (2) JMPNOT is immediately before current position (no code between), and
|
||||
* (3) the instruction is actually JMPNOT (not JMP from undefined pinned var) */
|
||||
if ((int32_t)(fail_pos + 2) + (int16_t)PEEK_S(s->iseq+fail_pos) == 0 &&
|
||||
fail_pos + 2 == s->pc) {
|
||||
fail_pos + 2 == s->pc &&
|
||||
s->iseq[fail_pos - 2] == OP_JMPNOT) {
|
||||
/* Single failure point - invert JMPNOT to JMPIF */
|
||||
s->iseq[fail_pos - 2] = OP_JMPIF;
|
||||
match_pos = fail_pos;
|
||||
|
||||
Reference in New Issue
Block a user