Commit Graph
168 Commits
Author SHA1 Message Date
Chris TateandAlbert 31f268be2b feat: support wasm32-wasi as a production target (#133)
* feat: support wasm32-wasi as a production target

- Add production LLVM WASI codegen with a 32-bit ABI, coroutines, and dynamic modules
- Integrate WASI builds and execution into the CLI with capability diagnostics
- Add differential coverage and document the fourth production target

Co-authored-by: Albert <57402359+bulatovv@users.noreply.github.com>

* fix: address wasm target review findings

* fix WASI guest paths and fetch alias detection

* fix WASI async bridge and fetch detection

---------

Co-authored-by: Albert <57402359+bulatovv@users.noreply.github.com>
2026-08-11 14:12:59 -05:00
Chris Tateandsqlpxc 2c164dd374 feat: support x86_64 Linux musl targets (#131)
* feat: support x86_64 Linux musl targets

- add musl runtime shims for randomness, fibers, and child-process cwd support
- validate executable and library outputs against Alpine Linux
- document x86_64-linux-musl cross-compilation

Co-authored-by: sqlpxc <38583139+sqlpxc@users.noreply.github.com>

* fix: harden musl runtime portability

* fix: keep child fixture portable across hosts

---------

Co-authored-by: sqlpxc <38583139+sqlpxc@users.noreply.github.com>
2026-08-11 12:10:03 -05:00
Chris TateandEli Sterling acf0a2b905 Support static HTTP server timeout properties (#127)
* Support static HTTP server timeout properties

- Lower typed timeout property reads and writes through both native backends.
- Store Node-compatible defaults independently on each HTTP/HTTPS server.
- Cover defaults and assignments with differential corpus tests.

Co-authored-by: Eli Sterling <240321107+eli-sterling@users.noreply.github.com>

* Support keep-alive timeout buffer property

* Fix HTTP server timeout property lowering

* fix: scope HTTP server timeout handling

* fix: preserve HTTP server timeout semantics

---------

Co-authored-by: Eli Sterling <240321107+eli-sterling@users.noreply.github.com>
2026-08-11 08:33:38 -05:00
Chris TateandI Plan Websites e281259db3 feat(fs): expose Stats disk metadata (#120)
* feat(fs): expose Stats disk metadata

- Lower blocks, nlink, and atimeMs through the C and LLVM backends.
- Populate path, promise, file-handle, and dynamic bridge stats across supported platforms.
- Add differential, declaration, and npm bridge coverage.

Co-authored-by: I Plan Websites <787729+iplanwebsites@users.noreply.github.com>

* fix(fs): keep Windows stats snapshots coherent

* fix(fs): preserve Windows lstat metadata

* fix(fs): validate Windows mount point payloads

---------

Co-authored-by: I Plan Websites <787729+iplanwebsites@users.noreply.github.com>
2026-08-10 12:21:11 -05:00
Chris Tateandmorler 00eb380a0f perf: use integer induction for byte loops (#121)
- Recognize canonical typed-array loops with semantics-safe fallbacks.
- Emit integer induction and direct integer byte indices in C and LLVM.
- Add backend and differential regression coverage.

Co-authored-by: morler <478444+morler@users.noreply.github.com>
2026-08-10 11:33:17 -05:00
Chris Tate 4d96d2de28 feat(fs): support three-argument writeFile (#112)
* feat(fs): support three-argument writeFile

- Lower static UTF-8 encoding and mode options for fs/promises.writeFile.

- Add mode-aware runtime and backend support with promise rejection behavior.

- Cover supported options and failures in the differential corpus.

* fix fs write option evaluation and mode validation

* fix fs prototype-backed write options

* fix: preserve ignored write option semantics
2026-08-10 10:19:51 -05:00
Chris Tate 17ee5eff94 feat: support process write callback and encoding args (#114)
* feat: support process write callback and encoding args

- Lower static stdout and stderr writes with encoding and callback overloads.
- Schedule completion callbacks through the next-tick queue in C and LLVM builds.
- Cover encoding aliases, ordering, and async-free refusal behavior.

* fix: handle omitted process write arguments
2026-08-10 10:07:08 -05:00
Chris Tate b94c88e31c feat: support static non-UTF-8 TextDecoder labels (#111)
* feat: support static non-UTF-8 TextDecoder labels

- Recognize static WHATWG labels and aliases during builtin lowering.
- Add feature-gated portable decoders generated against the pinned Node runtime.
- Cover legacy encodings, malformed input, and unsupported dynamic labels.

* fix: match Node legacy decoder recovery

* fix TextDecoder edge-case parity

* fix(runtime): match Node malformed text decoding

* fix TextDecoder recovery edge cases
2026-08-09 23:15:51 -05:00
Chris Tate 8188470e3a feat: support fs/promises FileHandle (#110)
* feat: support fs/promises FileHandle

- Add static lowering and typing for fs/promises.open and the supported FileHandle surface.

- Implement FileHandle ownership and I/O across the C runtime and C/LLVM backends.

- Add differential corpus coverage and refresh the supported-surface manifest.

* fix fs file handle argument handling

* fix fs file handle validation

* fix(fs): preserve FileHandle read error codes

* fix(runtime): match empty FileHandle buffer behavior
2026-08-09 21:22:19 -05:00
Chris Tate a9b6dba424 feat(string): support static split limits (#109)
* feat(string): support static split limits

- Lower split limits for string and literal RegExp separators across C and LLVM.
- Match JavaScript ToUint32 limit semantics in the runtime.
- Add differential coverage and refresh diagnostics and surface metadata.

* fix(string): default undefined split limits
2026-08-09 18:09:00 -05:00
Chris Tate f1066d7825 Support variable Buffer.toString encodings (#108)
* Support variable Buffer.toString encodings

- Lower runtime-valued BufferEncoding arguments through checked C and LLVM paths.
- Normalize aliases and casing while preserving Node unknown-encoding errors.
- Add differential coverage and remove the obsolete diagnostic fence.

* fix(buffer): preserve unknown encoding messages

* fix(buffer): preserve optional encoding defaults

* fix(runtime): handle empty Buffer decoding ranges
2026-08-09 17:23:13 -05:00
Chris Tate 82b065c014 feat(fs): support static writeSync (#106)
* feat(fs): support static writeSync

- Lower Buffer-window and UTF-8 string overloads through the C and LLVM backends.
- Match Node's positioned and current-offset write behavior, validation, and errors.
- Add differential corpus coverage and publish the static surface manifest entry.

* fix(fs): preserve writeSync runtime semantics

* fix fs.writeSync error parity

* fix fs write descriptor errors
2026-08-09 16:54:33 -05:00
Chris Tate b3d3101550 Add static array unshift and reverse (#107)
- Lower unshift and reverse through the C and LLVM backends.
- Preserve spread, mutation, evaluation-order, and reference-counting semantics.
- Add runtime, differential, and surface-manifest coverage.
2026-08-09 14:25:53 -05:00
Chris Tateandryoppippi 23a2d3309e feat(fs): support static rename APIs (#104)
* feat(fs): support static rename APIs

- Lower fs.rename, fs.renameSync, and fs/promises.rename through the C and LLVM backends.
- Add runtime callback, error, and promise handling for rename operations.
- Cover typed and check-JS usage with differential corpus tests.

Co-authored-by: ryoppippi <1560508+ryoppippi@users.noreply.github.com>

* fix Windows rename semantics

* fix: move callback rename work off main thread

* fix(runtime): preserve rename callback checkpoints

---------

Co-authored-by: ryoppippi <1560508+ryoppippi@users.noreply.github.com>
2026-08-09 13:29:15 -05:00
Chris Tate a4e9970119 Support static util.parseArgs (#103)
* Support static util.parseArgs

- Lower typed util.parseArgs calls through the C and LLVM backends.
- Add a link-gated native parser with Node-compatible options, tokens, defaults, and errors.
- Cover ESM, CommonJS, default argv, sanitizer, and TS7 behavior.

* fix(runtime): align parseArgs behavior with Node

* fix(runtime): close parseArgs parity gaps

* fix(runtime): match parseArgs edge cases

* fix(runtime): preserve parseArgs short and default semantics
2026-08-09 08:57:03 -05:00
Chris Tateandsensei-woo e5c875bd97 Support Date instance lowering (#101)
* Support Date instance lowering

- Lower read-only Date values and constructors through the C and LLVM backends.

- Add portable calendar helpers, differential coverage, and documented surface contracts.

- Fence unsupported mutation, identity, locale, and component-constructor forms.

Co-authored-by: sensei-woo <sensei-woo@users.noreply.github.com>

* Fix Date exception and timezone semantics

* fix: harden Date lowering edge cases

* fix Date lowering edge cases

* Fix Date union fences and offset clipping

---------

Co-authored-by: sensei-woo <sensei-woo@users.noreply.github.com>
2026-08-08 23:17:58 -05:00
Chris Tateandsensei-woo 0c45ee7d90 Support positioned fs.readSync calls (#99)
* Support positioned fs.readSync calls

- Lower numeric positions while preserving omitted and null current-offset behavior.

- Add offset-preserving native reads across POSIX and Windows runtimes.

- Cover positioned reads, offset semantics, EOF, and invalid positions.

Co-authored-by: sensei-woo <sensei-woo@users.noreply.github.com>

* fix(runtime): preserve partial positioned reads on Windows

* fix zero-length positioned reads

* fix(runtime): match empty readSync validation order

* fix(compiler): accept parenthesized null read positions

---------

Co-authored-by: sensei-woo <sensei-woo@users.noreply.github.com>
2026-08-08 16:58:34 -05:00
Chris Tateandmorler 53e2f08227 perf(compiler): specialize typed-array element access (#97)
* perf(compiler): specialize typed-array element access

- Lower typed-array reads, writes, and lengths directly by IR element kind.
- Preserve coercion, bounds, and receiver lifetime semantics across C and LLVM.
- Cover emission, ABI layout, and Node-differential behavior.

Co-authored-by: morler <478444+morler@users.noreply.github.com>

* fix: retain typed-array receiver across nested assignments

---------

Co-authored-by: morler <478444+morler@users.noreply.github.com>
2026-08-08 14:39:41 -05:00
Chris Tate 782d3b8451 fix(compiler): support implicit top-level await modules (#94)
* fix(compiler): support implicit top-level await modules

- Match Node 24 syntax detection by treating top-level await as an ES module marker.

- Add differential corpus coverage for TypeScript files without explicit imports or exports.

* fix Node ESM classification for top-level await

* fix ESM require diagnostics and classification caching

* fix require binding and package type precedence

* fix: align top-level await module detection with Node
2026-08-08 11:35:01 -05:00
Jimmy Miller d41b5dd3c3 Add generations to cycle detection (#30)
* runtime: pin the ScrCycHdr layout the LLVM backend hardcodes

scr_cyc_mark_live is a static inline, so there is no symbol for the LLVM
backend to call — it open-codes the retain hook as a raw `store i32 0` at
obj-16 and reaches the cycle header at obj-32. Three sites emit that
(llvm/shapes.ts, llvm/classes.ts, llvm/emitter.ts), which makes the C
struct's size and its `color` offset a real ABI between the runtime header
and hand-written IR. The stored VALUE is part of that ABI too: the emitted
store is the literal 0, not the enumerator, so SCR_CYC_BLACK's numeric value
is pinned as surely as the offsets are.

Nothing enforced any of it. llvm-runtime-abi.test.ts mechanically checks that
every `declare @scr_*` agrees with its C prototype, but that is the FUNCTION
ABI; a struct-offset skew is invisible to it, to the type system, and to the
C compiler. Narrowing `color` and putting another field in the freed bytes
compiles clean and silently zeroes that field on every retain; reordering the
color enum compiles clean and makes every retain write the wrong color.

Assert the four properties the emitted IR actually depends on, so the next
edit to this struct or that enum fails the build instead of miscompiling.

The three layout assertions bake in 64-bit pointers and size_t, which every
current target has. A 32-bit port would trip them — correctly: the backend's
hardcoded -16/-32 would need fixing too.

* runtime: collect cycles generationally

A trial-deletion pass costs O(objects reachable from its candidates), and a
candidate inside a large live structure reaches all of it. Collecting every
256 candidates therefore made total collection work quadratic in a growing
live heap: the V8 splay benchmark spent 749ms per iteration, ~99% of it in
the collector re-walking a tree that was entirely live and never garbage.

Make the collector generational, in the shape CPython uses for this same
algorithm. Each header carries a generation; a pass names the oldest one it
will walk and skips anything above it, exactly as it already skips NULL and
immortals; survivors are promoted so later nursery passes never re-walk
them. A pass then costs what was allocated since the last one rather than
the whole heap.

Restricting the walk stays sound because trial deletion is already
conservative in the safe direction: an edge from a skipped older object is
never trial-deleted, so its target keeps that count and reads as externally
referenced — the same answer the collector gives for a stack reference.
What it gives up is cycles that span generations, and the full pass (which
skips nothing, and so is exactly the old algorithm) is what finds those.

Three things that are load-bearing and were not obvious:

- A restricted pass may spare a candidate ONLY because the edge keeping it
  alive came from a generation it refused to walk. The candidate buffer is
  the collector's only root set and markRoots consumes the entry, so
  dropping such a survivor retires the one record that the object is a
  possible cycle root — and a dead cycle whose members were all spared that
  way is then invisible to every later pass, full ones included. So a
  restricted pass hands its survivors back as candidates. A full pass needs
  none of this: it walked every edge, so rc > 0 there is a genuine outside
  reference and Bacon-Rajan's own reasoning retires the candidate.

- Live data that is unlinked INTO a dead cycle grows no counter: those
  objects were tallied when they were allocated, and they are not in the
  nursery. A heap-growth trigger alone therefore never fires for a program
  that churns its long-lived structures, so the mature candidate buffer's
  own size is a second full-pass trigger.

- Restricting the walk leaves one edge accounted by NOBODY. markGray does
  not trial-delete an edge into a skipped generation, and the teardown
  contract has free_fn release exactly the UNTRACED children — because every
  traced edge was supposed to have been decremented by markGray. So freeing
  a white object that holds a traced edge into an older generation drops the
  edge while the target keeps the count, and that phantom reference reads as
  an external one to every later pass, full ones included: the target and
  everything it links to would never be reclaimable again.

  The white set pays those edges off explicitly, in two halves, because the
  walk cannot do it inline — a release there could free a survivor that
  scr_promote still points at, or cascade into the white set mid-teardown.
  Each target is PINNED with a retain while `gen` still holds the values the
  walk filtered on, and after the teardowns the pin is dropped and the edge
  given up for real. Two decrements per entry, because the pin is one of
  them; a single release would only undo the pin and leave the phantom edge
  where it was. The pin is also what makes the second decrement safe, since
  a teardown's releases of untraced children can reach a cycle-headered
  object — that is how they re-buffer survivors. One entry per skipped edge,
  so several edges sharing a target settle it once each. Nothing pinned can
  be in the white set: a skipped older object's edges were never
  trial-deleted, so anything it references was scan-blacked rather than
  whitened, by the same conservatism above.

The event loop's between-turns collection now runs one scheduled pass
instead of scr_collect_cycles(); a full sweep per turn would walk the whole
live heap every turn, which is the cost the generations exist to avoid.
scr_collect_cycles() stays the exit / session-reset sweep, where the RC
audit runs straight after and wants nothing reclaimable left.

757-cycle-cross-generation.ts covers the third point: a live list mutated
until its nodes promote, then dead nursery cycles holding traced edges into
it. Unaccounted, the sanitized lane reports 60 objects live at exit — the
whole list, held by phantom counts.

Measured, best-of-7 against the previous collector:

  splay          620.45ms -> 1.45ms   (428x)
  deltablue         1.25  -> 0.81     (1.55x)
  richards          1.196 -> 1.162    (1.03x)
  crypto/navier-stokes/raytrace/regexp   unchanged

  an LRU cache (200k entries, 200k ops)  32137ms -> 93ms   (345x)
  a large live cache + 500 event-loop turns  3095ms -> 776ms  (4.0x)

The trade is space: floating cyclic garbage is now a bounded fraction of the
live heap instead of a fixed candidate count, so peak RSS on
cyclic-garbage-heavy programs runs ~1.4x the old collector's. Bounded and
flat in run length, not a leak — verified by holding a 200k-object live heap
while churning 200k dead cycles per round for 30 rounds.

Test lanes show byte-identical failure sets against the previous collector:
Linux sanitized 164, Linux plain 528, macOS differential corpus 66 — all
pre-existing on those machines, none introduced or fixed here.

* runtime: bound scheduled mature cycle backlog

* runtime: rearm cycle trigger after candidate deaths
2026-08-08 11:32:45 -05:00
Chris Tate 52459a86d4 feat(compiler): lower stored text codec calls (#85)
* feat(compiler): lower stored text codec calls

- Lower same-scope const TextEncoder and TextDecoder call receivers without runtime instances.
- Preserve fences for escaping, captured, and imported codec values with actionable diagnostics.
- Add differential, diagnostic, and preflight baseline coverage for the supported idiom.

* fix(compiler): fence deferred text codec calls

* fix text codec switch-clause TDZ handling
2026-08-02 21:24:33 -05:00
Chris Tate 8a204cc7e7 fix(fetch): address remaining review regressions 2026-07-30 12:33:26 -05:00
Chris Tate b3b58ca878 fix(fetch): address static parity regressions 2026-07-30 11:55:17 -05:00
Chris Tateandmorler de0e54d776 fix: lower HTTPS request callbacks in LLVM
- Lower the HTTPS options row through the runtime ABI with callback ownership and loop liveness.
- Pin HTTP and HTTPS response callbacks with differential and tier-regression coverage.

Co-authored-by: morler <478444+morler@users.noreply.github.com>
2026-07-30 00:17:47 -05:00
Chris Tate 798a281be3 fix: lower wrapped undefined arguments 2026-07-29 22:36:45 -05:00
Chris Tate 4b041e630f fix: preserve array copying edge semantics 2026-07-29 21:35:09 -05:00
Chris Tate 296311fa81 fix: preserve static undefined argument semantics 2026-07-29 21:13:46 -05:00
Chris Tate f47ee03dc6 Support array copying and Uint8Array iteration
- Add static Array and Uint8Array copying, sorting, and join surfaces.
- Lower Uint8Array spread, destructuring, and iterator methods across C and LLVM.
- Pin Node 24 semantics with differential coverage and runtime size gating.
2026-07-29 18:03:00 -05:00
Chris Tate e95469364a Support numeric iterators in for-of
- Lower number-array and typed-array value iterators statically.
- Preserve stored iterator cursor and exhaustion state across loops.
- Add Node differential coverage for arrays and Uint8Array.
2026-07-29 16:32:41 -05:00
Chris Tate a992b644fb fix: align Array.toSorted ordering semantics 2026-07-29 15:30:48 -05:00
Chris Tate d7cb22a325 test: pin Array.toSorted evaluation order 2026-07-29 15:11:04 -05:00
Chris Tate 767be68ae2 feat: add static Array.toSorted support
- Lower to the stable array sort helper over a shallow snapshot.
- Publish Array.prototype.toSorted in the static surface manifest.
- Cover stability, copy semantics, and evaluation order differentially.
2026-07-29 14:56:18 -05:00
Chris Tate 9b0ad004f8 Fix top-level await rejection checkpoints 2026-07-29 01:32:26 -05:00
Chris Tate 05752fde96 Fix top-level await dependency rejection handling 2026-07-29 00:35:35 -05:00
Chris Tate 43e183dfc3 fix: await async cycle root from external importers 2026-07-29 00:11:21 -05:00
Chris Tate c50041b1bd fix: select async cycle root at runtime 2026-07-28 23:49:22 -05:00
Chris Tate 786f10dbf2 Fix top-level await cycle semantics 2026-07-28 23:27:25 -05:00
Chris Tate 2d9070cd54 fix top-level await rejection handling 2026-07-28 22:01:32 -05:00
Chris Tate e88ddc1678 Support top-level await
- Lower asynchronous ESM initialization with Node-compatible dependency ordering and caching.
- Finish top-level promises consistently across the C and LLVM runtimes.
- Add differential coverage for imports, rejection, and unsettled evaluation.
2026-07-28 11:19:04 -05:00
Chris Tate 81091a1a49 Preserve effectful toFixed defaults
- Evaluate undefined precision expressions before substituting zero.
- Cover effectful optional precision with a differential corpus case.
2026-07-26 21:21:07 -05:00
Chris Tate a3a5863cca fix optional toFixed lowering 2026-07-26 19:50:06 -05:00
Chris Tate bc2cd2b7d1 Support Number.toFixed statically
- Lower Number.prototype.toFixed through the compiler IR and native backends.
- Match JavaScript rounding, range errors, and numeric edge cases in the runtime.
- Add differential coverage and update surface metadata and diagnostics.
2026-07-26 18:43:53 -05:00
Chris Tate a7538fd87d URL-string and URL-object arguments to the http and https clients
- `http.get("http://host/path")` and its https spelling now compile. The declarations only described the options-record form, so the first thing a from-scratch client writes was a type error — the shape worked under --dynamic, where the engine does not consult our declarations, which is how it read as a hello-world failure.
- A URL object is accepted the same way, as its href through the same parse. An unparsable input is the WHATWG "Invalid URL" TypeError and a scheme that is not the calling module's is ERR_INVALID_PROTOCOL, both catchable, matching Node rather than silently upgrading the dial.
- `request` and `get` take one signature with a union first parameter instead of Node's two overloads: `tls ? https.request : http.request` unions two function types, and resolving a call on that union collapses each side to a single signature, so an overload set misresolves in either declaration order. The lowering dispatches on the argument's own type.
- Both rows run on the LLVM backend, and the tls CA-store entries joined it too — the omission there was stale, so 2557-tls-ca-store moved off the C lane with identical output.
- Corpus 2644 and 2645 cover both schemes against loopback servers, so neither needs the network.
2026-07-24 23:24:53 -05:00
Chris Tate 6345fabfcb Retag || on the truthy side instead of coercing the left
- tsc builds `u || d`'s result by DROPPING the left's falsy arms (`process.env.X || null` is `string | null`, `|| 3000` is `string | number`), so coercing the left into that result before the truthiness test retags an arm the test is about to rule out — and threw where Node yields the default.
- `orDefault` gains an optional `retag`: the truthy side hands the whole left box to a union→union helper whose stranded-arm throw is unreachable by construction, since truthiness has already ruled those arms out. Left evaluates once, right stays lazy, arm count is free.
- A ternary in logical-left position no longer adopts its contextual union over its own, for the same reason the eager coercion was wrong: tsc's assignability proof does not hold for that operand. Narrow to the union choice — contextual array element typing and the unmappable-own rescue are untouched.
- 2595 chained its two in-flight `fs.exists` stats: registering both after the awaited rejections orders them against the rejections, not against each other, and Node itself returns them reversed about one run in forty.
2026-07-24 21:15:53 -05:00
Chris Tate 44d05d8e74 Route the compiler's dyn world onto the engine's own operations
- Island values held in `unknown` arm the routed operation set (SCR_DYN_JSVAL): keyed reads and writes, calls and method dispatch, Object statics, and `??` all run in the engine, so a wrapped value answers exactly what Node answers instead of meeting a fence.
- Scalars normalize at the wrap, composites stay engine values by reference, and the round trip preserves identity — a value that crosses into the checked-dynamic tree and back is the same engine value.
- deepStrictEqual over a mixed engine-vs-native pair fails with the reason stated rather than guessing at an answer.
- Corpus 2582–2585 and an npm routed-row fixture pin the behavior; the dyncheck expectations move with it.
- The retired "DOM" nickname is swept out of the sources and corpus in the same pass (29 comment sites) — the world is the checked-dynamic tree, its values are dyn values.
2026-07-24 19:53:10 -05:00
Chris Tate 27e7537cec Crypto introspection, the TLS CA store, and the http2/rejection tail
- The crypto introspection statics (getFips and the cipher/hash/curve name lists) bake at the call site, and the crypto constant table joins http2's under a generalized per-module baked-constants lowering.
- The CA-store introspection surface lands in its own unit (scr_tls_ca.c) behind its own link gate, so a getCACertificates-only binary never pulls mbedTLS: getCACertificates, rootCertificates, setDefaultCACertificates.
- http2.createSecureServer grows the eager request handler and the runtime options record, riding the same server-options walk as tls.createServer; string-typed 'data' listeners decode.
- process once/off for 'unhandledRejection' plus the sibling 'rejectionHandled' registry, removal by closure identity per the warning-registry stance.
- Merge resolution unions this lane with main's fs ladders, createRequire erasure, and dyn secure-context work; the runtime's retired "DOM" nickname is spelled "dyn" throughout.
2026-07-24 19:49:54 -05:00
Chris Tate 2c0f01ad93 HTTP Agent and dynamic-handle compatibility
- Add Agent connection accounting and HTTP/socket compatibility surfaces
- Support dynamic Buffer at and slice access
- Pin behavior with differential corpus coverage
2026-07-24 18:52:19 -05:00
Chris Tate d1192f3785 2470's deferred fence is cured: the general for-of lowering claims its table loop 2026-07-24 17:56:17 -05:00
Chris Tate 6c4430e0de Bare 'module' resolves the builtin like node:module
- Node serves the builtin for both spellings, so both key the same lowering tables; the stale prefix-only caution predated the createRequire erasure
2026-07-24 17:18:36 -05:00
Chris Tate de37b09716 Trap-claim carve-outs restore two over-narrowed shapes; extending a poisoned base refuses at build time
- The written-binding decline yields when the declared type has no mapping or the write's RHS roots at an ambient-undefined name
- A class extending a collection-poisoned base flushes the base's diagnostics eagerly: the heritage evaluates at module init, so deferring the compiler's own fence manufactured a silent wrong output
2026-07-24 17:18:25 -05:00