Commit Graph
6750 Commits
Author SHA1 Message Date
Chris Tate 6828c23b50 Error tee branches when the source errors with no read pending
The tee learned a source error only through a pending read's error
steps, so a source that errored while both branches held buffered
chunks and no read was pending left the branches readable: the next read
returned a chunk where Node rejects. The tee now watches its source's
error, as the streams spec reacts to the source reader's closed promise,
and errors both branches in a microtask (resolving the cancel promise
unless both branches were canceled). A read's error steps only end the
read, and a clone of an already errored body errors both branches the
same way.
2026-10-23 11:20:05 -05:00
Chris Tate 5a829bd225 Compile unions of typed-array classes 2026-10-23 11:16:10 -05:00
Chris Tate 53115c7e50 Merge main and fix the Node island report 2026-10-23 11:15:27 -05:00
Chris Tate 81e2e35e64 Hold array and record elements whose serialization can call user code
JSON.stringify walked a dense native array through its borrowed storage
and wrote record fields borrowed from the record. When an element's own
serialization can run user code (it reaches an array that may hold
foreign elements, whose getters and toJSON run, or a class instance or
checked-dynamic value), that code could grow the array, reallocating the
storage the walk still read, or replace the field it was writing.

In programs that store foreign elements, such arrays now take the
general walk, which reads each index afresh and holds its element, and
such record fields are held across their write. Programs without
foreign elements compile as before.
2026-10-23 11:09:31 -05:00
Malte UblandClaude Sonnet 5.5 fab4b403e9 Give corpus scratch paths a per-process name
The differential and LLVM differential suites can run the same corpus
program's Node oracle at the same time in one shard. Programs whose
scratch directory or file was derived only from argv[1] collided, and
one oracle removed the paths under the other. Their names now include
the pid, as 1403 and 5567 already do. Printed output never carries the
name.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-23 09:07:41 -07:00
Chris Tate fe452bdb03 Merge main and harden the Node island loader 2026-10-23 11:04:36 -05:00
Malte Ubl ce06a3377d Merge remote-tracking branch 'origin/main' into ci/tsgo-timeout 2026-10-23 09:01:36 -07:00
Chris Tate 5f22ee7146 Run two-counter loops and element copies over number arrays without per-element checks (#1991) 2026-10-23 11:00:35 -05:00
Chris Tate 6e849eeaef Read string-keyed record entries without allocating under ?? and ! (#2007) 2026-10-23 11:00:10 -05:00
Chris Tate 2d4aac0976 Read Web Headers pairs without copying them, and cache their sorted list (#2000) 2026-10-23 10:50:13 -05:00
Malte UblandClaude Opus 5.5 3c2911ccad Implement the identity TransformStream natively
'new TransformStream()' had no lowering, so hono's stream() and
streamSSE() helpers failed to compile their checked-dynamic paths. The
constructor without arguments now builds a native handle: its readable
side is a native ReadableStream with a zero high-water mark, and its
writable side runs the streams spec's WritableStream state machine
(getWriter, abort, close, locked; the writer's write, close, abort,
releaseLock, ready, closed and desiredSize). A write completes when the
readable side reads its chunk, close/abort/cancel propagate across the
pair, and deferred reactions take as many microtask turns as in Node.
Web ReadableStreams can also be weak collection keys (hono keys a
WeakMap by the response stream). A transformer, queuing strategies and
the WritableStream constructor keep the SC2020 refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 08:47:47 -07:00
Malte UblandClaude Opus 5.5 e84f656172 Clone Response and Request bodies by teeing their streams
Response.clone() and Request.clone() on checked-dynamic handles answered
'res.clone is not a function' (hono's etag middleware hashes
res.clone().body). The runtime now implements the streams spec's
ReadableStreamDefaultTee over native streams and clones the body with it,
so the original and the clone each read every chunk. A used or locked body
throws undici's TypeErrors, the clone's headers are a copy with the same
guard, and a cloned Request's signal follows the original's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 08:47:43 -07:00
Chris Tate 998a385bde Mark constructed headers canonical only when every value is trimmed
The Headers and Response constructors combine duplicate entries (a: x,
a: "") into one value with the separator, which can end in its space
("x, "). They marked the pairs canonical anyway, so a copy took them
unchanged where Node trims the copied value ("x,"). The constructors
now mark the pairs canonical only when every value is already trimmed;
otherwise copies normalize them pair by pair.
2026-10-23 10:45:26 -05:00
Chris Tate ecbfa766ef Store number arrays of proven int32s in 4-byte slots across direct calls (#1960) 2026-10-23 10:42:51 -05:00
Malte Ubl 7c54da90fc Merge remote-tracking branch 'origin/ni/i10-js-island-requires' into HEAD 2026-10-23 08:38:20 -07:00
Malte Ubl 7330b81f1c Merge remote-tracking branch 'origin/ni/i9-recorded-deferral' into HEAD 2026-10-23 08:38:00 -07:00
Malte Ubl 6696d9bb6f Merge remote-tracking branch 'origin/ni/i8-exit' into HEAD 2026-10-23 08:37:40 -07:00
Malte Ubl 72644a2849 Merge remote-tracking branch 'origin/ni/i7-routing' into HEAD 2026-10-23 08:37:21 -07:00
Malte Ubl ca99384018 Merge remote-tracking branch 'origin/ni/i6-subclasses' into HEAD 2026-10-23 08:36:55 -07:00
Malte Ubl 6c6e4ea932 Merge remote-tracking branch 'origin/ni/i5-shared-modules' into HEAD 2026-10-23 08:36:19 -07:00
Malte Ubl 269a8c1408 Merge remote-tracking branch 'origin/ni/i4-deferred' into HEAD 2026-10-23 08:35:52 -07:00
Chris Tate c11253b228 Reject other classes' capsules inline in class-table brand probes (#2001) 2026-10-23 10:35:30 -05:00
Malte Ubl d8cefd71a1 Merge remote-tracking branch 'origin/ni/i3-exports' into HEAD 2026-10-23 08:35:26 -07:00
Malte Ubl 88b3e5f7ae Merge remote-tracking branch 'origin/ni/i2-handles' into HEAD 2026-10-23 08:34:57 -07:00
Malte Ubl 510527e9bb Merge remote-tracking branch 'origin/ni/i1-stack-bound' into HEAD 2026-10-23 08:34:29 -07:00
Malte UblandClaude Opus 5.5 5734e5747c Keep two Node oracles of 992-fs-roundtrip apart
The differential and LLVM differential suites can run the same corpus
program at the same time in one shard. Their Node oracles had the same
argv[1] and so the same scratch directory, and one removed it under the
other. The directory name now includes the pid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 08:34:23 -07:00
Chris Tate 5fd47eac77 Search proven-ASCII strings backwards by byte in lastIndexOf (#2002) 2026-10-23 10:34:16 -05:00
Chris Tate d3c8155c85 Reuse the bundled declaration files' diagnostics across builds 2026-10-23 10:32:15 -05:00
Chris Tate 14678cf4eb Keep arrays a present-undefined store may reach out of the dense fast copy
A present undefined that the fast copy stores leaves its slot out of the
hole-free prefix the entry test read. The matcher left out only the array
named by the store, so a store through another name for the same array,
such as `const b = a` followed by `(b as (number | undefined)[])[i] =
undefined`, kept `a` covered, and the fast copy read the slot as a number.

Such a store now leaves out every covered array it may reach: its own, and
every other array unless that array or the store's binding is a local
array no other binding holds. A store into a field reaches every array
except those local ones.
2026-10-23 10:29:35 -05:00
Chris Tate bbaa7d7ba4 Pass callbacks through bindings in tests of the array-helper and closure paths 2026-10-23 10:28:44 -05:00
Malte UblandClaude Opus 5.5 1f7677d246 Answer untyped property reads of plain values without the class tables
Every untyped property read or write in a program with dynamic-tier
classes calls a generated helper (%dyn.class.property.N). For a value that
is not a class instance, the helper still called the normalization, the
instance-bag and the static-bag tables, each of which returns the value
itself, then compared the bag with the value and finally read the key.

When every class branch of a helper tests a capsule key or a class key,
its fallthrough is still the access it was created with, and every table
that fallthrough calls has its kind exit, a value that is neither a class
capsule nor a function now gets the same access on itself at the top of
the helper. Helpers for `constructor` and `toString`, which answer
primitives and errors specially, keep their full body.

zod 3, z.array(Order).parse over 500 orders: 235.8M -> 199.8M
instructions per round (-15.3%).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 08:26:28 -07:00
Chris Tate 11426b4fc2 Read string-keyed record entries as stack unions under projections
A keyed read of a string-indexed record whose values are numbers or
booleans (`counts[key]` on a `Record<string, number>`, typed
`number | undefined`) allocated a heap union for every read, also when
the only consumer was `??`, `!` or a comparison with undefined. The
runtime already returns the entry's value and whether it is present;
the box came from wrapping that result.

Such a read is now a stack union source: under a projection, the read
writes the tag and bits of the declared field or index-signature entry
the key names, or the undefined arm for a missing key, into a private
stack box, and allocates nothing. This applies when every hit is a
number or boolean arm of the result union, or an inline field of the
same union, and also to an argument a callee only projects (the helper
that `x!` lowers to). Other consumers keep the heap union.

dictionary-walks allocates no union instead of 363,359 and runs 14.6%
faster; no other runtime benchmark's code changes.

Corpus 7390.
2026-10-23 10:26:22 -05:00
Chris Tate b6e8e149b5 Trim combined header values again when copying after an empty append
Appending an empty value to an existing header leaves the separator's
space at the end of the combined value ("x, "). Node keeps that in the
Headers object but trims it when the value is copied into another
Headers, Request or Response ("x,"). The copy fast path copied a
canonical object's pairs as they were, so the copy kept the space. Such
an append now marks the pairs as no longer canonical, and copies
normalize them pair by pair.
2026-10-23 10:25:37 -05:00
Malte Ubl 9eddb388e9 Merge remote-tracking branch 'origin/main' into HEAD 2026-10-23 08:20:57 -07:00
Chris Tate 949f4d51de Keep loop-carried locals written from int32 element reads int32 (#2003) 2026-10-23 10:17:54 -05:00
Chris Tate e1358fb563 Read Math, JSON and Reflect as real objects in JavaScript
In JavaScript sources, Math, JSON or Reflect read as a value lowered to
an identity token, the string "[builtin Math]": typeof, String, `in`,
descriptors and member calls through an alias all had string semantics.

Each of these namespaces read as a value is now one object per program,
built on first use, with Node 24's own properties in Node's order:
function members are writable, configurable and non-enumerable with
Node's `length`, the Math constants are read-only, and
Symbol.toStringTag names the namespace. Members hold the same function
values the spelled member read gives; a member without one throws its
fence when called. Global reads, globalThis, destructuring and
shorthand properties all produce the same object, and an object with a
string Symbol.toStringTag coerces to "[object <tag>]".

Direct member calls keep their static lowerings, so replacing or
deleting a function member would not reach them: such changes throw
SC1090. New properties and attribute-only redefinitions behave as in
Node.
2026-10-23 10:16:30 -05:00
Chris Tate 779893eef8 Address review feedback on int32 arrays across calls 2026-10-23 10:15:37 -05:00
Chris Tate 6ebdec28e2 Update tsc-ts to 0.0.9
tsc-ts 0.0.9 answers getDiagnosticsOfCheckedFiles, which checks only the
listed files of a program and answers their semantic diagnostics and the
global diagnostics. The release-age exclusions admit it with its platform
packages.
2026-10-23 10:14:37 -05:00
Chris Tate 29ed8d5753 Merge main 2026-10-23 10:12:39 -05:00
Malte Ubl 35b0b09d16 Merge remote-tracking branch 'origin/ni/i10-js-island-requires' into HEAD 2026-10-23 08:11:35 -07:00
Malte Ubl b5ab75e899 Merge remote-tracking branch 'origin/ni/i9-recorded-deferral' into HEAD 2026-10-23 08:11:12 -07:00
Malte Ubl 924e0cd22f Merge remote-tracking branch 'origin/ni/i8-exit' into HEAD 2026-10-23 08:10:49 -07:00
Malte Ubl 8e6aeda693 Merge remote-tracking branch 'origin/ni/i7-routing' into HEAD 2026-10-23 08:10:31 -07:00
Malte Ubl 7cc39c3db4 Merge remote-tracking branch 'origin/ni/i6-subclasses' into HEAD 2026-10-23 08:10:02 -07:00
Malte Ubl 23f1ac4b06 Merge remote-tracking branch 'origin/ni/i5-shared-modules' into HEAD 2026-10-23 08:09:34 -07:00
Malte Ubl 7438e6cc2c Merge remote-tracking branch 'origin/ni/i4-deferred' into HEAD 2026-10-23 08:09:07 -07:00
Malte Ubl 95b9b05096 Merge remote-tracking branch 'origin/ni/i3-exports' into HEAD 2026-10-23 08:08:40 -07:00
Malte Ubl b921774bf6 Merge remote-tracking branch 'origin/ni/i2-handles' into HEAD 2026-10-23 08:08:13 -07:00
Malte Ubl 17218d8c38 Merge remote-tracking branch 'origin/ni/i1-stack-bound' into HEAD 2026-10-23 08:07:47 -07:00
Malte Ubl e5060d5085 Merge remote-tracking branch 'origin/ni/islands-base' into HEAD 2026-10-23 08:07:26 -07:00