diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-11-15 23:31:29 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-11-15 23:34:32 +0900 |
| commit | 0a022f7b8d3e6abc0320001430de9e7d63ba9212 (patch) | |
| tree | 047d082db4085fb8f4c26eb920906138ebd01613 /src/vm.c | |
| parent | 418ad65db40200058a023b57682f4a3853fd63bc (diff) | |
| download | mruby-0a022f7b8d3e6abc0320001430de9e7d63ba9212.tar.gz mruby-0a022f7b8d3e6abc0320001430de9e7d63ba9212.zip | |
The saved `pc` from `ERR_PC_SET` was wrong; fix #4138
The saving `pc` position should be beginning of the instruction.
But after `mruby 2.0` byte code modification, the `pc` variable
points the beginning of the next instruction. We save the previous
position in a local variable `pc0`.
Diffstat (limited to 'src/vm.c')
| -rw-r--r-- | src/vm.c | 21 |
1 files changed, 11 insertions, 10 deletions
@@ -913,8 +913,8 @@ argnum_error(mrb_state *mrb, mrb_int num) mrb_exc_set(mrb, exc); } -#define ERR_PC_SET(mrb, pc) mrb->c->ci->err = pc; -#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0; +#define ERR_PC_SET(mrb) mrb->c->ci->err = pc0; +#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0; #ifdef MRB_ENABLE_DEBUG_HOOK #define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); #else @@ -936,7 +936,7 @@ argnum_error(mrb_state *mrb, mrb_int num) #ifndef DIRECT_THREADED #define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) { -#define CASE(insn,ops) case insn: pc++; FETCH_ ## ops ();; L_ ## insn ## _BODY: +#define CASE(insn,ops) case insn: pc0=pc++; FETCH_ ## ops ();; L_ ## insn ## _BODY: #define NEXT break #define JUMP NEXT #define END_DISPATCH }} @@ -944,7 +944,7 @@ argnum_error(mrb_state *mrb, mrb_int num) #else #define INIT_DISPATCH JUMP; return mrb_nil_value(); -#define CASE(insn,ops) L_ ## insn: pc++; FETCH_ ## ops (); L_ ## insn ## _BODY: +#define CASE(insn,ops) L_ ## insn: pc0=pc++; FETCH_ ## ops (); L_ ## insn ## _BODY: #define NEXT insn=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[insn] #define JUMP NEXT @@ -999,6 +999,7 @@ MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) { /* mrb_assert(mrb_proc_cfunc_p(proc)) */ + mrb_code *pc0 = pc; mrb_irep *irep = proc->body.irep; mrb_value *pool = irep->pool; mrb_sym *syms = irep->syms; @@ -1144,7 +1145,7 @@ RETRY_TRY_BLOCK: CASE(OP_GETCV, BB) { mrb_value val; - ERR_PC_SET(mrb, pc); + ERR_PC_SET(mrb); val = mrb_vm_cv_get(mrb, syms[b]); ERR_PC_CLR(mrb); regs[a] = val; @@ -1160,7 +1161,7 @@ RETRY_TRY_BLOCK: mrb_value val; mrb_sym sym = syms[b]; - ERR_PC_SET(mrb, pc); + ERR_PC_SET(mrb); val = mrb_vm_const_get(mrb, sym); ERR_PC_CLR(mrb); regs[a] = val; @@ -1175,7 +1176,7 @@ RETRY_TRY_BLOCK: CASE(OP_GETMCNST, BB) { mrb_value val; - ERR_PC_SET(mrb, pc); + ERR_PC_SET(mrb); val = mrb_const_get(mrb, regs[a], syms[b]); ERR_PC_CLR(mrb); regs[a] = val; @@ -1424,7 +1425,7 @@ RETRY_TRY_BLOCK: m = mrb_method_search_vm(mrb, &cls, missing); if (MRB_METHOD_UNDEF_P(m) || (missing == mrb->c->ci->mid && mrb_obj_eq(mrb, regs[0], recv))) { mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, c, regs+a+1); - ERR_PC_SET(mrb, pc); + ERR_PC_SET(mrb); mrb_method_missing(mrb, mid, recv, args); } if (argc >= 0) { @@ -1621,7 +1622,7 @@ RETRY_TRY_BLOCK: m = mrb_method_search_vm(mrb, &cls, missing); if (MRB_METHOD_UNDEF_P(m)) { mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1); - ERR_PC_SET(mrb, pc); + ERR_PC_SET(mrb); mrb_method_missing(mrb, mid, recv, args); } mid = missing; @@ -2925,7 +2926,7 @@ RETRY_TRY_BLOCK: mrb_value exc; exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); - ERR_PC_SET(mrb, pc); + ERR_PC_SET(mrb); mrb_exc_set(mrb, exc); goto L_RAISE; } |
