@scriptc/compiler 0.2.4 → 0.2.5
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 +915 -215
- package/ambient/scriptc-overrides.d.ts +5 -1
- package/ambient/scriptc.d.ts +22 -2
- package/dist/backend/build-cache.d.ts +4 -0
- package/dist/backend/build-cache.js +16 -2
- package/dist/backend/build-cache.js.map +1 -1
- package/dist/backend/cycle-analysis.js +17 -5
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +50 -11
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/debug-symbols.js.map +1 -1
- package/dist/backend/executable-features.js +2 -1
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/external-c.d.ts +13 -6
- package/dist/backend/external-c.js +15 -3
- package/dist/backend/external-c.js.map +1 -1
- package/dist/backend/ffi-callbacks.js +6 -9
- package/dist/backend/ffi-callbacks.js.map +1 -1
- package/dist/backend/library-identity-markers.js.map +1 -1
- package/dist/backend/library-pack.d.ts +1 -1
- package/dist/backend/library-pack.js +81 -24
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/link-plan-core.js +9 -2
- package/dist/backend/link-plan-core.js.map +1 -1
- package/dist/backend/link-plan.d.ts +1 -1
- package/dist/backend/link-plan.js +4 -5
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/linker.d.ts +1 -1
- package/dist/backend/linker.js +42 -23
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/literals.js +5 -4
- package/dist/backend/literals.js.map +1 -1
- package/dist/backend/literals.test.js +30 -5
- package/dist/backend/literals.test.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +5 -2
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/borrowed-inputs.js.map +1 -1
- package/dist/backend/llvm/borrowed-receivers.js +43 -19
- package/dist/backend/llvm/borrowed-receivers.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +6 -1
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-bounds.js +73 -22
- package/dist/backend/llvm/bytes-bounds.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.d.ts +3 -0
- package/dist/backend/llvm/call-lifetimes.js +60 -17
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +159 -28
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.d.ts +4 -0
- package/dist/backend/llvm/checked-value-lifetimes.js +14 -4
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.js +16 -12
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.js +4 -1
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/counted-loops.js +10 -3
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/debug-info.js +33 -13
- package/dist/backend/llvm/debug-info.js.map +1 -1
- package/dist/backend/llvm/debug-info.test.js +28 -6
- package/dist/backend/llvm/debug-info.test.js.map +1 -1
- package/dist/backend/llvm/dyn.js +68 -22
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +9 -3
- package/dist/backend/llvm/emitter.js +238 -105
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +233 -42
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +25 -6
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +13 -4
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.js +10 -4
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +20 -9
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +2 -0
- package/dist/backend/llvm/expr-containers.js +92 -33
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +1 -3
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +3 -1
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +19 -4
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-island.js +26 -6
- package/dist/backend/llvm/expr-island.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +88 -19
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +43 -1
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +10 -9
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +44 -26
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +51 -14
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.js +34 -14
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/integer-values.js +15 -4
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/integer-views.js +23 -7
- package/dist/backend/llvm/integer-views.js.map +1 -1
- package/dist/backend/llvm/integer-views.test.js +42 -7
- package/dist/backend/llvm/integer-views.test.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +13 -4
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +7 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +35 -10
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +35 -16
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +33 -18
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +60 -15
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +12 -5
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +97 -31
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +57 -14
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +107 -31
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +33 -14
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +21 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +69 -20
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +1 -0
- package/dist/backend/llvm/local-array-reads.js +96 -30
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +368 -60
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.d.ts +25 -0
- package/dist/backend/llvm/local-union-storage.js +109 -0
- package/dist/backend/llvm/local-union-storage.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.test.d.ts +1 -0
- package/dist/backend/llvm/local-union-storage.test.js +210 -0
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -0
- package/dist/backend/llvm/map-read-lifetimes.d.ts +6 -2
- package/dist/backend/llvm/map-read-lifetimes.js +44 -14
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +89 -17
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/reference-effects.d.ts +3 -2
- package/dist/backend/llvm/reference-effects.js +67 -36
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-effects.test.js +92 -9
- package/dist/backend/llvm/reference-effects.test.js.map +1 -1
- package/dist/backend/llvm/shapes.js +60 -17
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +3 -1
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/split.js +4 -4
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/split.test.js +14 -6
- package/dist/backend/llvm/split.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.js +14 -5
- package/dist/backend/llvm/stack-unions.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +151 -32
- package/dist/backend/llvm/stack-unions.test.js.map +1 -1
- package/dist/backend/llvm/string-construction.js.map +1 -1
- package/dist/backend/llvm/string-construction.test.js +32 -7
- package/dist/backend/llvm/string-construction.test.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.js +14 -8
- package/dist/backend/llvm/string-lifetimes.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +112 -26
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.d.ts +9 -0
- package/dist/backend/llvm/switch-dispatch.js +114 -0
- package/dist/backend/llvm/switch-dispatch.js.map +1 -0
- package/dist/backend/llvm/switch-dispatch.test.d.ts +1 -0
- package/dist/backend/llvm/switch-dispatch.test.js +83 -0
- package/dist/backend/llvm/switch-dispatch.test.js.map +1 -0
- package/dist/backend/llvm/unsupported.js.map +1 -1
- package/dist/backend/llvm/walkers.js +6 -3
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/mangle.js +9 -3
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.js +18 -8
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +118 -22
- package/dist/backend/may-throw.test.js.map +1 -1
- package/dist/backend/native/artifact-stamps.d.ts +39 -0
- package/dist/backend/native/artifact-stamps.js +371 -0
- package/dist/backend/native/artifact-stamps.js.map +1 -0
- package/dist/backend/native/cache-warm.d.ts +24 -0
- package/dist/backend/native/cache-warm.js +80 -0
- package/dist/backend/native/cache-warm.js.map +1 -0
- package/dist/backend/native/compiler-fingerprint.d.ts +19 -0
- package/dist/backend/native/compiler-fingerprint.js +357 -0
- package/dist/backend/native/compiler-fingerprint.js.map +1 -0
- package/dist/backend/native/contracts.d.ts +314 -0
- package/dist/backend/native/contracts.js +2 -0
- package/dist/backend/native/contracts.js.map +1 -0
- package/dist/backend/native/dependency-files.d.ts +5 -0
- package/dist/backend/native/dependency-files.js +83 -0
- package/dist/backend/native/dependency-files.js.map +1 -0
- package/dist/backend/native/driver.d.ts +50 -0
- package/dist/backend/native/driver.js +294 -0
- package/dist/backend/native/driver.js.map +1 -0
- package/dist/backend/native/executable.d.ts +18 -0
- package/dist/backend/native/executable.js +1267 -0
- package/dist/backend/native/executable.js.map +1 -0
- package/dist/backend/native/library.d.ts +2 -0
- package/dist/backend/native/library.js +614 -0
- package/dist/backend/native/library.js.map +1 -0
- package/dist/backend/native/linker-fingerprint.d.ts +8 -0
- package/dist/backend/native/linker-fingerprint.js +174 -0
- package/dist/backend/native/linker-fingerprint.js.map +1 -0
- package/dist/backend/native/object-merge.d.ts +2 -0
- package/dist/backend/native/object-merge.js +154 -0
- package/dist/backend/native/object-merge.js.map +1 -0
- package/dist/backend/native/process.d.ts +17 -0
- package/dist/backend/native/process.js +42 -0
- package/dist/backend/native/process.js.map +1 -0
- package/dist/backend/native/program-shards.d.ts +21 -0
- package/dist/backend/native/program-shards.js +99 -0
- package/dist/backend/native/program-shards.js.map +1 -0
- package/dist/backend/native/runtime-inputs.d.ts +12 -0
- package/dist/backend/native/runtime-inputs.js +163 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -0
- package/dist/backend/native/runtime-inputs.test.d.ts +1 -0
- package/dist/backend/native/runtime-inputs.test.js +64 -0
- package/dist/backend/native/runtime-inputs.test.js.map +1 -0
- package/dist/backend/native/runtime-objects.d.ts +16 -0
- package/dist/backend/native/runtime-objects.js +122 -0
- package/dist/backend/native/runtime-objects.js.map +1 -0
- package/dist/backend/native/session.d.ts +12 -0
- package/dist/backend/native/session.js +31 -0
- package/dist/backend/native/session.js.map +1 -0
- package/dist/backend/native/tool-identity.d.ts +37 -0
- package/dist/backend/native/tool-identity.js +310 -0
- package/dist/backend/native/tool-identity.js.map +1 -0
- package/dist/backend/native/trace-paths.d.ts +12 -0
- package/dist/backend/native/trace-paths.js +73 -0
- package/dist/backend/native/trace-paths.js.map +1 -0
- package/dist/backend/native/vendor.d.ts +1 -0
- package/dist/backend/native/vendor.js +12 -0
- package/dist/backend/native/vendor.js.map +1 -0
- package/dist/backend/native-codegen-core.js +2 -1
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +1 -1
- package/dist/backend/native-codegen.js +24 -13
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +12 -9
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.js +9 -5
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-link-info.js +14 -5
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-link-info.test.js +58 -13
- package/dist/backend/native-link-info.test.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +17 -450
- package/dist/backend/native-toolchain.js +17 -3971
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +103 -72
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/native-tools.js +27 -8
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/object-localize.js +17 -14
- package/dist/backend/object-localize.js.map +1 -1
- package/dist/backend/object-localize.test.js +59 -12
- package/dist/backend/object-localize.test.js.map +1 -1
- package/dist/backend/runtime-pack-core.js +96 -49
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +5 -3
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +87 -15
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.d.ts +1 -1
- package/dist/backend/runtime-pack.js +11 -12
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +40 -24
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/source-locations.js.map +1 -1
- package/dist/backend/source-locations.test.js +7 -2
- package/dist/backend/source-locations.test.js.map +1 -1
- package/dist/backend/target-diagnostics.js +44 -14
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +93 -20
- package/dist/backend/target-diagnostics.test.js.map +1 -1
- package/dist/backend/targets.js +230 -86
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +32 -18
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/backend/toolchain-environment.js +5 -1
- package/dist/backend/toolchain-environment.js.map +1 -1
- package/dist/backend/vendor-archives.d.ts +2 -2
- package/dist/backend/vendor-archives.js +84 -35
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.js +13 -1
- package/dist/backend/vendor-inputs.js.map +1 -1
- package/dist/backend/warm-cache.d.ts +1 -1
- package/dist/backend/warm-cache.js +33 -9
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/cli/command.js +39 -9
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/output-options.js +14 -4
- package/dist/cli/output-options.js.map +1 -1
- package/dist/cli/paths.js.map +1 -1
- package/dist/cli/wasi-runner.js.map +1 -1
- package/dist/compat/fetch-profile.js +36 -35
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/coverage/report.js +16 -17
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +112 -26
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +55 -16
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +1 -1
- package/dist/executable/executable-cache.js +78 -48
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +75 -26
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -2
- package/dist/executable/prepare.js.map +1 -1
- package/dist/ffi/ffi-manifest.js +78 -20
- package/dist/ffi/ffi-manifest.js.map +1 -1
- package/dist/ffi/ffi-manifest.test.js +96 -16
- package/dist/ffi/ffi-manifest.test.js.map +1 -1
- package/dist/format-integer.js.map +1 -1
- package/dist/frontend/analysis.js +12 -2
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/arguments-usage.js.map +1 -1
- package/dist/frontend/binding-source.js +9 -3
- package/dist/frontend/binding-source.js.map +1 -1
- package/dist/frontend/builtin-modules.js +46 -2
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-resolve.js +40 -17
- package/dist/frontend/cjs-resolve.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +31 -10
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/comptime-node.test.js +10 -11
- package/dist/frontend/comptime-node.test.js.map +1 -1
- package/dist/frontend/dts-paths.js +7 -3
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/fork-target.js +17 -12
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/function-completion.js +11 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +53 -6
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +18 -2
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +32 -12
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.test.js +11 -15
- package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
- package/dist/frontend/input-tracker.js +11 -11
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +4 -1
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lib-contract.js +38 -9
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/literal-values.js.map +1 -1
- package/dist/frontend/literal-values.test.js +28 -8
- package/dist/frontend/literal-values.test.js.map +1 -1
- package/dist/frontend/lowering/abstract-equality.js +53 -10
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-indexed-mutation.d.ts +1 -1
- package/dist/frontend/lowering/array-indexed-mutation.js +108 -106
- package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
- package/dist/frontend/lowering/array-values.js +37 -14
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/binding-analysis.d.ts +50 -0
- package/dist/frontend/lowering/binding-analysis.js +376 -0
- package/dist/frontend/lowering/binding-analysis.js.map +1 -0
- package/dist/frontend/lowering/builtin-calls.d.ts +9 -0
- package/dist/frontend/lowering/builtin-calls.js +60 -0
- package/dist/frontend/lowering/builtin-calls.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.d.ts +43 -0
- package/dist/frontend/lowering/builtins/arguments.js +247 -0
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -0
- package/dist/frontend/lowering/builtins/async-context.d.ts +52 -0
- package/dist/frontend/lowering/builtins/async-context.js +436 -0
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -0
- package/dist/frontend/lowering/builtins/atomics.d.ts +15 -0
- package/dist/frontend/lowering/builtins/atomics.js +46 -0
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.d.ts +13 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +87 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -0
- package/dist/frontend/lowering/builtins/child-process-async.d.ts +18 -0
- package/dist/frontend/lowering/builtins/child-process-async.js +245 -0
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -0
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +21 -0
- package/dist/frontend/lowering/builtins/child-process-methods.js +362 -0
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -0
- package/dist/frontend/lowering/builtins/child-process-sync.d.ts +4 -0
- package/dist/frontend/lowering/builtins/child-process-sync.js +639 -0
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -0
- package/dist/frontend/lowering/builtins/child-process.d.ts +55 -0
- package/dist/frontend/lowering/builtins/child-process.js +669 -0
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +7 -0
- package/dist/frontend/lowering/builtins/compression.js +115 -0
- package/dist/frontend/lowering/builtins/compression.js.map +1 -0
- package/dist/frontend/lowering/builtins/console.d.ts +10 -0
- package/dist/frontend/lowering/builtins/console.js +38 -0
- package/dist/frontend/lowering/builtins/console.js.map +1 -0
- package/dist/frontend/lowering/builtins/constants.d.ts +24 -0
- package/dist/frontend/lowering/builtins/constants.js +141 -0
- package/dist/frontend/lowering/builtins/constants.js.map +1 -0
- package/dist/frontend/lowering/builtins/crypto.d.ts +22 -0
- package/dist/frontend/lowering/builtins/crypto.js +517 -0
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -0
- package/dist/frontend/lowering/builtins/dates.js +101 -0
- package/dist/frontend/lowering/builtins/dates.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.d.ts +34 -0
- package/dist/frontend/lowering/builtins/environment.js +95 -0
- package/dist/frontend/lowering/builtins/environment.js.map +1 -0
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -0
- package/dist/frontend/lowering/builtins/errors.js +83 -0
- package/dist/frontend/lowering/builtins/errors.js.map +1 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +32 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +678 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -0
- package/dist/frontend/lowering/builtins/filesystem.d.ts +108 -0
- package/dist/frontend/lowering/builtins/filesystem.js +1061 -0
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -0
- package/dist/frontend/lowering/builtins/ipc.d.ts +8 -0
- package/dist/frontend/lowering/builtins/ipc.js +76 -0
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -0
- package/dist/frontend/lowering/builtins/json.d.ts +12 -0
- package/dist/frontend/lowering/builtins/json.js +387 -0
- package/dist/frontend/lowering/builtins/json.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +85 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +346 -0
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-calls.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-calls.js +303 -0
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +38 -0
- package/dist/frontend/lowering/builtins/module-resolution.js +344 -0
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.d.ts +15 -0
- package/dist/frontend/lowering/builtins/numbers.js +124 -0
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -0
- package/dist/frontend/lowering/builtins/operating-system.d.ts +13 -0
- package/dist/frontend/lowering/builtins/operating-system.js +148 -0
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -0
- package/dist/frontend/lowering/builtins/performance.d.ts +13 -0
- package/dist/frontend/lowering/builtins/performance.js +100 -0
- package/dist/frontend/lowering/builtins/performance.js.map +1 -0
- package/dist/frontend/lowering/builtins/process.d.ts +50 -0
- package/dist/frontend/lowering/builtins/process.js +1138 -0
- package/dist/frontend/lowering/builtins/process.js.map +1 -0
- package/dist/frontend/lowering/builtins/promises.d.ts +14 -0
- package/dist/frontend/lowering/builtins/promises.js +356 -0
- package/dist/frontend/lowering/builtins/promises.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.d.ts +11 -0
- package/dist/frontend/lowering/builtins/properties.js +186 -0
- package/dist/frontend/lowering/builtins/properties.js.map +1 -0
- package/dist/frontend/lowering/builtins/querystring.d.ts +19 -0
- package/dist/frontend/lowering/builtins/querystring.js +150 -0
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -0
- package/dist/frontend/lowering/builtins/readline.d.ts +13 -0
- package/dist/frontend/lowering/builtins/readline.js +138 -0
- package/dist/frontend/lowering/builtins/readline.js.map +1 -0
- package/dist/frontend/lowering/builtins/receiver-types.d.ts +5 -0
- package/dist/frontend/lowering/builtins/receiver-types.js +15 -0
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -0
- package/dist/frontend/lowering/builtins/reflection.d.ts +13 -0
- package/dist/frontend/lowering/builtins/reflection.js +95 -0
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.d.ts +14 -0
- package/dist/frontend/lowering/builtins/strings.js +121 -0
- package/dist/frontend/lowering/builtins/strings.js.map +1 -0
- package/dist/frontend/lowering/builtins/text-codecs.d.ts +29 -0
- package/dist/frontend/lowering/builtins/text-codecs.js +590 -0
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -0
- package/dist/frontend/lowering/builtins/timers.d.ts +22 -0
- package/dist/frontend/lowering/builtins/timers.js +180 -0
- package/dist/frontend/lowering/builtins/timers.js.map +1 -0
- package/dist/frontend/lowering/builtins/url.d.ts +37 -0
- package/dist/frontend/lowering/builtins/url.js +596 -0
- package/dist/frontend/lowering/builtins/url.js.map +1 -0
- package/dist/frontend/lowering/builtins/util-types.d.ts +7 -0
- package/dist/frontend/lowering/builtins/util-types.js +31 -0
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -0
- package/dist/frontend/lowering/call-arguments.d.ts +72 -0
- package/dist/frontend/lowering/call-arguments.js +618 -0
- package/dist/frontend/lowering/call-arguments.js.map +1 -0
- package/dist/frontend/lowering/call-signatures.d.ts +115 -0
- package/dist/frontend/lowering/call-signatures.js +719 -0
- package/dist/frontend/lowering/call-signatures.js.map +1 -0
- package/dist/frontend/lowering/callback-arg.js.map +1 -1
- package/dist/frontend/lowering/checked-iterable-spread.js +53 -10
- package/dist/frontend/lowering/checked-iterable-spread.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.js +41 -9
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +1 -1
- package/dist/frontend/lowering/class-callbacks.js +130 -27
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +1 -1
- package/dist/frontend/lowering/class-construction.js +247 -50
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.js +109 -29
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +6 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.js +2471 -465
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +284 -44
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +17 -5
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +199 -51
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.js +345 -86
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +80 -17
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +76 -16
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/coercions/builders.d.ts +13 -0
- package/dist/frontend/lowering/coercions/builders.js +77 -0
- package/dist/frontend/lowering/coercions/builders.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +58 -0
- package/dist/frontend/lowering/coercions/function-adapters.js +430 -0
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -0
- package/dist/frontend/lowering/coercions/island.d.ts +37 -0
- package/dist/frontend/lowering/coercions/island.js +350 -0
- package/dist/frontend/lowering/coercions/island.js.map +1 -0
- package/dist/frontend/lowering/coercions/state.d.ts +14 -0
- package/dist/frontend/lowering/coercions/state.js +16 -0
- package/dist/frontend/lowering/coercions/state.js.map +1 -0
- package/dist/frontend/lowering/coercions/structural-plans.d.ts +40 -0
- package/dist/frontend/lowering/coercions/structural-plans.js +447 -0
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -0
- package/dist/frontend/lowering/coercions/structural.d.ts +63 -0
- package/dist/frontend/lowering/coercions/structural.js +616 -0
- package/dist/frontend/lowering/coercions/structural.js.map +1 -0
- package/dist/frontend/lowering/coercions/unions.d.ts +65 -0
- package/dist/frontend/lowering/coercions/unions.js +318 -0
- package/dist/frontend/lowering/coercions/unions.js.map +1 -0
- package/dist/frontend/lowering/collection-ingestion.js +355 -72
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +92 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +1646 -0
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -0
- package/dist/frontend/lowering/containers/array-construction.d.ts +42 -0
- package/dist/frontend/lowering/containers/array-construction.js +1044 -0
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -0
- package/dist/frontend/lowering/containers/array-iteration.d.ts +16 -0
- package/dist/frontend/lowering/containers/array-iteration.js +95 -0
- package/dist/frontend/lowering/containers/array-iteration.js.map +1 -0
- package/dist/frontend/lowering/containers/array-methods.d.ts +27 -0
- package/dist/frontend/lowering/containers/array-methods.js +1854 -0
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.d.ts +17 -17
- package/dist/frontend/lowering/containers/bytes.js +419 -105
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +26 -0
- package/dist/frontend/lowering/containers/callback-arguments.js +179 -0
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -0
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +19 -0
- package/dist/frontend/lowering/containers/collection-grouping.js +297 -0
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -0
- package/dist/frontend/lowering/containers/collection-methods.d.ts +57 -0
- package/dist/frontend/lowering/containers/collection-methods.js +1314 -0
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -0
- package/dist/frontend/lowering/containers/dynamic-receivers.d.ts +18 -0
- package/dist/frontend/lowering/containers/dynamic-receivers.js +114 -0
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -0
- package/dist/frontend/lowering/containers/for-of.d.ts +60 -0
- package/dist/frontend/lowering/containers/for-of.js +643 -0
- package/dist/frontend/lowering/containers/for-of.js.map +1 -0
- package/dist/frontend/lowering/containers/indexed-objects.d.ts +132 -0
- package/dist/frontend/lowering/containers/indexed-objects.js +1743 -0
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -0
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +20 -0
- package/dist/frontend/lowering/containers/iterator-helpers.js +809 -0
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +580 -158
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +213 -63
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/crypto-tables.js +263 -64
- package/dist/frontend/lowering/crypto-tables.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +172 -68
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.test.js +41 -8
- package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -1
- package/dist/frontend/lowering/error-methods.js +339 -65
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/expressions/evaluation-safety.js +3 -2
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/global-symbols.js +2 -1
- package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -1
- package/dist/frontend/lowering/expressions/native-proxy.js +11 -5
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +67 -13
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +589 -162
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +68 -17
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-field-write.js +45 -18
- package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -1
- package/dist/frontend/lowering/function-context.js +5 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.d.ts +67 -0
- package/dist/frontend/lowering/function-returns.js +392 -0
- package/dist/frontend/lowering/function-returns.js.map +1 -0
- package/dist/frontend/lowering/generator-delegation.d.ts +1 -1
- package/dist/frontend/lowering/generator-delegation.js +171 -39
- package/dist/frontend/lowering/generator-delegation.js.map +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +176 -36
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +274 -0
- package/dist/frontend/lowering/generic-functions.js +1727 -0
- package/dist/frontend/lowering/generic-functions.js.map +1 -0
- package/dist/frontend/lowering/import-meta.d.ts +1 -1
- package/dist/frontend/lowering/import-meta.js +37 -14
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/indexed-comparison.js +6 -2
- package/dist/frontend/lowering/indexed-comparison.js.map +1 -1
- package/dist/frontend/lowering/iterator-consumption.d.ts +9 -0
- package/dist/frontend/lowering/iterator-consumption.js +91 -0
- package/dist/frontend/lowering/iterator-consumption.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.js +40 -17
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.test.js +49 -11
- package/dist/frontend/lowering/lib-boundary.test.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.d.ts +0 -19
- package/dist/frontend/lowering/lower-array-sort.js +331 -566
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +248 -43
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js +71 -16
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.js +420 -71
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +39 -558
- package/dist/frontend/lowering/lower-calls.js +2593 -5667
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +243 -242
- package/dist/frontend/lowering/lower-classes.js +1701 -724
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +35 -35
- package/dist/frontend/lowering/lower-comptime.js +39 -37
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +59 -31
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +5 -2
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +322 -85
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +19 -7
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +194 -194
- package/dist/frontend/lowering/lower-exprs.js +3446 -1154
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.d.ts +23 -0
- package/dist/frontend/lowering/lower-functions.js +449 -0
- package/dist/frontend/lowering/lower-functions.js.map +1 -0
- package/dist/frontend/lowering/lower-generators.js +121 -32
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +15 -4
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +479 -89
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +79 -79
- package/dist/frontend/lowering/lower-island.js +365 -273
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-island.test.js +7 -2
- package/dist/frontend/lowering/lower-island.test.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +17 -8
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +94 -94
- package/dist/frontend/lowering/lower-modules.js +612 -321
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.js +91 -20
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +25 -8
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.js +115 -34
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +1210 -290
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +148 -148
- package/dist/frontend/lowering/lower-stmts.js +2312 -984
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.test.js +13 -5
- package/dist/frontend/lowering/lower-stmts.test.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +362 -90
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-system-errors.js +30 -8
- package/dist/frontend/lowering/lower-system-errors.js.map +1 -1
- package/dist/frontend/lowering/lower-test.js +40 -13
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.d.ts +31 -0
- package/dist/frontend/lowering/lower-timers.js +336 -0
- package/dist/frontend/lowering/lower-timers.js.map +1 -0
- package/dist/frontend/lowering/lower-url.d.ts +1 -1
- package/dist/frontend/lowering/lower-url.js +46 -13
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +21 -351
- package/dist/frontend/lowering/lowerer.js +1024 -2704
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +85 -17
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js +43 -8
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.d.ts +21 -1
- package/dist/frontend/lowering/native-ffi.js +487 -18
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-enumeration-receiver.js +55 -10
- package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.d.ts +1 -1
- package/dist/frontend/lowering/object-factory-new.js +36 -11
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.js +49 -20
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.js +66 -14
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-locals.js +3 -1
- package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.js +4 -1
- package/dist/frontend/lowering/sanitize-class-types.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +86 -18
- package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -1
- package/dist/frontend/lowering/static-this.js +13 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/string-index.js +32 -10
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +42 -42
- package/dist/frontend/lowering/surfaces.js +1094 -249
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.js +40 -15
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.js +236 -24
- package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.test.js +84 -12
- package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -1
- package/dist/frontend/lowering/union-narrow.js +59 -16
- package/dist/frontend/lowering/union-narrow.js.map +1 -1
- package/dist/frontend/lowering/union-narrow.test.js +24 -7
- package/dist/frontend/lowering/union-narrow.test.js.map +1 -1
- package/dist/frontend/lowering/union-retag.js +155 -40
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +131 -33
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/unregistered-class-types.js.map +1 -1
- package/dist/frontend/lowering/unregistered-class-types.test.js +34 -8
- package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +21 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/module-syntax.test.js +37 -13
- package/dist/frontend/module-syntax.test.js.map +1 -1
- package/dist/frontend/npm-fetch-analysis.js +13 -4
- package/dist/frontend/npm-fetch-analysis.js.map +1 -1
- package/dist/frontend/npm-fetch-analysis.test.js +33 -10
- package/dist/frontend/npm-fetch-analysis.test.js.map +1 -1
- package/dist/frontend/npm-fetch-node.js.map +1 -1
- package/dist/frontend/npm-fetch-syntax.js +4 -9
- package/dist/frontend/npm-fetch-syntax.js.map +1 -1
- package/dist/frontend/npm-node.js +3 -1
- package/dist/frontend/npm-node.js.map +1 -1
- package/dist/frontend/npm-static-bundled-cjs.js +88 -29
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-cjs.test.js +29 -10
- package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -1
- package/dist/frontend/npm-static-declaration-syntax.js +148 -56
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-declarations.d.ts +1 -1
- package/dist/frontend/npm-static-declarations.js.map +1 -1
- package/dist/frontend/npm-static-declarations.test.js +33 -7
- package/dist/frontend/npm-static-declarations.test.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +26 -12
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-prune.test.js +17 -3
- package/dist/frontend/npm-static-prune.test.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.js +2 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.js +64 -21
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +9 -4
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.test.js +30 -6
- package/dist/frontend/npm-static-subtyping.test.js.map +1 -1
- package/dist/frontend/npm-static.js +15 -4
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.js +122 -36
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +30 -10
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/pipeline-native.js.map +1 -1
- package/dist/frontend/pipeline.js +25 -8
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +21 -7
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-node.js +5 -3
- package/dist/frontend/program-node.js.map +1 -1
- package/dist/frontend/program.d.ts +2 -2
- package/dist/frontend/program.js +234 -101
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +27 -27
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/provenance-core.js +8 -4
- package/dist/frontend/provenance-core.js.map +1 -1
- package/dist/frontend/provenance-registry.js +1 -4
- package/dist/frontend/provenance-registry.js.map +1 -1
- package/dist/frontend/resolve.js +32 -20
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +1 -1
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/runtime-resolve.js +13 -4
- package/dist/frontend/runtime-resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.test.js +25 -9
- package/dist/frontend/runtime-resolve.test.js.map +1 -1
- package/dist/frontend/services-node.js +6 -2
- package/dist/frontend/services-node.js.map +1 -1
- package/dist/frontend/services-node.test.js +18 -6
- package/dist/frontend/services-node.test.js.map +1 -1
- package/dist/frontend/services.js +8 -4
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +6 -2
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/ts7/api.js +12 -4
- package/dist/frontend/ts7/api.js.map +1 -1
- package/dist/frontend/ts7/ast-bytes.js +10 -3
- package/dist/frontend/ts7/ast-bytes.js.map +1 -1
- package/dist/frontend/ts7/ast-bytes.test.js +23 -4
- package/dist/frontend/ts7/ast-bytes.test.js.map +1 -1
- package/dist/frontend/ts7/ast-guards.test.js +14 -5
- package/dist/frontend/ts7/ast-guards.test.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +6 -1
- package/dist/frontend/ts7/ast-node.js +484 -164
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +109 -36
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-text.js +13 -3
- package/dist/frontend/ts7/ast-text.js.map +1 -1
- package/dist/frontend/ts7/ast-text.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.d.ts +1 -1
- package/dist/frontend/ts7/ast-wire.js +55 -20
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.test.js +53 -8
- package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
- package/dist/frontend/ts7/ast.js +47 -28
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/census-check.js +1 -1
- package/dist/frontend/ts7/census-check.js.map +1 -1
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.js +5 -3
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +54 -17
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/enums.test.js +9 -4
- package/dist/frontend/ts7/enums.test.js.map +1 -1
- package/dist/frontend/ts7/native-api.js.map +1 -1
- package/dist/frontend/ts7/native-host.js.map +1 -1
- package/dist/frontend/ts7/native-process.js +9 -3
- package/dist/frontend/ts7/native-process.js.map +1 -1
- package/dist/frontend/ts7/program-adapter.js +1 -1
- package/dist/frontend/ts7/program-adapter.js.map +1 -1
- package/dist/frontend/ts7/program-host.js +7 -4
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/program-host.test.js +43 -11
- package/dist/frontend/ts7/program-host.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.js +3 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/rpc-client.js +15 -5
- package/dist/frontend/ts7/rpc-client.js.map +1 -1
- package/dist/frontend/ts7/rpc-client.test.js +26 -8
- package/dist/frontend/ts7/rpc-client.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-filesystem.js.map +1 -1
- package/dist/frontend/ts7/rpc-filesystem.test.js +43 -10
- package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-process.js +16 -6
- package/dist/frontend/ts7/rpc-process.js.map +1 -1
- package/dist/frontend/ts7/rpc-process.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-wire.d.ts +1 -0
- package/dist/frontend/ts7/rpc-wire.js +41 -14
- package/dist/frontend/ts7/rpc-wire.js.map +1 -1
- package/dist/frontend/ts7/rpc-wire.test.js +36 -6
- package/dist/frontend/ts7/rpc-wire.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.js +209 -68
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +29 -14
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-json.js +7 -1
- package/dist/frontend/ts7/semantic-json.js.map +1 -1
- package/dist/frontend/ts7/semantic-json.test.js +17 -3
- package/dist/frontend/ts7/semantic-json.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.js +147 -51
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +72 -19
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +2 -2
- package/dist/frontend/ts7/session-cache.js +10 -3
- package/dist/frontend/ts7/session-cache.js.map +1 -1
- package/dist/frontend/ts7/session-cache.test.js +13 -4
- package/dist/frontend/ts7/session-cache.test.js.map +1 -1
- package/dist/frontend/ts7/session-path.js +25 -10
- package/dist/frontend/ts7/session-path.js.map +1 -1
- package/dist/frontend/ts7/session-path.test.js +47 -4
- package/dist/frontend/ts7/session-path.test.js.map +1 -1
- package/dist/frontend/ts7/session-timing.js +22 -3
- package/dist/frontend/ts7/session-timing.js.map +1 -1
- package/dist/frontend/ts7/session-timing.test.js +12 -3
- package/dist/frontend/ts7/session-timing.test.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +1 -0
- package/dist/frontend/ts7/session.js +109 -35
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +69 -15
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.js +17 -6
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +32 -9
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/tsc-codes.js +56 -11
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/tsc-codes.test.d.ts +1 -0
- package/dist/frontend/tsc-codes.test.js +16 -0
- package/dist/frontend/tsc-codes.test.js.map +1 -0
- package/dist/frontend/type-mapper.js +545 -204
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.js +108 -33
- package/dist/frontend/type-mapper.test.js.map +1 -1
- package/dist/frontend/union-discriminants.js +8 -2
- package/dist/frontend/union-discriminants.js.map +1 -1
- package/dist/frontend/union-discriminants.test.js +77 -20
- package/dist/frontend/union-discriminants.test.js.map +1 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.js +150 -81
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +95 -38
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +91 -15
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/api.d.ts +4 -0
- package/dist/ir/api.js +6 -0
- package/dist/ir/api.js.map +1 -0
- package/dist/ir/build.d.ts +7 -0
- package/dist/ir/build.js +27 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.d.ts +9 -0
- package/dist/ir/builtin-effects.js +631 -0
- package/dist/ir/builtin-effects.js.map +1 -0
- package/dist/ir/builtin-signatures.d.ts +15 -0
- package/dist/ir/builtin-signatures.js +3396 -0
- package/dist/ir/builtin-signatures.js.map +1 -0
- package/dist/ir/byte-numbers.js +67 -16
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/byte-numbers.test.js +17 -4
- package/dist/ir/byte-numbers.test.js.map +1 -1
- package/dist/ir/constant-tables.js +13 -5
- package/dist/ir/constant-tables.js.map +1 -1
- package/dist/ir/constant-tables.test.js +47 -7
- package/dist/ir/constant-tables.test.js.map +1 -1
- package/dist/ir/control-flow.js +2 -1
- package/dist/ir/control-flow.js.map +1 -1
- package/dist/ir/control-flow.test.js +35 -11
- package/dist/ir/control-flow.test.js.map +1 -1
- package/dist/ir/initializer-bindings.d.ts +9 -0
- package/dist/ir/initializer-bindings.js +115 -0
- package/dist/ir/initializer-bindings.js.map +1 -0
- package/dist/ir/initializer-bindings.test.d.ts +1 -0
- package/dist/ir/initializer-bindings.test.js +118 -0
- package/dist/ir/initializer-bindings.test.js.map +1 -0
- package/dist/ir/integer-loop-facts.d.ts +12 -0
- package/dist/ir/integer-loop-facts.js +137 -0
- package/dist/ir/integer-loop-facts.js.map +1 -0
- package/dist/ir/integer-loops.js +85 -30
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +76 -13
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.js +93 -21
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +199 -21
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.d.ts +20 -0
- package/dist/ir/intrinsic-signatures.js +57 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -0
- package/dist/ir/ir.d.ts +6 -2150
- package/dist/ir/ir.js +160 -1396
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +98 -77
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +221 -0
- package/dist/ir/runtime-features.js +551 -0
- package/dist/ir/runtime-features.js.map +1 -0
- package/dist/ir/runtime-features.test.d.ts +1 -0
- package/dist/ir/runtime-features.test.js +98 -0
- package/dist/ir/runtime-features.test.js.map +1 -0
- package/dist/ir/scalar-records.js +130 -40
- package/dist/ir/scalar-records.js.map +1 -1
- package/dist/ir/scalar-records.test.js +146 -27
- package/dist/ir/scalar-records.test.js.map +1 -1
- package/dist/ir/serialize.js +4 -2
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +44 -9
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/traverse.js +156 -43
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +99 -24
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/validate.d.ts +1 -31
- package/dist/ir/validate.js +782 -1889
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +610 -114
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/cache-primitives.js +9 -10
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/cache-reset.test.js +2 -1
- package/dist/library/cache-reset.test.js.map +1 -1
- package/dist/library/compiler-self-identity.js +11 -5
- package/dist/library/compiler-self-identity.js.map +1 -1
- package/dist/library/compiler-self-identity.test.js +10 -3
- package/dist/library/compiler-self-identity.test.js.map +1 -1
- package/dist/library/fence-eval.js +24 -7
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/fence-eval.test.js +31 -7
- package/dist/library/fence-eval.test.js.map +1 -1
- package/dist/library/int-infer.js +199 -59
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +133 -57
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/ir-policy.d.ts +27 -0
- package/dist/library/ir-policy.js +232 -0
- package/dist/library/ir-policy.js.map +1 -0
- package/dist/library/library-cache.js +40 -17
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +24 -13
- package/dist/library/library-cache.test.js.map +1 -1
- package/dist/library/library-profile.js +68 -13
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +48 -20
- package/dist/library/prepare.js.map +1 -1
- package/dist/library/semantic-source.js +16 -14
- package/dist/library/semantic-source.js.map +1 -1
- package/dist/library/semantic-source.test.js +9 -14
- package/dist/library/semantic-source.test.js.map +1 -1
- package/dist/library/sidecar-validate.js +53 -12
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.js +85 -24
- package/dist/library/sidecar.js.map +1 -1
- package/dist/library/trap-teaching.js +11 -2
- package/dist/library/trap-teaching.js.map +1 -1
- package/dist/native/cache.js +10 -4
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cli.js +34 -9
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +167 -43
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +129 -32
- package/dist/native/compiler.test.js.map +1 -1
- package/dist/native/comptime.js +23 -7
- package/dist/native/comptime.js.map +1 -1
- package/dist/native/comptime.test.js +26 -6
- package/dist/native/comptime.test.js.map +1 -1
- package/dist/native/executable-cache.js +77 -27
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/executable-cache.test.js +41 -6
- package/dist/native/executable-cache.test.js.map +1 -1
- package/dist/native/file-identity.js +9 -2
- package/dist/native/file-identity.js.map +1 -1
- package/dist/native/file-identity.test.js.map +1 -1
- package/dist/native/library.js +50 -12
- package/dist/native/library.js.map +1 -1
- package/dist/native/prepare.js +119 -34
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +22 -6
- package/dist/native/prepare.test.js.map +1 -1
- package/dist/native/runtime-typescript.js +24 -11
- package/dist/native/runtime-typescript.js.map +1 -1
- package/dist/native/runtime-typescript.test.js.map +1 -1
- package/dist/native/sanitizer.js +71 -18
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/sanitizer.test.js +77 -20
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/task.js.map +1 -1
- package/dist/native/task.test.js +7 -2
- package/dist/native/task.test.js.map +1 -1
- package/dist/native/toolchain.js +68 -26
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +59 -20
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -1
- package/dist/startup-cache.js +1 -1
- package/dist/startup-cache.js.map +1 -1
- package/dist/timing.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +0 -601
- package/dist/frontend/lowering/lower-builtins.js +0 -8986
- package/dist/frontend/lowering/lower-builtins.js.map +0 -1
- package/dist/frontend/lowering/lower-containers.d.ts +0 -382
- package/dist/frontend/lowering/lower-containers.js +0 -7344
- package/dist/frontend/lowering/lower-containers.js.map +0 -1
|
@@ -0,0 +1,1854 @@
|
|
|
1
|
+
import { boolLit, countedFor, numLit, strLit, varRef } from "../../../ir/build.js";
|
|
2
|
+
import { InternalCompilerError } from "../../../errors.js";
|
|
3
|
+
import * as ts from "../../ts7/adapter.js";
|
|
4
|
+
import { BOOL, DYN, F64, JSVAL, STRING, UNDEFINED_T, arrayOf, isRefCounted, isUnitType, typeEquals, } from "../../../ir/ir.js";
|
|
5
|
+
import { ARRAY_METHODS } from "../surfaces.js";
|
|
6
|
+
import { tryLowerExpression } from "../expressions/try-lower-expression.js";
|
|
7
|
+
import { isJsSourceFile, locOf } from "../../program.js";
|
|
8
|
+
import { islandPrimitiveExit, lowerDynDispatchMethodCall } from "../lower-calls.js";
|
|
9
|
+
import { arrayIndexPresent, arrayValueRead, arrayValueStore, arrayValueType, } from "../array-values.js";
|
|
10
|
+
import { typeKey } from "../../type-mapper.js";
|
|
11
|
+
import { defaultAfterUndefined, lowerPositionArgument, lowerStaticallyUndefinedArgument, positionNumber, } from "../optional-arguments.js";
|
|
12
|
+
import { lowerArrayCopyWithin, lowerArrayFill } from "../array-indexed-mutation.js";
|
|
13
|
+
import { lowerArrayUnionHofCall, lowerArraySortCall, lowerArrayHofCall, lowerArrayFindLikeCall, lowerArrayFlatMapCall, lowerArrayReduceCall, } from "./array-callbacks.js";
|
|
14
|
+
import { lowerArraySpreadItems, lowerArrayValueItems } from "./array-construction.js";
|
|
15
|
+
import { arrayLengthDeclaration } from "./array-iteration.js";
|
|
16
|
+
import { lowerArrayCallback, callbackArrayElement, requireProducedArrayElement, } from "./callback-arguments.js";
|
|
17
|
+
function primitivePositionType(lowerer, type) {
|
|
18
|
+
if (type.kind === "union") {
|
|
19
|
+
return (lowerer.unions.get(type.unionId)?.arms.every((arm) => primitivePositionType(lowerer, arm)) ??
|
|
20
|
+
false);
|
|
21
|
+
}
|
|
22
|
+
return (type.kind === "f64" ||
|
|
23
|
+
type.kind === "string" ||
|
|
24
|
+
type.kind === "bool" ||
|
|
25
|
+
type.kind === "nullT" ||
|
|
26
|
+
type.kind === "undefinedT");
|
|
27
|
+
}
|
|
28
|
+
function lowerArrayPosition(lowerer, node, defaultValue, subject) {
|
|
29
|
+
if (!node)
|
|
30
|
+
return defaultValue;
|
|
31
|
+
if (ts.isSpreadElement(node))
|
|
32
|
+
lowerer.noLowering(`${subject} with a spread argument`, node);
|
|
33
|
+
const value = lowerPositionArgument(lowerer, node, defaultValue);
|
|
34
|
+
if (!primitivePositionType(lowerer, value.type)) {
|
|
35
|
+
lowerer.noLowering(`${subject} of '${lowerer.fmt(value.type)}' values`, node);
|
|
36
|
+
}
|
|
37
|
+
const loc = locOf(node);
|
|
38
|
+
const local = lowerer.declareHiddenLocal("%arrayPosition", value.type);
|
|
39
|
+
const ref = varRef(local.id, value.type, loc);
|
|
40
|
+
return {
|
|
41
|
+
kind: "seqExpr",
|
|
42
|
+
stmts: [{ kind: "varDecl", localId: local.id, init: value, loc }],
|
|
43
|
+
result: positionNumber(lowerer, ref, defaultValue, node, subject),
|
|
44
|
+
type: F64,
|
|
45
|
+
loc,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function lowerArrayJoinSeparator(lowerer, node, loc) {
|
|
49
|
+
const comma = strLit(",", loc);
|
|
50
|
+
if (!node)
|
|
51
|
+
return comma;
|
|
52
|
+
const undefinedValue = lowerStaticallyUndefinedArgument(lowerer, node);
|
|
53
|
+
if (undefinedValue)
|
|
54
|
+
return defaultAfterUndefined(undefinedValue, comma);
|
|
55
|
+
const value = lowerer.lowerExpr(node);
|
|
56
|
+
if (value.type.kind === "nullT")
|
|
57
|
+
return defaultAfterUndefined(value, strLit("null", loc));
|
|
58
|
+
if (value.type.kind === "union") {
|
|
59
|
+
const undefinedTag = lowerer.armTag(value.type.unionId, UNDEFINED_T);
|
|
60
|
+
if (undefinedTag >= 0) {
|
|
61
|
+
const local = lowerer.declareHiddenLocal("%joinSeparator", value.type);
|
|
62
|
+
const ref = varRef(local.id, value.type, loc);
|
|
63
|
+
return {
|
|
64
|
+
kind: "seqExpr",
|
|
65
|
+
stmts: [{ kind: "varDecl", localId: local.id, init: value, loc }],
|
|
66
|
+
result: {
|
|
67
|
+
kind: "ternary",
|
|
68
|
+
cond: {
|
|
69
|
+
kind: "unionIsTag",
|
|
70
|
+
unionId: value.type.unionId,
|
|
71
|
+
tag: undefinedTag,
|
|
72
|
+
value: ref,
|
|
73
|
+
negated: false,
|
|
74
|
+
type: BOOL,
|
|
75
|
+
loc,
|
|
76
|
+
},
|
|
77
|
+
then: comma,
|
|
78
|
+
else_: lowerer.ensureString(ref, node),
|
|
79
|
+
type: STRING,
|
|
80
|
+
loc,
|
|
81
|
+
},
|
|
82
|
+
type: STRING,
|
|
83
|
+
loc,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (value.type.kind === "dyn" || value.type.kind === "jsval") {
|
|
88
|
+
lowerer.noLowering(".join separator with a runtime-dependent undefined value", node);
|
|
89
|
+
}
|
|
90
|
+
return lowerer.ensureString(value, node);
|
|
91
|
+
}
|
|
92
|
+
/** Ambient array method calls. `push`/`unshift`/`pop`/`reverse`/
|
|
93
|
+
* `indexOf`/`includes`/`join`
|
|
94
|
+
* lower to arrIntrinsic; the HOF family — `map`/`filter`/`forEach`/
|
|
95
|
+
* `find`/`some`/`every`/`flatMap`/`reduce`/`reduceRight` — desugars to a
|
|
96
|
+
* direct call of a synthetic loop function (see lowerArrayHofCall and
|
|
97
|
+
* friends). Null when this isn't an ambient array method call. tsc has
|
|
98
|
+
* already checked arity and argument types against ambient/scriptc.d.ts. */
|
|
99
|
+
export function lowerArrayMethodCall(lowerer, call, access) {
|
|
100
|
+
if (lowerer.chainBlocked(access, call))
|
|
101
|
+
return null;
|
|
102
|
+
const name = access.name.text;
|
|
103
|
+
if (!ARRAY_METHODS.has(name) && name !== "sort" && name !== "shift" && name !== "splice")
|
|
104
|
+
return null;
|
|
105
|
+
let receiverIr = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
106
|
+
const checkerReceiver = lowerer.checker.getTypeAtLocation(access.expression);
|
|
107
|
+
const implicitArrayReceiver = receiverIr?.kind === "array" &&
|
|
108
|
+
(checkerReceiver.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown) ||
|
|
109
|
+
lowerer.checkerAnyArrayType(checkerReceiver));
|
|
110
|
+
// A checker-`any[]` receiver (the readonly-array Array.isArray quirk)
|
|
111
|
+
// whose VALUE lowers to a real static array (maybeNarrow's isArray
|
|
112
|
+
// bridge): ride the ordinary tables on the lowered element type — the
|
|
113
|
+
// dyn-receiver string precedent (re-lowering is pure IR construction).
|
|
114
|
+
// A checker-untyped receiver has no stdlib-declared member symbol, so
|
|
115
|
+
// the isStdlibMember gate is skipped for probed receivers (nothing
|
|
116
|
+
// user-declared can shadow a method on a value the checker calls any).
|
|
117
|
+
let probedUntyped = false;
|
|
118
|
+
if (implicitArrayReceiver)
|
|
119
|
+
probedUntyped = true;
|
|
120
|
+
if ((receiverIr === null ||
|
|
121
|
+
receiverIr.kind === "dyn" ||
|
|
122
|
+
(receiverIr.kind === "array" && receiverIr.elem.kind === "dyn")) &&
|
|
123
|
+
(lowerer.checkerAnyArray(access.expression) ||
|
|
124
|
+
// A checker-`any` CHAIN whose value lowers to a real static array
|
|
125
|
+
// (`context.stack.split('\n').slice(2)` — the dyn-receiver string
|
|
126
|
+
// machinery answered string[]): same rule, any-typed spelling.
|
|
127
|
+
((lowerer.typeOf(access.expression).flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !==
|
|
128
|
+
0 &&
|
|
129
|
+
isJsSourceFile(access.getSourceFile())))) {
|
|
130
|
+
const probe = lowerer.lowerExpr(access.expression);
|
|
131
|
+
if (probe.type.kind === "array") {
|
|
132
|
+
receiverIr = probe.type;
|
|
133
|
+
probedUntyped = true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (receiverIr?.kind === "union") {
|
|
137
|
+
const unionHof = lowerArrayUnionHofCall(lowerer, call, access, receiverIr);
|
|
138
|
+
if (unionHof)
|
|
139
|
+
return unionHof;
|
|
140
|
+
}
|
|
141
|
+
if (receiverIr?.kind !== "array")
|
|
142
|
+
return null;
|
|
143
|
+
if (!probedUntyped && !lowerer.isStdlibMember(access))
|
|
144
|
+
return null;
|
|
145
|
+
let elem = receiverIr.elem;
|
|
146
|
+
const loc = locOf(call);
|
|
147
|
+
// An island handle behind an array-typed .d.ts surface
|
|
148
|
+
// (`parts().join("-")` — arrays never exit eagerly, so the value
|
|
149
|
+
// stays jsval): the ENGINE's own Array.prototype method runs on the
|
|
150
|
+
// engine array — every declared call form (fromIndex, comparators
|
|
151
|
+
// and HOF callbacks as marshaled host functions), Node-exact by
|
|
152
|
+
// construction, with the declared-primitive result exit. Never a
|
|
153
|
+
// static arrIntrinsic over a jsval (the validator ICE).
|
|
154
|
+
{
|
|
155
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
156
|
+
if (receiver.type.kind === "union") {
|
|
157
|
+
const arms = lowerer.unions.get(receiver.type.unionId)?.arms;
|
|
158
|
+
const present = arms?.find((arm) => arm.kind === "array");
|
|
159
|
+
if (present?.kind === "array" &&
|
|
160
|
+
arms?.every((arm) => typeEquals(arm, present) || isUnitType(arm))) {
|
|
161
|
+
// A predicate can narrow the element type without changing the
|
|
162
|
+
// original array layout. Extract that stored array before choosing
|
|
163
|
+
// a helper, then adapt callback arguments at their actual ABI.
|
|
164
|
+
const array = lowerer.runtimeOptionalPropertyReceiver(access.expression, receiver, present, name) ??
|
|
165
|
+
lowerer.coerceInto(access.expression, receiver, present);
|
|
166
|
+
return lowerer.withExpressionOverride(access.expression, array, () => lowerArrayMethodCall(lowerer, call, access));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (receiver.type.kind === "record" && lowerer.shapes.get(receiver.type.shapeId)?.tuple) {
|
|
170
|
+
return lowerTupleReadMethodCall(lowerer, call, access, receiver);
|
|
171
|
+
}
|
|
172
|
+
if (receiver.type.kind === "jsval") {
|
|
173
|
+
const loweredArgs = call.arguments.map((a) => lowerer.lowerExpr(a));
|
|
174
|
+
if (name === "filter" &&
|
|
175
|
+
loweredArgs[0]?.type.kind === "func" &&
|
|
176
|
+
loweredArgs[0].type.ret.kind === "void") {
|
|
177
|
+
lowerer.unsupported("SC1090", call.arguments[0], "'.filter()' with a void-returning predicate (the callback return value is erased before its truthiness can be tested)");
|
|
178
|
+
}
|
|
179
|
+
const args = loweredArgs.map((arg, i) => lowerer.jsvalIn(arg, call.arguments[i]));
|
|
180
|
+
const result = {
|
|
181
|
+
kind: "jsOp",
|
|
182
|
+
op: "callMethod",
|
|
183
|
+
name,
|
|
184
|
+
args: [receiver, ...args],
|
|
185
|
+
type: JSVAL,
|
|
186
|
+
loc,
|
|
187
|
+
};
|
|
188
|
+
return islandPrimitiveExit(lowerer, call, result);
|
|
189
|
+
}
|
|
190
|
+
// An array-mapped CHECKER type whose VALUE lives in the checked-dynamic tree
|
|
191
|
+
// (`Object.keys(dynObj).sort()` — the key-walk answers a dyn array):
|
|
192
|
+
// the record family's array sibling. Methods with a runtime
|
|
193
|
+
// receiver-kind dispatch ride dynInvoke — the real method runs on
|
|
194
|
+
// the dyn array, JS-exact; the rest keep an honest fence instead of
|
|
195
|
+
// handing a static array intrinsic a dyn receiver (the validator
|
|
196
|
+
// ICE). Consumers validate the dyn result where a static type is
|
|
197
|
+
// required (dynCheck — the member-read discipline).
|
|
198
|
+
if (receiver.type.kind === "dyn") {
|
|
199
|
+
const dispatched = lowerDynDispatchMethodCall(lowerer, call, access, receiver, true);
|
|
200
|
+
if (dispatched)
|
|
201
|
+
return dispatched;
|
|
202
|
+
lowerer.noLowering(`.${name} on an array value held in a checked-dynamic binding`, call, "assign it to an array-typed binding first (the validated extraction), then call the method");
|
|
203
|
+
}
|
|
204
|
+
// Flow predicates and evolving-any analysis can refine the checker
|
|
205
|
+
// element type without changing the array's storage. Helpers and
|
|
206
|
+
// callback array arguments must retain the original layout and
|
|
207
|
+
// identity; element conversions happen at the callback boundary.
|
|
208
|
+
if (receiver.type.kind === "array" && !typeEquals(receiverIr, receiver.type)) {
|
|
209
|
+
receiverIr = receiver.type;
|
|
210
|
+
elem = receiver.type.elem;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (name === "sort" || name === "toSorted") {
|
|
214
|
+
return lowerArraySortCall(lowerer, call, access, elem, receiverIr);
|
|
215
|
+
}
|
|
216
|
+
if (name === "toReversed") {
|
|
217
|
+
if (call.arguments.length !== 0) {
|
|
218
|
+
lowerer.noLowering(`.toReversed with ${call.arguments.length} arguments`, call);
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
kind: "arrIntrinsic",
|
|
222
|
+
method: "toReversed",
|
|
223
|
+
receiver: lowerer.lowerExpr(access.expression),
|
|
224
|
+
args: [],
|
|
225
|
+
type: receiverIr,
|
|
226
|
+
loc,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
if (name === "reverse") {
|
|
230
|
+
if (call.arguments.length !== 0) {
|
|
231
|
+
lowerer.noLowering(`.reverse with ${call.arguments.length} arguments`, call);
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
kind: "arrIntrinsic",
|
|
235
|
+
method: "reverse",
|
|
236
|
+
receiver: lowerer.lowerExpr(access.expression),
|
|
237
|
+
args: [],
|
|
238
|
+
type: receiverIr,
|
|
239
|
+
loc,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
if (name === "fill") {
|
|
243
|
+
if (call.arguments.length > 3 || call.arguments.some(ts.isSpreadElement)) {
|
|
244
|
+
lowerer.noLowering(`.fill with ${call.arguments.length} arguments`, call);
|
|
245
|
+
}
|
|
246
|
+
const value = call.arguments[0] ? lowerer.lowerExpr(call.arguments[0]) : null;
|
|
247
|
+
if (value &&
|
|
248
|
+
(value.type.kind === "dyn" || value.type.kind === "jsval") &&
|
|
249
|
+
isRefCounted(elem) &&
|
|
250
|
+
elem.kind !== "string" &&
|
|
251
|
+
!typeEquals(value.type, elem)) {
|
|
252
|
+
lowerer.noLowering(".fill of a checked-dynamic reference into a static array", call.arguments[0]);
|
|
253
|
+
}
|
|
254
|
+
const writeUndefined = value === null || value.type.kind === "undefinedT" || value.type.kind === "void";
|
|
255
|
+
return lowerArrayFill(lowerer, lowerer.lowerExpr(access.expression), value, writeUndefined, lowerArrayPosition(lowerer, call.arguments[1], numLit(0, loc), "array fill start"), lowerArrayPosition(lowerer, call.arguments[2], numLit(Infinity, loc), "array fill end"), receiverIr, loc);
|
|
256
|
+
}
|
|
257
|
+
if (name === "copyWithin") {
|
|
258
|
+
if (call.arguments.length > 3 || call.arguments.some(ts.isSpreadElement)) {
|
|
259
|
+
lowerer.noLowering(`.copyWithin with ${call.arguments.length} arguments`, call);
|
|
260
|
+
}
|
|
261
|
+
return lowerArrayCopyWithin(lowerer.lowerExpr(access.expression), lowerArrayPosition(lowerer, call.arguments[0], numLit(0, loc), "array copyWithin target"), lowerArrayPosition(lowerer, call.arguments[1], numLit(0, loc), "array copyWithin start"), lowerArrayPosition(lowerer, call.arguments[2], numLit(Infinity, loc), "array copyWithin end"), receiverIr, loc);
|
|
262
|
+
}
|
|
263
|
+
if (name === "with") {
|
|
264
|
+
if (call.arguments.length !== 2 || call.arguments.some(ts.isSpreadElement)) {
|
|
265
|
+
lowerer.noLowering(`.with with ${call.arguments.length} arguments`, call);
|
|
266
|
+
}
|
|
267
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
268
|
+
const index = lowerPositionArgument(lowerer, call.arguments[0], numLit(0, loc));
|
|
269
|
+
if (!primitivePositionType(lowerer, index.type)) {
|
|
270
|
+
lowerer.noLowering(`.with index of '${lowerer.fmt(index.type)}' values`, call.arguments[0]);
|
|
271
|
+
}
|
|
272
|
+
const value = lowerer.lowerExpr(call.arguments[1]);
|
|
273
|
+
const receiverLocal = lowerer.declareHiddenLocal("%withRecv", receiverIr);
|
|
274
|
+
const indexLocal = lowerer.declareHiddenLocal("%withIndex", index.type);
|
|
275
|
+
const valueLocal = lowerer.declareHiddenLocal("%withValue", value.type);
|
|
276
|
+
const receiverRef = varRef(receiverLocal.id, receiverIr, loc);
|
|
277
|
+
const indexRef = varRef(indexLocal.id, index.type, loc);
|
|
278
|
+
const valueRef = varRef(valueLocal.id, value.type, loc);
|
|
279
|
+
const numericIndex = positionNumber(lowerer, indexRef, numLit(0, loc), call.arguments[0], "array with index");
|
|
280
|
+
const stmts = [
|
|
281
|
+
{ kind: "varDecl", localId: receiverLocal.id, init: receiver, loc },
|
|
282
|
+
{ kind: "varDecl", localId: indexLocal.id, init: index, loc },
|
|
283
|
+
{ kind: "varDecl", localId: valueLocal.id, init: value, loc },
|
|
284
|
+
];
|
|
285
|
+
if (value.type.kind === "union" && lowerer.runtimeOptionalWidening(value.type, elem) !== null) {
|
|
286
|
+
// `.with()` validates its index and returns a fresh copy. Stabilize
|
|
287
|
+
// all three operands, then select the scalar replacement or the
|
|
288
|
+
// present-undefined copy without evaluating a read twice.
|
|
289
|
+
const unionId = value.type.unionId;
|
|
290
|
+
const undefTag = lowerer.armTag(unionId, UNDEFINED_T);
|
|
291
|
+
const condition = {
|
|
292
|
+
kind: "unionIsTag",
|
|
293
|
+
unionId,
|
|
294
|
+
tag: undefTag,
|
|
295
|
+
negated: false,
|
|
296
|
+
value: valueRef,
|
|
297
|
+
type: BOOL,
|
|
298
|
+
loc,
|
|
299
|
+
};
|
|
300
|
+
const missing = {
|
|
301
|
+
kind: "arrIntrinsic",
|
|
302
|
+
method: "withUndefined",
|
|
303
|
+
receiver: receiverRef,
|
|
304
|
+
args: [numericIndex],
|
|
305
|
+
type: receiverIr,
|
|
306
|
+
loc,
|
|
307
|
+
};
|
|
308
|
+
const present = {
|
|
309
|
+
kind: "arrIntrinsic",
|
|
310
|
+
method: "with",
|
|
311
|
+
receiver: receiverRef,
|
|
312
|
+
args: [numericIndex, lowerer.coerceToExpected(valueRef, elem)],
|
|
313
|
+
type: receiverIr,
|
|
314
|
+
loc,
|
|
315
|
+
};
|
|
316
|
+
return {
|
|
317
|
+
kind: "seqExpr",
|
|
318
|
+
stmts,
|
|
319
|
+
result: {
|
|
320
|
+
kind: "ternary",
|
|
321
|
+
cond: condition,
|
|
322
|
+
then: missing,
|
|
323
|
+
else_: present,
|
|
324
|
+
type: receiverIr,
|
|
325
|
+
loc,
|
|
326
|
+
},
|
|
327
|
+
type: receiverIr,
|
|
328
|
+
loc,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
const coercedValue = lowerer.coerceInto(call.arguments[1], valueRef, elem);
|
|
332
|
+
return {
|
|
333
|
+
kind: "seqExpr",
|
|
334
|
+
stmts,
|
|
335
|
+
result: {
|
|
336
|
+
kind: "arrIntrinsic",
|
|
337
|
+
method: "with",
|
|
338
|
+
receiver: receiverRef,
|
|
339
|
+
args: [numericIndex, coercedValue],
|
|
340
|
+
type: receiverIr,
|
|
341
|
+
loc,
|
|
342
|
+
},
|
|
343
|
+
type: receiverIr,
|
|
344
|
+
loc,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
if (name === "toSpliced") {
|
|
348
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
349
|
+
const start = lowerArrayPosition(lowerer, call.arguments[0], numLit(0, loc), "array toSpliced start");
|
|
350
|
+
const deleteCount = lowerArrayPosition(lowerer, call.arguments[1], numLit(call.arguments.length === 1 ? Infinity : 0, loc), "array toSpliced deleteCount");
|
|
351
|
+
const itemNodes = call.arguments.slice(2);
|
|
352
|
+
const hasSpread = itemNodes.some(ts.isSpreadElement);
|
|
353
|
+
const itemProbes = hasSpread ? [] : itemNodes.map((arg) => tryLowerExpression(lowerer, arg));
|
|
354
|
+
const statefulItems = itemProbes.some((probe) => probe !== null && lowerer.runtimeOptionalWidening(probe.type, elem) !== null);
|
|
355
|
+
const items = hasSpread
|
|
356
|
+
? lowerArraySpreadItems(lowerer, itemNodes, elem, receiverIr, loc)
|
|
357
|
+
: statefulItems
|
|
358
|
+
? lowerArrayValueItems(lowerer, itemNodes.map((arg) => lowerer.lowerExpr(arg)), elem, receiverIr, loc)
|
|
359
|
+
: {
|
|
360
|
+
kind: "arrayLit",
|
|
361
|
+
elems: itemNodes.map((arg) => lowerer.coerceInto(arg, lowerer.lowerExpr(arg), elem)),
|
|
362
|
+
type: receiverIr,
|
|
363
|
+
loc,
|
|
364
|
+
};
|
|
365
|
+
return {
|
|
366
|
+
kind: "arrIntrinsic",
|
|
367
|
+
method: "toSpliced",
|
|
368
|
+
receiver,
|
|
369
|
+
args: [start, deleteCount, items],
|
|
370
|
+
type: receiverIr,
|
|
371
|
+
loc,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
if (name === "flat")
|
|
375
|
+
return lowerArrayFlatCall(lowerer, call, access, receiverIr);
|
|
376
|
+
// The lib declares wider call forms than the lowered surface — the
|
|
377
|
+
// predicate/mapping HOFs take a thisArg. Each unlowered form is fenced
|
|
378
|
+
// per site (SC2020), never silently truncated to the supported
|
|
379
|
+
// arguments. push/unshift lower every declared form (variadic, 0 args
|
|
380
|
+
// included — Node returns the unchanged length); reduce/reduceRight
|
|
381
|
+
// lower both declared forms (with and without an initial value).
|
|
382
|
+
const arity = {
|
|
383
|
+
push: [0, Number.MAX_SAFE_INTEGER],
|
|
384
|
+
unshift: [0, Number.MAX_SAFE_INTEGER],
|
|
385
|
+
pop: [0, 0],
|
|
386
|
+
indexOf: [1, 2],
|
|
387
|
+
lastIndexOf: [1, 2],
|
|
388
|
+
includes: [0, 2],
|
|
389
|
+
join: [0, 1],
|
|
390
|
+
concat: [0, Number.MAX_SAFE_INTEGER],
|
|
391
|
+
slice: [0, 2],
|
|
392
|
+
shift: [0, 0],
|
|
393
|
+
splice: [0, Number.MAX_SAFE_INTEGER],
|
|
394
|
+
at: [0, 1],
|
|
395
|
+
map: [1, 1],
|
|
396
|
+
filter: [1, 1],
|
|
397
|
+
forEach: [1, 1],
|
|
398
|
+
find: [1, 1],
|
|
399
|
+
findIndex: [1, 1],
|
|
400
|
+
some: [1, 1],
|
|
401
|
+
findLast: [1, 1],
|
|
402
|
+
findLastIndex: [1, 1],
|
|
403
|
+
every: [1, 1],
|
|
404
|
+
flatMap: [1, 1],
|
|
405
|
+
reduce: [1, 2],
|
|
406
|
+
reduceRight: [1, 2],
|
|
407
|
+
}[name];
|
|
408
|
+
if (call.arguments.length < arity[0] || call.arguments.length > arity[1]) {
|
|
409
|
+
const hint = name === "map" ||
|
|
410
|
+
name === "filter" ||
|
|
411
|
+
name === "forEach" ||
|
|
412
|
+
name === "find" ||
|
|
413
|
+
name === "some" ||
|
|
414
|
+
name === "every" ||
|
|
415
|
+
name === "flatMap"
|
|
416
|
+
? "the thisArg parameter has no lowering — use an arrow function"
|
|
417
|
+
: undefined;
|
|
418
|
+
lowerer.noLowering(`.${name} with ${call.arguments.length} argument${call.arguments.length === 1 ? "" : "s"}`, call, hint);
|
|
419
|
+
}
|
|
420
|
+
if (name === "push" || name === "unshift") {
|
|
421
|
+
let receiver = lowerer.lowerExpr(access.expression);
|
|
422
|
+
if (receiver.type.kind === "union" && lowerer.armTag(receiver.type.unionId, UNDEFINED_T) >= 0) {
|
|
423
|
+
const present = lowerer.stripUndefinedArm(receiver.type);
|
|
424
|
+
const helper = present.kind === "array"
|
|
425
|
+
? lowerer.narrowedArmHelper(receiver.type.unionId, present, loc)
|
|
426
|
+
: null;
|
|
427
|
+
receiver = helper
|
|
428
|
+
? { kind: "call", callee: helper, args: [receiver], type: present, loc }
|
|
429
|
+
: lowerer.maybeNarrow(receiver, access.expression);
|
|
430
|
+
}
|
|
431
|
+
// `a.push(...src)` / `a.unshift(...src)`: copy src's elements in
|
|
432
|
+
// order (count snapshotted first, so the self-spread forms duplicate
|
|
433
|
+
// like JS) and return the new length.
|
|
434
|
+
const spreadArg = call.arguments.length === 1 && ts.isSpreadElement(call.arguments[0])
|
|
435
|
+
? call.arguments[0]
|
|
436
|
+
: null;
|
|
437
|
+
if ((name === "push" || name === "unshift") && spreadArg && ts.isSpreadElement(spreadArg)) {
|
|
438
|
+
let src = lowerer.lowerExpr(spreadArg.expression);
|
|
439
|
+
// `a.push(...someSet)` / `a.unshift(...someSet)`: a same-element Set drains first
|
|
440
|
+
// (setIntrinsic toArray — insertion order), then appends.
|
|
441
|
+
if (src.type.kind === "set" && typeEquals(src.type.elem, elem)) {
|
|
442
|
+
src = {
|
|
443
|
+
kind: "setIntrinsic",
|
|
444
|
+
method: "toArray",
|
|
445
|
+
receiver: src,
|
|
446
|
+
args: [],
|
|
447
|
+
type: arrayOf(src.type.elem),
|
|
448
|
+
loc,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
if (!typeEquals(src.type, receiverIr)) {
|
|
452
|
+
lowerer.unsupported("SC1090", spreadArg, `${name === "push" ? "pushing" : "unshifting"} a spread of '${lowerer.fmt(src.type)}' onto a '${lowerer.fmt(receiverIr)}' array (only a same-element-type array spreads)`);
|
|
453
|
+
}
|
|
454
|
+
return {
|
|
455
|
+
kind: "arrIntrinsic",
|
|
456
|
+
method: name === "push" ? "pushSpread" : "unshiftSpread",
|
|
457
|
+
receiver,
|
|
458
|
+
args: [src],
|
|
459
|
+
type: F64,
|
|
460
|
+
loc,
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
if (call.arguments.some(ts.isSpreadElement)) {
|
|
464
|
+
// Finish argument evaluation before mutating the receiver. Each
|
|
465
|
+
// spread snapshots its elements immediately, so a later argument
|
|
466
|
+
// can mutate that source without changing already-collected values.
|
|
467
|
+
const items = lowerArraySpreadItems(lowerer, call.arguments, elem, receiverIr, loc);
|
|
468
|
+
return {
|
|
469
|
+
kind: "arrIntrinsic",
|
|
470
|
+
method: name === "push" ? "pushSpread" : "unshiftSpread",
|
|
471
|
+
receiver,
|
|
472
|
+
args: [items],
|
|
473
|
+
type: F64,
|
|
474
|
+
loc,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
const valueProbes = call.arguments.map((arg) => tryLowerExpression(lowerer, arg));
|
|
478
|
+
if (valueProbes.some((probe) => probe !== null && lowerer.runtimeOptionalWidening(probe.type, elem) !== null)) {
|
|
479
|
+
const items = lowerArrayValueItems(lowerer, call.arguments.map((arg) => lowerer.lowerExpr(arg)), elem, receiverIr, loc);
|
|
480
|
+
return {
|
|
481
|
+
kind: "arrIntrinsic",
|
|
482
|
+
method: name === "push" ? "pushSpread" : "unshiftSpread",
|
|
483
|
+
receiver,
|
|
484
|
+
args: [items],
|
|
485
|
+
type: F64,
|
|
486
|
+
loc,
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
// Inserted values flow into the element slot like an assignment would:
|
|
490
|
+
// union-element arrays wrap plain arm values (coerceInto is inert
|
|
491
|
+
// when the types already agree).
|
|
492
|
+
const args = call.arguments.map((a) => name === "push" || name === "unshift"
|
|
493
|
+
? lowerer.lowerExprExpecting(a, elem)
|
|
494
|
+
: lowerer.lowerExpr(a));
|
|
495
|
+
return {
|
|
496
|
+
kind: "arrIntrinsic",
|
|
497
|
+
method: name,
|
|
498
|
+
receiver,
|
|
499
|
+
args,
|
|
500
|
+
type: F64,
|
|
501
|
+
loc,
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
if (name === "pop") {
|
|
505
|
+
// Widen a union payload through the normal array-read machinery
|
|
506
|
+
// before removing it. Reinterpreting the stored union's tag as the
|
|
507
|
+
// result union would confuse arms when undefined changes their order.
|
|
508
|
+
if (elem.kind === "union" && lowerer.armTag(elem.unionId, UNDEFINED_T) < 0) {
|
|
509
|
+
return lowerUnionArrayRemoval(lowerer, access.expression, elem, false, loc);
|
|
510
|
+
}
|
|
511
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
512
|
+
return {
|
|
513
|
+
kind: "arrIntrinsic",
|
|
514
|
+
method: "pop",
|
|
515
|
+
receiver,
|
|
516
|
+
args: [],
|
|
517
|
+
type: arrayValueType(lowerer, elem),
|
|
518
|
+
loc,
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
if (name === "indexOf" || name === "lastIndexOf" || name === "includes") {
|
|
522
|
+
return lowerArraySearchCall(lowerer, call, access, name, elem);
|
|
523
|
+
}
|
|
524
|
+
if (name === "concat") {
|
|
525
|
+
// `a.concat(x, ys, ...)` — a fresh array of a's elements followed by
|
|
526
|
+
// each argument in order: JS spreads array arguments one level
|
|
527
|
+
// (IsArray, never deeper) and appends plain values. Each argument is
|
|
528
|
+
// either an ELEMENT (pushed) or a SAME-ELEMENT ARRAY (spread) —
|
|
529
|
+
// decided by its static type, which matches IsArray exactly here
|
|
530
|
+
// because the two kinds map differently. The one ambiguous corner —
|
|
531
|
+
// an array-of-arrays receiver given a bare inner array, where TS
|
|
532
|
+
// types it as an element but JS would SPREAD it — is fenced.
|
|
533
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
534
|
+
const shape = [];
|
|
535
|
+
const args = [];
|
|
536
|
+
for (const argNode of call.arguments) {
|
|
537
|
+
if (ts.isSpreadElement(argNode)) {
|
|
538
|
+
lowerer.unsupported("SC1090", argNode, "spread arguments to concat (pass the array itself — concat already spreads array arguments)");
|
|
539
|
+
}
|
|
540
|
+
const argIr = lowerer.mapTypeOf(lowerer.typeOf(argNode));
|
|
541
|
+
const probedArg = probedUntyped ? tryLowerExpression(lowerer, argNode) : null;
|
|
542
|
+
const argArrayType = probedArg?.type.kind === "array" ? probedArg.type : argIr?.kind === "array" ? argIr : null;
|
|
543
|
+
if (argArrayType !== null && typeEquals(argArrayType.elem, elem)) {
|
|
544
|
+
if (elem.kind === "array" && typeEquals(argArrayType, elem)) {
|
|
545
|
+
// number[][].concat(inner: number[]) — TS says element, JS's
|
|
546
|
+
// IsArray says spread; no honest static answer exists.
|
|
547
|
+
lowerer.unsupported("SC1090", argNode, "concat of a bare inner array onto an array-of-arrays (JS would SPREAD it one level — wrap it: a.concat([inner]))");
|
|
548
|
+
}
|
|
549
|
+
// Declaration-backed JS methods can return checked values even
|
|
550
|
+
// when their public signature names a concrete array. Validate
|
|
551
|
+
// that boundary before spreading the represented elements.
|
|
552
|
+
let arg = lowerer.lowerExpr(argNode);
|
|
553
|
+
if (arg.type.kind === "dyn")
|
|
554
|
+
arg = lowerer.coerceInto(argNode, arg, argArrayType);
|
|
555
|
+
if (arg.type.kind !== "array")
|
|
556
|
+
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
557
|
+
shape.push("a");
|
|
558
|
+
args.push(arg);
|
|
559
|
+
continue;
|
|
560
|
+
}
|
|
561
|
+
// A handle-element receiver given an argument whose CHECKER type
|
|
562
|
+
// spells evolved elements while its VALUE is a jsval-element
|
|
563
|
+
// array (`fns.concat(tail)` — both sides of the evolving-`any`
|
|
564
|
+
// adoption): the value's array-ness decides, exactly JS's
|
|
565
|
+
// IsArray — spread it. Non-array values fall through to the
|
|
566
|
+
// element push (the jsvalIn coercion).
|
|
567
|
+
if (elem.kind === "jsval") {
|
|
568
|
+
const arg = lowerer.lowerExpr(argNode);
|
|
569
|
+
if (arg.type.kind === "array" && arg.type.elem.kind === "jsval") {
|
|
570
|
+
shape.push("a");
|
|
571
|
+
args.push(arg);
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
// An element value — union elements wrap exactly like a push.
|
|
576
|
+
shape.push("e");
|
|
577
|
+
args.push(lowerer.lowerExprExpecting(argNode, elem));
|
|
578
|
+
}
|
|
579
|
+
const helper = arrayConcatHelper(lowerer, elem, shape, loc);
|
|
580
|
+
return { kind: "call", callee: helper, args: [receiver, ...args], type: receiverIr, loc };
|
|
581
|
+
}
|
|
582
|
+
if (name === "slice") {
|
|
583
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
584
|
+
const args = [
|
|
585
|
+
lowerArrayPosition(lowerer, call.arguments[0], numLit(0, loc), "array slice start"),
|
|
586
|
+
lowerArrayPosition(lowerer, call.arguments[1], numLit(Infinity, loc), "array slice end"),
|
|
587
|
+
];
|
|
588
|
+
return { kind: "arrIntrinsic", method: "slice", receiver, args, type: receiverIr, loc };
|
|
589
|
+
}
|
|
590
|
+
if (name === "splice") {
|
|
591
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
592
|
+
const args = [
|
|
593
|
+
lowerArrayPosition(lowerer, call.arguments[0], numLit(0, loc), "array splice start"),
|
|
594
|
+
lowerArrayPosition(lowerer, call.arguments[1], numLit(call.arguments.length === 1 ? Infinity : 0, loc), "array splice deleteCount"),
|
|
595
|
+
];
|
|
596
|
+
if (call.arguments.length <= 2) {
|
|
597
|
+
return { kind: "arrIntrinsic", method: "splice", receiver, args, type: receiverIr, loc };
|
|
598
|
+
}
|
|
599
|
+
const itemNodes = call.arguments.slice(2);
|
|
600
|
+
const hasSpread = itemNodes.some(ts.isSpreadElement);
|
|
601
|
+
const itemProbes = hasSpread ? [] : itemNodes.map((arg) => tryLowerExpression(lowerer, arg));
|
|
602
|
+
const statefulItems = itemProbes.some((probe) => probe !== null && lowerer.runtimeOptionalWidening(probe.type, elem) !== null);
|
|
603
|
+
const items = hasSpread
|
|
604
|
+
? lowerArraySpreadItems(lowerer, itemNodes, elem, receiverIr, loc)
|
|
605
|
+
: statefulItems
|
|
606
|
+
? lowerArrayValueItems(lowerer, itemNodes.map((arg) => lowerer.lowerExpr(arg)), elem, receiverIr, loc)
|
|
607
|
+
: {
|
|
608
|
+
kind: "arrayLit",
|
|
609
|
+
elems: itemNodes.map((arg) => lowerer.coerceInto(arg, lowerer.lowerExpr(arg), elem)),
|
|
610
|
+
type: receiverIr,
|
|
611
|
+
loc,
|
|
612
|
+
};
|
|
613
|
+
return {
|
|
614
|
+
kind: "arrIntrinsic",
|
|
615
|
+
method: "spliceInsert",
|
|
616
|
+
receiver,
|
|
617
|
+
args: [...args, items],
|
|
618
|
+
type: receiverIr,
|
|
619
|
+
loc,
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
if (name === "shift") {
|
|
623
|
+
// Like pop, a union without undefined needs an explicit tag widening.
|
|
624
|
+
if (elem.kind === "union" && lowerer.armTag(elem.unionId, UNDEFINED_T) < 0) {
|
|
625
|
+
return lowerUnionArrayRemoval(lowerer, access.expression, elem, true, loc);
|
|
626
|
+
}
|
|
627
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
628
|
+
return {
|
|
629
|
+
kind: "arrIntrinsic",
|
|
630
|
+
method: "shift",
|
|
631
|
+
receiver,
|
|
632
|
+
args: [],
|
|
633
|
+
type: arrayValueType(lowerer, elem),
|
|
634
|
+
loc,
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
if (name === "join") {
|
|
638
|
+
if (elem.kind === "dyn") {
|
|
639
|
+
const receiver = lowerer.coerceToExpected(lowerer.lowerExpr(access.expression), DYN);
|
|
640
|
+
const args = call.arguments.length
|
|
641
|
+
? [lowerer.lowerExprExpecting(call.arguments[0], DYN)]
|
|
642
|
+
: [];
|
|
643
|
+
return lowerer.coerceToExpected({
|
|
644
|
+
kind: "dynInvoke",
|
|
645
|
+
recv: receiver,
|
|
646
|
+
method: "join",
|
|
647
|
+
calleeName: access.getText(),
|
|
648
|
+
args,
|
|
649
|
+
type: DYN,
|
|
650
|
+
loc,
|
|
651
|
+
}, STRING);
|
|
652
|
+
}
|
|
653
|
+
// The ambient declares join on every Array<T> (a per-element-type
|
|
654
|
+
// interface split isn't expressible there), so string-convertible
|
|
655
|
+
// elements are enforced here: nested arrays would need JS's recursive
|
|
656
|
+
// Array#toString. UNIONS of the convertible kinds join too —
|
|
657
|
+
// undefined/null arms print EMPTY per Array.prototype.join (the
|
|
658
|
+
// `.filter(Boolean)` idiom keeps its checker type `(string |
|
|
659
|
+
// undefined)[]`, and JS joins the units silently) — via a per-union
|
|
660
|
+
// interned walker in the backend.
|
|
661
|
+
const joinableUnion = elem.kind === "union" &&
|
|
662
|
+
(lowerer.unions
|
|
663
|
+
.get(elem.unionId)
|
|
664
|
+
?.arms.every((a) => a.kind === "f64" || a.kind === "string" || a.kind === "bool" || isUnitType(a)) ??
|
|
665
|
+
false);
|
|
666
|
+
if (elem.kind !== "f64" && elem.kind !== "string" && elem.kind !== "bool" && !joinableUnion) {
|
|
667
|
+
lowerer.unsupported("SC1090", call, "'.join()' on arrays of this element type (number, string, and boolean arrays join — unions of those with undefined/null arms too, the units printing empty like JS)");
|
|
668
|
+
}
|
|
669
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
670
|
+
const sep = lowerArrayJoinSeparator(lowerer, call.arguments[0], loc);
|
|
671
|
+
return { kind: "arrIntrinsic", method: "join", receiver, args: [sep], type: STRING, loc };
|
|
672
|
+
}
|
|
673
|
+
if (name === "map" || name === "filter" || name === "forEach") {
|
|
674
|
+
return lowerArrayHofCall(lowerer, call, access, name, elem);
|
|
675
|
+
}
|
|
676
|
+
if (name === "find" ||
|
|
677
|
+
name === "findIndex" ||
|
|
678
|
+
name === "findLast" ||
|
|
679
|
+
name === "findLastIndex" ||
|
|
680
|
+
name === "some" ||
|
|
681
|
+
name === "every") {
|
|
682
|
+
return lowerArrayFindLikeCall(lowerer, call, access, name, elem, probedUntyped);
|
|
683
|
+
}
|
|
684
|
+
if (name === "at")
|
|
685
|
+
return lowerArrayAtCall(lowerer, call, access, elem);
|
|
686
|
+
if (name === "flatMap")
|
|
687
|
+
return lowerArrayFlatMapCall(lowerer, call, access, elem);
|
|
688
|
+
// reduce / reduceRight
|
|
689
|
+
return lowerArrayReduceCall(lowerer, call, access, name, elem);
|
|
690
|
+
}
|
|
691
|
+
/** Read before splice so removal cannot destroy the result's owned payload.
|
|
692
|
+
* The source is evaluated once and empty/sparse arrays yield undefined using
|
|
693
|
+
* the same slot-state checks as an indexed read. */
|
|
694
|
+
function lowerUnionArrayRemoval(lowerer, source, elem, first, loc) {
|
|
695
|
+
const receiver = lowerer.lowerExpr(source);
|
|
696
|
+
const arr = lowerer.declareHiddenLocal("%removeArray", receiver.type);
|
|
697
|
+
const arrRef = varRef(arr.id, arr.type, loc);
|
|
698
|
+
const index = lowerer.declareHiddenLocal("%removeIndex", F64);
|
|
699
|
+
const indexRef = varRef(index.id, F64, loc);
|
|
700
|
+
const value = arrayValueRead(lowerer, arrRef, indexRef, elem, loc);
|
|
701
|
+
const result = lowerer.declareHiddenLocal("%removedValue", value.type);
|
|
702
|
+
return {
|
|
703
|
+
kind: "seqExpr",
|
|
704
|
+
stmts: [
|
|
705
|
+
{ kind: "varDecl", localId: arr.id, init: receiver, loc },
|
|
706
|
+
{
|
|
707
|
+
kind: "varDecl",
|
|
708
|
+
localId: index.id,
|
|
709
|
+
init: first
|
|
710
|
+
? numLit(0, loc)
|
|
711
|
+
: {
|
|
712
|
+
kind: "bin",
|
|
713
|
+
op: "-",
|
|
714
|
+
left: {
|
|
715
|
+
kind: "arrIntrinsic",
|
|
716
|
+
method: "length",
|
|
717
|
+
receiver: arrRef,
|
|
718
|
+
args: [],
|
|
719
|
+
type: F64,
|
|
720
|
+
loc,
|
|
721
|
+
},
|
|
722
|
+
right: numLit(1, loc),
|
|
723
|
+
type: F64,
|
|
724
|
+
loc,
|
|
725
|
+
},
|
|
726
|
+
loc,
|
|
727
|
+
},
|
|
728
|
+
{ kind: "varDecl", localId: result.id, init: value, loc },
|
|
729
|
+
{
|
|
730
|
+
kind: "exprStmt",
|
|
731
|
+
expr: {
|
|
732
|
+
kind: "arrIntrinsic",
|
|
733
|
+
method: "splice",
|
|
734
|
+
receiver: arrRef,
|
|
735
|
+
args: [indexRef, numLit(1, loc)],
|
|
736
|
+
type: arr.type,
|
|
737
|
+
loc,
|
|
738
|
+
},
|
|
739
|
+
loc,
|
|
740
|
+
},
|
|
741
|
+
],
|
|
742
|
+
result: varRef(result.id, result.type, loc),
|
|
743
|
+
type: result.type,
|
|
744
|
+
loc,
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
function literalFlatDepth(value) {
|
|
748
|
+
if (value.kind === "numLit")
|
|
749
|
+
return value.value;
|
|
750
|
+
if (value.kind === "strLit")
|
|
751
|
+
return Number(value.value);
|
|
752
|
+
if (value.kind === "boolLit")
|
|
753
|
+
return value.value ? 1 : 0;
|
|
754
|
+
if (value.kind === "unitLit")
|
|
755
|
+
return value.unit === "undefined" ? 1 : 0;
|
|
756
|
+
if (value.kind === "unary" && value.op === "-") {
|
|
757
|
+
const operand = literalFlatDepth(value.operand);
|
|
758
|
+
return operand === null ? null : -operand;
|
|
759
|
+
}
|
|
760
|
+
return null;
|
|
761
|
+
}
|
|
762
|
+
function lowerArrayFlatCall(lowerer, call, access, receiverType) {
|
|
763
|
+
const loc = locOf(call);
|
|
764
|
+
if (call.arguments.length > 1 || call.arguments.some(ts.isSpreadElement)) {
|
|
765
|
+
lowerer.noLowering(`.flat with ${call.arguments.length} arguments`, call);
|
|
766
|
+
}
|
|
767
|
+
const elemCouldNest = (elem) => elem.kind === "array" ||
|
|
768
|
+
elem.kind === "jsval" ||
|
|
769
|
+
elem.kind === "dyn" ||
|
|
770
|
+
(elem.kind === "union" &&
|
|
771
|
+
(lowerer.unions
|
|
772
|
+
.get(elem.unionId)
|
|
773
|
+
?.arms.some((arm) => arm.kind === "array" || arm.kind === "jsval" || arm.kind === "dyn") ??
|
|
774
|
+
true));
|
|
775
|
+
if (!elemCouldNest(receiverType.elem) && call.arguments[0]) {
|
|
776
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
777
|
+
const depth = lowerArrayPosition(lowerer, call.arguments[0], numLit(1, loc), "array flat depth");
|
|
778
|
+
const local = lowerer.declareHiddenLocal("%flatReceiver", receiverType);
|
|
779
|
+
const ref = varRef(local.id, receiverType, loc);
|
|
780
|
+
return {
|
|
781
|
+
kind: "seqExpr",
|
|
782
|
+
stmts: [
|
|
783
|
+
{ kind: "varDecl", localId: local.id, init: receiver, loc },
|
|
784
|
+
{ kind: "exprStmt", expr: depth, loc },
|
|
785
|
+
],
|
|
786
|
+
result: {
|
|
787
|
+
kind: "arrIntrinsic",
|
|
788
|
+
method: "flatCopy",
|
|
789
|
+
receiver: ref,
|
|
790
|
+
args: [{ kind: "arrayLit", elems: [], type: receiverType, loc }],
|
|
791
|
+
type: receiverType,
|
|
792
|
+
loc,
|
|
793
|
+
},
|
|
794
|
+
type: receiverType,
|
|
795
|
+
loc,
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
const depth = call.arguments[0] ? literalFlatDepth(lowerer.lowerExpr(call.arguments[0])) : 1;
|
|
799
|
+
if (depth === null)
|
|
800
|
+
lowerer.noLowering(".flat with a nonconstant depth", call);
|
|
801
|
+
let remaining = Number.isNaN(depth) || depth <= 0 ? 0 : Math.trunc(depth);
|
|
802
|
+
let result = lowerer.lowerExpr(access.expression);
|
|
803
|
+
let currentType = receiverType;
|
|
804
|
+
let flattened = false;
|
|
805
|
+
while (remaining > 0) {
|
|
806
|
+
const elem = currentType.elem;
|
|
807
|
+
if (elem.kind !== "array" && elemCouldNest(elem)) {
|
|
808
|
+
lowerer.noLowering(".flat over elements with runtime-dependent array shape", call);
|
|
809
|
+
}
|
|
810
|
+
if (elem.kind !== "array")
|
|
811
|
+
break;
|
|
812
|
+
result = {
|
|
813
|
+
kind: "arrIntrinsic",
|
|
814
|
+
method: "flatOne",
|
|
815
|
+
receiver: result,
|
|
816
|
+
args: [{ kind: "arrayLit", elems: [], type: elem, loc }],
|
|
817
|
+
type: elem,
|
|
818
|
+
loc,
|
|
819
|
+
};
|
|
820
|
+
currentType = elem;
|
|
821
|
+
remaining--;
|
|
822
|
+
flattened = true;
|
|
823
|
+
}
|
|
824
|
+
if (!flattened) {
|
|
825
|
+
result = {
|
|
826
|
+
kind: "arrIntrinsic",
|
|
827
|
+
method: "flatCopy",
|
|
828
|
+
receiver: result,
|
|
829
|
+
args: [{ kind: "arrayLit", elems: [], type: currentType, loc }],
|
|
830
|
+
type: currentType,
|
|
831
|
+
loc,
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
return result;
|
|
835
|
+
}
|
|
836
|
+
/** `indexOf` and `includes` normally use the runtime's typed search helpers,
|
|
837
|
+
* but an indexed array read is a `T | undefined` value. Keep that union
|
|
838
|
+
* through a small lowered loop so the needle's missing state is observable:
|
|
839
|
+
* indexOf and lastIndexOf skip holes, while includes treats holes as
|
|
840
|
+
* undefined. The same loop also gives union-element arrays their value
|
|
841
|
+
* equality rather than comparing the compiler's union boxes by pointer. */
|
|
842
|
+
function lowerArraySearchCall(lowerer, call, access, method, elem) {
|
|
843
|
+
const loc = locOf(call);
|
|
844
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
845
|
+
if (call.arguments.some(ts.isSpreadElement))
|
|
846
|
+
lowerer.noLowering(`.${method} with spread arguments`, call);
|
|
847
|
+
const needle = call.arguments[0]
|
|
848
|
+
? lowerer.lowerExpr(call.arguments[0])
|
|
849
|
+
: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc };
|
|
850
|
+
const fromIndex = call.arguments[1]
|
|
851
|
+
? lowerPositionArgument(lowerer, call.arguments[1], numLit(0, loc))
|
|
852
|
+
: method === "lastIndexOf"
|
|
853
|
+
? { kind: "bin", op: "/", left: numLit(1, loc), right: numLit(0, loc), type: F64, loc }
|
|
854
|
+
: numLit(0, loc);
|
|
855
|
+
return lowerArraySearchValues(lowerer, call, method, elem, receiver, needle, fromIndex);
|
|
856
|
+
}
|
|
857
|
+
function lowerArraySearchValues(lowerer, call, method, elem, receiver, needle, fromIndex) {
|
|
858
|
+
const loc = locOf(call);
|
|
859
|
+
const argNode = call.arguments[0] ?? call;
|
|
860
|
+
// A derived CLASS VALUE against a base-classval element widens (the same
|
|
861
|
+
// pointer — identity search is exact); the coercion path owns the ABI gate.
|
|
862
|
+
if (needle.type.kind === "classval" &&
|
|
863
|
+
elem.kind === "classval" &&
|
|
864
|
+
!typeEquals(needle.type, elem)) {
|
|
865
|
+
needle = lowerer.coerceInto(argNode, needle, elem);
|
|
866
|
+
}
|
|
867
|
+
// Preserve the existing fast path for an ordinary, non-union needle. Its
|
|
868
|
+
// runtime implementation already has exact primitive/reference equality.
|
|
869
|
+
if (method !== "lastIndexOf" &&
|
|
870
|
+
call.arguments.length === 1 &&
|
|
871
|
+
elem.kind !== "union" &&
|
|
872
|
+
elem.kind !== "bigint" &&
|
|
873
|
+
typeEquals(needle.type, elem)) {
|
|
874
|
+
return {
|
|
875
|
+
kind: "arrIntrinsic",
|
|
876
|
+
method,
|
|
877
|
+
receiver,
|
|
878
|
+
args: [needle],
|
|
879
|
+
type: method === "includes" ? BOOL : F64,
|
|
880
|
+
loc,
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
let valueT = arrayValueType(lowerer, elem);
|
|
884
|
+
// jsval/dyn arrays have a single engine value representation rather than a
|
|
885
|
+
// static undefined arm. Keep their existing runtime path and its explicit
|
|
886
|
+
// type fence; typed static arrays take the state-aware helper below.
|
|
887
|
+
if (valueT.kind !== "union") {
|
|
888
|
+
if (method === "lastIndexOf")
|
|
889
|
+
lowerer.noLowering(".lastIndexOf on an array of engine values", call);
|
|
890
|
+
if (call.arguments.length > 1)
|
|
891
|
+
lowerer.noLowering(`.${method} with fromIndex on '${lowerer.fmt(elem)}' elements`, call);
|
|
892
|
+
if (!typeEquals(needle.type, elem))
|
|
893
|
+
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
894
|
+
return {
|
|
895
|
+
kind: "arrIntrinsic",
|
|
896
|
+
method,
|
|
897
|
+
receiver,
|
|
898
|
+
args: [needle],
|
|
899
|
+
type: method === "includes" ? BOOL : F64,
|
|
900
|
+
loc,
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
// Search uses strict equality, never conversion to the array's element
|
|
904
|
+
// type. Retain primitive needles of a different kind in the comparison
|
|
905
|
+
// union so a nonmatching kind returns a miss instead of throwing.
|
|
906
|
+
const needleArms = needle.type.kind === "union" ? lowerer.unions.get(needle.type.unionId).arms : [needle.type];
|
|
907
|
+
const scalarNeedle = needleArms.every((arm) => arm.kind === "f64" ||
|
|
908
|
+
arm.kind === "string" ||
|
|
909
|
+
arm.kind === "bool" ||
|
|
910
|
+
arm.kind === "bigint" ||
|
|
911
|
+
arm.kind === "symbol" ||
|
|
912
|
+
isUnitType(arm));
|
|
913
|
+
const valueDef = lowerer.unions.get(valueT.unionId);
|
|
914
|
+
const valueArms = valueDef.arms;
|
|
915
|
+
if (scalarNeedle && !valueArms.some((arm) => arm.kind === "func" || arm.kind === "set")) {
|
|
916
|
+
const arms = [...valueArms];
|
|
917
|
+
for (const arm of needleArms)
|
|
918
|
+
if (!arms.some((existing) => typeEquals(existing, arm)))
|
|
919
|
+
arms.push(arm);
|
|
920
|
+
if (arms.length !== valueArms.length)
|
|
921
|
+
valueT = { kind: "union", unionId: lowerer.unions.transform(valueDef, arms) };
|
|
922
|
+
}
|
|
923
|
+
const directNeedle = method === "lastIndexOf" && elem.kind !== "union" && typeEquals(needle.type, elem);
|
|
924
|
+
const searchNeedle = directNeedle ? needle : lowerer.coerceInto(argNode, needle, valueT);
|
|
925
|
+
// Checked dynamic extraction can copy a composite. Its new identity cannot
|
|
926
|
+
// be compared to an array element as though it were the original value.
|
|
927
|
+
if (method === "lastIndexOf" &&
|
|
928
|
+
searchNeedle.kind === "dynCheck" &&
|
|
929
|
+
(elem.kind === "record" || elem.kind === "array")) {
|
|
930
|
+
lowerer.noLowering(".lastIndexOf with a checked dynamic reference needle", call);
|
|
931
|
+
}
|
|
932
|
+
if (!directNeedle && !typeEquals(searchNeedle.type, valueT))
|
|
933
|
+
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
934
|
+
const helper = arraySearchHelper(lowerer, method, elem, valueT, searchNeedle.type, directNeedle, fromIndex.type, call.arguments[1] ?? call, loc);
|
|
935
|
+
return {
|
|
936
|
+
kind: "call",
|
|
937
|
+
callee: helper,
|
|
938
|
+
args: [receiver, searchNeedle, fromIndex],
|
|
939
|
+
type: method === "includes" ? BOOL : F64,
|
|
940
|
+
loc,
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
/** SameValueZero over a static value union. `unionEq` supplies strict
|
|
944
|
+
* equality for every arm; the extra f64-arm test is the only difference for
|
|
945
|
+
* includes, where NaN equals NaN while +0 and -0 remain equal. */
|
|
946
|
+
function arraySearchEquality(lowerer, left, right, sameValueZero, loc) {
|
|
947
|
+
if (left.type.kind !== "union" ||
|
|
948
|
+
right.type.kind !== "union" ||
|
|
949
|
+
left.type.unionId !== right.type.unionId) {
|
|
950
|
+
if (left.type.kind === "string" && right.type.kind === "string") {
|
|
951
|
+
return { kind: "strEq", negated: false, left, right, type: BOOL, loc };
|
|
952
|
+
}
|
|
953
|
+
if (left.type.kind === "bigint" && right.type.kind === "bigint") {
|
|
954
|
+
return {
|
|
955
|
+
kind: "bin",
|
|
956
|
+
op: "===",
|
|
957
|
+
left: { kind: "libCall", fn: "bigint.cmp", args: [left, right], type: F64, loc },
|
|
958
|
+
right: numLit(0, loc),
|
|
959
|
+
type: BOOL,
|
|
960
|
+
loc,
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
return { kind: "bin", op: "===", left, right, type: BOOL, loc };
|
|
964
|
+
}
|
|
965
|
+
const unionId = left.type.unionId;
|
|
966
|
+
const strict = {
|
|
967
|
+
kind: "unionEq",
|
|
968
|
+
unionId,
|
|
969
|
+
negated: false,
|
|
970
|
+
sameValue: false,
|
|
971
|
+
left,
|
|
972
|
+
right,
|
|
973
|
+
type: BOOL,
|
|
974
|
+
loc,
|
|
975
|
+
};
|
|
976
|
+
if (!sameValueZero)
|
|
977
|
+
return strict;
|
|
978
|
+
const numberTag = lowerer.unions.get(unionId)?.arms.findIndex((arm) => arm.kind === "f64") ?? -1;
|
|
979
|
+
if (numberTag < 0)
|
|
980
|
+
return strict;
|
|
981
|
+
const leftIsNumber = {
|
|
982
|
+
kind: "unionIsTag",
|
|
983
|
+
unionId,
|
|
984
|
+
tag: numberTag,
|
|
985
|
+
negated: false,
|
|
986
|
+
value: left,
|
|
987
|
+
type: BOOL,
|
|
988
|
+
loc,
|
|
989
|
+
};
|
|
990
|
+
const rightIsNumber = {
|
|
991
|
+
kind: "unionIsTag",
|
|
992
|
+
unionId,
|
|
993
|
+
tag: numberTag,
|
|
994
|
+
negated: false,
|
|
995
|
+
value: right,
|
|
996
|
+
type: BOOL,
|
|
997
|
+
loc,
|
|
998
|
+
};
|
|
999
|
+
const leftNumber = {
|
|
1000
|
+
kind: "unionNarrow",
|
|
1001
|
+
unionId,
|
|
1002
|
+
tag: numberTag,
|
|
1003
|
+
value: left,
|
|
1004
|
+
type: F64,
|
|
1005
|
+
loc,
|
|
1006
|
+
};
|
|
1007
|
+
const rightNumber = {
|
|
1008
|
+
kind: "unionNarrow",
|
|
1009
|
+
unionId,
|
|
1010
|
+
tag: numberTag,
|
|
1011
|
+
value: right,
|
|
1012
|
+
type: F64,
|
|
1013
|
+
loc,
|
|
1014
|
+
};
|
|
1015
|
+
const bothNaN = {
|
|
1016
|
+
kind: "logical",
|
|
1017
|
+
op: "&&",
|
|
1018
|
+
left: {
|
|
1019
|
+
kind: "logical",
|
|
1020
|
+
op: "&&",
|
|
1021
|
+
left: leftIsNumber,
|
|
1022
|
+
right: rightIsNumber,
|
|
1023
|
+
type: BOOL,
|
|
1024
|
+
loc,
|
|
1025
|
+
},
|
|
1026
|
+
right: {
|
|
1027
|
+
kind: "logical",
|
|
1028
|
+
op: "&&",
|
|
1029
|
+
left: { kind: "libCall", fn: "num.isNaN", args: [leftNumber], type: BOOL, loc },
|
|
1030
|
+
right: { kind: "libCall", fn: "num.isNaN", args: [rightNumber], type: BOOL, loc },
|
|
1031
|
+
type: BOOL,
|
|
1032
|
+
loc,
|
|
1033
|
+
},
|
|
1034
|
+
type: BOOL,
|
|
1035
|
+
loc,
|
|
1036
|
+
};
|
|
1037
|
+
return { kind: "logical", op: "||", left: strict, right: bothNaN, type: BOOL, loc };
|
|
1038
|
+
}
|
|
1039
|
+
function arraySearchHelper(lowerer, method, elem, valueT, needleT, directNeedle, fromT, fromNode, loc) {
|
|
1040
|
+
const key = `${method}:${typeKey(elem)}:${typeKey(valueT)}:${typeKey(needleT)}:${directNeedle}:${typeKey(fromT)}`;
|
|
1041
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
1042
|
+
if (existing)
|
|
1043
|
+
return existing;
|
|
1044
|
+
const name = `%arr.${method}.${lowerer.arrHofHelpers.size}`;
|
|
1045
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
1046
|
+
const arrT = arrayOf(elem);
|
|
1047
|
+
const resultT = method === "includes" ? BOOL : F64;
|
|
1048
|
+
const arrRef = varRef("a.0", arrT, loc);
|
|
1049
|
+
const indexRef = varRef("i.0", F64, loc);
|
|
1050
|
+
const needleRef = varRef("needle.0", needleT, loc);
|
|
1051
|
+
const stateRef = varRef("state.0", F64, loc);
|
|
1052
|
+
const nextRef = varRef("next.0", F64, loc);
|
|
1053
|
+
const fromRef = varRef("from.0", fromT, loc);
|
|
1054
|
+
const numberRef = varRef("number.0", F64, loc);
|
|
1055
|
+
const integerRef = varRef("integer.0", F64, loc);
|
|
1056
|
+
// Snapshot length before coercing fromIndex, then apply ToIntegerOrInfinity.
|
|
1057
|
+
const number = positionNumber(lowerer, fromRef, numLit(0, loc), fromNode, "array search position");
|
|
1058
|
+
const integer = {
|
|
1059
|
+
kind: "ternary",
|
|
1060
|
+
cond: { kind: "libCall", fn: "num.isNaN", args: [numberRef], type: BOOL, loc },
|
|
1061
|
+
then: numLit(0, loc),
|
|
1062
|
+
else_: { kind: "libCall", fn: "math.trunc", args: [numberRef], type: F64, loc },
|
|
1063
|
+
type: F64,
|
|
1064
|
+
loc,
|
|
1065
|
+
};
|
|
1066
|
+
const forwardStart = {
|
|
1067
|
+
kind: "ternary",
|
|
1068
|
+
cond: { kind: "bin", op: "<", left: integerRef, right: numLit(0, loc), type: BOOL, loc },
|
|
1069
|
+
then: {
|
|
1070
|
+
kind: "libCall",
|
|
1071
|
+
fn: "math.max",
|
|
1072
|
+
args: [
|
|
1073
|
+
{ kind: "bin", op: "+", left: varRef("n.0", F64, loc), right: integerRef, type: F64, loc },
|
|
1074
|
+
numLit(0, loc),
|
|
1075
|
+
],
|
|
1076
|
+
type: F64,
|
|
1077
|
+
loc,
|
|
1078
|
+
},
|
|
1079
|
+
// Adding positive zero canonicalizes a truncated negative zero.
|
|
1080
|
+
else_: { kind: "bin", op: "+", left: integerRef, right: numLit(0, loc), type: F64, loc },
|
|
1081
|
+
type: F64,
|
|
1082
|
+
loc,
|
|
1083
|
+
};
|
|
1084
|
+
const start = method === "lastIndexOf"
|
|
1085
|
+
? {
|
|
1086
|
+
kind: "ternary",
|
|
1087
|
+
cond: { kind: "bin", op: "<", left: integerRef, right: numLit(0, loc), type: BOOL, loc },
|
|
1088
|
+
then: {
|
|
1089
|
+
kind: "bin",
|
|
1090
|
+
op: "+",
|
|
1091
|
+
left: varRef("n.0", F64, loc),
|
|
1092
|
+
right: integerRef,
|
|
1093
|
+
type: F64,
|
|
1094
|
+
loc,
|
|
1095
|
+
},
|
|
1096
|
+
else_: {
|
|
1097
|
+
kind: "libCall",
|
|
1098
|
+
fn: "math.min",
|
|
1099
|
+
args: [
|
|
1100
|
+
{ kind: "bin", op: "+", left: integerRef, right: numLit(0, loc), type: F64, loc },
|
|
1101
|
+
{
|
|
1102
|
+
kind: "bin",
|
|
1103
|
+
op: "-",
|
|
1104
|
+
left: varRef("n.0", F64, loc),
|
|
1105
|
+
right: numLit(1, loc),
|
|
1106
|
+
type: F64,
|
|
1107
|
+
loc,
|
|
1108
|
+
},
|
|
1109
|
+
],
|
|
1110
|
+
type: F64,
|
|
1111
|
+
loc,
|
|
1112
|
+
},
|
|
1113
|
+
type: F64,
|
|
1114
|
+
loc,
|
|
1115
|
+
}
|
|
1116
|
+
: forwardStart;
|
|
1117
|
+
const rawRead = { kind: "arrayGet", arr: arrRef, index: indexRef, type: elem, loc };
|
|
1118
|
+
const missing = lowerer.wrappedUndefined(valueT, loc);
|
|
1119
|
+
if (!missing)
|
|
1120
|
+
throw new InternalCompilerError("array search helper needs an undefined arm");
|
|
1121
|
+
const optionalValue = {
|
|
1122
|
+
kind: "ternary",
|
|
1123
|
+
cond: { kind: "bin", op: "===", left: stateRef, right: numLit(1, loc), type: BOOL, loc },
|
|
1124
|
+
then: typeEquals(elem, valueT) ? rawRead : lowerer.coerceToExpected(rawRead, valueT),
|
|
1125
|
+
else_: missing,
|
|
1126
|
+
type: valueT,
|
|
1127
|
+
loc,
|
|
1128
|
+
};
|
|
1129
|
+
const value = directNeedle ? rawRead : optionalValue;
|
|
1130
|
+
const readT = directNeedle ? elem : valueT;
|
|
1131
|
+
const equal = arraySearchEquality(lowerer, varRef("value.0", readT, loc), needleRef, method === "includes", loc);
|
|
1132
|
+
const match = method !== "includes"
|
|
1133
|
+
? {
|
|
1134
|
+
kind: "logical",
|
|
1135
|
+
op: "&&",
|
|
1136
|
+
left: {
|
|
1137
|
+
kind: "bin",
|
|
1138
|
+
op: directNeedle ? "===" : "!==",
|
|
1139
|
+
left: stateRef,
|
|
1140
|
+
right: numLit(directNeedle ? 1 : 0, loc),
|
|
1141
|
+
type: BOOL,
|
|
1142
|
+
loc,
|
|
1143
|
+
},
|
|
1144
|
+
right: equal,
|
|
1145
|
+
type: BOOL,
|
|
1146
|
+
loc,
|
|
1147
|
+
}
|
|
1148
|
+
: equal;
|
|
1149
|
+
const undefinedTag = lowerer.armTag(valueT.unionId, UNDEFINED_T);
|
|
1150
|
+
if (undefinedTag < 0)
|
|
1151
|
+
throw new InternalCompilerError("array search helper needs an undefined tag");
|
|
1152
|
+
const needleIsUndefined = directNeedle
|
|
1153
|
+
? boolLit(false, loc)
|
|
1154
|
+
: {
|
|
1155
|
+
kind: "unionIsTag",
|
|
1156
|
+
unionId: valueT.unionId,
|
|
1157
|
+
tag: undefinedTag,
|
|
1158
|
+
negated: false,
|
|
1159
|
+
value: needleRef,
|
|
1160
|
+
type: BOOL,
|
|
1161
|
+
loc,
|
|
1162
|
+
};
|
|
1163
|
+
const advance = {
|
|
1164
|
+
kind: "assign",
|
|
1165
|
+
localId: "i.0",
|
|
1166
|
+
value: {
|
|
1167
|
+
kind: "bin",
|
|
1168
|
+
op: method === "lastIndexOf" ? "-" : "+",
|
|
1169
|
+
left: indexRef,
|
|
1170
|
+
right: numLit(1, loc),
|
|
1171
|
+
type: F64,
|
|
1172
|
+
loc,
|
|
1173
|
+
},
|
|
1174
|
+
loc,
|
|
1175
|
+
};
|
|
1176
|
+
const visitPresent = [
|
|
1177
|
+
{ kind: "varDecl", localId: "value.0", init: value, loc },
|
|
1178
|
+
{
|
|
1179
|
+
kind: "if",
|
|
1180
|
+
cond: match,
|
|
1181
|
+
then: [{ kind: "return", value: method === "includes" ? boolLit(true, loc) : indexRef, loc }],
|
|
1182
|
+
else_: null,
|
|
1183
|
+
loc,
|
|
1184
|
+
},
|
|
1185
|
+
advance,
|
|
1186
|
+
];
|
|
1187
|
+
const skipHole = method === "lastIndexOf"
|
|
1188
|
+
? [advance]
|
|
1189
|
+
: [
|
|
1190
|
+
{
|
|
1191
|
+
kind: "varDecl",
|
|
1192
|
+
localId: "next.0",
|
|
1193
|
+
init: {
|
|
1194
|
+
kind: "arrIntrinsic",
|
|
1195
|
+
method: "nextPresent",
|
|
1196
|
+
receiver: arrRef,
|
|
1197
|
+
args: [indexRef],
|
|
1198
|
+
type: F64,
|
|
1199
|
+
loc,
|
|
1200
|
+
},
|
|
1201
|
+
loc,
|
|
1202
|
+
},
|
|
1203
|
+
...(method === "includes"
|
|
1204
|
+
? [
|
|
1205
|
+
{
|
|
1206
|
+
kind: "if",
|
|
1207
|
+
cond: needleIsUndefined,
|
|
1208
|
+
then: [{ kind: "return", value: boolLit(true, loc), loc }],
|
|
1209
|
+
else_: null,
|
|
1210
|
+
loc,
|
|
1211
|
+
},
|
|
1212
|
+
]
|
|
1213
|
+
: []),
|
|
1214
|
+
{ kind: "assign", localId: "i.0", value: nextRef, loc },
|
|
1215
|
+
];
|
|
1216
|
+
const loopBody = [
|
|
1217
|
+
{
|
|
1218
|
+
kind: "varDecl",
|
|
1219
|
+
localId: "state.0",
|
|
1220
|
+
init: { kind: "arrayState", arr: arrRef, index: indexRef, type: F64, loc },
|
|
1221
|
+
loc,
|
|
1222
|
+
},
|
|
1223
|
+
{
|
|
1224
|
+
kind: "if",
|
|
1225
|
+
cond: { kind: "bin", op: "===", left: stateRef, right: numLit(0, loc), type: BOOL, loc },
|
|
1226
|
+
then: skipHole,
|
|
1227
|
+
else_: visitPresent,
|
|
1228
|
+
loc,
|
|
1229
|
+
},
|
|
1230
|
+
];
|
|
1231
|
+
lowerer.liftedFns.push({
|
|
1232
|
+
name,
|
|
1233
|
+
params: [
|
|
1234
|
+
{ localId: "a.0", name: "a", type: arrT },
|
|
1235
|
+
{ localId: "needle.0", name: "needle", type: needleT },
|
|
1236
|
+
{ localId: "from.0", name: "from", type: fromT },
|
|
1237
|
+
],
|
|
1238
|
+
returnType: resultT,
|
|
1239
|
+
locals: [
|
|
1240
|
+
{ id: "a.0", name: "a", type: arrT, mutable: true },
|
|
1241
|
+
{ id: "needle.0", name: "needle", type: needleT, mutable: true },
|
|
1242
|
+
{ id: "from.0", name: "from", type: fromT, mutable: false },
|
|
1243
|
+
{ id: "number.0", name: "number", type: F64, mutable: false },
|
|
1244
|
+
{ id: "integer.0", name: "integer", type: F64, mutable: false },
|
|
1245
|
+
{ id: "n.0", name: "n", type: F64, mutable: false },
|
|
1246
|
+
{ id: "i.0", name: "i", type: F64, mutable: true },
|
|
1247
|
+
{ id: "state.0", name: "state", type: F64, mutable: false },
|
|
1248
|
+
{ id: "next.0", name: "next", type: F64, mutable: false },
|
|
1249
|
+
{ id: "value.0", name: "value", type: readT, mutable: false },
|
|
1250
|
+
],
|
|
1251
|
+
body: [
|
|
1252
|
+
arrayLengthDeclaration(arrT, loc),
|
|
1253
|
+
{ kind: "varDecl", localId: "number.0", init: number, loc },
|
|
1254
|
+
{ kind: "varDecl", localId: "integer.0", init: integer, loc },
|
|
1255
|
+
{ kind: "varDecl", localId: "i.0", init: start, loc },
|
|
1256
|
+
{
|
|
1257
|
+
kind: "while",
|
|
1258
|
+
cond: method === "lastIndexOf"
|
|
1259
|
+
? { kind: "bin", op: ">=", left: indexRef, right: numLit(0, loc), type: BOOL, loc }
|
|
1260
|
+
: {
|
|
1261
|
+
kind: "bin",
|
|
1262
|
+
op: "<",
|
|
1263
|
+
left: indexRef,
|
|
1264
|
+
right: varRef("n.0", F64, loc),
|
|
1265
|
+
type: BOOL,
|
|
1266
|
+
loc,
|
|
1267
|
+
},
|
|
1268
|
+
body: loopBody,
|
|
1269
|
+
loc,
|
|
1270
|
+
},
|
|
1271
|
+
{ kind: "return", value: method === "includes" ? boolLit(false, loc) : numLit(-1, loc), loc },
|
|
1272
|
+
],
|
|
1273
|
+
loc,
|
|
1274
|
+
});
|
|
1275
|
+
return name;
|
|
1276
|
+
}
|
|
1277
|
+
/** Tuple methods keep the original receiver alive through argument evaluation.
|
|
1278
|
+
* Callback methods read each position only when it is visited, so writes to
|
|
1279
|
+
* later positions through a captured alias are visible. A tuple cannot be
|
|
1280
|
+
* passed as the callback's array parameter without changing its identity;
|
|
1281
|
+
* that parameter retains an explicit representation boundary. */
|
|
1282
|
+
export function lowerTupleReadMethodCall(lowerer, call, access, tupleReceiver) {
|
|
1283
|
+
if (lowerer.chainBlocked(access, call))
|
|
1284
|
+
return null;
|
|
1285
|
+
const method = access.name.text;
|
|
1286
|
+
const search = method === "includes" || method === "indexOf" || method === "lastIndexOf";
|
|
1287
|
+
if (method !== "slice" &&
|
|
1288
|
+
method !== "map" &&
|
|
1289
|
+
method !== "flatMap" &&
|
|
1290
|
+
method !== "join" &&
|
|
1291
|
+
!search)
|
|
1292
|
+
return null;
|
|
1293
|
+
if (!lowerer.isStdlibMember(access))
|
|
1294
|
+
return null;
|
|
1295
|
+
let receiverIr = tupleReceiver?.type ?? lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
1296
|
+
let receiver = tupleReceiver ?? null;
|
|
1297
|
+
const checkerArray = lowerer.checkerArrayValue(access.expression);
|
|
1298
|
+
if (checkerArray?.type.kind === "record") {
|
|
1299
|
+
receiverIr = checkerArray.type;
|
|
1300
|
+
receiver = checkerArray;
|
|
1301
|
+
}
|
|
1302
|
+
if (receiverIr?.kind !== "record")
|
|
1303
|
+
return null;
|
|
1304
|
+
const shape = lowerer.shapes.get(receiverIr.shapeId);
|
|
1305
|
+
if (!shape?.tuple)
|
|
1306
|
+
return null;
|
|
1307
|
+
receiver ??= lowerer.lowerExpr(access.expression);
|
|
1308
|
+
if (method === "join") {
|
|
1309
|
+
// Object.entries can retain its dynamic array representation behind a
|
|
1310
|
+
// checker tuple. Native tuples box as live references, so separator
|
|
1311
|
+
// evaluation can still mutate their elements before join reads them.
|
|
1312
|
+
// An unchecked outer array read must validate its optional payload
|
|
1313
|
+
// before passing the tuple to the runtime.
|
|
1314
|
+
if (receiver.type.kind === "union") {
|
|
1315
|
+
receiver = lowerer.coerceInto(access.expression, receiver, receiverIr);
|
|
1316
|
+
}
|
|
1317
|
+
const converted = lowerer.coerceInto(access.expression, receiver, DYN);
|
|
1318
|
+
const boxed = converted.kind === "dynFrom" && converted.value.type.kind === "record"
|
|
1319
|
+
? { ...converted, liveRef: true }
|
|
1320
|
+
: converted;
|
|
1321
|
+
const joined = lowerDynDispatchMethodCall(lowerer, call, access, boxed, true);
|
|
1322
|
+
return joined ? lowerer.coerceInto(call, joined, STRING) : null;
|
|
1323
|
+
}
|
|
1324
|
+
if (receiver.type.kind !== "record")
|
|
1325
|
+
return null;
|
|
1326
|
+
const fields = [...shape.fields].sort((a, b) => Number(a.name) - Number(b.name));
|
|
1327
|
+
const arms = [];
|
|
1328
|
+
for (const field of fields) {
|
|
1329
|
+
const types = field.type.kind === "union" ? lowerer.unions.get(field.type.unionId).arms : [field.type];
|
|
1330
|
+
for (const type of types)
|
|
1331
|
+
if (!arms.some((arm) => typeEquals(arm, type)))
|
|
1332
|
+
arms.push(type);
|
|
1333
|
+
}
|
|
1334
|
+
if (arms.length === 0)
|
|
1335
|
+
return null;
|
|
1336
|
+
const elem = arms.length === 1 ? arms[0] : { kind: "union", unionId: lowerer.unions.intern(arms) };
|
|
1337
|
+
const loc = locOf(call);
|
|
1338
|
+
const tuple = varRef("a.0", receiver.type, loc);
|
|
1339
|
+
const read = (field) => lowerer.coerceInto(access.expression, {
|
|
1340
|
+
kind: "recordGet",
|
|
1341
|
+
obj: tuple,
|
|
1342
|
+
shapeId: receiverIr.shapeId,
|
|
1343
|
+
field: field.name,
|
|
1344
|
+
type: field.type,
|
|
1345
|
+
loc,
|
|
1346
|
+
}, elem);
|
|
1347
|
+
if (search) {
|
|
1348
|
+
if (call.arguments.length > 2 || call.arguments.some(ts.isSpreadElement)) {
|
|
1349
|
+
return lowerer.noLowering(`tuple .${method} with spread or extra arguments`, call);
|
|
1350
|
+
}
|
|
1351
|
+
const arg = call.arguments[0];
|
|
1352
|
+
const undefinedArg = arg ? lowerStaticallyUndefinedArgument(lowerer, arg) : null;
|
|
1353
|
+
let needle = arg ? (undefinedArg ?? lowerer.lowerExpr(arg)) : null;
|
|
1354
|
+
if (!needle || isUnitType(needle.type) || needle.type.kind === "void") {
|
|
1355
|
+
const optional = arrayValueType(lowerer, elem);
|
|
1356
|
+
const wrapped = needle?.type.kind === "nullT"
|
|
1357
|
+
? lowerer.coerceInto(arg ?? call, needle, optional)
|
|
1358
|
+
: lowerer.wrappedUndefined(optional, loc);
|
|
1359
|
+
if (!wrapped)
|
|
1360
|
+
return lowerer.noLowering(`tuple .${method} missing search value`, call);
|
|
1361
|
+
needle = needle ? defaultAfterUndefined(needle, wrapped) : wrapped;
|
|
1362
|
+
}
|
|
1363
|
+
const from = call.arguments[1]
|
|
1364
|
+
? lowerPositionArgument(lowerer, call.arguments[1], numLit(0, loc))
|
|
1365
|
+
: numLit(method === "lastIndexOf" ? Infinity : 0, loc);
|
|
1366
|
+
const key = `tuple.${method}:${typeKey(receiver.type)}:${typeKey(needle.type)}:${typeKey(from.type)}:${call.arguments.length}`;
|
|
1367
|
+
let helper = lowerer.arrHofHelpers.get(key);
|
|
1368
|
+
const resultType = method === "includes" ? BOOL : F64;
|
|
1369
|
+
if (!helper) {
|
|
1370
|
+
helper = `%tuple.${method}.${lowerer.arrHofHelpers.size}`;
|
|
1371
|
+
lowerer.arrHofHelpers.set(key, helper);
|
|
1372
|
+
const params = [
|
|
1373
|
+
{ localId: "a.0", name: "a", type: receiver.type },
|
|
1374
|
+
{ localId: "needle.0", name: "needle", type: needle.type },
|
|
1375
|
+
{ localId: "from.0", name: "from", type: from.type },
|
|
1376
|
+
];
|
|
1377
|
+
const result = lowerArraySearchValues(lowerer, call, method, elem, { kind: "arrayLit", elems: fields.map(read), type: arrayOf(elem), loc }, varRef("needle.0", needle.type, loc), varRef("position.0", F64, loc));
|
|
1378
|
+
lowerer.liftedFns.push({
|
|
1379
|
+
name: helper,
|
|
1380
|
+
params,
|
|
1381
|
+
returnType: resultType,
|
|
1382
|
+
locals: [
|
|
1383
|
+
...params.map((param) => ({
|
|
1384
|
+
id: param.localId,
|
|
1385
|
+
name: param.name,
|
|
1386
|
+
type: param.type,
|
|
1387
|
+
mutable: false,
|
|
1388
|
+
})),
|
|
1389
|
+
{ id: "position.0", name: "position", type: F64, mutable: false },
|
|
1390
|
+
],
|
|
1391
|
+
body: [
|
|
1392
|
+
{
|
|
1393
|
+
kind: "varDecl",
|
|
1394
|
+
localId: "position.0",
|
|
1395
|
+
init: positionNumber(lowerer, varRef("from.0", from.type, loc), numLit(0, loc), call.arguments[1] ?? call, "tuple search position"),
|
|
1396
|
+
loc,
|
|
1397
|
+
},
|
|
1398
|
+
{ kind: "return", value: result, loc },
|
|
1399
|
+
],
|
|
1400
|
+
loc,
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
return { kind: "call", callee: helper, args: [receiver, needle, from], type: resultType, loc };
|
|
1404
|
+
}
|
|
1405
|
+
if (method === "slice") {
|
|
1406
|
+
if (call.arguments.length > 2 || call.arguments.some(ts.isSpreadElement)) {
|
|
1407
|
+
lowerer.noLowering(`.slice with ${call.arguments.length} arguments`, call);
|
|
1408
|
+
}
|
|
1409
|
+
const args = call.arguments.map((arg) => lowerer.lowerExpr(arg));
|
|
1410
|
+
args.forEach((arg, i) => {
|
|
1411
|
+
if (arg.type.kind !== "f64")
|
|
1412
|
+
lowerer.badType(call.arguments[i], lowerer.typeOf(call.arguments[i]));
|
|
1413
|
+
});
|
|
1414
|
+
const resultType = arrayOf(elem);
|
|
1415
|
+
const key = `tuple.slice:${typeKey(receiver.type)}:${args.length}`;
|
|
1416
|
+
let helper = lowerer.arrHofHelpers.get(key);
|
|
1417
|
+
if (!helper) {
|
|
1418
|
+
helper = `%tuple.slice.${lowerer.arrHofHelpers.size}`;
|
|
1419
|
+
lowerer.arrHofHelpers.set(key, helper);
|
|
1420
|
+
const params = [receiver, ...args].map((arg, i) => ({
|
|
1421
|
+
localId: i === 0 ? "a.0" : `arg.${i}`,
|
|
1422
|
+
name: `arg${i}`,
|
|
1423
|
+
type: arg.type,
|
|
1424
|
+
}));
|
|
1425
|
+
lowerer.liftedFns.push({
|
|
1426
|
+
name: helper,
|
|
1427
|
+
params,
|
|
1428
|
+
returnType: resultType,
|
|
1429
|
+
locals: params.map((param) => ({
|
|
1430
|
+
id: param.localId,
|
|
1431
|
+
name: param.name,
|
|
1432
|
+
type: param.type,
|
|
1433
|
+
mutable: false,
|
|
1434
|
+
})),
|
|
1435
|
+
body: [
|
|
1436
|
+
{
|
|
1437
|
+
kind: "return",
|
|
1438
|
+
value: {
|
|
1439
|
+
kind: "arrIntrinsic",
|
|
1440
|
+
method: "slice",
|
|
1441
|
+
receiver: { kind: "arrayLit", elems: fields.map(read), type: resultType, loc },
|
|
1442
|
+
args: args.map((arg, i) => varRef(`arg.${i + 1}`, arg.type, loc)),
|
|
1443
|
+
type: resultType,
|
|
1444
|
+
loc,
|
|
1445
|
+
},
|
|
1446
|
+
loc,
|
|
1447
|
+
},
|
|
1448
|
+
],
|
|
1449
|
+
loc,
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
return { kind: "call", callee: helper, args: [receiver, ...args], type: resultType, loc };
|
|
1453
|
+
}
|
|
1454
|
+
if (call.arguments.length !== 1 || call.arguments.some(ts.isSpreadElement)) {
|
|
1455
|
+
lowerer.noLowering(`.${method} with ${call.arguments.length} arguments`, call, "the thisArg parameter has no lowering — use an arrow function");
|
|
1456
|
+
}
|
|
1457
|
+
const callback = call.arguments[0];
|
|
1458
|
+
// Check before the array HOF adapter can create a tuple-to-array copy.
|
|
1459
|
+
const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(callback));
|
|
1460
|
+
if (signatures.some((signature) => signature.getParameters().length > 2)) {
|
|
1461
|
+
lowerer.noLowering(`tuple .${method} callback array parameter`, callback, "capture the original tuple explicitly to preserve its identity");
|
|
1462
|
+
}
|
|
1463
|
+
const { fnArg, arity } = lowerArrayCallback(lowerer, callback, [elem], receiver.type);
|
|
1464
|
+
const ret = fnArg.type.ret;
|
|
1465
|
+
if (ret.kind === "void" || ret.kind === "func")
|
|
1466
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
1467
|
+
if (method === "flatMap" &&
|
|
1468
|
+
(ret.kind === "dyn" ||
|
|
1469
|
+
ret.kind === "jsval" ||
|
|
1470
|
+
(ret.kind === "record" && lowerer.shapes.get(ret.shapeId)?.tuple))) {
|
|
1471
|
+
return {
|
|
1472
|
+
kind: "dynInvoke",
|
|
1473
|
+
recv: { kind: "dynFrom", value: receiver, type: DYN, loc },
|
|
1474
|
+
method: "flatMap",
|
|
1475
|
+
calleeName: access.getText(),
|
|
1476
|
+
args: [{ kind: "dynFrom", value: fnArg, type: DYN, loc }],
|
|
1477
|
+
type: DYN,
|
|
1478
|
+
loc,
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
if (method === "flatMap" &&
|
|
1482
|
+
ret.kind === "union" &&
|
|
1483
|
+
lowerer.unions.get(ret.unionId).arms.some((arm) => arm.kind === "array")) {
|
|
1484
|
+
lowerer.noLowering("tuple .flatMap callback mixing array and scalar results", callback, "return an array from every path");
|
|
1485
|
+
}
|
|
1486
|
+
const flatten = method === "flatMap" && ret.kind === "array";
|
|
1487
|
+
const outElem = flatten ? ret.elem : callbackArrayElement(lowerer, call, ret);
|
|
1488
|
+
requireProducedArrayElement(lowerer, call, `'.${method}()'`, outElem);
|
|
1489
|
+
const outType = arrayOf(outElem);
|
|
1490
|
+
const key = `tuple.${method}:${typeKey(receiver.type)}:${typeKey(fnArg.type)}:${typeKey(outElem)}`;
|
|
1491
|
+
let helper = lowerer.arrHofHelpers.get(key);
|
|
1492
|
+
if (!helper) {
|
|
1493
|
+
helper = `%tuple.${method}.${lowerer.arrHofHelpers.size}`;
|
|
1494
|
+
lowerer.arrHofHelpers.set(key, helper);
|
|
1495
|
+
const out = varRef("out.0", outType, loc);
|
|
1496
|
+
const result = varRef("r.0", ret, loc);
|
|
1497
|
+
const outputLength = {
|
|
1498
|
+
kind: "arrIntrinsic",
|
|
1499
|
+
method: "length",
|
|
1500
|
+
receiver: out,
|
|
1501
|
+
args: [],
|
|
1502
|
+
type: F64,
|
|
1503
|
+
loc,
|
|
1504
|
+
};
|
|
1505
|
+
const body = [
|
|
1506
|
+
{
|
|
1507
|
+
kind: "varDecl",
|
|
1508
|
+
localId: "out.0",
|
|
1509
|
+
init: { kind: "arrayLit", elems: [], type: outType, loc },
|
|
1510
|
+
loc,
|
|
1511
|
+
},
|
|
1512
|
+
];
|
|
1513
|
+
for (const field of fields) {
|
|
1514
|
+
const invocation = {
|
|
1515
|
+
kind: "callValue",
|
|
1516
|
+
callee: varRef("f.0", fnArg.type, loc),
|
|
1517
|
+
args: [read(field), numLit(Number(field.name), loc)].slice(0, arity),
|
|
1518
|
+
type: ret,
|
|
1519
|
+
loc,
|
|
1520
|
+
};
|
|
1521
|
+
body.push(field === fields[0]
|
|
1522
|
+
? { kind: "varDecl", localId: "r.0", init: invocation, loc }
|
|
1523
|
+
: { kind: "assign", localId: "r.0", value: invocation, loc });
|
|
1524
|
+
if (flatten) {
|
|
1525
|
+
const index = varRef("i.0", F64, loc);
|
|
1526
|
+
body.push(countedFor(loc, { kind: "arrIntrinsic", method: "length", receiver: result, args: [], type: F64, loc }, () => [
|
|
1527
|
+
{
|
|
1528
|
+
kind: "if",
|
|
1529
|
+
cond: arrayIndexPresent(result, index, loc),
|
|
1530
|
+
then: [
|
|
1531
|
+
{
|
|
1532
|
+
kind: "varDecl",
|
|
1533
|
+
localId: "inner.0",
|
|
1534
|
+
init: arrayValueRead(lowerer, result, index, outElem, loc),
|
|
1535
|
+
loc,
|
|
1536
|
+
},
|
|
1537
|
+
arrayValueStore(lowerer, out, outputLength, varRef("inner.0", arrayValueType(lowerer, outElem), loc), outElem, loc),
|
|
1538
|
+
],
|
|
1539
|
+
else_: null,
|
|
1540
|
+
loc,
|
|
1541
|
+
},
|
|
1542
|
+
]));
|
|
1543
|
+
}
|
|
1544
|
+
else {
|
|
1545
|
+
body.push(arrayValueStore(lowerer, out, outputLength, result, outElem, loc));
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
body.push({ kind: "return", value: out, loc });
|
|
1549
|
+
lowerer.liftedFns.push({
|
|
1550
|
+
name: helper,
|
|
1551
|
+
params: [
|
|
1552
|
+
{ localId: "a.0", name: "a", type: receiver.type },
|
|
1553
|
+
{ localId: "f.0", name: "f", type: fnArg.type },
|
|
1554
|
+
],
|
|
1555
|
+
returnType: outType,
|
|
1556
|
+
locals: [
|
|
1557
|
+
{ id: "a.0", name: "a", type: receiver.type, mutable: false },
|
|
1558
|
+
{ id: "f.0", name: "f", type: fnArg.type, mutable: false },
|
|
1559
|
+
{ id: "out.0", name: "out", type: outType, mutable: false },
|
|
1560
|
+
{ id: "r.0", name: "r", type: ret, mutable: true },
|
|
1561
|
+
...(flatten
|
|
1562
|
+
? [
|
|
1563
|
+
{ id: "i.0", name: "i", type: F64, mutable: true },
|
|
1564
|
+
{
|
|
1565
|
+
id: "inner.0",
|
|
1566
|
+
name: "inner",
|
|
1567
|
+
type: arrayValueType(lowerer, outElem),
|
|
1568
|
+
mutable: false,
|
|
1569
|
+
},
|
|
1570
|
+
]
|
|
1571
|
+
: []),
|
|
1572
|
+
],
|
|
1573
|
+
body,
|
|
1574
|
+
loc,
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
return { kind: "call", callee: helper, args: [receiver, fnArg], type: outType, loc };
|
|
1578
|
+
}
|
|
1579
|
+
/** An ordinary indexed read: values retain their element type, while
|
|
1580
|
+
* holes, missing properties, and present undefined yield undefined. */
|
|
1581
|
+
export function lowerSafeIndexRead(lowerer, arr, index, loc) {
|
|
1582
|
+
if (arr.type.kind !== "array")
|
|
1583
|
+
throw new InternalCompilerError("indexed read requires an array");
|
|
1584
|
+
const elem = arr.type.elem;
|
|
1585
|
+
if (elem.kind === "void")
|
|
1586
|
+
return null;
|
|
1587
|
+
const resultT = arrayValueType(lowerer, elem);
|
|
1588
|
+
const key = `idxOr:${typeKey(elem)}`;
|
|
1589
|
+
let name = lowerer.arrHofHelpers.get(key);
|
|
1590
|
+
if (!name) {
|
|
1591
|
+
name = `%arr.idxOr.${lowerer.arrHofHelpers.size}`;
|
|
1592
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
1593
|
+
const arrT = arr.type;
|
|
1594
|
+
lowerer.liftedFns.push({
|
|
1595
|
+
name,
|
|
1596
|
+
params: [
|
|
1597
|
+
{ localId: "a.0", name: "a", type: arrT },
|
|
1598
|
+
{ localId: "i.0", name: "i", type: F64 },
|
|
1599
|
+
],
|
|
1600
|
+
returnType: resultT,
|
|
1601
|
+
locals: [
|
|
1602
|
+
{ id: "a.0", name: "a", type: arrT, mutable: false },
|
|
1603
|
+
{ id: "i.0", name: "i", type: F64, mutable: false },
|
|
1604
|
+
],
|
|
1605
|
+
body: [
|
|
1606
|
+
{
|
|
1607
|
+
kind: "return",
|
|
1608
|
+
value: arrayValueRead(lowerer, varRef("a.0", arrT, loc), varRef("i.0", F64, loc), elem, loc),
|
|
1609
|
+
loc,
|
|
1610
|
+
},
|
|
1611
|
+
],
|
|
1612
|
+
loc,
|
|
1613
|
+
});
|
|
1614
|
+
}
|
|
1615
|
+
return { kind: "call", callee: name, args: [arr, index], type: resultT, loc };
|
|
1616
|
+
}
|
|
1617
|
+
/** Fuse only our own f64-array read helper with immediate ToNumber.
|
|
1618
|
+
* Reuse its arguments verbatim so the receiver and index still evaluate
|
|
1619
|
+
* exactly once, in order, before the read. Do not specialize user calls,
|
|
1620
|
+
* union-element arrays, or optional values stored in locals. */
|
|
1621
|
+
export function tryLowerNumericIndexRead(lowerer, operand, loc) {
|
|
1622
|
+
if (operand.kind !== "call" ||
|
|
1623
|
+
operand.callee !== lowerer.arrHofHelpers.get(`idxOr:${typeKey(F64)}`))
|
|
1624
|
+
return null;
|
|
1625
|
+
const [arr, index] = operand.args;
|
|
1626
|
+
if (operand.args.length !== 2 ||
|
|
1627
|
+
arr?.type.kind !== "array" ||
|
|
1628
|
+
arr.type.elem.kind !== "f64" ||
|
|
1629
|
+
index?.type.kind !== "f64")
|
|
1630
|
+
return null;
|
|
1631
|
+
// The intrinsic owns the evaluated receiver through index evaluation,
|
|
1632
|
+
// then borrows it for one slot lookup. No extra helper parameter or
|
|
1633
|
+
// separate state/getter expressions need to retain the array again.
|
|
1634
|
+
return {
|
|
1635
|
+
kind: "arrIntrinsic",
|
|
1636
|
+
method: "getNumber",
|
|
1637
|
+
receiver: arr,
|
|
1638
|
+
args: [index],
|
|
1639
|
+
type: F64,
|
|
1640
|
+
loc,
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
/** Backward-compatible name for the npm-static probe path. */
|
|
1644
|
+
export const lowerNpmStaticSafeIndexRead = lowerSafeIndexRead;
|
|
1645
|
+
/** Interned synthetic function for one (elem, argument-shape) concat —
|
|
1646
|
+
* `%arr.concat.<n>(a, x0, x1, ...)`: a fresh array takes a's elements
|
|
1647
|
+
* (pushSpread), then each argument pushes (element) or spreads (array)
|
|
1648
|
+
* in order; the receiver and array arguments are only READ. Rides
|
|
1649
|
+
* liftedFns like the HOF helpers (a plain function — no captures). */
|
|
1650
|
+
function arrayConcatHelper(lowerer, elem, shape, loc) {
|
|
1651
|
+
const key = `concat:${typeKey(elem)}:${shape.join("")}`;
|
|
1652
|
+
const existing = lowerer.arrHofHelpers.get(key);
|
|
1653
|
+
if (existing)
|
|
1654
|
+
return existing;
|
|
1655
|
+
const name = `%arr.concat.${lowerer.arrHofHelpers.size}`;
|
|
1656
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
1657
|
+
const arrT = arrayOf(elem);
|
|
1658
|
+
const locals = [
|
|
1659
|
+
{ id: "a.0", name: "a", type: arrT, mutable: false },
|
|
1660
|
+
...shape.map((s, i) => ({
|
|
1661
|
+
id: `x.${i}`,
|
|
1662
|
+
name: `x${i}`,
|
|
1663
|
+
type: s === "a" ? arrT : elem,
|
|
1664
|
+
mutable: false,
|
|
1665
|
+
})),
|
|
1666
|
+
{ id: "out.0", name: "out", type: arrT, mutable: false },
|
|
1667
|
+
];
|
|
1668
|
+
const params = [
|
|
1669
|
+
{ localId: "a.0", name: "a", type: arrT },
|
|
1670
|
+
...shape.map((s, i) => ({
|
|
1671
|
+
localId: `x.${i}`,
|
|
1672
|
+
name: `x${i}`,
|
|
1673
|
+
type: s === "a" ? arrT : elem,
|
|
1674
|
+
})),
|
|
1675
|
+
];
|
|
1676
|
+
const append = (s, src) => ({
|
|
1677
|
+
kind: "exprStmt",
|
|
1678
|
+
expr: {
|
|
1679
|
+
kind: "arrIntrinsic",
|
|
1680
|
+
method: s === "a" ? "concatSpread" : "push",
|
|
1681
|
+
receiver: varRef("out.0", arrT, loc),
|
|
1682
|
+
args: [src],
|
|
1683
|
+
type: F64,
|
|
1684
|
+
loc,
|
|
1685
|
+
},
|
|
1686
|
+
loc,
|
|
1687
|
+
});
|
|
1688
|
+
const body = [
|
|
1689
|
+
{
|
|
1690
|
+
kind: "varDecl",
|
|
1691
|
+
localId: "out.0",
|
|
1692
|
+
init: { kind: "arrayLit", elems: [], type: arrT, loc },
|
|
1693
|
+
loc,
|
|
1694
|
+
},
|
|
1695
|
+
append("a", varRef("a.0", arrT, loc)),
|
|
1696
|
+
...shape.map((s, i) => append(s, varRef(`x.${i}`, s === "a" ? arrT : elem, loc))),
|
|
1697
|
+
{ kind: "return", value: varRef("out.0", arrT, loc), loc },
|
|
1698
|
+
];
|
|
1699
|
+
lowerer.liftedFns.push({ name, params, returnType: arrT, locals, body, loc });
|
|
1700
|
+
return name;
|
|
1701
|
+
}
|
|
1702
|
+
/** `a.at(i)` — the es2022 relative-index read. Desugars to an interned
|
|
1703
|
+
* helper over existing IR nodes, ToIntegerOrInfinity-exact: the index
|
|
1704
|
+
* truncates toward zero (floor for non-negatives, mirrored floor for
|
|
1705
|
+
* negatives, NaN → 0), negatives wrap by the length once, and anything
|
|
1706
|
+
* still outside [0, n) answers the undefined arm — never a bounds throw.
|
|
1707
|
+
* The result is the checker's own `T | undefined` union, the find
|
|
1708
|
+
* machinery's wrap rules (an undefined-armed element type passes
|
|
1709
|
+
* through). */
|
|
1710
|
+
function lowerArrayAtCall(lowerer, call, access, elem) {
|
|
1711
|
+
const loc = locOf(call);
|
|
1712
|
+
if (call.arguments.some(ts.isSpreadElement))
|
|
1713
|
+
lowerer.noLowering(".at with spread arguments", call);
|
|
1714
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
1715
|
+
const indexNode = call.arguments[0];
|
|
1716
|
+
const index = lowerPositionArgument(lowerer, indexNode, numLit(0, loc));
|
|
1717
|
+
const resultT = lowerer.irTypeOf(call);
|
|
1718
|
+
if (resultT.kind !== "union")
|
|
1719
|
+
lowerer.badType(call, lowerer.typeOf(call)); // defensive: T | undefined always maps to a union
|
|
1720
|
+
const undefTag = lowerer.armTag(resultT.unionId, UNDEFINED_T);
|
|
1721
|
+
if (undefTag < 0)
|
|
1722
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
1723
|
+
const key = `at:${typeKey(elem)}:${typeKey(resultT)}:${typeKey(index.type)}`;
|
|
1724
|
+
let name = lowerer.arrHofHelpers.get(key);
|
|
1725
|
+
if (!name) {
|
|
1726
|
+
name = `%arr.at.${lowerer.arrHofHelpers.size}`;
|
|
1727
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
1728
|
+
const arrT = arrayOf(elem);
|
|
1729
|
+
const t = varRef("t.0", F64, loc);
|
|
1730
|
+
const i = varRef("i.0", index.type, loc);
|
|
1731
|
+
const number = varRef("number.0", F64, loc);
|
|
1732
|
+
const n = varRef("n.0", F64, loc);
|
|
1733
|
+
const found = lowerer.coerceToExpected(arrayValueRead(lowerer, varRef("a.0", arrT, loc), t, elem, loc), resultT);
|
|
1734
|
+
const miss = {
|
|
1735
|
+
kind: "unionWrap",
|
|
1736
|
+
unionId: resultT.unionId,
|
|
1737
|
+
tag: undefTag,
|
|
1738
|
+
value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc },
|
|
1739
|
+
type: resultT,
|
|
1740
|
+
loc,
|
|
1741
|
+
};
|
|
1742
|
+
const floorOf = (e) => ({
|
|
1743
|
+
kind: "libCall",
|
|
1744
|
+
fn: "math.floor",
|
|
1745
|
+
args: [e],
|
|
1746
|
+
type: F64,
|
|
1747
|
+
loc,
|
|
1748
|
+
});
|
|
1749
|
+
const lt = (l, r) => ({
|
|
1750
|
+
kind: "bin",
|
|
1751
|
+
op: "<",
|
|
1752
|
+
left: l,
|
|
1753
|
+
right: r,
|
|
1754
|
+
type: BOOL,
|
|
1755
|
+
loc,
|
|
1756
|
+
});
|
|
1757
|
+
const body = [
|
|
1758
|
+
arrayLengthDeclaration(arrT, loc),
|
|
1759
|
+
{
|
|
1760
|
+
kind: "varDecl",
|
|
1761
|
+
localId: "number.0",
|
|
1762
|
+
init: positionNumber(lowerer, i, numLit(0, loc), indexNode ?? call, "array at position"),
|
|
1763
|
+
loc,
|
|
1764
|
+
},
|
|
1765
|
+
// ToIntegerOrInfinity: floor is trunc for i >= 0; negatives mirror
|
|
1766
|
+
// (trunc(i) = -floor(-i)); NaN becomes 0. ±Infinity floors to
|
|
1767
|
+
// itself and falls out of range below, exactly the spec.
|
|
1768
|
+
{ kind: "varDecl", localId: "t.0", init: floorOf(number), loc },
|
|
1769
|
+
{
|
|
1770
|
+
kind: "if",
|
|
1771
|
+
cond: lt(number, numLit(0, loc)),
|
|
1772
|
+
then: [
|
|
1773
|
+
{
|
|
1774
|
+
kind: "assign",
|
|
1775
|
+
localId: "t.0",
|
|
1776
|
+
value: {
|
|
1777
|
+
kind: "bin",
|
|
1778
|
+
op: "-",
|
|
1779
|
+
left: numLit(0, loc),
|
|
1780
|
+
right: floorOf({
|
|
1781
|
+
kind: "bin",
|
|
1782
|
+
op: "-",
|
|
1783
|
+
left: numLit(0, loc),
|
|
1784
|
+
right: number,
|
|
1785
|
+
type: F64,
|
|
1786
|
+
loc,
|
|
1787
|
+
}),
|
|
1788
|
+
type: F64,
|
|
1789
|
+
loc,
|
|
1790
|
+
},
|
|
1791
|
+
loc,
|
|
1792
|
+
},
|
|
1793
|
+
],
|
|
1794
|
+
else_: null,
|
|
1795
|
+
loc,
|
|
1796
|
+
},
|
|
1797
|
+
{
|
|
1798
|
+
kind: "if",
|
|
1799
|
+
cond: { kind: "libCall", fn: "num.isNaN", args: [number], type: BOOL, loc },
|
|
1800
|
+
then: [{ kind: "assign", localId: "t.0", value: numLit(0, loc), loc }],
|
|
1801
|
+
else_: null,
|
|
1802
|
+
loc,
|
|
1803
|
+
},
|
|
1804
|
+
{
|
|
1805
|
+
kind: "if",
|
|
1806
|
+
cond: lt(t, numLit(0, loc)),
|
|
1807
|
+
then: [
|
|
1808
|
+
{
|
|
1809
|
+
kind: "assign",
|
|
1810
|
+
localId: "t.0",
|
|
1811
|
+
value: { kind: "bin", op: "+", left: t, right: n, type: F64, loc },
|
|
1812
|
+
loc,
|
|
1813
|
+
},
|
|
1814
|
+
],
|
|
1815
|
+
else_: null,
|
|
1816
|
+
loc,
|
|
1817
|
+
},
|
|
1818
|
+
{
|
|
1819
|
+
kind: "if",
|
|
1820
|
+
cond: lt(t, numLit(0, loc)),
|
|
1821
|
+
then: [{ kind: "return", value: miss, loc }],
|
|
1822
|
+
else_: null,
|
|
1823
|
+
loc,
|
|
1824
|
+
},
|
|
1825
|
+
{
|
|
1826
|
+
kind: "if",
|
|
1827
|
+
cond: { kind: "bin", op: ">=", left: t, right: n, type: BOOL, loc },
|
|
1828
|
+
then: [{ kind: "return", value: miss, loc }],
|
|
1829
|
+
else_: null,
|
|
1830
|
+
loc,
|
|
1831
|
+
},
|
|
1832
|
+
{ kind: "return", value: found, loc },
|
|
1833
|
+
];
|
|
1834
|
+
lowerer.liftedFns.push({
|
|
1835
|
+
name,
|
|
1836
|
+
params: [
|
|
1837
|
+
{ localId: "a.0", name: "a", type: arrT },
|
|
1838
|
+
{ localId: "i.0", name: "i", type: index.type },
|
|
1839
|
+
],
|
|
1840
|
+
returnType: resultT,
|
|
1841
|
+
locals: [
|
|
1842
|
+
{ id: "a.0", name: "a", type: arrT, mutable: true },
|
|
1843
|
+
{ id: "i.0", name: "i", type: index.type, mutable: false },
|
|
1844
|
+
{ id: "n.0", name: "n", type: F64, mutable: false },
|
|
1845
|
+
{ id: "number.0", name: "number", type: F64, mutable: false },
|
|
1846
|
+
{ id: "t.0", name: "t", type: F64, mutable: true },
|
|
1847
|
+
],
|
|
1848
|
+
body,
|
|
1849
|
+
loc,
|
|
1850
|
+
});
|
|
1851
|
+
}
|
|
1852
|
+
return { kind: "call", callee: name, args: [receiver, index], type: resultT, loc };
|
|
1853
|
+
}
|
|
1854
|
+
//# sourceMappingURL=array-methods.js.map
|