Merge ni/i7-routing into ni/i8-exit

This commit is contained in:
Malte Ubl
2026-10-22 19:56:48 -07:00
8 changed files with 41 additions and 22 deletions
+12 -4
View File
@@ -461,10 +461,13 @@ function preflightIslands(
/** Packages compiled natively with runtime fences (refusals deferred to the
* operation that reaches them) that should run in islands instead: those
* whose island class is runtime (R1) or object-model (R2), by NI-2's report
* over the pre-scan markers and the fences, or with a fence that itself
* needs the runtime. Gap-only packages keep their fences until decision 8
* (D6) retires them. `--node-islands=auto` only; null for none. */
* with a fence that surely fires (one in top-level module code, which runs
* when the module evaluates) or that itself needs the runtime (R1). Other
* fences stay deferred refusals until decision 8 (D6) retires them, so
* typed packages like jose stay native. With `requireFence` false (after a
* failed build) the package's island class by NI-2's report decides
* instead: runtime (R1) or object-model (R2). `--node-islands=auto` only;
* null for none. */
function fenceIslands(
entryPath: string,
opts: CompileRequestOptions,
@@ -515,6 +518,11 @@ function fenceIslands(
if (runtimeFence === undefined || island.path === null) continue;
if (!compiled.has(island.package) || known.has(island.package)) continue;
if (policy.forcedNative.has(island.package) || policy.unloaded.has(island.package)) continue;
// With fences (requireFence), only fences that surely fire count: a
// gap fence inside a function body may never run (jose's typed paths
// stay native, DECISIONS.md 2026-10-21). After a failed build
// (!requireFence), the package's report class decides.
if (requireFence && !runtimeFence) continue;
if (!runtimeFence && island.class !== "runtime" && island.class !== "object-model") continue;
grown.set(island.package, {
name: island.package,
@@ -1444,6 +1444,11 @@ Local<Value> ExportValue(Isolate *isolate, Local<Context> context, const ScrNode
} else {
obj = ExportTemplate(isolate)->NewInstance(context).ToLocalChecked();
obj->SetInternalField(0, data);
// A template instance inherits from its implicit constructor's own
// prototype object; a native plain object is a plain object to island
// code (`Object.getPrototypeOf(o) === Object.prototype`, as jose's
// isObject checks), so it inherits Object.prototype directly.
obj->SetPrototypeV2(context, v8::Object::New(isolate)->GetPrototypeV2()).FromMaybe(false);
}
if (!obj->IsProxy()) obj->SetPrivate(context, ExportKey(isolate), data).Check();
Global<Object> &slot = g_exports[id];
@@ -1 +0,0 @@
{ "type": "module", "scriptc": { "packages": { "jose": "native" } } }
@@ -1 +0,0 @@
{ "type": "module", "scriptc": { "packages": { "run-node": "native" } } }
@@ -12,6 +12,7 @@ import {
nodeVersionFor,
cwd,
envValue,
plain,
type Config,
} from "argprobe";
import { mkdtempSync, writeFileSync, rmSync } from "node:fs";
@@ -54,6 +55,8 @@ const none = projectSettings(false);
console.log(version("/work", "unused", { nodeVersion: project?.nodeVersion }, undefined, available));
console.log(version("/work", "unused", { nodeVersion: none?.nodeVersion }, undefined, available));
console.log(probe("p", { nodeVersion: project?.nodeVersion }), probe("n", { nodeVersion: none?.nodeVersion }));
const claims = { role: "admin" };
console.log("plain", plain({ sub: "alice" }), plain(claims));
async function main(): Promise<void> {
// A package.json the program writes just before the island reads it.
@@ -21,3 +21,4 @@ export declare function nodeVersionFor(
): Promise<string>;
export declare function cwd(): string;
export declare function envValue(name: string): string | undefined;
export declare function plain(v: object): string;
@@ -68,3 +68,11 @@ exports.nodeVersionFor = async function nodeVersionFor(
exports.cwd = () => process.cwd();
exports.envValue = (name) => process.env[name];
// A native plain object is a plain object here (jose's isObject).
exports.plain = (v) =>
[
Object.getPrototypeOf(v) === Object.prototype,
Object.prototype.toString.call(v),
Object.getPrototypeOf(Object.getPrototypeOf(v)) === null,
].join(" ");
+12 -16
View File
@@ -66,46 +66,42 @@ const KNOWN: Record<string, Known> = {
divergence:
"Timeout handles are numbers (typeof) and lose their ref flag once fired or cleared",
},
"hot-shots-udp": {
divergence:
"as a Node island (its runtime fences pick one), output stops after the socket-not-running error; the built-in hot-shots shim (#1836) compiles it natively",
},
"island-web-plumbing": { run: "SC2020" },
"lazy-traps": { island: true },
"misc-shims": { island: true },
"misc-shims": { run: "SC2020" },
namespace: { island: true },
"node24-async-events": { run: "SC2020" },
"node24-commonjs-metadata": { island: true },
"node24-crypto-kdf": { run: "SC2020" },
"node24-deep-equality": { island: true },
"node24-deep-equality": { run: "SC2020" },
"node24-diagnostics-async": { run: "SC1090" },
"node24-diagnostics-tracing": { run: "SC1090" },
"node24-env": { island: true },
"node24-env": { run: "SC1090" },
"node24-esm-metadata": { island: true },
"node24-event-emitter": { run: "SC2020" },
"node24-file-url-conversion": { island: true },
"node24-fs-descriptors": { run: "SC2020" },
"node24-mime": { island: true },
"node24-mime-errors": { island: true },
"node24-mime": { run: "SC2020" },
"node24-mime-errors": { run: "SC1090" },
"node24-no-error-assertions": { run: "SC2020" },
"node24-parseargs": { island: true },
"node24-parseargs": { run: "SC1090" },
"node24-promise-timers": { run: "SC2020" },
"node24-string-decoder": { run: "SC2020" },
"node24-style-text": { island: true },
"node24-style-text": { run: "SC2020" },
"node24-system-errors": { run: "SC1090" },
"node24-text-encoding": { run: "SC2020" },
"node24-text-utilities": { run: "SC2020" },
"node24-timers-unref": { run: "SC2020" },
"node24-url-factories": { run: "SC2020" },
"node24-url-mutation": { run: "SC1090" },
"node24-util-adapters": { island: true },
"node24-util-types": { island: true },
"node24-util-adapters": { run: "Object.create with this value is not supported yet" },
"node24-util-types": { run: "SC1090" },
"node24-web-stream-encoding": { run: "SC1090" },
"node24-web-stream-errors": { run: "SC1090" },
"node24-web-stream-lifecycle": { run: "SC1090" },
"node24-web-stream-pipe-abort": { run: "SC2020" },
"node24-web-stream-pipe-errors": { run: "SC1090" },
"node24-web-stream-pipes": { island: true },
"node24-web-stream-pipes": { run: "SC1090" },
"node24-web-stream-queues": { run: "SC1090" },
"node24-web-stream-readable-lifecycle": { run: "SC2020" },
"node24-web-stream-readers": { run: "SC1090" },
@@ -114,8 +110,8 @@ const KNOWN: Record<string, Known> = {
"package-imports": { island: true },
"promise-bridge": { build: "SC1090" },
"self-name": { build: "SC2013" },
"stream-shims": { island: true },
"util-shims": { island: true },
"stream-shims": { run: "SC1090" },
"util-shims": { run: "SC2020" },
"web-streams": { run: "SC1090" },
"workspace-copied": { island: true },
"workspace-unclean": { build: "SC2013" },