mruby-task: raise exception when task.pass is called from C function

when task.pass is called from within a C function (such as Module.new's
block evaluation), attempting to yield would cause a segfault because C
functions lack valid bytecode program counters (see #6642).

this commit adds C function boundary detection to task.pass, raising a
runtime error when cci > 0 (indicating execution is inside a C function).
this matches fiber's behavior and provides a clear error message instead of
a cryptic segfault.

unlike the previous commit which allowed sleep to fall back to blocking
sleep, task.pass raises an exception because its sole purpose is cooperative
yielding - there is no sensible blocking fallback behavior.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-10-16 10:49:25 +09:00
parent f8883178c5
commit d72b5d5fbc
+8
View File
@@ -770,6 +770,14 @@ mrb_task_s_pass(mrb_state *mrb, mrb_value self)
task_run_one_iteration(mrb);
}
else {
/* Check for C function boundary - cannot yield from C function */
mrb_callinfo *ci;
for (ci = mrb->c->ci; ci >= mrb->c->cibase; ci--) {
if (ci->cci > 0) {
mrb_raise(mrb, E_RUNTIME_ERROR, "can't pass across C function boundary");
}
}
/* In task context - trigger context switch */
switching_ = TRUE;
}