@scriptc/compiler 0.4.2 → 0.4.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.
- package/ambient/scriptc-node-fallback.d.ts +470 -66
- package/dist/backend/cycle-analysis.d.ts +4 -1
- package/dist/backend/cycle-analysis.js +6 -4
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +55 -0
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.d.ts +7 -0
- package/dist/backend/cycle-mutability.js +19 -1
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +2 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.d.ts +6 -3
- package/dist/backend/immutability.js +33 -29
- package/dist/backend/immutability.js.map +1 -1
- package/dist/backend/library-pack.js +1 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +16 -1
- package/dist/backend/llvm/alloc.js +54 -4
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.d.ts +2 -1
- package/dist/backend/llvm/appended-array-literals.js +44 -36
- package/dist/backend/llvm/appended-array-literals.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +4 -3
- package/dist/backend/llvm/appended-array-literals.test.js.map +1 -1
- package/dist/backend/llvm/array-search.d.ts +4 -3
- package/dist/backend/llvm/array-search.js +21 -9
- package/dist/backend/llvm/array-search.js.map +1 -1
- package/dist/backend/llvm/blocks.d.ts +1 -1
- package/dist/backend/llvm/blocks.js +2 -2
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/byte-windows.js +2 -0
- package/dist/backend/llvm/byte-windows.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +6 -1
- package/dist/backend/llvm/bytes-alias.js +8 -2
- package/dist/backend/llvm/bytes-alias.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.d.ts +47 -5
- package/dist/backend/llvm/bytes-loop-versions.js +479 -32
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.test.js +263 -2
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +2 -0
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +7 -5
- package/dist/backend/llvm/classes.js +44 -20
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +167 -7
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +9 -3
- package/dist/backend/llvm/common.js +9 -3
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +2 -1
- package/dist/backend/llvm/constant-callbacks.js +83 -52
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +7 -0
- package/dist/backend/llvm/counted-loops.js +18 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/debug-info.js +2 -5
- package/dist/backend/llvm/debug-info.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +39 -8
- package/dist/backend/llvm/dense-array-access.js +222 -52
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +36 -0
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +17 -1
- package/dist/backend/llvm/dense-array-loops.js +194 -5
- package/dist/backend/llvm/dense-array-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.test.js +90 -1
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -1
- package/dist/backend/llvm/dyn-handle-tags.test.js +6 -1
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +30 -0
- package/dist/backend/llvm/dyn.js +373 -70
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +13 -28
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-journal.d.ts +93 -0
- package/dist/backend/llvm/emit-journal.js +170 -0
- package/dist/backend/llvm/emit-journal.js.map +1 -0
- package/dist/backend/llvm/emit-module.js +211 -33
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emit-statements.d.ts +0 -4
- package/dist/backend/llvm/emit-statements.js +268 -84
- package/dist/backend/llvm/emit-statements.js.map +1 -1
- package/dist/backend/llvm/emitter-state.d.ts +7 -0
- package/dist/backend/llvm/emitter-state.js +14 -0
- package/dist/backend/llvm/emitter-state.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +186 -37
- package/dist/backend/llvm/emitter.js +733 -90
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +65 -7
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +11 -13
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +48 -20
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.js +47 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +28 -14
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +14 -2
- package/dist/backend/llvm/expr-containers.js +143 -37
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +14 -0
- package/dist/backend/llvm/expr-dynamic.js +18 -11
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +119 -38
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +11 -6
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +12 -0
- package/dist/backend/llvm/expr-records.js +106 -0
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +2 -2
- package/dist/backend/llvm/expr-stream-bridges.js +210 -69
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +74 -20
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-kind-loops.d.ts +39 -0
- package/dist/backend/llvm/int32-kind-loops.js +106 -0
- package/dist/backend/llvm/int32-kind-loops.js.map +1 -0
- package/dist/backend/llvm/integer-or-nan-indexes.test.d.ts +1 -0
- package/dist/backend/llvm/integer-or-nan-indexes.test.js +118 -0
- package/dist/backend/llvm/integer-or-nan-indexes.test.js.map +1 -0
- package/dist/backend/llvm/integer-values.d.ts +25 -1
- package/dist/backend/llvm/integer-values.js +95 -0
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/js-ic.d.ts +1 -1
- package/dist/backend/llvm/js-ic.js +1 -1
- package/dist/backend/llvm/js-ic.js.map +1 -1
- package/dist/backend/llvm/key-orders.d.ts +7 -0
- package/dist/backend/llvm/key-orders.js +33 -0
- package/dist/backend/llvm/key-orders.js.map +1 -0
- package/dist/backend/llvm/lib-connect.js +4 -0
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +11 -0
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +213 -5
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +4 -4
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +4 -0
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +16 -6
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +37 -1
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +94 -2
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +35 -5
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +115 -19
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +14 -0
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/loop-state.d.ts +33 -0
- package/dist/backend/llvm/loop-state.js +42 -0
- package/dist/backend/llvm/loop-state.js.map +1 -0
- package/dist/backend/llvm/map-number-lookup.d.ts +26 -8
- package/dist/backend/llvm/map-number-lookup.js +91 -31
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +55 -0
- package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.js +4 -2
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.d.ts +2 -1
- package/dist/backend/llvm/nullable-unions.js +15 -3
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/publish.d.ts +10 -0
- package/dist/backend/llvm/publish.js +15 -3
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/receivers.js +6 -1
- package/dist/backend/llvm/receivers.js.map +1 -1
- package/dist/backend/llvm/record-results.d.ts +1 -9
- package/dist/backend/llvm/record-results.js +2 -11
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +3 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +7 -2
- package/dist/backend/llvm/reference-writes.js +89 -72
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/running-extrema.d.ts +11 -0
- package/dist/backend/llvm/running-extrema.js +115 -0
- package/dist/backend/llvm/running-extrema.js.map +1 -0
- package/dist/backend/llvm/running-extrema.test.d.ts +1 -0
- package/dist/backend/llvm/running-extrema.test.js +89 -0
- package/dist/backend/llvm/running-extrema.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +71 -15
- package/dist/backend/llvm/shapes.js +224 -40
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +53 -7
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +6 -0
- package/dist/backend/llvm/speculative-integers.js +2 -2
- package/dist/backend/llvm/speculative-integers.js.map +1 -1
- package/dist/backend/llvm/stack-captures.js +1 -5
- package/dist/backend/llvm/stack-captures.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +3 -2
- package/dist/backend/llvm/stack-objects.js +5 -2
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +12 -0
- package/dist/backend/llvm/string-reads.js +44 -0
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/union-repr.d.ts +4 -3
- package/dist/backend/llvm/union-repr.js +6 -5
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/walk-borrows.d.ts +3 -0
- package/dist/backend/llvm/walk-borrows.js +46 -41
- package/dist/backend/llvm/walk-borrows.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +3 -0
- package/dist/backend/llvm/walkers.js +101 -65
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wrapping-sums.d.ts +16 -1
- package/dist/backend/llvm/wrapping-sums.js +126 -0
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/may-throw.d.ts +8 -10
- package/dist/backend/may-throw.js +14 -10
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +5 -0
- package/dist/backend/native/executable.js +7 -0
- 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 +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +5 -3
- package/dist/backend/native-codegen-core.js +13 -6
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.test.js +6 -4
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +4 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.d.ts +12 -1
- package/dist/backend/publication.js +37 -14
- package/dist/backend/publication.js.map +1 -1
- package/dist/backend/publication.test.js +30 -0
- package/dist/backend/publication.test.js.map +1 -1
- package/dist/backend/result-slots.d.ts +16 -0
- package/dist/backend/result-slots.js +23 -0
- package/dist/backend/result-slots.js.map +1 -0
- 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 +1 -0
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +2 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +2 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +2 -1
- package/dist/backend/stack-observations.js +67 -42
- package/dist/backend/stack-observations.js.map +1 -1
- package/dist/backend/target-cpu.d.ts +26 -0
- package/dist/backend/target-cpu.js +98 -0
- package/dist/backend/target-cpu.js.map +1 -0
- package/dist/backend/target-cpu.test.d.ts +1 -0
- package/dist/backend/target-cpu.test.js +38 -0
- package/dist/backend/target-cpu.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +5 -3
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/warm-cache.js +1 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/cli/command.js +20 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +4 -1
- package/dist/cli/usage.js +10 -3
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +1 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +7 -0
- package/dist/contracts/check.js +4 -3
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.js +10 -2
- package/dist/contracts/int32-elements.js.map +1 -1
- package/dist/coverage/report.js +12 -3
- package/dist/coverage/report.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +4 -0
- package/dist/diagnostics/diagnostic.js +1 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +3 -0
- package/dist/diagnostics/envelope.js +1 -0
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +5 -0
- package/dist/executable/executable-cache.js +5 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +3 -0
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/decl-projection.d.ts +41 -0
- package/dist/frontend/decl-projection.js +949 -0
- package/dist/frontend/decl-projection.js.map +1 -0
- package/dist/frontend/decl-projection.test.d.ts +1 -0
- package/dist/frontend/decl-projection.test.js +30 -0
- package/dist/frontend/decl-projection.test.js.map +1 -0
- package/dist/frontend/dts-paths.d.ts +15 -0
- package/dist/frontend/dts-paths.js +25 -0
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +6 -0
- package/dist/frontend/input-tracker.js +51 -28
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +19 -0
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lowering/array-values.js +100 -2
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.d.ts +8 -2
- package/dist/frontend/lowering/builtins/async-context.js +62 -3
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.js +46 -15
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.js +13 -2
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.js +87 -10
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.js +4 -1
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +3 -3
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +6 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-paths.d.ts +43 -5
- package/dist/frontend/lowering/builtins/fs-paths.js +245 -93
- package/dist/frontend/lowering/builtins/fs-paths.js.map +1 -1
- package/dist/frontend/lowering/builtins/global-namespace-keys.d.ts +3 -0
- package/dist/frontend/lowering/builtins/global-namespace-keys.js +122 -0
- package/dist/frontend/lowering/builtins/global-namespace-keys.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-calls.js +6 -3
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/numbers.js +9 -1
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +7 -1
- package/dist/frontend/lowering/builtins/promises.js +236 -139
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +5 -1
- package/dist/frontend/lowering/builtins/readline.js +35 -3
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.js +24 -1
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/webassembly.js +6 -3
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.js +0 -1
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
- package/dist/frontend/lowering/cjs-inline-require.d.ts +32 -0
- package/dist/frontend/lowering/cjs-inline-require.js +307 -4
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +5 -2
- package/dist/frontend/lowering/class-callbacks.js +82 -12
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +4 -1
- package/dist/frontend/lowering/class-construction.js +17 -3
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +49 -2
- package/dist/frontend/lowering/class-dynamic-dispatch.js +880 -108
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +47 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +2 -1
- package/dist/frontend/lowering/class-iterables.js +9 -1
- package/dist/frontend/lowering/class-iterables.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +83 -24
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +25 -0
- package/dist/frontend/lowering/class-protocols.js +183 -1
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.js +31 -2
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +9 -3
- package/dist/frontend/lowering/class-runtime-statics.js +29 -4
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +48 -1
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +91 -1
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/completion-callbacks.d.ts +4 -0
- package/dist/frontend/lowering/completion-callbacks.js +146 -0
- package/dist/frontend/lowering/completion-callbacks.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +2 -2
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +5 -4
- package/dist/frontend/lowering/containers/array-callbacks.js +345 -24
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +10 -0
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +5 -0
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +26 -3
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +19 -8
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +25 -17
- package/dist/frontend/lowering/containers/bytes.js +455 -46
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +3 -0
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +7 -2
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/filter-predicates.d.ts +6 -0
- package/dist/frontend/lowering/containers/filter-predicates.js +205 -0
- package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -0
- package/dist/frontend/lowering/containers/indexed-objects.d.ts +0 -12
- package/dist/frontend/lowering/containers/indexed-objects.js +46 -7
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +55 -9
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +43 -19
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/date-values.d.ts +11 -0
- package/dist/frontend/lowering/date-values.js +207 -0
- package/dist/frontend/lowering/date-values.js.map +1 -0
- package/dist/frontend/lowering/dispatch-sites.js +15 -1
- package/dist/frontend/lowering/dispatch-sites.js.map +1 -1
- package/dist/frontend/lowering/divergences.js +9 -1
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/error-methods.js +47 -2
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/expressions/array-literals.js +53 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +100 -28
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +169 -13
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +64 -5
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/narrowing.js +95 -1
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +3 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +138 -51
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +12 -0
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.js +168 -10
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/relational.js +212 -33
- package/dist/frontend/lowering/expressions/relational.js.map +1 -1
- package/dist/frontend/lowering/expressions/typeof.js +6 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js +4 -0
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +39 -3
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/frozen-records.d.ts +28 -0
- package/dist/frontend/lowering/frozen-records.js +322 -0
- package/dist/frontend/lowering/frozen-records.js.map +1 -0
- package/dist/frontend/lowering/function-returns.js +64 -0
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.js +7 -2
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/indexed-unions.d.ts +54 -0
- package/dist/frontend/lowering/indexed-unions.js +401 -0
- package/dist/frontend/lowering/indexed-unions.js.map +1 -0
- package/dist/frontend/lowering/iterable-values.d.ts +49 -0
- package/dist/frontend/lowering/iterable-values.js +297 -0
- package/dist/frontend/lowering/iterable-values.js.map +1 -0
- package/dist/frontend/lowering/iterator-adapters.js +186 -1
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +8 -0
- package/dist/frontend/lowering/js-class-fields.js +45 -10
- package/dist/frontend/lowering/js-class-fields.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.d.ts +18 -3
- package/dist/frontend/lowering/key-order-witness.js +974 -48
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.test.js +530 -10
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +15 -3
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js +4 -1
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +7 -0
- package/dist/frontend/lowering/lower-calls.js +462 -44
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +11 -2
- package/dist/frontend/lowering/lower-classes.js +324 -69
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +3 -1
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +215 -3
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.d.ts +11 -0
- package/dist/frontend/lowering/lower-functions.js +83 -0
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +42 -32
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +6 -3
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
- package/dist/frontend/lowering/lower-inspect.js +53 -17
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +53 -5
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +5 -1
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +2 -2
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +5 -0
- package/dist/frontend/lowering/lower-stdlib.js +30 -0
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +23 -0
- package/dist/frontend/lowering/lower-stmts.js +553 -81
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +20 -2
- package/dist/frontend/lowering/lower-stream.js +1483 -156
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +107 -8
- package/dist/frontend/lowering/lowerer.js +381 -36
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.d.ts +11 -1
- package/dist/frontend/lowering/module-namespace-elements.js +82 -5
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/new-target.d.ts +12 -0
- package/dist/frontend/lowering/new-target.js +280 -0
- package/dist/frontend/lowering/new-target.js.map +1 -0
- package/dist/frontend/lowering/object-factory-new.d.ts +5 -0
- package/dist/frontend/lowering/object-factory-new.js +20 -6
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/overload-choice.d.ts +33 -0
- package/dist/frontend/lowering/overload-choice.js +190 -0
- package/dist/frontend/lowering/overload-choice.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +3 -0
- package/dist/frontend/lowering/surfaces.js +73 -8
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/undefined-index.d.ts +27 -0
- package/dist/frontend/lowering/undefined-index.js +82 -0
- package/dist/frontend/lowering/undefined-index.js.map +1 -0
- package/dist/frontend/lowering/var-hoisting.js +29 -13
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +18 -0
- package/dist/frontend/npm-static-bundled-chunks.js +9 -11
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.test.js +6 -5
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.js +9 -1
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static.js +4 -20
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/package-shims.d.ts +3 -0
- package/dist/frontend/package-shims.js +71 -8
- package/dist/frontend/package-shims.js.map +1 -1
- package/dist/frontend/pipeline.js +19 -11
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/process-fork.d.ts +25 -0
- package/dist/frontend/process-fork.js +2 -0
- package/dist/frontend/process-fork.js.map +1 -0
- package/dist/frontend/program-analysis.d.ts +5 -1
- package/dist/frontend/program-analysis.js +5 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +21 -6
- package/dist/frontend/program.js +681 -83
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +43 -3
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/token-equivalence.d.ts +3 -0
- package/dist/frontend/token-equivalence.js +409 -0
- package/dist/frontend/token-equivalence.js.map +1 -0
- package/dist/frontend/token-equivalence.test.d.ts +1 -0
- package/dist/frontend/token-equivalence.test.js +67 -0
- package/dist/frontend/token-equivalence.test.js.map +1 -0
- package/dist/frontend/ts7/ast-node.d.ts +22 -0
- package/dist/frontend/ts7/ast-node.js +1048 -103
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +24 -0
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.d.ts +4 -3
- package/dist/frontend/ts7/ast-wire.js +34 -24
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.test.js +23 -0
- package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +3 -4
- package/dist/frontend/ts7/checker-backend.js +2 -2
- package/dist/frontend/ts7/checker-backend.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.test.js +5 -9
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +4 -0
- package/dist/frontend/ts7/checker.js +7 -0
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/lib-diagnostics.d.ts +24 -0
- package/dist/frontend/ts7/lib-diagnostics.js +307 -0
- package/dist/frontend/ts7/lib-diagnostics.js.map +1 -0
- package/dist/frontend/ts7/lib-diagnostics.test.d.ts +1 -0
- package/dist/frontend/ts7/lib-diagnostics.test.js +199 -0
- package/dist/frontend/ts7/lib-diagnostics.test.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +7 -0
- package/dist/frontend/ts7/program-host.js +25 -2
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +3 -0
- package/dist/frontend/ts7/semantic-model.js +5 -0
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +6 -1
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +1 -1
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +14 -1
- package/dist/frontend/ts7/session.js +22 -0
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +13 -1
- package/dist/frontend/type-mapper.js +229 -20
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.js +46 -4
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +5 -3
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +4 -0
- package/dist/ir/array-length-stability.js +19 -6
- package/dist/ir/array-length-stability.js.map +1 -1
- package/dist/ir/array-length-stability.test.js +24 -0
- package/dist/ir/array-length-stability.test.js.map +1 -1
- package/dist/ir/builtin-effects.d.ts +7 -0
- package/dist/ir/builtin-effects.js +60 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +6 -4
- package/dist/ir/builtin-signatures.js +222 -13
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +2 -1
- package/dist/ir/callback-specialization.js +23 -18
- package/dist/ir/callback-specialization.js.map +1 -1
- package/dist/ir/char-unit-locals.d.ts +19 -0
- package/dist/ir/char-unit-locals.js +185 -0
- package/dist/ir/char-unit-locals.js.map +1 -0
- package/dist/ir/char-unit-locals.test.d.ts +1 -0
- package/dist/ir/char-unit-locals.test.js +94 -0
- package/dist/ir/char-unit-locals.test.js.map +1 -0
- package/dist/ir/final-fields.d.ts +2 -1
- package/dist/ir/final-fields.js +14 -16
- package/dist/ir/final-fields.js.map +1 -1
- package/dist/ir/function-references.d.ts +2 -0
- package/dist/ir/function-references.js +2 -0
- package/dist/ir/function-references.js.map +1 -1
- package/dist/ir/function-references.test.js +3 -0
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/initializer-bindings.d.ts +2 -1
- package/dist/ir/initializer-bindings.js +27 -20
- package/dist/ir/initializer-bindings.js.map +1 -1
- package/dist/ir/int32-arrays.d.ts +108 -0
- package/dist/ir/int32-arrays.js +831 -0
- package/dist/ir/int32-arrays.js.map +1 -0
- package/dist/ir/int32-slots.d.ts +24 -2
- package/dist/ir/int32-slots.js +266 -57
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +33 -0
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +3 -3
- package/dist/ir/integer-loops.js +28 -10
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +10 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +5 -0
- package/dist/ir/integer-ranges.js +125 -12
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +30 -0
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/ir.d.ts +83 -10
- package/dist/ir/ir.js +77 -6
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +23 -2
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/js-ic.d.ts +4 -0
- package/dist/ir/js-ic.js +17 -1
- package/dist/ir/js-ic.js.map +1 -1
- package/dist/ir/js-ic.test.js +46 -0
- package/dist/ir/js-ic.test.js.map +1 -1
- package/dist/ir/node-index.d.ts +57 -0
- package/dist/ir/node-index.js +215 -0
- package/dist/ir/node-index.js.map +1 -0
- package/dist/ir/paired-while-loops.d.ts +25 -0
- package/dist/ir/paired-while-loops.js +335 -0
- package/dist/ir/paired-while-loops.js.map +1 -0
- package/dist/ir/paired-while-loops.test.d.ts +1 -0
- package/dist/ir/paired-while-loops.test.js +163 -0
- package/dist/ir/paired-while-loops.test.js.map +1 -0
- package/dist/ir/parameter-versions.d.ts +25 -0
- package/dist/ir/parameter-versions.js +300 -0
- package/dist/ir/parameter-versions.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +34 -13
- package/dist/ir/runtime-features.js +177 -39
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/serialize.d.ts +12 -2
- package/dist/ir/serialize.js +16 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +17 -0
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/traverse.js +18 -6
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +167 -40
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/ir-policy.js +3 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/native/cache.d.ts +6 -1
- package/dist/native/cache.js +28 -5
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cache.test.js +16 -2
- package/dist/native/cache.test.js.map +1 -1
- package/dist/native/cli.js +21 -1
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +8 -6
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/executable-cache.d.ts +1 -1
- package/dist/native/executable-cache.js +2 -2
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/prepare.d.ts +4 -2
- package/dist/native/prepare.js +130 -32
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +96 -20
- package/dist/native/prepare.test.js.map +1 -1
- package/dist/native/sanitizer.test.js +2 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/text-file.d.ts +13 -3
- package/dist/native/text-file.js +63 -9
- package/dist/native/text-file.js.map +1 -1
- package/dist/native/text-file.test.d.ts +1 -0
- package/dist/native/text-file.test.js +49 -0
- package/dist/native/text-file.test.js.map +1 -0
- package/dist/native/toolchain.js +4 -4
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +3 -3
- package/dist/native/toolchain.test.js.map +1 -1
- package/package.json +21 -21
- package/shims/chalk/v5.ts +688 -0
- package/shims/hono-node-server/v2.ts +645 -0
- package/shims/hot-shots/client.ts +1126 -0
- package/shims/hot-shots/v8-unix-dgram.ts +8 -0
- package/shims/hot-shots/v8.ts +8 -0
- package/surface-manifest.json +27 -7
|
@@ -0,0 +1,831 @@
|
|
|
1
|
+
import { exprFunctionReference, moduleFunctionReferences } from "./function-references.js";
|
|
2
|
+
import { F64 } from "./ir.js";
|
|
3
|
+
import { reparseExpr } from "./serialize.js";
|
|
4
|
+
import { everyExprChild, everyStmtChild, everyStmtList, mapExprChildren, mapStmtChildren, transformExpr, transformStmt, transformStmtList, } from "./traverse.js";
|
|
5
|
+
/** Number arrays the backend may store as int32 slots.
|
|
6
|
+
*
|
|
7
|
+
* A candidate is a `number[]` binding that only compiled element
|
|
8
|
+
* operations reach: a local of a synchronous function, a module global, or
|
|
9
|
+
* a parameter. Every write of a local or a global stores a fresh array (an
|
|
10
|
+
* array literal, or `new Array(n).fill(v)`); a parameter is never written.
|
|
11
|
+
* Every read of a candidate is the receiver of an element read, write,
|
|
12
|
+
* state test, `length`, `push` or `pop` (a discarded `pop` included), the
|
|
13
|
+
* array of an element-reader helper call, or the argument of a direct call
|
|
14
|
+
* whose parameter at that position is a candidate itself. A parameter is a
|
|
15
|
+
* candidate only when its function is reached by direct calls alone and
|
|
16
|
+
* every call passes a candidate there, so every binding that can hold one
|
|
17
|
+
* of these arrays is a candidate: the array never reaches a runtime
|
|
18
|
+
* function that reads its slots, a library call, a closure, a return or
|
|
19
|
+
* untyped code.
|
|
20
|
+
*
|
|
21
|
+
* Candidates are only proposed here. The int32 slot analysis
|
|
22
|
+
* (int32-slots.ts) keeps the ones whose every stored element is a proven
|
|
23
|
+
* int32 (never -0), assuming the candidates' own elements are int32s, at
|
|
24
|
+
* a fixpoint, and the LLVM backend stores those as SCR_ELEM_I32. It keeps
|
|
25
|
+
* the ones whose stores are exact integers but not all proven int32s as
|
|
26
|
+
* int32 arrays with checked stores: SCR_ELEM_I32 until a store that is not
|
|
27
|
+
* an int32 widens them to doubles in place. Their element-reader helper
|
|
28
|
+
* calls are inlined first (rewriteCandidates), so no shared helper ever
|
|
29
|
+
* receives an int32 array. */
|
|
30
|
+
/** The candidate key of the binding `localId` as `fnName` reads it:
|
|
31
|
+
* `function\0local` for a local or parameter, `\0global` for a module
|
|
32
|
+
* global (`%g.` ids), which every function reads alike. */
|
|
33
|
+
export function int32ArrayKey(fnName, localId) {
|
|
34
|
+
return localId.startsWith("%g.") ? `\0${localId}` : `${fnName}\0${localId}`;
|
|
35
|
+
}
|
|
36
|
+
/** The int32 element slot (int32-slots.ts) of a candidate key. */
|
|
37
|
+
export function int32ArraySlot(key) {
|
|
38
|
+
return key.startsWith("\0") ? `g:${key.slice(1)}` : `l:${key}`;
|
|
39
|
+
}
|
|
40
|
+
/** Array methods a candidate may be the receiver of: the runtime paths
|
|
41
|
+
* behind them read and write int32 slots through the double-valued slot
|
|
42
|
+
* accessors. */
|
|
43
|
+
export const INT32_ARRAY_METHODS = new Set([
|
|
44
|
+
"length",
|
|
45
|
+
"push",
|
|
46
|
+
"pop",
|
|
47
|
+
"getNumber",
|
|
48
|
+
]);
|
|
49
|
+
/** An element-reader helper (`%arr.idxOr.*`): `(a, i) => a's state at i is
|
|
50
|
+
* a value ? the element : undefined`, as one returned ternary. */
|
|
51
|
+
export function isElementReader(fn) {
|
|
52
|
+
if (fn.params.length !== 2 || fn.body.length !== 1)
|
|
53
|
+
return false;
|
|
54
|
+
const [array, index] = fn.params;
|
|
55
|
+
const ret = fn.body[0];
|
|
56
|
+
if (array.type.kind !== "array" || array.type.elem.kind !== "f64")
|
|
57
|
+
return false;
|
|
58
|
+
if (index.type.kind !== "f64" || ret.kind !== "return" || ret.value?.kind !== "ternary")
|
|
59
|
+
return false;
|
|
60
|
+
const isParam = (e, id) => e.kind === "varRef" && e.localId === id;
|
|
61
|
+
const { cond, then, else_ } = ret.value;
|
|
62
|
+
return (cond.kind === "bin" &&
|
|
63
|
+
cond.op === "===" &&
|
|
64
|
+
cond.left.kind === "arrayState" &&
|
|
65
|
+
isParam(cond.left.arr, array.localId) &&
|
|
66
|
+
isParam(cond.left.index, index.localId) &&
|
|
67
|
+
cond.right.kind === "numLit" &&
|
|
68
|
+
cond.right.value === 1 &&
|
|
69
|
+
then.kind === "unionWrap" &&
|
|
70
|
+
then.value.kind === "arrayGet" &&
|
|
71
|
+
isParam(then.value.arr, array.localId) &&
|
|
72
|
+
isParam(then.value.index, index.localId) &&
|
|
73
|
+
else_.kind === "unionWrap" &&
|
|
74
|
+
else_.value.kind === "unitLit");
|
|
75
|
+
}
|
|
76
|
+
/** `new Array(n).fill(v)` as lowering spells it: `fill` over a sequence
|
|
77
|
+
* that declares a temporary empty array, sets its length and yields it. */
|
|
78
|
+
function fillAllocation(e) {
|
|
79
|
+
if (e.kind !== "arrIntrinsic" || e.method !== "fill" || e.receiver.kind !== "seqExpr")
|
|
80
|
+
return null;
|
|
81
|
+
const seq = e.receiver;
|
|
82
|
+
const [decl, length] = seq.stmts;
|
|
83
|
+
if (seq.stmts.length !== 2 ||
|
|
84
|
+
decl?.kind !== "varDecl" ||
|
|
85
|
+
decl.init?.kind !== "arrayLit" ||
|
|
86
|
+
decl.init.elems.length !== 0 ||
|
|
87
|
+
length?.kind !== "arraySetLength" ||
|
|
88
|
+
length.arr.kind !== "varRef" ||
|
|
89
|
+
length.arr.localId !== decl.localId ||
|
|
90
|
+
seq.result.kind !== "varRef" ||
|
|
91
|
+
seq.result.localId !== decl.localId)
|
|
92
|
+
return null;
|
|
93
|
+
return e;
|
|
94
|
+
}
|
|
95
|
+
/** Fill-form arrays shorter than this hold doubles even when they are int32
|
|
96
|
+
* arrays with checked stores: their doubles fit a typical 32 KiB L1 data
|
|
97
|
+
* cache, so 4-byte slots save no memory traffic. */
|
|
98
|
+
export const CHECKED_INT32_MIN_LENGTH = 4096;
|
|
99
|
+
/** The length `n` of `new Array(n).fill(v)`, or null for any other
|
|
100
|
+
* allocation. */
|
|
101
|
+
export function fillAllocationLength(e) {
|
|
102
|
+
const fill = fillAllocation(e);
|
|
103
|
+
if (!fill || fill.receiver.kind !== "seqExpr")
|
|
104
|
+
return null;
|
|
105
|
+
const set = fill.receiver.stmts[1];
|
|
106
|
+
return set.kind === "arraySetLength" ? set.length : null;
|
|
107
|
+
}
|
|
108
|
+
/** A number expression whose evaluation has no effect: locals, literals and
|
|
109
|
+
* arithmetic. */
|
|
110
|
+
function isPureLength(e) {
|
|
111
|
+
if (e.type.kind !== "f64")
|
|
112
|
+
return false;
|
|
113
|
+
switch (e.kind) {
|
|
114
|
+
case "numLit":
|
|
115
|
+
case "varRef":
|
|
116
|
+
return true;
|
|
117
|
+
case "bin":
|
|
118
|
+
return e.left.type.kind === "f64" && isPureLength(e.left) && isPureLength(e.right);
|
|
119
|
+
case "unary":
|
|
120
|
+
return isPureLength(e.operand);
|
|
121
|
+
default:
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** Whether the candidate `id` of `fn` may hold int32 slots with checked
|
|
126
|
+
* stores: every array it is assigned is the fill form, with a length that
|
|
127
|
+
* may reach CHECKED_INT32_MIN_LENGTH and evaluates without effects (the
|
|
128
|
+
* backend evaluates it once more to pick the new array's kind). */
|
|
129
|
+
export function checkableInt32Allocations(fn, id) {
|
|
130
|
+
let ok = true;
|
|
131
|
+
everyStmtList(fn.body, {
|
|
132
|
+
stmt: (s) => {
|
|
133
|
+
if ((s.kind === "varDecl" || s.kind === "assign") && s.localId === id) {
|
|
134
|
+
const value = s.kind === "varDecl" ? s.init : s.value;
|
|
135
|
+
const length = value ? fillAllocationLength(value) : null;
|
|
136
|
+
if (length === null ||
|
|
137
|
+
!isPureLength(length) ||
|
|
138
|
+
(length.kind === "numLit" && length.value < CHECKED_INT32_MIN_LENGTH))
|
|
139
|
+
ok = false;
|
|
140
|
+
}
|
|
141
|
+
return ok;
|
|
142
|
+
},
|
|
143
|
+
expr: () => ok,
|
|
144
|
+
});
|
|
145
|
+
return ok;
|
|
146
|
+
}
|
|
147
|
+
/** A fresh number array: a literal without spreads, or the fill form. */
|
|
148
|
+
export function int32ArrayAllocation(e) {
|
|
149
|
+
return (e.kind === "arrayLit" && (e.spreads?.length ?? 0) === 0) || fillAllocation(e) !== null;
|
|
150
|
+
}
|
|
151
|
+
/** The array literal a candidate's allocation builds (the literal itself,
|
|
152
|
+
* or the fill form's temporary's), and the fill form's temporary. */
|
|
153
|
+
export function allocatedLiteral(e) {
|
|
154
|
+
if (e.kind === "arrayLit")
|
|
155
|
+
return { literal: e, temporary: null };
|
|
156
|
+
const fill = fillAllocation(e);
|
|
157
|
+
if (!fill || fill.receiver.kind !== "seqExpr")
|
|
158
|
+
return null;
|
|
159
|
+
const decl = fill.receiver.stmts[0];
|
|
160
|
+
return decl.kind === "varDecl" && decl.init?.kind === "arrayLit"
|
|
161
|
+
? { literal: decl.init, temporary: decl.localId }
|
|
162
|
+
: null;
|
|
163
|
+
}
|
|
164
|
+
/** `xs.pop()` whose value is unused, as lowering spells it: a sequence
|
|
165
|
+
* that binds the array to a hidden local, then only reads that local's
|
|
166
|
+
* length and truncates it with pop stores. Returns the hidden local and the
|
|
167
|
+
* array read it binds. */
|
|
168
|
+
function discardedPop(e) {
|
|
169
|
+
if (e.kind !== "seqExpr")
|
|
170
|
+
return null;
|
|
171
|
+
const [bind, ...rest] = e.stmts;
|
|
172
|
+
if (bind?.kind !== "varDecl" || bind.init?.kind !== "varRef")
|
|
173
|
+
return null;
|
|
174
|
+
const local = bind.localId;
|
|
175
|
+
const isLocal = (x) => x.kind === "varRef" && x.localId === local;
|
|
176
|
+
const expr = (x) => {
|
|
177
|
+
if (x.kind === "arrIntrinsic" && x.method === "length" && isLocal(x.receiver))
|
|
178
|
+
return true;
|
|
179
|
+
return !isLocal(x) && everyExprChild(x, expr, stmt);
|
|
180
|
+
};
|
|
181
|
+
const stmt = (x) => {
|
|
182
|
+
if (x.kind === "arraySetLength" && x.pop === true && isLocal(x.arr))
|
|
183
|
+
return expr(x.length);
|
|
184
|
+
return (!((x.kind === "varDecl" || x.kind === "assign") && x.localId === local) &&
|
|
185
|
+
everyStmtChild(x, expr, stmt));
|
|
186
|
+
};
|
|
187
|
+
return rest.every(stmt) && expr(e.result) ? { local, array: bind.init } : null;
|
|
188
|
+
}
|
|
189
|
+
/** Whether evaluating `e` may assign the local `id`. */
|
|
190
|
+
function writesLocal(e, id) {
|
|
191
|
+
const expr = (x) => !(x.kind === "assignExpr" && x.localId === id) && everyExprChild(x, expr, stmt);
|
|
192
|
+
const stmt = (x) => !((x.kind === "varDecl" || x.kind === "assign") && x.localId === id) &&
|
|
193
|
+
everyStmtChild(x, expr, stmt);
|
|
194
|
+
return !expr(e);
|
|
195
|
+
}
|
|
196
|
+
/** Expression kinds an index can be built from without running any code. */
|
|
197
|
+
const PURE_INDEX_KINDS = new Set([
|
|
198
|
+
"varRef",
|
|
199
|
+
"numLit",
|
|
200
|
+
"boolLit",
|
|
201
|
+
"bin",
|
|
202
|
+
"unary",
|
|
203
|
+
"ternary",
|
|
204
|
+
"logical",
|
|
205
|
+
"arrayGet",
|
|
206
|
+
"arrayState",
|
|
207
|
+
]);
|
|
208
|
+
/** Whether evaluating an index runs no code (no call, accessor or
|
|
209
|
+
* conversion): plain reads, literals and their operators only. */
|
|
210
|
+
function pureIndex(e) {
|
|
211
|
+
return PURE_INDEX_KINDS.has(e.kind) && everyExprChild(e, pureIndex, () => false);
|
|
212
|
+
}
|
|
213
|
+
const NO_SHARED = {
|
|
214
|
+
params: new Set(),
|
|
215
|
+
globals: new Set(),
|
|
216
|
+
paramAt: () => false,
|
|
217
|
+
};
|
|
218
|
+
/** The candidates of `fn` (see the module comment): its own locals, its
|
|
219
|
+
* parameters in `shared.params`, and the globals of `shared.globals` that
|
|
220
|
+
* it reads only in candidate positions. `written` receives the globals it
|
|
221
|
+
* assigns fresh arrays. */
|
|
222
|
+
export function int32ArrayCandidates(fn, readers, shared = NO_SHARED, written = new Set()) {
|
|
223
|
+
const result = new Set();
|
|
224
|
+
if (fn.async || fn.generator) {
|
|
225
|
+
// Globals read here leave the candidates.
|
|
226
|
+
for (const id of shared.globals)
|
|
227
|
+
result.add(id);
|
|
228
|
+
everyStmtList(fn.body, {
|
|
229
|
+
expr: (e) => {
|
|
230
|
+
if ((e.kind === "varRef" || e.kind === "assignExpr") && result.has(e.localId))
|
|
231
|
+
result.delete(e.localId);
|
|
232
|
+
return true;
|
|
233
|
+
},
|
|
234
|
+
stmt: (s) => {
|
|
235
|
+
if ((s.kind === "varDecl" || s.kind === "assign") && result.has(s.localId))
|
|
236
|
+
result.delete(s.localId);
|
|
237
|
+
return true;
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
return result;
|
|
241
|
+
}
|
|
242
|
+
const captured = new Set([...(fn.captures ?? []), ...(fn.classCaptures ?? [])].map((c) => c.localId));
|
|
243
|
+
const params = new Set(fn.params.map((p) => p.localId));
|
|
244
|
+
for (const local of fn.locals)
|
|
245
|
+
if (local.type.kind === "array" &&
|
|
246
|
+
local.type.elem.kind === "f64" &&
|
|
247
|
+
!local.boxed &&
|
|
248
|
+
!local.tdz &&
|
|
249
|
+
!captured.has(local.id) &&
|
|
250
|
+
(!params.has(local.id) || shared.params.has(`${fn.name}\0${local.id}`)))
|
|
251
|
+
result.add(local.id);
|
|
252
|
+
for (const id of shared.globals)
|
|
253
|
+
result.add(id);
|
|
254
|
+
if (result.size === 0)
|
|
255
|
+
return result;
|
|
256
|
+
const allocated = new Set();
|
|
257
|
+
// A receiver position: the candidate is read there without escaping.
|
|
258
|
+
const receiver = (e) => {
|
|
259
|
+
if (e.kind !== "varRef")
|
|
260
|
+
expr(e);
|
|
261
|
+
};
|
|
262
|
+
const expr = (e) => {
|
|
263
|
+
switch (e.kind) {
|
|
264
|
+
case "varRef":
|
|
265
|
+
result.delete(e.localId);
|
|
266
|
+
return true;
|
|
267
|
+
case "assignExpr":
|
|
268
|
+
result.delete(e.localId);
|
|
269
|
+
break;
|
|
270
|
+
case "arrayGet":
|
|
271
|
+
case "arrayState":
|
|
272
|
+
case "arrayHas":
|
|
273
|
+
receiver(e.arr);
|
|
274
|
+
expr(e.index);
|
|
275
|
+
return true;
|
|
276
|
+
case "arrIntrinsic":
|
|
277
|
+
if (!INT32_ARRAY_METHODS.has(e.method))
|
|
278
|
+
break;
|
|
279
|
+
receiver(e.receiver);
|
|
280
|
+
e.args.forEach(expr);
|
|
281
|
+
return true;
|
|
282
|
+
case "seqExpr": {
|
|
283
|
+
// The pop's hidden local is the array itself; every use of it is a
|
|
284
|
+
// length read or a pop store.
|
|
285
|
+
const pop = discardedPop(e);
|
|
286
|
+
if (!pop)
|
|
287
|
+
break;
|
|
288
|
+
e.stmts.slice(1).every(stmt);
|
|
289
|
+
expr(e.result);
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
case "call": {
|
|
293
|
+
if (readers.has(e.callee) && e.args.length === 2) {
|
|
294
|
+
const [array, index] = e.args;
|
|
295
|
+
// Inlining evaluates the index before the array read: an index
|
|
296
|
+
// that rebinds the array keeps it out, and so does one that can run
|
|
297
|
+
// code when the array is a module global (a call can reassign it).
|
|
298
|
+
if (array.kind === "varRef" &&
|
|
299
|
+
(writesLocal(index, array.localId) ||
|
|
300
|
+
(array.localId.startsWith("%g.") && !pureIndex(index))))
|
|
301
|
+
result.delete(array.localId);
|
|
302
|
+
receiver(array);
|
|
303
|
+
expr(index);
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
// An argument at a candidate parameter position passes the array
|
|
307
|
+
// to another candidate binding (moduleInt32ArrayCandidates checks
|
|
308
|
+
// every such call).
|
|
309
|
+
e.args.forEach((arg, index) => {
|
|
310
|
+
if (shared.paramAt(e.callee, index))
|
|
311
|
+
receiver(arg);
|
|
312
|
+
else
|
|
313
|
+
expr(arg);
|
|
314
|
+
});
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return everyExprChild(e, expr, stmt);
|
|
319
|
+
};
|
|
320
|
+
const stmt = (s) => {
|
|
321
|
+
switch (s.kind) {
|
|
322
|
+
case "varDecl":
|
|
323
|
+
case "assign": {
|
|
324
|
+
const value = s.kind === "varDecl" ? s.init : s.value;
|
|
325
|
+
if (params.has(s.localId))
|
|
326
|
+
result.delete(s.localId);
|
|
327
|
+
else if (value && int32ArrayAllocation(value))
|
|
328
|
+
allocated.add(s.localId);
|
|
329
|
+
else if (value)
|
|
330
|
+
result.delete(s.localId);
|
|
331
|
+
if (value)
|
|
332
|
+
expr(value);
|
|
333
|
+
return true;
|
|
334
|
+
}
|
|
335
|
+
case "arraySet":
|
|
336
|
+
receiver(s.arr);
|
|
337
|
+
expr(s.index);
|
|
338
|
+
expr(s.value);
|
|
339
|
+
return true;
|
|
340
|
+
case "arraySetUndefined":
|
|
341
|
+
// Stores a present undefined: a state, and a cleared (+0) slot.
|
|
342
|
+
receiver(s.arr);
|
|
343
|
+
expr(s.index);
|
|
344
|
+
return true;
|
|
345
|
+
case "forOf":
|
|
346
|
+
result.delete(s.localId);
|
|
347
|
+
break;
|
|
348
|
+
case "tryCatch":
|
|
349
|
+
if (s.catchLocalId)
|
|
350
|
+
result.delete(s.catchLocalId);
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
return everyStmtChild(s, expr, stmt);
|
|
354
|
+
};
|
|
355
|
+
fn.body.every(stmt);
|
|
356
|
+
for (const id of result) {
|
|
357
|
+
if (shared.globals.has(id)) {
|
|
358
|
+
if (allocated.has(id))
|
|
359
|
+
written.add(id);
|
|
360
|
+
}
|
|
361
|
+
else if (!params.has(id) && !allocated.has(id))
|
|
362
|
+
result.delete(id);
|
|
363
|
+
}
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
/** The members of `ids` (none when absent) that are in `live`. */
|
|
367
|
+
function liveIn(ids, live) {
|
|
368
|
+
const result = new Set();
|
|
369
|
+
if (ids)
|
|
370
|
+
for (const id of ids)
|
|
371
|
+
if (live.has(id))
|
|
372
|
+
result.add(id);
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
/** The candidates of every function of `mod` that has any, only those
|
|
376
|
+
* whose keys are in `keep` when given. Parameters and globals are shared:
|
|
377
|
+
* starting from every one that may qualify, each pass drops the ones a
|
|
378
|
+
* function reads outside candidate positions, the parameters some call
|
|
379
|
+
* passes anything but a candidate, and the globals never assigned a fresh
|
|
380
|
+
* array, until a pass drops nothing. Functions in `redirected` keep their
|
|
381
|
+
* parameters: some of their calls reach another function. */
|
|
382
|
+
export function moduleInt32ArrayCandidates(mod, readers, keep = null, redirected = new Set()) {
|
|
383
|
+
const kept = (key) => keep === null || keep.has(key);
|
|
384
|
+
const arrayParams = new Map();
|
|
385
|
+
for (const fn of mod.functions) {
|
|
386
|
+
// Class methods, constructors and runtime helpers (`%` names) keep
|
|
387
|
+
// their parameters.
|
|
388
|
+
if (fn.name.startsWith("%") || fn.async || fn.generator || redirected.has(fn.name))
|
|
389
|
+
continue;
|
|
390
|
+
const indexes = [];
|
|
391
|
+
fn.params.forEach((p, i) => {
|
|
392
|
+
if (p.type.kind === "array" && p.type.elem.kind === "f64")
|
|
393
|
+
indexes.push(i);
|
|
394
|
+
});
|
|
395
|
+
if (indexes.length > 0)
|
|
396
|
+
arrayParams.set(fn.name, indexes);
|
|
397
|
+
}
|
|
398
|
+
let globals = new Set();
|
|
399
|
+
for (const g of mod.globals ?? [])
|
|
400
|
+
if (g.type.kind === "array" &&
|
|
401
|
+
g.type.elem.kind === "f64" &&
|
|
402
|
+
g.initFlag === undefined &&
|
|
403
|
+
kept(`\0${g.id}`))
|
|
404
|
+
globals.add(g.id);
|
|
405
|
+
const result = new Map();
|
|
406
|
+
if (arrayParams.size === 0 && globals.size === 0) {
|
|
407
|
+
for (const fn of mod.functions) {
|
|
408
|
+
const candidates = int32ArrayCandidates(fn, readers);
|
|
409
|
+
for (const id of candidates)
|
|
410
|
+
if (!kept(`${fn.name}\0${id}`))
|
|
411
|
+
candidates.delete(id);
|
|
412
|
+
if (candidates.size > 0)
|
|
413
|
+
result.set(fn.name, candidates);
|
|
414
|
+
}
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
417
|
+
// One walk: the functions reached other than by direct calls, the direct
|
|
418
|
+
// calls of functions with number[] parameters, the globals each function
|
|
419
|
+
// reads or writes, and whether a module namespace object exists (its
|
|
420
|
+
// member reads can reach any global by name).
|
|
421
|
+
const reached = new Set(moduleFunctionReferences(mod));
|
|
422
|
+
const calls = [];
|
|
423
|
+
const globalsIn = new Map();
|
|
424
|
+
let namespaces = false;
|
|
425
|
+
for (const fn of mod.functions) {
|
|
426
|
+
const used = new Set();
|
|
427
|
+
const note = (id) => {
|
|
428
|
+
if (globals.has(id))
|
|
429
|
+
used.add(id);
|
|
430
|
+
};
|
|
431
|
+
everyStmtList(fn.body, {
|
|
432
|
+
expr: (e) => {
|
|
433
|
+
const name = exprFunctionReference(e);
|
|
434
|
+
if (name !== undefined)
|
|
435
|
+
reached.add(name);
|
|
436
|
+
if (e.kind === "moduleNsRef")
|
|
437
|
+
namespaces = true;
|
|
438
|
+
if (e.kind === "call" && arrayParams.has(e.callee))
|
|
439
|
+
calls.push({ caller: fn.name, call: e });
|
|
440
|
+
if (e.kind === "varRef" || e.kind === "assignExpr")
|
|
441
|
+
note(e.localId);
|
|
442
|
+
return true;
|
|
443
|
+
},
|
|
444
|
+
stmt: (s) => {
|
|
445
|
+
if (s.kind === "varDecl" || s.kind === "assign")
|
|
446
|
+
note(s.localId);
|
|
447
|
+
return true;
|
|
448
|
+
},
|
|
449
|
+
});
|
|
450
|
+
if (used.size > 0)
|
|
451
|
+
globalsIn.set(fn.name, used);
|
|
452
|
+
}
|
|
453
|
+
if (namespaces) {
|
|
454
|
+
globals = new Set();
|
|
455
|
+
globalsIn.clear();
|
|
456
|
+
}
|
|
457
|
+
const paramIds = new Map();
|
|
458
|
+
let params = new Set();
|
|
459
|
+
for (const fn of mod.functions) {
|
|
460
|
+
const indexes = arrayParams.get(fn.name);
|
|
461
|
+
if (!indexes || reached.has(fn.name))
|
|
462
|
+
continue;
|
|
463
|
+
paramIds.set(fn.name, fn.params.map((p) => p.localId));
|
|
464
|
+
for (const i of indexes) {
|
|
465
|
+
const key = `${fn.name}\0${fn.params[i].localId}`;
|
|
466
|
+
if (kept(key))
|
|
467
|
+
params.add(key);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
for (;;) {
|
|
471
|
+
const current = params;
|
|
472
|
+
const written = new Set();
|
|
473
|
+
const liveGlobals = new Set(globals);
|
|
474
|
+
result.clear();
|
|
475
|
+
for (const fn of mod.functions) {
|
|
476
|
+
const shared = {
|
|
477
|
+
params: current,
|
|
478
|
+
globals: liveIn(globalsIn.get(fn.name), globals),
|
|
479
|
+
paramAt: (callee, index) => {
|
|
480
|
+
const id = paramIds.get(callee)?.[index];
|
|
481
|
+
return id !== undefined && current.has(`${callee}\0${id}`);
|
|
482
|
+
},
|
|
483
|
+
};
|
|
484
|
+
const candidates = int32ArrayCandidates(fn, readers, shared, written);
|
|
485
|
+
for (const id of shared.globals)
|
|
486
|
+
if (!candidates.has(id))
|
|
487
|
+
liveGlobals.delete(id);
|
|
488
|
+
for (const id of candidates)
|
|
489
|
+
if (!shared.globals.has(id) && !kept(`${fn.name}\0${id}`))
|
|
490
|
+
candidates.delete(id);
|
|
491
|
+
if (candidates.size > 0)
|
|
492
|
+
result.set(fn.name, candidates);
|
|
493
|
+
}
|
|
494
|
+
for (const id of liveGlobals)
|
|
495
|
+
if (!written.has(id))
|
|
496
|
+
liveGlobals.delete(id);
|
|
497
|
+
const live = new Set([...current].filter((key) => {
|
|
498
|
+
const cut = key.indexOf("\0");
|
|
499
|
+
return result.get(key.slice(0, cut))?.has(key.slice(cut + 1)) === true;
|
|
500
|
+
}));
|
|
501
|
+
// A parameter needs a candidate at that position of every call; a call
|
|
502
|
+
// with fewer arguments passes undefined.
|
|
503
|
+
for (const { caller, call } of calls) {
|
|
504
|
+
const ids = paramIds.get(call.callee);
|
|
505
|
+
if (!ids)
|
|
506
|
+
continue;
|
|
507
|
+
ids.forEach((id, i) => {
|
|
508
|
+
const key = `${call.callee}\0${id}`;
|
|
509
|
+
if (!live.has(key))
|
|
510
|
+
return;
|
|
511
|
+
const arg = call.args[i];
|
|
512
|
+
const ok = arg?.kind === "varRef" &&
|
|
513
|
+
(arg.localId.startsWith("%g.")
|
|
514
|
+
? liveGlobals.has(arg.localId)
|
|
515
|
+
: result.get(caller)?.has(arg.localId) === true);
|
|
516
|
+
if (!ok)
|
|
517
|
+
live.delete(key);
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
if (live.size === current.size && liveGlobals.size === globals.size)
|
|
521
|
+
break;
|
|
522
|
+
params = live;
|
|
523
|
+
globals = liveGlobals;
|
|
524
|
+
}
|
|
525
|
+
return result;
|
|
526
|
+
}
|
|
527
|
+
/** The candidates one array can reach together: a direct call's argument
|
|
528
|
+
* and the parameter it binds hold the same array, so their element facts
|
|
529
|
+
* stand or fall together. `group` maps each of `keys` to its group's keys
|
|
530
|
+
* (itself alone for most), and `globalReaders` each candidate global's
|
|
531
|
+
* key to the functions that read or write it. */
|
|
532
|
+
export function int32ArrayGroups(mod, keys) {
|
|
533
|
+
const parent = new Map();
|
|
534
|
+
const root = (key) => {
|
|
535
|
+
let r = key;
|
|
536
|
+
while (parent.has(r))
|
|
537
|
+
r = parent.get(r);
|
|
538
|
+
if (r !== key)
|
|
539
|
+
parent.set(key, r);
|
|
540
|
+
return r;
|
|
541
|
+
};
|
|
542
|
+
const globalReaders = new Map();
|
|
543
|
+
const params = new Map(mod.functions.map((fn) => [fn.name, fn.params]));
|
|
544
|
+
const paramKeys = new Set(mod.functions.flatMap((fn) => fn.params.map((p) => `${fn.name}\0${p.localId}`)));
|
|
545
|
+
if ([...keys].some((key) => key.startsWith("\0") || paramKeys.has(key))) {
|
|
546
|
+
for (const fn of mod.functions) {
|
|
547
|
+
const touch = (id) => {
|
|
548
|
+
const key = int32ArrayKey(fn.name, id);
|
|
549
|
+
if (!key.startsWith("\0") || !keys.has(key))
|
|
550
|
+
return;
|
|
551
|
+
const set = globalReaders.get(key) ?? new Set();
|
|
552
|
+
set.add(fn.name);
|
|
553
|
+
globalReaders.set(key, set);
|
|
554
|
+
};
|
|
555
|
+
everyStmtList(fn.body, {
|
|
556
|
+
expr: (e) => {
|
|
557
|
+
if (e.kind === "varRef" || e.kind === "assignExpr")
|
|
558
|
+
touch(e.localId);
|
|
559
|
+
if (e.kind === "call")
|
|
560
|
+
e.args.forEach((arg, i) => {
|
|
561
|
+
const param = params.get(e.callee)?.[i];
|
|
562
|
+
if (arg.kind !== "varRef" || !param)
|
|
563
|
+
return;
|
|
564
|
+
const a = int32ArrayKey(fn.name, arg.localId), p = `${e.callee}\0${param.localId}`;
|
|
565
|
+
if (!keys.has(a) || !keys.has(p))
|
|
566
|
+
return;
|
|
567
|
+
const ra = root(a), rp = root(p);
|
|
568
|
+
if (ra !== rp)
|
|
569
|
+
parent.set(ra, rp);
|
|
570
|
+
});
|
|
571
|
+
return true;
|
|
572
|
+
},
|
|
573
|
+
stmt: (s) => {
|
|
574
|
+
if (s.kind === "varDecl" || s.kind === "assign")
|
|
575
|
+
touch(s.localId);
|
|
576
|
+
return true;
|
|
577
|
+
},
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
const members = new Map();
|
|
582
|
+
for (const key of keys) {
|
|
583
|
+
const r = root(key);
|
|
584
|
+
const list = members.get(r);
|
|
585
|
+
if (list)
|
|
586
|
+
list.push(key);
|
|
587
|
+
else
|
|
588
|
+
members.set(r, [key]);
|
|
589
|
+
}
|
|
590
|
+
const group = new Map();
|
|
591
|
+
for (const key of keys)
|
|
592
|
+
group.set(key, members.get(root(key)));
|
|
593
|
+
return { group, globalReaders };
|
|
594
|
+
}
|
|
595
|
+
/** The element values stored into each candidate: element writes, pushed
|
|
596
|
+
* values, literal elements and fill values. */
|
|
597
|
+
export function int32ArrayStores(fn, candidates) {
|
|
598
|
+
const stores = new Map();
|
|
599
|
+
const add = (id, value) => {
|
|
600
|
+
const list = stores.get(id);
|
|
601
|
+
if (list)
|
|
602
|
+
list.push(value);
|
|
603
|
+
else
|
|
604
|
+
stores.set(id, [value]);
|
|
605
|
+
};
|
|
606
|
+
const target = (e) => e.kind === "varRef" && candidates.has(e.localId) ? e.localId : null;
|
|
607
|
+
const expr = (e) => {
|
|
608
|
+
if (e.kind === "arrIntrinsic" && e.method === "push") {
|
|
609
|
+
const id = target(e.receiver);
|
|
610
|
+
if (id !== null)
|
|
611
|
+
for (const arg of e.args)
|
|
612
|
+
add(id, arg);
|
|
613
|
+
}
|
|
614
|
+
return everyExprChild(e, expr, stmt);
|
|
615
|
+
};
|
|
616
|
+
const stmt = (s) => {
|
|
617
|
+
if ((s.kind === "varDecl" || s.kind === "assign") && candidates.has(s.localId)) {
|
|
618
|
+
const value = s.kind === "varDecl" ? s.init : s.value;
|
|
619
|
+
if (value?.kind === "arrayLit")
|
|
620
|
+
for (const el of value.elems)
|
|
621
|
+
add(s.localId, el);
|
|
622
|
+
else if (value) {
|
|
623
|
+
const fill = fillAllocation(value);
|
|
624
|
+
if (fill)
|
|
625
|
+
add(s.localId, fill.args[0]);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
if (s.kind === "arraySet") {
|
|
629
|
+
const id = target(s.arr);
|
|
630
|
+
if (id !== null)
|
|
631
|
+
add(id, s.value);
|
|
632
|
+
}
|
|
633
|
+
return everyStmtChild(s, expr, stmt);
|
|
634
|
+
};
|
|
635
|
+
fn.body.every(stmt);
|
|
636
|
+
return stores;
|
|
637
|
+
}
|
|
638
|
+
const REPEATED_INDEX_OPS = new Set(["+", "-", "*", "&", "|", "^", "<<", ">>", ">>>"]);
|
|
639
|
+
/** An index the inlined read may evaluate at each of its uses: a plain read,
|
|
640
|
+
* a literal, or integer arithmetic over them. Repeating it keeps the forms
|
|
641
|
+
* the backend derives from its operands at every use, such as the exact i64
|
|
642
|
+
* of an int32 product, where a bound local holds only the double. */
|
|
643
|
+
function repeatableIndex(e) {
|
|
644
|
+
if (e.kind === "varRef" || e.kind === "numLit")
|
|
645
|
+
return true;
|
|
646
|
+
if (e.kind === "unary")
|
|
647
|
+
return e.op === "-" && repeatableIndex(e.operand);
|
|
648
|
+
return (e.kind === "bin" &&
|
|
649
|
+
REPEATED_INDEX_OPS.has(e.op) &&
|
|
650
|
+
repeatableIndex(e.left) &&
|
|
651
|
+
repeatableIndex(e.right));
|
|
652
|
+
}
|
|
653
|
+
/** Rewrite a function's candidates for the backend. A discarded pop uses
|
|
654
|
+
* the candidate in place of its hidden local. An element-reader helper call
|
|
655
|
+
* whose array is a candidate is inlined: the helper's returned ternary, with
|
|
656
|
+
* the candidate for its array and the index for its index, so the read means
|
|
657
|
+
* the same. An index that is not repeatable (repeatableIndex) is bound to a
|
|
658
|
+
* fresh local first: in its own declaration just before the statement when
|
|
659
|
+
* the call is the whole value of a declaration or assignment (the form
|
|
660
|
+
* lowering gives `a[i]!`, and the one the backend reads without a box),
|
|
661
|
+
* otherwise in a sequence around the ternary. Selection keeps out indexes
|
|
662
|
+
* that write the array, so evaluating the index before the array read is
|
|
663
|
+
* unobservable. */
|
|
664
|
+
function rewriteCandidates(fn, candidates, readers) {
|
|
665
|
+
const locals = [...fn.locals];
|
|
666
|
+
let fresh = 0;
|
|
667
|
+
const bind = (index) => {
|
|
668
|
+
const id = `%int32.read.${fresh++}`;
|
|
669
|
+
locals.push({ id, name: id, type: F64, mutable: false });
|
|
670
|
+
return {
|
|
671
|
+
decl: { kind: "varDecl", localId: id, init: index, loc: index.loc },
|
|
672
|
+
ref: { kind: "varRef", localId: id, type: F64, loc: index.loc },
|
|
673
|
+
};
|
|
674
|
+
};
|
|
675
|
+
const readerCall = (e) => e?.kind === "call" &&
|
|
676
|
+
e.args.length === 2 &&
|
|
677
|
+
readers.has(e.callee) &&
|
|
678
|
+
e.args[0].kind === "varRef" &&
|
|
679
|
+
candidates.has(e.args[0].localId)
|
|
680
|
+
? e
|
|
681
|
+
: null;
|
|
682
|
+
// The statements of a list, with complex read indexes declared first.
|
|
683
|
+
const hoist = (list) => list.flatMap((s) => {
|
|
684
|
+
if (s.kind !== "varDecl" && s.kind !== "assign")
|
|
685
|
+
return [s];
|
|
686
|
+
const value = s.kind === "varDecl" ? s.init : s.value;
|
|
687
|
+
const call = readerCall(value);
|
|
688
|
+
if (!call || repeatableIndex(call.args[1]))
|
|
689
|
+
return [s];
|
|
690
|
+
const { decl, ref } = bind(call.args[1]);
|
|
691
|
+
const read = { ...call, args: [call.args[0], ref] };
|
|
692
|
+
if (s.kind === "varDecl")
|
|
693
|
+
return [decl, { ...s, init: read }];
|
|
694
|
+
return [decl, { ...s, value: read }];
|
|
695
|
+
});
|
|
696
|
+
const hoistCase = (c) => ({ ...c, body: hoist(c.body) });
|
|
697
|
+
const lists = (s) => {
|
|
698
|
+
switch (s.kind) {
|
|
699
|
+
case "if":
|
|
700
|
+
return { ...s, then: hoist(s.then), else_: s.else_ === null ? null : hoist(s.else_) };
|
|
701
|
+
case "block":
|
|
702
|
+
return { ...s, body: hoist(s.body) };
|
|
703
|
+
case "while":
|
|
704
|
+
return { ...s, body: hoist(s.body) };
|
|
705
|
+
case "doWhile":
|
|
706
|
+
return { ...s, body: hoist(s.body) };
|
|
707
|
+
case "for":
|
|
708
|
+
return { ...s, body: hoist(s.body) };
|
|
709
|
+
case "forOf":
|
|
710
|
+
return { ...s, body: hoist(s.body) };
|
|
711
|
+
case "switch":
|
|
712
|
+
return { ...s, cases: s.cases.map((c) => hoistCase(c)) };
|
|
713
|
+
case "tryCatch":
|
|
714
|
+
return {
|
|
715
|
+
...s,
|
|
716
|
+
tryBody: hoist(s.tryBody),
|
|
717
|
+
catchBody: s.catchBody === null ? null : hoist(s.catchBody),
|
|
718
|
+
finallyBody: s.finallyBody === null ? null : hoist(s.finallyBody),
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
return s;
|
|
722
|
+
};
|
|
723
|
+
// Hidden pop locals replaced by their candidate array.
|
|
724
|
+
const popLocals = new Set();
|
|
725
|
+
const rewrite = (e) => {
|
|
726
|
+
const pop = discardedPop(e);
|
|
727
|
+
if (e.kind === "seqExpr" && pop && candidates.has(pop.array.localId)) {
|
|
728
|
+
popLocals.add(pop.local);
|
|
729
|
+
const array = pop.array;
|
|
730
|
+
const substitute = {
|
|
731
|
+
expr: (x) => x.kind === "varRef" && x.localId === pop.local ? { ...array, loc: x.loc } : x,
|
|
732
|
+
stmt: (x) => x,
|
|
733
|
+
};
|
|
734
|
+
return {
|
|
735
|
+
...e,
|
|
736
|
+
stmts: e.stmts.slice(1).map((x) => transformStmt(x, substitute)),
|
|
737
|
+
result: transformExpr(e.result, substitute),
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
const call = readerCall(e);
|
|
741
|
+
if (!call) {
|
|
742
|
+
if (e.kind === "seqExpr")
|
|
743
|
+
return { ...e, stmts: hoist(e.stmts) };
|
|
744
|
+
return e;
|
|
745
|
+
}
|
|
746
|
+
const helper = readers.get(call.callee);
|
|
747
|
+
const array = call.args[0];
|
|
748
|
+
const [arrayParam, indexParam] = helper.params;
|
|
749
|
+
const ret = helper.body[0];
|
|
750
|
+
if (ret.kind !== "return" || !ret.value)
|
|
751
|
+
return e;
|
|
752
|
+
let index = call.args[1];
|
|
753
|
+
const stmts = [];
|
|
754
|
+
if (!repeatableIndex(index)) {
|
|
755
|
+
const { decl, ref } = bind(index);
|
|
756
|
+
stmts.push(decl);
|
|
757
|
+
index = ref;
|
|
758
|
+
}
|
|
759
|
+
const operand = index;
|
|
760
|
+
// The arguments' copies are not searched again: an index may read a
|
|
761
|
+
// local that has the id of one of the helper's parameters.
|
|
762
|
+
const substituteExpr = (x) => {
|
|
763
|
+
if (x.kind !== "varRef")
|
|
764
|
+
return mapExprChildren(x, substituteExpr, substituteStmt);
|
|
765
|
+
if (x.localId === arrayParam.localId)
|
|
766
|
+
return reparseExpr(array);
|
|
767
|
+
if (x.localId === indexParam.localId)
|
|
768
|
+
return reparseExpr(operand);
|
|
769
|
+
return x;
|
|
770
|
+
};
|
|
771
|
+
const substituteStmt = (x) => mapStmtChildren(x, substituteExpr, substituteStmt);
|
|
772
|
+
const body = substituteExpr(reparseExpr(ret.value));
|
|
773
|
+
// The ternary is a fresh copy (reparseExpr): it takes the call's location.
|
|
774
|
+
const typed = body;
|
|
775
|
+
typed.loc = e.loc;
|
|
776
|
+
return stmts.length === 0
|
|
777
|
+
? typed
|
|
778
|
+
: { kind: "seqExpr", stmts, result: typed, type: typed.type, loc: e.loc };
|
|
779
|
+
};
|
|
780
|
+
const body = transformStmtList(hoist(fn.body), { expr: rewrite, stmt: lists });
|
|
781
|
+
if (fresh === 0 && popLocals.size === 0)
|
|
782
|
+
return { ...fn, body };
|
|
783
|
+
return { ...fn, body, locals: locals.filter((local) => !popLocals.has(local.id)) };
|
|
784
|
+
}
|
|
785
|
+
/** Propose the module's int32 array candidates (int32ArrayKey keys in
|
|
786
|
+
* `int32ArrayCandidates`), only those in `keep` when given, and rewrite
|
|
787
|
+
* their functions. */
|
|
788
|
+
export function markInt32ArrayCandidates(mod, keep = null, redirected = new Set()) {
|
|
789
|
+
if (mod.lib !== undefined)
|
|
790
|
+
return mod;
|
|
791
|
+
const readers = new Map();
|
|
792
|
+
for (const fn of mod.functions)
|
|
793
|
+
if (isElementReader(fn))
|
|
794
|
+
readers.set(fn.name, fn);
|
|
795
|
+
const all = moduleInt32ArrayCandidates(mod, new Set(readers.keys()), keep, redirected);
|
|
796
|
+
if (all.size === 0)
|
|
797
|
+
return mod;
|
|
798
|
+
const keys = new Set();
|
|
799
|
+
const functions = mod.functions.map((fn) => {
|
|
800
|
+
const candidates = all.get(fn.name);
|
|
801
|
+
if (!candidates)
|
|
802
|
+
return fn;
|
|
803
|
+
for (const id of candidates)
|
|
804
|
+
keys.add(int32ArrayKey(fn.name, id));
|
|
805
|
+
return rewriteCandidates(fn, candidates, readers);
|
|
806
|
+
});
|
|
807
|
+
return { ...mod, functions, int32ArrayCandidates: [...keys] };
|
|
808
|
+
}
|
|
809
|
+
/** The module the backend emits: rewritten for exactly the candidates the
|
|
810
|
+
* int32 slot analysis (`prove`, returning its int32Arrays) keeps, so a
|
|
811
|
+
* module without int32 arrays is `mod` itself. A dropped candidate's
|
|
812
|
+
* rewrite is undone by marking again without it, until every candidate
|
|
813
|
+
* marked is kept. `redirected` names the functions some of whose calls the
|
|
814
|
+
* backend emits as calls of another function (a result-slot entry): their
|
|
815
|
+
* parameters keep doubles. */
|
|
816
|
+
export function selectInt32Arrays(mod, prove, redirected = () => new Set()) {
|
|
817
|
+
let keep = null;
|
|
818
|
+
const others = redirected(mod);
|
|
819
|
+
for (let round = 0; round < 4; round++) {
|
|
820
|
+
const marked = markInt32ArrayCandidates(mod, keep, others);
|
|
821
|
+
if (marked === mod)
|
|
822
|
+
return mod;
|
|
823
|
+
const kept = prove(marked);
|
|
824
|
+
const proposed = marked.int32ArrayCandidates ?? [];
|
|
825
|
+
if (proposed.every((key) => kept.has(key)))
|
|
826
|
+
return marked;
|
|
827
|
+
keep = new Set(proposed.filter((key) => kept.has(key)));
|
|
828
|
+
}
|
|
829
|
+
return mod;
|
|
830
|
+
}
|
|
831
|
+
//# sourceMappingURL=int32-arrays.js.map
|