mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
vm: add OP_MATCHERR instruction for pattern matching errors
Replace 4-instruction sequence (GETCONST + STRING + SEND + RAISEIF) with single OP_MATCHERR instruction that raises NoMatchingPatternError with "pattern not matched" message. Bump RITE binary format version from 0300 to 0400 due to opcode number shift. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -52,13 +52,13 @@ MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
|
||||
/* Binary Format Version Major:Minor */
|
||||
/* Major: Incompatible to prior versions */
|
||||
/* Minor: Upper-compatible to prior versions */
|
||||
#define RITE_BINARY_MAJOR_VER "03"
|
||||
#define RITE_BINARY_MAJOR_VER "04"
|
||||
#define RITE_BINARY_MINOR_VER "00"
|
||||
#define RITE_BINARY_FORMAT_VER RITE_BINARY_MAJOR_VER RITE_BINARY_MINOR_VER
|
||||
#define RITE_COMPILER_NAME "MATZ"
|
||||
#define RITE_COMPILER_VERSION "0000"
|
||||
|
||||
#define RITE_VM_VER "0300"
|
||||
#define RITE_VM_VER "0400"
|
||||
|
||||
#define RITE_BINARY_EOF "END\0"
|
||||
#define RITE_SECTION_IREP_IDENT "IREP"
|
||||
|
||||
@@ -57,6 +57,7 @@ OPCODE(JMPUW, S) /* unwind_and_jump_to(a) */
|
||||
OPCODE(EXCEPT, B) /* R[a] = exc */
|
||||
OPCODE(RESCUE, BB) /* R[b] = R[a].isa?(R[b]) */
|
||||
OPCODE(RAISEIF, B) /* raise(R[a]) if R[a] */
|
||||
OPCODE(MATCHERR, Z) /* raise NoMatchingPatternError */
|
||||
OPCODE(SSEND, BBB) /* R[a] = self.send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..) (c=n|k<<4) */
|
||||
OPCODE(SSENDB, BBB) /* R[a] = self.send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..,&R[a+n+2k+1]) */
|
||||
OPCODE(SEND, BBB) /* R[a] = R[a].send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..) (c=n|k<<4) */
|
||||
|
||||
@@ -6647,20 +6647,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
pop(); /* pop the value */
|
||||
if (mp->raise_on_fail) {
|
||||
/* expr => pattern: raise NoMatchingPatternError */
|
||||
int msg_off = new_lit_cstr(s, "pattern not matched");
|
||||
int exc_reg = cursp();
|
||||
/* Get NoMatchingPatternError class */
|
||||
genop_2(s, OP_GETCONST, exc_reg, sym_idx(s, MRB_SYM_2(s->mrb, NoMatchingPatternError)));
|
||||
push();
|
||||
/* Create message string */
|
||||
genop_2(s, OP_STRING, cursp(), msg_off);
|
||||
push();
|
||||
/* Call NoMatchingPatternError.new(message) */
|
||||
pop(); /* pop argument */
|
||||
genop_3(s, OP_SEND, exc_reg, sym_idx(s, MRB_SYM_2(s->mrb, new)), 1);
|
||||
/* Raise the exception */
|
||||
genop_1(s, OP_RAISEIF, exc_reg);
|
||||
/* No push here: RAISEIF never returns, control transfers to rescue handler */
|
||||
genop_0(s, OP_MATCHERR);
|
||||
}
|
||||
else {
|
||||
/* expr in pattern: return false */
|
||||
|
||||
@@ -572,6 +572,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out)
|
||||
fprintf(out, "RAISEIF\tR%d\t", a);
|
||||
print_lv_a(mrb, irep, a, out);
|
||||
break;
|
||||
CASE(OP_MATCHERR, Z):
|
||||
fprintf(out, "MATCHERR\n");
|
||||
break;
|
||||
|
||||
CASE(OP_DEBUG, BBB):
|
||||
fprintf(out, "DEBUG\t\t%d\t%d\t%d\n", a, b, c);
|
||||
|
||||
Reference in New Issue
Block a user