Repository navigation
Pass native closures, promises and objects into Node islands by reference (NI-5) - #1900
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…ence (NI-5) Node islands stack, part 3 of 11 (scriptc-perf/results/islands-prs/PLAN.md). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
984d3fd to
a1b6fda
Compare
060092e to
106eccd
Compare
structuredClone in an island of a value holding native records, class instances or objects (interceptor objects V8's serializer cannot clone) clones a plain copy of that data, as Node clones the objects themselves. An island array of primitives or strings (or arrays of those) returned directly or through a promise crosses as a copy, which the checked cast then meets, instead of failing the cast as an object handle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # packages/compiler/src/backend/native/executable.ts # packages/runtime-pack-common/runtime-pack-matrix.mjs
# Conflicts: # packages/compiler/src/frontend/lowering/lower-classes.ts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Round complete (head
No code change on this branch this round; it was merged forward with the fixed #1899 heads ( The zero-cost gate against 🤖 Generated with Claude Code |
Co-Authored-By: Claude 5.5 <noreply@anthropic.com>
g05-zlib starts a zlib.gzip from a 0 ms island timer and arms a 2 ms timer on the native side. The 0 ms timer's callback runs before the 2 ms timer is due, so the gzip job races that timer: if the job completes on libuv's thread pool before the timer's turn, its callback runs first. Node orders the two the other way only because its first gzip usually takes longer than the wait. With zlib already loaded and the thread pool started, Node prints i-zlib first in about a quarter of runs. On fast macOS hosts the native runs took the other order. Mark it `// @order: race`, as g01 (fs), g03 (child process) and g04 (dns) already are, so its native runs must produce the lines of one of Node's outputs in any order, and name thread-pool work among the races the harness describes.
Stacked on #1899. Third of nine Node islands PRs.
What it does
Runtime.
scr_node_island_export.cadds an export table. A value's identity is its referent: a closure, a promise, a typed capsule's native pointer, or otherwise the dyn box. Host callbacks run over the generic dyn operations: calls go through the closure's thunk, so its contract checks apply, and records and class instances go through Reflect.get/set. A native promise's V8 representative resolves inside the native settlement (scr_promise_on_settle_sync,SCR_NODE_ISLANDSonly). An island Error passed to a native callback arrives as its pinnedScrError, so nativeinstanceof RangeErrorholds.Bridge, ABI 6.
Function::Newwith the export id as data. Promises use aPromise::Resolver. Objects use one ObjectTemplate with named and indexed interceptors.scriptc:exportsymbol carries the export id, so representatives come back into the program as the native value.Compiler. These arguments cross by reference: functions, Promises, and object types other than arrays, tuples, Map and Set.
any/unknownvalues cross as dyn. Class instances answer their prototype methods through a per-class method table. A result typed with a native object type is a checked cast, so an export comes back as itself. A nativeclass X extends <island value>is SC8011.This PR also includes NI-4a's follow-up in the harness: only runtime-class fences make islands.
At exit, after Node stops, the runtime releases the export table, its ids, the class method tables and the last conversion's keep. This keeps the sanitized lane's RC audit clean. NI-6 (#1902) extends this.
Evidence
6830–6836, byte-identical with Node. They cover callbacks, promises, objects and typed callbacks. They also cover an island EventEmitter subclass with native listeners, Node-style async callbacks carrying island errors, and native throws through island frames. Promise interleavings are tested in both directions, as are native records mutated by the island and class instance fields and methods.node-island-subclass(SC8011).Shortcuts
Object.prototype. Islandinstanceofagainst native classes is not supported, and symbol-keyed properties are not intercepted.Gate results
node-island*.test.ts,npm.test.ts,packages/compiler/src/node-islands, differential68xx): plain 207/207 + diff 49/49; sanitized 207/207 + 49/49.pnpm lint,pnpm format:checkandpnpm test:ts7 --baselines-onlypass.packages/compiler/src/native/cli.ts --emit=llvm) builds.corpus/fs-extra-package(%m0.settleVoid). It differs in every gate of the stack, including Bound V8's stack scan by Node's own stack in Node islands #1898, which does not touch the compiler, so it is nondeterministic on the base.both-failcovers only the island programs, because the gate host has no libnode pack. Compile time stays within tolerance.CI on the first push found failures outside the focused island set: the ABI in
bridge.test.ts, the runtime ABI header declarations, the effect gate on the ts7 allowlist, weak collections in the compiler, the pipeline scout and the Node version line. The fixes are folded into the PRs that introduce each piece, and they are re-checked in a Sandbox on the final tree.Stack
#1898
#1899
→ #1900
#1901
#1902
#1903
#1904
#1905
#1906
#1907
#1908
🤖 Generated with Claude Code