4611 Commits
Author SHA1 Message Date
Chris Tate f5972b0e75 Prepare v0.4.4 release (#2065) v0.4.4 2026-10-23 23:20:41 -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 cc4428ad1e Keep int32 class fields beside Buffer.from over an ArrayBuffer range (#2070) 2026-10-23 23:02:51 -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 9e07382bcd Merge main 2026-10-23 21:48:59 -05:00
Chris Tate 96dbc6204f Keep int32 class fields beside Buffer.from over an ArrayBuffer range
Buffer.from(arrayBuffer, byteOffset[, length]) lowers to
buffer.poolFromDynRange with its operands as checked values. The int32
slot analysis treats any runtime helper with a checked-value argument
as a possible store into a live class instance unless the helper is
listed as read-only, so one such call dropped every int32 class field
fact in the program (tsc-ts's scanner makes one).

buffer.poolFromDynRange and buffer.poolFromDynOffset read their
operands (the ArrayBuffer's view after Node's offset and length
conversions, or a copy of a string's, array-like's or typed array's
values) and store into no class instance, so they join DYN_READ_ONLY.
2026-10-23 21:48:25 -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 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 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 a294403acd Version while loops only for accesses at their counters (#2056) 2026-10-23 21:02:55 -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 7784800c8e Prepare v0.4.4 release 2026-10-23 20:51:00 -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
Chris Tate a5db27a5a7 Merge main and fix the review comments 2026-10-23 20:24:35 -05:00
Chris Tate e813250813 Keep a constructor's name ahead of later properties in the runtime fallback 2026-10-23 20:22:14 -05:00
Chris Tate b2e609d73e Merge main 2026-10-23 20:20:34 -05:00
Chris Tate 01e802ff9d Box JavaScript class instances at their exact class (#2047) 2026-10-23 20:18:12 -05:00
Chris Tate d06e6ab0a5 Keep checked narrowing for optional standard library parameters, and merge main 2026-10-23 20:11:11 -05:00
Chris Tate e9833e3260 Add --target-cpu for x86-64 microarchitecture levels (#2025) 2026-10-23 20:00:33 -05:00
Chris Tate 1af3a86370 Compile unions of typed-array classes (#2011) 2026-10-23 20:00:12 -05:00
Chris Tate 37df3c4dfd Support split CommonJS require bindings (#1945) 2026-10-23 19:50:13 -05:00
Chris Tate 9ab731bf66 Version while loops only for accesses at their counters
A while loop over typed arrays also versioned when its only checks were
thread-owned receivers or static indices. A worker's job loop such as
`while ((job = Atomics.load(next, 0)) < count) { ...; run(job) }` then
got a second copy whose guard fails whenever the array is shared, and
the doubled call kept the job function from being inlined. A while loop
now versions only when it has an access at one of its counters. Other
while loops compile as they did before they could version.
2026-10-23 19:42:52 -05:00
Malte UblandClaude Opus 5.5 c9f1f95d5b Box JavaScript class instances at their exact class
A class instance converted to an untyped value was boxed in a capsule of
its static class. Before any member table read it,
%dyn.class.normalize tested it against each subclass and boxed it again
at the instance's own class: two capsules per crossing for every value
of a class with subclasses, and the subclass tests on every member read.

After the dispatch tables settle, each conversion of a value whose static
JavaScript class has a normalization branch now calls
%dyn.class.boxExact:<Class>, which runs the same subclass tests in the
same order once, at the conversion. The capsule is created at the exact
class, and normalization falls through for it. TypeScript hierarchies,
classes that are never boxed, and hierarchies without subclasses are
untouched.

zod 3, z.array(Order).parse over 500 orders: 178.5M -> 174.4M
instructions per round (-2.3%).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 17:41:28 -07:00
Chris Tate a4e7a03761 Address review comments 2026-10-23 19:37:04 -05:00
Chris Tate 3a613c31a8 Merge main 2026-10-23 19:33:44 -05:00
Chris Tate d56a884011 Merge main 2026-10-23 19:28:30 -05:00
Chris Tate 4206155ac9 Convert non-null asserted operands that hold undefined or null as Node does (#2049) 2026-10-23 19:25:15 -05:00
Chris Tate cc325de274 Merge main 2026-10-23 19:24:16 -05:00
Chris Tate bf68b3860c Skip split require calls by identity and climb parentheses in early-read checks 2026-10-23 19:05:58 -05:00
Chris Tate fbaf51c032 Decide string or number concatenation at run time for untyped partners 2026-10-23 18:53:36 -05:00
Chris Tate 9adb9692cd Accept file URL paths in existsSync and fs.promises (#2042) 2026-10-23 18:47:49 -05:00
Malte UblandClaude Opus 5.5 f896786ef4 Give the zod4-record npm case the zod 4 cases' timeout
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:42:23 -07:00
Malte UblandClaude Opus 5.5 e81c9ddaa4 Give the hono-zod-default-hook npm case the zod 4 cases' timeout
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:42:19 -07:00
Malte UblandClaude Opus 5.5 09f0342641 Keep an error's name and message where a JavaScript factory created them
zValidator's default failure hook serializes zod 4's ZodError with
`name` after `message` natively, and with the first `name` zod's factory
assigns ("$ZodError") when the second assignment took the typed slot.
ZodError instances are views of a JavaScript class extending Error: each
view rebuilds `message` and `name` from the error slots at fixed
positions (after `stack`, and after every other property), and the
property bag that holds the dynamically added properties copied its
committed, possibly stale, values over them.

A JavaScript Error subclass with a property bag now marks its class
(errorBagOrder), and its view calls scr_error_dyn_follow_bag after the
bag is copied: `name` and `message` move to follow the property they
followed when the bag was committed, and data values come from the
slots. TypeScript classes keep their views.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:40:35 -07:00
Malte UblandClaude Opus 5.5 17721bae55 Answer builtin prototype reflection in untyped code as Node does
zod 4's z.record rejected every plain object natively ("expected record,
received object"): its isPlainObject reads o.constructor.prototype, which
was undefined, and asks whether that prototype has its own isPrototypeOf,
which Object.prototype answered false.

- The Object, Array and Error constructors held as values have their
  builtin prototype as a non-writable, non-enumerable, non-configurable
  own `prototype`; reading Function's constructor value's prototype
  throws SC2020 instead of answering undefined.
- hasOwnProperty / Object.hasOwn on Object.prototype answer its builtin
  members, and on Array.prototype its constructor;
  Object.getOwnPropertyNames lists them in Node's order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:40:07 -07:00
Chris Tate 6dace8e40b Compare and index with the integer beside a sum's double (#2040) 2026-10-23 18:34:30 -05:00
Chris Tate 6b1a56a49a Check target CPU levels in the native CLI and honor them for assembly and object builds 2026-10-23 18:26:12 -05:00
Malte UblandClaude Opus 5.5 0dfea3c642 Reject class capsules of other classes without materializing them
A dynMatch helper for a class target tested the capsule's class key and,
when it did not match, materialized the capsule's view and matched that.
A materialized view is a plain object, which never matches a class target,
so the answer was always false: the helper now answers false directly.
Checked casts from unknown to unions of classes no longer build a view per
non-matching arm (1,000 casts x 2,000 rounds: 255 ms -> 67 ms).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:20:16 -07:00
Chris Tate 79feeb9a56 Store the frontend cache's LLVM placeholder as an empty array (#2051) 2026-10-23 18:19:25 -05:00
Chris Tate b7f86b9bb5 Run TypedArray methods on typed arrays held as untyped values (#2043) 2026-10-23 18:14:18 -05:00
Chris Tate 3e73eee0c4 Evaluate fs.promises URL arguments once and fence the new fs entries 2026-10-23 18:12:45 -05:00
Chris Tate 39bb8a5b7e Require integer views to stay below 2^53 exactly, and fix corpus 1420 2026-10-23 18:05:10 -05:00
Chris Tate 5a4935ed9e Settle Promise.all over different entry types on Node's turns (#1843) 2026-10-23 17:49:52 -05:00