mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user