@scriptc/compiler 0.2.8 → 0.2.9

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.
Files changed (189) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +1 -0
  2. package/dist/backend/cycle-analysis.js +50 -17
  3. package/dist/backend/cycle-analysis.js.map +1 -1
  4. package/dist/backend/cycle-analysis.test.js +138 -14
  5. package/dist/backend/cycle-analysis.test.js.map +1 -1
  6. package/dist/backend/cycle-mutability.d.ts +31 -6
  7. package/dist/backend/cycle-mutability.js +120 -18
  8. package/dist/backend/cycle-mutability.js.map +1 -1
  9. package/dist/backend/llvm/alloc.d.ts +13 -3
  10. package/dist/backend/llvm/alloc.js +24 -10
  11. package/dist/backend/llvm/alloc.js.map +1 -1
  12. package/dist/backend/llvm/alloc.test.js +5 -5
  13. package/dist/backend/llvm/alloc.test.js.map +1 -1
  14. package/dist/backend/llvm/byte-numbers.js +2 -3
  15. package/dist/backend/llvm/byte-numbers.js.map +1 -1
  16. package/dist/backend/llvm/classes.js +7 -6
  17. package/dist/backend/llvm/classes.js.map +1 -1
  18. package/dist/backend/llvm/common.d.ts +17 -0
  19. package/dist/backend/llvm/common.js +28 -0
  20. package/dist/backend/llvm/common.js.map +1 -1
  21. package/dist/backend/llvm/dense-array-access.js +1 -1
  22. package/dist/backend/llvm/dense-array-access.test.js +1 -1
  23. package/dist/backend/llvm/dyn.d.ts +4 -4
  24. package/dist/backend/llvm/dyn.js +27 -11
  25. package/dist/backend/llvm/dyn.js.map +1 -1
  26. package/dist/backend/llvm/emitter.d.ts +45 -3
  27. package/dist/backend/llvm/emitter.js +333 -74
  28. package/dist/backend/llvm/emitter.js.map +1 -1
  29. package/dist/backend/llvm/emitter.test.js +36 -3
  30. package/dist/backend/llvm/emitter.test.js.map +1 -1
  31. package/dist/backend/llvm/expr-bytes.js +35 -28
  32. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  33. package/dist/backend/llvm/expr-containers.js +1 -1
  34. package/dist/backend/llvm/expr-context.d.ts +2 -0
  35. package/dist/backend/llvm/expr-control.js +46 -5
  36. package/dist/backend/llvm/expr-control.js.map +1 -1
  37. package/dist/backend/llvm/expr-dynamic.js +3 -0
  38. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  39. package/dist/backend/llvm/expr-stream-bridges.d.ts +3 -0
  40. package/dist/backend/llvm/expr-stream-bridges.js +73 -11
  41. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  42. package/dist/backend/llvm/lib-filesystem.js +18 -2
  43. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  44. package/dist/backend/llvm/lib-shared.js +1 -0
  45. package/dist/backend/llvm/lib-shared.js.map +1 -1
  46. package/dist/backend/llvm/local-array-reads.d.ts +17 -6
  47. package/dist/backend/llvm/local-array-reads.js +155 -43
  48. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  49. package/dist/backend/llvm/reference-effects.js +34 -1
  50. package/dist/backend/llvm/reference-effects.js.map +1 -1
  51. package/dist/backend/llvm/shapes.d.ts +14 -3
  52. package/dist/backend/llvm/shapes.js +43 -12
  53. package/dist/backend/llvm/shapes.js.map +1 -1
  54. package/dist/backend/llvm/shapes.test.js +5 -5
  55. package/dist/backend/llvm/shapes.test.js.map +1 -1
  56. package/dist/backend/llvm/string-reads.js +29 -26
  57. package/dist/backend/llvm/string-reads.js.map +1 -1
  58. package/dist/backend/llvm/string-slices.js +1 -1
  59. package/dist/backend/llvm/trunc.d.ts +8 -0
  60. package/dist/backend/llvm/trunc.js +28 -0
  61. package/dist/backend/llvm/trunc.js.map +1 -0
  62. package/dist/backend/loop-polls.d.ts +14 -0
  63. package/dist/backend/loop-polls.js +100 -0
  64. package/dist/backend/loop-polls.js.map +1 -0
  65. package/dist/backend/loop-polls.test.d.ts +1 -0
  66. package/dist/backend/loop-polls.test.js +86 -0
  67. package/dist/backend/loop-polls.test.js.map +1 -0
  68. package/dist/backend/may-throw.js +20 -1
  69. package/dist/backend/may-throw.js.map +1 -1
  70. package/dist/backend/may-throw.test.js +23 -0
  71. package/dist/backend/may-throw.test.js.map +1 -1
  72. package/dist/backend/native-codegen.d.ts +1 -3
  73. package/dist/backend/native-codegen.js +4 -32
  74. package/dist/backend/native-codegen.js.map +1 -1
  75. package/dist/backend/runtime-abi.d.ts +2 -2
  76. package/dist/backend/runtime-abi.js +2 -2
  77. package/dist/backend/runtime-abi.js.map +1 -1
  78. package/dist/backend/runtime-pack-targets.test.js +1 -1
  79. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  80. package/dist/backend/runtime-pack.test.js +1 -1
  81. package/dist/backend/runtime-pack.test.js.map +1 -1
  82. package/dist/cli/command.js +8 -1
  83. package/dist/cli/command.js.map +1 -1
  84. package/dist/cli/output-options.d.ts +1 -0
  85. package/dist/cli/output-options.js +3 -0
  86. package/dist/cli/output-options.js.map +1 -1
  87. package/dist/cli/usage.d.ts +5 -1
  88. package/dist/cli/usage.js +6 -0
  89. package/dist/cli/usage.js.map +1 -1
  90. package/dist/compile-types.d.ts +5 -0
  91. package/dist/executable/executable-cache.d.ts +2 -0
  92. package/dist/executable/executable-cache.js +3 -0
  93. package/dist/executable/executable-cache.js.map +1 -1
  94. package/dist/executable/executable-cache.test.js +1 -0
  95. package/dist/executable/executable-cache.test.js.map +1 -1
  96. package/dist/frontend/lowering/array-values.js +37 -1
  97. package/dist/frontend/lowering/array-values.js.map +1 -1
  98. package/dist/frontend/lowering/builtins/strings.js +4 -1
  99. package/dist/frontend/lowering/builtins/strings.js.map +1 -1
  100. package/dist/frontend/lowering/call-arguments.js +96 -4
  101. package/dist/frontend/lowering/call-arguments.js.map +1 -1
  102. package/dist/frontend/lowering/class-method-mutations.js +88 -0
  103. package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
  104. package/dist/frontend/lowering/containers/bytes.js +15 -4
  105. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  106. package/dist/frontend/lowering/expressions/union-fields.d.ts +19 -0
  107. package/dist/frontend/lowering/expressions/union-fields.js +236 -0
  108. package/dist/frontend/lowering/expressions/union-fields.js.map +1 -0
  109. package/dist/frontend/lowering/lower-calls.js +12 -2
  110. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  111. package/dist/frontend/lowering/lower-exprs.d.ts +6 -0
  112. package/dist/frontend/lowering/lower-exprs.js +162 -3
  113. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  114. package/dist/frontend/lowering/lower-island.js +5 -19
  115. package/dist/frontend/lowering/lower-island.js.map +1 -1
  116. package/dist/frontend/lowering/lower-stmts.js +11 -1
  117. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  118. package/dist/frontend/lowering/lowerer.d.ts +5 -0
  119. package/dist/frontend/lowering/lowerer.js +174 -8
  120. package/dist/frontend/lowering/lowerer.js.map +1 -1
  121. package/dist/frontend/lowering/nan-coded-reads.d.ts +161 -0
  122. package/dist/frontend/lowering/nan-coded-reads.js +1342 -0
  123. package/dist/frontend/lowering/nan-coded-reads.js.map +1 -0
  124. package/dist/frontend/lowering/runtime-optional-bounds.d.ts +14 -2
  125. package/dist/frontend/lowering/runtime-optional-bounds.js +17 -11
  126. package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
  127. package/dist/frontend/lowering/runtime-optional-bounds.test.js +28 -0
  128. package/dist/frontend/lowering/runtime-optional-bounds.test.js.map +1 -1
  129. package/dist/frontend/lowering/surfaces.js +8 -0
  130. package/dist/frontend/lowering/surfaces.js.map +1 -1
  131. package/dist/index.d.ts +1 -1
  132. package/dist/index.js +20 -8
  133. package/dist/index.js.map +1 -1
  134. package/dist/ir/builtin-signatures.d.ts +1 -1
  135. package/dist/ir/builtin-signatures.js +2 -0
  136. package/dist/ir/builtin-signatures.js.map +1 -1
  137. package/dist/ir/constant-globals.d.ts +14 -0
  138. package/dist/ir/constant-globals.js +81 -0
  139. package/dist/ir/constant-globals.js.map +1 -0
  140. package/dist/ir/constant-globals.test.d.ts +1 -0
  141. package/dist/ir/constant-globals.test.js +97 -0
  142. package/dist/ir/constant-globals.test.js.map +1 -0
  143. package/dist/ir/final-fields.d.ts +35 -0
  144. package/dist/ir/final-fields.js +187 -0
  145. package/dist/ir/final-fields.js.map +1 -0
  146. package/dist/ir/final-fields.test.d.ts +1 -0
  147. package/dist/ir/final-fields.test.js +106 -0
  148. package/dist/ir/final-fields.test.js.map +1 -0
  149. package/dist/ir/int32-slots.d.ts +9 -0
  150. package/dist/ir/int32-slots.js +70 -57
  151. package/dist/ir/int32-slots.js.map +1 -1
  152. package/dist/ir/int32-slots.test.js +27 -0
  153. package/dist/ir/int32-slots.test.js.map +1 -1
  154. package/dist/ir/integer-loops.d.ts +5 -0
  155. package/dist/ir/integer-loops.js +20 -4
  156. package/dist/ir/integer-loops.js.map +1 -1
  157. package/dist/ir/integer-loops.test.js +17 -0
  158. package/dist/ir/integer-loops.test.js.map +1 -1
  159. package/dist/ir/ir.d.ts +6 -1
  160. package/dist/ir/ir.js +4 -0
  161. package/dist/ir/ir.js.map +1 -1
  162. package/dist/ir/serialize.d.ts +12 -2
  163. package/dist/ir/serialize.js +190 -39
  164. package/dist/ir/serialize.js.map +1 -1
  165. package/dist/ir/serialize.test.js +65 -1
  166. package/dist/ir/serialize.test.js.map +1 -1
  167. package/dist/native/cache.d.ts +8 -1
  168. package/dist/native/cache.js +38 -1
  169. package/dist/native/cache.js.map +1 -1
  170. package/dist/native/cache.test.js +11 -0
  171. package/dist/native/cache.test.js.map +1 -1
  172. package/dist/native/compiler.js +4 -3
  173. package/dist/native/compiler.js.map +1 -1
  174. package/dist/native/prepare.d.ts +3 -1
  175. package/dist/native/prepare.js +63 -28
  176. package/dist/native/prepare.js.map +1 -1
  177. package/dist/native/prepare.test.js +23 -1
  178. package/dist/native/prepare.test.js.map +1 -1
  179. package/dist/native/text-file.d.ts +10 -0
  180. package/dist/native/text-file.js +41 -0
  181. package/dist/native/text-file.js.map +1 -0
  182. package/dist/text-parts.d.ts +5 -0
  183. package/dist/text-parts.js +36 -0
  184. package/dist/text-parts.js.map +1 -0
  185. package/package.json +20 -20
  186. package/surface-manifest.json +7 -1
  187. package/dist/frontend/lowering/expressions/union-field-write.d.ts +0 -8
  188. package/dist/frontend/lowering/expressions/union-field-write.js +0 -108
  189. package/dist/frontend/lowering/expressions/union-field-write.js.map +0 -1
@@ -0,0 +1,81 @@
1
+ import { everyStmtList, mapExprChildren, mapStmtChildren } from "./traverse.js";
2
+ /** Module constants such as `const DOT = 0x2e` read as their literal.
3
+ *
4
+ * A module-level binding is a global that the module initializer stores
5
+ * once; every other function loads it (a thread-local load in worker
6
+ * programs), which also hides the value from integer ranges, switch
7
+ * dispatch and LLVM's constant folding. When the global is immutable, has
8
+ * exactly one write in the program and that write stores a number or
9
+ * boolean literal, every read sees that literal: reads that could run before
10
+ * the store carry the frontend's initialization flag (`initFlag`) or a TDZ
11
+ * sentinel, and those globals are left alone. The store stays, so module
12
+ * namespace views and debuggers still find the value in the global. Library
13
+ * builds keep their globals: a host may observe them across the boundary. */
14
+ export function foldConstantGlobals(mod) {
15
+ if (mod.lib || !mod.globals?.length)
16
+ return mod;
17
+ const candidates = new Set();
18
+ for (const g of mod.globals)
19
+ if (!g.mutable &&
20
+ g.tdz !== true &&
21
+ g.initFlag === undefined &&
22
+ (g.type.kind === "f64" || g.type.kind === "bool"))
23
+ candidates.add(g.id);
24
+ if (candidates.size === 0)
25
+ return mod;
26
+ const writes = new Map();
27
+ const values = new Map();
28
+ const write = (id, value) => {
29
+ if (!candidates.has(id))
30
+ return;
31
+ writes.set(id, (writes.get(id) ?? 0) + 1);
32
+ if (value && (value.kind === "numLit" || value.kind === "boolLit"))
33
+ values.set(id, value);
34
+ else
35
+ values.delete(id);
36
+ };
37
+ for (const fn of mod.functions)
38
+ everyStmtList(fn.body, {
39
+ // Every node other than a read that names the binding is a write
40
+ // (assignments, loop and catch bindings, compound updates); only a
41
+ // plain assignment or declaration contributes a value.
42
+ stmt: (s) => {
43
+ if (s.kind === "assign")
44
+ write(s.localId, s.value);
45
+ else if (s.kind === "varDecl")
46
+ write(s.localId, s.init);
47
+ else if ("localId" in s && typeof s.localId === "string")
48
+ write(s.localId, null);
49
+ return true;
50
+ },
51
+ expr: (e) => {
52
+ if (e.kind !== "varRef" && "localId" in e && typeof e.localId === "string")
53
+ write(e.localId, null);
54
+ return true;
55
+ },
56
+ });
57
+ const constants = new Map();
58
+ for (const [id, value] of values)
59
+ if (writes.get(id) === 1)
60
+ constants.set(id, value);
61
+ if (constants.size === 0)
62
+ return mod;
63
+ const reads = (e) => !(e.kind === "varRef" && constants.has(e.localId));
64
+ const rewriteExpr = (e) => {
65
+ if (e.kind === "varRef") {
66
+ const value = constants.get(e.localId);
67
+ return value ? { ...value, type: e.type, loc: e.loc } : e;
68
+ }
69
+ return mapExprChildren(e, rewriteExpr, rewriteStmt);
70
+ };
71
+ const rewriteStmt = (s) => mapStmtChildren(s, rewriteExpr, rewriteStmt);
72
+ let changed = false;
73
+ const functions = mod.functions.map((fn) => {
74
+ if (everyStmtList(fn.body, { stmt: () => true, expr: reads }))
75
+ return fn;
76
+ changed = true;
77
+ return { ...fn, body: fn.body.map(rewriteStmt) };
78
+ });
79
+ return changed ? { ...mod, functions } : mod;
80
+ }
81
+ //# sourceMappingURL=constant-globals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constant-globals.js","sourceRoot":"","sources":["../../src/ir/constant-globals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,97 @@
1
+ import { expect, test } from "vitest";
2
+ import { foldConstantGlobals } from "./constant-globals.js";
3
+ import { F64, VOID } from "./ir.js";
4
+ const loc = { file: "constant-globals.ts", start: 0, end: 0 };
5
+ const num = (value) => ({ loc, kind: "numLit", value, type: F64 });
6
+ const ref = (localId) => ({ loc, kind: "varRef", localId, type: F64 });
7
+ const assign = (localId, value) => ({
8
+ loc,
9
+ kind: "assign",
10
+ localId,
11
+ value,
12
+ });
13
+ const ret = (value) => ({ loc, kind: "return", value });
14
+ const fn = (name, body) => ({
15
+ loc,
16
+ name,
17
+ params: [],
18
+ locals: [],
19
+ returnType: name === "%init" ? VOID : F64,
20
+ body,
21
+ });
22
+ const global = (id, extra = {}) => ({
23
+ id,
24
+ name: id,
25
+ type: F64,
26
+ mutable: false,
27
+ ...extra,
28
+ });
29
+ test("immutable globals stored once with a literal read as that literal", () => {
30
+ const mod = {
31
+ irVersion: 15,
32
+ sourceFile: "constant-globals.ts",
33
+ entry: "%init",
34
+ functions: [
35
+ fn("%init", [
36
+ assign("%g.DOT", num(46)),
37
+ assign("%g.LATE", num(7)),
38
+ assign("%g.TWICE", num(1)),
39
+ assign("%g.TWICE", num(2)),
40
+ assign("%g.MUT", num(3)),
41
+ ]),
42
+ fn("read", [
43
+ ret({
44
+ loc,
45
+ kind: "bin",
46
+ op: "+",
47
+ left: ref("%g.DOT"),
48
+ right: {
49
+ loc,
50
+ kind: "bin",
51
+ op: "+",
52
+ left: ref("%g.LATE"),
53
+ right: {
54
+ loc,
55
+ kind: "bin",
56
+ op: "+",
57
+ left: ref("%g.TWICE"),
58
+ right: ref("%g.MUT"),
59
+ type: F64,
60
+ },
61
+ type: F64,
62
+ },
63
+ type: F64,
64
+ }),
65
+ ]),
66
+ ],
67
+ classes: [],
68
+ records: [],
69
+ unions: [],
70
+ globals: [
71
+ global("%g.DOT"),
72
+ global("%g.LATE", { initFlag: "%g.LATE.initialized" }),
73
+ global("%g.TWICE"),
74
+ global("%g.MUT", { mutable: true }),
75
+ ],
76
+ };
77
+ const folded = foldConstantGlobals(mod);
78
+ const reads = [];
79
+ const walk = (e) => {
80
+ if (e.kind === "varRef")
81
+ reads.push(e.localId);
82
+ else if (e.kind === "numLit")
83
+ reads.push(String(e.value));
84
+ else if (e.kind === "bin") {
85
+ walk(e.left);
86
+ walk(e.right);
87
+ }
88
+ };
89
+ const body = folded.functions.find((f) => f.name === "read").body[0];
90
+ if (body.kind === "return" && body.value)
91
+ walk(body.value);
92
+ expect(reads).toEqual(["46", "%g.LATE", "%g.TWICE", "%g.MUT"]);
93
+ // The initializer keeps its store; the input module is not modified.
94
+ expect(folded.functions[0]).toBe(mod.functions[0]);
95
+ expect(mod.functions[1].body[0]).not.toBe(body);
96
+ });
97
+ //# sourceMappingURL=constant-globals.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constant-globals.test.js","sourceRoot":"","sources":["../../src/ir/constant-globals.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { type IrClassDef, type IrModule } from "./ir.js";
2
+ /** Whole-program final reference fields.
3
+ *
4
+ * A reference-counted class field is final when every write the program can
5
+ * make to it is a constructor of its family storing through that
6
+ * constructor's own `this`. Outside the constructors such a field never
7
+ * changes, so while its object is alive the field keeps its value alive: a
8
+ * read of `o.f` may be borrowed for as long as `o` itself is (`this.scanner`
9
+ * inside a method, across any call), without a retain and a release.
10
+ * Constructors are excluded from that use, because they are where the field
11
+ * changes; so are async functions and generators, whose suspensions let
12
+ * other code (a constructor that is still running) continue.
13
+ *
14
+ * Writes the IR does not show disqualify fields up front: library builds
15
+ * (instances cross a native boundary), live dynamic views whose stores can
16
+ * name the field (see dynamicFieldStores), and classes with runtime-provided
17
+ * or generic ancestors. Generated stores only initialize fresh objects or
18
+ * tear down dead ones. */
19
+ export declare class FinalFields {
20
+ private readonly classes;
21
+ private readonly finals;
22
+ private readonly familyOf;
23
+ /** Disqualified families and the first reason, for tests. */
24
+ readonly reasons: Map<string, string>;
25
+ constructor(classes?: ReadonlyMap<string, IrClassDef>);
26
+ /** The topmost class in the base chain declaring the field, and the field. */
27
+ family(className: string, field: string): string | null;
28
+ isFinal(className: string, field: string): boolean;
29
+ get size(): number;
30
+ add(family: string): void;
31
+ drop(family: string, why: string): void;
32
+ }
33
+ /** `%C.constructor`'s class name, or null for any other function. */
34
+ export declare function constructorClass(fnName: string): string | null;
35
+ export declare function analyzeFinalFields(mod: IrModule): FinalFields;
@@ -0,0 +1,187 @@
1
+ import { isRefCounted } from "./ir.js";
2
+ import { dynamicFieldStores } from "./int32-slots.js";
3
+ import { everyExprChild, everyStmtChild } from "./traverse.js";
4
+ /** Whole-program final reference fields.
5
+ *
6
+ * A reference-counted class field is final when every write the program can
7
+ * make to it is a constructor of its family storing through that
8
+ * constructor's own `this`. Outside the constructors such a field never
9
+ * changes, so while its object is alive the field keeps its value alive: a
10
+ * read of `o.f` may be borrowed for as long as `o` itself is (`this.scanner`
11
+ * inside a method, across any call), without a retain and a release.
12
+ * Constructors are excluded from that use, because they are where the field
13
+ * changes; so are async functions and generators, whose suspensions let
14
+ * other code (a constructor that is still running) continue.
15
+ *
16
+ * Writes the IR does not show disqualify fields up front: library builds
17
+ * (instances cross a native boundary), live dynamic views whose stores can
18
+ * name the field (see dynamicFieldStores), and classes with runtime-provided
19
+ * or generic ancestors. Generated stores only initialize fresh objects or
20
+ * tear down dead ones. */
21
+ export class FinalFields {
22
+ classes;
23
+ finals = new Set();
24
+ familyOf = new Map();
25
+ /** Disqualified families and the first reason, for tests. */
26
+ reasons = new Map();
27
+ constructor(classes = new Map()) {
28
+ this.classes = classes;
29
+ }
30
+ /** The topmost class in the base chain declaring the field, and the field. */
31
+ family(className, field) {
32
+ const key = `${className}\0${field}`;
33
+ const cached = this.familyOf.get(key);
34
+ if (cached !== undefined)
35
+ return cached;
36
+ let owner = this.classes.get(className);
37
+ let result = null;
38
+ if (owner?.fields.some((f) => f.name === field)) {
39
+ for (;;) {
40
+ const base = owner.base ? this.classes.get(owner.base) : undefined;
41
+ if (!base?.fields.some((f) => f.name === field))
42
+ break;
43
+ owner = base;
44
+ }
45
+ result = `${owner.name}\0${field}`;
46
+ }
47
+ this.familyOf.set(key, result);
48
+ return result;
49
+ }
50
+ isFinal(className, field) {
51
+ if (this.finals.size === 0)
52
+ return false;
53
+ const family = this.family(className, field);
54
+ return family !== null && this.finals.has(family);
55
+ }
56
+ get size() {
57
+ return this.finals.size;
58
+ }
59
+ /* ── construction (analyzeFinalFields only) ── */
60
+ add(family) {
61
+ this.finals.add(family);
62
+ }
63
+ drop(family, why) {
64
+ if (!this.reasons.has(family))
65
+ this.reasons.set(family, why);
66
+ this.finals.delete(family);
67
+ }
68
+ }
69
+ const CONSTRUCTOR_SUFFIX = ".constructor";
70
+ /** `%C.constructor`'s class name, or null for any other function. */
71
+ export function constructorClass(fnName) {
72
+ return fnName.startsWith("%") && fnName.endsWith(CONSTRUCTOR_SUFFIX)
73
+ ? fnName.slice(1, -CONSTRUCTOR_SUFFIX.length)
74
+ : null;
75
+ }
76
+ export function analyzeFinalFields(mod) {
77
+ const classes = new Map((mod.classes ?? []).map((c) => [c.name, c]));
78
+ const finals = new FinalFields(classes);
79
+ if (mod.lib)
80
+ return finals;
81
+ const dynamic = dynamicFieldStores(mod);
82
+ if (dynamic.all)
83
+ return finals;
84
+ const genericFamilies = new Set();
85
+ for (const cls of classes.values())
86
+ if (cls.genericOf !== undefined) {
87
+ genericFamilies.add(cls.name);
88
+ genericFamilies.add(cls.genericOf);
89
+ }
90
+ const plainClass = (cls) => {
91
+ for (let c = cls; c; c = c.base ? classes.get(c.base) : undefined) {
92
+ if (c.runtime || genericFamilies.has(c.name))
93
+ return false;
94
+ if (c.base && !classes.has(c.base))
95
+ return false;
96
+ }
97
+ return true;
98
+ };
99
+ const inFamily = (className, family) => {
100
+ const owner = family.slice(0, family.indexOf("\0"));
101
+ for (let c = classes.get(className); c; c = c.base ? classes.get(c.base) : undefined)
102
+ if (c.name === owner)
103
+ return true;
104
+ return false;
105
+ };
106
+ for (const cls of classes.values())
107
+ for (const field of cls.fields) {
108
+ if (!isRefCounted(field.type) || field.name.startsWith("%"))
109
+ continue;
110
+ const family = finals.family(cls.name, field.name);
111
+ if (finals.reasons.has(family))
112
+ continue;
113
+ if (!plainClass(cls))
114
+ finals.drop(family, "runtime-provided or generic class");
115
+ else if (dynamic.names.has(field.name))
116
+ finals.drop(family, "dynamic stores can name the field");
117
+ else
118
+ finals.add(family);
119
+ }
120
+ if (finals.size === 0)
121
+ return finals;
122
+ for (const fn of mod.functions) {
123
+ const ctor = constructorClass(fn.name);
124
+ const self = ctor !== null ? fn.params[0]?.localId : undefined;
125
+ const selfLocal = self !== undefined ? fn.locals.find((l) => l.id === self) : undefined;
126
+ // `this` must name the object under construction for the whole body.
127
+ const constructing = selfLocal !== undefined && !selfLocal.boxed && !reassigns(fn.body, self);
128
+ const stmt = (s) => {
129
+ if (s.kind === "fieldSet") {
130
+ const family = finals.family(s.className, s.field);
131
+ if (family !== null && finals.isFinal(s.className, s.field)) {
132
+ const own = constructing && ctor !== null && inFamily(ctor, family) && isSelf(s.obj, self);
133
+ if (!own)
134
+ finals.drop(family, `written in ${fn.name}`);
135
+ }
136
+ }
137
+ return everyStmtChild(s, expr, stmt);
138
+ };
139
+ const expr = (e) => everyExprChild(e, expr, stmt);
140
+ for (const s of fn.body)
141
+ stmt(s);
142
+ }
143
+ return finals;
144
+ }
145
+ /** `this` itself, or behind the derived constructor's guards (`if (!super
146
+ * called) throw`), which read no reference and write nothing. */
147
+ function isSelf(e, self) {
148
+ if (e.kind === "varRef")
149
+ return e.localId === self;
150
+ if (e.kind !== "seqExpr")
151
+ return false;
152
+ for (const s of e.stmts) {
153
+ if (s.kind !== "if" || s.else_ !== null || s.then.length !== 1)
154
+ return false;
155
+ const only = s.then[0];
156
+ if (only.kind !== "exprStmt" ||
157
+ only.expr.kind !== "libCall" ||
158
+ only.expr.fn !== "error.nodeThrow" ||
159
+ !only.expr.args.every((arg) => arg.kind === "numLit" || arg.kind === "strLit") ||
160
+ !throwFreeCondition(s.cond))
161
+ return false;
162
+ }
163
+ return isSelf(e.result, self);
164
+ }
165
+ function throwFreeCondition(e) {
166
+ if (e.kind === "varRef" || e.kind === "boolLit")
167
+ return e.type.kind === "bool";
168
+ return e.kind === "unary" && throwFreeCondition(e.operand);
169
+ }
170
+ function reassigns(body, localId) {
171
+ let found = false;
172
+ const expr = (e) => {
173
+ if ((e.kind === "assignExpr" || e.kind === "incDec") && e.localId === localId)
174
+ found = true;
175
+ return !found && everyExprChild(e, expr, stmt);
176
+ };
177
+ const stmt = (s) => {
178
+ if (s.kind === "assign" && s.localId === localId && s.initializes !== true)
179
+ found = true;
180
+ return !found && everyStmtChild(s, expr, stmt);
181
+ };
182
+ for (const s of body)
183
+ if (!stmt(s))
184
+ break;
185
+ return found;
186
+ }
187
+ //# sourceMappingURL=final-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"final-fields.js","sourceRoot":"","sources":["../../src/ir/final-fields.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,106 @@
1
+ import { expect, test } from "vitest";
2
+ import { analyzeFinalFields, constructorClass } from "./final-fields.js";
3
+ import { BOOL, STRING, VOID, } from "./ir.js";
4
+ const loc = { file: "final-fields.ts", start: 0, end: 0 };
5
+ const obj = (className) => ({ kind: "object", className });
6
+ const ref = (localId, type) => ({ loc, kind: "varRef", localId, type });
7
+ const str = (value) => ({ loc, kind: "strLit", value, type: STRING });
8
+ const set = (target, className, field, value) => ({
9
+ loc,
10
+ kind: "fieldSet",
11
+ obj: target,
12
+ className,
13
+ field,
14
+ value,
15
+ });
16
+ const fn = (name, self, body) => ({
17
+ loc,
18
+ name,
19
+ params: self ? [{ localId: "this", name: "this", type: obj(self) }] : [],
20
+ locals: self ? [{ id: "this", name: "this", type: obj(self), mutable: false }] : [],
21
+ returnType: VOID,
22
+ body,
23
+ });
24
+ const cls = (name, fields, base) => ({
25
+ loc,
26
+ name,
27
+ ...(base ? { base } : {}),
28
+ fields: fields.map((field) => ({ name: field, type: STRING })),
29
+ });
30
+ const mod = (classes, functions) => ({
31
+ irVersion: 15,
32
+ sourceFile: "final-fields.ts",
33
+ entry: "%main",
34
+ classes,
35
+ functions: [fn("%main", null, []), ...functions],
36
+ records: [],
37
+ unions: [],
38
+ globals: [],
39
+ });
40
+ const self = (className) => ref("this", obj(className));
41
+ test("constructor names map to their class", () => {
42
+ expect(constructorClass("%%m1.Parser.constructor")).toBe("%m1.Parser");
43
+ expect(constructorClass("%%m1.Parser.parse")).toBeNull();
44
+ });
45
+ test("fields written only through their constructors' this are final", () => {
46
+ const finals = analyzeFinalFields(mod([cls("A", ["kept", "moved"]), cls("B", ["kept", "moved", "own"], "A")], [
47
+ fn("%A.constructor", "A", [
48
+ set(self("A"), "A", "kept", str("a")),
49
+ set(self("A"), "A", "kept", str("twice")),
50
+ set(self("A"), "A", "moved", str("a")),
51
+ ]),
52
+ // A subclass constructor initializes its base's field through a guard.
53
+ fn("%B.constructor", "B", [
54
+ set({
55
+ loc,
56
+ kind: "seqExpr",
57
+ stmts: [
58
+ {
59
+ loc,
60
+ kind: "if",
61
+ cond: {
62
+ loc,
63
+ kind: "unary",
64
+ op: "!",
65
+ operand: ref("superCalled", BOOL),
66
+ type: BOOL,
67
+ },
68
+ then: [
69
+ {
70
+ loc,
71
+ kind: "exprStmt",
72
+ expr: {
73
+ loc,
74
+ kind: "libCall",
75
+ fn: "error.nodeThrow",
76
+ args: [str("ReferenceError")],
77
+ type: VOID,
78
+ },
79
+ },
80
+ ],
81
+ else_: null,
82
+ },
83
+ ],
84
+ result: self("B"),
85
+ type: obj("B"),
86
+ }, "B", "own", str("b")),
87
+ ]),
88
+ // Any write elsewhere disqualifies the field family.
89
+ fn("%A.reset", "A", [set(self("A"), "A", "moved", str("later"))]),
90
+ ]));
91
+ expect(finals.isFinal("A", "kept")).toBe(true);
92
+ expect(finals.isFinal("B", "kept")).toBe(true);
93
+ expect(finals.isFinal("B", "own")).toBe(true);
94
+ expect(finals.isFinal("A", "moved")).toBe(false);
95
+ expect(finals.isFinal("B", "moved")).toBe(false);
96
+ expect(finals.reasons.get("A\0moved")).toBe("written in %A.reset");
97
+ });
98
+ test("constructors writing another object, and library builds, are not final", () => {
99
+ const other = fn("%A.constructor", "A", [set(ref("peer", obj("A")), "A", "kept", str("a"))]);
100
+ other.locals.push({ id: "peer", name: "peer", type: obj("A"), mutable: false });
101
+ expect(analyzeFinalFields(mod([cls("A", ["kept"])], [other])).isFinal("A", "kept")).toBe(false);
102
+ const library = mod([cls("A", ["kept"])], []);
103
+ library.lib = { profile: "p" };
104
+ expect(analyzeFinalFields(library).size).toBe(0);
105
+ });
106
+ //# sourceMappingURL=final-fields.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"final-fields.test.js","sourceRoot":"","sources":["../../src/ir/final-fields.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,IAAI,EACJ,MAAM,EACN,IAAI,GAOL,MAAM,SAAS,CAAC;AAEjB,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAC1D,MAAM,GAAG,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;AAC3E,MAAM,GAAG,GAAG,CAAC,OAAe,EAAE,IAAY,EAAU,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAChG,MAAM,GAAG,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AACtF,MAAM,GAAG,GAAG,CAAC,MAAc,EAAE,SAAiB,EAAE,KAAa,EAAE,KAAa,EAAU,EAAE,CAAC,CAAC;IACxF,GAAG;IACH,IAAI,EAAE,UAAU;IAChB,GAAG,EAAE,MAAM;IACX,SAAS;IACT,KAAK;IACL,KAAK;CACN,CAAC,CAAC;AACH,MAAM,EAAE,GAAG,CAAC,IAAY,EAAE,IAAmB,EAAE,IAAc,EAAc,EAAE,CAAC,CAAC;IAC7E,GAAG;IACH,IAAI;IACJ,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;IACxE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;IACnF,UAAU,EAAE,IAAI;IAChB,IAAI;CACL,CAAC,CAAC;AACH,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,MAAgB,EAAE,IAAa,EAAc,EAAE,CAAC,CAAC;IAC1E,GAAG;IACH,IAAI;IACJ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;CAC/D,CAAC,CAAC;AACH,MAAM,GAAG,GAAG,CAAC,OAAqB,EAAE,SAAuB,EAAY,EAAE,CAAC,CAAC;IACzE,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,iBAAiB;IAC7B,KAAK,EAAE,OAAO;IACd,OAAO;IACP,SAAS,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC;IAChD,OAAO,EAAE,EAAE;IACX,MAAM,EAAE,EAAE;IACV,OAAO,EAAE,EAAE;CACZ,CAAC,CAAC;AACH,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;AAExE,IAAI,CAAC,sCAAsC,EAAE,GAAG,EAAE;IAChD,MAAM,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvE,MAAM,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,GAAG,EAAE;IAC1E,MAAM,MAAM,GAAG,kBAAkB,CAC/B,GAAG,CACD,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,EACtE;QACE,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;YACrC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACzC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;SACvC,CAAC;QACF,uEAAuE;QACvE,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,GAAG,CACD;gBACE,GAAG;gBACH,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE;oBACL;wBACE,GAAG;wBACH,IAAI,EAAE,IAAI;wBACV,IAAI,EAAE;4BACJ,GAAG;4BACH,IAAI,EAAE,OAAO;4BACb,EAAE,EAAE,GAAG;4BACP,OAAO,EAAE,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC;4BACjC,IAAI,EAAE,IAAI;yBACX;wBACD,IAAI,EAAE;4BACJ;gCACE,GAAG;gCACH,IAAI,EAAE,UAAU;gCAChB,IAAI,EAAE;oCACJ,GAAG;oCACH,IAAI,EAAE,SAAS;oCACf,EAAE,EAAE,iBAAiB;oCACrB,IAAI,EAAE,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;oCAC7B,IAAI,EAAE,IAAI;iCACX;6BACF;yBACF;wBACD,KAAK,EAAE,IAAI;qBACZ;iBACF;gBACD,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC;gBACjB,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC;aACf,EACD,GAAG,EACH,KAAK,EACL,GAAG,CAAC,GAAG,CAAC,CACT;SACF,CAAC;QACF,qDAAqD;QACrD,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;KAClE,CACF,CACF,CAAC;IACF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wEAAwE,EAAE,GAAG,EAAE;IAClF,MAAM,KAAK,GAAG,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAChF,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChG,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,GAAG,EAAE,OAAO,EAAE,GAAG,EAA6C,CAAC;IAC1E,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC"}
@@ -69,4 +69,13 @@ export declare class Int32Slots {
69
69
  get returnCount(): number;
70
70
  get paramCount(): number;
71
71
  }
72
+ /** The class field names that runtime stores through live dynamic views
73
+ * (typed-ref capsules) can write: every name when `all` (islands, jsval
74
+ * values, or a dynamic store whose key is not a literal), otherwise the
75
+ * literal keys of `dyn.keySet`/`dyn.keyDelete`. A view commits a store back
76
+ * into the instance's native field slots, which the IR does not show. */
77
+ export declare function dynamicFieldStores(mod: IrModule, records?: Map<string, import("./ir.js").IrRecordShape>, unions?: Map<string, import("./ir.js").IrUnionDef>): {
78
+ all: boolean;
79
+ names: Set<string>;
80
+ };
72
81
  export declare function analyzeInt32Slots(mod: IrModule): Int32Slots;