Commit Graph
5555 Commits
Author SHA1 Message Date
Malte UblandClaude Opus 5.5 3ea7031ea1 Merge the ASan fix for nested entries on macOS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 13:34:29 -07:00
Malte UblandClaude Opus 5.5 6748313cba Unpoison a nested entry's ending frame for ASan on macOS
The nested trampoline never returns (setcontext back), so the redzones
around its locals stayed poisoned in the shadow of Node's stack, and
Node's own frames tripped over them later (stack-buffer-underflow in
__bzero, sanitized corpus 6822/6823/6831/6832/6894 on macOS). Linux's
ASan clears a context's stack in its swapcontext interceptor; macOS's has
none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 13:34:14 -07:00
Malte UblandClaude Opus 5.5 704e6b4992 Merge the macOS island fixes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:50:41 -07:00
Malte UblandClaude Opus 5.5 bfbbd349a3 Merge the macOS island fixes, and make nested entries' contexts the same way
A nested entry below the mark makes its context with ni_make_context,
so macOS clears only the top slice of the range instead of the whole of
Node's stack below the mark on every nested call (17 ms per call, and
the cross-heap GC test ran past its timeout).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:50:40 -07:00
Malte UblandClaude Opus 5.5 1d915b0c04 Merge ni/3-hosted-loop
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:50:40 -07:00
Malte UblandClaude Opus 5.5 50385349d3 Merge the macOS island fixes of ni/13-libnode-packs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:50:39 -07:00
Malte UblandClaude Opus 5.5 b1005549c3 Merge the macOS island fixes of ni/1-libnode-loader
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:50:39 -07:00
Malte UblandClaude Opus 5.5 5f3e97998d Merge the macOS island fixes of ni/1-libnode-loader
The libnode-linux action becomes .github/actions/libnode, which serves
the Linux x64 and macOS lanes: the libnode-packs cache for the runner's
platform, else the development pack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:50:39 -07:00
Malte UblandClaude Opus 5.5 df869f28b0 Run Node islands on macOS, and test them in the macOS CI lanes
macOS binds libnode's own calls to v8::base::Stack inside libnode, so the
bridge's definitions cannot give V8 Node's stack as they do on Linux; V8
took the main thread's stack start and its conservative scan faulted in
the gap above Node's stack. While Node starts on its stack, the main
thread's pthread record now names that stack, which V8 reads once and
keeps.

macOS's makecontext clears the whole stack it is given, so it gets only
the top slice of Node's stack (no 64 MiB pass per context).

CI: dev-pack.json pins mirrored darwin-arm64 and darwin-x64 libnode
builds of the pinned Node 24.22.0 from the libnode-packs workflow, the
dev-pack action serves either platform, and the macOS lanes provision it,
so island tests fail rather than skip on macOS CI. The arm64 LLVM job
runs the island harness; the Intel job runs it and the island corpus.
bridge-smoke loads the .dylib bridge on macOS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 12:50:38 -07:00
Chris Tate b0a559e6c9 Address review feedback 2026-10-26 13:25:42 -05:00
Malte Ubl 39a125ec38 Move the Node island handle tag to 84
Main's navigator global took tag 83.
2026-10-26 11:25:16 -07:00
Malte Ubl 3a5aab5b2f Merge remote-tracking branch 'origin/ni/i1-stack-bound' into HEAD
# Conflicts:
#	packages/compiler/src/cli/command.ts
#	packages/compiler/src/executable/executable-cache.ts
#	packages/compiler/src/frontend/lowering/builtins/module-resolution.ts
#	packages/compiler/src/frontend/lowering/lowerer.ts
#	packages/compiler/src/index.ts
#	packages/runtime/src/scr_json.c
#	tests/harness/npm.test.ts
2026-10-26 11:22:14 -07:00
Malte Ubl f5b1e5f007 Merge remote-tracking branch 'origin/ni/islands-base' into HEAD
# Conflicts:
#	packages/compiler/src/diagnostics/diagnostic.ts
#	packages/compiler/src/node-islands/libnode-pack.ts
#	packages/libnode-darwin-arm64/package.json
#	packages/libnode-darwin-x64/package.json
#	packages/libnode-linux-arm64-gnu/package.json
#	packages/libnode-linux-x64-gnu/package.json
#	packages/node/package.json
2026-10-26 11:20:55 -07:00
Malte Ubl b3e29df342 Merge remote-tracking branch 'origin/ni/13-libnode-packs' into HEAD
# Conflicts:
#	packages/cli/src/bootstrap.ts
#	packages/compiler/src/node-islands/libnode.ts
#	packages/libnode-common/smoke/smoke.c
2026-10-26 11:18:28 -07:00
Malte Ubl ae66edf566 Merge remote-tracking branch 'origin/ni/3-hosted-loop' into HEAD
# Conflicts:
#	packages/cli/src/bootstrap.ts
#	packages/compiler/src/diagnostics/diagnostic.ts
#	packages/compiler/src/node-islands/libnode.ts
2026-10-26 11:17:30 -07:00
Malte Ubl 141279b74c Merge remote-tracking branch 'origin/ni/1-libnode-loader' into ni/13-libnode-packs 2026-10-26 11:15:43 -07:00
Malte Ubl c088613033 Merge remote-tracking branch 'origin/ni/1-libnode-loader' into ni/3-hosted-loop 2026-10-26 11:15:41 -07:00
Malte Ubl 5817be4d0f Merge remote-tracking branch 'origin/main' into ni/1-libnode-loader
# Conflicts:
#	packages/compiler/src/diagnostics/diagnostic.ts
#	packages/compiler/src/ir/function-references.test.ts
2026-10-26 11:08:44 -07:00
Chris Tate 58197ed89d Close the largest canonical-mapping gaps the shadow census found (#2340) 2026-10-26 12:42:03 -05:00
Chris Tate 9b4a6ffdf1 Regenerate the IR field readers for dynCheck's inferred site (#2347) 2026-10-26 12:08:27 -05:00
Chris Tate 5b29eb1bae Merge main 2026-10-26 12:07:21 -05:00
Chris Tate 91014dfb66 Read TypeScript 7.1's binary AST format beside 7.0's (#2346) 2026-10-26 11:59:28 -05:00
Chris Tate 34c2f9851d Have the native CLI packages depend on their LLVM helper and runtime pack (#2333) 2026-10-26 11:47:34 -05:00
Chris Tate 6dbdf39120 Track a stream's 'data' listeners instead of looking them up per chunk (#2344) 2026-10-26 11:38:04 -05:00
Chris Tate 341ddd41ae Regenerate the IR field readers for dynCheck's inferred site 2026-10-26 11:34:57 -05:00
Chris Tate de6cdf1156 Add the shape overlay: typed JavaScript from analysis-proven facts (opt-in) (#2176) 2026-10-26 11:33:47 -05:00
Chris Tate ce1f3c4d2b Read TypeScript 7.1's binary AST format beside 7.0's
The AST reader accepts protocol 9, TypeScript 7.1's encoding, as well as
protocol 5 (7.0's), so scriptc can read either checker's responses:

- the 64-byte header of protocol 9;
- its node kinds, which count 7.1's SourceKeyword: each kind above it
  reads as 7.0's, and node handles name the response's own kinds;
- a module declaration's child mask, whose attributes slot moves the
  body to slot 3.

A protocol 9 response with a node 7.0 has no form for (a SourceKeyword
node, import attributes on a module declaration, or an `import source`
clause) throws an AstDecodeError that names it.
2026-10-26 11:27:36 -05:00
Chris Tate a5971450ec Tear down self-recursive records and classes in one loop (#2343) 2026-10-26 11:14:35 -05:00
Chris Tate b1b6b98c0d Compare canonical mapping with mapType in an opt-in shadow mode (#2334) 2026-10-26 11:03:38 -05:00
Chris Tate cc5c81fb4d Keep frontend snapshots stable when a file is read before and after it settles (#2342) 2026-10-26 11:02:20 -05:00
Chris Tate e7f3ab29c2 Track a stream's 'data' listeners instead of looking them up per chunk
Each chunk a readable side delivered looked up its 'data' listeners by
name twice: once to decide whether a flowing stream emits directly, and
again in emit('data'), which scans the stream's event names even when a
piped stream has no 'data' listener at all. The stream now keeps a
data_listeners flag, set from the emitter registry's empty/nonempty
transitions through scr_emitter_observe, and reads it on those paths;
emit('data') is skipped when the stream has no 'data' listener.
2026-10-26 10:59:32 -05:00
Chris Tate fbd82745e3 Merge the island stack base 2026-10-26 10:58:36 -05:00
Chris Tate 09a73ab6ed Fix Array.prototype calls on native arrays, typeof on ambient names, and net connections to Unix sockets (#2326) 2026-10-26 10:56:58 -05:00
Chris Tate 6e4fdf95d0 Link the exported bootstrap package's helper and runtime pack dependencies
The native bootstrap's package checks copy the seed's distribution into a
package directory outside the workspace and, since the CLI packages depend
on their LLVM helper and runtime pack, drop the bundled copies. Nothing in
that directory resolved @scriptc/llvm-linux-x64-gnu, so
verify-native-cli.mjs failed with 'Cannot find module'. The test now links
both packages into the directory's node_modules, as pnpm links a workspace
package's dependencies.
2026-10-26 10:56:27 -05:00
Chris Tate 36273adc8f Unroll counted loops by the period of a guard on the counter's low bits (#2341) 2026-10-26 10:56:09 -05:00
Chris Tate d5dc896576 Merge main 2026-10-26 10:53:46 -05:00
Chris Tate 48c521dc27 Address review feedback 2026-10-26 10:43:59 -05:00
Chris Tate 9b96314c20 Tear down self-recursive records and classes in one loop
The teardown of a type with children of its own type called itself for
each child: a call, its register saves and the segment bookkeeping per
node, 45 instructions per node in a binary tree.

A record or standalone class whose every reference field holds its own
type and that has no collector header now tears down in one loop. A child
whose last reference the dead node held goes onto a pending list linked
through its own count word, which it no longer needs, and the loop takes
the list's first node next, so nodes are visited parent first. Each node
frees its block as before (dispose observers, the RC audit, blocks of
other arenas), the calling thread's blocks go into the teardown segment
in visit order, and the segment goes onto the free list in one step, so a
structure built parent first takes the blocks in its allocation order.
Shared and immortal children keep their release. The loop needs no depth
budget. Other teardowns keep the recursive form.
2026-10-26 10:42:41 -05:00
Chris Tate dec2b8a454 Record one probe for two reads of a file that saw the same content
A read within IDENTITY_SETTLE_MS of a file's last write records no
identity, and a later read of the same bytes in the same frontend does.
FrontendInputTracker.record compared the two probes as JSON and marked
the snapshot unstable. A build or coverage run that read its entry
before and after that point then published no cache entry: the exact
repeat of a build lowered again, and a coverage verdict was not replayed.
Two file probes with the same digest now merge into one that keeps the
settled identity; any other difference still marks the snapshot
unstable.
2026-10-26 10:33:02 -05:00
Chris Tate 6fa88c7243 Observe every top-level mapping in the canonical shadow 2026-10-26 10:32:41 -05:00
Chris Tate 928c30e908 Bind thisArg in the array callback methods of dynamic arrays
forEach, map, filter, some, every, find, findIndex, findLast,
findLastIndex and flatMap on a dynamic array, and through
Array.prototype.<method>.call on a native array, called the callback
without its thisArg, so `this` in the callback was not the second
argument. These methods now bind `this` to the thisArg, or undefined
when there is none, once per call, around all of the method's callbacks.
2026-10-26 10:19:57 -05:00
Chris Tate be293e3dfb Unroll counted loops by the period of a guard on the counter's low bits
A counted loop whose body branches on `(i & M) === C`, with M one of 1, 3
and 7 (a check every second, fourth or eighth iteration), now asks LLVM to
unroll it by M + 1 (llvm.loop.unroll.count on its back edge). In each
unrolled copy the counter's low bits are known, so the guard folds to a
constant and only one copy per period keeps the check. Before, LLVM tested
the guard on every iteration and, when the guarded condition was cheap,
evaluated that condition on every iteration too.

The loop must step by 1 from a multiple of the period, have no nested
loop, and stay under 4096 IR nodes once unrolled. Loops with the same
period share one loop ID node, which the module emits only when a back
edge refers to it.
2026-10-26 10:19:25 -05:00
Chris Tate 0b12340ead Merge the libnode loader and mark e04 as a race 2026-10-26 10:18:44 -05:00
Chris Tate 26b2fdcc67 Read IR nodes' fields by name in three llvm-emit passes (#2336) 2026-10-26 10:17:48 -05:00
Chris Tate 1947bf66c7 Release a substitution's operands when it returns (#2337) 2026-10-26 10:17:28 -05:00
Chris Tate c1ad72e1a4 Build the candidate's own compiler source in the zero-cost gate (#2339) 2026-10-26 10:15:57 -05:00
Malte UblandClaude Opus 5.5 812aa3a7bb Close the largest canonical-mapping gaps the shadow census found
- 'this' in a class body maps through the nominal table (it is the class).
- An unbound type parameter maps through the lowerer's IR-level binding,
  which is how generic class instances bind their parameters.
- An intersection that refines a class (a mixin instance, 'T & Class') is
  that class, not a merged record.
- An object whose members do not map structurally (an interface over Map
  or Set, method-only interfaces) keeps its per-type recognition.

On a 160-program sample of the corpus (generic classes, interfaces, Maps),
the shadow census goes from 78.7% equal (2,936 canonical failures, 943
divergences) to 98.0% equal (25 failures, 343 divergences).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 07:21:05 -07:00
Malte UblandClaude Opus 5.5 5aa6699b3d Build the candidate's own compiler source in the zero-cost gate
The self program compiles the compiler source of the checkout the programs
come from (the baseline by default), so a change adding compiler code the
self-hosted frontend cannot lower passed the gate and failed CI's
self-hosting tests. With the self set, the gate now also builds the
candidate's packages/compiler/src/native/cli.ts with the candidate (LLVM
only, not compared) and fails when that build fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 07:09:02 -07:00
Chris Tate 823ebd50dc Resolve each shipped declaration path once (#2335) 2026-10-26 08:42:47 -05:00
Chris Tate 5a14c0a3dc Merge main 2026-10-26 08:37:13 -05:00