@scriptc/compiler 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +57 -30
- package/dist/backend/cycle-analysis.test.js +1 -1
- package/dist/backend/executable-features.js +1 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/link-plan-core.d.ts +2 -0
- package/dist/backend/link-plan-core.js +1 -0
- package/dist/backend/link-plan-core.js.map +1 -1
- package/dist/backend/link-plan.d.ts +1 -0
- package/dist/backend/link-plan.js +3 -0
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +32 -4
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/byte-windows.d.ts +31 -0
- package/dist/backend/llvm/byte-windows.js +334 -0
- package/dist/backend/llvm/byte-windows.js.map +1 -0
- package/dist/backend/llvm/byte-windows.test.d.ts +1 -0
- package/dist/backend/llvm/byte-windows.test.js +244 -0
- package/dist/backend/llvm/byte-windows.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.d.ts +2 -2
- package/dist/backend/llvm/call-lifetimes.js +17 -7
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +14 -1
- package/dist/backend/llvm/classes.js +80 -9
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.d.ts +1 -0
- package/dist/backend/llvm/classes.test.js +99 -0
- package/dist/backend/llvm/classes.test.js.map +1 -0
- package/dist/backend/llvm/constant-callbacks.d.ts +11 -0
- package/dist/backend/llvm/constant-callbacks.js +213 -0
- package/dist/backend/llvm/constant-callbacks.js.map +1 -0
- package/dist/backend/llvm/constant-callbacks.test.d.ts +1 -0
- package/dist/backend/llvm/constant-callbacks.test.js +124 -0
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +1 -1
- package/dist/backend/llvm/dyn.js +7 -34
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +19 -0
- package/dist/backend/llvm/emitter.js +274 -46
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +17 -11
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +11 -0
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +91 -23
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +21 -9
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +36 -3
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +7 -0
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
- package/dist/backend/llvm/integer-remainder.d.ts +7 -0
- package/dist/backend/llvm/integer-remainder.js +26 -0
- package/dist/backend/llvm/integer-remainder.js.map +1 -0
- package/dist/backend/llvm/layouts.js +1 -1
- package/dist/backend/llvm/layouts.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +7 -0
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +7 -22
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +15 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +8 -2
- package/dist/backend/llvm/local-array-reads.js +89 -68
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +28 -4
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +1 -1
- package/dist/backend/llvm/loop-array-borrows.d.ts +11 -0
- package/dist/backend/llvm/loop-array-borrows.js +70 -0
- package/dist/backend/llvm/loop-array-borrows.js.map +1 -0
- package/dist/backend/llvm/loop-array-borrows.test.d.ts +1 -0
- package/dist/backend/llvm/loop-array-borrows.test.js +145 -0
- package/dist/backend/llvm/loop-array-borrows.test.js.map +1 -0
- package/dist/backend/llvm/map-read-lifetimes.d.ts +5 -0
- package/dist/backend/llvm/map-read-lifetimes.js +20 -5
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +1 -1
- package/dist/backend/llvm/reference-effects.d.ts +2 -1
- package/dist/backend/llvm/reference-effects.js +7 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +4 -1
- package/dist/backend/llvm/shapes.js +22 -7
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/split-loops.d.ts +48 -0
- package/dist/backend/llvm/split-loops.js +183 -0
- package/dist/backend/llvm/split-loops.js.map +1 -0
- package/dist/backend/llvm/split.js +0 -7
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/split.test.js +66 -2
- package/dist/backend/llvm/split.test.js.map +1 -1
- package/dist/backend/llvm/stack-callbacks.d.ts +14 -0
- package/dist/backend/llvm/stack-callbacks.js +73 -0
- package/dist/backend/llvm/stack-callbacks.js.map +1 -0
- package/dist/backend/llvm/stack-captures.d.ts +25 -0
- package/dist/backend/llvm/stack-captures.js +150 -0
- package/dist/backend/llvm/stack-captures.js.map +1 -0
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +8 -4
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +20 -0
- package/dist/backend/llvm/string-slices.js +87 -0
- package/dist/backend/llvm/string-slices.js.map +1 -0
- package/dist/backend/llvm/string-slices.test.d.ts +1 -0
- package/dist/backend/llvm/string-slices.test.js +98 -0
- package/dist/backend/llvm/string-slices.test.js.map +1 -0
- package/dist/backend/llvm/switch-dispatch.test.js +1 -1
- package/dist/backend/llvm/walkers.d.ts +4 -14
- package/dist/backend/llvm/walkers.js +53 -311
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/may-throw.js +1 -1
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +2 -0
- package/dist/backend/native/executable.js +12 -4
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +2 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +6 -0
- package/dist/backend/native-codegen-core.js +21 -0
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +4 -0
- package/dist/backend/native-codegen.js +34 -18
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +47 -2
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +1 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-tools.d.ts +3 -1
- package/dist/backend/native-tools.js +6 -4
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +1 -0
- package/dist/backend/runtime-pack-core.js +8 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +41 -4
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +11 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/executable/executable-cache.d.ts +1 -0
- package/dist/executable/executable-cache.js +2 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +15 -0
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/fork-target.d.ts +5 -0
- package/dist/frontend/fork-target.js +40 -8
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.d.ts +1 -0
- package/dist/frontend/fork-target.test.js +59 -0
- package/dist/frontend/fork-target.test.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +2 -2
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.d.ts +2 -11
- package/dist/frontend/lowering/builtins/atomics.js +64 -28
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +3 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +51 -4
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +6 -1
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/workers.d.ts +5 -0
- package/dist/frontend/lowering/builtins/workers.js +65 -0
- package/dist/frontend/lowering/builtins/workers.js.map +1 -0
- package/dist/frontend/lowering/class-assertions.d.ts +7 -0
- package/dist/frontend/lowering/class-assertions.js +96 -0
- package/dist/frontend/lowering/class-assertions.js.map +1 -0
- package/dist/frontend/lowering/class-protocols.d.ts +17 -0
- package/dist/frontend/lowering/class-protocols.js +126 -0
- package/dist/frontend/lowering/class-protocols.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +7 -11
- package/dist/frontend/lowering/containers/array-callbacks.js +52 -87
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +12 -34
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +22 -3
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +2 -6
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +2 -5
- package/dist/frontend/lowering/generic-functions.js +13 -10
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/instantiation-path.d.ts +8 -0
- package/dist/frontend/lowering/instantiation-path.js +10 -0
- package/dist/frontend/lowering/instantiation-path.js.map +1 -0
- package/dist/frontend/lowering/instantiation-path.test.d.ts +1 -0
- package/dist/frontend/lowering/instantiation-path.test.js +23 -0
- package/dist/frontend/lowering/instantiation-path.test.js.map +1 -0
- package/dist/frontend/lowering/lower-builtin-values.js +11 -7
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +36 -3
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +5 -0
- package/dist/frontend/lowering/lower-classes.js +121 -53
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +31 -10
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.d.ts +1 -1
- package/dist/frontend/lowering/lower-functions.js +2 -2
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +1 -1
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +1 -0
- package/dist/frontend/lowering/lower-modules.js +44 -9
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +13 -11
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +1 -1
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +13 -1
- package/dist/frontend/lowering/lowerer.js +51 -9
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.d.ts +7 -0
- package/dist/frontend/lowering/split-consumers.js +64 -0
- package/dist/frontend/lowering/split-consumers.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +3 -4
- package/dist/frontend/lowering/surfaces.js +35 -7
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/module-source-candidates.d.ts +10 -0
- package/dist/frontend/module-source-candidates.js +40 -0
- package/dist/frontend/module-source-candidates.js.map +1 -0
- package/dist/frontend/module-source-candidates.test.d.ts +1 -0
- package/dist/frontend/module-source-candidates.test.js +53 -0
- package/dist/frontend/module-source-candidates.test.js.map +1 -0
- package/dist/frontend/pipeline.js +2 -2
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +2 -0
- package/dist/frontend/program-analysis.js +2 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.js +17 -29
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/ts7/ast-node.js +6 -8
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +42 -1
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.d.ts +4 -0
- package/dist/frontend/ts7/ast-wire.js +28 -0
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/ast.d.ts +2 -1
- package/dist/frontend/ts7/ast.js +8 -4
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +8 -2
- package/dist/frontend/ts7/checker.js +41 -5
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +42 -0
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/program-host.d.ts +7 -0
- package/dist/frontend/ts7/program-host.js +26 -2
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/program-host.test.js +29 -0
- package/dist/frontend/ts7/program-host.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +3 -0
- package/dist/frontend/type-mapper.js +44 -2
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/worker-target.d.ts +6 -0
- package/dist/frontend/worker-target.js +108 -0
- package/dist/frontend/worker-target.js.map +1 -0
- package/dist/frontend/worker-target.test.d.ts +1 -0
- package/dist/frontend/worker-target.test.js +71 -0
- package/dist/frontend/worker-target.test.js.map +1 -0
- package/dist/index.js +24 -7
- package/dist/index.js.map +1 -1
- package/dist/ir/builtin-effects.js +12 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +13 -12
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/ir.d.ts +9 -10
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/numeric-call-specialization.d.ts +8 -0
- package/dist/ir/numeric-call-specialization.js +198 -0
- package/dist/ir/numeric-call-specialization.js.map +1 -0
- package/dist/ir/runtime-features.js +4 -3
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +3 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.js +89 -23
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +91 -4
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +2 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/native/compiler.js +24 -11
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +7 -3
- package/dist/native/compiler.test.js.map +1 -1
- package/dist/native/prepare.js +2 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +1 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +30 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as ts from "../../ts7/adapter.js";
|
|
2
|
+
import { locOf } from "../../program.js";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { isWorkerConstructor, workerModulePath } from "../../worker-target.js";
|
|
5
|
+
import { tsgoPath } from "../../dts-paths.js";
|
|
6
|
+
import { BOOL, DYN, F64, STRING, UNDEFINED_T, isFfiCallbackParam, } from "../../../ir/ir.js";
|
|
7
|
+
export function lowerWorkerMetadata(member, loc) {
|
|
8
|
+
switch (member) {
|
|
9
|
+
case "isMainThread":
|
|
10
|
+
return { kind: "libCall", fn: "worker.isMainThread", args: [], type: BOOL, loc };
|
|
11
|
+
case "threadId":
|
|
12
|
+
return { kind: "libCall", fn: "worker.threadId", args: [], type: F64, loc };
|
|
13
|
+
case "workerData":
|
|
14
|
+
return { kind: "libCall", fn: "worker.data", args: [], type: DYN, loc };
|
|
15
|
+
case "parentPort":
|
|
16
|
+
return { kind: "libCall", fn: "worker.parentPort", args: [], type: DYN, loc };
|
|
17
|
+
case "isInternalThread":
|
|
18
|
+
return { kind: "boolLit", value: false, type: BOOL, loc };
|
|
19
|
+
default:
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function lowerWorkerNew(lowerer, expression) {
|
|
24
|
+
const constructor = expression.expression;
|
|
25
|
+
if (!isWorkerConstructor(lowerer.program, constructor))
|
|
26
|
+
return null;
|
|
27
|
+
const args = expression.arguments ?? [];
|
|
28
|
+
if (args.length < 1 || args.length > 2 || args.some(ts.isSpreadElement)) {
|
|
29
|
+
lowerer.noLowering("Worker constructor arguments", expression, "use new Worker(filename, options?)");
|
|
30
|
+
}
|
|
31
|
+
const filename = args[0];
|
|
32
|
+
const path = workerModulePath(lowerer.program, filename);
|
|
33
|
+
const root = path === null ? undefined : lowerer.workerTargetIdByPath.get(tsgoPath(resolve(path)));
|
|
34
|
+
if (root === undefined) {
|
|
35
|
+
lowerer.noLowering("this Worker entry point", filename, "the worker entry must resolve to a statically compiled source file");
|
|
36
|
+
}
|
|
37
|
+
if (lowerer.dynamic || lowerer.targetPlatform === "wasi") {
|
|
38
|
+
lowerer.noLowering("Worker execution in this target", expression, "use a native static executable");
|
|
39
|
+
}
|
|
40
|
+
if (lowerer.ffiImports.some((entry) => entry.params.some((parameter) => isFfiCallbackParam(parameter) && parameter.callback.invoke === "foreign"))) {
|
|
41
|
+
lowerer.noLowering("workers with foreign-thread native callbacks", expression, "native callbacks in worker executables must run on their owning script thread");
|
|
42
|
+
}
|
|
43
|
+
lowerer.usesWorkers = true;
|
|
44
|
+
const loc = locOf(expression);
|
|
45
|
+
const options = args[1]
|
|
46
|
+
? lowerer.lowerExprExpecting(args[1], DYN)
|
|
47
|
+
: {
|
|
48
|
+
kind: "dynFrom",
|
|
49
|
+
value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc },
|
|
50
|
+
type: DYN,
|
|
51
|
+
loc,
|
|
52
|
+
};
|
|
53
|
+
return {
|
|
54
|
+
kind: "libCall",
|
|
55
|
+
fn: "worker.new",
|
|
56
|
+
args: [
|
|
57
|
+
{ kind: "numLit", value: root, type: F64, loc },
|
|
58
|
+
{ kind: "strLit", value: path, type: STRING, loc },
|
|
59
|
+
options,
|
|
60
|
+
],
|
|
61
|
+
type: DYN,
|
|
62
|
+
loc,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=workers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workers.js","sourceRoot":"","sources":["../../../../src/frontend/lowering/builtins/workers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type IrExpr, type IrType, type SrcLoc } from "../../ir/ir.js";
|
|
2
|
+
import type { Lowerer } from "./lowerer.js";
|
|
3
|
+
/** Assertions cannot prove a subclass layout. Check the stored class before
|
|
4
|
+
* exposing descendant fields, preserving identity and one operand evaluation. */
|
|
5
|
+
export declare function checkedClassAssertion(lowerer: Lowerer, value: IrExpr, target: IrType & {
|
|
6
|
+
kind: "object";
|
|
7
|
+
}, loc: SrcLoc): IrExpr | null;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { nodeThrowExpr, varRef } from "../../ir/build.js";
|
|
2
|
+
import { BOOL, typeEquals, typeKey, } from "../../ir/ir.js";
|
|
3
|
+
/** Assertions cannot prove a subclass layout. Check the stored class before
|
|
4
|
+
* exposing descendant fields, preserving identity and one operand evaluation. */
|
|
5
|
+
export function checkedClassAssertion(lowerer, value, target, loc) {
|
|
6
|
+
const source = value;
|
|
7
|
+
const compatible = (type) => type.kind === "object" &&
|
|
8
|
+
(typeEquals(type, target) ||
|
|
9
|
+
lowerer.isSubclassOf(type.className, target.className) ||
|
|
10
|
+
lowerer.isSubclassOf(target.className, type.className));
|
|
11
|
+
const failure = () => nodeThrowExpr(1, "", `Value is not an instance of '${lowerer.fmt(target)}'`, target, loc);
|
|
12
|
+
const convert = (input) => {
|
|
13
|
+
if (input.type.kind !== "object")
|
|
14
|
+
return failure();
|
|
15
|
+
if (typeEquals(input.type, target))
|
|
16
|
+
return input;
|
|
17
|
+
if (lowerer.isSubclassOf(input.type.className, target.className))
|
|
18
|
+
return { kind: "upcast", value: input, type: target, loc };
|
|
19
|
+
return {
|
|
20
|
+
kind: "ternary",
|
|
21
|
+
cond: { kind: "instanceOf", value: input, className: target.className, type: BOOL, loc },
|
|
22
|
+
then: { kind: "downcast", value: input, type: target, loc },
|
|
23
|
+
else_: failure(),
|
|
24
|
+
type: target,
|
|
25
|
+
loc,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
const union = source.type.kind === "union" ? lowerer.unions.get(source.type.unionId) : null;
|
|
29
|
+
if (union) {
|
|
30
|
+
if (!union.arms.some(compatible))
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
if (!compatible(source.type))
|
|
35
|
+
return null;
|
|
36
|
+
if (typeEquals(source.type, target))
|
|
37
|
+
return source;
|
|
38
|
+
if (lowerer.isSubclassOf(source.type.className, target.className))
|
|
39
|
+
return convert(source);
|
|
40
|
+
}
|
|
41
|
+
const key = `classassert:${typeKey(source.type)}:${typeKey(target)}`;
|
|
42
|
+
let name = lowerer.coercions.retags.get(key);
|
|
43
|
+
if (!name) {
|
|
44
|
+
name = `%class.assert.${lowerer.coercions.retags.size}`;
|
|
45
|
+
lowerer.coercions.retags.set(key, name);
|
|
46
|
+
const input = varRef("value.0", source.type, loc);
|
|
47
|
+
const body = [];
|
|
48
|
+
const locals = [{ id: "value.0", name: "value", type: source.type, mutable: false }];
|
|
49
|
+
if (union) {
|
|
50
|
+
for (let tag = 0; tag < union.arms.length; tag++) {
|
|
51
|
+
const arm = union.arms[tag];
|
|
52
|
+
if (!compatible(arm))
|
|
53
|
+
continue;
|
|
54
|
+
const localId = `arm.${tag}`;
|
|
55
|
+
locals.push({ id: localId, name: "arm", type: arm, mutable: false });
|
|
56
|
+
body.push({
|
|
57
|
+
kind: "if",
|
|
58
|
+
cond: {
|
|
59
|
+
kind: "unionIsTag",
|
|
60
|
+
unionId: union.id,
|
|
61
|
+
tag,
|
|
62
|
+
negated: false,
|
|
63
|
+
value: input,
|
|
64
|
+
type: BOOL,
|
|
65
|
+
loc,
|
|
66
|
+
},
|
|
67
|
+
then: [
|
|
68
|
+
{
|
|
69
|
+
kind: "varDecl",
|
|
70
|
+
localId,
|
|
71
|
+
init: { kind: "unionNarrow", unionId: union.id, tag, value: input, type: arm, loc },
|
|
72
|
+
loc,
|
|
73
|
+
},
|
|
74
|
+
{ kind: "return", value: convert(varRef(localId, arm, loc)), loc },
|
|
75
|
+
],
|
|
76
|
+
else_: null,
|
|
77
|
+
loc,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
body.push({ kind: "return", value: failure(), loc });
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
body.push({ kind: "return", value: convert(input), loc });
|
|
84
|
+
}
|
|
85
|
+
lowerer.liftedFns.push({
|
|
86
|
+
name,
|
|
87
|
+
params: [{ localId: "value.0", name: "value", type: source.type }],
|
|
88
|
+
locals,
|
|
89
|
+
returnType: target,
|
|
90
|
+
body,
|
|
91
|
+
loc,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return { kind: "call", callee: name, args: [source], type: target, loc };
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=class-assertions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class-assertions.js","sourceRoot":"","sources":["../../../src/frontend/lowering/class-assertions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as ts from "../ts7/adapter.js";
|
|
2
|
+
/** Index only program classes. Ambient declarations describe APIs, not
|
|
3
|
+
* compiled implementations, and must not change a protocol's storage. */
|
|
4
|
+
export declare class ClassProtocols {
|
|
5
|
+
private readonly checker;
|
|
6
|
+
private readonly sources;
|
|
7
|
+
private implemented;
|
|
8
|
+
private readonly methods;
|
|
9
|
+
private readonly answers;
|
|
10
|
+
constructor(checker: ts.TypeChecker, sources: readonly ts.SourceFile[]);
|
|
11
|
+
private index;
|
|
12
|
+
/** Class-backed protocols require live receiver dispatch. Other interfaces,
|
|
13
|
+
* including factories backed by static methods and ordinary records of
|
|
14
|
+
* closures, retain their fixed native layouts. */
|
|
15
|
+
usesCheckedIdentity(type: ts.Type): boolean;
|
|
16
|
+
private protocol;
|
|
17
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as ts from "../ts7/adapter.js";
|
|
2
|
+
import { isGenericCallableMemberType } from "../type-mapper.js";
|
|
3
|
+
/** Index only program classes. Ambient declarations describe APIs, not
|
|
4
|
+
* compiled implementations, and must not change a protocol's storage. */
|
|
5
|
+
export class ClassProtocols {
|
|
6
|
+
checker;
|
|
7
|
+
sources;
|
|
8
|
+
implemented = null;
|
|
9
|
+
methods = new Map();
|
|
10
|
+
answers = new Map();
|
|
11
|
+
constructor(checker, sources) {
|
|
12
|
+
this.checker = checker;
|
|
13
|
+
this.sources = sources;
|
|
14
|
+
}
|
|
15
|
+
index() {
|
|
16
|
+
if (this.implemented !== null)
|
|
17
|
+
return this.implemented;
|
|
18
|
+
const protocols = new Set();
|
|
19
|
+
this.implemented = protocols;
|
|
20
|
+
const add = (type) => {
|
|
21
|
+
const symbol = type.getSymbol();
|
|
22
|
+
if (!symbol || protocols.has(symbol))
|
|
23
|
+
return;
|
|
24
|
+
protocols.add(symbol);
|
|
25
|
+
const target = type.isTypeReference() ? type.getTarget() : type;
|
|
26
|
+
if (target?.isClassOrInterface())
|
|
27
|
+
this.checker.getBaseTypes(target).forEach(add);
|
|
28
|
+
};
|
|
29
|
+
const usesReceiver = (node) => node.kind === ts.SyntaxKind.ThisKeyword || ts.forEachChild(node, usesReceiver) === true;
|
|
30
|
+
const visit = (node) => {
|
|
31
|
+
if (ts.isClassDeclaration(node) || ts.isClassExpression(node)) {
|
|
32
|
+
for (const clause of node.heritageClauses ?? [])
|
|
33
|
+
if (clause.token === ts.SyntaxKind.ImplementsKeyword)
|
|
34
|
+
for (const protocol of clause.types)
|
|
35
|
+
add(this.checker.getTypeAtLocation(protocol));
|
|
36
|
+
const symbol = node.name ? this.checker.getSymbolAtLocation(node.name) : undefined;
|
|
37
|
+
const instance = symbol ? this.checker.getDeclaredTypeOfSymbol(symbol) : undefined;
|
|
38
|
+
for (const property of instance ? this.checker.getPropertiesOfType(instance) : []) {
|
|
39
|
+
if (!this.checker
|
|
40
|
+
.declarationsOf(property)
|
|
41
|
+
.some((member) => ts.isMethodDeclaration(member) &&
|
|
42
|
+
!member.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword)))
|
|
43
|
+
continue;
|
|
44
|
+
const entries = this.methods.get(property.name) ?? [];
|
|
45
|
+
entries.push(node);
|
|
46
|
+
this.methods.set(property.name, entries);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (ts.isObjectLiteralExpression(node) &&
|
|
50
|
+
node.properties.some((property) => (ts.isMethodDeclaration(property) ||
|
|
51
|
+
ts.isGetAccessorDeclaration(property) ||
|
|
52
|
+
ts.isSetAccessorDeclaration(property)) &&
|
|
53
|
+
property.body !== undefined &&
|
|
54
|
+
usesReceiver(property.body))) {
|
|
55
|
+
// Receiver-dependent methods and accessors need a live object even
|
|
56
|
+
// without a class implementation. Receiver-free methods keep their
|
|
57
|
+
// native callable fields, including async callbacks crossing islands.
|
|
58
|
+
add(this.checker.getTypeAtLocation(node));
|
|
59
|
+
const contextual = this.checker.getContextualType(node);
|
|
60
|
+
if (contextual)
|
|
61
|
+
add(contextual);
|
|
62
|
+
}
|
|
63
|
+
ts.forEachChild(node, visit);
|
|
64
|
+
};
|
|
65
|
+
for (const source of this.sources)
|
|
66
|
+
if (!source.isDeclarationFile)
|
|
67
|
+
visit(source);
|
|
68
|
+
return protocols;
|
|
69
|
+
}
|
|
70
|
+
/** Class-backed protocols require live receiver dispatch. Other interfaces,
|
|
71
|
+
* including factories backed by static methods and ordinary records of
|
|
72
|
+
* closures, retain their fixed native layouts. */
|
|
73
|
+
usesCheckedIdentity(type) {
|
|
74
|
+
if (type.isUnionType()) {
|
|
75
|
+
const present = ts
|
|
76
|
+
.constituentTypes(type)
|
|
77
|
+
.filter((part) => (part.flags & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)) === 0);
|
|
78
|
+
return present.length > 0 && present.every((part) => this.usesCheckedIdentity(part));
|
|
79
|
+
}
|
|
80
|
+
if (type.isIntersectionType())
|
|
81
|
+
return ts.constituentTypes(type).some((part) => this.usesCheckedIdentity(part));
|
|
82
|
+
if ((type.flags & ts.TypeFlags.Object) === 0)
|
|
83
|
+
return false;
|
|
84
|
+
const previous = this.answers.get(type);
|
|
85
|
+
if (previous !== undefined)
|
|
86
|
+
return previous;
|
|
87
|
+
const answer = this.protocol(type);
|
|
88
|
+
this.answers.set(type, answer);
|
|
89
|
+
return answer;
|
|
90
|
+
}
|
|
91
|
+
protocol(type) {
|
|
92
|
+
const protocols = this.index();
|
|
93
|
+
const symbol = type.getSymbol();
|
|
94
|
+
const properties = this.checker.getPropertiesOfType(type);
|
|
95
|
+
// Generic-only members have no single runtime callable signature. Keep
|
|
96
|
+
// their existing declaration-based specialization and refusal boundary.
|
|
97
|
+
if (properties.length > 0 &&
|
|
98
|
+
properties.every((property) => isGenericCallableMemberType(this.checker.getTypeOfSymbol(property), this.checker)))
|
|
99
|
+
return false;
|
|
100
|
+
if (symbol && protocols.has(symbol))
|
|
101
|
+
return true;
|
|
102
|
+
if (!symbol ||
|
|
103
|
+
!this.checker
|
|
104
|
+
.declarationsOf(symbol)
|
|
105
|
+
.some((declaration) => ts.isInterfaceDeclaration(declaration) &&
|
|
106
|
+
!declaration.getSourceFile().isDeclarationFile))
|
|
107
|
+
return false;
|
|
108
|
+
for (const property of properties) {
|
|
109
|
+
const memberType = this.checker.getTypeOfSymbol(property);
|
|
110
|
+
if (isGenericCallableMemberType(memberType, this.checker))
|
|
111
|
+
continue;
|
|
112
|
+
if (this.checker.getCallSignatures(memberType).length === 0)
|
|
113
|
+
continue;
|
|
114
|
+
for (const declaration of this.methods.get(property.name) ?? []) {
|
|
115
|
+
const classSymbol = declaration.name
|
|
116
|
+
? this.checker.getSymbolAtLocation(declaration.name)
|
|
117
|
+
: undefined;
|
|
118
|
+
if (classSymbol &&
|
|
119
|
+
this.checker.isTypeAssignableTo(this.checker.getDeclaredTypeOfSymbol(classSymbol), type))
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=class-protocols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"class-protocols.js","sourceRoot":"","sources":["../../../src/frontend/lowering/class-protocols.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAEhE;yEACyE;AACzE,MAAM,OAAO,cAAc;IAMN,OAAO;IACP,OAAO;IANlB,WAAW,GAA0B,IAAI,CAAC;IACjC,OAAO,GAAG,IAAI,GAAG,EAAqC,CAAC;IACvD,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEvD,YACmB,OAAuB,EACvB,OAAiC;uBADjC,OAAO;uBACP,OAAO;IACvB,CAAC;IAEI,KAAK;QACX,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAa,CAAC;QACvC,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC7B,MAAM,GAAG,GAAG,CAAC,IAAa,EAAQ,EAAE;YAClC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,OAAO;YAC7C,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACtB,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAChE,IAAI,MAAM,EAAE,kBAAkB,EAAE;gBAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnF,CAAC,CAAC;QACF,MAAM,YAAY,GAAG,CAAC,IAAa,EAAW,EAAE,CAC9C,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,KAAK,IAAI,CAAC;QAC1F,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;YACpC,IAAI,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9D,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,eAAe,IAAI,EAAE;oBAC7C,IAAI,MAAM,CAAC,KAAK,KAAK,EAAE,CAAC,UAAU,CAAC,iBAAiB;wBAClD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,KAAK;4BAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACvF,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACnF,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACnF,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;oBAClF,IACE,CAAC,IAAI,CAAC,OAAO;yBACV,cAAc,CAAC,QAAQ,CAAC;yBACxB,IAAI,CACH,CAAC,MAAM,EAAE,EAAE,CACT,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC;wBAC9B,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CACrB,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,aAAa,CAC5D,CACJ;wBAEH,SAAS;oBACX,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACtD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACnB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;YACD,IACE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC;gBAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAClB,CAAC,QAAQ,EAAE,EAAE,CACX,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC;oBAC/B,EAAE,CAAC,wBAAwB,CAAC,QAAQ,CAAC;oBACrC,EAAE,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC;oBACxC,QAAQ,CAAC,IAAI,KAAK,SAAS;oBAC3B,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAC9B,EACD,CAAC;gBACD,mEAAmE;gBACnE,mEAAmE;gBACnE,sEAAsE;gBACtE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBACxD,IAAI,UAAU;oBAAE,GAAG,CAAC,UAAU,CAAC,CAAC;YAClC,CAAC;YACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC,CAAC;QACF,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB;gBAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAChF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;sDAEkD;IAClD,mBAAmB,CAAC,IAAa;QAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,EAAE;iBACf,gBAAgB,CAAC,IAAI,CAAC;iBACtB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACvF,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC3B,OAAO,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;QAClF,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,QAAQ,CAAC,IAAa;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1D,uEAAuE;QACvE,wEAAwE;QACxE,IACE,UAAU,CAAC,MAAM,GAAG,CAAC;YACrB,UAAU,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC5B,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAClF;YAED,OAAO,KAAK,CAAC;QACf,IAAI,MAAM,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QACjD,IACE,CAAC,MAAM;YACP,CAAC,IAAI,CAAC,OAAO;iBACV,cAAc,CAAC,MAAM,CAAC;iBACtB,IAAI,CACH,CAAC,WAAW,EAAE,EAAE,CACd,EAAE,CAAC,sBAAsB,CAAC,WAAW,CAAC;gBACtC,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,iBAAiB,CACjD;YAEH,OAAO,KAAK,CAAC;QACf,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC1D,IAAI,2BAA2B,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC;gBAAE,SAAS;YACpE,IAAI,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACtE,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBAChE,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI;oBAClC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,IAAI,CAAC;oBACpD,CAAC,CAAC,SAAS,CAAC;gBACd,IACE,WAAW;oBACX,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC;oBAExF,OAAO,IAAI,CAAC;YAChB,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|
|
@@ -50,21 +50,17 @@ export declare function lowerArrayReduceCall(lowerer: Lowerer, call: ts.CallExpr
|
|
|
50
50
|
* function like the other array HOFs. sort mutates and returns the receiver;
|
|
51
51
|
* toSorted takes its shallow snapshot INSIDE the helper, after the receiver
|
|
52
52
|
* and comparator expressions have both been evaluated, then sorts and
|
|
53
|
-
* returns that copy without touching the receiver. The helper
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* even when every boundary is already ordered. During a merge, an element
|
|
53
|
+
* returns that copy without touching the receiver. The helper merges stable
|
|
54
|
+
* natural runs, reversing only strict descending runs and extending short
|
|
55
|
+
* runs with insertion sort. Ordered boundaries skip merging. During a merge, an element
|
|
57
56
|
* moves right only while cmp(left, right) > 0, so a NaN or 0 result keeps
|
|
58
57
|
* the left element first. Undefined values sink without reaching the user
|
|
59
58
|
* comparator. The callback sequence differs from V8's TimSort, so exact
|
|
60
59
|
* order and count parity are not claimed; results agree for consistent
|
|
61
|
-
* comparators.
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* operators. For numbers that default is the notorious string sort
|
|
66
|
-
* ([10, 9, 1] → [1, 10, 9]), deliberately fenced toward an explicit
|
|
67
|
-
* comparator. */
|
|
60
|
+
* comparators. Without a comparator, string, number and boolean arrays use
|
|
61
|
+
* native stable ordering: their String conversions cannot call user code.
|
|
62
|
+
* Strings compare UTF-16 units; numbers compare their decimal spellings
|
|
63
|
+
* ([10, 9, 1] → [1, 10, 9]). Other element types still need a comparator. */
|
|
68
64
|
export declare function lowerArraySortCall(lowerer: Lowerer, call: ts.CallExpression, access: ts.PropertyAccessExpression, elem: IrType, arrT: IrType & {
|
|
69
65
|
kind: "array";
|
|
70
66
|
}): IrExpr;
|
|
@@ -9,6 +9,7 @@ import { typeKey } from "../../type-mapper.js";
|
|
|
9
9
|
import { lowerArrayCallback, requireProducedArrayElement, callbackArrayElement, } from "./callback-arguments.js";
|
|
10
10
|
import { reverseArrayLoop, arrayLengthDeclaration, arrayCallbackParams, arrayCallbackLocals, callArrayCallback, } from "./array-iteration.js";
|
|
11
11
|
import { dynamicReceiverThrows } from "./dynamic-receivers.js";
|
|
12
|
+
import { defaultAfterUndefined, lowerStaticallyUndefinedArgument } from "../optional-arguments.js";
|
|
12
13
|
/** `a.map(fn)` / `a.filter(fn)` / `a.forEach(fn)` desugar to a direct
|
|
13
14
|
* call of a synthetic module function — one per method + element/result
|
|
14
15
|
* type + callback-arity combination, interned — whose body is a plain
|
|
@@ -1107,46 +1108,70 @@ function reduceHelper(lowerer, method, elem, accT, fnRet, arity, hasInit, loc) {
|
|
|
1107
1108
|
* function like the other array HOFs. sort mutates and returns the receiver;
|
|
1108
1109
|
* toSorted takes its shallow snapshot INSIDE the helper, after the receiver
|
|
1109
1110
|
* and comparator expressions have both been evaluated, then sorts and
|
|
1110
|
-
* returns that copy without touching the receiver. The helper
|
|
1111
|
-
*
|
|
1112
|
-
*
|
|
1113
|
-
* even when every boundary is already ordered. During a merge, an element
|
|
1111
|
+
* returns that copy without touching the receiver. The helper merges stable
|
|
1112
|
+
* natural runs, reversing only strict descending runs and extending short
|
|
1113
|
+
* runs with insertion sort. Ordered boundaries skip merging. During a merge, an element
|
|
1114
1114
|
* moves right only while cmp(left, right) > 0, so a NaN or 0 result keeps
|
|
1115
1115
|
* the left element first. Undefined values sink without reaching the user
|
|
1116
1116
|
* comparator. The callback sequence differs from V8's TimSort, so exact
|
|
1117
1117
|
* order and count parity are not claimed; results agree for consistent
|
|
1118
|
-
* comparators.
|
|
1119
|
-
*
|
|
1120
|
-
*
|
|
1121
|
-
*
|
|
1122
|
-
* operators. For numbers that default is the notorious string sort
|
|
1123
|
-
* ([10, 9, 1] → [1, 10, 9]), deliberately fenced toward an explicit
|
|
1124
|
-
* comparator. */
|
|
1118
|
+
* comparators. Without a comparator, string, number and boolean arrays use
|
|
1119
|
+
* native stable ordering: their String conversions cannot call user code.
|
|
1120
|
+
* Strings compare UTF-16 units; numbers compare their decimal spellings
|
|
1121
|
+
* ([10, 9, 1] → [1, 10, 9]). Other element types still need a comparator. */
|
|
1125
1122
|
export function lowerArraySortCall(lowerer, call, access, elem, arrT) {
|
|
1126
1123
|
const loc = locOf(call);
|
|
1127
1124
|
const method = access.name.text === "toSorted" ? "toSorted" : "sort";
|
|
1128
1125
|
const copyFirst = method === "toSorted";
|
|
1129
|
-
if (call.arguments.length === 0 &&
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
}
|
|
1140
|
-
const fnArg = { kind: "closure", fnName: cmp, captures: [], type: fnT, loc };
|
|
1141
|
-
return { kind: "call", callee: helper, args: [receiver, fnArg], type: arrT, loc };
|
|
1126
|
+
if (call.arguments.length === 0 &&
|
|
1127
|
+
(elem.kind === "string" || elem.kind === "f64" || elem.kind === "bool")) {
|
|
1128
|
+
return {
|
|
1129
|
+
kind: "arrIntrinsic",
|
|
1130
|
+
method: copyFirst ? "toSortedPrimitive" : "sortPrimitive",
|
|
1131
|
+
receiver: lowerer.lowerExpr(access.expression),
|
|
1132
|
+
args: [],
|
|
1133
|
+
type: arrT,
|
|
1134
|
+
loc,
|
|
1135
|
+
};
|
|
1142
1136
|
}
|
|
1143
1137
|
if (call.arguments.length !== 1) {
|
|
1144
|
-
lowerer.noLowering(`.${method} with ${call.arguments.length} arguments`, call, "
|
|
1145
|
-
`${method}((a, b) => a - b) for numbers`);
|
|
1138
|
+
lowerer.noLowering(`.${method} with ${call.arguments.length} arguments`, call, "default ordering supports string[], number[] and boolean[]; other element types need a comparator");
|
|
1146
1139
|
}
|
|
1147
1140
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
1148
1141
|
const argNode = call.arguments[0];
|
|
1149
|
-
|
|
1142
|
+
const undefinedArg = lowerStaticallyUndefinedArgument(lowerer, argNode);
|
|
1143
|
+
let unwrappedArg = argNode;
|
|
1144
|
+
while (ts.isParenthesizedExpression(unwrappedArg) ||
|
|
1145
|
+
ts.isAsExpression(unwrappedArg) ||
|
|
1146
|
+
ts.isTypeAssertion(unwrappedArg) ||
|
|
1147
|
+
ts.isSatisfiesExpression(unwrappedArg))
|
|
1148
|
+
unwrappedArg = unwrappedArg.expression;
|
|
1149
|
+
if (undefinedArg?.type.kind === "void" && !ts.isVoidExpression(unwrappedArg)) {
|
|
1150
|
+
lowerer.noLowering(`.${method} with an erased comparator result`, argNode, "pass the comparator directly, or use void expression to explicitly select default ordering");
|
|
1151
|
+
}
|
|
1152
|
+
if (undefinedArg !== null &&
|
|
1153
|
+
(undefinedArg.type.kind === "undefinedT" || ts.isVoidExpression(unwrappedArg)) &&
|
|
1154
|
+
(elem.kind === "string" || elem.kind === "f64" || elem.kind === "bool")) {
|
|
1155
|
+
// A type assertion alone cannot turn a function value into undefined.
|
|
1156
|
+
// The explicit undefined expression can mutate or replace the receiver.
|
|
1157
|
+
// Keep its original value alive and run the argument before sorting.
|
|
1158
|
+
const saved = lowerer.declareHiddenLocal("%sortReceiver", arrT);
|
|
1159
|
+
return {
|
|
1160
|
+
kind: "seqExpr",
|
|
1161
|
+
stmts: [{ kind: "varDecl", localId: saved.id, init: receiver, loc }],
|
|
1162
|
+
result: defaultAfterUndefined(undefinedArg, {
|
|
1163
|
+
kind: "arrIntrinsic",
|
|
1164
|
+
method: copyFirst ? "toSortedPrimitive" : "sortPrimitive",
|
|
1165
|
+
receiver: varRef(saved.id, arrT, loc),
|
|
1166
|
+
args: [],
|
|
1167
|
+
type: arrT,
|
|
1168
|
+
loc,
|
|
1169
|
+
}),
|
|
1170
|
+
type: arrT,
|
|
1171
|
+
loc,
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
let fnArg = undefinedArg ?? lowerer.lowerExpr(argNode);
|
|
1150
1175
|
// Reusable JS comparators often accept checked values. Adapt the array's
|
|
1151
1176
|
// element ABI just as other array callbacks do before sorting.
|
|
1152
1177
|
if (fnArg.type.kind === "func" &&
|
|
@@ -1181,66 +1206,6 @@ export function lowerArraySortCall(lowerer, call, access, elem, arrT) {
|
|
|
1181
1206
|
}
|
|
1182
1207
|
return { kind: "call", callee: helper, args: [receiver, fnArg], type: arrT, loc };
|
|
1183
1208
|
}
|
|
1184
|
-
/** JS's default sort comparator for STRING elements, interned once:
|
|
1185
|
-
*
|
|
1186
|
-
* (a, b) => a < b ? -1 : a > b ? 1 : 0
|
|
1187
|
-
*
|
|
1188
|
-
* The dedicated UTF-16 comparison flag keeps this exact across
|
|
1189
|
-
* supplementary-plane code points and U+E000..U+FFFF, where the runtime's
|
|
1190
|
-
* ordinary code-point relational order deliberately differs. */
|
|
1191
|
-
function defaultStringCmpHelper(lowerer, loc) {
|
|
1192
|
-
const key = "sortCmpStr";
|
|
1193
|
-
const existing = lowerer.arrHofHelpers.get(key);
|
|
1194
|
-
if (existing)
|
|
1195
|
-
return existing;
|
|
1196
|
-
const name = `%arr.sortCmpStr`;
|
|
1197
|
-
lowerer.arrHofHelpers.set(key, name);
|
|
1198
|
-
const cmp = (op) => ({
|
|
1199
|
-
kind: "strCmp",
|
|
1200
|
-
op,
|
|
1201
|
-
left: varRef("a.0", STRING, loc),
|
|
1202
|
-
right: varRef("b.0", STRING, loc),
|
|
1203
|
-
utf16: true,
|
|
1204
|
-
type: BOOL,
|
|
1205
|
-
loc,
|
|
1206
|
-
});
|
|
1207
|
-
const body = [
|
|
1208
|
-
{
|
|
1209
|
-
kind: "return",
|
|
1210
|
-
value: {
|
|
1211
|
-
kind: "ternary",
|
|
1212
|
-
cond: cmp("<"),
|
|
1213
|
-
then: numLit(-1, loc),
|
|
1214
|
-
else_: {
|
|
1215
|
-
kind: "ternary",
|
|
1216
|
-
cond: cmp(">"),
|
|
1217
|
-
then: numLit(1, loc),
|
|
1218
|
-
else_: numLit(0, loc),
|
|
1219
|
-
type: F64,
|
|
1220
|
-
loc,
|
|
1221
|
-
},
|
|
1222
|
-
type: F64,
|
|
1223
|
-
loc,
|
|
1224
|
-
},
|
|
1225
|
-
loc,
|
|
1226
|
-
},
|
|
1227
|
-
];
|
|
1228
|
-
lowerer.liftedFns.push({
|
|
1229
|
-
name,
|
|
1230
|
-
params: [
|
|
1231
|
-
{ localId: "a.0", name: "a", type: STRING },
|
|
1232
|
-
{ localId: "b.0", name: "b", type: STRING },
|
|
1233
|
-
],
|
|
1234
|
-
returnType: F64,
|
|
1235
|
-
locals: [
|
|
1236
|
-
{ id: "a.0", name: "a", type: STRING, mutable: true },
|
|
1237
|
-
{ id: "b.0", name: "b", type: STRING, mutable: true },
|
|
1238
|
-
],
|
|
1239
|
-
body,
|
|
1240
|
-
loc,
|
|
1241
|
-
});
|
|
1242
|
-
return name;
|
|
1243
|
-
}
|
|
1244
1209
|
/** `d.filter(pred)` on a dyn receiver: the receiver must BE a dyn array
|
|
1245
1210
|
* (else the Node-shaped TypeError above); the predicate runs per element
|
|
1246
1211
|
* over the dyn value, and each SURVIVOR is validated-extracted into the
|