@scriptc/compiler 0.1.3 → 0.1.4

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 (147) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +200 -51
  2. package/dist/backend/c/async.d.ts +25 -0
  3. package/dist/backend/c/async.js +167 -0
  4. package/dist/backend/c/async.js.map +1 -1
  5. package/dist/backend/c/c-emitter.d.ts +10 -0
  6. package/dist/backend/c/c-emitter.js +14 -2
  7. package/dist/backend/c/c-emitter.js.map +1 -1
  8. package/dist/backend/c/exprs.js +293 -51
  9. package/dist/backend/c/exprs.js.map +1 -1
  10. package/dist/backend/c/types.js +2 -0
  11. package/dist/backend/c/types.js.map +1 -1
  12. package/dist/backend/link-plan.d.ts +2 -1
  13. package/dist/backend/link-plan.js +2 -1
  14. package/dist/backend/link-plan.js.map +1 -1
  15. package/dist/backend/llvm/emitter.js +20 -6
  16. package/dist/backend/llvm/emitter.js.map +1 -1
  17. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  18. package/dist/backend/llvm/expr-bytes.js +8 -8
  19. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  20. package/dist/backend/llvm/expr-callbacks.d.ts +9 -0
  21. package/dist/backend/llvm/expr-callbacks.js +125 -0
  22. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  23. package/dist/backend/llvm/expr-context.d.ts +14 -2
  24. package/dist/backend/llvm/expr-dispatch.js +1 -0
  25. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  26. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  27. package/dist/backend/llvm/expr-primitives.js +30 -9
  28. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  29. package/dist/backend/llvm/expr-primitives.test.d.ts +1 -0
  30. package/dist/backend/llvm/expr-primitives.test.js +38 -0
  31. package/dist/backend/llvm/expr-primitives.test.js.map +1 -0
  32. package/dist/backend/llvm/expr-stream-callbacks.d.ts +3 -0
  33. package/dist/backend/llvm/expr-stream-callbacks.js +69 -0
  34. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  35. package/dist/backend/llvm/lib-filesystem.js +68 -10
  36. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  37. package/dist/backend/llvm/lib-network.js +18 -2
  38. package/dist/backend/llvm/lib-network.js.map +1 -1
  39. package/dist/backend/llvm/lib-process.js +156 -6
  40. package/dist/backend/llvm/lib-process.js.map +1 -1
  41. package/dist/backend/llvm/lib-shared.js +36 -0
  42. package/dist/backend/llvm/lib-shared.js.map +1 -1
  43. package/dist/backend/llvm/lib-stream.js +23 -0
  44. package/dist/backend/llvm/lib-stream.js.map +1 -1
  45. package/dist/backend/native-toolchain.d.ts +3 -0
  46. package/dist/backend/native-toolchain.js +3 -1
  47. package/dist/backend/native-toolchain.js.map +1 -1
  48. package/dist/backend/runtime-pack.test.js +28 -10
  49. package/dist/backend/runtime-pack.test.js.map +1 -1
  50. package/dist/backend/targets.d.ts +4 -0
  51. package/dist/backend/targets.js +13 -0
  52. package/dist/backend/targets.js.map +1 -1
  53. package/dist/backend/targets.test.js +8 -1
  54. package/dist/backend/targets.test.js.map +1 -1
  55. package/dist/coverage/surface-manifest.js +8 -0
  56. package/dist/coverage/surface-manifest.js.map +1 -1
  57. package/dist/diagnostics/diagnostic.js +1 -1
  58. package/dist/diagnostics/diagnostic.js.map +1 -1
  59. package/dist/executable/executable-cache.d.ts +2 -0
  60. package/dist/executable/executable-cache.js +3 -0
  61. package/dist/executable/executable-cache.js.map +1 -1
  62. package/dist/frontend/fork-target.d.ts +17 -0
  63. package/dist/frontend/fork-target.js +256 -0
  64. package/dist/frontend/fork-target.js.map +1 -0
  65. package/dist/frontend/lowering/abstract-equality.d.ts +6 -0
  66. package/dist/frontend/lowering/abstract-equality.js +250 -0
  67. package/dist/frontend/lowering/abstract-equality.js.map +1 -0
  68. package/dist/frontend/lowering/lower-assert.js +71 -2
  69. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  70. package/dist/frontend/lowering/lower-builtins.d.ts +50 -23
  71. package/dist/frontend/lowering/lower-builtins.js +939 -106
  72. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  73. package/dist/frontend/lowering/lower-calls.d.ts +29 -21
  74. package/dist/frontend/lowering/lower-calls.js +573 -121
  75. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  76. package/dist/frontend/lowering/lower-classes.js +39 -8
  77. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  78. package/dist/frontend/lowering/lower-containers.js +150 -0
  79. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  80. package/dist/frontend/lowering/lower-event-emitter.js +212 -21
  81. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  82. package/dist/frontend/lowering/lower-exprs.js +135 -83
  83. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  84. package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
  85. package/dist/frontend/lowering/lower-inspect.js +1 -1
  86. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  87. package/dist/frontend/lowering/lower-island.d.ts +6 -3
  88. package/dist/frontend/lowering/lower-island.js +165 -6
  89. package/dist/frontend/lowering/lower-island.js.map +1 -1
  90. package/dist/frontend/lowering/lower-modules.d.ts +6 -0
  91. package/dist/frontend/lowering/lower-modules.js +184 -38
  92. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  93. package/dist/frontend/lowering/lower-namespaces.js +7 -0
  94. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  95. package/dist/frontend/lowering/lower-server.d.ts +1 -1
  96. package/dist/frontend/lowering/lower-server.js +130 -27
  97. package/dist/frontend/lowering/lower-server.js.map +1 -1
  98. package/dist/frontend/lowering/lower-stmts.js +118 -15
  99. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  100. package/dist/frontend/lowering/lower-stream.d.ts +3 -0
  101. package/dist/frontend/lowering/lower-stream.js +7 -0
  102. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  103. package/dist/frontend/lowering/lowerer.d.ts +86 -9
  104. package/dist/frontend/lowering/lowerer.js +412 -72
  105. package/dist/frontend/lowering/lowerer.js.map +1 -1
  106. package/dist/frontend/lowering/surfaces.d.ts +26 -0
  107. package/dist/frontend/lowering/surfaces.js +140 -77
  108. package/dist/frontend/lowering/surfaces.js.map +1 -1
  109. package/dist/frontend/npm-static-declarations.d.ts +4 -0
  110. package/dist/frontend/npm-static-declarations.js +56 -0
  111. package/dist/frontend/npm-static-declarations.js.map +1 -1
  112. package/dist/frontend/npm-static-declarations.test.js +23 -2
  113. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  114. package/dist/frontend/npm-static.js +6 -5
  115. package/dist/frontend/npm-static.js.map +1 -1
  116. package/dist/frontend/npm.d.ts +15 -3
  117. package/dist/frontend/npm.js +80 -8
  118. package/dist/frontend/npm.js.map +1 -1
  119. package/dist/frontend/npm.test.js +76 -9
  120. package/dist/frontend/npm.test.js.map +1 -1
  121. package/dist/frontend/program.js +92 -10
  122. package/dist/frontend/program.js.map +1 -1
  123. package/dist/frontend/resolve.d.ts +6 -0
  124. package/dist/frontend/resolve.js +7 -4
  125. package/dist/frontend/resolve.js.map +1 -1
  126. package/dist/frontend/type-mapper.d.ts +5 -0
  127. package/dist/frontend/type-mapper.js +64 -24
  128. package/dist/frontend/type-mapper.js.map +1 -1
  129. package/dist/index.d.ts +5 -0
  130. package/dist/index.js +24 -3
  131. package/dist/index.js.map +1 -1
  132. package/dist/ir/ir.d.ts +93 -47
  133. package/dist/ir/ir.js +63 -4
  134. package/dist/ir/ir.js.map +1 -1
  135. package/dist/ir/ir.test.js +14 -1
  136. package/dist/ir/ir.test.js.map +1 -1
  137. package/dist/ir/serialize.d.ts +1 -1
  138. package/dist/ir/serialize.js +1 -1
  139. package/dist/ir/serialize.js.map +1 -1
  140. package/dist/ir/validate.js +165 -13
  141. package/dist/ir/validate.js.map +1 -1
  142. package/dist/library/int-infer.test.js +4 -4
  143. package/dist/library/int-infer.test.js.map +1 -1
  144. package/dist/library/library-cache.test.js +5 -5
  145. package/dist/library/library-cache.test.js.map +1 -1
  146. package/package.json +17 -17
  147. package/surface-manifest.json +132 -38
@@ -0,0 +1,256 @@
1
+ import { resolve } from "node:path";
2
+ import { fileURLToPath, pathToFileURL } from "node:url";
3
+ import * as ts from "./ts7/adapter.js";
4
+ import { canonicalBuiltinModule } from "./builtin-modules.js";
5
+ function strip(expr) {
6
+ let current = expr;
7
+ while (ts.isParenthesizedExpression(current) ||
8
+ ts.isAsExpression(current) ||
9
+ ts.isTypeAssertion(current) ||
10
+ ts.isNonNullExpression(current)) {
11
+ current = current.expression;
12
+ }
13
+ return current;
14
+ }
15
+ /** True when an identifier is a named import of one Node builtin member.
16
+ * The declaration-file fallback preserves re-export facades in the same
17
+ * way as lowering's builtinImportOf helper. */
18
+ export function isBuiltinMemberImport(program, ident, moduleName, memberName) {
19
+ const checker = program.getTypeChecker();
20
+ const symbol = checker.getSymbolAtLocation(ident);
21
+ const decl = symbol ? checker.declarationsOf(symbol)[0] : undefined;
22
+ if (decl !== undefined && ts.isImportSpecifier(decl)) {
23
+ const importDecl = decl.parent.parent.parent;
24
+ if (ts.isImportDeclaration(importDecl) && ts.isStringLiteral(importDecl.moduleSpecifier)) {
25
+ const member = decl.propertyName?.text ?? decl.name.text;
26
+ if (canonicalBuiltinModule(importDecl.moduleSpecifier.text) === moduleName && member === memberName) {
27
+ return true;
28
+ }
29
+ }
30
+ }
31
+ if (symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0) {
32
+ const target = checker.getAliasedSymbol(symbol);
33
+ const targetDecl = checker.declarationsOf(target)[0];
34
+ if (targetDecl !== undefined && targetDecl.getSourceFile().isDeclarationFile) {
35
+ for (let parent = targetDecl.parent; parent !== undefined && !ts.isSourceFile(parent); parent = parent.parent) {
36
+ if (ts.isModuleDeclaration(parent) && ts.isStringLiteral(parent.name)) {
37
+ return canonicalBuiltinModule(parent.name.text) === moduleName && target.name === memberName;
38
+ }
39
+ }
40
+ }
41
+ }
42
+ return false;
43
+ }
44
+ /** True when an identifier is the namespace/default binding for one Node
45
+ * builtin module. JavaScript default imports of CommonJS builtins expose the
46
+ * same module object as namespace imports, matching lowering's provenance. */
47
+ function isBuiltinNamespaceImport(program, ident, moduleName) {
48
+ const checker = program.getTypeChecker();
49
+ const symbol = checker.getSymbolAtLocation(ident);
50
+ const decl = symbol ? checker.declarationsOf(symbol)[0] : undefined;
51
+ let importDecl;
52
+ if (decl !== undefined && ts.isNamespaceImport(decl)) {
53
+ const candidate = decl.parent.parent;
54
+ if (ts.isImportDeclaration(candidate))
55
+ importDecl = candidate;
56
+ }
57
+ else if (decl !== undefined && ts.isImportClause(decl) && decl.name !== undefined) {
58
+ if (ts.isImportDeclaration(decl.parent))
59
+ importDecl = decl.parent;
60
+ }
61
+ return importDecl !== undefined &&
62
+ ts.isStringLiteral(importDecl.moduleSpecifier) &&
63
+ canonicalBuiltinModule(importDecl.moduleSpecifier.text) === moduleName;
64
+ }
65
+ function constInitializer(program, expr) {
66
+ const current = strip(expr);
67
+ if (!ts.isIdentifier(current))
68
+ return null;
69
+ const symbol = program.getTypeChecker().getSymbolAtLocation(current);
70
+ const decl = symbol
71
+ ? program.getTypeChecker().declarationsOf(symbol).find((candidate) => ts.isVariableDeclaration(candidate))
72
+ : undefined;
73
+ if (decl === undefined ||
74
+ decl.initializer === undefined ||
75
+ !ts.isVariableDeclarationList(decl.parent) ||
76
+ (decl.parent.flags & ts.NodeFlags.Const) === 0) {
77
+ return null;
78
+ }
79
+ return decl.initializer;
80
+ }
81
+ function importMetaUrl(expr) {
82
+ const current = strip(expr);
83
+ return (ts.isPropertyAccessExpression(current) &&
84
+ !current.questionDotToken &&
85
+ current.name.text === "url" &&
86
+ ts.isMetaProperty(current.expression) &&
87
+ current.expression.keywordToken === ts.SyntaxKind.ImportKeyword &&
88
+ current.expression.name.text === "meta");
89
+ }
90
+ function staticBoolean(program, expr, seen) {
91
+ const current = strip(expr);
92
+ if (current.kind === ts.SyntaxKind.TrueKeyword)
93
+ return true;
94
+ if (current.kind === ts.SyntaxKind.FalseKeyword)
95
+ return false;
96
+ const init = constInitializer(program, current);
97
+ if (init !== null && ts.isIdentifier(current)) {
98
+ const symbol = program.getTypeChecker().getSymbolAtLocation(current);
99
+ if (symbol === undefined || seen.has(symbol))
100
+ return null;
101
+ seen.add(symbol);
102
+ const value = staticBoolean(program, init, seen);
103
+ seen.delete(symbol);
104
+ return value;
105
+ }
106
+ if (ts.isCallExpression(current) &&
107
+ !current.questionDotToken &&
108
+ current.arguments.length === 1 &&
109
+ ts.isPropertyAccessExpression(current.expression) &&
110
+ !current.expression.questionDotToken &&
111
+ (current.expression.name.text === "endsWith" || current.expression.name.text === "startsWith")) {
112
+ const receiver = staticString(program, current.expression.expression, seen);
113
+ const needle = staticString(program, current.arguments[0], seen);
114
+ if (receiver === null || needle === null)
115
+ return null;
116
+ return current.expression.name.text === "endsWith"
117
+ ? receiver.endsWith(needle)
118
+ : receiver.startsWith(needle);
119
+ }
120
+ return null;
121
+ }
122
+ /** A deliberately small compile-time string evaluator for fork target paths.
123
+ * It follows const aliases, import.meta.url, templates, conditionals, the
124
+ * relative URL constructor, and fileURLToPath. No user function executes. */
125
+ export function staticForkString(program, expr, seen = new Set()) {
126
+ return staticString(program, expr, seen);
127
+ }
128
+ function staticString(program, expr, seen) {
129
+ const current = strip(expr);
130
+ if (ts.isStringLiteralLike(current))
131
+ return current.text;
132
+ if (importMetaUrl(current))
133
+ return pathToFileURL(current.getSourceFile().fileName).href;
134
+ if (ts.isTemplateExpression(current)) {
135
+ let value = current.head.text;
136
+ for (const span of current.templateSpans) {
137
+ const part = staticString(program, span.expression, seen);
138
+ if (part === null)
139
+ return null;
140
+ value += part + span.literal.text;
141
+ }
142
+ return value;
143
+ }
144
+ if (ts.isConditionalExpression(current)) {
145
+ const condition = staticBoolean(program, current.condition, seen);
146
+ return condition === null
147
+ ? null
148
+ : staticString(program, condition ? current.whenTrue : current.whenFalse, seen);
149
+ }
150
+ const init = constInitializer(program, current);
151
+ if (init !== null && ts.isIdentifier(current)) {
152
+ const symbol = program.getTypeChecker().getSymbolAtLocation(current);
153
+ if (symbol === undefined || seen.has(symbol))
154
+ return null;
155
+ seen.add(symbol);
156
+ const value = staticString(program, init, seen);
157
+ seen.delete(symbol);
158
+ return value;
159
+ }
160
+ if (ts.isCallExpression(current) &&
161
+ !current.questionDotToken &&
162
+ current.arguments.length === 1 &&
163
+ ts.isIdentifier(current.expression) &&
164
+ isBuiltinMemberImport(program, current.expression, "url", "fileURLToPath")) {
165
+ const href = staticString(program, current.arguments[0], seen);
166
+ if (href === null)
167
+ return null;
168
+ try {
169
+ return fileURLToPath(href);
170
+ }
171
+ catch {
172
+ return null;
173
+ }
174
+ }
175
+ if (ts.isNewExpression(current) && ts.isIdentifier(current.expression) && current.expression.text === "URL") {
176
+ const args = current.arguments ?? [];
177
+ if (args.length < 1 || args.length > 2)
178
+ return null;
179
+ const input = staticString(program, args[0], seen);
180
+ const base = args[1] === undefined ? null : staticString(program, args[1], seen);
181
+ if (input === null || (args.length === 2 && base === null))
182
+ return null;
183
+ try {
184
+ return base === null ? new URL(input).href : new URL(input, base).href;
185
+ }
186
+ catch {
187
+ return null;
188
+ }
189
+ }
190
+ return null;
191
+ }
192
+ /** Resolves the supported fork modulePath expression to an absolute source
193
+ * path. Plain runtime strings are intentionally excluded: worker selection
194
+ * is part of the compiled graph, not a runtime filesystem lookup. */
195
+ export function staticForkModulePath(program, expr) {
196
+ const current = strip(expr);
197
+ const init = constInitializer(program, current);
198
+ if (init !== null && ts.isIdentifier(current))
199
+ return staticForkModulePath(program, init);
200
+ const supported = (ts.isCallExpression(current) &&
201
+ !current.questionDotToken &&
202
+ current.arguments.length === 1 &&
203
+ ts.isIdentifier(current.expression) &&
204
+ isBuiltinMemberImport(program, current.expression, "url", "fileURLToPath")) ||
205
+ (ts.isNewExpression(current) && ts.isIdentifier(current.expression) && current.expression.text === "URL");
206
+ if (!supported)
207
+ return null;
208
+ const value = staticString(program, current, new Set());
209
+ if (value === null)
210
+ return null;
211
+ try {
212
+ const path = value.startsWith("file:") ? fileURLToPath(value) : value;
213
+ return resolve(path);
214
+ }
215
+ catch {
216
+ return null;
217
+ }
218
+ }
219
+ export function forkCallModulePath(program, call) {
220
+ const callee = strip(call.expression);
221
+ const isFork = (ts.isIdentifier(callee) &&
222
+ isBuiltinMemberImport(program, callee, "child_process", "fork")) ||
223
+ (ts.isPropertyAccessExpression(callee) &&
224
+ !callee.questionDotToken &&
225
+ callee.name.text === "fork" &&
226
+ ts.isIdentifier(callee.expression) &&
227
+ isBuiltinNamespaceImport(program, callee.expression, "child_process"));
228
+ if (call.questionDotToken ||
229
+ call.arguments[0] === undefined ||
230
+ !isFork) {
231
+ return null;
232
+ }
233
+ return staticForkModulePath(program, call.arguments[0]);
234
+ }
235
+ /** Source-order static fork targets in the supplied files, deduplicated by
236
+ * resolved path. */
237
+ export function forkTargetPaths(program, files) {
238
+ const targets = [];
239
+ const seen = new Set();
240
+ for (const sourceFile of files) {
241
+ if (sourceFile.isDeclarationFile || sourceFile.fileName.endsWith(".json"))
242
+ continue;
243
+ ts.walkPreorder(sourceFile, (node) => {
244
+ if (!ts.isCallExpression(node))
245
+ return undefined;
246
+ const target = forkCallModulePath(program, node);
247
+ if (target !== null && !seen.has(target)) {
248
+ seen.add(target);
249
+ targets.push(target);
250
+ }
251
+ return undefined;
252
+ });
253
+ }
254
+ return targets;
255
+ }
256
+ //# sourceMappingURL=fork-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fork-target.js","sourceRoot":"","sources":["../../src/frontend/fork-target.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,SAAS,KAAK,CAAC,IAAmB;IAChC,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,OACE,EAAE,CAAC,yBAAyB,CAAC,OAAO,CAAC;QACrC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC;QAC1B,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC;QAC3B,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAC/B,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAC/B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;+CAE+C;AAC/C,MAAM,UAAU,qBAAqB,CACnC,OAAmB,EACnB,KAAoB,EACpB,UAAkB,EAClB,UAAkB;IAElB,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAC7C,IAAI,EAAE,CAAC,mBAAmB,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YACzF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACzD,IAAI,sBAAsB,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;gBACpG,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,aAAa,EAAE,CAAC,iBAAiB,EAAE,CAAC;YAC7E,KAAK,IAAI,MAAM,GAAwB,UAAU,CAAC,MAAM,EAAE,MAAM,KAAK,SAAS,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnI,IAAI,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtE,OAAO,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,UAAU,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC;gBAC/F,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;8EAE8E;AAC9E,SAAS,wBAAwB,CAC/B,OAAmB,EACnB,KAAoB,EACpB,UAAkB;IAElB,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,IAAI,UAA4C,CAAC;IACjD,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QACrC,IAAI,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC;YAAE,UAAU,GAAG,SAAS,CAAC;IAChE,CAAC;SAAM,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACpF,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;IACpE,CAAC;IACD,OAAO,UAAU,KAAK,SAAS;QAC7B,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,eAAe,CAAC;QAC9C,sBAAsB,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC;AAC3E,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAmB,EAAE,IAAmB;IAChE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACrE,MAAM,IAAI,GAAG,MAAM;QACjB,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAuC,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QAC/I,CAAC,CAAC,SAAS,CAAC;IACd,IACE,IAAI,KAAK,SAAS;QAClB,IAAI,CAAC,WAAW,KAAK,SAAS;QAC9B,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1C,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAC9C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC,WAAW,CAAC;AAC1B,CAAC;AAED,SAAS,aAAa,CAAC,IAAmB;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,CACL,EAAE,CAAC,0BAA0B,CAAC,OAAO,CAAC;QACtC,CAAC,OAAO,CAAC,gBAAgB;QACzB,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK;QAC3B,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC;QACrC,OAAO,CAAC,UAAU,CAAC,YAAY,KAAK,EAAE,CAAC,UAAU,CAAC,aAAa;QAC/D,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CACxC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,OAAmB,EACnB,IAAmB,EACnB,IAAoB;IAEpB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC5D,IAAI,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACrE,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IACE,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAC5B,CAAC,OAAO,CAAC,gBAAgB;QACzB,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAC9B,EAAE,CAAC,0BAA0B,CAAC,OAAO,CAAC,UAAU,CAAC;QACjD,CAAC,OAAO,CAAC,UAAU,CAAC,gBAAgB;QACpC,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,EAC9F,CAAC;QACD,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAE,EAAE,IAAI,CAAC,CAAC;QAClE,IAAI,QAAQ,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACtD,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU;YAChD,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC3B,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;6EAE6E;AAC7E,MAAM,UAAU,gBAAgB,CAC9B,OAAmB,EACnB,IAAmB,EACnB,IAAI,GAAmB,IAAI,GAAG,EAAE;IAEhC,OAAO,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,YAAY,CACnB,OAAmB,EACnB,IAAmB,EACnB,IAAoB;IAEpB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC;IACzD,IAAI,aAAa,CAAC,OAAO,CAAC;QAAE,OAAO,aAAa,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;IACxF,IAAI,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC1D,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC/B,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QACpC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,EAAE,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAClE,OAAO,SAAS,KAAK,IAAI;YACvB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACrE,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjB,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IACE,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAC5B,CAAC,OAAO,CAAC,gBAAgB;QACzB,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAC9B,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC;QACnC,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,eAAe,CAAC,EAC1E,CAAC;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAE,EAAE,IAAI,CAAC,CAAC;QAChE,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC/B,IAAI,CAAC;YACH,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,IAAI,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC5G,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACpD,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,IAAI,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACjF,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACxE,IAAI,CAAC;YACH,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;QACzE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;qEAEqE;AACrE,MAAM,UAAU,oBAAoB,CAAC,OAAmB,EAAE,IAAmB;IAC3E,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;QAAE,OAAO,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC1F,MAAM,SAAS,GACb,CAAC,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAC3B,CAAC,OAAO,CAAC,gBAAgB;QACzB,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAC9B,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC;QACnC,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;QAC7E,CAAC,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IAC5G,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IACxD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACtE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAmB,EAAE,IAAuB;IAC7E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,MAAM,GACV,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC;QACtB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;QAClE,CAAC,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC;YACpC,CAAC,MAAM,CAAC,gBAAgB;YACxB,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;YAC3B,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC;YAClC,wBAAwB,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC;IAC3E,IACE,IAAI,CAAC,gBAAgB;QACrB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS;QAC/B,CAAC,MAAM,EACP,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;oBACoB;AACpB,MAAM,UAAU,eAAe,CAAC,OAAmB,EAAE,KAA+B;IAClF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,UAAU,IAAI,KAAK,EAAE,CAAC;QAC/B,IAAI,UAAU,CAAC,iBAAiB,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAS;QACpF,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE;YACnC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;gBAAE,OAAO,SAAS,CAAC;YACjD,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACjD,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { IrExpr, IrType, SrcLoc } from "../../ir/ir.js";
2
+ import type { Lowerer } from "./lowerer.js";
3
+ export declare function abstractEqualitySupported(lowerer: Lowerer, left: IrType, right: IrType): boolean;
4
+ export declare function abstractEqualityExpr(lowerer: Lowerer, left: IrExpr, right: IrExpr, loc: SrcLoc, nanEqualsNan?: boolean): IrExpr;
5
+ /** Evaluate both operands once, left-to-right, then compare their stable values. */
6
+ export declare function lowerAbstractEquality(lowerer: Lowerer, left: IrExpr, right: IrExpr, negated: boolean, loc: SrcLoc): IrExpr | null;
@@ -0,0 +1,250 @@
1
+ import { InternalCompilerError } from "../../errors.js";
2
+ import { BOOL, DYN_HANDLE_KINDS, F64, isUnitType, typeEquals } from "../../ir/ir.js";
3
+ import { boolLit, numLit, varRef } from "../../ir/build.js";
4
+ /**
5
+ * The engine-free part of ECMAScript Abstract Equality Comparison.
6
+ *
7
+ * Every primitive pair is exact, including StringToNumber,
8
+ * StringToBigInt, Boolean-to-number recursion, and BigInt/Number's
9
+ * mathematical comparison. Object-to-primitive coercion stays outside
10
+ * this helper: user-defined valueOf/toString methods can execute arbitrary
11
+ * JavaScript, so a static build must keep that form fenced. Object pairs
12
+ * with one exact representation compare by identity, as == and === agree
13
+ * there.
14
+ */
15
+ const IDENTITY_KINDS = new Set([
16
+ "array",
17
+ "bytes",
18
+ "map",
19
+ "set",
20
+ "object",
21
+ "record",
22
+ "promise",
23
+ "symbol",
24
+ "classval",
25
+ "moduleNs",
26
+ ]);
27
+ const PRIMITIVE_KINDS = new Set([
28
+ "f64",
29
+ "string",
30
+ "bool",
31
+ "bigint",
32
+ "symbol",
33
+ ]);
34
+ function supportsPair(lowerer, left, right) {
35
+ if (left.kind === "union") {
36
+ const def = lowerer.unions.get(left.unionId);
37
+ return def !== undefined && def.arms.every((arm) => supportsPair(lowerer, arm, right));
38
+ }
39
+ if (right.kind === "union") {
40
+ const def = lowerer.unions.get(right.unionId);
41
+ return def !== undefined && def.arms.every((arm) => supportsPair(lowerer, left, arm));
42
+ }
43
+ if (isUnitType(left) || isUnitType(right)) {
44
+ const other = isUnitType(left) ? right : left;
45
+ return other.kind !== "dyn" && other.kind !== "jsval" && other.kind !== "caught" && other.kind !== "void";
46
+ }
47
+ if (PRIMITIVE_KINDS.has(left.kind) && PRIMITIVE_KINDS.has(right.kind))
48
+ return true;
49
+ if (left.kind === "func" && right.kind === "func")
50
+ return true;
51
+ if (IDENTITY_KINDS.has(left.kind) && typeEquals(left, right))
52
+ return true;
53
+ if (DYN_HANDLE_KINDS.has(left.kind) && typeEquals(left, right))
54
+ return true;
55
+ if (left.kind === "object" && right.kind === "object") {
56
+ return lowerer.isSubclassOf(left.className, right.className) || lowerer.isSubclassOf(right.className, left.className);
57
+ }
58
+ return false;
59
+ }
60
+ function boolAsNumber(value, loc) {
61
+ return {
62
+ kind: "ternary",
63
+ cond: value,
64
+ then: numLit(1, loc),
65
+ else_: numLit(0, loc),
66
+ type: F64,
67
+ loc,
68
+ };
69
+ }
70
+ function numericEq(left, right, nanEqualsNan, loc) {
71
+ const ordinary = { kind: "bin", op: "===", left, right, type: BOOL, loc };
72
+ if (!nanEqualsNan)
73
+ return ordinary;
74
+ return {
75
+ kind: "logical",
76
+ op: "||",
77
+ left: ordinary,
78
+ right: {
79
+ kind: "logical",
80
+ op: "&&",
81
+ left: { kind: "libCall", fn: "num.isNaN", args: [left], type: BOOL, loc },
82
+ right: { kind: "libCall", fn: "num.isNaN", args: [right], type: BOOL, loc },
83
+ type: BOOL,
84
+ loc,
85
+ },
86
+ type: BOOL,
87
+ loc,
88
+ };
89
+ }
90
+ function primitivePair(lowerer, left, right, nanEqualsNan, loc) {
91
+ if (isUnitType(left.type) || isUnitType(right.type)) {
92
+ return boolLit(isUnitType(left.type) && isUnitType(right.type), loc);
93
+ }
94
+ if (left.type.kind === "object" && right.type.kind === "object") {
95
+ if (typeEquals(left.type, right.type)) {
96
+ return { kind: "bin", op: "===", left, right, type: BOOL, loc };
97
+ }
98
+ if (lowerer.isSubclassOf(left.type.className, right.type.className)) {
99
+ return { kind: "bin", op: "===", left: lowerer.upcastTo(left, right.type.className), right, type: BOOL, loc };
100
+ }
101
+ if (lowerer.isSubclassOf(right.type.className, left.type.className)) {
102
+ return { kind: "bin", op: "===", left, right: lowerer.upcastTo(right, left.type.className), type: BOOL, loc };
103
+ }
104
+ }
105
+ if (left.type.kind === right.type.kind) {
106
+ switch (left.type.kind) {
107
+ case "f64":
108
+ return numericEq(left, right, nanEqualsNan, loc);
109
+ case "string":
110
+ return { kind: "strEq", negated: false, left, right, type: BOOL, loc };
111
+ case "bool":
112
+ return { kind: "bin", op: "===", left, right, type: BOOL, loc };
113
+ case "bigint":
114
+ return { kind: "libCall", fn: "bigint.eq", args: [left, right], type: BOOL, loc };
115
+ case "symbol":
116
+ case "array":
117
+ case "bytes":
118
+ case "map":
119
+ case "set":
120
+ case "record":
121
+ case "promise":
122
+ case "classval":
123
+ case "moduleNs":
124
+ return { kind: "bin", op: "===", left, right, type: BOOL, loc };
125
+ default:
126
+ break;
127
+ }
128
+ }
129
+ if (left.type.kind === "func" && right.type.kind === "func") {
130
+ return { kind: "bin", op: "===", left, right, type: BOOL, loc };
131
+ }
132
+ if (DYN_HANDLE_KINDS.has(left.type.kind) && typeEquals(left.type, right.type)) {
133
+ return { kind: "bin", op: "===", left, right, type: BOOL, loc };
134
+ }
135
+ // Boolean first recurses as ToNumber(boolean), per ECMA-262 7.2.13.
136
+ if (left.type.kind === "bool")
137
+ return primitivePair(lowerer, boolAsNumber(left, loc), right, nanEqualsNan, loc);
138
+ if (right.type.kind === "bool")
139
+ return primitivePair(lowerer, left, boolAsNumber(right, loc), nanEqualsNan, loc);
140
+ // Symbols never equal a different primitive type. Object/symbol would
141
+ // require ToPrimitive and was rejected by supportsPair.
142
+ if (left.type.kind === "symbol" || right.type.kind === "symbol")
143
+ return boolLit(false, loc);
144
+ if (left.type.kind === "f64" && right.type.kind === "string") {
145
+ const parsed = { kind: "libCall", fn: "num.fromString", args: [right], type: F64, loc };
146
+ return numericEq(left, parsed, false, loc);
147
+ }
148
+ if (left.type.kind === "string" && right.type.kind === "f64") {
149
+ const parsed = { kind: "libCall", fn: "num.fromString", args: [left], type: F64, loc };
150
+ return numericEq(parsed, right, false, loc);
151
+ }
152
+ if (left.type.kind === "bigint" && right.type.kind === "string") {
153
+ return { kind: "libCall", fn: "bigint.eqString", args: [left, right], type: BOOL, loc };
154
+ }
155
+ if (left.type.kind === "string" && right.type.kind === "bigint") {
156
+ return { kind: "libCall", fn: "bigint.eqString", args: [right, left], type: BOOL, loc };
157
+ }
158
+ if (left.type.kind === "bigint" && right.type.kind === "f64") {
159
+ const cmp = { kind: "libCall", fn: "bigint.cmpNumber", args: [left, right], type: F64, loc };
160
+ return { kind: "bin", op: "===", left: cmp, right: numLit(0, loc), type: BOOL, loc };
161
+ }
162
+ if (left.type.kind === "f64" && right.type.kind === "bigint") {
163
+ const cmp = { kind: "libCall", fn: "bigint.cmpNumber", args: [right, left], type: F64, loc };
164
+ return { kind: "bin", op: "===", left: cmp, right: numLit(0, loc), type: BOOL, loc };
165
+ }
166
+ throw new InternalCompilerError(`abstract equality reached an unplanned pair ${left.type.kind}/${right.type.kind}`);
167
+ }
168
+ function pairExpr(lowerer, left, right, nanEqualsNan, loc) {
169
+ if (left.type.kind === "union") {
170
+ const unionId = left.type.unionId;
171
+ const def = lowerer.unions.get(unionId);
172
+ if (!def || def.arms.length === 0)
173
+ throw new InternalCompilerError(`abstract equality over unknown union ${unionId}`);
174
+ const branch = (tag) => {
175
+ const arm = def.arms[tag];
176
+ if (!arm)
177
+ throw new InternalCompilerError(`abstract equality union ${unionId} lacks tag ${tag}`);
178
+ return pairExpr(lowerer, { kind: "unionNarrow", unionId, tag, value: left, type: arm, loc }, right, nanEqualsNan, loc);
179
+ };
180
+ let out = branch(def.arms.length - 1);
181
+ for (let tag = def.arms.length - 2; tag >= 0; tag--) {
182
+ out = {
183
+ kind: "ternary",
184
+ cond: { kind: "unionIsTag", unionId, tag, negated: false, value: left, type: BOOL, loc },
185
+ then: branch(tag),
186
+ else_: out,
187
+ type: BOOL,
188
+ loc,
189
+ };
190
+ }
191
+ return out;
192
+ }
193
+ if (right.type.kind === "union") {
194
+ const unionId = right.type.unionId;
195
+ const def = lowerer.unions.get(unionId);
196
+ if (!def || def.arms.length === 0)
197
+ throw new InternalCompilerError(`abstract equality over unknown union ${unionId}`);
198
+ const branch = (tag) => {
199
+ const arm = def.arms[tag];
200
+ if (!arm)
201
+ throw new InternalCompilerError(`abstract equality union ${unionId} lacks tag ${tag}`);
202
+ return pairExpr(lowerer, left, { kind: "unionNarrow", unionId, tag, value: right, type: arm, loc }, nanEqualsNan, loc);
203
+ };
204
+ let out = branch(def.arms.length - 1);
205
+ for (let tag = def.arms.length - 2; tag >= 0; tag--) {
206
+ out = {
207
+ kind: "ternary",
208
+ cond: { kind: "unionIsTag", unionId, tag, negated: false, value: right, type: BOOL, loc },
209
+ then: branch(tag),
210
+ else_: out,
211
+ type: BOOL,
212
+ loc,
213
+ };
214
+ }
215
+ return out;
216
+ }
217
+ return primitivePair(lowerer, left, right, nanEqualsNan, loc);
218
+ }
219
+ export function abstractEqualitySupported(lowerer, left, right) {
220
+ return supportsPair(lowerer, left, right);
221
+ }
222
+ export function abstractEqualityExpr(lowerer, left, right, loc, nanEqualsNan = false) {
223
+ if (!supportsPair(lowerer, left.type, right.type)) {
224
+ throw new InternalCompilerError(`abstract equality expression built for unsupported ${left.type.kind}/${right.type.kind} pair`);
225
+ }
226
+ return pairExpr(lowerer, left, right, nanEqualsNan, loc);
227
+ }
228
+ /** Evaluate both operands once, left-to-right, then compare their stable values. */
229
+ export function lowerAbstractEquality(lowerer, left, right, negated, loc) {
230
+ if (!supportsPair(lowerer, left.type, right.type))
231
+ return null;
232
+ const stmts = [];
233
+ const stable = (value, name) => {
234
+ if (isUnitType(value.type)) {
235
+ if (value.kind !== "unitLit")
236
+ stmts.push({ kind: "exprStmt", expr: value, loc });
237
+ return { kind: "unitLit", unit: value.type.kind === "nullT" ? "null" : "undefined", type: value.type, loc };
238
+ }
239
+ const local = lowerer.declareHiddenLocal(name, value.type);
240
+ stmts.push({ kind: "varDecl", localId: local.id, init: value, loc });
241
+ return varRef(local.id, value.type, loc);
242
+ };
243
+ const a = stable(left, "%looseA");
244
+ const b = stable(right, "%looseB");
245
+ let result = pairExpr(lowerer, a, b, false, loc);
246
+ if (negated)
247
+ result = { kind: "unary", op: "!", operand: result, type: BOOL, loc };
248
+ return stmts.length === 0 ? result : { kind: "seqExpr", stmts, result, type: BOOL, loc };
249
+ }
250
+ //# sourceMappingURL=abstract-equality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abstract-equality.js","sourceRoot":"","sources":["../../../src/frontend/lowering/abstract-equality.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import { InternalCompilerError } from "../../errors.js";
2
2
  /* The node:assert lowering (a spoke module like lower-dgram.ts): the
3
3
  * callable module form (`assert(x)` through a default import or a CJS
4
- * require binding), ok, the strict/deep equality quartet, fail, throws,
4
+ * require binding), ok, legacy equal/notEqual, the strict/deep equality
5
+ * quartet, fail, throws,
5
6
  * and match/doesNotMatch — for BOTH the "assert" and "assert/strict"
6
7
  * modules ("assert/strict" additionally binds the loose NAMES to the
7
8
  * strict comparisons: equal IS strictEqual, exactly Node's aliasing).
@@ -26,7 +27,8 @@ import * as ts from "../ts7/adapter.js";
26
27
  import { resultIsDiscarded } from "./call-position.js";
27
28
  import { jsFuncNameOf, own } from "./lowerer.js";
28
29
  import { NARROW_FIRST } from "./surfaces.js";
29
- import { typeReachesItself } from "./lower-inspect.js";
30
+ import { inspectExpr, typeReachesItself } from "./lower-inspect.js";
31
+ import { abstractEqualityExpr, abstractEqualitySupported } from "./abstract-equality.js";
30
32
  import { BOOL, CAUGHT, DYN, DYN_HANDLE_KINDS, F64, REGEX, RUNTIME_ERROR_CLASSES, STRING, VOID, isUnitType, typeEquals, typeKey } from "../../ir/ir.js";
31
33
  import { boolLit, countedFor, numLit, strLit, varRef } from "../../ir/build.js";
32
34
  /** node:assert/strict binds the loose NAMES to the strict comparisons —
@@ -76,6 +78,10 @@ export function lowerAssertModuleCall(lowerer, expr, bi, loc) {
76
78
  switch (canonicalAssertMember(bi.module, bi.member)) {
77
79
  case "ok":
78
80
  return lowerAssertOk(lowerer, expr, loc);
81
+ case "equal":
82
+ return lowerAssertLooseEqual(lowerer, expr, loc, false);
83
+ case "notEqual":
84
+ return lowerAssertLooseEqual(lowerer, expr, loc, true);
79
85
  case "strictEqual":
80
86
  return lowerAssertEqual(lowerer, expr, loc, false, false);
81
87
  case "notStrictEqual":
@@ -102,6 +108,69 @@ export function lowerAssertModuleCall(lowerer, expr, bi, loc) {
102
108
  return null;
103
109
  }
104
110
  }
111
+ function looseAssertTypeSupported(lowerer, type) {
112
+ if (type.kind === "f64" || type.kind === "bigint" || type.kind === "string" ||
113
+ type.kind === "bool" || type.kind === "symbol" || isUnitType(type)) {
114
+ return true;
115
+ }
116
+ if (type.kind !== "union")
117
+ return false;
118
+ const def = lowerer.unions.get(type.unionId);
119
+ return def !== undefined && def.arms.every((arm) => looseAssertTypeSupported(lowerer, arm));
120
+ }
121
+ /** assert.equal / assert.notEqual over statically represented primitives.
122
+ * The shared Abstract Equality kernel owns coercion; this wrapper adds
123
+ * Node v24's legacy NaN-equals-NaN exception and the exact one-line
124
+ * generated message. Both values stabilize first so comparison and
125
+ * inspection never re-evaluate user expressions. */
126
+ function lowerAssertLooseEqual(lowerer, expr, loc, negated) {
127
+ const surface = negated ? "assert.notEqual" : "assert.equal";
128
+ requireStatementPosition(lowerer, expr, surface);
129
+ if (expr.arguments.length < 2 || expr.arguments.length > 3) {
130
+ lowerer.noLowering(`${surface} with ${expr.arguments.length} arguments`, expr);
131
+ }
132
+ const aNode = expr.arguments[0];
133
+ const bNode = expr.arguments[1];
134
+ if (!aNode || !bNode)
135
+ throw new InternalCompilerError(`${surface} arity fence returned unexpectedly`);
136
+ const left = lowerer.lowerExpr(aNode);
137
+ const right = lowerer.lowerExpr(bNode);
138
+ if (!looseAssertTypeSupported(lowerer, left.type) ||
139
+ !looseAssertTypeSupported(lowerer, right.type) ||
140
+ !abstractEqualitySupported(lowerer, left.type, right.type)) {
141
+ lowerer.noLowering(`${surface} of '${lowerer.fmt(left.type)}' and '${lowerer.fmt(right.type)}' values`, expr, "legacy equality lowers for primitive and primitive-union operands; object-to-primitive coercion can execute user-defined valueOf/toString methods");
142
+ }
143
+ const stmts = [];
144
+ const stable = (value, name) => {
145
+ if (isUnitType(value.type)) {
146
+ if (value.kind !== "unitLit")
147
+ stmts.push({ kind: "exprStmt", expr: value, loc });
148
+ return {
149
+ kind: "unitLit",
150
+ unit: value.type.kind === "nullT" ? "null" : "undefined",
151
+ type: value.type,
152
+ loc,
153
+ };
154
+ }
155
+ const local = lowerer.declareHiddenLocal(name, value.type);
156
+ stmts.push({ kind: "varDecl", localId: local.id, init: value, loc });
157
+ return varRef(local.id, value.type, loc);
158
+ };
159
+ const a = stable(left, "%assertLooseA");
160
+ const b = stable(right, "%assertLooseB");
161
+ const equal = abstractEqualityExpr(lowerer, a, b, loc, true);
162
+ const actual = inspectExpr(lowerer, a.type, a, numLit(0, loc), numLit(2, loc), loc);
163
+ const expected = inspectExpr(lowerer, b.type, b, numLit(0, loc), numLit(2, loc), loc);
164
+ const { msg, hasMsg } = lowerMessageArg(lowerer, expr.arguments[2], loc);
165
+ const result = {
166
+ kind: "libCall",
167
+ fn: "assert.looseResult",
168
+ args: [equal, boolLit(negated, loc), actual, expected, msg, hasMsg],
169
+ type: VOID,
170
+ loc,
171
+ };
172
+ return { kind: "seqExpr", stmts, result, type: VOID, loc };
173
+ }
105
174
  /** The callable-module form: `assert(x)` where the callee identifier IS
106
175
  * the assert module binding — a default import (`import assert from
107
176
  * "node:assert"`) or the CJS `const assert = require("assert")`. Node's