diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-06-07 15:59:00 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-06-07 15:59:00 +0900 |
| commit | 778500563a9f7ceba996937dc886bd8cde29b42b (patch) | |
| tree | 82268fb4bb6eff6d808e66c39e41187f526b79d8 | |
| parent | ff0a4f78674308b7643db1da9b9dc591f25c21d0 (diff) | |
| download | mruby-778500563a9f7ceba996937dc886bd8cde29b42b.tar.gz mruby-778500563a9f7ceba996937dc886bd8cde29b42b.zip | |
Extend stack when pushing arguments that does not fit in; fix #4038
| -rw-r--r-- | mrbgems/mruby-fiber/src/fiber.c | 18 |
1 files changed, 9 insertions, 9 deletions
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; |
