Files
scriptc/tests/corpus/stackless-async-unhandled.ts
T
Malte UblandClaude Opus 5.5 74a9cfb8cc Compile async functions that suspend only at their awaits to stackless coroutines
Native async bodies whose only suspension points are their own awaits now
compile to LLVM switched coroutines, the lowering WASI async bodies and
native synchronous generators already use. A suspended call keeps a heap
frame of the values live across its awaits instead of a fiber with its own
stack. Bodies that reach other suspension points (async generator
consumption, dyn awaits, node:test subtests), module evaluation bodies,
dyn results, worker and library programs, and Windows keep their fibers.

The emitter selects bodies by emitting them as usual first: that text may
suspend only through await runtime calls and await-call entries, and may
call no function that parks. The coroutine form is then emitted and
checked again. Each await prepares its continuation in the runtime (a
pending promise's waiter list, or one READY-queue turn, continuing in place
exactly where a fiber's hop would) and extracts the settled result after
resuming. The eager prefix runs on the spawner's stack and moves to a fresh
stack near the stack guard, so deep async recursion keeps working.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 11:29:05 -07:00

23 lines
693 B
TypeScript

// @exit: 1
// A stackless async body that rejects after suspending with nobody
// observing its promise: the rejection reaches Node's unhandled-rejection
// path once the microtask checkpoint completes, after the work already
// queued ahead of it, and the process exits with status 1.
async function failLater(label: string): Promise<number> {
console.log("start", label);
await Promise.resolve();
console.log("resumed", label);
await null;
throw new Error("unhandled " + label);
}
async function fine(): Promise<void> {
await null;
console.log("fine done");
}
void fine();
void failLater("x");
setTimeout(() => console.log("timer never runs"), 5);
console.log("main done");