Commit Graph
4 Commits
Author SHA1 Message Date
Chris Tate fe244085d4 Run native async generators as stackless coroutines
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.
2026-10-26 07:28:50 -05:00
Chris Tate 9f2e9b00c9 Write the limitations partials one sentence per line
Each limitations partial held its whole text on one line (map-and-set.mdx
was a single 1,080-character line), so any two edits to the same partial
conflicted. The partials now put one sentence per line, with a bullet's
continuation lines indented two spaces. Markdown joins the lines, so the
rendered pages are unchanged.

scripts/limitations-partials.mjs reads a labeled bullet's indented
continuation lines as part of the bullet when it splits and joins the page,
and AGENTS.md states the convention.
2026-10-19 00:11:31 -05:00
Chris Tate 2b6f15c7fa Answer undefined for missing Record and index-signature keys
A keyed or dot read of an index signature that misses now answers
undefined, as in Node, instead of aborting with "record has no key".
The read carries an explicit optional value through the same analysis
that already widens bindings, parameters, returns and fields for missing
array elements; TypeScript's static types are unchanged. Numeric reads
whose consumers treat undefined like NaN lower to plain doubles, and
nested reads and writes through a missing entry throw Node's TypeError.

Fixes #964
Co-authored-by: Quim T. <26749475+espetro@users.noreply.github.com>
2026-10-17 19:35:34 -05:00
Chris Tate 7e99752246 Split the Limitations page into partials
docs/content/docs/limitations.mdx now holds the frontmatter, the
headings, the anchor spans and one <include> line per partial. The text
moves unchanged to docs/content/limitations/: one file per labeled
bullet (<section>/<label>.mdx) and one per section's other text
(<section>.mdx). Edits to different bullets no longer touch adjacent
lines of one file.

remarkDocsConventions splices the included partials into the page and
joins the lists that consecutive bullet partials contribute, so the page,
its Markdown twin and the search index render as before. The route tests
read the page with its partials inlined. A page that includes partials
takes its last-modified date, used by the sitemap, from the newest commit
to the page or any of its partials.

docs/scripts/limitations-partials.mjs joins the partials back into one
file, splits a single-file page, and merges a branch's edits to the
single-file page into the partials.
2026-10-15 04:31:49 -05:00