summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h1
-rw-r--r--mrbgems/mruby-fiber/src/fiber.c18
-rw-r--r--src/vm.c46
3 files changed, 33 insertions, 32 deletions
diff --git a/include/mruby.h b/include/mruby.h
index 3b953a327..8c4f9280b 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -1235,6 +1235,7 @@ MRB_API mrb_value mrb_fiber_alive_p(mrb_state *mrb, mrb_value fib);
* @mrbgem mruby-fiber
*/
#define E_FIBER_ERROR (mrb_exc_get(mrb, "FiberError"))
+MRB_API void mrb_stack_extend(mrb_state*, int);
/* memory pool implementation */
typedef struct mrb_pool mrb_pool;
diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c
index 83153a9df..b88fa4949 100644
--- a/mrbgems/mruby-fiber/src/fiber.c
+++ b/mrbgems/mruby-fiber/src/fiber.c
@@ -184,26 +184,27 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr
{
struct mrb_context *c = fiber_check(mrb, self);
struct mrb_context *old_c = mrb->c;
+ enum mrb_fiber_state status;
mrb_value value;
fiber_check_cfunc(mrb, c);
- if (resume && c->status == MRB_FIBER_TRANSFERRED) {
+ status = c->status;
+ if (resume && status == MRB_FIBER_TRANSFERRED) {
mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber");
}
- if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMED) {
+ if (status == MRB_FIBER_RUNNING || status == MRB_FIBER_RESUMED) {
mrb_raise(mrb, E_FIBER_ERROR, "double resume (fib)");
}
- if (c->status == MRB_FIBER_TERMINATED) {
+ if (status == MRB_FIBER_TERMINATED) {
mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber");
}
- mrb->c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED;
+ old_c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED;
c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c);
- if (c->status == MRB_FIBER_CREATED) {
+ fiber_switch_context(mrb, c);
+ if (status == MRB_FIBER_CREATED) {
mrb_value *b, *e;
- if (len >= c->stend - c->stack) {
- mrb_raise(mrb, E_FIBER_ERROR, "too many arguments to fiber");
- }
+ mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */
b = c->stack+1;
e = b + len;
while (b<e) {
@@ -215,7 +216,6 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr
else {
value = fiber_result(mrb, a, len);
}
- fiber_switch_context(mrb, c);
if (vmexec) {
c->vmexec = TRUE;
diff --git a/src/vm.c b/src/vm.c
index f1eae5ba5..59ae57c32 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -217,8 +217,8 @@ stack_extend_alloc(mrb_state *mrb, int room)
}
}
-static inline void
-stack_extend(mrb_state *mrb, int room)
+MRB_API void
+mrb_stack_extend(mrb_state *mrb, int room)
{
if (mrb->c->stack + room >= mrb->c->stend) {
stack_extend_alloc(mrb, room);
@@ -446,7 +446,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
mrb_method_missing(mrb, mid, self, args);
}
mrb_ary_unshift(mrb, args, mrb_symbol_value(mid));
- stack_extend(mrb, n+2);
+ mrb_stack_extend(mrb, n+2);
mrb->c->stack[n+1] = args;
argc = -1;
}
@@ -464,11 +464,11 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
}
if (MRB_METHOD_CFUNC_P(m)) {
ci->nregs = (int)(argc + 2);
- stack_extend(mrb, ci->nregs);
+ mrb_stack_extend(mrb, ci->nregs);
}
else if (argc >= CALL_MAXARGS) {
mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
- stack_extend(mrb, ci->nregs+2);
+ mrb_stack_extend(mrb, ci->nregs+2);
mrb->c->stack[1] = args;
ci->argc = -1;
argc = 1;
@@ -478,7 +478,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc
ci->proc = p;
if (argc < 0) argc = 1;
ci->nregs = (int)(p->body.irep->nregs + argc);
- stack_extend(mrb, ci->nregs);
+ mrb_stack_extend(mrb, ci->nregs);
}
if (voff >= 0) {
argv = mrb->c->stbase + voff;
@@ -531,10 +531,10 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
if (ci->argc < 0) keep = 3;
else keep = ci->argc + 2;
if (ci->nregs < keep) {
- stack_extend(mrb, keep);
+ mrb_stack_extend(mrb, keep);
}
else {
- stack_extend(mrb, ci->nregs);
+ mrb_stack_extend(mrb, ci->nregs);
stack_clear(mrb->c->stack+keep, ci->nregs-keep);
}
@@ -633,14 +633,14 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
ci->argc = 1;
ci->mid = ci[-1].mid;
if (MRB_PROC_CFUNC_P(p)) {
- stack_extend(mrb, 3);
+ mrb_stack_extend(mrb, 3);
mrb->c->stack[0] = self;
mrb->c->stack[1] = self;
mrb->c->stack[2] = mrb_nil_value();
return MRB_PROC_CFUNC(p)(mrb, self);
}
ci->nregs = p->body.irep->nregs;
- stack_extend(mrb, (ci->nregs < 3) ? 3 : ci->nregs);
+ mrb_stack_extend(mrb, (ci->nregs < 3) ? 3 : ci->nregs);
mrb->c->stack[0] = self;
mrb->c->stack[1] = self;
mrb->c->stack[2] = mrb_nil_value();
@@ -747,7 +747,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value
ci->acc = CI_ACC_SKIP;
mrb->c->stack = mrb->c->stack + n;
ci->nregs = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs;
- stack_extend(mrb, ci->nregs);
+ mrb_stack_extend(mrb, ci->nregs);
mrb->c->stack[0] = self;
if (argc > 0) {
@@ -798,7 +798,7 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const
p = mrb_proc_ptr(b);
ci = mrb->c->ci;
- stack_extend(mrb, 3);
+ mrb_stack_extend(mrb, 3);
mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
mrb->c->stack[2] = mrb_nil_value();
ci->argc = -1;
@@ -942,7 +942,7 @@ mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stac
}
if (stack_keep > nregs)
nregs = stack_keep;
- stack_extend(mrb, nregs);
+ mrb_stack_extend(mrb, nregs);
stack_clear(c->stack + stack_keep, nregs - stack_keep);
c->stack[0] = self;
result = mrb_vm_exec(mrb, proc, irep->iseq);
@@ -1371,7 +1371,7 @@ RETRY_TRY_BLOCK:
ci->pc = pc;
ci->acc = ci[-1].nregs;
mrb->c->stack += ci->acc;
- stack_extend(mrb, ci->nregs);
+ mrb_stack_extend(mrb, ci->nregs);
regs[0] = self;
pc = irep->iseq;
}
@@ -1435,7 +1435,7 @@ RETRY_TRY_BLOCK:
}
if (argc >= 0) {
if (a+2 >= irep->nregs) {
- stack_extend(mrb, a+3);
+ mrb_stack_extend(mrb, a+3);
}
regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
regs[a+2] = blk;
@@ -1508,7 +1508,7 @@ RETRY_TRY_BLOCK:
pool = irep->pool;
syms = irep->syms;
ci->nregs = irep->nregs;
- stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs);
+ mrb_stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs);
pc = irep->iseq;
JUMP;
}
@@ -1569,7 +1569,7 @@ RETRY_TRY_BLOCK:
pool = irep->pool;
syms = irep->syms;
ci->nregs = irep->nregs;
- stack_extend(mrb, ci->nregs);
+ mrb_stack_extend(mrb, ci->nregs);
if (ci->argc < 0) {
if (irep->nregs > 3) {
stack_clear(regs+3, irep->nregs-3);
@@ -1646,7 +1646,7 @@ RETRY_TRY_BLOCK:
mid = missing;
if (argc >= 0) {
if (a+2 >= ci->nregs) {
- stack_extend(mrb, a+3);
+ mrb_stack_extend(mrb, a+3);
}
regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
regs[a+2] = blk;
@@ -1707,7 +1707,7 @@ RETRY_TRY_BLOCK:
pool = irep->pool;
syms = irep->syms;
ci->nregs = irep->nregs;
- stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs);
+ mrb_stack_extend(mrb, (argc < 0 && ci->nregs < 3) ? 3 : ci->nregs);
pc = irep->iseq;
JUMP;
}
@@ -1965,7 +1965,7 @@ RETRY_TRY_BLOCK:
if (ci < ci0) {
mrb->c->stack = ci[1].stackent;
}
- stack_extend(mrb, irep->nregs);
+ mrb_stack_extend(mrb, irep->nregs);
pc = mrb->c->rescue[--ci->ridx];
}
else {
@@ -2198,10 +2198,10 @@ RETRY_TRY_BLOCK:
pool = irep->pool;
syms = irep->syms;
if (ci->argc < 0) {
- stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
+ mrb_stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
}
else {
- stack_extend(mrb, irep->nregs);
+ mrb_stack_extend(mrb, irep->nregs);
}
pc = irep->iseq;
}
@@ -2875,7 +2875,7 @@ RETRY_TRY_BLOCK:
pool = irep->pool;
syms = irep->syms;
ci->nregs = irep->nregs;
- stack_extend(mrb, ci->nregs);
+ mrb_stack_extend(mrb, ci->nregs);
stack_clear(regs+1, ci->nregs-1);
pc = irep->iseq;
JUMP;