Unverified Commit 11cc7bed authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto Committed by GitHub

Merge pull request #5052 from dearblue/cistacks

Extend the `cipush()` and `cipop()` functions
parents ef9c6879 d96be5c1
...@@ -269,14 +269,13 @@ top_proc(mrb_state *mrb, struct RProc *proc) ...@@ -269,14 +269,13 @@ top_proc(mrb_state *mrb, struct RProc *proc)
#define CI_ACC_RESUMED -3 #define CI_ACC_RESUMED -3
static inline mrb_callinfo* static inline mrb_callinfo*
cipush(mrb_state *mrb) cipush(mrb_state *mrb, const mrb_code *pc, int push_stacks, int acc,
struct RClass *target_class, struct RProc *proc, mrb_sym mid, int argc)
{ {
struct mrb_context *c = mrb->c; struct mrb_context *c = mrb->c;
static const mrb_callinfo ci_zero = { 0 }; static const mrb_callinfo ci_zero = { 0 };
mrb_callinfo *ci = c->ci; mrb_callinfo *ci = c->ci;
int ridx = ci->ridx;
if (ci + 1 == c->ciend) { if (ci + 1 == c->ciend) {
ptrdiff_t size = ci - c->cibase; ptrdiff_t size = ci - c->cibase;
...@@ -286,8 +285,16 @@ cipush(mrb_state *mrb) ...@@ -286,8 +285,16 @@ cipush(mrb_state *mrb)
} }
ci = ++c->ci; ci = ++c->ci;
*ci = ci_zero; *ci = ci_zero;
ci->epos = mrb->c->eidx; ci->mid = mid;
ci->ridx = ridx; ci->proc = proc;
ci->stackent = c->stack;
ci->epos = c->eidx;
ci->ridx = ci[-1].ridx;
ci->pc = pc;
ci->argc = argc;
ci->acc = acc;
ci->target_class = target_class;
c->stack += push_stacks;
return ci; return ci;
} }
...@@ -313,14 +320,16 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e) ...@@ -313,14 +320,16 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e)
} }
} }
static inline void static inline mrb_callinfo*
cipop(mrb_state *mrb) cipop(mrb_state *mrb)
{ {
struct mrb_context *c = mrb->c; struct mrb_context *c = mrb->c;
struct REnv *env = c->ci->env; struct REnv *env = c->ci->env;
mrb->c->stack = c->ci->stackent;
c->ci--; c->ci--;
if (env) mrb_env_unshare(mrb, env); if (env) mrb_env_unshare(mrb, env);
return c->ci;
} }
void mrb_exc_set(mrb_state *mrb, mrb_value exc); void mrb_exc_set(mrb_state *mrb, mrb_value exc);
...@@ -356,16 +365,9 @@ ecall(mrb_state *mrb) ...@@ -356,16 +365,9 @@ ecall(mrb_state *mrb)
nregs = ci->proc->body.irep->nregs; nregs = ci->proc->body.irep->nregs;
} }
cioff = ci - c->cibase; cioff = ci - c->cibase;
ci = cipush(mrb); ci = cipush(mrb, NULL, nregs, CI_ACC_SKIP, MRB_PROC_TARGET_CLASS(p), p, ci->mid, 0);
ci->stackent = mrb->c->stack;
ci->mid = ci[-1].mid;
ci->acc = CI_ACC_SKIP;
ci->argc = 0;
ci->proc = p;
ci->target_class = MRB_PROC_TARGET_CLASS(p);
env = MRB_PROC_ENV(p); env = MRB_PROC_ENV(p);
mrb_assert(env); mrb_assert(env);
c->stack += nregs;
exc = mrb->exc; mrb->exc = 0; exc = mrb->exc; mrb->exc = 0;
if (exc) { if (exc) {
mrb_gc_protect(mrb, mrb_obj_value(exc)); mrb_gc_protect(mrb, mrb_obj_value(exc));
...@@ -447,7 +449,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ...@@ -447,7 +449,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
} }
MRB_CATCH(&c_jmp) { /* error */ MRB_CATCH(&c_jmp) { /* error */
while (nth_ci < (mrb->c->ci - mrb->c->cibase)) { while (nth_ci < (mrb->c->ci - mrb->c->cibase)) {
mrb->c->stack = mrb->c->ci->stackent;
cipop(mrb); cipop(mrb);
} }
mrb->jmp = 0; mrb->jmp = 0;
...@@ -486,12 +487,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ...@@ -486,12 +487,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
} }
ci = cipush(mrb); ci = cipush(mrb, NULL, n, 0, c, NULL, mid, argc);
ci->mid = mid;
ci->stackent = mrb->c->stack;
ci->argc = (int)argc;
ci->target_class = c;
mrb->c->stack = mrb->c->stack + n;
if (argc < 0) argc = 1; if (argc < 0) argc = 1;
if (mrb->c->stbase <= argv && argv < mrb->c->stend) { if (mrb->c->stbase <= argv && argv < mrb->c->stend) {
voff = argv - mrb->c->stbase; voff = argv - mrb->c->stbase;
...@@ -524,7 +520,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ...@@ -524,7 +520,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_CFUNC_P(m)) {
ci->acc = CI_ACC_DIRECT; ci->acc = CI_ACC_DIRECT;
val = MRB_METHOD_CFUNC(m)(mrb, self); val = MRB_METHOD_CFUNC(m)(mrb, self);
mrb->c->stack = mrb->c->ci->stackent;
cipop(mrb); cipop(mrb);
} }
else { else {
...@@ -565,11 +560,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) ...@@ -565,11 +560,7 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
stack_clear(mrb->c->stack+keep, nregs-keep); stack_clear(mrb->c->stack+keep, nregs-keep);
} }
ci = cipush(mrb); cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0);
ci->target_class = 0;
ci->pc = p->body.irep->iseq;
ci->stackent = mrb->c->stack;
ci->acc = 0;
return self; return self;
} }
...@@ -671,11 +662,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) ...@@ -671,11 +662,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
mrb->c->stack[0] = self; mrb->c->stack[0] = self;
mrb->c->stack[1] = self; mrb->c->stack[1] = self;
stack_clear(mrb->c->stack+2, nregs-2); stack_clear(mrb->c->stack+2, nregs-2);
ci = cipush(mrb); ci = cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0);
ci->target_class = 0;
ci->pc = p->body.irep->iseq;
ci->stackent = mrb->c->stack;
ci->acc = 0;
return self; return self;
} }
...@@ -751,13 +738,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value ...@@ -751,13 +738,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
} }
p = mrb_proc_ptr(b); p = mrb_proc_ptr(b);
ci = cipush(mrb); ci = cipush(mrb, NULL, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */);
ci->mid = mid;
ci->proc = p;
ci->target_class = c;
ci->acc = CI_ACC_SKIP;
ci->stackent = mrb->c->stack;
mrb->c->stack += n;
if (argc >= CALL_MAXARGS) { if (argc >= CALL_MAXARGS) {
ci->argc = -1; ci->argc = -1;
n = 3; n = 3;
...@@ -779,7 +760,6 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value ...@@ -779,7 +760,6 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
if (MRB_PROC_CFUNC_P(p)) { if (MRB_PROC_CFUNC_P(p)) {
val = MRB_PROC_CFUNC(p)(mrb, self); val = MRB_PROC_CFUNC(p)(mrb, self);
mrb->c->stack = mrb->c->ci->stackent;
cipop(mrb); cipop(mrb);
} }
else { else {
...@@ -1328,15 +1308,7 @@ RETRY_TRY_BLOCK: ...@@ -1328,15 +1308,7 @@ RETRY_TRY_BLOCK:
mrb->c->ensure[epos+n] = NULL; mrb->c->ensure[epos+n] = NULL;
if (proc == NULL) continue; if (proc == NULL) continue;
irep = proc->body.irep; irep = proc->body.irep;
ci = cipush(mrb); ci = cipush(mrb, pc, nregs, nregs, target_class, proc, ci->mid, 0);
ci->mid = ci[-1].mid;
ci->argc = 0;
ci->proc = proc;
ci->stackent = mrb->c->stack;
ci->target_class = target_class;
ci->pc = pc;
ci->acc = nregs;
mrb->c->stack += ci->acc;
mrb_stack_extend(mrb, irep->nregs); mrb_stack_extend(mrb, irep->nregs);
regs[0] = self; regs[0] = self;
pc = irep->iseq; pc = irep->iseq;
...@@ -1418,17 +1390,7 @@ RETRY_TRY_BLOCK: ...@@ -1418,17 +1390,7 @@ RETRY_TRY_BLOCK:
} }
/* push callinfo */ /* push callinfo */
ci = cipush(mrb); ci = cipush(mrb, pc, a, a, cls, NULL, mid, argc);
ci->mid = mid;
ci->stackent = mrb->c->stack;
ci->target_class = cls;
ci->argc = argc;
ci->pc = pc;
ci->acc = a;
/* prepare stack */
mrb->c->stack += a;
if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_CFUNC_P(m)) {
if (MRB_METHOD_PROC_P(m)) { if (MRB_METHOD_PROC_P(m)) {
...@@ -1470,7 +1432,6 @@ RETRY_TRY_BLOCK: ...@@ -1470,7 +1432,6 @@ RETRY_TRY_BLOCK:
} }
mrb->c->stack[0] = recv; mrb->c->stack[0] = recv;
/* pop stackpos */ /* pop stackpos */
mrb->c->stack = ci->stackent;
pc = ci->pc; pc = ci->pc;
cipop(mrb); cipop(mrb);
JUMP; JUMP;
...@@ -1508,10 +1469,9 @@ RETRY_TRY_BLOCK: ...@@ -1508,10 +1469,9 @@ RETRY_TRY_BLOCK:
if (mrb->exc) goto L_RAISE; if (mrb->exc) goto L_RAISE;
/* pop stackpos */ /* pop stackpos */
ci = mrb->c->ci; ci = mrb->c->ci;
mrb->c->stack = ci->stackent;
regs[ci->acc] = recv;
pc = ci->pc; pc = ci->pc;
cipop(mrb); cipop(mrb);
regs[ci->acc] = recv;
irep = mrb->c->ci->proc->body.irep; irep = mrb->c->ci->proc->body.irep;
pool = irep->pool; pool = irep->pool;
syms = irep->syms; syms = irep->syms;
...@@ -1617,15 +1577,9 @@ RETRY_TRY_BLOCK: ...@@ -1617,15 +1577,9 @@ RETRY_TRY_BLOCK:
} }
/* push callinfo */ /* push callinfo */
ci = cipush(mrb); ci = cipush(mrb, pc, a, 0, cls, NULL, mid, argc);
ci->mid = mid;
ci->stackent = mrb->c->stack;
ci->target_class = cls;
ci->pc = pc;
ci->argc = argc;
/* prepare stack */ /* prepare stack */
mrb->c->stack += a;
mrb->c->stack[0] = recv; mrb->c->stack[0] = recv;
if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_CFUNC_P(m)) {
...@@ -1652,8 +1606,6 @@ RETRY_TRY_BLOCK: ...@@ -1652,8 +1606,6 @@ RETRY_TRY_BLOCK:
} }
} }
mrb->c->stack[0] = v; mrb->c->stack[0] = v;
/* pop stackpos */
mrb->c->stack = ci->stackent;
pc = ci->pc; pc = ci->pc;
cipop(mrb); cipop(mrb);
JUMP; JUMP;
...@@ -1954,13 +1906,11 @@ RETRY_TRY_BLOCK: ...@@ -1954,13 +1906,11 @@ RETRY_TRY_BLOCK:
goto L_RESCUE; goto L_RESCUE;
} }
while (ci[0].ridx == ci[-1].ridx) { while (ci[0].ridx == ci[-1].ridx) {
cipop(mrb); ci = cipop(mrb);
mrb->c->stack = ci->stackent; if (ci[1].acc == CI_ACC_SKIP && prev_jmp) {
if (ci->acc == CI_ACC_SKIP && prev_jmp) {
mrb->jmp = prev_jmp; mrb->jmp = prev_jmp;
MRB_THROW(prev_jmp); MRB_THROW(prev_jmp);
} }
ci = mrb->c->ci;
if (ci == mrb->c->cibase) { if (ci == mrb->c->cibase) {
if (ci->ridx == 0) { if (ci->ridx == 0) {
L_FTOP: /* fiber top */ L_FTOP: /* fiber top */
...@@ -2142,15 +2092,13 @@ RETRY_TRY_BLOCK: ...@@ -2142,15 +2092,13 @@ RETRY_TRY_BLOCK:
return v; return v;
} }
acc = ci->acc; acc = ci->acc;
mrb->c->stack = ci->stackent; ci = cipop(mrb);
cipop(mrb);
if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) { if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) {
mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_restore(mrb, ai);
mrb->jmp = prev_jmp; mrb->jmp = prev_jmp;
return v; return v;
} }
pc = ci->pc; pc = ci[1].pc;
ci = mrb->c->ci;
DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid))); DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid)));
proc = mrb->c->ci->proc; proc = mrb->c->ci->proc;
irep = proc->body.irep; irep = proc->body.irep;
...@@ -2664,7 +2612,6 @@ RETRY_TRY_BLOCK: ...@@ -2664,7 +2612,6 @@ RETRY_TRY_BLOCK:
} }
CASE(OP_EXEC, BB) { CASE(OP_EXEC, BB) {
mrb_callinfo *ci;
mrb_value recv = regs[a]; mrb_value recv = regs[a];
struct RProc *p; struct RProc *p;
mrb_irep *nirep = irep->reps[b]; mrb_irep *nirep = irep->reps[b];
...@@ -2677,19 +2624,7 @@ RETRY_TRY_BLOCK: ...@@ -2677,19 +2624,7 @@ RETRY_TRY_BLOCK:
p->flags |= MRB_PROC_SCOPE; p->flags |= MRB_PROC_SCOPE;
/* prepare call stack */ /* prepare call stack */
ci = cipush(mrb); cipush(mrb, pc, a, a, mrb_class_ptr(recv), p, 0, 0);
ci->pc = pc;
ci->acc = a;
ci->mid = 0;
ci->stackent = mrb->c->stack;
ci->argc = 0;
ci->target_class = mrb_class_ptr(recv);
/* prepare stack */
mrb->c->stack += a;
/* setup block to call */
ci->proc = p;
irep = p->body.irep; irep = p->body.irep;
pool = irep->pool; pool = irep->pool;
...@@ -2834,7 +2769,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -2834,7 +2769,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
MRB_API mrb_value MRB_API mrb_value
mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep) mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
{ {
mrb_callinfo *ci;
mrb_value v; mrb_value v;
if (!mrb->c->cibase) { if (!mrb->c->cibase) {
...@@ -2844,11 +2778,7 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta ...@@ -2844,11 +2778,7 @@ mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int sta
mrb->c->ci->env = NULL; mrb->c->ci->env = NULL;
return mrb_vm_run(mrb, proc, self, stack_keep); return mrb_vm_run(mrb, proc, self, stack_keep);
} }
ci = cipush(mrb); cipush(mrb, NULL, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0);
ci->stackent = mrb->c->stack;
ci->mid = 0;
ci->acc = CI_ACC_SKIP;
ci->target_class = mrb->object_class;
v = mrb_vm_run(mrb, proc, self, stack_keep); v = mrb_vm_run(mrb, proc, self, stack_keep);
return v; return v;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment