Parent: #140 Tracked by: #134, #163, #164
Symbols
| Symbol | Home (packages/runtime/src/jsc/VM.zig @ 7ed99c02) | Bun (upstream/src/jsc/bindings/bindings.cpp) |
|---|---|---|
JSC__VM__notifyNeedWatchdogCheck | VM.zig:142 | bindings.cpp:4992 — (*arg0).notifyNeedWatchdogCheck() |
JSC__VM__notifyNeedDebuggerBreak | VM.zig:148 | bindings.cpp:4997 — (*arg0).notifyNeedDebuggerBreak() |
Both are one-liners that set JSC::VMTraps bits on the VM. The traps are consumed on the executing thread at the next safepoint: NeedWatchdogCheck re-checks the armed watchdog time limit and raises termination when it has elapsed; NeedDebuggerBreak makes the debugger break at the next statement boundary (inert when no debugger is attached).
Explicitly rejected in this slice
JSC__VM__notifyNeedShellTimeoutCheck(VM.zig:154,bindings.cpp:5002) — jsc-shell-specific (--timeoutCLI) trap with no possible zig-js consumer; same category as the already-documentedSourceProvider__derefrejection on #163. Rationale recorded on the tracker.
Acceptance criteria
JSC__VM__notifyNeedWatchdogChecksets a VM(CContextGroup)-wide trap flag; the interpreter's 1024-step checkpoint consumes it and re-checks the armed execution deadline (#302) on the executing thread, terminating evaluation (worker terminated) when the deadline has elapsed. No armed limit → consumed as a no-op (no spurious termination).- Trap + deadline plumbing uses atomics end-to-end so the notify is safe from a non-evaluating thread, matching JSC's atomic trap bits.
JSC__VM__notifyNeedDebuggerBreakrequests a debugger pause (reason"pause") at the next statement boundary for every realm of the VM that has an enabled debugger session attached — the same path as CDPDebugger.pause. With no debugger attached the notify is inert, matching JSC.- Both exports tolerate a null
JSC__VMRef. - Compiled runtime fixture
tests/abi/home_private_value_shims.zigcovers: trap with no limit armed (bounded loop completes), trap with future limit (no spurious termination), trap with elapsed limit (unbounded loop terminates + termination request attributed), debugger-break with no debugger attached (inert), null-VM tolerance. Fixture symbol count 288 → 290. - Home inventory
288/431implemented, Bun inventory280/421;bun-private-abi-audit+c-api-auditgreen; fullzig build testshows zero new failures (worktree baseline-vs-candidate against the same pinned base).
Design constraints (as implemented)
zig-jskeeps trap state on the context group (CContextGroup.need_watchdog_check) and consumes it in the tree-walker's existing step checkpoint (next to thestop_flagpoll); there is no separate VMTraps word — the flag is the trap bit.Contextcarrieswatchdog_check_flag/watchdog_deadline_nshost pointers (same pattern asstop_flag), wired for the group primary and every realm.- The watchdog consumption and the #302 host watchdog thread are intentionally redundant (belt and suspenders), exactly as JSC's trap and
Watchdogtimer are. CInspectorState.pause_requestedis nowstd.atomic.Value(bool)so the cross-thread notify cannot race the runtime thread's consume; owner selection still goes throughchooseInspectorPauseOwner.- No JSC API behavior is invented beyond the mapped semantics; deltas (termination stays terminal for the context per the #302 contract) are documented on the exports.