Parent: #24
Goal
The current shared-realm Thread heap-limit contract is intentionally fail-closed and allocation-free: when a spawned Thread hits native error.OutOfMemory, its completion record publishes the static string sentinel "OutOfMemoryError", so join() has deterministic JS-visible behavior even with zero remaining context heap budget.
That is robust, but the ideal final embedder-facing API should expose a real error object without reintroducing an allocation dependency on an already-exhausted heap.
Design sketch
- Add a small per-Context emergency reserve or prebuilt OOM completion object for capped contexts.
- Ensure
ThreadOOM completion can publish a realOutOfMemoryErrorobject with stable.name,.message, andinstanceof Errorbehavior. - Define how the reserve is replenished or consumed across repeated OOM completions.
- Keep top-level host
Context.evaluate()behavior distinct: it may still return Zigerror.OutOfMemoryto the embedder boundary. - Preserve the existing fail-closed guarantee: OOM reporting must not allocate from the already-exhausted ordinary heap path.
Acceptance criteria
join()on a heap-limit-exhausted spawnedThreadthrows an object, not a primitive string.- The thrown value is distinguishable as
OutOfMemoryErrorand is still available when the ordinary context budget has no headroom. - Sibling
Threadsurvivor tests continue to pass. - The docs in
docs/threads/limits.mdno longer need to call out the primitive sentinel as the final observable value.