Commit Graph
3274 Commits
Author SHA1 Message Date
Chris Tate 7278c3c467 Read a union's discriminant once in checked casts (#2073) 2026-10-24 04:51:36 -05:00
Chris Tate c652e418f6 Read the discriminant again after an arm's check fails
An arm's field check can run a getter that changes the discriminant. The
checked cast now reads the discriminant again after each failed arm;
when its case changed, the tests continue arm by arm after the failed
arm, so the cast picks the arm the arm-by-arm tests pick.
2026-10-24 04:10:52 -05:00
Chris Tate 64f3bb8fbe Give the capped Linux test workers the heap they had before the cap (#2084) 2026-10-24 03:49:00 -05:00
Chris Tate 0f90e07603 Process non-ASCII URL hosts with UTS #46 as Node does (#2088) 2026-10-24 02:48:24 -05:00
Chris Tate 66726267fc Share untyped module bindings that combine with strings and numbers (#2087) 2026-10-24 02:35:45 -05:00
Chris Tate 0e0bedca01 Forward pointer-union wraps of call arguments to the callee's parameter proof (#2048) 2026-10-24 01:56:42 -05:00
Chris Tate 937db54656 Raise the capped Linux test scope to 15 GB of RAM
The sanitized self-hosting native-frontend build needs about 15 GB by
itself: its clang compile of the whole frontend under ASan peaks at
10.5 GB beside a 3.8 GB compile in Node. In the 14 GB scope, with the
shard's other work running beside it, the kernel killed that clang
intermittently, so SC5004 reported clang's warnings and no error (SAN
16/20 and 19/20). The scope now caps RAM at 15 GB, still below the
runner's 16 GB, and may still swap past it.
2026-10-24 01:42:23 -05:00
Chris Tate 9496e42968 Keep a pointer-wrapped argument on the heap when its callee keeps the narrowed payload
A union parameter's proof covered the union, not its payload: narrowing it
and storing, returning or pushing the result, a narrowed nullish read, and a
store into a nullable-pointer field all counted as projections. That holds
for a boxed union, whose payload is a separate object. A record passed
through a nullable-pointer union is that payload, so forwarding it to such a
callee let a record in its caller's frame escape the frame.

A pointer-wrapped argument now needs a second fact from the callee's union
parameter: its payload stays in place too. The payload is in place when it
is only tested, narrowed for a field read (directly or through the checked
narrowing a field read of a `T | undefined` parameter compiles to), or passed
on to a parameter that is proved in turn. The facts that other arguments use
are unchanged.

Corpus 7663 has callees that push (directly and through a non-null
assertion), default, store in a global record field or a class field, or
pass on the narrowed record, and one that only reads it.
2026-10-24 01:27:44 -05:00
Chris Tate 1e90263517 Support Symbol.toStringTag class fields and getters (#2037) 2026-10-24 01:21:32 -05:00
Chris Tate 20339d9c27 Process non-ASCII URL hosts with UTS #46 as Node does 2026-10-24 01:13:00 -05:00
Chris Tate 70c2b8246d Share untyped module bindings that combine with strings and numbers
A JavaScript module binding whose initializer joins an untyped value with
a string, number or boolean through `||`, `&&`, `??` or `?:`
(`export const APP_NAME = pkg.appConfig?.name || "app"`) stayed a local of
the module's initializer, so reads from other modules and functions
failed with "a binding form with no lowering". Such initializers now
register the binding in checked-dynamic module storage, like the untyped
initializers they combine.

pi-coding-agent's config.js declares APP_NAME, APP_TITLE and isBundledNode
this way.

Refs #1777.
2026-10-24 01:03:18 -05:00
Chris Tate 373ebd9706 Initialize import cycles that re-export a member with export \* (#2081) 2026-10-24 00:55:34 -05:00
Chris Tate 68a9dea3fa Give the capped Linux test workers the heap they had before the cap 2026-10-24 00:42:45 -05:00
Chris Tate 7bf50dd9cc zlib: Brotli compression and decompression over the vendored brotli 1.2.0 (#2053) 2026-10-24 00:30:21 -05:00
Chris Tate fd768cd914 Initialize import cycles that re-export a member with export *
An `export * from` declaration binds each re-exported name to the binding
of the module that declares it, like a named re-export, so it has no
initialization state of its own. Import cycles whose modules re-export
another member of the cycle this way now compile with the exact cycle
initialization: re-exported names read the same values, and throw the
same temporal dead zone errors, as in Node. `export * as ns` of a cycle
member keeps the SC1016 refusal.

pi-coding-agent's sdk.js (sdk.js → agent-session-runtime.js →
agent-session-services.js → sdk.js) has this shape.

Refs #1777.
2026-10-24 00:24:12 -05:00
Chris Tate de5557ce5a Answer Error.prototype for Object.getPrototypeOf of an Error (#2058) 2026-10-24 00:04:29 -05:00
Chris Tate 07bab259ee Read typed-array elements through non-null assertions as undefined where Node does (#2067) 2026-10-23 23:53:54 -05:00
Chris Tate cbb87e8812 Address review comments 2026-10-23 23:49:40 -05:00
Chris Tate e3fb35cc68 Cap the Linux test step's memory and move memory-heavy side files apart (#2030) 2026-10-23 23:48:45 -05:00
Chris Tate fe3fd0de44 Parse URL hosts and paths as the URL Standard does, and inspect URLs as Node does (#2071) 2026-10-23 23:38:03 -05:00
Chris Tate cdef55778a Answer Error.prototype only while an error keeps its built prototype
Object.getPrototypeOf of an Error answers Error.prototype when the error's view was built from its fields and its prototype is still the object the view was built with. After Object.setPrototypeOf(error, {}), it answers the object that was set.
2026-10-23 23:31:30 -05:00
Chris Tate 543cb5c3c2 Divide by Math.pow(2, n) as a multiply by its reciprocal (#2076) 2026-10-23 23:29:14 -05:00
Chris Tate 6722a01898 Track asserted typed-array reads that can be undefined in element state 2026-10-23 23:28:09 -05:00
Chris Tate f060cad505 Inspect dynamic classes, functions and %o arguments as Node does (#1848) 2026-10-23 23:23:51 -05:00
Chris Tate 928697324f Reject class capsules of other classes without materializing them (#2075) 2026-10-23 23:14:24 -05:00
Chris Tate 0b4deda1d0 Print URL {} past the inspect depth limit 2026-10-23 23:05:32 -05:00
Chris Tate d6a6980849 Divide by Math.pow(2, n) as a multiply by its reciprocal
A quotient x / Math.pow(2, n) divided on every evaluation, and a
division's latency bounds loops that carry the quotient, such as a key
that keeps its low bits with k - Math.floor(k / Math.pow(2, n)) *
Math.pow(2, n). A divisor that is a positive power of two from 2^-1022
to 2^1022 has a reciprocal that is a power of two too, whose bits are
0x7FE0000000000000 minus the divisor's, and the product with it is the
quotient for every dividend. The quotient now multiplies by that
reciprocal when the divisor's bits are such a power, and divides
otherwise.

Corpus 8180 compares the quotient with an ordinary division for every
integer exponent from -1080 to 1030, including divisors that are
subnormal, zero or infinite, and for exponents that are not integers.
2026-10-23 22:59:39 -05:00
Chris Tate f986d76d3b Bound Brotli parameter names in error messages 2026-10-23 22:57:22 -05:00
Chris Tate 3dcd730841 Detect class cycles by class identity when inspecting static fields 2026-10-23 22:50:14 -05:00
Chris Tate d68a705975 Read a union's discriminant once in checked casts
A checked cast into a union whose discriminant has four or more string
literals reads the discriminant field once (scr_dyn_discriminant_case)
and then tests only the arms whose literal it holds and the arms without
a literal, in the union's arm order. Every other arm's literal test would
fail, so the arm chosen and the error for a value no arm matches are
unchanged. A typed capsule, an accessor or an inherited discriminant
still takes the tests arm by arm. Unions with fewer literals emit the
same code as before.
2026-10-23 22:31:08 -05:00
Chris Tate 260cf6e8c0 Answer builtin prototype reflection in untyped code as Node does (#2054) 2026-10-23 22:26:47 -05:00
Chris Tate 5c131cba35 Report dictionary copies of {} views, and keep method calls direct after writes into dictionaries of dictionaries (#1855) 2026-10-23 22:18:05 -05:00
Chris Tate 52e84ad3b4 Parse URL hosts and paths as the URL Standard does, and inspect URLs as Node does 2026-10-23 21:57:53 -05:00
Chris Tate c9346c1583 Merge main 2026-10-23 21:51:54 -05:00
Chris Tate 9031ddafe0 Merge main 2026-10-23 21:50:24 -05:00
Chris Tate 9e07382bcd Merge main 2026-10-23 21:48:59 -05:00
Chris Tate 1df99a8414 Convert checked-dynamic expected errors in assert.throws and assert.match (#2066) 2026-10-23 21:41:23 -05:00
Chris Tate e4079abd41 Keep swap under the test memory cap and continue past OOM kills 2026-10-23 21:39:03 -05:00
Chris Tate 43b0f29011 Guard direct calls after dot-property method writes through dictionary views 2026-10-23 21:34:14 -05:00
Chris Tate ee237c3276 Keep literal key order through self copies and conversions that build no records (#1982) 2026-10-23 21:21:37 -05:00
Chris Tate 61647a8e40 Read typed-array elements through non-null assertions as undefined where Node does
`t[i]!` on a typed array always took the numeric element read, which is NaN
for an index outside the array. Node reads undefined there, so `t[n]! ===
t[n]!` was false instead of true, `${t[n]!}` was "NaN", and `typeof t[n]!`
was "number".

`t[i]!` now takes the numeric read only where its use converts the value to
a number. Where the use tells undefined from NaN (an equality, a template
span, `+` with a string, a comparison with a string, `!`, `typeof`, an array
literal element, or an argument whose parameter admits undefined, such as
`Object.is` and `String`), it reads undefined for an invalid index, like
`t[i]`. Returns and plain bindings keep the numeric read.

Corpus 7394.
2026-10-23 21:20:57 -05:00
Malte UblandClaude Opus 5.5 995f345827 Record corpus 8115's CI cost
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 19:15:31 -07:00
Chris Tate 10e3476a55 Convert checked-dynamic expected errors in assert.throws and assert.match
An expected regex or string read from a JavaScript object literal's
field is a checked-dynamic value while its checker type is RegExp or
string. assert.throws chose its regex comparison from the checker type
and passed the value unconverted, an internal compiler error, and
assert.match and the expected-object form refused it. Such a value now
converts to the regex or string its type names.
2026-10-23 21:12:15 -05:00
Chris Tate 02aa5d4184 Keep the run-time result of overloaded calls with untyped arguments (#2064) 2026-10-23 21:00:49 -05:00
Chris Tate e59fdca0f4 Search TypedArrays, read stdin through 'readable', and assign constructor-function globals (#1974) 2026-10-23 20:57:24 -05:00
Chris Tate f9e9f3cb52 Keep an error's name and message where a JavaScript factory created them (#2055) 2026-10-23 20:55:51 -05:00
Chris Tate cecab7fc0f Keep null and undefined through non-null assertions into nullable destinations (#2050) 2026-10-23 20:48:03 -05:00
Chris Tate 0392a032c5 Merge main and fix the self-copy key order 2026-10-23 20:47:40 -05:00
Chris Tate 6dfde9919c Keep checked dictionary protocols and invalidate direct calls after method writes 2026-10-23 20:45:37 -05:00
Chris Tate 0f75f5b952 Keep the run-time result of overloaded calls with untyped arguments
The checker resolves an overloaded call whose argument is `any` to the
first overload that argument satisfies, but in JavaScript the value can
select another one: generateKeyPairSync("ec", options) returns KeyObjects
or PEM strings by the options, and digest(encoding) returns a Buffer when
the encoding is undefined. The result was converted to the first
overload's return type, so such calls threw a TypeError where Node
returns the other overload's value.

When a checked-dynamic argument could take another overload whose return
type differs (trailing untyped or undefined arguments may also be
absent), the call's result in a JavaScript source is checked-dynamic. So
are the unannotated bindings it initializes, destructured or not, and
the unannotated functions that return it. fs.globSync keeps choosing its
result form from the resolved overload, since the runtime checks that
withFileTypes agrees with it.
2026-10-23 20:31:12 -05:00