diff options
Diffstat (limited to 'src/vm.c')
| -rw-r--r-- | src/vm.c | 196 |
1 files changed, 105 insertions, 91 deletions
@@ -4,7 +4,6 @@ ** See Copyright Notice in mruby.h */ -#include <string.h> #include <setjmp.h> #include <stddef.h> #include <stdarg.h> @@ -13,7 +12,6 @@ #include "mruby/class.h" #include "mruby/hash.h" #include "mruby/irep.h" -#include "mruby/numeric.h" #include "mruby/proc.h" #include "mruby/range.h" #include "mruby/string.h" @@ -69,6 +67,8 @@ The value below allows about 60000 recursive calls in the simplest case. */ #define TO_STR(x) TO_STR_(x) #define TO_STR_(x) #x +#define ARENA_RESTORE(mrb,ai) (mrb)->arena_idx = (ai) + static inline void stack_clear(mrb_value *from, size_t count) { @@ -109,6 +109,7 @@ stack_init(mrb_state *mrb) c->ciend = c->cibase + CALLINFO_INIT_SIZE; c->ci = c->cibase; c->ci->target_class = mrb->object_class; + c->ci->stackent = c->stack; } static inline void @@ -116,6 +117,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase) { mrb_callinfo *ci = mrb->c->cibase; + if (newbase == oldbase) return; while (ci <= mrb->c->ci) { struct REnv *e = ci->env; if (e && e->cioff >= 0) { @@ -123,6 +125,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase) e->stack = newbase + off; } + ci->stackent = newbase + (ci->stackent - oldbase); ci++; } } @@ -130,39 +133,39 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase) /** def rec ; $deep =+ 1 ; if $deep > 1000 ; return 0 ; end ; rec ; end */ static void +stack_extend_alloc(mrb_state *mrb, int room) +{ + mrb_value *oldbase = mrb->c->stbase; + int size = mrb->c->stend - mrb->c->stbase; + int off = mrb->c->stack - mrb->c->stbase; + + /* Use linear stack growth. + It is slightly slower than doubling the stack space, + but it saves memory on small devices. */ + if (room <= size) + size += MRB_STACK_GROWTH; + else + size += room; + + mrb->c->stbase = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); + mrb->c->stack = mrb->c->stbase + off; + mrb->c->stend = mrb->c->stbase + size; + envadjust(mrb, oldbase, mrb->c->stbase); + /* Raise an exception if the new stack size will be too large, + to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */ + if (size > MRB_STACK_MAX) { + mrb_raise(mrb, E_RUNTIME_ERROR, "stack level too deep. (limit=" TO_STR(MRB_STACK_MAX) ")"); + } +} + +static inline void stack_extend(mrb_state *mrb, int room, int keep) { if (mrb->c->stack + room >= mrb->c->stend) { - int size, off; - - mrb_value *oldbase = mrb->c->stbase; - - size = mrb->c->stend - mrb->c->stbase; - off = mrb->c->stack - mrb->c->stbase; - - /* do not leave uninitialized malloc region */ - if (keep > size) keep = size; - - /* Use linear stack growth. - It is slightly slower than doubling thestack space, - but it saves memory on small devices. */ - if (room <= size) - size += MRB_STACK_GROWTH; - else - size += room; - - mrb->c->stbase = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size); - mrb->c->stack = mrb->c->stbase + off; - mrb->c->stend = mrb->c->stbase + size; - envadjust(mrb, oldbase, mrb->c->stbase); - /* Raise an exception if the new stack size will be too large, - to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */ - if (size > MRB_STACK_MAX) { - mrb_raise(mrb, E_RUNTIME_ERROR, "stack level too deep. (limit=" TO_STR(MRB_STACK_MAX) ")"); - } + stack_extend_alloc(mrb, room); } - if (room > keep) { + /* do not leave uninitialized malloc region */ stack_clear(&(mrb->c->stack[keep]), room - keep); } } @@ -229,6 +232,7 @@ cipush(mrb_state *mrb) ci->ridx = ridx; ci->env = 0; ci->pc = 0; + ci->err = 0; return ci; } @@ -261,8 +265,10 @@ ecall(mrb_state *mrb, int i) p = mrb->c->ensure[i]; if (!p) return; + if (mrb->c->ci->eidx > i) + mrb->c->ci->eidx = i; ci = cipush(mrb); - ci->stackidx = mrb->c->stack - mrb->c->stbase; + ci->stackent = mrb->c->stack; ci->mid = ci[-1].mid; ci->acc = CI_ACC_SKIP; ci->argc = 0; @@ -326,7 +332,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr if (setjmp(c_jmp) != 0) { /* error */ while (old_ci != mrb->c->ci) { - mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx; + mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); } mrb->jmp = 0; @@ -357,14 +363,14 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr p = mrb_method_search_vm(mrb, &c, mid); if (!p) { undef = mid; - mid = mrb_intern2(mrb, "method_missing", 14); + mid = mrb_intern_lit(mrb, "method_missing"); p = mrb_method_search_vm(mrb, &c, mid); n++; argc++; } ci = cipush(mrb); ci->mid = mid; ci->proc = p; - ci->stackidx = mrb->c->stack - mrb->c->stbase; + ci->stackent = mrb->c->stack; ci->argc = argc; ci->target_class = c; if (MRB_PROC_CFUNC_P(p)) { @@ -391,7 +397,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr ci->acc = CI_ACC_DIRECT; val = p->body.func(mrb, self); - mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx; + mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); mrb_gc_arena_restore(mrb, ai); } @@ -426,7 +432,7 @@ mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_v ci = cipush(mrb); ci->mid = mid; ci->proc = p; - ci->stackidx = mrb->c->stack - mrb->c->stbase; + ci->stackent = mrb->c->stack; ci->argc = argc; ci->target_class = c; if (MRB_PROC_CFUNC_P(p)) { @@ -447,7 +453,7 @@ mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_v if (MRB_PROC_CFUNC_P(p)) { val = p->body.func(mrb, self); - mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx; + mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); } else { @@ -490,7 +496,7 @@ localjump_error(mrb_state *mrb, localjump_error_kind kind) msg = mrb_str_buf_new(mrb, sizeof(lead) + 7); mrb_str_buf_cat(mrb, msg, lead, sizeof(lead) - 1); mrb_str_buf_cat(mrb, msg, kind_str[kind], kind_str_len[kind]); - exc = mrb_exc_new3(mrb, E_LOCALJUMP_ERROR, msg); + exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); mrb->exc = mrb_obj_ptr(exc); } @@ -509,11 +515,12 @@ argnum_error(mrb_state *mrb, int num) str = mrb_format(mrb, "wrong number of arguments (%S for %S)", mrb_fixnum_value(mrb->c->ci->argc), mrb_fixnum_value(num)); } - exc = mrb_exc_new3(mrb, E_ARGUMENT_ERROR, str); + exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str); mrb->exc = mrb_obj_ptr(exc); } -#define ERR_PC_HOOK(mrb, pc) mrb->c->ci->err = pc; +#define ERR_PC_SET(mrb, pc) mrb->c->ci->err = pc; +#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0; #ifdef ENABLE_DEBUG #define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); #else @@ -554,7 +561,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int /* mrb_assert(mrb_proc_cfunc_p(proc)) */ mrb_irep *irep = proc->body.irep; mrb_code *pc = irep->iseq; - struct irep_pool *pool = irep->pool; + mrb_value *pool = irep->pool; mrb_sym *syms = irep->syms; mrb_value *regs = NULL; mrb_code i; @@ -598,7 +605,6 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_init(mrb); } stack_extend(mrb, irep->nregs, stack_keep); - mrb->c->ci->err = pc; mrb->c->ci->proc = proc; mrb->c->ci->nregs = irep->nregs + 1; regs = mrb->c->stack; @@ -618,10 +624,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int CASE(OP_LOADL) { /* A Bx R(A) := Pool(Bx) */ - if (pool[GETARG_Bx(i)].type == IREP_TT_FLOAT) - SET_FLT_VALUE(mrb, regs[GETARG_A(i)], pool[GETARG_Bx(i)].value.f); - else - SET_INT_VALUE(regs[GETARG_A(i)], pool[GETARG_Bx(i)].value.i); + regs[GETARG_A(i)] = pool[GETARG_Bx(i)]; NEXT; } @@ -693,8 +696,9 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int CASE(OP_GETCV) { /* A B R(A) := ivget(Sym(B)) */ - ERR_PC_HOOK(mrb, pc); + ERR_PC_SET(mrb, pc); regs[GETARG_A(i)] = mrb_vm_cv_get(mrb, syms[GETARG_Bx(i)]); + ERR_PC_CLR(mrb); NEXT; } @@ -708,8 +712,9 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int /* A B R(A) := constget(Sym(B)) */ mrb_value val; - ERR_PC_HOOK(mrb, pc); + ERR_PC_SET(mrb, pc); val = mrb_vm_const_get(mrb, syms[GETARG_Bx(i)]); + ERR_PC_CLR(mrb); regs = mrb->c->stack; regs[GETARG_A(i)] = val; NEXT; @@ -726,8 +731,9 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int mrb_value val; int a = GETARG_A(i); - ERR_PC_HOOK(mrb, pc); + ERR_PC_SET(mrb, pc); val = mrb_const_get(mrb, regs[a], syms[GETARG_Bx(i)]); + ERR_PC_CLR(mrb); regs = mrb->c->stack; regs[a] = val; NEXT; @@ -843,19 +849,20 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize); } mrb->c->ensure[mrb->c->ci->eidx++] = p; - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } CASE(OP_EPOP) { /* A A.times{ensure_pop().call} */ - int n; int a = GETARG_A(i); + mrb_callinfo *ci = mrb->c->ci; + int n, eidx = ci->eidx; - for (n=0; n<a; n++) { - ecall(mrb, --mrb->c->ci->eidx); + for (n=0; n<a && eidx > ci[-1].eidx; n++) { + ecall(mrb, --eidx); + ARENA_RESTORE(mrb, ai); } - mrb_gc_arena_restore(mrb, ai); NEXT; } @@ -896,7 +903,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int if (!m) { mrb_value sym = mrb_symbol_value(mid); - mid = mrb_intern2(mrb, "method_missing", 14); + mid = mrb_intern_lit(mrb, "method_missing"); m = mrb_method_search_vm(mrb, &c, mid); if (n == CALL_MAXARGS) { mrb_ary_unshift(mrb, regs[a+1], sym); @@ -911,7 +918,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int ci = cipush(mrb); ci->mid = mid; ci->proc = m; - ci->stackidx = mrb->c->stack - mrb->c->stbase; + ci->stackent = mrb->c->stack; if (n == CALL_MAXARGS) { ci->argc = -1; } @@ -951,7 +958,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int syms = irep->syms; } } - regs = mrb->c->stack = mrb->c->stbase + ci->stackidx; + regs = mrb->c->stack = ci->stackent; pc = ci->pc; cipop(mrb); JUMP; @@ -1006,7 +1013,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int if (mrb->exc) goto L_RAISE; /* pop stackpos */ ci = mrb->c->ci; - regs = mrb->c->stack = mrb->c->stbase + ci->stackidx; + regs = mrb->c->stack = ci->stackent; regs[ci->acc] = recv; pc = ci->pc; cipop(mrb); @@ -1053,7 +1060,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int c = mrb->c->ci->target_class->super; m = mrb_method_search_vm(mrb, &c, mid); if (!m) { - mid = mrb_intern2(mrb, "method_missing", 14); + mid = mrb_intern_lit(mrb, "method_missing"); m = mrb_method_search_vm(mrb, &c, mid); if (n == CALL_MAXARGS) { mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); @@ -1068,7 +1075,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int ci = cipush(mrb); ci->mid = mid; ci->proc = m; - ci->stackidx = mrb->c->stack - mrb->c->stbase; + ci->stackent = mrb->c->stack; if (n == CALL_MAXARGS) { ci->argc = -1; } @@ -1087,7 +1094,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int mrb_gc_arena_restore(mrb, ai); if (mrb->exc) goto L_RAISE; /* pop stackpos */ - regs = mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx; + regs = mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); NEXT; } @@ -1161,7 +1168,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int rest->len = m1+len+m2; } regs[a+1] = stack[m1+r+m2]; - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -1266,8 +1273,8 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int L_RAISE: ci = mrb->c->ci; - mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "lastpc", 6), mrb_cptr_value(mrb, pc)); - mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->c->cibase)); + mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern_lit(mrb, "lastpc"), mrb_cptr_value(mrb, pc)); + mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value(ci - mrb->c->cibase)); eidx = ci->eidx; if (ci == mrb->c->cibase) { if (ci->ridx == 0) goto L_STOP; @@ -1279,15 +1286,17 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int while (ci[0].ridx == ci[-1].ridx) { cipop(mrb); ci = mrb->c->ci; - mrb->c->stack = mrb->c->stbase + ci[1].stackidx; + mrb->c->stack = ci[1].stackent; if (ci[1].acc == CI_ACC_SKIP && prev_jmp) { mrb->jmp = prev_jmp; mrb_longjmp(mrb); } - while (eidx > ci->eidx) { - ecall(mrb, --eidx); + if (ci > mrb->c->cibase) { + while (eidx > ci[-1].eidx) { + ecall(mrb, --eidx); + } } - if (ci == mrb->c->cibase) { + else if (ci == mrb->c->cibase) { if (ci->ridx == 0) { regs = mrb->c->stack = mrb->c->stbase; goto L_STOP; @@ -1299,7 +1308,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int irep = ci->proc->body.irep; pool = irep->pool; syms = irep->syms; - regs = mrb->c->stack = mrb->c->stbase + ci[1].stackidx; + regs = mrb->c->stack = ci[1].stackent; pc = mrb->c->rescue[--ci->ridx]; } else { @@ -1332,7 +1341,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int goto L_RAISE; } if (mrb->c->prev->ci == mrb->c->prev->cibase) { - mrb_value exc = mrb_exc_new3(mrb, E_RUNTIME_ERROR, mrb_str_new(mrb, "double resume", 13)); + mrb_value exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mrb_str_new(mrb, "double resume", 13)); mrb->exc = mrb_obj_ptr(exc); goto L_RAISE; } @@ -1344,7 +1353,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int ci = mrb->c->ci; break; case OP_R_BREAK: - if (proc->env->cioff < 0) { + if (!proc->env || proc->env->cioff < 0) { localjump_error(mrb, LOCALJUMP_ERROR_BREAK); goto L_RAISE; } @@ -1360,7 +1369,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int cipop(mrb); acc = ci->acc; pc = ci->pc; - regs = mrb->c->stack = mrb->c->stbase + ci->stackidx; + regs = mrb->c->stack = ci->stackent; if (acc == CI_ACC_SKIP) { mrb->jmp = prev_jmp; return v; @@ -1392,7 +1401,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int if (!m) { mrb_value sym = mrb_symbol_value(mid); - mid = mrb_intern2(mrb, "method_missing", 14); + mid = mrb_intern_lit(mrb, "method_missing"); m = mrb_method_search_vm(mrb, &c, mid); if (n == CALL_MAXARGS) { mrb_ary_unshift(mrb, regs[a+1], sym); @@ -1536,7 +1545,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int default: goto L_SEND; } - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -1853,7 +1862,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int CASE(OP_ARRAY) { /* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */ regs[GETARG_A(i)] = mrb_ary_new_from_values(mrb, GETARG_C(i), ®s[GETARG_B(i)]); - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -1861,7 +1870,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int /* A B mrb_ary_concat(R(A),R(B)) */ mrb_ary_concat(mrb, regs[GETARG_A(i)], mrb_ary_splat(mrb, regs[GETARG_B(i)])); - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -1933,14 +1942,14 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int } } } - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } CASE(OP_STRING) { /* A Bx R(A) := str_new(Lit(Bx)) */ - regs[GETARG_A(i)] = mrb_str_new(mrb, pool[GETARG_Bx(i)].value.s->buf, pool[GETARG_Bx(i)].value.s->len); - mrb_gc_arena_restore(mrb, ai); + regs[GETARG_A(i)] = mrb_str_dup(mrb, pool[GETARG_Bx(i)]); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -1962,7 +1971,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int b+=2; } regs[GETARG_A(i)] = hash; - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -1979,7 +1988,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int } if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT; regs[GETARG_A(i)] = mrb_obj_value(p); - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -2003,7 +2012,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int } c = mrb_vm_define_class(mrb, base, super, id); regs[a] = mrb_obj_value(c); - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -2020,7 +2029,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int } c = mrb_vm_define_module(mrb, base, id); regs[a] = mrb_obj_value(c); - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -2036,7 +2045,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int ci->pc = pc + 1; ci->acc = a; ci->mid = 0; - ci->stackidx = mrb->c->stack - mrb->c->stbase; + ci->stackent = mrb->c->stack; ci->argc = 0; ci->target_class = mrb_class_ptr(recv); @@ -2052,7 +2061,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int mrb_gc_arena_restore(mrb, ai); if (mrb->exc) goto L_RAISE; /* pop stackpos */ - regs = mrb->c->stack = mrb->c->stbase + mrb->c->ci->stackidx; + regs = mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); NEXT; } @@ -2074,14 +2083,14 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int struct RClass *c = mrb_class_ptr(regs[a]); mrb_define_method_vm(mrb, c, syms[GETARG_B(i)], regs[a+1]); - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } CASE(OP_SCLASS) { /* A B R(A) := R(B).singleton_class */ regs[GETARG_A(i)] = mrb_singleton_class(mrb, regs[GETARG_B(i)]); - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } @@ -2101,17 +2110,21 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int /* A B C R(A) := range_new(R(B),R(B+1),C) */ int b = GETARG_B(i); regs[GETARG_A(i)] = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i)); - mrb_gc_arena_restore(mrb, ai); + ARENA_RESTORE(mrb, ai); NEXT; } CASE(OP_DEBUG) { /* A debug print R(A),R(B),R(C) */ +#ifdef ENABLE_DEBUG + mrb->debug_op_hook(mrb, irep, pc, regs); +#else #ifdef ENABLE_STDIO printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i)); #else abort(); #endif +#endif NEXT; } @@ -2125,6 +2138,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int ecall(mrb, n); } } + ERR_PC_CLR(mrb); mrb->jmp = prev_jmp; if (mrb->exc) { return mrb_obj_value(mrb->exc); @@ -2134,14 +2148,14 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int CASE(OP_ERR) { /* Bx raise RuntimeError with message Lit(Bx) */ - mrb_value msg = mrb_str_new(mrb, pool[GETARG_Bx(i)].value.s->buf, pool[GETARG_Bx(i)].value.s->len); + mrb_value msg = mrb_str_dup(mrb, pool[GETARG_Bx(i)]); mrb_value exc; if (GETARG_A(i) == 0) { - exc = mrb_exc_new3(mrb, E_RUNTIME_ERROR, msg); + exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, msg); } else { - exc = mrb_exc_new3(mrb, E_LOCALJUMP_ERROR, msg); + exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); } mrb->exc = mrb_obj_ptr(exc); goto L_RAISE; |
