Commit Graph
3948 Commits
Author SHA1 Message Date
Chris Tate 714dbfe2bb Merge main 2026-10-22 06:59:47 -05:00
Chris Tate 41245eeb0c Allow the JSX lowering tests' TypeScript 5 import (#1808) 2026-10-22 06:50:21 -05:00
Chris Tate 9b317ba97d Allow the JSX lowering tests' TypeScript 5 import
jsx-source.test.ts compares the JSX rewrite with TypeScript 5's
transpileModule output, so it imports typescript5 as the other test
oracles on the TypeScript 5 island allowlist do. scripts/test-ts7.mjs
did not list it, and the TypeScript 7 parity job failed since #1786.
2026-10-22 06:48:13 -05:00
Chris Tate 5d3dced191 Throw Node's TypeError for member reads of array holes in wide unions (#1806) 2026-10-22 06:35:04 -05:00
Chris Tate 66642b1835 Batch the contextual types and signatures that lowering asks per node (#1805) 2026-10-22 06:34:40 -05:00
Chris Tate 3fecf687f5 Throw Node's TypeError for member reads of holes in wide unions
A binding that may hold a value its declared type omits (a function
parameter fed array elements, which can be holes) and that the checker
narrowed to one record or class arm of a union with more than two arms
was read through a checked extraction of that arm. When the binding held
a hole, a member read or method call threw "undefined is not
representable in the target union ..." for a record arm and "Value is
not an instance of 'Shape'" for a class arm, where Node throws "Cannot
read properties of undefined (reading 'a')".

The read now tests for undefined first and throws Node's TypeError, as
the two-arm path already does.
2026-10-22 06:31:30 -05:00
Chris Tate d22215faaa Merge main 2026-10-22 06:31:17 -05:00
Chris Tate 3edec984d5 Compile JSX with the classic runtime (#1786) 2026-10-22 06:29:40 -05:00
Chris Tate 8ff58d2810 Match Node for generic arrow bindings used before their declarations (#1773) 2026-10-22 06:19:57 -05:00
Chris Tate 0f6ea63f21 Give each evaluation of a forward-read generic binding its own function
A generic binding inside a function that a nested function read before
the declaration lowered stores its instance into a TDZ box when the
declaration runs. That value was the instance's closure, which the
backend interns for module functions, so every evaluation of the
declaration stored the same function object. JavaScript makes a new one
each time. The stored value is now a closure over a lifted forwarder that
calls the instance, so each evaluation allocates a new closure; the
forwarder is created once per instance. Async and rest-parameter
bindings read this way report SC1090.

Corpus 7180 checks the identities.
2026-10-22 06:17:05 -05:00
Chris Tate d01117fa51 Batch the contextual types and signatures that lowering asks per node
ClassProtocols' identity-flow fixpoint asks the contextual type of each
site whose source carries identity, one round trip at a time, and lowering
asks the resolved signature of each call and the contextual type of each
array literal and conditional it lowers the same way. The checker facade
can now batch them: prefetchContextualTypes for the fixpoint's sites before
it runs, and, for each prefetched wave of reachable roots, the resolved
signatures of its calls and the contextual types of its array literals and
conditionals. A batched query that fails is left out of the memo, so a
direct query still throws where it is made.

The batches use the checker's getContextualTypes and getResolvedSignatures
requests. NODE_BATCH_QUERIES keeps them off until scriptc depends on a
tsc-ts release that answers them; while it is off the prefetches do
nothing.
2026-10-22 06:13:45 -05:00
Chris Tate 655c36c880 Match Node's AsyncLocalStorage context in async prefixes and generator steps (#1774) 2026-10-22 06:09:13 -05:00
Chris Tate fb403d5755 Clear a store that an async prefix enters in a loop callback
When an event-loop callback calls an async function or steps a generator
that enters a store before its first await, the store becomes the
callback's at the end of the prefix. On the main slot it now ends with
that callback, as an enterWith there does: the copy schedules the tick
that clears the main slot, so the store does not reach later callbacks.
2026-10-22 06:06:45 -05:00
Chris Tate 7f19e582e3 Read error constructors as values and destructure workerData in JavaScript (reland) (#1803) 2026-10-22 06:05:36 -05:00
Chris Tate df6de14c94 Support new tls.TLSSocket and tls.connect({ socket }) (#1791) 2026-10-22 06:01:47 -05:00
Chris Tate 4e834f8eed Read error constructors as values and destructure workerData in JavaScript (reland) 2026-10-22 06:00:28 -05:00
Chris Tate 3cefd421a1 Fence requestCert beside a secureContext and free failed TLSSockets
new tls.TLSSocket(socket, { isServer: true, secureContext, requestCert:
true }) skipped the options walk that refuses requestCert, so the server
asked for no client certificate and accepted every client, even with
rejectUnauthorized: true. With a secureContext, Node still reads the
socket's own options, so a truthy requestCert, SNICallback and
ALPNCallback now throw the fence there too.

A TLS socket's transport kept its 'secure' and 'session' listeners until
the socket was freed. A handshake that fails never fires 'secure', so a
listener that captures the socket kept the socket and its TLS state alive
after it closed. The transport now drops those listeners when the socket
settles, and ignores listeners added after that.
2026-10-22 05:58:32 -05:00
Chris Tate daac2a4a15 Support objectMode streams with any value as a chunk (#1785) 2026-10-22 05:55:45 -05:00
Chris Tate 2e29fd6a8c Support asymmetric keys, signatures and Ed25519 in node:crypto and WebCrypto (#1771) 2026-10-22 05:54:11 -05:00
Chris Tate c14e2607c5 Address #1785 review: Buffer|string data adapter and objectMode chunk handling 2026-10-22 05:52:31 -05:00
Chris Tate c086610b94 Keep each build's translation unit private until the build ends (#1766) 2026-10-22 05:50:07 -05:00
Chris Tate 01a467060b Support WebCrypto wrapKey and unwrapKey
crypto.subtle.wrapKey exports a secret key (raw, raw-secret or jwk) and
encrypts it, and unwrapKey decrypts and imports one, as Node's
webcrypto.js does: the wrap algorithm normalizes through the wrapKey
registry (AES-KW) and then the encrypt registry (AES-GCM, AES-CBC and
AES-CTR with their dictionaries), the wrapping key's algorithm and
usages are checked, and a JWK payload is its JSON text, padded with
spaces to a multiple of 8 bytes for AES-KW. A wrapped JWK that is not
UTF-8 JSON with a kty member rejects with Node's DataError.

AES-KW is RFC 3394 key wrap over the vendored mbedTLS block cipher, in
scr_webcrypto_aes.c beside the other AES modes: wrapping takes a
multiple of 8 bytes and at least 16, unwrapping a multiple of 8 and at
least 24, and the integrity check value is compared in constant time.
The cipher's failures, and unwrapKey's import errors, reject on a later
loop turn as Node's job promises do.

This completes jose's symmetric key management: 7132 runs the real
jose 6.2.12 PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW,
A128KW and A256KW paths (EncryptJWT and jwtDecrypt) against Node.
getPublicKey replaces wrapKey as the refused method in the fenced
fixture and the JavaScript refusal test.
2026-10-22 05:48:30 -05:00
Chris Tate 6f11afa09e Size crypto error messages to their whole text
The key and signature errors formatted into fixed stack buffers and
passed snprintf's return value on as the message length. A message
longer than the buffer, such as "Invalid digest: " with a long algorithm
name from crypto.sign or crypto.verify, then copied bytes past the end of
the buffer into the error. The messages are now sized to their whole
text, so a long name appears in full, as in Node.

The received values in these messages also follow Node: strings as
util.inspect quotes them, cut at 128 characters, and large integers with
ERR_OUT_OF_RANGE's separators. A fractional, NaN or infinite
modulusLength reports "It must be an integer", as validateUint32 does.
2026-10-22 05:46:53 -05:00
Chris Tate 6bf3b7d9df Install driver-built translation units before the native build
The private copy of the LLVM text had no extension. Builds that compile it
with the C driver (sanitize builds, targets without the LLVM helper) passed
it to clang directly when the native cache was off, and clang read it as a
linker input, so the build failed. The copy is now named with `.ll`.

Those builds also record the output directory in their native cache proof.
Renaming the private copies to the shared names after the native build
changed that directory, so every unchanged repeat missed the proof and
relinked the executable. The shared names are now installed before the
native build, which compiles and caches copies in a private directory
outside the output directory.
2026-10-22 05:44:28 -05:00
Chris Tate ed1a5b21c4 Resolve repeated checker objects from their ids without decoding them (#1795) 2026-10-22 05:32:46 -05:00
Chris Tate 54e3b0ce13 Test an array read's hole-free prefix before its capacity (#1793) 2026-10-22 05:32:26 -05:00
Chris Tate 14dfb37161 Skip declaration files when looking for writes to a narrowed binding (#1794) 2026-10-22 05:28:51 -05:00
Chris Tate 999fef551e Resolve repeated checker objects from their ids without decoding them
Checker replies name every type, symbol and signature they reach in
full, and most of them are objects the client already holds: building
tsc-ts, 96% of the types, 79% of the symbols and 80% of the signatures
in replies are cached by id. Object replies are now read as bytes, each
element's extent is found by a scan that skips strings, and an element
whose leading "id" is cached resolves to the cached object without its
text being decoded. The other elements are parsed as before.
2026-10-22 05:27:07 -05:00
Chris Tate 9893630810 Skip declaration files when looking for writes to a narrowed binding
Narrowing stability looked for writes to a binding by walking the whole
file that declares it. For globals such as `console` and `JSON` that file
is a declaration file (scriptc-node-fallback.d.ts, lib.es5.d.ts), so every
build that read one of them materialized about 46,000 AST nodes and kept
them until the end of the build. A declaration file holds no code that
runs, so none of its writes happen: the walk now returns no writes for it.
2026-10-22 05:26:43 -05:00
Chris Tate 1917d1aa00 Test an array read's hole-free prefix before its capacity
The dense path of an element read that may be undefined (the
`%arr.idxOr` reads behind `a[i]` as `T | undefined`, the store
`a[x] = a[y]!`, and the element reads of the lowered array methods)
tested the index against the capacity, then against the hole-free prefix
(`filled`), and only above the prefix against the length and the slot's
state. `filled` is at most the length and the capacity (scr_array.h), so
an index below it needs no other test: the read now tests `filled` first
and takes the value path on that test alone. Above the prefix it tests
the capacity, the length and the state as before.

A double index first branches to the runtime lookup when it is not an
exact integer, then takes the same tests on its i64 value, which a 32-bit
target compares before truncating it.
2026-10-22 05:25:02 -05:00
Chris Tate 13dccd5b99 Map a JS binding's declared type only for a nullish write (#1792) 2026-10-22 05:12:43 -05:00
Chris Tate c09801c064 Map a JS binding's declared type only for a nullish write 2026-10-22 05:08:24 -05:00
Chris Tate 30bfe1ac65 Run two-counter for loops on integer counters (#1790) 2026-10-22 04:53:39 -05:00
Chris Tate 1360830149 Support new tls.TLSSocket and tls.connect({ socket }) 2026-10-22 04:52:44 -05:00
Chris Tate 883f22ddd6 Run two-counter for loops on integer counters
`for (let lo = a, hi = b; lo < hi; lo++, hi--)` kept both counters as
doubles: the counted-loop match takes a single counter, so every
`a[lo]`/`a[hi]` converted and tested its index. A loop whose two counters
close in on each other by positive literal steps, are not written by the
body and index something now stores both as i64: on every body entry both
lie between the first start and the second. A start without a proven
integer range is tested at run time on a versioned loop, as a counted
loop's is.
2026-10-22 04:50:13 -05:00
Chris Tate 3703c94387 Call typed-array callbacks directly and visit on an integer counter (#1789) 2026-10-22 04:49:08 -05:00
Chris Tate feec4bf4df Call typed-array callbacks directly and visit on an integer counter
The helpers of the typed-array callback methods (forEach, map, filter,
some, every, find, findIndex, findLast, findLastIndex, reduce,
reduceRight) called their callback through the closure's code pointer on
every element, and one helper served every call with the same signature,
so the callback was never inlined. A literal callback now gets a helper
of its own, as for the array methods, and the constant-callback census
accepts the typed-array helpers, so the helper calls that function
directly.

The visit is now a loop on its own counter, `for (let i = 0; i < a.length;
i++)` or down from the last index, instead of a loop on a counter
declared before it, so the counter is an integer and element reads need no
index test. reduce and reduceRight without an initial value read their
seed at the first visited index and start one past it.

Adds reduce, some and map callbacks to the typed-array-kernels workload.
2026-10-22 04:44:34 -05:00
Chris Tate af2597016c Resolve 7058's promises with undefined so both checkers agree (#1788) 2026-10-22 04:38:01 -05:00
Chris Tate b03e965bf9 Resolve 7058's promises with undefined so both checkers agree 2026-10-22 04:35:27 -05:00
Chris Tate 72f6293e26 Drop the Cipheriv stream fence from the node-types fixture (#1787) 2026-10-22 04:30:34 -05:00
Chris Tate cab2db4f96 Drop the Cipheriv stream fence from the node-types fixture 2026-10-22 04:27:50 -05:00
Chris Tate c47a0e90ae Compile JSX with the classic runtime
Fixes #889
Co-authored-by: papack <33105506+papack@users.noreply.github.com>
2026-10-22 04:27:35 -05:00
Chris Tate 67247dd26b Support objectMode streams with any value as a chunk
Readable, Writable, Duplex, Transform and PassThrough take the
objectMode option, and a Duplex, Transform or PassThrough the
readableObjectMode and writableObjectMode options, as true or false
literals in an options object literal or in an options value. An
object-mode side holds any value that converts to a checked-dynamic
value: push, unshift, write, end, pipe, pipeline, for await, 'data'
listeners, Readable.from and the transform callback carry values in
TypeScript and JavaScript, and constructor-function streams and options
held in variables do the same. The object-mode high-water mark counts
values and defaults to 16. A readable buffer that mixes strings, Buffers
and other values holds them all, and push(undefined) and other values on
a byte-mode stream report ERR_INVALID_ARG_TYPE through 'error', as in
Node.

In typed code a write or transform callback, or a _write or _transform
method, may declare its chunk with any such type, which converts when
the callback runs. Writes pass the encoding argument to _write and
_transform as Node does: undefined when absent, null when a callback
took its place, otherwise the value unchanged. A parameter declared
string | null | undefined receives that value and one declared string
receives "" for undefined and null. write(chunk, encoding) on a
byte-mode stream encodes a string chunk with any known encoding and
throws ERR_UNKNOWN_ENCODING for an unknown one. Readable.from takes
typed Maps and Sets of any such value, and arrays that mix strings and
Buffers.

for await over a readable-only stream that will emit 'close' now ends
after 'close', as Node's eos does. Buffered writes that complete inside
clearBuffer run their callbacks in order, and 'finish' waits for a
deferred afterWrite that carries a callback, as Node's pendingcb does,
unless a _final callback schedules it.

The 'data' listener adapters take three slots and write and transform
callbacks read their chunk and encoding through runtime accessors, so
RUNTIME_ABI_VERSION is now 26.
2026-10-22 04:21:55 -05:00
Chris Tate 6e25c5ddb7 Compile js-yaml and smol-toml statically and match Node (#1751) 2026-10-22 04:15:26 -05:00
Chris Tate d5489cabd7 Merge main 2026-10-22 04:10:59 -05:00
Chris Tate 544110bed2 Revert "Read error constructors as values and destructure workerData in JavaScript" (#1783) 2026-10-22 04:08:00 -05:00
Chris Tate b99094543f Revert "Read error constructors as values and destructure workerData in JavaScript"
This reverts #1776, which made main CI fail.
2026-10-22 04:04:16 -05:00
Chris Tate ce2e517f6b Fix recursive JSON unions and primitive constructors as array callbacks (#1782) 2026-10-22 04:01:35 -05:00
Chris Tate ebbc6c1831 Fix recursive JSON unions and primitive constructors as array callbacks 2026-10-22 03:56:15 -05:00
Chris Tate 4f70f46e34 Name lowered helpers and closures independently of lowering order (#1781) 2026-10-22 03:50:43 -05:00