diff options
| -rw-r--r-- | doc/opcode.md | 2 | ||||
| -rw-r--r-- | include/mruby/ops.h | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 2 | ||||
| -rw-r--r-- | src/codedump.c | 4 | ||||
| -rw-r--r-- | src/vm.c | 34 |
5 files changed, 34 insertions, 10 deletions
diff --git a/doc/opcode.md b/doc/opcode.md index 98d29cdc0..d7e620350 100644 --- a/doc/opcode.md +++ b/doc/opcode.md @@ -66,7 +66,7 @@ sign) of operands. | OP_EXCEPT | B | R(a) = exc | | OP_RESCUE | BB | R(b) = R(a).isa?(R(b)) | | OP_POPERR | B | a.times{rescue_pop()} | -| OP_RAISE | B | raise(R(a)) | +| OP_RAISEIF | B | raise(R(a)) if R(a) | | OP_EPUSH | B | ensure_push(SEQ[a]) | | OP_EPOP | B | A.times{ensure_pop().call} | | OP_SENDV | BB | R(a) = call(R(a),Syms(b),*R(a+1)) | diff --git a/include/mruby/ops.h b/include/mruby/ops.h index 7d20ac0ad..45397e2ed 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -53,7 +53,7 @@ OPCODE(ONERR, S) /* rescue_push(a) */ OPCODE(EXCEPT, B) /* R(a) = exc */ OPCODE(RESCUE, BB) /* R(b) = R(a).isa?(R(b)) */ OPCODE(POPERR, B) /* a.times{rescue_pop()} */ -OPCODE(RAISE, B) /* raise(R(a)) */ +OPCODE(RAISEIF, B) /* raise(R(a)) if R(a) */ OPCODE(EPUSH, B) /* ensure_push(SEQ[a]) */ OPCODE(EPOP, B) /* A.times{ensure_pop().call} */ OPCODE(SENDV, BB) /* R(a) = call(R(a),Syms(b),*R(a+1)) */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index e55b6791d..7911ecb36 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -1533,7 +1533,7 @@ codegen(codegen_scope *s, node *tree, int val) } if (pos1) { dispatch(s, pos1); - genop_1(s, OP_RAISE, exc); + genop_1(s, OP_RAISEIF, exc); } } pop(); diff --git a/src/codedump.c b/src/codedump.c index a19d60708..2225da4ce 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -507,8 +507,8 @@ codedump(mrb_state *mrb, const mrb_irep *irep) printf("OP_RESCUE\tR%d\tR%d", a, b); print_lv_ab(mrb, irep, a, b); break; - CASE(OP_RAISE, B); - printf("OP_RAISE\tR%d\t\t", a); + CASE(OP_RAISEIF, B); + printf("OP_RAISEIF\tR%d\t\t", a); print_lv_a(mrb, irep, a); break; CASE(OP_POPERR, B); @@ -1255,8 +1255,24 @@ RETRY_TRY_BLOCK: } CASE(OP_EXCEPT, B) { - mrb_value exc = mrb_obj_value(mrb->exc); - mrb->exc = 0; + mrb_value exc; + + if (mrb->exc == NULL) { + exc = mrb_nil_value(); + } + else { + switch (mrb->exc->tt) { + case MRB_TT_BREAK: + case MRB_TT_EXCEPTION: + exc = mrb_obj_value(mrb->exc); + break; + default: + mrb_assert(!"bad mrb_type"); + exc = mrb_nil_value(); + break; + } + mrb->exc = NULL; + } regs[a] = exc; NEXT; } @@ -1289,9 +1305,17 @@ RETRY_TRY_BLOCK: NEXT; } - CASE(OP_RAISE, B) { - mrb_exc_set(mrb, regs[a]); - goto L_RAISE; + CASE(OP_RAISEIF, B) { + mrb_value exc = regs[a]; + if (mrb_break_p(exc)) { + mrb->exc = mrb_obj_ptr(exc); + goto L_BREAK; + } + mrb_exc_set(mrb, exc); + if (mrb->exc) { + goto L_RAISE; + } + NEXT; } CASE(OP_EPUSH, B) { |
