Commit Graph
3145 Commits
Author SHA1 Message Date
Chris Tate ddc7fe8b0d Store number-key map entries in 16 bytes and size the direct index near the largest key 2026-10-20 23:01:43 -05:00
Chris Tate 4dd62802c8 Bound loop counters compared as i + c with a bound (#1463) 2026-10-20 22:56:44 -05:00
Chris Tate 2783b96100 Round a loop bound to an integer before taking the counter's offset off it
- Narrowing `x + c < b` and its other comparison forms subtracted the offset from the bound in floating point. A fractional bound could then round across an integer: `x + 2147483648 > -(2 ** -60)` gave the minimum -2147483647, which leaves out -2147483648. The bound now rounds to an integer first, and the offset comes off in exact integer arithmetic. Integer bounds give the same facts as before.
- A unit test covers that comparison.
2026-10-20 22:54:32 -05:00
Chris Tate f31b97ee64 Pin the zone-offset cache's answers across a double offset change to Node's
- The zone-offset cache keeps an offset over 19 days when both ends agree, as V8's date cache does. America/Argentina/Tucuman changed its offset twice within 12 days in June 2004, so in Node the answers between the two changes depend on the order of the reads: ascending reads keep the May offset through June 12, and descending reads see the June offset.
- The cache's comment now states that behavior, and corpus date-zone-intervals.ts reads those days in both orders. Its output matches Node for each order.
2026-10-20 22:32:08 -05:00
Chris Tate 43f1c445e8 Keep counters a for loop bounds in integer shadows (#1491) 2026-10-20 22:31:47 -05:00
Chris Tate 6bf550e11f Treat bindings a for loop's condition or update writes as unbounded
- The bounded-loop analysis collected writes from the loop body only. A binding the condition writes (`i < ((source = values[i]), values).length`) then passed as stable, so a cursor copied from it took the source's entry range, and its integer shadow truncated fractional values. The condition and the update are now scanned too, and a binding either one writes is neither a stable bound nor a copy source.
- Corpus 5686 adds a copy whose source the condition writes with fractional values.
2026-10-20 22:29:56 -05:00
Chris Tate b602cdc76e Start small arrays with three inline slots 2026-10-20 22:01:41 -05:00
Chris Tate e5af4def98 Promisify untyped functions at run time (#1502) 2026-10-20 21:54:51 -05:00
Chris Tate 012fdb3fb0 Merge main 2026-10-20 21:52:19 -05:00
Chris Tate 69ef7da7f8 Run death-triggered full collections at the event loop's idle moments (#1522) 2026-10-20 21:48:02 -05:00
Chris Tate 44c586b1ee Run a waiting death pass at the idle moment even after the heap shrank 2026-10-20 21:44:46 -05:00
Chris Tate 24eb054395 Compile the hot-shots StatsD client over UDP (#1568) 2026-10-20 21:29:48 -05:00
Chris Tate b811317f26 Keep String method arguments read before another argument's conversion runs
concat, substr and the other typed String and Number extra methods
convert their arguments after evaluating all of them. When an argument's
conversion can run program code (an object's toString or valueOf), a
variable read of the receiver or another argument is now kept in a local
as well, so a conversion that assigns the variable leaves the
already-evaluated argument unchanged, as in Node.
2026-10-20 21:22:29 -05:00
Chris Tate bde7afa980 Compile undici from a built-in implementation (#1425) 2026-10-20 21:14:37 -05:00
Chris Tate d59d8ff6f2 Merge main and count declaration writes to parameters 2026-10-20 21:05:19 -05:00
Chris Tate eb8a148605 Merge main 2026-10-20 21:01:40 -05:00
Chris Tate 53171c282d Read and write dynamic-tier properties through shapes and inline caches (#1396) 2026-10-20 20:52:12 -05:00
Chris Tate 70e0af8094 Keep shapes off objects that threads share
A published graph is immortal and shared by pointer across threads, but a
shape names a node of one thread's transition tree, which ends with that
thread. A worker that read a published object through a cache left its
shape in the object; after the worker exited, the main thread's reads
followed it into freed memory. Immortal objects now stay unshaped, and
publishing (postMessage's shared graphs and @scriptc/threads publish)
clears a shape the object already has.
2026-10-20 20:44:14 -05:00
Malte UblandClaude Opus 5.5 3b4ddd4c8d Keep object literals' key order through IR rewrites and on shapes typed JSON.parse also builds
The key-order witness pass chose a shape's enumeration table from the
order its object literals write their keys, but two gaps sent literal
values back to the declaration order (JSON.stringify, Object.keys and
inspect then differed from Node, silently):

- Witness notes are keyed by node identity, and frontend passes that run
  before the witness pass (the caught-value dispatch, the class dynamic
  dispatch) rebuild whole function bodies through mapExprChildren, so
  every record literal in such a function became an unnoted construction
  that pins its shape. The mapper now reports rebuilt record literals to
  an observer, and the notes follow them to the rebuilt node.
- A shape a checked conversion (typed JSON.parse) also builds stayed
  pinned to today's table even when the program's own literals build it
  in another order, such as a message sent to a child and parsed back. It
  now takes its literals' order; parsed values in another order keep
  their own through the record-source view, and a shape only checked
  conversions build keeps today's table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:34:38 -07:00
Chris Tate 94aa7065f1 Compile the remaining corpus programs with the native compiler (#1418) 2026-10-20 20:29:41 -05:00
Malte UblandClaude Opus 5.5 da13375a8b Keep properties JavaScript adds to a child process, and await it as a thenable
execa 5 mixes then/catch/finally into a real ChildProcess with
Reflect.defineProperty, replaces kill and adds cancel by assignment, and
awaits the child.

- A new optional runtime unit, scr_dyn_handle_props.c, keeps those
  properties in a side table keyed by the native child. Wrapper ops for
  the child tag look there first for reads, member calls and writes.
  defineProperty and getOwnPropertyDescriptor use it, and await adopts a
  child with a callable then. Class methods read as values call the
  class's own method.
- In JavaScript files, writes onto typed children, reads and calls of
  added names, method values for bind/call/apply, and members no typed
  lowering claims go through the child's checked-dynamic box.
- Only programs whose JavaScript adds properties to children link the
  unit and install the table; everything else compiles as before.
- A setTimeout delay that may be a boolean converts with ToNumber, and
  `if (t.unref)` over a timer handle folds to true (execa's lib/kill.js).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:28:00 -07:00
Chris Tate 6e278b8487 Name the spread expression in not-iterable errors for values held as any (#1587) 2026-10-20 20:25:52 -05:00
Malte UblandClaude Opus 5.5 3a27a92cb4 Forward at most four emit arguments through EventEmitter method values
The dispatch instantiates one bridged emit per argument count and emitter
class; capping it at four keeps programs that only read emitter members
through computed keys from growing by the full table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 18:22:43 -07:00
Chris Tate 5a1882957d Convert Promise and record results and record arguments in function adapters (#1556) 2026-10-20 20:21:38 -05:00
Chris Tate 81bc045524 Spin briefly before a mailbox wait blocks, and signal after the unlock (#1400) 2026-10-20 20:20:14 -05:00
Chris Tate 08c7930958 Support crypto.createECDH and ECDH.convertKey (#1589) 2026-10-20 20:18:22 -05:00
Chris Tate 7ccd9fb3ac Name functions stored in JavaScript object literals as Node (#1591) 2026-10-20 20:17:19 -05:00
Chris Tate f32c309baa Declare function adapter scratch locals in the adapter
A function value whose result is a union of records, assigned to a slot
that returns one record type, lifts each record arm into the slot's
record. The lift declares a scratch local, which went into the function
that requested the adapter, so calling the adapted function failed IR
validation. The adapter body now lowers in its own function context and
the adapter declares those locals.
2026-10-20 20:16:46 -05:00
Chris Tate fae56ff409 Run exec on regular expressions held as any (#1600) 2026-10-20 20:16:04 -05:00
Chris Tate b04166a8f0 Read runtime keys of package enum objects as checked-dynamic values
The enum rewrite turns a package's numeric enum into one object holding
its names and its reverse mapping, so the object's fields have different
types. A reverse read with a runtime key, such as
DiagLogLevel[DiagLogLevel.WARN] in @opentelemetry/api, then failed with
SC1090 ("the declared fields have no one common type").

A keyed read of such a record already answers a checked-dynamic value in
JavaScript files. It now does the same where the checker types the read
'any'. The new npm case tsc-enum-reverse-reads matches Node, as does the
opentelemetry-api case again.
2026-10-20 20:04:06 -05:00
Chris Tate 904b773d0a Adopt thenables in await of untyped values, and read Promise.prototype as a value (#1562) 2026-10-20 19:58:53 -05:00
Chris Tate 4e80351f87 Merge main 2026-10-20 19:53:23 -05:00
Chris Tate aec7758dfb Revert the checked-cast fallback (#1561); keep the optional-chain fix (#1601) 2026-10-20 19:46:23 -05:00
Chris Tate ca379c5d14 Run exec on regular expressions held as any
exec on a regular expression held as an untyped value threw "Native RegExp
method has no lowering". It now returns Node's match array: the captures,
with undefined for one that did not participate, then index, input and
groups, or null without a match. Global and sticky expressions read and
advance lastIndex and reset it when nothing matches, as the typed exec
does.
2026-10-20 19:38:31 -05:00
Malte UblandClaude Opus 5.5 ce6be86afb Await each value of for await over an untyped array
A JavaScript array literal that mixes promises and plain values lowers as
a checked-dynamic value, and for await over it took the synchronous
iteration path, binding the promises themselves. It now takes the async
mode of the checked-dynamic loop, which awaits each value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:37:15 -07:00
Chris Tate dffefb4120 Keep missing runtime-key entries undefined in parameter patterns
- The indexed-read prepass now scans parameter patterns with the parameter's type. A function that destructures a missing runtime-key entry of an index-signature record from a parameter (`function pick(k, { [k]: v }: Record<string, number>) { return v; }`) returns undefined instead of throwing a TypeError, nested patterns included.
- Corpus 6492 adds a function, an arrow and a nested parameter pattern; 6492 and 6493 get their per-program cost files.
2026-10-20 19:37:06 -05:00
Malte UblandClaude Opus 5.5 22b9db26b5 Short-circuit optional chains on any values only on the guarded step
`a?.b.c` on an `any` value answered undefined when `a` was present and
`a.b` undefined: every later step of the chain read optionally. Node
short-circuits only on the guarded receiver and throws reading `.c`.

An `any` receiver now makes the tail an optional chain like a dyn one,
and inside the chain's guarded body the consumed `?.` no longer marks
the later dynamic reads optional. (Kept from #1561, whose checked-cast
fallback is reverted.)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:36:52 -07:00
Malte UblandClaude Opus 5.5 0cf62ebecf Answer EventEmitter methods read as values off compiled emitters
Reading an EventEmitter.prototype method off a compiled emitter (a program
class extending EventEmitter, or new EventEmitter()) through an untyped
value answered undefined (`typeof o.on`, `const f = o.on; f.call(o, ...)`,
`o.emit.bind(o)`), and EventEmitter.prototype.on in JavaScript was a fence.

Such reads, typed value reads, computed keys, `in`, and
EventEmitter.prototype.<method> now answer the runtime's
EventEmitter.prototype functions, the ones constructor-function emitters
inherit, so `o.on === o.addListener === EventEmitter.prototype.on` and
names and lengths match Node. The first read installs a program dispatch
that those functions call for a compiled emitter receiver; it invokes the
method through the existing untyped dispatch with the call's argument
count (emit forwards up to 16 arguments after the name, then fences).

An untyped emit on, or read of emit from, a class that overrides emit now
fences instead of bypassing the override for the native emit. A subclass
visited under the boxed EventEmitter capsule keeps its own dispatch plan
for values boxed as itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 17:36:37 -07:00
Chris Tate 1f4f7d822f Merge main 2026-10-20 19:27:58 -05:00
Chris Tate c812518fb3 Merge main 2026-10-20 19:24:28 -05:00
Chris Tate 35c48c93a6 Name functions stored in JavaScript object literals as Node does
A function stored in a JavaScript object literal's property printed as
[Function (anonymous)] and had an empty `.name`. The property's boxed
function now takes the name Node gives it: a function read by name keeps
that name (`{ f }`, `{ k: f }`), and an anonymous function, arrow or method
takes the property's key (`{ g: function () {} }`, `{ m() {} }`,
`{ 'a-b': () => 1 }`, a computed key that folds to one string).
2026-10-20 19:23:31 -05:00
Chris Tate eac75404d5 Merge main 2026-10-20 19:19:07 -05:00
Chris Tate 2582e46e76 Support crypto.createECDH and ECDH.convertKey
crypto.createECDH returns a native ECDH handle backed by mbedTLS for
prime192v1, secp224r1, prime256v1, secp384r1, secp521r1, secp192k1,
secp224k1, secp256k1, brainpoolP256r1, brainpoolP384r1 and
brainpoolP512r1. generateKeys, computeSecret, getPublicKey,
getPrivateKey, setPrivateKey, setPublicKey and ECDH.convertKey follow
Node 24: compressed, uncompressed and hybrid points, input and output
encodings, the private key range, key pair validation, and Node's error
codes and messages.

Curve names follow OpenSSL's short-name lookup: names of other curves
from crypto.getCurves() are refused at compile time when literal and
throw a coded SC2020 error when computed, other OpenSSL short names
throw ERR_CRYPTO_OPERATION_FAILED, and unknown names throw
ERR_CRYPTO_INVALID_CURVE. Calls whose arguments no @types/node overload
accepts, and computeSecret(view, encoding), are refused at compile time.

The runtime unit scr_ecdh.c links, with the mbedTLS archive, only into
programs that use ECDH. wasm32-wasi builds refuse it.
2026-10-20 19:17:05 -05:00
Chris Tate f63e99a7de Name the spread expression in not-iterable errors for values held as any
Spreading a value held as any that is not iterable into an array literal
threw `TypeError: value`. It now throws V8's message, which names the
spread expression: `x is not iterable` for an identifier or property path,
through parentheses and type assertions, and `f is not a function or its
return value is not iterable` for a call of one. for...of and array spread
share the helper that spells it.
2026-10-20 19:10:56 -05:00
Chris Tate 222ea51bd8 Keep missing runtime-key entries undefined in nested module-scope patterns
- The indexed-read prepass now visits nested object patterns with the nested element's own type. A module-scope binding from a missing runtime-key entry of a nested index-signature record (`const { limits: { [key]: limit } } = config`) holds undefined instead of throwing a TypeError, with or without a default for the nested source.
- Corpus 6492 adds both nested forms.
2026-10-20 19:09:12 -05:00
Chris Tate 50f93d0be0 Merge main 2026-10-20 19:05:22 -05:00
Chris Tate f7e8d7c490 Compile import cycles whose class is reached only after initialization (#1495) 2026-10-20 18:55:01 -05:00
Chris Tate 4a90c59cf3 Await a synchronous iterator's final value in for await
for await over a synchronous iterator held as any reads and awaits the value
of the result that finishes the loop, as the async-from-sync iterator does, so
a throwing value getter or a rejected promise there rejects the loop.
2026-10-20 18:49:56 -05:00
Chris Tate e41f642a55 Compile literal-key 'in' over index-signature records, fresh array spread insertions, and any-annotated dictionaries (#1514) 2026-10-20 18:46:29 -05:00
Chris Tate 145268ed55 Inspect program-declared Error subclasses with Node's constructor-name header (#1520) 2026-10-20 18:43:16 -05:00