Commit Graph
459 Commits
Author SHA1 Message Date
Chris Tate 7e225c5d87 Merge main 2026-10-26 17:33:06 -05:00
Chris Tate 2f13edd058 Merge main 2026-10-26 11:36:06 -05:00
Malte Ubl 572e7e3eac Merge remote-tracking branch 'origin/lf/l4-expressions' into lf/l5-polish
# Conflicts:
#	packages/compiler/src/frontend/lowering/lowerer.ts
2026-10-26 05:37:00 -07:00
Chris Tate fe244085d4 Run native async generators as stackless coroutines
An async generator whose body suspends only at its own awaits and yields
now compiles to an LLVM switched coroutine, as async functions of that
kind already do, instead of running on a fiber with its own stack. Its
steps run on the stack that resumes it (the loop's after an await), its
awaits suspend through scr_coro_await_prepare and scr_coro_hop_prepare,
and its yields store OUT through scr_coro_yield_* before suspending.

- scr_async_gen_new_stackless creates the generator. The stackless hop
  settles an async generator's state as the fiber hop does, and a step
  that would start below the stack guard throws a RangeError, which
  rejects its request.
- Calling an async generator's next, return or throw no longer counts as
  parking the caller: they queue a request and run the body to its next
  suspension, which returns to the caller. Bodies that consume async
  generators can now be stackless too.
- An untyped await (async.awaitDyn) has a native coroutine form,
  extracted by scr_coro_await_dyn_value, so async bodies that await
  untyped values can be stackless.
- An async generator's return through a finally region takes its await
  turn through the coroutine when the body is one.

Debug builds, libraries, worker programs and Windows executables keep
fibers, as for stackless async functions.
2026-10-26 07:28:50 -05:00
Chris Tate b8aaa5985a Merge main 2026-10-26 05:23:00 -05:00
Chris Tate acf19e2652 Merge main 2026-10-26 02:53:26 -05:00
Chris Tate 21bce9e4fa Merge main 2026-10-26 00:21:24 -05:00
Malte UblandClaude Opus 5.5 1ae5f105ca Rank dynamic slots by their dynamic operations, name them in SC6101, and document them
Stage L5 of the localized-failure design.

- SC6101 names a dynamic slot as the cause of a likely-hot untyped function
  ('tool' is a dynamic slot, declared 'ToolDefinition', which does not
  compile).
- Coverage counts the dynamic operations each slot's values take part in,
  lists the costly slots first, and puts the count in the JSON envelope.
- A build whose only performance warnings are dynamic slots closes with a
  line about declared types instead of function types.
- Docs: a Dynamic slots section in the coverage guide, the limitations
  page bullet, and --fail-on=dynamic-slots in the CLI reference and usage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 19:48:18 -07:00
Chris Tate 80ae660be6 Merge main 2026-10-25 21:22:05 -05:00
Chris Tate 8981b5c0a2 Resolve computed createRequire specifiers at run time (#2079) 2026-10-25 20:29:51 -05:00
Chris Tate 5dfa62b9fc Merge main 2026-10-25 18:54:10 -05:00
Chris Tate 061202a844 Merge main 2026-10-25 18:51:28 -05:00
Chris Tate 30cf205e90 Run untyped pipeline function stages and later iterable stages
A pipeline stage that arrives as an untyped value now follows Node's
stage ladder for more shapes. As the first stage, a function is a source
function: the pipeline calls it with { signal } while it is set up and
pumps its result, which must be iterable (ERR_INVALID_RETURN_VALUE
otherwise), and a { readable, writable } pair pumps its readable side.

After the first stage, the pipeline call is lowered once per combination
of its first three untyped stages being functions or not, and a typeof
test picks the branch at run time. A function stage is called with the
previous stage and { signal }; before the last stage its result must be
async iterable, and as the last stage a promise resolves the pipeline's
value and an async iterable feeds the PassThrough pipeline() returns
(SCR_PIPE_DEST_DYN). Any other value that is not a stream becomes
Duplex.from of it, which the next stage reads from without the previous
stage being piped into it, and Duplex.from's ERR_INVALID_ARG_TYPE for
the values it rejects.

An untyped stage followed by an untyped function stage hands its value to
that stage through a cell created per pipeline call, so the function
receives the previous stage's own iterator, as Node's makeAsyncIterable
answers it, instead of an async generator over it.

Untyped web streams, pairs after the first stage, and function stages
that return a stream throw the not-supported error.

RUNTIME_ABI_VERSION goes from 45 to 46 for the new stream exports.
2026-10-25 18:10:32 -05:00
Chris Tate 27c00f6577 util: runtime format strings, inspect.custom and colors, untyped promisify (#1911) 2026-10-25 17:46:31 -05:00
Malte UblandClaude Opus 5.5 a2be7d8bc0 Answer Object.prototype's methods on typed records
Records inherit toString, toLocaleString, valueOf, hasOwnProperty,
isPrototypeOf and propertyIsEnumerable. Calls of these methods by name
run an own callable entry when the record's type allows one and the
record holds it, and otherwise the built-in with the record as receiver;
toLocaleString, valueOf and isPrototypeOf on records were refused, and
toString ignored an own entry. Keyed reads of records of functions answer
the built-in as a native function value when the key misses: bound to the
record when called at once, with an undefined `this` otherwise. The
backend fuses the read with its fallback, so hits cost nothing extra.
Records of other value types keep reading undefined for these names; the
limitations page says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 12:05:14 -07:00
Chris Tate 701173a2ae Read builtin globals through the global object, and support Node's navigator 2026-10-25 13:55:44 -05:00
Chris Tate 1b9a4e1361 Refuse SC9001 cases and merge main 2026-10-25 13:26:27 -05:00
Chris Tate eca815da02 Merge main 2026-10-25 10:55:32 -05:00
Chris Tate f0add87f10 Crypto parity: RSA key generation lengths, RSA-PSS keys and encrypted private keys (#2103) 2026-10-25 09:45:21 -05:00
Chris Tate 14fa2aedd3 Merge main 2026-10-25 08:28:00 -05:00
Chris Tate b7915b92a7 Merge main 2026-10-25 06:38:44 -05:00
Chris Tate 303bfcd922 Merge main 2026-10-25 05:25:41 -05:00
Chris Tate 5da6d76085 Run lone array callbacks as loops with their bodies inlined (#1997) 2026-10-25 05:24:07 -05:00
Chris Tate 0eef6251de Merge main 2026-10-25 02:28:32 -05:00
Chris Tate 5d3e0c7a8b Support X509Certificate fields and methods, TLS certificates and tls.Server contexts (#2052) 2026-10-25 01:00:24 -05:00
Chris Tate d775fdee8c Merge main 2026-10-24 23:26:30 -05:00
Chris Tate 90f0dd3dc5 Merge main 2026-10-24 21:09:40 -05:00
Chris Tate e3bda96fd1 Merge main 2026-10-24 20:31:45 -05:00
Chris Tate 03af6fb9ff Iterate classes with object-literal iterators and close them on early exits (#1860) 2026-10-24 20:30:36 -05:00
Chris Tate fc076258e4 Merge main 2026-10-24 20:07:16 -05:00
Chris Tate 97c3b04f73 Merge main and add the Node 24 util batch 2026-10-24 18:55:14 -05:00
Chris Tate d6c09279a7 Compile createRequire probes for optional addons as deferred refusals (#2015) 2026-10-24 18:41:05 -05:00
Chris Tate 9e55835014 Compile more npm and CommonJS JavaScript dependencies statically (#2122) 2026-10-24 18:30:56 -05:00
Chris Tate 6c18c58708 Merge main 2026-10-24 18:21:25 -05:00
Chris Tate 29e5bacb9c Pump untyped iterable pipeline sources (#2111) 2026-10-24 18:03:36 -05:00
Chris Tate 055c9ffa25 Evaluate the arguments of deferred require.resolve calls before they throw
Preflight admits a createRequire loader's require.resolve call with a
computed request inside a try block, but lowering refused the call, so
in JavaScript source the whole statement became a runtime fence. The
fence threw before the request expression ran, and before anything else
in the statement: `try { where = load.resolve(candidate(name)); }`
skipped candidate()'s side effects, so the catch clause saw a different
state than in Node.

Such calls (a computed request, another argument shape, or
runtime-computed options, on require.resolve and require.resolve.paths)
now evaluate their arguments in order and then throw the fence, as a
computed require call does. The addon-probe fixture checks that a
computed candidate path runs before each failed lookup.
2026-10-24 17:07:44 -05:00
Chris Tate 8d9705e22d Run CommonJS top-level return, untyped assert forms, and untyped instanceof Object as Node does (#2101) 2026-10-24 17:01:39 -05:00
Chris Tate c37963b8aa Let objects inherit from JavaScript class prototypes (#2078) 2026-10-24 16:58:49 -05:00
Chris Tate 6a8ba89d9f Make Dates mutable objects with Node's setters and conversions (#2072) 2026-10-24 16:21:06 -05:00
Chris Tate 4f0975cbbe Compile more npm and CommonJS JavaScript dependencies statically 2026-10-24 12:01:26 -05:00
Chris Tate 53baad4ebe Pump untyped iterable pipeline sources
A pipeline whose first stage is a checked-dynamic value now checks it at
run time, as Node's stage ladder does: a stream is piped as before, and a
string or a value with a Symbol.asyncIterator or Symbol.iterator method is
pumped into the next stage through an async generator over its iterator.
A typed Set, Map, generator or async generator object as the first stage
takes the same path. This covers the callback and stream/promises forms,
with or without function stages and pipeline options.

A write whose callback fails synchronously no longer sets needDrain, so no
'drain' follows the error and a pumped source stops at the failed write,
as in Node.

RUNTIME_ABI_VERSION goes from 37 to 42 for scr_stream_dyn_iterable_source.
2026-10-24 10:12:06 -05:00
Chris Tate e35621323d Trust no certificate for an empty ca in TLS clients
tls.connect, https.request and http2.connect verified the server against
the default CAs when ca was an empty Buffer, because the runtime read a
zero-length ca as none. The compiled calls now pass a null ca for none
(an omitted ca, or an empty string, which Node reads as no ca) and a
non-null one for any Buffer, and runtime option records read ca the same
way, so an empty Buffer or array trusts no certificate, as in Node. The
connection pool keys tell an empty ca from none. An empty array, which
threw, is an empty trust store too. A runtime-valued empty string ca in
http2.connect is refused instead of being read as an empty store.
2026-10-24 10:06:35 -05:00
Chris Tate 878f032886 Crypto parity: RSA key generation lengths, RSA-PSS keys and encrypted private keys 2026-10-24 08:35:30 -05:00
Chris Tate d9f1457cd5 Run CommonJS top-level return, untyped assert forms, and untyped instanceof Object as Node does 2026-10-24 08:07:52 -05:00
Chris Tate f23447dc99 Merge main 2026-10-24 06:50:53 -05:00
Chris Tate f505e8a044 Merge main 2026-10-24 06:49:45 -05:00
Chris Tate 76611d1151 Merge main 2026-10-24 06:49:23 -05:00
Chris Tate 702265e4ce Merge main 2026-10-24 06:48:58 -05:00
Chris Tate 1d5a7ff48a Merge main 2026-10-24 06:47:59 -05:00
Chris Tate ead125a5c5 Merge main 2026-10-24 06:47:32 -05:00