typesea 0.1.0 → 0.2.0
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/CHANGELOG.md +67 -6
- package/README.md +98 -17
- package/dist/adapters/index.d.ts +50 -8
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +169 -48
- package/dist/aot/index.d.ts +18 -2
- package/dist/aot/index.d.ts.map +1 -1
- package/dist/aot/index.js +93 -14
- package/dist/async/index.d.ts +28 -56
- package/dist/async/index.d.ts.map +1 -1
- package/dist/async/index.js +94 -37
- package/dist/builders/composite.d.ts +37 -6
- package/dist/builders/composite.d.ts.map +1 -1
- package/dist/builders/composite.js +84 -10
- package/dist/builders/index.d.ts +2 -0
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +2 -0
- package/dist/builders/modifier.d.ts +30 -5
- package/dist/builders/modifier.d.ts.map +1 -1
- package/dist/builders/modifier.js +38 -5
- package/dist/builders/object/guard.d.ts +18 -22
- package/dist/builders/object/guard.d.ts.map +1 -1
- package/dist/builders/object/guard.js +26 -26
- package/dist/builders/object/index.d.ts +2 -0
- package/dist/builders/object/index.d.ts.map +1 -1
- package/dist/builders/object/index.js +2 -0
- package/dist/builders/object/schema.d.ts +55 -9
- package/dist/builders/object/schema.d.ts.map +1 -1
- package/dist/builders/object/schema.js +92 -15
- package/dist/builders/object/types.d.ts +5 -31
- package/dist/builders/object/types.d.ts.map +1 -1
- package/dist/builders/object/types.js +2 -0
- package/dist/builders/scalar.d.ts +29 -8
- package/dist/builders/scalar.d.ts.map +1 -1
- package/dist/builders/scalar.js +33 -8
- package/dist/builders/table.d.ts +4 -0
- package/dist/builders/table.d.ts.map +1 -1
- package/dist/builders/table.js +4 -0
- package/dist/builders/types.d.ts +14 -4
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/builders/types.js +2 -0
- package/dist/compile/check-composite.d.ts +22 -1
- package/dist/compile/check-composite.d.ts.map +1 -1
- package/dist/compile/check-composite.js +564 -24
- package/dist/compile/check-scalar.d.ts +78 -0
- package/dist/compile/check-scalar.d.ts.map +1 -1
- package/dist/compile/check-scalar.js +432 -1
- package/dist/compile/check.d.ts +12 -0
- package/dist/compile/check.d.ts.map +1 -1
- package/dist/compile/check.js +37 -0
- package/dist/compile/context.d.ts +47 -9
- package/dist/compile/context.d.ts.map +1 -1
- package/dist/compile/context.js +51 -8
- package/dist/compile/graph-predicate.d.ts +4 -2
- package/dist/compile/graph-predicate.d.ts.map +1 -1
- package/dist/compile/graph-predicate.js +1907 -171
- package/dist/compile/guard.d.ts +15 -24
- package/dist/compile/guard.d.ts.map +1 -1
- package/dist/compile/guard.js +158 -74
- package/dist/compile/index.d.ts +3 -1
- package/dist/compile/index.d.ts.map +1 -1
- package/dist/compile/index.js +2 -0
- package/dist/compile/issue.d.ts +110 -0
- package/dist/compile/issue.d.ts.map +1 -1
- package/dist/compile/issue.js +184 -1
- package/dist/compile/names.d.ts +12 -2
- package/dist/compile/names.d.ts.map +1 -1
- package/dist/compile/names.js +19 -3
- package/dist/compile/predicate.d.ts +24 -0
- package/dist/compile/predicate.d.ts.map +1 -1
- package/dist/compile/predicate.js +131 -5
- package/dist/compile/runtime.d.ts +80 -12
- package/dist/compile/runtime.d.ts.map +1 -1
- package/dist/compile/runtime.js +25 -6
- package/dist/compile/source.d.ts +10 -2
- package/dist/compile/source.d.ts.map +1 -1
- package/dist/compile/source.js +361 -26
- package/dist/compile/types.d.ts +20 -0
- package/dist/compile/types.d.ts.map +1 -1
- package/dist/compile/types.js +2 -0
- package/dist/decoder/index.d.ts +32 -46
- package/dist/decoder/index.d.ts.map +1 -1
- package/dist/decoder/index.js +102 -38
- package/dist/evaluate/check-composite.d.ts +59 -0
- package/dist/evaluate/check-composite.d.ts.map +1 -1
- package/dist/evaluate/check-composite.js +151 -3
- package/dist/evaluate/check-scalar.d.ts +16 -0
- package/dist/evaluate/check-scalar.d.ts.map +1 -1
- package/dist/evaluate/check-scalar.js +32 -0
- package/dist/evaluate/check.d.ts +7 -0
- package/dist/evaluate/check.d.ts.map +1 -1
- package/dist/evaluate/check.js +43 -0
- package/dist/evaluate/index.d.ts +2 -0
- package/dist/evaluate/index.d.ts.map +1 -1
- package/dist/evaluate/index.js +2 -0
- package/dist/evaluate/issue.d.ts +11 -1
- package/dist/evaluate/issue.d.ts.map +1 -1
- package/dist/evaluate/issue.js +15 -1
- package/dist/evaluate/predicate.d.ts +16 -5
- package/dist/evaluate/predicate.d.ts.map +1 -1
- package/dist/evaluate/predicate.js +20 -5
- package/dist/evaluate/shared.d.ts +59 -13
- package/dist/evaluate/shared.d.ts.map +1 -1
- package/dist/evaluate/shared.js +66 -8
- package/dist/evaluate/state.d.ts +35 -13
- package/dist/evaluate/state.d.ts.map +1 -1
- package/dist/evaluate/state.js +35 -2
- package/dist/guard/base.d.ts +79 -29
- package/dist/guard/base.d.ts.map +1 -1
- package/dist/guard/base.js +91 -29
- package/dist/guard/error.d.ts +10 -5
- package/dist/guard/error.d.ts.map +1 -1
- package/dist/guard/error.js +10 -5
- package/dist/guard/index.d.ts +2 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +2 -0
- package/dist/guard/number.d.ts +26 -11
- package/dist/guard/number.d.ts.map +1 -1
- package/dist/guard/number.js +30 -11
- package/dist/guard/props.d.ts +27 -3
- package/dist/guard/props.d.ts.map +1 -1
- package/dist/guard/props.js +27 -3
- package/dist/guard/read.d.ts +62 -9
- package/dist/guard/read.d.ts.map +1 -1
- package/dist/guard/read.js +83 -10
- package/dist/guard/registry.d.ts +12 -2
- package/dist/guard/registry.d.ts.map +1 -1
- package/dist/guard/registry.js +15 -3
- package/dist/guard/string.d.ts +33 -13
- package/dist/guard/string.d.ts.map +1 -1
- package/dist/guard/string.js +37 -13
- package/dist/guard/types.d.ts +92 -40
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/guard/types.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/index.d.ts +42 -6
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +51 -8
- package/dist/ir/builder.d.ts +16 -126
- package/dist/ir/builder.d.ts.map +1 -1
- package/dist/ir/builder.js +77 -137
- package/dist/ir/freeze.d.ts +4 -0
- package/dist/ir/freeze.d.ts.map +1 -1
- package/dist/ir/freeze.js +59 -0
- package/dist/ir/index.d.ts +3 -1
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js +2 -0
- package/dist/ir/regexp.d.ts +2 -0
- package/dist/ir/regexp.d.ts.map +1 -1
- package/dist/ir/regexp.js +2 -0
- package/dist/ir/types.d.ts +90 -55
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js +2 -0
- package/dist/ir/validate.d.ts +8 -1
- package/dist/ir/validate.d.ts.map +1 -1
- package/dist/ir/validate.js +477 -61
- package/dist/issue/index.d.ts +41 -9
- package/dist/issue/index.d.ts.map +1 -1
- package/dist/issue/index.js +61 -11
- package/dist/json-schema/emit-combinator.d.ts +44 -4
- package/dist/json-schema/emit-combinator.d.ts.map +1 -1
- package/dist/json-schema/emit-combinator.js +44 -4
- package/dist/json-schema/emit-composite.d.ts +10 -0
- package/dist/json-schema/emit-composite.d.ts.map +1 -1
- package/dist/json-schema/emit-composite.js +15 -1
- package/dist/json-schema/emit-scalar.d.ts +26 -3
- package/dist/json-schema/emit-scalar.d.ts.map +1 -1
- package/dist/json-schema/emit-scalar.js +70 -9
- package/dist/json-schema/emit-types.d.ts +11 -1
- package/dist/json-schema/emit-types.d.ts.map +1 -1
- package/dist/json-schema/emit-types.js +2 -0
- package/dist/json-schema/emit.d.ts +12 -1
- package/dist/json-schema/emit.d.ts.map +1 -1
- package/dist/json-schema/emit.js +12 -1
- package/dist/json-schema/freeze.d.ts +13 -2
- package/dist/json-schema/freeze.d.ts.map +1 -1
- package/dist/json-schema/freeze.js +41 -8
- package/dist/json-schema/index.d.ts +16 -2
- package/dist/json-schema/index.d.ts.map +1 -1
- package/dist/json-schema/index.js +23 -3
- package/dist/json-schema/issue.d.ts +4 -1
- package/dist/json-schema/issue.d.ts.map +1 -1
- package/dist/json-schema/issue.js +4 -1
- package/dist/json-schema/read.d.ts +24 -3
- package/dist/json-schema/read.d.ts.map +1 -1
- package/dist/json-schema/read.js +59 -12
- package/dist/json-schema/types.d.ts +38 -15
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/json-schema/types.js +2 -0
- package/dist/kind/index.d.ts +15 -28
- package/dist/kind/index.d.ts.map +1 -1
- package/dist/kind/index.js +15 -10
- package/dist/lower/index.d.ts +6 -1
- package/dist/lower/index.d.ts.map +1 -1
- package/dist/lower/index.js +411 -44
- package/dist/message/index.d.ts +46 -10
- package/dist/message/index.d.ts.map +1 -1
- package/dist/message/index.js +88 -17
- package/dist/optimize/algebraic.d.ts +54 -0
- package/dist/optimize/algebraic.d.ts.map +1 -0
- package/dist/optimize/algebraic.js +314 -0
- package/dist/optimize/compact.d.ts +8 -1
- package/dist/optimize/compact.d.ts.map +1 -1
- package/dist/optimize/compact.js +13 -2
- package/dist/optimize/domain.d.ts +16 -0
- package/dist/optimize/domain.d.ts.map +1 -0
- package/dist/optimize/domain.js +615 -0
- package/dist/optimize/fold-boolean.d.ts +17 -2
- package/dist/optimize/fold-boolean.d.ts.map +1 -1
- package/dist/optimize/fold-boolean.js +59 -14
- package/dist/optimize/fold-common.d.ts +43 -8
- package/dist/optimize/fold-common.d.ts.map +1 -1
- package/dist/optimize/fold-common.js +37 -6
- package/dist/optimize/fold-constraints.d.ts +33 -0
- package/dist/optimize/fold-constraints.d.ts.map +1 -0
- package/dist/optimize/fold-constraints.js +484 -0
- package/dist/optimize/fold-scalar.d.ts +98 -13
- package/dist/optimize/fold-scalar.d.ts.map +1 -1
- package/dist/optimize/fold-scalar.js +98 -13
- package/dist/optimize/fold.d.ts +8 -1
- package/dist/optimize/fold.d.ts.map +1 -1
- package/dist/optimize/fold.js +22 -2
- package/dist/optimize/index.d.ts +9 -1
- package/dist/optimize/index.d.ts.map +1 -1
- package/dist/optimize/index.js +18 -3
- package/dist/optimize/map-node.d.ts +3 -1
- package/dist/optimize/map-node.d.ts.map +1 -1
- package/dist/optimize/map-node.js +45 -3
- package/dist/optimize/peephole.d.ts +16 -0
- package/dist/optimize/peephole.d.ts.map +1 -0
- package/dist/optimize/peephole.js +254 -0
- package/dist/optimize/remap.d.ts +2 -0
- package/dist/optimize/remap.d.ts.map +1 -1
- package/dist/optimize/remap.js +2 -0
- package/dist/optimize/rewrite.d.ts +13 -8
- package/dist/optimize/rewrite.d.ts.map +1 -1
- package/dist/optimize/rewrite.js +13 -8
- package/dist/plan/cache.d.ts +9 -3
- package/dist/plan/cache.d.ts.map +1 -1
- package/dist/plan/cache.js +21 -5
- package/dist/plan/index.d.ts +2 -0
- package/dist/plan/index.d.ts.map +1 -1
- package/dist/plan/index.js +2 -0
- package/dist/plan/predicate.d.ts +2 -0
- package/dist/plan/predicate.d.ts.map +1 -1
- package/dist/plan/predicate.js +268 -29
- package/dist/plan/schema-predicate.d.ts +6 -0
- package/dist/plan/schema-predicate.d.ts.map +1 -1
- package/dist/plan/schema-predicate.js +117 -13
- package/dist/plan/types.d.ts +2 -0
- package/dist/plan/types.d.ts.map +1 -1
- package/dist/plan/types.js +2 -0
- package/dist/result/index.d.ts +19 -5
- package/dist/result/index.d.ts.map +1 -1
- package/dist/result/index.js +10 -2
- package/dist/schema/common.d.ts +69 -6
- package/dist/schema/common.d.ts.map +1 -1
- package/dist/schema/common.js +104 -10
- package/dist/schema/freeze.d.ts +4 -0
- package/dist/schema/freeze.d.ts.map +1 -1
- package/dist/schema/freeze.js +18 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -0
- package/dist/schema/lazy.d.ts +4 -0
- package/dist/schema/lazy.d.ts.map +1 -1
- package/dist/schema/lazy.js +4 -0
- package/dist/schema/literal.d.ts +7 -1
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +7 -1
- package/dist/schema/types.d.ts +20 -96
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +5 -1
- package/dist/schema/undefined.d.ts +17 -0
- package/dist/schema/undefined.d.ts.map +1 -0
- package/dist/schema/undefined.js +72 -0
- package/dist/schema/validate.d.ts +8 -1
- package/dist/schema/validate.d.ts.map +1 -1
- package/dist/schema/validate.js +146 -55
- package/docs/api.md +57 -0
- package/docs/assets/benchmark-headline.svg +163 -0
- package/docs/engine-notes.md +58 -15
- package/docs/index.html +130 -110
- package/package.json +65 -65
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file fold-constraints.ts
|
|
3
|
+
* @brief Boolean constraint canonicalization for pure predicate runs.
|
|
4
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
5
|
+
* before code generation consumes the graph.
|
|
6
|
+
*/
|
|
7
|
+
import { NodeTag } from "../kind/index.js";
|
|
8
|
+
import { readConst } from "./fold-common.js";
|
|
9
|
+
/**
|
|
10
|
+
* @brief Numeric tags for runtime type facts extracted from predicate nodes.
|
|
11
|
+
* @details Numeric tags keep fact comparisons cheap and avoid string switching
|
|
12
|
+
* in the tight canonicalization scan.
|
|
13
|
+
*/
|
|
14
|
+
const TypeFactTag = {
|
|
15
|
+
String: 1,
|
|
16
|
+
Number: 2,
|
|
17
|
+
Boolean: 3,
|
|
18
|
+
BigInt: 4,
|
|
19
|
+
Symbol: 5,
|
|
20
|
+
Object: 6,
|
|
21
|
+
Array: 7,
|
|
22
|
+
Undefined: 8,
|
|
23
|
+
Null: 9
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* @brief canonicalize and values.
|
|
27
|
+
* @details Removes duplicate predicates and dominated scalar bounds while keeping
|
|
28
|
+
* the first observable execution order intact. Only the pure prefix may collapse
|
|
29
|
+
* the whole conjunction to `false`.
|
|
30
|
+
* @returns Canonical node id vector or a contradiction marker.
|
|
31
|
+
*/
|
|
32
|
+
export function canonicalizeAndValues(values, nodes) {
|
|
33
|
+
const omitted = new Array(values.length).fill(false);
|
|
34
|
+
const seen = new Set();
|
|
35
|
+
const pureEnd = findPurePrefixEnd(values, nodes);
|
|
36
|
+
omitDuplicateIds(values, omitted, seen);
|
|
37
|
+
if (canonicalizeTypeFacts(values, nodes, omitted, pureEnd)) {
|
|
38
|
+
return {
|
|
39
|
+
contradiction: true,
|
|
40
|
+
values: []
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (canonicalizeStringBounds(values, nodes, omitted, pureEnd)) {
|
|
44
|
+
return {
|
|
45
|
+
contradiction: true,
|
|
46
|
+
values: []
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (canonicalizeNumericBounds(values, nodes, omitted, pureEnd)) {
|
|
50
|
+
return {
|
|
51
|
+
contradiction: true,
|
|
52
|
+
values: []
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
contradiction: false,
|
|
57
|
+
values: collectKeptValues(values, omitted)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @brief canonicalize or values.
|
|
62
|
+
* @details Removes repeated node ids. Repeated ids are already memoized by graph
|
|
63
|
+
* execution, so this only shrinks emitted boolean expressions.
|
|
64
|
+
* @returns Canonical node id vector.
|
|
65
|
+
*/
|
|
66
|
+
export function canonicalizeOrValues(values) {
|
|
67
|
+
const kept = [];
|
|
68
|
+
const seen = new Set();
|
|
69
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
70
|
+
const value = values[index];
|
|
71
|
+
if (value === undefined || seen.has(value)) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
seen.add(value);
|
|
75
|
+
kept.push(value);
|
|
76
|
+
}
|
|
77
|
+
return kept;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* @brief Mark repeated node ids as omitted while preserving first occurrence.
|
|
81
|
+
* @details Graph execution memoizes node results, so repeated ids inside the
|
|
82
|
+
* same boolean fold only inflate generated expressions.
|
|
83
|
+
* @param values Original fold input node ids.
|
|
84
|
+
* @param omitted Mutable omission bitmap aligned with `values`.
|
|
85
|
+
* @param seen Mutable set used by the caller for duplicate tracking.
|
|
86
|
+
*/
|
|
87
|
+
function omitDuplicateIds(values, omitted, seen) {
|
|
88
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
89
|
+
const value = values[index];
|
|
90
|
+
if (value === undefined) {
|
|
91
|
+
omitted[index] = true;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (seen.has(value)) {
|
|
95
|
+
omitted[index] = true;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
seen.add(value);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* @brief Remove duplicate type predicates and detect impossible type pairs.
|
|
103
|
+
* @details The scan is limited to the pure prefix so dynamic schema checks and
|
|
104
|
+
* composite loops keep their original execution order. Conflicting facts turn
|
|
105
|
+
* the whole conjunction into a contradiction.
|
|
106
|
+
* @param values Original fold input node ids.
|
|
107
|
+
* @param nodes Graph node table.
|
|
108
|
+
* @param omitted Mutable omission bitmap aligned with `values`.
|
|
109
|
+
* @param end Exclusive end of the pure scalar prefix.
|
|
110
|
+
* @returns True when the facts prove the conjunction impossible.
|
|
111
|
+
*/
|
|
112
|
+
function canonicalizeTypeFacts(values, nodes, omitted, end) {
|
|
113
|
+
const facts = new Map();
|
|
114
|
+
for (let index = 0; index < end; index += 1) {
|
|
115
|
+
if (omitted[index] === true) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const id = values[index];
|
|
119
|
+
const node = id === undefined ? undefined : nodes[id];
|
|
120
|
+
const fact = node === undefined ? undefined : readTypeFact(node, index);
|
|
121
|
+
if (id === undefined || fact === undefined) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const previous = facts.get(fact.value);
|
|
125
|
+
if (previous === undefined) {
|
|
126
|
+
facts.set(fact.value, fact);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (previous.tag !== fact.tag) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
if (previous.tag === TypeFactTag.Number && previous.integer !== fact.integer) {
|
|
133
|
+
if (previous.integer) {
|
|
134
|
+
omitted[index] = true;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
omitted[previous.index] = true;
|
|
138
|
+
facts.set(fact.value, fact);
|
|
139
|
+
}
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
omitted[index] = true;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* @brief Keep only the strongest string-length bounds in the pure prefix.
|
|
148
|
+
* @details Weaker bounds are marked omitted, while crossing min/max bounds prove
|
|
149
|
+
* the conjunction false before runtime.
|
|
150
|
+
* @param values Original fold input node ids.
|
|
151
|
+
* @param nodes Graph node table.
|
|
152
|
+
* @param omitted Mutable omission bitmap aligned with `values`.
|
|
153
|
+
* @param end Exclusive end of the pure scalar prefix.
|
|
154
|
+
* @returns True when the bounds prove the conjunction impossible.
|
|
155
|
+
*/
|
|
156
|
+
function canonicalizeStringBounds(values, nodes, omitted, end) {
|
|
157
|
+
const bounds = new Map();
|
|
158
|
+
for (let index = 0; index < end; index += 1) {
|
|
159
|
+
if (omitted[index] === true) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const id = values[index];
|
|
163
|
+
const node = id === undefined ? undefined : nodes[id];
|
|
164
|
+
if (node?.tag !== NodeTag.StringMin && node?.tag !== NodeTag.StringMax) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const slot = readStringBounds(bounds, node.value);
|
|
168
|
+
if (node.tag === NodeTag.StringMin) {
|
|
169
|
+
keepStrongestMin(omitted, slot, index, node.bound);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
keepStrongestMax(omitted, slot, index, node.bound);
|
|
173
|
+
}
|
|
174
|
+
if (hasImpossibleBounds(slot)) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* @brief Keep only the strongest finite numeric bounds in the pure prefix.
|
|
182
|
+
* @details The pass ignores non-constant and non-finite comparisons because
|
|
183
|
+
* those do not create stable static intervals.
|
|
184
|
+
* @param values Original fold input node ids.
|
|
185
|
+
* @param nodes Graph node table.
|
|
186
|
+
* @param omitted Mutable omission bitmap aligned with `values`.
|
|
187
|
+
* @param end Exclusive end of the pure scalar prefix.
|
|
188
|
+
* @returns True when the bounds prove the conjunction impossible.
|
|
189
|
+
*/
|
|
190
|
+
function canonicalizeNumericBounds(values, nodes, omitted, end) {
|
|
191
|
+
const bounds = new Map();
|
|
192
|
+
for (let index = 0; index < end; index += 1) {
|
|
193
|
+
if (omitted[index] === true) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const id = values[index];
|
|
197
|
+
const node = id === undefined ? undefined : nodes[id];
|
|
198
|
+
if (node?.tag !== NodeTag.Gte && node?.tag !== NodeTag.Lte) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const right = readConst(nodes, node.right);
|
|
202
|
+
if (!right.found || typeof right.value !== "number" ||
|
|
203
|
+
!Number.isFinite(right.value)) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const slot = readNumericBounds(bounds, node.left);
|
|
207
|
+
if (node.tag === NodeTag.Gte) {
|
|
208
|
+
keepStrongestGte(omitted, slot, index, right.value);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
keepStrongestLte(omitted, slot, index, right.value);
|
|
212
|
+
}
|
|
213
|
+
if (hasImpossibleNumericBounds(slot)) {
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* @brief Convert a primitive predicate node into a type fact.
|
|
221
|
+
* @details Constraint folding uses these facts to remove redundant checks and
|
|
222
|
+
* to detect impossible type intersections. Nodes without direct type meaning
|
|
223
|
+
* return undefined and remain under normal folding control.
|
|
224
|
+
* @param node Graph node to classify.
|
|
225
|
+
* @param index Node id currently being scanned.
|
|
226
|
+
* @returns Type fact for primitive predicate nodes, otherwise undefined.
|
|
227
|
+
*/
|
|
228
|
+
function readTypeFact(node, index) {
|
|
229
|
+
switch (node.tag) {
|
|
230
|
+
case NodeTag.IsString:
|
|
231
|
+
return makeTypeFact(TypeFactTag.String, node.value, false, index);
|
|
232
|
+
case NodeTag.IsNumber:
|
|
233
|
+
return makeTypeFact(TypeFactTag.Number, node.value, false, index);
|
|
234
|
+
case NodeTag.IsInteger:
|
|
235
|
+
return makeTypeFact(TypeFactTag.Number, node.value, true, index);
|
|
236
|
+
case NodeTag.IsBoolean:
|
|
237
|
+
return makeTypeFact(TypeFactTag.Boolean, node.value, false, index);
|
|
238
|
+
case NodeTag.IsBigInt:
|
|
239
|
+
return makeTypeFact(TypeFactTag.BigInt, node.value, false, index);
|
|
240
|
+
case NodeTag.IsSymbol:
|
|
241
|
+
return makeTypeFact(TypeFactTag.Symbol, node.value, false, index);
|
|
242
|
+
case NodeTag.IsObject:
|
|
243
|
+
return makeTypeFact(TypeFactTag.Object, node.value, false, index);
|
|
244
|
+
case NodeTag.IsArray:
|
|
245
|
+
return makeTypeFact(TypeFactTag.Array, node.value, false, index);
|
|
246
|
+
case NodeTag.IsUndefined:
|
|
247
|
+
return makeTypeFact(TypeFactTag.Undefined, node.value, false, index);
|
|
248
|
+
case NodeTag.IsNull:
|
|
249
|
+
return makeTypeFact(TypeFactTag.Null, node.value, false, index);
|
|
250
|
+
default:
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* @brief Pack the normalized type fact used by the constraint pass.
|
|
256
|
+
* @details The `integer` bit distinguishes `number` from `integer` predicates
|
|
257
|
+
* without introducing a separate domain family, which keeps conflict checks
|
|
258
|
+
* small and branch-free.
|
|
259
|
+
* @param tag Runtime domain proven by the predicate.
|
|
260
|
+
* @param value Node id whose type is constrained.
|
|
261
|
+
* @param integer True when the predicate is the integer subtype check.
|
|
262
|
+
* @param index Node id of the predicate that produced the fact.
|
|
263
|
+
* @returns Type fact record used by later scans.
|
|
264
|
+
*/
|
|
265
|
+
function makeTypeFact(tag, value, integer, index) {
|
|
266
|
+
return {
|
|
267
|
+
tag,
|
|
268
|
+
value,
|
|
269
|
+
integer,
|
|
270
|
+
index
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* @brief Get or create the accumulated string-length bounds for a value node.
|
|
275
|
+
* @details A mutable slot lets multiple `minLength` and `maxLength` predicates
|
|
276
|
+
* compete while the pass marks weaker predicates for omission.
|
|
277
|
+
* @param bounds Map from value node id to accumulated string bounds.
|
|
278
|
+
* @param value Node id whose string bounds are being tracked.
|
|
279
|
+
* @returns Mutable bounds slot for that value node.
|
|
280
|
+
*/
|
|
281
|
+
function readStringBounds(bounds, value) {
|
|
282
|
+
const cached = bounds.get(value);
|
|
283
|
+
if (cached !== undefined) {
|
|
284
|
+
return cached;
|
|
285
|
+
}
|
|
286
|
+
const slot = {
|
|
287
|
+
min: undefined,
|
|
288
|
+
max: undefined
|
|
289
|
+
};
|
|
290
|
+
bounds.set(value, slot);
|
|
291
|
+
return slot;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* @brief Get or create the accumulated numeric bounds for a value node.
|
|
295
|
+
* @details The pass stores lower and upper numeric limits separately so it can
|
|
296
|
+
* keep the strongest surviving predicate while also detecting impossible ranges.
|
|
297
|
+
* @param bounds Map from value node id to accumulated numeric bounds.
|
|
298
|
+
* @param value Node id whose numeric bounds are being tracked.
|
|
299
|
+
* @returns Mutable bounds slot for that value node.
|
|
300
|
+
*/
|
|
301
|
+
function readNumericBounds(bounds, value) {
|
|
302
|
+
const cached = bounds.get(value);
|
|
303
|
+
if (cached !== undefined) {
|
|
304
|
+
return cached;
|
|
305
|
+
}
|
|
306
|
+
const slot = {
|
|
307
|
+
gte: undefined,
|
|
308
|
+
lte: undefined
|
|
309
|
+
};
|
|
310
|
+
bounds.set(value, slot);
|
|
311
|
+
return slot;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* @brief Keep the strongest string lower bound in an accumulated slot.
|
|
315
|
+
* @details A larger minimum dominates a smaller one. The dominated predicate is
|
|
316
|
+
* marked in the original omission bitmap so final collection remains ordered.
|
|
317
|
+
* @param omitted Mutable omission bitmap aligned with the fold inputs.
|
|
318
|
+
* @param slot Accumulated bounds for one value node.
|
|
319
|
+
* @param index Position of the candidate predicate.
|
|
320
|
+
* @param bound Candidate minimum length.
|
|
321
|
+
*/
|
|
322
|
+
function keepStrongestMin(omitted, slot, index, bound) {
|
|
323
|
+
if (slot.min === undefined || bound >= slot.min.bound) {
|
|
324
|
+
if (slot.min !== undefined) {
|
|
325
|
+
omitted[slot.min.index] = true;
|
|
326
|
+
}
|
|
327
|
+
slot.min = {
|
|
328
|
+
index,
|
|
329
|
+
bound
|
|
330
|
+
};
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
omitted[index] = true;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* @brief Keep the strongest string upper bound in an accumulated slot.
|
|
337
|
+
* @details A smaller maximum dominates a larger one and preserves the same
|
|
338
|
+
* runtime acceptance set.
|
|
339
|
+
* @param omitted Mutable omission bitmap aligned with the fold inputs.
|
|
340
|
+
* @param slot Accumulated bounds for one value node.
|
|
341
|
+
* @param index Position of the candidate predicate.
|
|
342
|
+
* @param bound Candidate maximum length.
|
|
343
|
+
*/
|
|
344
|
+
function keepStrongestMax(omitted, slot, index, bound) {
|
|
345
|
+
if (slot.max === undefined || bound <= slot.max.bound) {
|
|
346
|
+
if (slot.max !== undefined) {
|
|
347
|
+
omitted[slot.max.index] = true;
|
|
348
|
+
}
|
|
349
|
+
slot.max = {
|
|
350
|
+
index,
|
|
351
|
+
bound
|
|
352
|
+
};
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
omitted[index] = true;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* @brief Keep the strongest numeric lower bound in an accumulated slot.
|
|
359
|
+
* @details A larger inclusive lower bound dominates a smaller one for the same
|
|
360
|
+
* numeric value node.
|
|
361
|
+
* @param omitted Mutable omission bitmap aligned with the fold inputs.
|
|
362
|
+
* @param slot Accumulated bounds for one value node.
|
|
363
|
+
* @param index Position of the candidate predicate.
|
|
364
|
+
* @param bound Candidate inclusive lower bound.
|
|
365
|
+
*/
|
|
366
|
+
function keepStrongestGte(omitted, slot, index, bound) {
|
|
367
|
+
if (slot.gte === undefined || bound >= slot.gte.bound) {
|
|
368
|
+
if (slot.gte !== undefined) {
|
|
369
|
+
omitted[slot.gte.index] = true;
|
|
370
|
+
}
|
|
371
|
+
slot.gte = {
|
|
372
|
+
index,
|
|
373
|
+
bound
|
|
374
|
+
};
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
omitted[index] = true;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* @brief Keep the strongest numeric upper bound in an accumulated slot.
|
|
381
|
+
* @details A smaller inclusive upper bound dominates a larger one for the same
|
|
382
|
+
* numeric value node.
|
|
383
|
+
* @param omitted Mutable omission bitmap aligned with the fold inputs.
|
|
384
|
+
* @param slot Accumulated bounds for one value node.
|
|
385
|
+
* @param index Position of the candidate predicate.
|
|
386
|
+
* @param bound Candidate inclusive upper bound.
|
|
387
|
+
*/
|
|
388
|
+
function keepStrongestLte(omitted, slot, index, bound) {
|
|
389
|
+
if (slot.lte === undefined || bound <= slot.lte.bound) {
|
|
390
|
+
if (slot.lte !== undefined) {
|
|
391
|
+
omitted[slot.lte.index] = true;
|
|
392
|
+
}
|
|
393
|
+
slot.lte = {
|
|
394
|
+
index,
|
|
395
|
+
bound
|
|
396
|
+
};
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
omitted[index] = true;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* @brief Detect a statically impossible string-length interval.
|
|
403
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
404
|
+
* before code generation consumes the graph.
|
|
405
|
+
* @param slot Accumulated string bounds for one value node.
|
|
406
|
+
* @returns True when minimum length exceeds maximum length.
|
|
407
|
+
*/
|
|
408
|
+
function hasImpossibleBounds(slot) {
|
|
409
|
+
return slot.min !== undefined &&
|
|
410
|
+
slot.max !== undefined &&
|
|
411
|
+
slot.min.bound > slot.max.bound;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* @brief Detect a statically impossible numeric interval.
|
|
415
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
416
|
+
* before code generation consumes the graph.
|
|
417
|
+
* @param slot Accumulated numeric bounds for one value node.
|
|
418
|
+
* @returns True when lower bound exceeds upper bound.
|
|
419
|
+
*/
|
|
420
|
+
function hasImpossibleNumericBounds(slot) {
|
|
421
|
+
return slot.gte !== undefined &&
|
|
422
|
+
slot.lte !== undefined &&
|
|
423
|
+
slot.gte.bound > slot.lte.bound;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* @brief Find the prefix of fold inputs that can be reordered semantically.
|
|
427
|
+
* @details Pure scalar checks have no callbacks, loops, or schema recursion.
|
|
428
|
+
* The pass stops before composite or dynamic nodes so optimization cannot hide
|
|
429
|
+
* observable validation behavior.
|
|
430
|
+
* @param values Original fold input node ids.
|
|
431
|
+
* @param nodes Graph node table.
|
|
432
|
+
* @returns Exclusive index where pure scalar processing must stop.
|
|
433
|
+
*/
|
|
434
|
+
function findPurePrefixEnd(values, nodes) {
|
|
435
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
436
|
+
const id = values[index];
|
|
437
|
+
const node = id === undefined ? undefined : nodes[id];
|
|
438
|
+
if (node === undefined || !isPureScalarNode(node)) {
|
|
439
|
+
return index;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return values.length;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* @brief Decide whether a graph node is safe for scalar constraint folding.
|
|
446
|
+
* @details Composite loops, union dispatch, and SchemaCheck may trigger dynamic
|
|
447
|
+
* behavior or nested validation, so they form a barrier for this pass.
|
|
448
|
+
* @param node Graph node to classify.
|
|
449
|
+
* @returns True for scalar predicate nodes handled by local constraint folding.
|
|
450
|
+
*/
|
|
451
|
+
function isPureScalarNode(node) {
|
|
452
|
+
switch (node.tag) {
|
|
453
|
+
case NodeTag.SchemaCheck:
|
|
454
|
+
case NodeTag.ArrayEvery:
|
|
455
|
+
case NodeTag.TupleItems:
|
|
456
|
+
case NodeTag.RecordEvery:
|
|
457
|
+
case NodeTag.DiscriminantDispatch:
|
|
458
|
+
case NodeTag.ObjectShape:
|
|
459
|
+
case NodeTag.UnionDispatch:
|
|
460
|
+
case NodeTag.And:
|
|
461
|
+
case NodeTag.Or:
|
|
462
|
+
return false;
|
|
463
|
+
default:
|
|
464
|
+
return true;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* @brief Rebuild the fold input vector after omission marks are applied.
|
|
469
|
+
* @details Values are appended in their original order so generated code keeps
|
|
470
|
+
* the same left-to-right scalar check sequence after simplification.
|
|
471
|
+
* @param values Original fold input node ids.
|
|
472
|
+
* @param omitted Omission bitmap aligned with `values`.
|
|
473
|
+
* @returns Compact vector containing only surviving node ids.
|
|
474
|
+
*/
|
|
475
|
+
function collectKeptValues(values, omitted) {
|
|
476
|
+
const kept = [];
|
|
477
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
478
|
+
const value = values[index];
|
|
479
|
+
if (value !== undefined && omitted[index] !== true) {
|
|
480
|
+
kept.push(value);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return kept;
|
|
484
|
+
}
|
|
@@ -1,59 +1,144 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file fold-scalar.ts
|
|
3
3
|
* @brief Constant folding for scalar graph nodes.
|
|
4
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
5
|
+
* before code generation consumes the graph.
|
|
4
6
|
*/
|
|
5
7
|
import type { ArrayEveryNode, DiscriminantDispatchNode, EqualsNode, GetPropNode, GraphNode, HasOwnDataNode, HasOwnNode, NodeId, NumericCompareNode, RecordEveryNode, RegexNode, StrictKeysNode, StringBoundNode, TupleItemsNode, UnaryPredicateNode } from "../ir/index.js";
|
|
6
8
|
import { type FoldResult } from "./fold-common.js";
|
|
7
9
|
/**
|
|
8
|
-
* @brief
|
|
10
|
+
* @brief Fold property reads whose receiver is already a literal constant.
|
|
11
|
+
* @details Lowered graphs never materialize object literals as safe Const data,
|
|
12
|
+
* so a constant receiver cannot provide a trustworthy property slot. The node
|
|
13
|
+
* folds to undefined instead of executing user accessors during optimization.
|
|
14
|
+
* @param node Property-read node to fold.
|
|
15
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
16
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
17
|
+
* @returns Fold result for the property read.
|
|
9
18
|
*/
|
|
10
19
|
export declare function foldGetProp(node: GetPropNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
11
20
|
/**
|
|
12
|
-
* @brief
|
|
21
|
+
* @brief Fold unary predicate nodes when their subject is constant.
|
|
22
|
+
* @details Each predicate mirrors the runtime validator's exact primitive test,
|
|
23
|
+
* including finite-number and plain-record semantics, so compile-time folding
|
|
24
|
+
* cannot widen the accepted value set.
|
|
25
|
+
* @param node Unary predicate node to fold.
|
|
26
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
27
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
28
|
+
* @returns Fold result for the predicate.
|
|
13
29
|
*/
|
|
14
30
|
export declare function foldUnary(node: UnaryPredicateNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
15
31
|
/**
|
|
16
|
-
* @brief
|
|
32
|
+
* @brief Fold literal equality when both operands are constants.
|
|
33
|
+
* @details `Object.is` is used so NaN and negative zero follow TypeSea literal
|
|
34
|
+
* equality semantics instead of JavaScript `===` corner cases.
|
|
35
|
+
* @param node Equality node to fold.
|
|
36
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
37
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
38
|
+
* @returns Fold result for the equality node.
|
|
17
39
|
*/
|
|
18
40
|
export declare function foldEquals(node: EqualsNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
19
41
|
/**
|
|
20
|
-
* @brief
|
|
42
|
+
* @brief Fold numeric comparisons with two constant operands.
|
|
43
|
+
* @details Non-number operands fold to false, matching the runtime predicate
|
|
44
|
+
* path where numeric schema checks require number values before comparison.
|
|
45
|
+
* @param node Numeric comparison node to fold.
|
|
46
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
47
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
48
|
+
* @returns Fold result for the comparison node.
|
|
21
49
|
*/
|
|
22
50
|
export declare function foldNumeric(node: NumericCompareNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
23
51
|
/**
|
|
24
|
-
* @brief
|
|
52
|
+
* @brief Fold string length predicates with a constant subject.
|
|
53
|
+
* @details Non-string subjects fold to false because the separate string guard
|
|
54
|
+
* may later be removed or reordered by boolean simplification.
|
|
55
|
+
* @param node String bound node to fold.
|
|
56
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
57
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
58
|
+
* @returns Fold result for the string bound node.
|
|
25
59
|
*/
|
|
26
60
|
export declare function foldStringBound(node: StringBoundNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
27
61
|
/**
|
|
28
|
-
* @brief
|
|
62
|
+
* @brief Fold regular expression checks with a constant string subject.
|
|
63
|
+
* @details `lastIndex` is reset before and after the test so global or sticky
|
|
64
|
+
* expressions cannot leak state across optimizer and runtime use.
|
|
65
|
+
* @param node Regex node to fold.
|
|
66
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
67
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
68
|
+
* @returns Fold result for the regex node.
|
|
29
69
|
*/
|
|
30
70
|
export declare function foldRegex(node: RegexNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
31
71
|
/**
|
|
32
|
-
* @brief
|
|
72
|
+
* @brief Fold own-property presence checks on constant receivers.
|
|
73
|
+
* @details Const nodes do not carry safe object identity, so the optimizer never
|
|
74
|
+
* inspects properties here. A constant receiver means the object check cannot be
|
|
75
|
+
* satisfied through this IR path and folds to false.
|
|
76
|
+
* @param node Own-property check node to fold.
|
|
77
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
78
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
79
|
+
* @returns Fold result for the own-property check.
|
|
33
80
|
*/
|
|
34
81
|
export declare function foldHasOwn(node: HasOwnNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
35
82
|
/**
|
|
36
|
-
* @brief
|
|
83
|
+
* @brief Fold own-data-property checks on constant receivers.
|
|
84
|
+
* @details The optimizer refuses to execute descriptors or getters. Constant
|
|
85
|
+
* receivers therefore fold to false instead of probing runtime object state.
|
|
86
|
+
* @param node Own-data-property check node to fold.
|
|
87
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
88
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
89
|
+
* @returns Fold result for the data-property check.
|
|
37
90
|
*/
|
|
38
91
|
export declare function foldHasOwnData(node: HasOwnDataNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
39
92
|
/**
|
|
40
|
-
* @brief
|
|
93
|
+
* @brief Fold strict-key checks on constant receivers.
|
|
94
|
+
* @details Strict-key validation depends on own property keys. The optimizer
|
|
95
|
+
* does not enumerate runtime objects, so constant receivers fold to false and
|
|
96
|
+
* non-constant receivers stay intact.
|
|
97
|
+
* @param node Strict-key node to fold.
|
|
98
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
99
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
100
|
+
* @returns Fold result for the strict-key node.
|
|
41
101
|
*/
|
|
42
102
|
export declare function foldStrictKeys(node: StrictKeysNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
43
103
|
/**
|
|
44
|
-
* @brief
|
|
104
|
+
* @brief Fold array iteration nodes with constant receivers.
|
|
105
|
+
* @details Iteration semantics require reading runtime indexes and child
|
|
106
|
+
* schemas. Constants cannot safely stand in for arrays here, so the node folds
|
|
107
|
+
* to false only when the receiver is already constant.
|
|
108
|
+
* @param node Array iteration node to fold.
|
|
109
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
110
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
111
|
+
* @returns Fold result for the array iteration node.
|
|
45
112
|
*/
|
|
46
113
|
export declare function foldArrayEvery(node: ArrayEveryNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
47
114
|
/**
|
|
48
|
-
* @brief
|
|
115
|
+
* @brief Fold tuple item checks with constant receivers.
|
|
116
|
+
* @details Tuple validation depends on array length and descriptor-backed item
|
|
117
|
+
* reads, so the optimizer does not simulate it for constant receivers.
|
|
118
|
+
* @param node Tuple item node to fold.
|
|
119
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
120
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
121
|
+
* @returns Fold result for the tuple item node.
|
|
49
122
|
*/
|
|
50
123
|
export declare function foldTupleItems(node: TupleItemsNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
51
124
|
/**
|
|
52
|
-
* @brief
|
|
125
|
+
* @brief Fold record iteration nodes with constant receivers.
|
|
126
|
+
* @details Record validation must enumerate own keys at runtime. The optimizer
|
|
127
|
+
* keeps non-constant records intact and folds constant receivers closed.
|
|
128
|
+
* @param node Record iteration node to fold.
|
|
129
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
130
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
131
|
+
* @returns Fold result for the record iteration node.
|
|
53
132
|
*/
|
|
54
133
|
export declare function foldRecordEvery(node: RecordEveryNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
55
134
|
/**
|
|
56
|
-
* @brief
|
|
135
|
+
* @brief Fold discriminant dispatch nodes with constant receivers.
|
|
136
|
+
* @details Dispatch requires an object tag read, which the optimizer does not
|
|
137
|
+
* perform on constants. Non-constant receivers remain available for codegen.
|
|
138
|
+
* @param node Discriminant dispatch node to fold.
|
|
139
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
140
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
141
|
+
* @returns Fold result for the dispatch node.
|
|
57
142
|
*/
|
|
58
143
|
export declare function foldDiscriminantDispatch(node: DiscriminantDispatchNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
59
144
|
//# sourceMappingURL=fold-scalar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fold-scalar.d.ts","sourceRoot":"","sources":["../../src/optimize/fold-scalar.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fold-scalar.d.ts","sourceRoot":"","sources":["../../src/optimize/fold-scalar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACR,cAAc,EACd,wBAAwB,EACxB,UAAU,EACV,WAAW,EACX,SAAS,EACT,cAAc,EACd,UAAU,EACV,MAAM,EACN,kBAAkB,EAClB,eAAe,EACf,SAAS,EACT,cAAc,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAOH,KAAK,UAAU,EAClB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACvB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAMZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACrB,IAAI,EAAE,kBAAkB,EACxB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CA6BZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACtB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAOZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACvB,IAAI,EAAE,kBAAkB,EACxB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAWZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC3B,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CASZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACrB,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAYZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACtB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAMZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC1B,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAMZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC1B,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAMZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC1B,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAMZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC1B,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAMZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC3B,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAMZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACpC,IAAI,EAAE,wBAAwB,EAC9B,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CAMZ"}
|