From f467b02d4598ab64d98727348e8a9c4f04fc9b83 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 24 May 2020 11:44:31 +0900 Subject: Extended `OP_EXCEPT` and `OP_RAISE` (`OP_RAISEIF`) instructions - `OP_EXCEPT` checks if `mrb->exc` is `NULL`, `MRB_TT_EXCEPTION` or `MRB_TT_BREAK`. If `mrb->exc` is `NULL`, it will be replaced with `nil`. - If `OP_RAISE` is `nil`, it does nothing and the immediately following instruction is executed (like `OP_NOP`). Also, in case of `RBreak` object, it moves to the processing for `break`. With this change, the instruction name is changed from `OP_RAISE` to `OP_RAISEIF`. --- src/codedump.c | 4 ++-- src/vm.c | 34 +++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 7 deletions(-) (limited to 'src') 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); diff --git a/src/vm.c b/src/vm.c index 3faecfaf2..2dbbe85f8 100644 --- a/src/vm.c +++ b/src/vm.c @@ -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) { -- cgit v1.2.3