From 6897eb55f98e67c18197d7b4724ca6171ba291d8 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 17 Jul 2022 20:13:37 +0900 Subject: [PATCH] Place `LocalJumpError` messages in ROM Note that the meaning of the operand `a` in `OP_ERR` has changed. --- include/mruby/internal.h | 17 ++++++++ include/mruby/ops.h | 2 +- mrbgems/mruby-compiler/core/codegen.c | 19 ++++----- src/codedump.c | 7 ++-- src/vm.c | 59 ++++++++++----------------- 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/include/mruby/internal.h b/include/mruby/internal.h index 30b1edf522..1486922eec 100644 --- a/include/mruby/internal.h +++ b/include/mruby/internal.h @@ -45,6 +45,23 @@ mrb_value mrb_get_backtrace(mrb_state *mrb); void mrb_exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg); mrb_value mrb_exc_mesg_get(mrb_state *mrb, struct RException *exc); +#define MRB_LOCALJUMP_ERROR_FOREACH(def) \ + def(MRB_LOCALJUMP_ERROR_BREAK, "unexpected break") \ + def(MRB_LOCALJUMP_ERROR_NEXT, "unexpected next") \ + def(MRB_LOCALJUMP_ERROR_REDO, "unexpected redo") \ + def(MRB_LOCALJUMP_ERROR_RETRY, "unexpected retry") \ + def(MRB_LOCALJUMP_ERROR_RETURN, "unexpected return") \ + def(MRB_LOCALJUMP_ERROR_YIELD, "unexpected yield") + +enum { +#define MRB_LOCALJUMP_ERROR_DEFINE(n, mesg) n, + MRB_LOCALJUMP_ERROR_FOREACH(MRB_LOCALJUMP_ERROR_DEFINE) +#undef MRB_LOCALJUMP_ERROR_DEFINE + MRB_LOCALJUMP_ERROR_LAST +}; + +extern const char *const mrb_localjump_error_messages[MRB_LOCALJUMP_ERROR_LAST]; + /* gc */ void mrb_gc_mark_mt(mrb_state*, struct RClass*); size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); diff --git a/include/mruby/ops.h b/include/mruby/ops.h index b4d71748b1..dd2835b0a3 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -113,7 +113,7 @@ OPCODE(UNDEF, B) /* undef_method(target_class,Syms[a]) */ OPCODE(SCLASS, B) /* R[a] = R[a].singleton_class */ OPCODE(TCLASS, B) /* R[a] = target_class */ OPCODE(DEBUG, BBB) /* print a,b,c */ -OPCODE(ERR, B) /* raise(LocalJumpError, Pool[a]) */ +OPCODE(ERR, B) /* raise(LocalJumpError, mrb_localjump_error_messages[a]) */ OPCODE(EXT1, Z) /* make 1st operand (a) 16bit */ OPCODE(EXT2, Z) /* make 2nd operand (b) 16bit */ OPCODE(EXT3, Z) /* make 1st and 2nd operands 16bit */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 58adf59739..487bad448a 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -106,7 +106,7 @@ static void gen_assignment(codegen_scope *s, node *tree, node *rhs, int sp, int static void gen_massignment(codegen_scope *s, node *tree, int sp, int val); static void codegen(codegen_scope *s, node *tree, int val); -static void raise_error(codegen_scope *s, const char *msg); +static void raise_error(codegen_scope *s, int msg); static void codegen_error(codegen_scope *s, const char *message) @@ -2143,11 +2143,9 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) } static void -raise_error(codegen_scope *s, const char *msg) +raise_error(codegen_scope *s, int msg) { - int idx = new_lit_cstr(s, msg); - - genop_1(s, OP_ERR, idx); + genop_1(s, OP_ERR, msg); } static mrb_int @@ -3144,7 +3142,7 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_NEXT: if (!s->loop) { - raise_error(s, "unexpected next"); + raise_error(s, MRB_LOCALJUMP_ERROR_NEXT); } else if (s->loop->type == LOOP_NORMAL) { codegen(s, tree, NOVAL); @@ -3165,7 +3163,7 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_REDO: if (!s->loop || s->loop->type == LOOP_BEGIN || s->loop->type == LOOP_RESCUE) { - raise_error(s, "unexpected redo"); + raise_error(s, MRB_LOCALJUMP_ERROR_REDO); } else { genjmp(s, OP_JMPUW, s->loop->pc1); @@ -3175,14 +3173,13 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_RETRY: { - const char *msg = "unexpected retry"; const struct loopinfo *lp = s->loop; while (lp && lp->type != LOOP_RESCUE) { lp = lp->prev; } if (!lp) { - raise_error(s, msg); + raise_error(s, MRB_LOCALJUMP_ERROR_RETRY); } else { genjmp(s, OP_JMPUW, lp->pc0); @@ -3950,7 +3947,7 @@ loop_break(codegen_scope *s, node *tree) { if (!s->loop) { codegen(s, tree, NOVAL); - raise_error(s, "unexpected break"); + raise_error(s, MRB_LOCALJUMP_ERROR_BREAK); } else { struct loopinfo *loop; @@ -3977,7 +3974,7 @@ loop_break(codegen_scope *s, node *tree) } } if (!loop) { - raise_error(s, "unexpected break"); + raise_error(s, MRB_LOCALJUMP_ERROR_BREAK); return; } diff --git a/src/codedump.c b/src/codedump.c index 751dd7ad0c..4a55c10633 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -548,11 +548,12 @@ codedump(mrb_state *mrb, const mrb_irep *irep) print_lv_a(mrb, irep, a); break; CASE(OP_ERR, B): - if ((irep->pool[a].tt & IREP_TT_NFLAG) == 0) { - printf("ERR\t\t%s\n", irep->pool[a].u.str); + printf("ERR\t\t%d", a); + if (a < MRB_LOCALJUMP_ERROR_LAST) { + printf("\t\t\t; %s\n", mrb_localjump_error_messages[a]); } else { - printf("ERR\tL(%d)\n", a); + printf("\n"); } break; CASE(OP_EXCEPT, B): diff --git a/src/vm.c b/src/vm.c index c3b8d9bd56..1dab5d7615 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1115,27 +1115,11 @@ catch_handler_find(mrb_state *mrb, mrb_callinfo *ci, const mrb_code *pc, uint32_ return NULL; } -typedef enum { - LOCALJUMP_ERROR_RETURN = 0, - LOCALJUMP_ERROR_BREAK = 1, - LOCALJUMP_ERROR_YIELD = 2 -} localjump_error_kind; - -static void -localjump_error(mrb_state *mrb, localjump_error_kind kind) -{ - char kind_str[3][7] = { "return", "break", "yield" }; - char kind_str_len[] = { 6, 5, 5 }; - static const char lead[] = "unexpected "; - mrb_value msg; - mrb_value exc; - - msg = mrb_str_new_capa(mrb, sizeof(lead) + 7); - mrb_str_cat(mrb, msg, lead, sizeof(lead) - 1); - mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]); - exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); - mrb_exc_set(mrb, exc); -} +const char *const mrb_localjump_error_messages[MRB_LOCALJUMP_ERROR_LAST] = { +#define MRB_LOCALJUMP_ERROR_MESSAGE(n, mesg) mesg, + MRB_LOCALJUMP_ERROR_FOREACH(MRB_LOCALJUMP_ERROR_MESSAGE) +#undef MRB_LOCALJUMP_ERROR_MESSAGE +}; #define RAISE_EXC(mrb, exc) do { \ mrb_value exc_value = (exc); \ @@ -1143,6 +1127,12 @@ localjump_error(mrb_state *mrb, localjump_error_kind kind) goto L_RAISE; \ } while (0) +#define RAISE_LOCALJUMP_ERROR(mrb, kind) do { \ + const char *exc_cmesg = mrb_localjump_error_messages[kind]; \ + mrb_value exc_mesg = mrb_str_new_static(mrb, exc_cmesg, strlen(exc_cmesg)); \ + RAISE_EXC(mrb, mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, exc_mesg)); \ +} while (0) + #define RAISE_LIT(mrb, c, str) RAISE_EXC(mrb, mrb_exc_new_lit(mrb, c, str)) #define RAISE_FORMAT(mrb, c, fmt, ...) RAISE_EXC(mrb, mrb_exc_new_str(mrb, c, mrb_format(mrb, fmt, __VA_ARGS__))) @@ -2243,21 +2233,18 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) struct REnv *e = MRB_PROC_ENV(dst); if (!MRB_ENV_ONSTACK_P(e) || (e->cxt && e->cxt != mrb->c)) { - localjump_error(mrb, LOCALJUMP_ERROR_RETURN); - goto L_RAISE; + RAISE_LOCALJUMP_ERROR(mrb, MRB_LOCALJUMP_ERROR_RETURN); } } /* check jump destination */ while (cibase <= ci && ci->proc != dst) { if (ci->cci > CINFO_NONE) { /* jump cross C boundary */ - localjump_error(mrb, LOCALJUMP_ERROR_RETURN); - goto L_RAISE; + RAISE_LOCALJUMP_ERROR(mrb, MRB_LOCALJUMP_ERROR_RETURN); } ci--; } if (ci <= cibase) { /* no jump destination */ - localjump_error(mrb, LOCALJUMP_ERROR_RETURN); - goto L_RAISE; + RAISE_LOCALJUMP_ERROR(mrb, MRB_LOCALJUMP_ERROR_RETURN); } ci = mrb->c->ci; while (cibase <= ci && ci->proc != dst) { @@ -2447,14 +2434,12 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) struct REnv *e = uvenv(mrb, lv-1); if (!e || (!MRB_ENV_ONSTACK_P(e) && e->mid == 0) || MRB_ENV_LEN(e) <= m1+r+m2+1) { - localjump_error(mrb, LOCALJUMP_ERROR_YIELD); - goto L_RAISE; + RAISE_LOCALJUMP_ERROR(mrb, MRB_LOCALJUMP_ERROR_YIELD); } stack = e->stack + 1; } if (mrb_nil_p(stack[m1+r+m2+kd])) { - localjump_error(mrb, LOCALJUMP_ERROR_YIELD); - goto L_RAISE; + RAISE_LOCALJUMP_ERROR(mrb, MRB_LOCALJUMP_ERROR_YIELD); } regs[a] = stack[m1+r+m2+kd]; NEXT; @@ -3035,12 +3020,12 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) } CASE(OP_ERR, B) { - size_t len = pool[a].tt >> 2; - mrb_value exc; - - mrb_assert((pool[a].tt&IREP_TT_NFLAG)==0); - exc = mrb_exc_new(mrb, E_LOCALJUMP_ERROR, pool[a].u.str, len); - RAISE_EXC(mrb, exc); + if (a < MRB_LOCALJUMP_ERROR_LAST) { + RAISE_LOCALJUMP_ERROR(mrb, a); + } + else { + RAISE_LIT(mrb, E_INDEX_ERROR, "invalid `a` operand for OP_ERR"); + } } CASE(OP_EXT1, Z) {