@scriptc/compiler 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +54 -9
- package/dist/backend/emission/emit-exprs.js +170 -14
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-walkers.js +29 -2
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.js +25 -1
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +1 -0
- package/dist/backend/llvm/dyn.js +83 -1
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +210 -13
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -2
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +41 -14
- package/dist/diagnostics/diagnostic.js +79 -27
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/render.js +8 -0
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +11 -1
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +69 -0
- package/dist/frontend/lowering/lower-builtins.js +380 -4
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +41 -0
- package/dist/frontend/lowering/lower-calls.js +559 -11
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +7 -0
- package/dist/frontend/lowering/lower-classes.js +51 -1
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +21 -0
- package/dist/frontend/lowering/lower-containers.js +262 -17
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +92 -17
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-emitter.d.ts +70 -3
- package/dist/frontend/lowering/lower-emitter.js +436 -29
- package/dist/frontend/lowering/lower-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +80 -5
- package/dist/frontend/lowering/lower-exprs.js +651 -23
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +8 -5
- package/dist/frontend/lowering/lower-modules.js +144 -19
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +39 -11
- package/dist/frontend/lowering/lower-namespaces.js +166 -24
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +211 -4
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +1 -5
- package/dist/frontend/lowering/lower-stmts.js +293 -10
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +178 -10
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +53 -1
- package/dist/frontend/lowering/lowerer.js +210 -19
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +44 -0
- package/dist/frontend/lowering/surfaces.js +234 -3
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm.d.ts +12 -0
- package/dist/frontend/npm.js +30 -0
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.d.ts +25 -0
- package/dist/frontend/program.js +144 -135
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/shared.d.ts +1 -1
- package/dist/frontend/shared.js +1 -1
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/types.d.ts +13 -0
- package/dist/frontend/types.js +84 -7
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +157 -12
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +163 -13
- package/dist/ir/nodes.js +65 -6
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +64 -5
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/fence-eval.d.ts +77 -0
- package/dist/library/fence-eval.js +395 -0
- package/dist/library/fence-eval.js.map +1 -0
- package/dist/library/int-infer.d.ts +119 -0
- package/dist/library/int-infer.js +1301 -0
- package/dist/library/int-infer.js.map +1 -0
- package/dist/library/int-infer.test.d.ts +1 -0
- package/dist/library/int-infer.test.js +279 -0
- package/dist/library/int-infer.test.js.map +1 -0
- package/dist/library/profile.d.ts +43 -6
- package/dist/library/profile.js +179 -31
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar.d.ts +23 -0
- package/dist/library/sidecar.js +150 -16
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +208 -10
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type SurfaceEntryKind } from "../coverage/surface-manifest.js";
|
|
2
|
+
import { type ScrDiagnostic } from "../diagnostics/diagnostic.js";
|
|
3
|
+
import type { IrModule } from "../ir/nodes.js";
|
|
4
|
+
/** One raw fence declaration as the profile spelled it (validated for
|
|
5
|
+
* shape by the loader; resolved here against the manifest). */
|
|
6
|
+
export interface LibraryFenceDecl {
|
|
7
|
+
/** JSON path for exact-path refusals: `determinism.fences[2]`. */
|
|
8
|
+
path: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
prefix?: string;
|
|
11
|
+
teaching?: string;
|
|
12
|
+
remediation?: string;
|
|
13
|
+
}
|
|
14
|
+
/** The IR facts that witness one surface's reach in the compiled graph.
|
|
15
|
+
* A surface is reached exactly when any listed fact appears. */
|
|
16
|
+
interface SurfaceDetector {
|
|
17
|
+
libFns?: readonly string[];
|
|
18
|
+
strMethods?: readonly string[];
|
|
19
|
+
arrMethods?: readonly string[];
|
|
20
|
+
mapMethods?: readonly string[];
|
|
21
|
+
setMethods?: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
/** One manifest entry a fence covers, resolved and load-validated. */
|
|
24
|
+
export interface FencedSurface {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
kind: SurfaceEntryKind;
|
|
28
|
+
/** The diagnostic code the manifest entry carries (every non-static
|
|
29
|
+
* entry has one) — the code whose refusal the fence teaching rides. */
|
|
30
|
+
code?: string;
|
|
31
|
+
/** Present exactly when the entry is static (it compiles, so the fence
|
|
32
|
+
* must deny it): the reach witness. Absent = the surface already
|
|
33
|
+
* refuses with `code` and the fence changes only the message. */
|
|
34
|
+
detector?: SurfaceDetector;
|
|
35
|
+
}
|
|
36
|
+
export interface ResolvedLibraryFence {
|
|
37
|
+
/** The declared selector, for messages: `id 'stdlib.math.random'` or
|
|
38
|
+
* `prefix 'node-builtin.fs.'`. */
|
|
39
|
+
declared: string;
|
|
40
|
+
teaching?: string;
|
|
41
|
+
remediation?: string;
|
|
42
|
+
surfaces: readonly FencedSurface[];
|
|
43
|
+
}
|
|
44
|
+
/** Resolve the profile's fence declarations against this compiler
|
|
45
|
+
* release's surface manifest. Every failure returns the exact-path detail
|
|
46
|
+
* the loader wraps as SC4001. Selector strictness is RATIFIED: an id or
|
|
47
|
+
* prefix matching nothing refuses; a covered static entry no detector can
|
|
48
|
+
* police refuses (loudly, never silently inert). Compile-time-folded
|
|
49
|
+
* constants refuse as `id` fences (the message says why) and are exempt
|
|
50
|
+
* under a `prefix` — the family sweep stays usable, and the fold means
|
|
51
|
+
* there is genuinely nothing at runtime to deny. */
|
|
52
|
+
export declare function resolveLibraryFences(decls: readonly LibraryFenceDecl[]): {
|
|
53
|
+
ok: true;
|
|
54
|
+
fences: ResolvedLibraryFence[];
|
|
55
|
+
} | {
|
|
56
|
+
ok: false;
|
|
57
|
+
detail: string;
|
|
58
|
+
};
|
|
59
|
+
/** The structural slice of LibraryProfile the fence machinery reads —
|
|
60
|
+
* kept structural so this module never value-imports the loader. */
|
|
61
|
+
export interface FenceProfileView {
|
|
62
|
+
name: string;
|
|
63
|
+
teachings: Readonly<Record<string, string>>;
|
|
64
|
+
fences: readonly ResolvedLibraryFence[];
|
|
65
|
+
}
|
|
66
|
+
/** Evaluate the profile's fences against the COMPILED module graph: every
|
|
67
|
+
* fenced static surface the graph reaches refuses as SC4008, anchored at
|
|
68
|
+
* the reaching construct, the fence's teaching attached as the attributed
|
|
69
|
+
* note. Unreached fences add nothing; a profile whose fences carry no
|
|
70
|
+
* detector-backed surface skips the walk entirely. */
|
|
71
|
+
export declare function evaluateLibraryFences(mod: IrModule, profile: FenceProfileView): ScrDiagnostic[];
|
|
72
|
+
/** Attach the profile's teaching text to every library-mode refusal it
|
|
73
|
+
* names — by code, by manifest id, or through a fence — as the visibly
|
|
74
|
+
* attributed `note`. Diagnostics already carrying a note (SC4008 threads
|
|
75
|
+
* its fence's teaching at mint time) pass through unchanged. */
|
|
76
|
+
export declare function decorateLibraryRefusals(diagnostics: ScrDiagnostic[], profile: FenceProfileView): ScrDiagnostic[];
|
|
77
|
+
export {};
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/* Ask-5 determinism fences + the generalized teaching decoration.
|
|
2
|
+
*
|
|
3
|
+
* The profile's `determinism.fences` array denies surfaces BY SURFACE-
|
|
4
|
+
* MANIFEST ID (coverage/surface-manifest.ts — the compiler's one stable
|
|
5
|
+
* surface taxonomy; no new vocabulary). Resolution happens at profile
|
|
6
|
+
* load, against the manifest generated from this compiler's own tables:
|
|
7
|
+
*
|
|
8
|
+
* - an `id` names exactly one manifest entry; a `prefix` fences every
|
|
9
|
+
* entry it string-prefixes. An id or prefix matching NOTHING refuses
|
|
10
|
+
* loudly at load (ratified): fences pin to a compiler release's
|
|
11
|
+
* manifest, and a silently-inert fence is a footgun, so there is no
|
|
12
|
+
* forward-compatible acceptance of unknown selectors.
|
|
13
|
+
* - a fenced entry the static tier refuses anyway (status not "static")
|
|
14
|
+
* needs no new machinery: the surface's own refusal fires, and the
|
|
15
|
+
* fence's teaching rides it as the attributed note (spec §1: "changes
|
|
16
|
+
* only the message").
|
|
17
|
+
* - a fenced STATIC entry is policed against the COMPILED module graph:
|
|
18
|
+
* the emit pass lowers only reachability-discovered bodies, so the
|
|
19
|
+
* module IR *is* the reached graph — the same ground the sidecar's
|
|
20
|
+
* `deterministic` attestation stands on (ir/nodes.ts's
|
|
21
|
+
* moduleLibNondeterministicSurface). Fence evaluation reuses that
|
|
22
|
+
* posture with one generic walk collecting the reached surface facts
|
|
23
|
+
* (libCall spellings, str/arr/map/set intrinsic methods); each fenced
|
|
24
|
+
* entry then answers by table-derived detector. Unreached fences cost
|
|
25
|
+
* exactly this one walk — and no walk at all when no fence declares a
|
|
26
|
+
* detector-backed surface.
|
|
27
|
+
* - a fenced static entry with NO honest detector refuses at load,
|
|
28
|
+
* never accepted-and-ignored. Two families are named specifically:
|
|
29
|
+
* compile-time-folded constants (os.EOL, path.sep — the artifact
|
|
30
|
+
* performs no runtime read a fence could deny) and desugared surfaces
|
|
31
|
+
* (array map/filter/forEach and friends lower to plain loops with no
|
|
32
|
+
* distinct trace).
|
|
33
|
+
*
|
|
34
|
+
* Detectors derive MECHANICALLY from the same lowering tables the
|
|
35
|
+
* manifest projects from (frontend/lowering/surfaces.ts), so a table row
|
|
36
|
+
* added later grows the fenceable surface without hand maintenance. Two
|
|
37
|
+
* aliased-lowering facts are inherited from the tables and deliberate:
|
|
38
|
+
* string trimLeft/trimRight share trimStart/trimEnd's IR method, and
|
|
39
|
+
* querystring decode/encode share parse/stringify's libCall — fencing one
|
|
40
|
+
* spelling fences the operation.
|
|
41
|
+
*
|
|
42
|
+
* decorateLibraryRefusals is the generalized teaching rider (spec §2):
|
|
43
|
+
* profile text attaches to ANY library-mode refusal by diagnostic code
|
|
44
|
+
* (the ratified SC4004/SC4005 rider's keys, "async" shared-key fallback
|
|
45
|
+
* included), by manifest id (matched against the refusal's code plus the
|
|
46
|
+
* entry's surface name in the message; diagnostic-fence entries match on
|
|
47
|
+
* code alone — the entry IS the code family), or by a fence entry
|
|
48
|
+
* covering the refused surface. The text renders as the diagnostic's
|
|
49
|
+
* `note`, always prefixed with the profile's name — the tool's message
|
|
50
|
+
* stays the tool's. */
|
|
51
|
+
import { generateSurfaceManifest } from "../coverage/surface-manifest.js";
|
|
52
|
+
import { libFenceDiag } from "../diagnostics/diagnostic.js";
|
|
53
|
+
import { AMBIENT_SURFACE_FNS, BUILTIN_MODULE_CONSTS, BUILTIN_MODULE_FNS, BUILTIN_MODULE_FN_ALIASES, STATIC_MATH_FNS, STR_METHODS, } from "../frontend/lowering/surfaces.js";
|
|
54
|
+
import { compilerReleaseVersion } from "./sidecar.js";
|
|
55
|
+
let taxonomy = null;
|
|
56
|
+
function builtinRootId(mod) {
|
|
57
|
+
return `node-builtin.${mod.split("/").join(".")}`;
|
|
58
|
+
}
|
|
59
|
+
function fenceTaxonomy() {
|
|
60
|
+
if (taxonomy !== null)
|
|
61
|
+
return taxonomy;
|
|
62
|
+
const manifest = generateSurfaceManifest(compilerReleaseVersion());
|
|
63
|
+
const byId = new Map(manifest.entries.map((e) => [e.id, e]));
|
|
64
|
+
const builtinFns = new Map();
|
|
65
|
+
const builtinRoots = new Map();
|
|
66
|
+
const foldedIds = new Set();
|
|
67
|
+
for (const [mod, members] of Object.entries(BUILTIN_MODULE_FNS)) {
|
|
68
|
+
const root = new Set();
|
|
69
|
+
for (const [member, entry] of Object.entries(members)) {
|
|
70
|
+
if (entry === undefined)
|
|
71
|
+
continue;
|
|
72
|
+
const fns = new Set([entry.fn]);
|
|
73
|
+
// The bare-path and url tables rebind per TARGET platform
|
|
74
|
+
// (builtinModuleFnsOf): a fence on the bare id covers both flavors.
|
|
75
|
+
if (mod === "path") {
|
|
76
|
+
const w = BUILTIN_MODULE_FNS["path/win32"]?.[member];
|
|
77
|
+
if (w !== undefined)
|
|
78
|
+
fns.add(w.fn);
|
|
79
|
+
}
|
|
80
|
+
if (mod === "url" && member === "pathToFileURL")
|
|
81
|
+
fns.add("url.pathToFileURLWin32");
|
|
82
|
+
// Alternate spellings the dispatch special-cases around the table
|
|
83
|
+
// row (Buffer/fd/options forms) are the same surface.
|
|
84
|
+
for (const alias of BUILTIN_MODULE_FN_ALIASES[mod]?.[member] ?? [])
|
|
85
|
+
fns.add(alias);
|
|
86
|
+
builtinFns.set(`${builtinRootId(mod)}.${member}`, [...fns]);
|
|
87
|
+
for (const f of fns)
|
|
88
|
+
root.add(f);
|
|
89
|
+
}
|
|
90
|
+
if (root.size > 0)
|
|
91
|
+
builtinRoots.set(builtinRootId(mod), [...root]);
|
|
92
|
+
}
|
|
93
|
+
for (const [mod, members] of Object.entries(BUILTIN_MODULE_CONSTS)) {
|
|
94
|
+
for (const member of Object.keys(members))
|
|
95
|
+
foldedIds.add(`${builtinRootId(mod)}.${member}`);
|
|
96
|
+
}
|
|
97
|
+
const ambientFns = new Map(AMBIENT_SURFACE_FNS.map((row) => [row.id, row.fns]));
|
|
98
|
+
taxonomy = { byId, ids: manifest.entries.map((e) => e.id), builtinFns, builtinRoots, foldedIds, ambientFns };
|
|
99
|
+
return taxonomy;
|
|
100
|
+
}
|
|
101
|
+
/* ── classification: what policing a static entry means ───────────────── */
|
|
102
|
+
/** Array methods with a distinct IR trace (arrIntrinsic methods). `push`
|
|
103
|
+
* includes the spread spelling — `a.push(...xs)` lowers to pushSpread and
|
|
104
|
+
* is the same surface. The rest of ARRAY_METHODS desugars to plain loops. */
|
|
105
|
+
const ARR_DETECTABLE = {
|
|
106
|
+
push: ["push", "pushSpread"],
|
|
107
|
+
pop: ["pop"],
|
|
108
|
+
indexOf: ["indexOf"],
|
|
109
|
+
includes: ["includes"],
|
|
110
|
+
join: ["join"],
|
|
111
|
+
slice: ["slice"],
|
|
112
|
+
};
|
|
113
|
+
const MAP_DETECTABLE = new Set(["get", "set", "has", "delete", "clear"]);
|
|
114
|
+
const SET_DETECTABLE = new Set(["add", "has", "delete", "clear"]);
|
|
115
|
+
const DESUGARED_WHY = "it desugars at compile time into plain loops over iteration primitives, so the compiled graph carries no distinct trace to police";
|
|
116
|
+
function classifySurface(entry, tax) {
|
|
117
|
+
// Non-static entries already refuse with their own code wherever they
|
|
118
|
+
// are reached — the fence's teaching rides that refusal.
|
|
119
|
+
if (entry.status !== "static")
|
|
120
|
+
return { kind: "refusal" };
|
|
121
|
+
if (tax.foldedIds.has(entry.id)) {
|
|
122
|
+
return {
|
|
123
|
+
kind: "unfenceable",
|
|
124
|
+
why: "reads of it fold to a per-binary constant at compile time — the artifact performs no runtime read a fence could deny",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
// Ambient dedicated-path surfaces (Date/perf_hooks/process): the row
|
|
128
|
+
// that projected the entry carries its reach witness.
|
|
129
|
+
const ambient = tax.ambientFns.get(entry.id);
|
|
130
|
+
if (ambient !== undefined)
|
|
131
|
+
return { kind: "detector", detector: { libFns: ambient } };
|
|
132
|
+
const builtinFns = tax.builtinFns.get(entry.id);
|
|
133
|
+
if (builtinFns !== undefined)
|
|
134
|
+
return { kind: "detector", detector: { libFns: builtinFns } };
|
|
135
|
+
const rootFns = tax.builtinRoots.get(entry.id);
|
|
136
|
+
if (rootFns !== undefined)
|
|
137
|
+
return { kind: "detector", detector: { libFns: rootFns } };
|
|
138
|
+
const [, family, member] = entry.id.split(".");
|
|
139
|
+
if (entry.id.startsWith("stdlib.") && family !== undefined && member !== undefined) {
|
|
140
|
+
if (family === "math") {
|
|
141
|
+
const fn = Object.hasOwn(STATIC_MATH_FNS, member) ? STATIC_MATH_FNS[member] : undefined;
|
|
142
|
+
if (fn !== undefined)
|
|
143
|
+
return { kind: "detector", detector: { libFns: [fn.fn] } };
|
|
144
|
+
}
|
|
145
|
+
if (family === "string") {
|
|
146
|
+
const m = Object.hasOwn(STR_METHODS, member) ? STR_METHODS[member] : undefined;
|
|
147
|
+
if (m !== undefined)
|
|
148
|
+
return { kind: "detector", detector: { strMethods: [m.method] } };
|
|
149
|
+
}
|
|
150
|
+
if (family === "array") {
|
|
151
|
+
const methods = Object.hasOwn(ARR_DETECTABLE, member) ? ARR_DETECTABLE[member] : undefined;
|
|
152
|
+
if (methods !== undefined)
|
|
153
|
+
return { kind: "detector", detector: { arrMethods: methods } };
|
|
154
|
+
return { kind: "unfenceable", why: DESUGARED_WHY };
|
|
155
|
+
}
|
|
156
|
+
if (family === "map") {
|
|
157
|
+
if (MAP_DETECTABLE.has(member))
|
|
158
|
+
return { kind: "detector", detector: { mapMethods: [member] } };
|
|
159
|
+
return { kind: "unfenceable", why: DESUGARED_WHY };
|
|
160
|
+
}
|
|
161
|
+
if (family === "set") {
|
|
162
|
+
if (SET_DETECTABLE.has(member))
|
|
163
|
+
return { kind: "detector", detector: { setMethods: [member] } };
|
|
164
|
+
return { kind: "unfenceable", why: DESUGARED_WHY };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (entry.id.startsWith("syntax.")) {
|
|
168
|
+
return {
|
|
169
|
+
kind: "unfenceable",
|
|
170
|
+
why: "it lowers to the same IR as its expanded spelling, so the compiled graph carries no distinct trace to police",
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (entry.id.startsWith("node-builtin.")) {
|
|
174
|
+
return {
|
|
175
|
+
kind: "unfenceable",
|
|
176
|
+
why: "its lowered surface leaves no tabled per-call trace at this compiler release — fence the member entries the manifest projects instead",
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return { kind: "unfenceable", why: "no fence detector exists for it at this compiler release" };
|
|
180
|
+
}
|
|
181
|
+
/* ── load-time resolution ──────────────────────────────────────────────── */
|
|
182
|
+
/** Resolve the profile's fence declarations against this compiler
|
|
183
|
+
* release's surface manifest. Every failure returns the exact-path detail
|
|
184
|
+
* the loader wraps as SC4001. Selector strictness is RATIFIED: an id or
|
|
185
|
+
* prefix matching nothing refuses; a covered static entry no detector can
|
|
186
|
+
* police refuses (loudly, never silently inert). Compile-time-folded
|
|
187
|
+
* constants refuse as `id` fences (the message says why) and are exempt
|
|
188
|
+
* under a `prefix` — the family sweep stays usable, and the fold means
|
|
189
|
+
* there is genuinely nothing at runtime to deny. */
|
|
190
|
+
export function resolveLibraryFences(decls) {
|
|
191
|
+
const tax = fenceTaxonomy();
|
|
192
|
+
const fences = [];
|
|
193
|
+
for (const d of decls) {
|
|
194
|
+
const surfaces = [];
|
|
195
|
+
const keep = (entry, cls) => {
|
|
196
|
+
surfaces.push({
|
|
197
|
+
id: entry.id,
|
|
198
|
+
name: entry.name,
|
|
199
|
+
kind: entry.kind,
|
|
200
|
+
...(entry.code !== undefined ? { code: entry.code } : {}),
|
|
201
|
+
...(cls.kind === "detector" ? { detector: cls.detector } : {}),
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
if (d.id !== undefined) {
|
|
205
|
+
const entry = tax.byId.get(d.id);
|
|
206
|
+
if (entry === undefined) {
|
|
207
|
+
return {
|
|
208
|
+
ok: false,
|
|
209
|
+
detail: `'${d.path}.id' names no entry in this compiler release's surface manifest ('${d.id}') — ` +
|
|
210
|
+
`fences pin to the release's manifest ids (the package ships surface-manifest.json), and an unknown id is refused, never accepted as inert`,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const cls = classifySurface(entry, tax);
|
|
214
|
+
if (cls.kind === "unfenceable") {
|
|
215
|
+
return { ok: false, detail: `'${d.path}.id' names '${d.id}', which cannot be fenced: ${cls.why}` };
|
|
216
|
+
}
|
|
217
|
+
keep(entry, cls);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
const covered = tax.ids.filter((id) => id.startsWith(d.prefix));
|
|
221
|
+
if (covered.length === 0) {
|
|
222
|
+
return {
|
|
223
|
+
ok: false,
|
|
224
|
+
detail: `'${d.path}.prefix' matches no entry in this compiler release's surface manifest ('${d.prefix}') — ` +
|
|
225
|
+
`fences pin to the release's manifest ids (the package ships surface-manifest.json), and an unknown prefix is refused, never accepted as inert`,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
for (const id of covered) {
|
|
229
|
+
const entry = tax.byId.get(id);
|
|
230
|
+
const cls = classifySurface(entry, tax);
|
|
231
|
+
if (cls.kind === "unfenceable") {
|
|
232
|
+
if (tax.foldedIds.has(id))
|
|
233
|
+
continue; // the fold IS the exemption — see above
|
|
234
|
+
return { ok: false, detail: `'${d.path}.prefix' ('${d.prefix}') covers '${id}', which cannot be fenced: ${cls.why}` };
|
|
235
|
+
}
|
|
236
|
+
keep(entry, cls);
|
|
237
|
+
}
|
|
238
|
+
if (surfaces.length === 0) {
|
|
239
|
+
return {
|
|
240
|
+
ok: false,
|
|
241
|
+
detail: `'${d.path}.prefix' ('${d.prefix}') covers only compile-time-folded constants — there is nothing at runtime for the fence to deny`,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
fences.push({
|
|
246
|
+
declared: d.id !== undefined ? `id '${d.id}'` : `prefix '${d.prefix}'`,
|
|
247
|
+
...(d.teaching !== undefined ? { teaching: d.teaching } : {}),
|
|
248
|
+
...(d.remediation !== undefined ? { remediation: d.remediation } : {}),
|
|
249
|
+
surfaces,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
return { ok: true, fences };
|
|
253
|
+
}
|
|
254
|
+
/** One generic walk over the compiled module (the moduleLibAsyncSurface
|
|
255
|
+
* shape: nearest enclosing `loc` tracked so refusals anchor at the
|
|
256
|
+
* reaching construct), collecting every reached surface fact the fence
|
|
257
|
+
* detectors speak. First location per fact wins. */
|
|
258
|
+
function collectReachedSurfaces(mod) {
|
|
259
|
+
const reached = {
|
|
260
|
+
libFns: new Map(),
|
|
261
|
+
strMethods: new Map(),
|
|
262
|
+
arrMethods: new Map(),
|
|
263
|
+
mapMethods: new Map(),
|
|
264
|
+
setMethods: new Map(),
|
|
265
|
+
};
|
|
266
|
+
const note = (map, key, loc) => {
|
|
267
|
+
if (!map.has(key))
|
|
268
|
+
map.set(key, loc);
|
|
269
|
+
};
|
|
270
|
+
const entryLoc = { file: mod.sourceFile, start: 0, end: 0 };
|
|
271
|
+
const visit = (v, loc) => {
|
|
272
|
+
if (v === null || typeof v !== "object")
|
|
273
|
+
return;
|
|
274
|
+
if (Array.isArray(v)) {
|
|
275
|
+
for (const item of v)
|
|
276
|
+
visit(item, loc);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const node = v;
|
|
280
|
+
const here = node.loc ?? loc;
|
|
281
|
+
if (typeof node.kind === "string") {
|
|
282
|
+
if (node.kind === "libCall" && typeof node.fn === "string")
|
|
283
|
+
note(reached.libFns, node.fn, here);
|
|
284
|
+
else if (typeof node.method === "string") {
|
|
285
|
+
if (node.kind === "strIntrinsic")
|
|
286
|
+
note(reached.strMethods, node.method, here);
|
|
287
|
+
else if (node.kind === "arrIntrinsic")
|
|
288
|
+
note(reached.arrMethods, node.method, here);
|
|
289
|
+
else if (node.kind === "mapIntrinsic")
|
|
290
|
+
note(reached.mapMethods, node.method, here);
|
|
291
|
+
else if (node.kind === "setIntrinsic")
|
|
292
|
+
note(reached.setMethods, node.method, here);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
for (const key of Object.keys(v))
|
|
296
|
+
visit(v[key], here);
|
|
297
|
+
};
|
|
298
|
+
visit(mod, entryLoc);
|
|
299
|
+
return reached;
|
|
300
|
+
}
|
|
301
|
+
function detectorHit(reached, det) {
|
|
302
|
+
const scan = (facts, keys) => {
|
|
303
|
+
for (const k of keys ?? []) {
|
|
304
|
+
const loc = facts.get(k);
|
|
305
|
+
if (loc !== undefined)
|
|
306
|
+
return loc;
|
|
307
|
+
}
|
|
308
|
+
return null;
|
|
309
|
+
};
|
|
310
|
+
return (scan(reached.libFns, det.libFns) ??
|
|
311
|
+
scan(reached.strMethods, det.strMethods) ??
|
|
312
|
+
scan(reached.arrMethods, det.arrMethods) ??
|
|
313
|
+
scan(reached.mapMethods, det.mapMethods) ??
|
|
314
|
+
scan(reached.setMethods, det.setMethods));
|
|
315
|
+
}
|
|
316
|
+
/** Evaluate the profile's fences against the COMPILED module graph: every
|
|
317
|
+
* fenced static surface the graph reaches refuses as SC4008, anchored at
|
|
318
|
+
* the reaching construct, the fence's teaching attached as the attributed
|
|
319
|
+
* note. Unreached fences add nothing; a profile whose fences carry no
|
|
320
|
+
* detector-backed surface skips the walk entirely. */
|
|
321
|
+
export function evaluateLibraryFences(mod, profile) {
|
|
322
|
+
if (!profile.fences.some((f) => f.surfaces.some((s) => s.detector !== undefined)))
|
|
323
|
+
return [];
|
|
324
|
+
const reached = collectReachedSurfaces(mod);
|
|
325
|
+
const diags = [];
|
|
326
|
+
const seen = new Set();
|
|
327
|
+
for (const fence of profile.fences) {
|
|
328
|
+
for (const s of fence.surfaces) {
|
|
329
|
+
if (s.detector === undefined || seen.has(s.id))
|
|
330
|
+
continue;
|
|
331
|
+
const loc = detectorHit(reached, s.detector);
|
|
332
|
+
if (loc === null)
|
|
333
|
+
continue;
|
|
334
|
+
seen.add(s.id);
|
|
335
|
+
diags.push(libFenceDiag(profile.name, s.id, s.name, loc, s.code, fence.teaching));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return diags;
|
|
339
|
+
}
|
|
340
|
+
/* ── the generalized teaching rider ────────────────────────────────────── */
|
|
341
|
+
function surfaceMatchesDiag(surface, diag) {
|
|
342
|
+
if (surface.code === undefined || surface.code !== diag.code)
|
|
343
|
+
return false;
|
|
344
|
+
// A diagnostic-fence entry IS the code family; member entries must also
|
|
345
|
+
// appear by name in the refusal's message (SC2020/SC2012 refusals spell
|
|
346
|
+
// the surface exactly as the manifest names it).
|
|
347
|
+
return surface.kind === "diagnostic-fence" || diag.message.includes(surface.name);
|
|
348
|
+
}
|
|
349
|
+
function teachingForRefusal(profile, diag) {
|
|
350
|
+
// 1. Code-keyed teachings — the ratified SC4004/SC4005 rider's keys,
|
|
351
|
+
// "async" shared-key fallback included (profile.ts's profileTeaching
|
|
352
|
+
// rule, restated here to keep the import graph acyclic).
|
|
353
|
+
const direct = profile.teachings[diag.code] ??
|
|
354
|
+
(diag.code === "SC4004" || diag.code === "SC4005" ? profile.teachings["async"] : undefined);
|
|
355
|
+
if (direct !== undefined)
|
|
356
|
+
return direct;
|
|
357
|
+
// 2. Manifest-id-keyed teachings (dotted keys — embedder refusal-code
|
|
358
|
+
// tokens never carry dots; an id key resolves against the taxonomy and
|
|
359
|
+
// attaches where that surface's refusal fired).
|
|
360
|
+
for (const [key, text] of Object.entries(profile.teachings)) {
|
|
361
|
+
if (!key.includes("."))
|
|
362
|
+
continue;
|
|
363
|
+
const entry = fenceTaxonomy().byId.get(key);
|
|
364
|
+
if (entry !== undefined && surfaceMatchesDiag(entry, diag))
|
|
365
|
+
return text;
|
|
366
|
+
}
|
|
367
|
+
// 3. A fence covering the refused surface: the teaching rides the
|
|
368
|
+
// surface's own refusal (the non-static half of fence coverage).
|
|
369
|
+
for (const fence of profile.fences) {
|
|
370
|
+
if (fence.teaching === undefined)
|
|
371
|
+
continue;
|
|
372
|
+
for (const s of fence.surfaces) {
|
|
373
|
+
if (surfaceMatchesDiag(s, diag))
|
|
374
|
+
return fence.teaching;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
/** Attach the profile's teaching text to every library-mode refusal it
|
|
380
|
+
* names — by code, by manifest id, or through a fence — as the visibly
|
|
381
|
+
* attributed `note`. Diagnostics already carrying a note (SC4008 threads
|
|
382
|
+
* its fence's teaching at mint time) pass through unchanged. */
|
|
383
|
+
export function decorateLibraryRefusals(diagnostics, profile) {
|
|
384
|
+
if (Object.keys(profile.teachings).length === 0 && profile.fences.length === 0)
|
|
385
|
+
return diagnostics;
|
|
386
|
+
return diagnostics.map((d) => {
|
|
387
|
+
if (d.note !== undefined)
|
|
388
|
+
return d;
|
|
389
|
+
const teaching = teachingForRefusal(profile, d);
|
|
390
|
+
if (teaching === undefined)
|
|
391
|
+
return d;
|
|
392
|
+
return { ...d, note: `from the '${profile.name}' profile: ${teaching}` };
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
//# sourceMappingURL=fence-eval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fence-eval.js","sourceRoot":"","sources":["../../src/library/fence-eval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { IrModule, IrNumBinOp, SrcLoc } from "../ir/nodes.js";
|
|
2
|
+
export declare const SAFE_MAX: number;
|
|
3
|
+
export declare const SAFE_MIN: number;
|
|
4
|
+
/** The set of f64 values a binding may hold at a program point: a closed
|
|
5
|
+
* interval over the extended reals (`-0` normalized to 0 — the interval
|
|
6
|
+
* tracks mathematical value; zero's sign is an f64-interior observation
|
|
7
|
+
* with no boundary consequence), `whole` when every member is a finite
|
|
8
|
+
* integer-valued f64, `maybeNaN` when NaN may be in the set (NaN lives
|
|
9
|
+
* outside the interval, which describes only the numeric members), and
|
|
10
|
+
* the integer literal's source `spelling` for the representability check
|
|
11
|
+
* (propagates through copies and agreeing joins only; any arithmetic
|
|
12
|
+
* drops it — a computed value is a new number, not the author's
|
|
13
|
+
* literal). */
|
|
14
|
+
export interface AbsVal {
|
|
15
|
+
lo: number;
|
|
16
|
+
hi: number;
|
|
17
|
+
whole: boolean;
|
|
18
|
+
maybeNaN: boolean;
|
|
19
|
+
spelling?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function absVal(lo: number, hi: number, whole: boolean, maybeNaN: boolean, spelling?: string): AbsVal;
|
|
22
|
+
/** Any f64 a caller could pass — unbounded, not whole, NaN included. */
|
|
23
|
+
export declare const TOP: AbsVal;
|
|
24
|
+
/** The empty set (unreachable): lo > hi and no NaN. */
|
|
25
|
+
export declare const BOTTOM: AbsVal;
|
|
26
|
+
export declare const isBottom: (v: AbsVal) => boolean;
|
|
27
|
+
export declare const isSingleton: (v: AbsVal) => boolean;
|
|
28
|
+
export declare function constVal(value: number, spelling?: string): AbsVal;
|
|
29
|
+
/** Least upper bound: interval hull, wholeness/NaN pessimism, spelling
|
|
30
|
+
* kept only when both sides carry the same one. */
|
|
31
|
+
export declare function join(a: AbsVal, b: AbsVal): AbsVal;
|
|
32
|
+
export declare function sameVal(a: AbsVal, b: AbsVal): boolean;
|
|
33
|
+
export declare function widen(prev: AbsVal, next: AbsVal): AbsVal;
|
|
34
|
+
/** JS `~`: ToInt32, complement — whole, int32 range, whatever the input. */
|
|
35
|
+
export declare function transferBitNot(a: AbsVal): AbsVal;
|
|
36
|
+
export declare function transferNeg(a: AbsVal): AbsVal;
|
|
37
|
+
export declare function transferBin(op: IrNumBinOp, a: AbsVal, b: AbsVal): AbsVal;
|
|
38
|
+
/** The Math rounding family is the author's stated intent: every finite
|
|
39
|
+
* input maps to a whole output, so these discharge the WHOLENESS
|
|
40
|
+
* obligation. They do not discharge range (an unbounded input stays
|
|
41
|
+
* unbounded) or NaN (Math.trunc(NaN) is NaN — maybeNaN propagates). */
|
|
42
|
+
export declare function transferMathRound(fn: "trunc" | "floor" | "ceil" | "round", a: AbsVal): AbsVal;
|
|
43
|
+
export declare function transferAbs(a: AbsVal): AbsVal;
|
|
44
|
+
/** Math.min/max propagate NaN from ANY argument, exactly as JS does. */
|
|
45
|
+
export declare function transferMinMax(fn: "min" | "max", args: AbsVal[]): AbsVal;
|
|
46
|
+
export type IntClass = "i64" | "u64";
|
|
47
|
+
export type IntObligation = "representability" | "wholeness" | "range";
|
|
48
|
+
export interface IntVerdict {
|
|
49
|
+
/** The sidecar slot path (`Msg.count`, `Point.x`,
|
|
50
|
+
* `helpers.clamp.params[0]`, `exports.send.params[0]`). */
|
|
51
|
+
path: string;
|
|
52
|
+
cls: IntClass;
|
|
53
|
+
loc: SrcLoc;
|
|
54
|
+
outcome: "prove" | "refuse";
|
|
55
|
+
/** PROVE: the proven crossing range (the exact crossing value when the
|
|
56
|
+
* interval is a singleton); NaN/NaN for a vacuous (unreachable) proof. */
|
|
57
|
+
provenLo?: number;
|
|
58
|
+
provenHi?: number;
|
|
59
|
+
/** REFUSE: the failed obligation (the FIRST failure in the §2.4 order),
|
|
60
|
+
* the observed evidence, and the author's concrete fix. */
|
|
61
|
+
obligation?: IntObligation;
|
|
62
|
+
detail?: string;
|
|
63
|
+
fix?: string;
|
|
64
|
+
}
|
|
65
|
+
/** Does an integer literal's source spelling survive the trip through
|
|
66
|
+
* f64? Parse, convert, format back, compare (numeric separators were
|
|
67
|
+
* stripped by the frontend — they are spelling sugar, not value). */
|
|
68
|
+
export declare function spellingRoundTrips(spelling: string): boolean;
|
|
69
|
+
/** Check a converged abstract value against a slot's obligations, in the
|
|
70
|
+
* teaching-quality order: representability, then NaN, then range, then
|
|
71
|
+
* fractional wholeness — the FIRST failure names the refusal (a value
|
|
72
|
+
* both fractional and out of range hears about the more fundamental
|
|
73
|
+
* problem). */
|
|
74
|
+
export declare function checkBoundary(v: AbsVal, path: string, cls: IntClass, loc: SrcLoc): IntVerdict;
|
|
75
|
+
/** One function's declared integer slots: `params[i]` is the class of the
|
|
76
|
+
* i-th parameter (null = not integer-declared), `ret` the return's.
|
|
77
|
+
* `paramPaths`/`retPath` are the sidecar slot paths refusals carry. */
|
|
78
|
+
export interface FnIntSlots {
|
|
79
|
+
fnName: string;
|
|
80
|
+
params: (IntClass | null)[];
|
|
81
|
+
paramPaths: (string | null)[];
|
|
82
|
+
ret: IntClass | null;
|
|
83
|
+
retPath: string | null;
|
|
84
|
+
/** The plumbing classes of the NON-integer params (u8/u32/i32/f64/...):
|
|
85
|
+
* used to seed the callee's parameter environment precisely. */
|
|
86
|
+
paramSeeds: (AbsVal | null)[];
|
|
87
|
+
}
|
|
88
|
+
/** One record-field slot, resolved to an interned IR record shape: every
|
|
89
|
+
* program-side construction (recordLit) or write (recordSet) of `field`
|
|
90
|
+
* on shape `shapeId` must discharge the obligations. Shapes are interned
|
|
91
|
+
* STRUCTURALLY, so a second type with the identical field list shares the
|
|
92
|
+
* shape — and inherits the obligation, a sound over-approximation. */
|
|
93
|
+
export interface RecordIntSlot {
|
|
94
|
+
shapeId: string;
|
|
95
|
+
field: string;
|
|
96
|
+
cls: IntClass;
|
|
97
|
+
path: string;
|
|
98
|
+
}
|
|
99
|
+
export interface IntSlotConfig {
|
|
100
|
+
/** Keyed by IR function name. */
|
|
101
|
+
fns: Map<string, FnIntSlots>;
|
|
102
|
+
/** shapeId → field → slot. */
|
|
103
|
+
records: Map<string, Map<string, {
|
|
104
|
+
cls: IntClass;
|
|
105
|
+
path: string;
|
|
106
|
+
}>>;
|
|
107
|
+
}
|
|
108
|
+
export declare function hasIntSlots(cfg: IntSlotConfig): boolean;
|
|
109
|
+
/** The class seed for a declared parameter: what the slot's own contract
|
|
110
|
+
* proves about every value that ever arrives through it (internal calls
|
|
111
|
+
* are checked at their call sites; external calls range-check in the
|
|
112
|
+
* marshalling wrapper). */
|
|
113
|
+
export declare function classSeed(cls: string): AbsVal;
|
|
114
|
+
/** Run the inference over every function of a lowered library module and
|
|
115
|
+
* return one verdict per (obligation site) — internal call arguments into
|
|
116
|
+
* declared integer parameters, returns of declared integer returns, and
|
|
117
|
+
* writes into declared record-field slots. Callers turn REFUSE verdicts
|
|
118
|
+
* into diagnostics; PROVE verdicts carry the proven crossing range. */
|
|
119
|
+
export declare function checkLibraryIntegerSlots(mod: IrModule, cfg: IntSlotConfig): IntVerdict[];
|