From 42308c42b548c30e54663e70902fc3eca7b22ea8 Mon Sep 17 00:00:00 2001 From: dearblue Date: Mon, 4 Dec 2023 21:51:10 +0900 Subject: [PATCH] Fix CI misalignment between `Fiber#resume` and `Fiber.yield` When a fiber switched by `Fiber.yield` is resumed by `Fiber#resume` by C, it is necessary to pop CI with `fiber_switch()`. Previously, CI misalignment caused inconsistencies, including crashes, on the next `Fiber#resume`. --- mrbgems/mruby-fiber/src/fiber.c | 2 +- src/vm.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 893a0c960..f5254a286 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -272,6 +272,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr else { value = fiber_result(mrb, a, len); if (vmexec) { + if (c->ci > c->cibase) c->ci--; /* pop dummy callinfo */ c->ci[1].stack[0] = value; } } @@ -412,7 +413,6 @@ mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a) if (c->vmexec) { c->vmexec = FALSE; mrb->c->ci->cci = CINFO_RESUMED; - c->ci--; /* pop callinfo for yield */ } MARK_CONTEXT_MODIFY(mrb->c); return fiber_result(mrb, a, len); diff --git a/src/vm.c b/src/vm.c index 50c7b0b08..2b8660ee0 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1839,6 +1839,7 @@ RETRY_TRY_BLOCK: } recv = MRB_METHOD_FUNC(m)(mrb, recv); } + mrb_assert(mrb->c->ci > mrb->c->cibase); mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; ci = mrb->c->ci;