mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
An async generator whose body suspends only at its own awaits and yields now compiles to an LLVM switched coroutine, as async functions of that kind already do, instead of running on a fiber with its own stack. Its steps run on the stack that resumes it (the loop's after an await), its awaits suspend through scr_coro_await_prepare and scr_coro_hop_prepare, and its yields store OUT through scr_coro_yield_* before suspending. - scr_async_gen_new_stackless creates the generator. The stackless hop settles an async generator's state as the fiber hop does, and a step that would start below the stack guard throws a RangeError, which rejects its request. - Calling an async generator's next, return or throw no longer counts as parking the caller: they queue a request and run the body to its next suspension, which returns to the caller. Bodies that consume async generators can now be stackless too. - An untyped await (async.awaitDyn) has a native coroutine form, extracted by scr_coro_await_dyn_value, so async bodies that await untyped values can be stackless. - An async generator's return through a finally region takes its await turn through the coroutine when the body is one. Debug builds, libraries, worker programs and Windows executables keep fibers, as for stackless async functions.
17 lines
1.8 KiB
Plaintext
17 lines
1.8 KiB
Plaintext
Typed-array reads at an index that is not an integer in the array's range return `undefined`, as in Node.js, and invalid numeric indexed writes are ignored, while the assignment expression retains its original value.
|
|
A non-null assertion on such a read (`bytes[i]!`) yields `NaN` instead of `undefined`.
|
|
|
|
Ordinary arrays track holes separately from present `undefined` values.
|
|
Missing reads and empty `pop()`/`shift()` return `undefined`, indexed writes can grow the array, and length growth creates holes.
|
|
|
|
Keyed reads of a `Record` or an index signature return `undefined` for a missing key, as in Node.js, with or without `noUncheckedIndexedAccess`.
|
|
A missing array element or key that reaches storage that cannot hold `undefined`, such as a class field typed `number`, throws a `TypeError`.
|
|
|
|
Runtime traps cannot be caught.
|
|
User-thrown values and supported exceptions, including JSON parse, checked-cast, filesystem, regex, and `String.prototype.repeat` count errors, can be caught; hard traps such as out-of-range reads of statically typed ordinary arrays terminate the process.
|
|
|
|
Deep recursion in Linux and macOS executables throws Node's catchable `RangeError: Maximum call stack size exceeded`, on the main thread, in worker threads, and inside async functions and generators.
|
|
The depth at which it is thrown differs from Node: the main thread uses the process stack limit (usually 8 MiB), worker threads get an 8 MiB stack, async functions and generators that keep a fiber run on 512 KiB stacks, and stackless ones run on the stack that resumes them, so native code usually recurses deeper than Node on threads and somewhat less deeply inside fiber bodies.
|
|
Recursion inside runtime library operations, such as serializing deeply nested data, is not checked.
|
|
Windows executables, WASI builds and library builds do not check the stack, and exhausting it there terminates the process.
|