summaryrefslogtreecommitdiffhomepage
path: root/src/vm.c
diff options
context:
space:
mode:
authorYAMAMOTO Masaya <[email protected]>2017-11-04 01:23:12 +0900
committerYAMAMOTO Masaya <[email protected]>2017-11-04 01:23:12 +0900
commit625f9f6fa314872968632c5adbee7fb3823268b8 (patch)
treefdde1700b13048212606e4a995907f3757e18e2f /src/vm.c
parentb70d69de09130ce2bc89289b4826b3deea8afaae (diff)
parente7fe6ee2638dee438c1d79ab16a0403aebec0a60 (diff)
downloadmruby-625f9f6fa314872968632c5adbee7fb3823268b8.tar.gz
mruby-625f9f6fa314872968632c5adbee7fb3823268b8.zip
Merge branch 'master' of github.com:mruby/mruby
Diffstat (limited to 'src/vm.c')
-rw-r--r--src/vm.c320
1 files changed, 139 insertions, 181 deletions
diff --git a/src/vm.c b/src/vm.c
index 7263a349e..d5c7b64f1 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -211,38 +211,38 @@ stack_extend(mrb_state *mrb, int room)
static inline struct REnv*
uvenv(mrb_state *mrb, int up)
{
- struct REnv *e = mrb->c->ci->proc->env;
+ struct RProc *proc = mrb->c->ci->proc;
+ struct REnv *e;
while (up--) {
- if (!e) return NULL;
- e = (struct REnv*)e->c;
+ proc = proc->upper;
+ if (!proc) return NULL;
}
- return e;
-}
-
-static inline mrb_bool
-is_strict(mrb_state *mrb, struct REnv *e)
-{
- ptrdiff_t cioff = e->cioff;
+ e = MRB_PROC_ENV(proc);
+ if (e) return e; /* proc has enclosed env */
+ else {
+ mrb_callinfo *ci = mrb->c->ci;
+ mrb_callinfo *cb = mrb->c->cibase;
- if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc &&
- MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) {
- return TRUE;
+ while (cb <= ci) {
+ if (ci->proc == proc) {
+ return ci->env;
+ }
+ ci--;
+ }
}
- return FALSE;
+ return NULL;
}
-static inline struct REnv*
-top_env(mrb_state *mrb, struct RProc *proc)
+static inline struct RProc*
+top_proc(mrb_state *mrb, struct RProc *proc)
{
- struct REnv *e = proc->env;
-
- if (is_strict(mrb, e)) return e;
- while (e->c) {
- e = (struct REnv*)e->c;
- if (is_strict(mrb, e)) return e;
+ while (proc->upper) {
+ if (MRB_PROC_SCOPE_P(proc) || MRB_PROC_STRICT_P(proc))
+ return proc;
+ proc = proc->upper;
}
- return e;
+ return proc;
}
#define CI_ACC_SKIP -1
@@ -273,25 +273,17 @@ cipush(mrb_state *mrb)
return ci;
}
-MRB_API void
+void
mrb_env_unshare(mrb_state *mrb, struct REnv *e)
{
if (e == NULL) return;
else {
size_t len = (size_t)MRB_ENV_STACK_LEN(e);
- ptrdiff_t cioff = e->cioff;
mrb_value *p;
if (!MRB_ENV_STACK_SHARED_P(e)) return;
- if (e->cxt.c != mrb->c) return;
- if (e->cioff == 0 && e->cxt.c == mrb->root_c) return;
+ if (e->cxt != mrb->c) return;
MRB_ENV_UNSHARE_STACK(e);
- if (!e->c) {
- /* save block argument position (negated) */
- e->cioff = -e->cxt.c->cibase[cioff].argc-1;
- if (e->cioff == 0) e->cioff = -2; /* blkarg position for vararg (1:args, 2:blk) */
- }
- e->cxt.mid = e->cxt.c->cibase[cioff].mid;
p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
if (len > 0) {
stack_copy(p, e->stack, len);
@@ -317,20 +309,22 @@ static void
ecall(mrb_state *mrb, int i)
{
struct RProc *p;
- mrb_callinfo *ci = mrb->c->ci;
- mrb_value *self = mrb->c->stack;
+ struct mrb_context *c = mrb->c;
+ mrb_callinfo *ci = c->ci;
struct RObject *exc;
+ struct REnv *env;
ptrdiff_t cioff;
int ai = mrb_gc_arena_save(mrb);
if (i<0) return;
- if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
+ if (ci - c->cibase > MRB_FUNCALL_DEPTH_MAX) {
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
}
- p = mrb->c->ensure[i];
+ p = c->ensure[i];
if (!p) return;
- mrb->c->ensure[i] = NULL;
- cioff = ci - mrb->c->cibase;
+ mrb_assert(!MRB_PROC_CFUNC_P(p));
+ c->ensure[i] = NULL;
+ cioff = ci - c->cibase;
ci = cipush(mrb);
ci->stackent = mrb->c->stack;
ci->mid = ci[-1].mid;
@@ -338,14 +332,17 @@ ecall(mrb_state *mrb, int i)
ci->argc = 0;
ci->proc = p;
ci->nregs = p->body.irep->nregs;
- ci->target_class = p->target_class;
- mrb->c->stack = mrb->c->stack + ci[-1].nregs;
+ ci->target_class = MRB_PROC_TARGET_CLASS(p);
+ env = MRB_PROC_ENV(p);
+ mrb_assert(env);
+ c->stack += p->body.irep->nregs;
exc = mrb->exc; mrb->exc = 0;
if (exc) {
mrb_gc_protect(mrb, mrb_obj_value(exc));
}
- mrb_run(mrb, p, *self);
- mrb->c->ci = mrb->c->cibase + cioff;
+ mrb_run(mrb, p, env->stack[0]);
+ mrb->c = c;
+ c->ci = c->cibase + cioff;
if (!mrb->exc) mrb->exc = exc;
mrb_gc_arena_restore(mrb, ai);
}
@@ -497,7 +494,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
mrb->c->stack[0] = self;
ci->proc = p;
- ci->target_class = p->target_class;
+ ci->target_class = MRB_PROC_TARGET_CLASS(p);
if (MRB_PROC_CFUNC_P(p)) {
return p->body.func(mrb, self);
}
@@ -734,7 +731,7 @@ mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv)
{
struct RProc *p = mrb_proc_ptr(b);
- return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class);
+ return mrb_yield_with_class(mrb, b, argc, argv, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p));
}
MRB_API mrb_value
@@ -742,7 +739,7 @@ mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg)
{
struct RProc *p = mrb_proc_ptr(b);
- return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);
+ return mrb_yield_with_class(mrb, b, 1, &arg, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p));
}
mrb_value
@@ -772,23 +769,23 @@ mrb_value
mrb_mod_s_nesting(mrb_state *mrb, mrb_value mod)
{
struct RProc *proc;
- mrb_irep *irep;
mrb_value ary;
- struct RClass *c;
+ struct RClass *c = NULL;
mrb_get_args(mrb, "");
ary = mrb_ary_new(mrb);
proc = mrb->c->ci[-1].proc; /* callee proc */
- c = proc->target_class;
- mrb_ary_push(mrb, ary, mrb_obj_value(c));
mrb_assert(!MRB_PROC_CFUNC_P(proc));
- irep = proc->body.irep;
- while (irep) {
- if (irep->target_class && irep->target_class != c) {
- c = irep->target_class;
- mrb_ary_push(mrb, ary, mrb_obj_value(c));
+ while (proc) {
+ if (MRB_PROC_SCOPE_P(proc)) {
+ struct RClass *c2 = MRB_PROC_TARGET_CLASS(proc);
+
+ if (c2 != c) {
+ c = c2;
+ mrb_ary_push(mrb, ary, mrb_obj_value(c));
+ }
}
- irep = irep->outer;
+ proc = proc->upper;
}
return ary;
}
@@ -854,18 +851,6 @@ argnum_error(mrb_state *mrb, mrb_int num)
mrb_exc_set(mrb, exc);
}
-void
-irep_uplink(mrb_state *mrb, mrb_irep *outer, mrb_irep *irep)
-{
- if (irep->outer != outer) {
- if (irep->outer) {
- mrb_irep_decref(mrb, irep->outer);
- }
- irep->outer = outer;
- mrb_irep_incref(mrb, outer);
- }
-}
-
#define ERR_PC_SET(mrb, pc) mrb->c->ci->err = pc;
#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0;
#ifdef MRB_ENABLE_DEBUG_HOOK
@@ -1323,9 +1308,10 @@ RETRY_TRY_BLOCK:
CASE(OP_EPOP) {
/* A A.times{ensure_pop().call} */
int a = GETARG_A(i);
- int n, epos = mrb->c->ci->epos;
- mrb_callinfo *ci;
+ mrb_callinfo *ci = mrb->c->ci;
+ int n, epos = ci->epos;
mrb_value self = regs[0];
+ struct RClass *target_class = ci->target_class;
if (mrb->c->eidx == epos) {
NEXT;
@@ -1343,7 +1329,7 @@ RETRY_TRY_BLOCK:
ci->proc = proc;
ci->stackent = mrb->c->stack;
ci->nregs = irep->nregs;
- ci->target_class = proc->target_class;
+ ci->target_class = target_class;
ci->pc = pc;
ci->acc = ci[-1].nregs;
mrb->c->stack += ci->acc;
@@ -1445,7 +1431,7 @@ RETRY_TRY_BLOCK:
if (GET_OPCODE(i) == OP_SENDB) {
if (mrb_type(blk) == MRB_TT_PROC) {
struct RProc *p = mrb_proc_ptr(blk);
- if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) {
+ if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) {
p->flags |= MRB_PROC_ORPHAN;
}
}
@@ -1497,20 +1483,16 @@ RETRY_TRY_BLOCK:
/* replace callinfo */
ci = mrb->c->ci;
- ci->target_class = m->target_class;
+ ci->target_class = MRB_PROC_TARGET_CLASS(m);
ci->proc = m;
- if (m->env) {
+ if (MRB_PROC_ENV_P(m)) {
mrb_sym mid;
+ struct REnv *e = MRB_PROC_ENV(m);
- if (MRB_ENV_STACK_SHARED_P(m->env)) {
- mid = m->env->cxt.c->cibase[m->env->cioff].mid;
- }
- else {
- mid = m->env->cxt.mid;
- }
+ mid = e->mid;
if (mid) ci->mid = mid;
- if (!m->env->stack) {
- m->env->stack = mrb->c->stack;
+ if (!e->stack) {
+ e->stack = mrb->c->stack;
}
}
@@ -1551,8 +1533,8 @@ RETRY_TRY_BLOCK:
else if (ci->argc+2 < irep->nregs) {
stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2);
}
- if (m->env) {
- regs[0] = m->env->stack[0];
+ if (MRB_PROC_ENV_P(m)) {
+ regs[0] = MRB_PROC_ENV(m)->stack[0];
}
pc = irep->iseq;
JUMP;
@@ -1837,6 +1819,12 @@ RETRY_TRY_BLOCK:
/* A B return R(A) (B=normal,in-block return/break) */
mrb_callinfo *ci;
+#define ecall_adjust() do {\
+ ptrdiff_t cioff = ci - mrb->c->cibase;\
+ ecall(mrb, --mrb->c->eidx);\
+ ci = mrb->c->cibase + cioff;\
+} while (0)
+
ci = mrb->c->ci;
if (ci->mid) {
mrb_value blk;
@@ -1851,7 +1839,7 @@ RETRY_TRY_BLOCK:
struct RProc *p = mrb_proc_ptr(blk);
if (!MRB_PROC_STRICT_P(p) &&
- ci > mrb->c->cibase && p->env == ci[-1].env) {
+ ci > mrb->c->cibase && MRB_PROC_ENV(p) == ci[-1].env) {
p->flags |= MRB_PROC_ORPHAN;
}
}
@@ -1901,8 +1889,7 @@ RETRY_TRY_BLOCK:
if (ci[0].ridx == ci[-1].ridx) {
mrb_value *org_stbase = mrb->c->stbase;
while (mrb->c->eidx > ci->epos) {
- ecall(mrb, --mrb->c->eidx);
- ci = mrb->c->ci;
+ ecall_adjust();
if (org_stbase != mrb->c->stbase) {
stk = mrb->c->stack;
}
@@ -1915,7 +1902,7 @@ RETRY_TRY_BLOCK:
irep = proc->body.irep;
pool = irep->pool;
syms = irep->syms;
- if (ci != ci0) {
+ if (ci < ci0) {
mrb->c->stack = ci[1].stackent;
}
stack_extend(mrb, irep->nregs);
@@ -1924,37 +1911,37 @@ RETRY_TRY_BLOCK:
else {
int acc;
mrb_value v;
+ struct RProc *dst;
+ ci = mrb->c->ci;
v = regs[GETARG_A(i)];
mrb_gc_protect(mrb, v);
switch (GETARG_B(i)) {
case OP_R_RETURN:
/* Fall through to OP_R_NORMAL otherwise */
- if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) {
- struct REnv *e = top_env(mrb, proc);
- mrb_callinfo *ce;
+ if (ci->acc >=0 && MRB_PROC_ENV_P(proc) && !MRB_PROC_STRICT_P(proc)) {
+ mrb_callinfo *cibase = mrb->c->cibase;
+ dst = top_proc(mrb, proc);
- if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) {
- localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
- goto L_RAISE;
+ if (MRB_PROC_ENV_P(dst)) {
+ struct REnv *e = MRB_PROC_ENV(dst);
+
+ if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt != mrb->c) {
+ localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
+ goto L_RAISE;
+ }
}
-
- ce = mrb->c->cibase + e->cioff;
- while (ci > ce) {
- mrb_env_unshare(mrb, ci->env);
+ while (cibase <= ci && ci->proc != dst) {
if (ci->acc < 0) {
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
goto L_RAISE;
}
ci--;
}
- mrb_env_unshare(mrb, ci->env);
- if (ce == mrb->c->cibase) {
+ if (ci <= cibase) {
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
goto L_RAISE;
}
- mrb->c->stack = mrb->c->ci->stackent;
- mrb->c->ci = ce;
break;
}
case OP_R_NORMAL:
@@ -1970,14 +1957,14 @@ RETRY_TRY_BLOCK:
goto L_RAISE;
}
while (mrb->c->eidx > 0) {
- ecall(mrb, --mrb->c->eidx);
+ ecall_adjust();
}
/* automatic yield at the end */
mrb->c->status = MRB_FIBER_TERMINATED;
mrb->c = mrb->c->prev;
mrb->c->status = MRB_FIBER_RUNNING;
+ ci = mrb->c->ci;
}
- ci = mrb->c->ci;
break;
case OP_R_BREAK:
if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN;
@@ -1990,23 +1977,23 @@ RETRY_TRY_BLOCK:
mrb_exc_set(mrb, exc);
goto L_RAISE;
}
- if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {
+ if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_STACK_SHARED_P(MRB_PROC_ENV(proc))) {
goto L_BREAK_ERROR;
}
- if (proc->env->cxt.c != mrb->c) {
+ if (MRB_PROC_ENV(proc)->cxt != mrb->c) {
goto L_BREAK_ERROR;
}
while (mrb->c->eidx > mrb->c->ci->epos) {
- ecall(mrb, --mrb->c->eidx);
+ ecall_adjust();
}
/* break from fiber block */
- if (mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) {
+ if (ci == mrb->c->cibase && ci->pc) {
struct mrb_context *c = mrb->c;
mrb->c = c->prev;
c->prev = NULL;
+ ci = mrb->c->ci;
}
- ci = mrb->c->ci;
if (ci->acc < 0) {
mrb_gc_arena_restore(mrb, ai);
mrb->c->vmexec = FALSE;
@@ -2022,31 +2009,32 @@ RETRY_TRY_BLOCK:
ci = mrb->c->ci;
}
mrb->c->stack = ci->stackent;
- mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1;
- while (ci > mrb->c->ci) {
- mrb_env_unshare(mrb, ci->env);
+ proc = proc->upper;
+ while (mrb->c->cibase < ci && ci[-1].proc != proc) {
if (ci[-1].acc == CI_ACC_SKIP) {
mrb->c->ci = ci;
goto L_BREAK_ERROR;
}
ci--;
}
- mrb_env_unshare(mrb, ci->env);
break;
default:
/* cannot happen */
break;
}
- while (mrb->c->eidx > mrb->c->ci->epos) {
- ecall(mrb, --mrb->c->eidx);
+ while (mrb->c->eidx > ci->epos) {
+ ecall_adjust();
}
- if (mrb->c->vmexec && !mrb->c->ci->target_class) {
+ if (mrb->c->vmexec && !ci->target_class) {
mrb_gc_arena_restore(mrb, ai);
mrb->c->vmexec = FALSE;
mrb->jmp = prev_jmp;
return v;
}
- ci = mrb->c->ci;
+ while (ci < mrb->c->ci) {
+ mrb_env_unshare(mrb, mrb->c->ci->env);
+ mrb->c->ci--;
+ }
acc = ci->acc;
mrb->c->stack = ci->stackent;
cipop(mrb);
@@ -2056,6 +2044,7 @@ RETRY_TRY_BLOCK:
return v;
}
pc = ci->pc;
+ ci = mrb->c->ci;
DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid)));
proc = mrb->c->ci->proc;
irep = proc->body.irep;
@@ -2156,8 +2145,7 @@ RETRY_TRY_BLOCK:
if (lv == 0) stack = regs + 1;
else {
struct REnv *e = uvenv(mrb, lv-1);
- if (!e || e->cioff == 0 ||
- (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0) ||
+ if (!e || (!MRB_ENV_STACK_SHARED_P(e) && e->mid == 0) ||
MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) {
localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
goto L_RAISE;
@@ -2359,75 +2347,51 @@ RETRY_TRY_BLOCK:
CASE(OP_DIV) {
/* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/
int a = GETARG_A(i);
+#ifndef MRB_WITHOUT_FLOAT
+ double x, y, f;
+#endif
/* need to check if op is overridden */
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
+#ifdef MRB_WITHOUT_FLOAT
{
mrb_int x = mrb_fixnum(regs[a]);
mrb_int y = mrb_fixnum(regs[a+1]);
-#ifdef MRB_WITHOUT_FLOAT
SET_INT_VALUE(regs[a], y ? x / y : 0);
-#else
- double f;
- if (y == 0) {
- if (x > 0) f = INFINITY;
- else if (x < 0) f = -INFINITY;
- else /* if (x == 0) */ f = NAN;
- }
- else {
- f = (mrb_float)x / (mrb_float)y;
- }
- SET_FLOAT_VALUE(mrb, regs[a], f);
-#endif
}
break;
-#ifndef MRB_WITHOUT_FLOAT
+#else
+ x = (mrb_float)mrb_fixnum(regs[a]);
+ y = (mrb_float)mrb_fixnum(regs[a+1]);
+ break;
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
- {
- mrb_int x = mrb_fixnum(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / y);
- }
+ x = (mrb_float)mrb_fixnum(regs[a]);
+ y = mrb_float(regs[a+1]);
break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_int y = mrb_fixnum(regs[a+1]);
- double f;
- if (y == 0) {
- f = INFINITY;
- }
- else {
- f = x / y;
- }
- SET_FLOAT_VALUE(mrb, regs[a], f);
- }
-#else
- OP_MATH_BODY(/,mrb_float,mrb_fixnum);
-#endif
+ x = mrb_float(regs[a]);
+ y = (mrb_float)mrb_fixnum(regs[a+1]);
break;
case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
-#ifdef MRB_WORD_BOXING
- {
- mrb_float x = mrb_float(regs[a]);
- mrb_float y = mrb_float(regs[a+1]);
- SET_FLOAT_VALUE(mrb, regs[a], x / y);
- }
-#else
- OP_MATH_BODY(/,mrb_float,mrb_float);
-#endif
+ x = mrb_float(regs[a]);
+ y = mrb_float(regs[a+1]);
break;
#endif
default:
goto L_SEND;
}
-#ifdef MRB_NAN_BOXING
- if (isnan(mrb_float(regs[a]))) {
- mrb_value v = mrb_float_value(mrb, mrb_float(regs[a]));
- regs[a] = v;
+
+#ifndef MRB_WITHOUT_FLOAT
+ if (y == 0) {
+ if (x > 0) f = INFINITY;
+ else if (x < 0) f = -INFINITY;
+ else /* if (x == 0) */ f = NAN;
}
+ else {
+ f = x / y;
+ }
+ SET_FLOAT_VALUE(mrb, regs[a], f);
#endif
NEXT;
}
@@ -2738,7 +2702,6 @@ RETRY_TRY_BLOCK:
int c = GETARG_c(i);
mrb_irep *nirep = irep->reps[b];
- irep_uplink(mrb, irep, nirep);
if (c & OP_L_CAPTURE) {
p = mrb_closure_new(mrb, nirep);
}
@@ -2767,9 +2730,7 @@ RETRY_TRY_BLOCK:
base = regs[a];
super = regs[a+1];
if (mrb_nil_p(base)) {
- baseclass = mrb->c->ci->proc->target_class;
- if (!baseclass) baseclass = mrb->c->ci->target_class;
-
+ baseclass = mrb->c->ci->target_class;
base = mrb_obj_value(baseclass);
}
c = mrb_vm_define_class(mrb, base, super, id);
@@ -2787,9 +2748,7 @@ RETRY_TRY_BLOCK:
base = regs[a];
if (mrb_nil_p(base)) {
- baseclass = mrb->c->ci->proc->target_class;
- if (!baseclass) baseclass = mrb->c->ci->target_class;
-
+ baseclass = mrb->c->ci->target_class;
base = mrb_obj_value(baseclass);
}
c = mrb_vm_define_module(mrb, base, id);
@@ -2807,13 +2766,14 @@ RETRY_TRY_BLOCK:
struct RProc *p;
mrb_irep *nirep = irep->reps[bx];
- irep_uplink(mrb, irep, nirep);
- nirep->target_class = mrb_class_ptr(recv);
/* prepare closure */
- p = mrb_closure_new(mrb, nirep);
+ p = mrb_proc_new(mrb, nirep);
p->c = NULL;
+ mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)proc);
+ MRB_PROC_SET_TARGET_CLASS(p, mrb_class_ptr(recv));
+ p->flags |= MRB_PROC_SCOPE;
- /* prepare stack */
+ /* prepare call stack */
ci = cipush(mrb);
ci->pc = pc + 1;
ci->acc = a;
@@ -2825,8 +2785,7 @@ RETRY_TRY_BLOCK:
/* prepare stack */
mrb->c->stack += a;
- /* setup closure */
- p->target_class = ci->target_class;
+ /* setup block to call */
ci->proc = p;
irep = p->body.irep;
@@ -2957,7 +2916,6 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta
return mrb_vm_run(mrb, proc, self, stack_keep);
}
if (mrb->c->ci == mrb->c->cibase) {
- mrb->c->ci->env = NULL;
return mrb_vm_run(mrb, proc, self, stack_keep);
}
ci = cipush(mrb);