diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-07-17 10:35:41 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-07-17 10:35:41 +0900 |
| commit | d605b72c1d6fa4564a0a5e88535504b6850463b5 (patch) | |
| tree | 774fc0de56002abb3bb2b1c3387ff08f91876d17 /mrbgems/mruby-fiber | |
| parent | 2af92d0ebcbeca6d3d85a27c8193273080a63090 (diff) | |
| parent | 9af3b7c6258de327218dd04e69d76ae68caf17b1 (diff) | |
| download | mruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.tar.gz mruby-d605b72c1d6fa4564a0a5e88535504b6850463b5.zip | |
Merge branch 'master' into i110/inspect-recursion
Diffstat (limited to 'mrbgems/mruby-fiber')
| -rw-r--r-- | mrbgems/mruby-fiber/src/fiber.c | 25 | ||||
| -rw-r--r-- | mrbgems/mruby-fiber/test/fiber.rb | 2 |
2 files changed, 16 insertions, 11 deletions
diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 83153a9df..17ce77c5d 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -127,7 +127,6 @@ fiber_init(mrb_state *mrb, mrb_value self) ci->proc = p; mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); ci->pc = p->body.irep->iseq; - ci->nregs = p->body.irep->nregs; ci[1] = ci[0]; c->ci++; /* push dummy callinfo */ @@ -175,6 +174,9 @@ fiber_check_cfunc(mrb_state *mrb, struct mrb_context *c) static void fiber_switch_context(mrb_state *mrb, struct mrb_context *c) { + if (mrb->c->fib) { + mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib); + } c->status = MRB_FIBER_RUNNING; mrb->c = c; } @@ -184,26 +186,30 @@ 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) { - mrb_raise(mrb, E_FIBER_ERROR, "double resume (fib)"); + if (status == MRB_FIBER_RUNNING || status == MRB_FIBER_RESUMED) { + mrb_raise(mrb, E_FIBER_ERROR, "double resume"); } - 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"); + if (!c->ci->proc) { + mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)"); } + mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */ b = c->stack+1; e = b + len; while (b<e) { @@ -215,7 +221,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/mrbgems/mruby-fiber/test/fiber.rb b/mrbgems/mruby-fiber/test/fiber.rb index d063a0a62..b6ecb798c 100644 --- a/mrbgems/mruby-fiber/test/fiber.rb +++ b/mrbgems/mruby-fiber/test/fiber.rb @@ -76,7 +76,7 @@ assert('Fiber iteration') do end assert('Fiber with splat in the block argument list') { - Fiber.new{|*x|x}.resume(1) == [1] + assert_equal([1], Fiber.new{|*x|x}.resume(1)) } assert('Fiber raises on resume when dead') do |
