summaryrefslogtreecommitdiffhomepage
path: root/src/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm.c')
-rw-r--r--src/vm.c196
1 files changed, 105 insertions, 91 deletions
diff --git a/src/vm.c b/src/vm.c
index 9e2cfc97e..2901f89d9 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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), &regs[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;