@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.
- package/ambient/scriptc-node-fallback.d.ts +1 -0
- package/dist/backend/cycle-analysis.js +50 -17
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +138 -14
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.d.ts +31 -6
- package/dist/backend/cycle-mutability.js +120 -18
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +13 -3
- package/dist/backend/llvm/alloc.js +24 -10
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +5 -5
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +2 -3
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/classes.js +7 -6
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +17 -0
- package/dist/backend/llvm/common.js +28 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.js +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +1 -1
- package/dist/backend/llvm/dyn.d.ts +4 -4
- package/dist/backend/llvm/dyn.js +27 -11
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +45 -3
- package/dist/backend/llvm/emitter.js +333 -74
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +36 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +35 -28
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +1 -1
- package/dist/backend/llvm/expr-context.d.ts +2 -0
- package/dist/backend/llvm/expr-control.js +46 -5
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +3 -0
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +3 -0
- package/dist/backend/llvm/expr-stream-bridges.js +73 -11
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +18 -2
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +1 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +17 -6
- package/dist/backend/llvm/local-array-reads.js +155 -43
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +34 -1
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +14 -3
- package/dist/backend/llvm/shapes.js +43 -12
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +5 -5
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/string-reads.js +29 -26
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/string-slices.js +1 -1
- package/dist/backend/llvm/trunc.d.ts +8 -0
- package/dist/backend/llvm/trunc.js +28 -0
- package/dist/backend/llvm/trunc.js.map +1 -0
- package/dist/backend/loop-polls.d.ts +14 -0
- package/dist/backend/loop-polls.js +100 -0
- package/dist/backend/loop-polls.js.map +1 -0
- package/dist/backend/loop-polls.test.d.ts +1 -0
- package/dist/backend/loop-polls.test.js +86 -0
- package/dist/backend/loop-polls.test.js.map +1 -0
- package/dist/backend/may-throw.js +20 -1
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +23 -0
- package/dist/backend/may-throw.test.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +1 -3
- package/dist/backend/native-codegen.js +4 -32
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-abi.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +1 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/cli/command.js +8 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/output-options.d.ts +1 -0
- package/dist/cli/output-options.js +3 -0
- package/dist/cli/output-options.js.map +1 -1
- package/dist/cli/usage.d.ts +5 -1
- package/dist/cli/usage.js +6 -0
- package/dist/cli/usage.js.map +1 -1
- package/dist/compile-types.d.ts +5 -0
- package/dist/executable/executable-cache.d.ts +2 -0
- package/dist/executable/executable-cache.js +3 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +1 -0
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/lowering/array-values.js +37 -1
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtins/strings.js +4 -1
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +96 -4
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +88 -0
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +15 -4
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-fields.d.ts +19 -0
- package/dist/frontend/lowering/expressions/union-fields.js +236 -0
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -0
- package/dist/frontend/lowering/lower-calls.js +12 -2
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +6 -0
- package/dist/frontend/lowering/lower-exprs.js +162 -3
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +5 -19
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +11 -1
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +5 -0
- package/dist/frontend/lowering/lowerer.js +174 -8
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +161 -0
- package/dist/frontend/lowering/nan-coded-reads.js +1342 -0
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.d.ts +14 -2
- package/dist/frontend/lowering/runtime-optional-bounds.js +17 -11
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-bounds.test.js +28 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.js.map +1 -1
- package/dist/frontend/lowering/surfaces.js +8 -0
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +20 -8
- package/dist/index.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +2 -0
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/constant-globals.d.ts +14 -0
- package/dist/ir/constant-globals.js +81 -0
- package/dist/ir/constant-globals.js.map +1 -0
- package/dist/ir/constant-globals.test.d.ts +1 -0
- package/dist/ir/constant-globals.test.js +97 -0
- package/dist/ir/constant-globals.test.js.map +1 -0
- package/dist/ir/final-fields.d.ts +35 -0
- package/dist/ir/final-fields.js +187 -0
- package/dist/ir/final-fields.js.map +1 -0
- package/dist/ir/final-fields.test.d.ts +1 -0
- package/dist/ir/final-fields.test.js +106 -0
- package/dist/ir/final-fields.test.js.map +1 -0
- package/dist/ir/int32-slots.d.ts +9 -0
- package/dist/ir/int32-slots.js +70 -57
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +27 -0
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +5 -0
- package/dist/ir/integer-loops.js +20 -4
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +17 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/ir.d.ts +6 -1
- package/dist/ir/ir.js +4 -0
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/serialize.d.ts +12 -2
- package/dist/ir/serialize.js +190 -39
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +65 -1
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/native/cache.d.ts +8 -1
- package/dist/native/cache.js +38 -1
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cache.test.js +11 -0
- package/dist/native/cache.test.js.map +1 -1
- package/dist/native/compiler.js +4 -3
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/prepare.d.ts +3 -1
- package/dist/native/prepare.js +63 -28
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +23 -1
- package/dist/native/prepare.test.js.map +1 -1
- package/dist/native/text-file.d.ts +10 -0
- package/dist/native/text-file.js +41 -0
- package/dist/native/text-file.js.map +1 -0
- package/dist/text-parts.d.ts +5 -0
- package/dist/text-parts.js +36 -0
- package/dist/text-parts.js.map +1 -0
- package/package.json +20 -20
- package/surface-manifest.json +7 -1
- package/dist/frontend/lowering/expressions/union-field-write.d.ts +0 -8
- package/dist/frontend/lowering/expressions/union-field-write.js +0 -108
- 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":"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"}
|
package/dist/ir/int32-slots.d.ts
CHANGED
|
@@ -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;
|