@scriptc/compiler 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +682 -50
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +6 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +11 -0
- package/dist/backend/llvm/classes.js +71 -14
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +58 -8
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.js +1 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +12 -3
- package/dist/backend/llvm/dense-array-access.js +72 -14
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +59 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +28 -4
- package/dist/backend/llvm/dyn.js +293 -178
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1190 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1535 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +58 -0
- package/dist/backend/llvm/emit-statements.js +1964 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +547 -283
- package/dist/backend/llvm/emitter.js +689 -4643
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +71 -53
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +39 -15
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +67 -62
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +121 -25
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +2 -2
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +54 -12
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +488 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +189 -23
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +42 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +56 -22
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +90 -50
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +187 -6
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +43 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +2 -2
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.js +2 -2
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +151 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +64 -6
- package/dist/backend/llvm/nullable-unions.js +103 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +4 -0
- package/dist/backend/llvm/publish.js +14 -2
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +12 -1
- package/dist/backend/llvm/record-results.js +64 -4
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +142 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +9 -6
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +1 -1
- package/dist/backend/llvm/shapes.d.ts +66 -43
- package/dist/backend/llvm/shapes.js +280 -21
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +110 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +7 -0
- package/dist/backend/mangle.js +11 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +4 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +37 -0
- package/dist/backend/native/executable.js +192 -137
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +30 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-pack-core.d.ts +9 -1
- package/dist/backend/runtime-pack-core.js +10 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +5 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +5 -0
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +8 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +5 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +44 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +11 -1
- package/dist/cli/usage.js +20 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +13 -0
- package/dist/contracts/check.js +24 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -6
- package/dist/diagnostics/diagnostic.js +29 -21
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +17 -0
- package/dist/executable/executable-cache.js +13 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +7 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +63 -5
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +23 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +156 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +16 -5
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
- package/dist/frontend/lowering/builtins/compression.js +107 -44
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +19 -0
- package/dist/frontend/lowering/builtins/crypto.js +211 -37
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +169 -3
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.js +77 -77
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +232 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +55 -44
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +32 -1
- package/dist/frontend/lowering/builtins/process.js +461 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +37 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +320 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
- package/dist/frontend/lowering/builtins/readline.js +136 -39
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +16 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +75 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
- package/dist/frontend/lowering/builtins/workers.js +193 -8
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +19 -1
- package/dist/frontend/lowering/call-signatures.js +254 -47
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +528 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1115 -89
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +25 -44
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +80 -18
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +261 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +145 -3
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +9 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +266 -100
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +51 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
- package/dist/frontend/lowering/containers/array-from-async.js +159 -14
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +89 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +161 -101
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +54 -25
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +419 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +4 -0
- package/dist/frontend/lowering/cycle-initialization.js +39 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +62 -125
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +703 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2483 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1797 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +40 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +226 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1322 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +253 -85
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +2 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +91 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +110 -0
- package/dist/frontend/lowering/expressions/property-access.js +3544 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1679 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +538 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +39 -0
- package/dist/frontend/lowering/generic-functions.js +393 -75
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +32 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1239 -442
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +50 -3
- package/dist/frontend/lowering/lower-classes.js +1473 -468
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +179 -8
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +258 -70
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1481 -12489
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +68 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +29 -16
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +331 -96
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +8 -1
- package/dist/frontend/lowering/lower-mock.js +185 -18
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +267 -61
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +45 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +488 -100
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +151 -109
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +28 -2
- package/dist/frontend/lowering/lower-stmts.js +1541 -391
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +398 -56
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +437 -62
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +80 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +399 -26
- package/dist/frontend/lowering/lowerer.js +1910 -305
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +10 -10
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +12 -3
- package/dist/frontend/lowering/surfaces.js +252 -41
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.js +13 -6
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.d.ts +51 -0
- package/dist/frontend/npm-static-bundled-chunks.js +810 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +287 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +768 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +207 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +17 -1
- package/dist/frontend/npm-static.js +167 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/pipeline.js +164 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +92 -2
- package/dist/frontend/program.js +1557 -255
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +36 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +20 -1
- package/dist/frontend/services.js +40 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +5 -1
- package/dist/frontend/ts7/program-host.js +12 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +54 -24
- package/dist/frontend/ts7/semantic-model.js +88 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +11 -11
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2545 -719
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +29 -2
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +30 -0
- package/dist/ir/array-length-stability.js +236 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +113 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +103 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +494 -25
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +9 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +97 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +1 -1
- package/dist/ir/integer-loop-facts.d.ts +2 -0
- package/dist/ir/integer-loop-facts.js +24 -3
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +3 -0
- package/dist/ir/integer-ranges.js +3 -1
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +82 -1
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +221 -58
- package/dist/ir/ir.js +119 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +365 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +148 -33
- package/dist/ir/runtime-features.js +629 -386
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +103 -94
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +175 -68
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +26 -9
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +13 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +5 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +2 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/prepare.js +7 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +12 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +21 -20
- package/surface-manifest.json +303 -19
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { boolLit, numLit, varRef } from "../../../ir/build.js";
|
|
2
2
|
import { InternalCompilerError } from "../../../errors.js";
|
|
3
3
|
import * as ts from "../../ts7/adapter.js";
|
|
4
|
-
import { BOOL, F64, STRING, UNDEFINED_T, VOID, arrayOf, typeEquals, } from "../../../ir/ir.js";
|
|
4
|
+
import { BOOL, CAUGHT, DYN, F64, STRING, UNDEFINED_T, VOID, arrayOf, isUnitType, typeEquals, } from "../../../ir/ir.js";
|
|
5
5
|
import { locOf } from "../../program.js";
|
|
6
|
-
import { typeKey } from "../../type-mapper.js";
|
|
6
|
+
import { genResultRecord, typeKey } from "../../type-mapper.js";
|
|
7
7
|
import { concatStrings, throwTypeError } from "./dynamic-receivers.js";
|
|
8
|
+
import { generatorLoopBinding, resultRecordOf, genStep, genValue, stepDrivable, } from "../lower-generators.js";
|
|
9
|
+
import { classGeneratorIterable, iteratesThroughGenerator } from "../class-iterables.js";
|
|
10
|
+
import { exitBeforeReturns } from "./for-of.js";
|
|
11
|
+
import { iteratorSlotAdapter, lowerArrayIteratorValue, lowerBytesIteratorValue, lowerCollectionIteratorValue, lowerStringIteratorValue, } from "../iterator-adapters.js";
|
|
12
|
+
import { lowerArrayCallback } from "./callback-arguments.js";
|
|
8
13
|
/* ── iterator helpers (ES2025) ─────────────────────────────────────────── */
|
|
9
14
|
/** The lowered iterator-helper chains: `arr.values()` (the array
|
|
10
15
|
* iterator) through any run of map/filter/take/drop/flatMap into a
|
|
@@ -19,9 +24,9 @@ import { concatStrings, throwTypeError } from "./dynamic-receivers.js";
|
|
|
19
24
|
* raw value in the message) through an interned checker call inserted
|
|
20
25
|
* at the argument's evaluation position. The source array is iterated
|
|
21
26
|
* LIVE by index against a re-read length, exactly the array iterator's
|
|
22
|
-
* contract.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
27
|
+
* contract. Chains over generators and other iterator objects lower in
|
|
28
|
+
* lowerGeneratorHelperCall. Null when the callee isn't a terminal over
|
|
29
|
+
* such a chain. */
|
|
25
30
|
export function lowerIteratorHelperCall(lowerer, call, access) {
|
|
26
31
|
if (call.questionDotToken || access.questionDotToken)
|
|
27
32
|
return null;
|
|
@@ -41,7 +46,7 @@ export function lowerIteratorHelperCall(lowerer, call, access) {
|
|
|
41
46
|
if (cur.questionDotToken || cur.expression.questionDotToken)
|
|
42
47
|
return null;
|
|
43
48
|
const name = cur.expression.name.text;
|
|
44
|
-
if ((name === "values" || name === "entries") && cur.arguments.length === 0) {
|
|
49
|
+
if ((name === "values" || name === "entries") && cur.arguments.nodes.length === 0) {
|
|
45
50
|
const recvIr = lowerer.mapTypeOf(lowerer.typeOf(cur.expression.expression));
|
|
46
51
|
if (recvIr?.kind !== "array")
|
|
47
52
|
return null;
|
|
@@ -52,21 +57,19 @@ export function lowerIteratorHelperCall(lowerer, call, access) {
|
|
|
52
57
|
break;
|
|
53
58
|
}
|
|
54
59
|
if (!ITER_STAGES.has(name) ||
|
|
55
|
-
cur.arguments.length !== 1 ||
|
|
56
|
-
ts.isSpreadElement(cur.arguments[0]))
|
|
60
|
+
cur.arguments.nodes.length !== 1 ||
|
|
61
|
+
ts.isSpreadElement(cur.arguments.nodes[0]))
|
|
57
62
|
return null;
|
|
58
|
-
stages.push({ name, argNode: cur.arguments[0] });
|
|
63
|
+
stages.push({ name, argNode: cur.arguments.nodes[0], access: cur.expression });
|
|
59
64
|
cur = cur.expression.expression;
|
|
60
65
|
}
|
|
61
66
|
stages.reverse(); // source order
|
|
62
67
|
for (const s of stages) {
|
|
63
|
-
|
|
64
|
-
if (acc !== null && !lowerer.isStdlibMember(acc))
|
|
68
|
+
if (!lowerer.isStdlibMember(s.access))
|
|
65
69
|
return null;
|
|
66
70
|
}
|
|
67
71
|
if (!lowerer.isStdlibMember(access))
|
|
68
72
|
return null;
|
|
69
|
-
const loc = locOf(call);
|
|
70
73
|
// Lower everything in SOURCE ORDER (the chain's own evaluation
|
|
71
74
|
// order): the source array, each stage argument, the terminal's.
|
|
72
75
|
const items = lowerer.lowerExpr(source);
|
|
@@ -75,77 +78,611 @@ export function lowerIteratorHelperCall(lowerer, call, access) {
|
|
|
75
78
|
// The entries() seed: the interned [number, T] tuple — the same shape
|
|
76
79
|
// the checker's own [number, T] maps to, so stage callbacks typed
|
|
77
80
|
// against the lib's pairs intern equal.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
const elem = srcProj === "entries" ? entryPairType(lowerer, items.type.elem) : items.type.elem;
|
|
82
|
+
return lowerFusedChain(lowerer, call, terminal, stages, { kind: "array", type: items.type, proj: srcProj }, items, elem);
|
|
83
|
+
}
|
|
84
|
+
/** Iterator-helper calls whose receiver is an iterator object: a
|
|
85
|
+
* generator, a stored array iterator, a helper result (IteratorObject),
|
|
86
|
+
* an `Iterator<T>` value, or a Map/Set iterator (adapted into a
|
|
87
|
+
* generator over the live collection).
|
|
88
|
+
*
|
|
89
|
+
* - A terminal (toArray/forEach/reduce/some/every/find) fuses the chain
|
|
90
|
+
* of helper stages before it into one loop over the source generator,
|
|
91
|
+
* with the helpers' pull order and closing: the source is closed (its
|
|
92
|
+
* `return()` runs) when take's budget is spent, a short-circuit
|
|
93
|
+
* terminal hits, or a callback throws, and is not closed when it is
|
|
94
|
+
* exhausted or its own `next()` throws.
|
|
95
|
+
* - A stage (map/filter/take/drop/flatMap) outside such a chain builds
|
|
96
|
+
* an iterator helper object: a generator over its source that pulls
|
|
97
|
+
* lazily, closes the source on early exit, and closes it on a
|
|
98
|
+
* `return()` before the first `next()` (`closesSource`).
|
|
99
|
+
*
|
|
100
|
+
* Budgets and callbacks validate at the call, as in Node. Null when the
|
|
101
|
+
* call is not such a helper call. */
|
|
102
|
+
export function lowerGeneratorHelperCall(lowerer, call, access) {
|
|
103
|
+
if (call.questionDotToken || access.questionDotToken)
|
|
104
|
+
return null;
|
|
105
|
+
const name = access.name.text;
|
|
106
|
+
const isTerminal = ITER_TERMINALS.has(name);
|
|
107
|
+
if (!isTerminal && !ITER_STAGES.has(name))
|
|
108
|
+
return null;
|
|
109
|
+
if (!isHelperReceiver(lowerer, access.expression))
|
|
110
|
+
return null;
|
|
111
|
+
if (!lowerer.isStdlibMember(access))
|
|
112
|
+
return null;
|
|
113
|
+
const loc = locOf(call);
|
|
114
|
+
if (!isTerminal) {
|
|
115
|
+
const argNode = call.arguments.nodes[0];
|
|
116
|
+
if (call.arguments.nodes.length !== 1 || argNode === undefined || ts.isSpreadElement(argNode)) {
|
|
117
|
+
lowerer.noLowering(`.${name} with ${call.arguments.nodes.length} arguments`, call);
|
|
85
118
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (
|
|
90
|
-
const
|
|
91
|
-
if (
|
|
92
|
-
lowerer.badType(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
119
|
+
// A stage on m.keys()/values()/entries() (or a Set's) walks the
|
|
120
|
+
// collection inside the helper's own generator.
|
|
121
|
+
const collection = collectionIteratorCall(lowerer, access.expression);
|
|
122
|
+
if (collection !== null) {
|
|
123
|
+
const coll = lowerer.lowerExpr(collection.receiver);
|
|
124
|
+
if (coll.type.kind !== "map" && coll.type.kind !== "set")
|
|
125
|
+
lowerer.badType(collection.receiver, lowerer.typeOf(collection.receiver));
|
|
126
|
+
const source = { kind: "collection", type: coll.type, proj: collection.proj };
|
|
127
|
+
const elem = collectionSeed(lowerer, source);
|
|
128
|
+
const { stage, out } = lowerStage(lowerer, { name, argNode, access }, elem, loc);
|
|
129
|
+
return lowerHelperObject(lowerer, call, coll, source, elem, stage, out, loc);
|
|
130
|
+
}
|
|
131
|
+
const src = lowerHelperSource(lowerer, access.expression);
|
|
132
|
+
if (name !== "take" && name !== "drop") {
|
|
133
|
+
const { stage, out } = lowerStage(lowerer, { name, argNode, access }, src.elem, loc);
|
|
134
|
+
return lowerHelperObject(lowerer, call, src.gen, { kind: "generator", type: src.gen.type, elem: src.elem }, src.elem, stage, out, loc);
|
|
135
|
+
}
|
|
136
|
+
// The budget check closes the source, so the source is bound first.
|
|
137
|
+
const bound = bindSource(lowerer, src.gen, loc);
|
|
138
|
+
const { stage, out } = lowerStage(lowerer, { name, argNode, access }, src.elem, loc, bound.ref);
|
|
139
|
+
const helper = lowerHelperObject(lowerer, call, bound.ref, { kind: "generator", type: src.gen.type, elem: src.elem }, src.elem, stage, out, loc);
|
|
140
|
+
return { kind: "seqExpr", stmts: [bound.decl], result: helper, type: helper.type, loc };
|
|
141
|
+
}
|
|
142
|
+
// The stages before the terminal, back to the first receiver that is
|
|
143
|
+
// not itself a helper stage.
|
|
144
|
+
const stages = [];
|
|
145
|
+
let cur = access.expression;
|
|
146
|
+
while (isStageCall(lowerer, cur)) {
|
|
147
|
+
const stageAccess = cur.expression;
|
|
148
|
+
stages.push({
|
|
149
|
+
name: stageAccess.name.text,
|
|
150
|
+
argNode: cur.arguments.nodes[0],
|
|
151
|
+
access: stageAccess,
|
|
152
|
+
});
|
|
153
|
+
cur = stageAccess.expression;
|
|
154
|
+
}
|
|
155
|
+
stages.reverse(); // source order
|
|
156
|
+
// A chain from m.keys()/values()/entries() (or a Set's) walks the
|
|
157
|
+
// collection itself, live, as for-of does.
|
|
158
|
+
const collection = collectionIteratorCall(lowerer, cur);
|
|
159
|
+
if (collection !== null) {
|
|
160
|
+
const items = lowerer.lowerExpr(collection.receiver);
|
|
161
|
+
if (items.type.kind !== "map" && items.type.kind !== "set")
|
|
162
|
+
lowerer.badType(collection.receiver, lowerer.typeOf(collection.receiver));
|
|
163
|
+
const source = { kind: "collection", type: items.type, proj: collection.proj };
|
|
164
|
+
return lowerFusedChain(lowerer, call, name, stages, source, items, collectionSeed(lowerer, source));
|
|
165
|
+
}
|
|
166
|
+
// Iterator.from(arr) walks the array by index.
|
|
167
|
+
const arrayRoot = arrayIteratorCall(lowerer, cur);
|
|
168
|
+
if (arrayRoot !== null) {
|
|
169
|
+
const items = lowerer.lowerExpr(arrayRoot.receiver);
|
|
170
|
+
if (items.type.kind !== "array")
|
|
171
|
+
lowerer.badType(arrayRoot.receiver, lowerer.typeOf(arrayRoot.receiver));
|
|
172
|
+
const elem = arrayRoot.proj === "entries" ? entryPairType(lowerer, items.type.elem) : items.type.elem;
|
|
173
|
+
return lowerFusedChain(lowerer, call, name, stages, { kind: "array", type: items.type, proj: arrayRoot.proj }, items, elem);
|
|
174
|
+
}
|
|
175
|
+
const src = lowerHelperSource(lowerer, cur);
|
|
176
|
+
return lowerFusedChain(lowerer, call, name, stages, { kind: "generator", type: src.gen.type, elem: src.elem }, src.gen, src.elem);
|
|
177
|
+
}
|
|
178
|
+
/** `h.return!()` or `h.return?.()` on a helper object. The lib declares
|
|
179
|
+
* return() as optional on iterator objects, and a helper object always
|
|
180
|
+
* has one, so both spellings are the call: the helper completes and closes
|
|
181
|
+
* its source, and the result is `{ value: undefined, done: true }`. The
|
|
182
|
+
* receiver must be provably a helper object — a helper stage call, or a
|
|
183
|
+
* const binding initialized with one — since other iterator objects (the
|
|
184
|
+
* array, string, Map and Set iterators) have no return(). Null otherwise,
|
|
185
|
+
* and for the plain `h.return()` spelling (lowerGenMethodCall's). */
|
|
186
|
+
export function lowerHelperReturnCall(lowerer, call) {
|
|
187
|
+
let callee = call.expression;
|
|
188
|
+
const nonNull = ts.isNonNullExpression(callee);
|
|
189
|
+
if (nonNull)
|
|
190
|
+
callee = callee.expression;
|
|
191
|
+
if (!nonNull && call.questionDotToken === undefined)
|
|
192
|
+
return null;
|
|
193
|
+
if (!ts.isPropertyAccessExpression(callee) || callee.questionDotToken)
|
|
194
|
+
return null;
|
|
195
|
+
if (callee.name.text !== "return" || call.arguments.nodes.length !== 0)
|
|
196
|
+
return null;
|
|
197
|
+
if (!isHelperObject(lowerer, callee.expression) || !lowerer.isStdlibMember(callee))
|
|
198
|
+
return null;
|
|
199
|
+
const callT = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
200
|
+
const gen = lowerer.lowerExpr(callee.expression);
|
|
201
|
+
if (gen.type.kind !== "generator" || gen.type.async)
|
|
202
|
+
return null;
|
|
203
|
+
const loc = locOf(call);
|
|
204
|
+
const recT = resultRecordOf(lowerer, gen.type);
|
|
205
|
+
const resume = { kind: "genResume", mode: "return", gen, arg: null, type: recT, loc };
|
|
206
|
+
// `?.` types the call `IteratorResult | undefined`, which has no mapping
|
|
207
|
+
// as a whole; the result is never undefined, so it is the record itself.
|
|
208
|
+
if (callT === null || typeEquals(callT, recT))
|
|
209
|
+
return resume;
|
|
210
|
+
const result = lowerer.coerceToExpected(resume, callT);
|
|
211
|
+
if (!typeEquals(result.type, callT))
|
|
212
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
215
|
+
/** Whether `expr` is a helper stage call, or a const binding initialized
|
|
216
|
+
* with one. */
|
|
217
|
+
function isHelperObject(lowerer, expr) {
|
|
218
|
+
while (ts.isParenthesizedExpression(expr))
|
|
219
|
+
expr = expr.expression;
|
|
220
|
+
if (isStageCall(lowerer, expr))
|
|
221
|
+
return true;
|
|
222
|
+
if (!ts.isIdentifier(expr))
|
|
223
|
+
return false;
|
|
224
|
+
const symbol = lowerer.resolveValueSymbol(expr);
|
|
225
|
+
const decl = symbol ? symbol.valueDeclaration : undefined;
|
|
226
|
+
if (!decl ||
|
|
227
|
+
!ts.isVariableDeclaration(decl) ||
|
|
228
|
+
decl.initializer === undefined ||
|
|
229
|
+
!ts.isVariableDeclarationList(decl.parent) ||
|
|
230
|
+
(decl.parent.flags & ts.NodeFlags.Const) === 0)
|
|
231
|
+
return false;
|
|
232
|
+
let init = decl.initializer;
|
|
233
|
+
while (ts.isParenthesizedExpression(init))
|
|
234
|
+
init = init.expression;
|
|
235
|
+
return isStageCall(lowerer, init);
|
|
236
|
+
}
|
|
237
|
+
/** `Iterator.from(value)` over a typed built-in iterable: the value's own
|
|
238
|
+
* iterator, which already inherits from Iterator.prototype, so Node returns
|
|
239
|
+
* it rather than a wrapper. A generator (including a helper object or an
|
|
240
|
+
* array iterator) is itself; an array, string or typed array gives its
|
|
241
|
+
* values iterator; a Set its values and a Map its entries, as a generator
|
|
242
|
+
* over the live collection; a class instance whose `[Symbol.iterator]` is
|
|
243
|
+
* a generator method gives the generator it returns. The result converts
|
|
244
|
+
* into the call's IteratorObject type. Null for other arguments (objects
|
|
245
|
+
* with their own next method, untyped values), which keep the Iterator
|
|
246
|
+
* fence. */
|
|
247
|
+
export function lowerIteratorFromCall(lowerer, call, access) {
|
|
248
|
+
if (access.name.text !== "from" || call.arguments.nodes.length !== 1)
|
|
249
|
+
return null;
|
|
250
|
+
const argNode = call.arguments.nodes[0];
|
|
251
|
+
if (ts.isSpreadElement(argNode))
|
|
252
|
+
return null;
|
|
253
|
+
const resultT = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
254
|
+
const argT = lowerer.mapTypeOf(lowerer.typeOf(argNode));
|
|
255
|
+
if (resultT?.kind !== "generator" || resultT.async || argT === null)
|
|
256
|
+
return null;
|
|
257
|
+
const iterableKinds = ["generator", "array", "string", "bytes", "set", "map"];
|
|
258
|
+
const classIterable = iteratesThroughGenerator(lowerer, argT);
|
|
259
|
+
if (!classIterable && !iterableKinds.includes(argT.kind))
|
|
260
|
+
return null;
|
|
261
|
+
if (argT.kind === "generator" && argT.async)
|
|
262
|
+
return null;
|
|
263
|
+
const loc = locOf(call);
|
|
264
|
+
const value = lowerer.lowerExpr(argNode);
|
|
265
|
+
const own = (yieldT) => ({
|
|
266
|
+
kind: "generator",
|
|
267
|
+
yieldT,
|
|
268
|
+
retT: VOID,
|
|
269
|
+
nextT: UNDEFINED_T,
|
|
270
|
+
});
|
|
271
|
+
let iterator = null;
|
|
272
|
+
const t = value.type;
|
|
273
|
+
if (t.kind === "generator")
|
|
274
|
+
iterator = value;
|
|
275
|
+
else if (classIterable)
|
|
276
|
+
iterator = classGeneratorIterable(lowerer, value);
|
|
277
|
+
else if (t.kind === "array")
|
|
278
|
+
iterator = lowerArrayIteratorValue(lowerer, value, "values", own(t.elem), loc);
|
|
279
|
+
else if (t.kind === "string")
|
|
280
|
+
iterator = lowerStringIteratorValue(lowerer, value, own(STRING), loc);
|
|
281
|
+
else if (t.kind === "bytes")
|
|
282
|
+
iterator = lowerBytesIteratorValue(lowerer, value, "values", own(F64), loc);
|
|
283
|
+
else if (t.kind === "set" || t.kind === "map") {
|
|
284
|
+
const elem = t.kind === "set" ? t.elem : entryPairTypeOf(lowerer, t.key, t.value);
|
|
285
|
+
iterator = lowerCollectionIteratorValue(lowerer, value, t.kind === "set" ? "values" : "entries", own(elem), loc);
|
|
286
|
+
}
|
|
287
|
+
if (iterator === null)
|
|
288
|
+
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
289
|
+
const result = lowerer.coerceToExpected(iterator, resultT);
|
|
290
|
+
if (!typeEquals(result.type, resultT))
|
|
291
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
/** The interned [K, V] pair a Map's entries yield. */
|
|
295
|
+
function entryPairTypeOf(lowerer, keyT, valueT) {
|
|
296
|
+
return {
|
|
297
|
+
kind: "record",
|
|
298
|
+
shapeId: lowerer.shapes.intern([
|
|
299
|
+
{ name: "0", type: keyT },
|
|
300
|
+
{ name: "1", type: valueT },
|
|
301
|
+
], true),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const ITER_STAGES = new Set(["map", "filter", "take", "drop", "flatMap"]);
|
|
305
|
+
const ITER_TERMINALS = new Set(["toArray", "forEach", "reduce", "some", "every", "find"]);
|
|
306
|
+
/** Native iterators that ride checked runtime values and adapt into
|
|
307
|
+
* generators for the helpers. */
|
|
308
|
+
const ADAPTED_ITERATOR_TYPES = new Set(["MapIterator", "SetIterator"]);
|
|
309
|
+
/** `for (x of <chain>)` where the head is a run of map/filter/take/drop
|
|
310
|
+
* stages over an array iterator, a Map or Set iterator, or a generator:
|
|
311
|
+
* one loop over the source with the stages nested in it and the loop body
|
|
312
|
+
* innermost, instead of a helper object per stage. The pull order and the
|
|
313
|
+
* closing are the helpers': `break`, `return` and throws from the body
|
|
314
|
+
* close a generator source (run its `return()`), and take closes it on
|
|
315
|
+
* the pass after its last delivery. Chains with flatMap keep the helper
|
|
316
|
+
* objects (a `break` there leaves an inner loop). Null when the head is
|
|
317
|
+
* not such a chain. */
|
|
318
|
+
export function lowerForOfHelperChain(lowerer, stmt, labels) {
|
|
319
|
+
if (stmt.awaitModifier)
|
|
320
|
+
return null;
|
|
321
|
+
if (ts.isVariableDeclarationList(stmt.initializer) &&
|
|
322
|
+
(stmt.initializer.flags & ts.NodeFlags.Using) !== 0)
|
|
323
|
+
return null;
|
|
324
|
+
let head = stmt.expression;
|
|
325
|
+
while (ts.isParenthesizedExpression(head))
|
|
326
|
+
head = head.expression;
|
|
327
|
+
const stages = [];
|
|
328
|
+
let cur = head;
|
|
329
|
+
while (isStageCall(lowerer, cur)) {
|
|
330
|
+
const stageAccess = cur.expression;
|
|
331
|
+
if (stageAccess.name.text === "flatMap")
|
|
332
|
+
return null;
|
|
333
|
+
stages.push({
|
|
334
|
+
name: stageAccess.name.text,
|
|
335
|
+
argNode: cur.arguments.nodes[0],
|
|
336
|
+
access: stageAccess,
|
|
337
|
+
});
|
|
338
|
+
cur = stageAccess.expression;
|
|
339
|
+
}
|
|
340
|
+
if (stages.length === 0)
|
|
341
|
+
return null;
|
|
342
|
+
stages.reverse(); // source order
|
|
343
|
+
const arrayRoot = arrayIteratorCall(lowerer, cur);
|
|
344
|
+
const collection = arrayRoot === null ? collectionIteratorCall(lowerer, cur) : null;
|
|
345
|
+
if (arrayRoot === null && collection === null) {
|
|
346
|
+
const mapped = lowerer.mapTypeOf(lowerer.typeOf(cur));
|
|
347
|
+
if (mapped?.kind !== "generator" || !stepDrivable(mapped))
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
const loc = locOf(stmt);
|
|
351
|
+
lowerer.scopes.push(new Map());
|
|
352
|
+
try {
|
|
353
|
+
const frame = new HostFrame(lowerer, loc);
|
|
354
|
+
let items;
|
|
355
|
+
let source;
|
|
356
|
+
let elem;
|
|
357
|
+
if (arrayRoot !== null) {
|
|
358
|
+
items = lowerer.lowerExpr(arrayRoot.receiver);
|
|
359
|
+
if (items.type.kind !== "array")
|
|
360
|
+
lowerer.badType(arrayRoot.receiver, lowerer.typeOf(arrayRoot.receiver));
|
|
361
|
+
source = { kind: "array", type: items.type, proj: arrayRoot.proj };
|
|
362
|
+
elem =
|
|
363
|
+
arrayRoot.proj === "entries" ? entryPairType(lowerer, items.type.elem) : items.type.elem;
|
|
364
|
+
}
|
|
365
|
+
else if (collection !== null) {
|
|
366
|
+
items = lowerer.lowerExpr(collection.receiver);
|
|
367
|
+
if (items.type.kind !== "map" && items.type.kind !== "set")
|
|
368
|
+
lowerer.badType(collection.receiver, lowerer.typeOf(collection.receiver));
|
|
369
|
+
source = { kind: "collection", type: items.type, proj: collection.proj };
|
|
370
|
+
elem = collectionSeed(lowerer, source);
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
const src = lowerHelperSource(lowerer, cur);
|
|
374
|
+
items = src.gen;
|
|
375
|
+
source = { kind: "generator", type: src.gen.type, elem: src.elem };
|
|
376
|
+
elem = src.elem;
|
|
377
|
+
}
|
|
378
|
+
const itemsId = frame.local("items", items.type, false);
|
|
379
|
+
const out = [{ kind: "varDecl", localId: itemsId, init: items, loc }];
|
|
380
|
+
// Stage arguments evaluate in chain order, before the first pull.
|
|
381
|
+
const slots = [];
|
|
382
|
+
for (const s of stages) {
|
|
383
|
+
const { stage, out: next } = lowerStage(lowerer, s, elem, loc, source.kind === "generator"
|
|
384
|
+
? varRef(itemsId, source.type, loc)
|
|
385
|
+
: null);
|
|
386
|
+
const arg = "budget" in stage ? stage.budget : stage.fn;
|
|
387
|
+
const argId = frame.local("budget" in stage ? "n" : "f", arg.type, false);
|
|
388
|
+
out.push({ kind: "varDecl", localId: argId, init: arg, loc });
|
|
389
|
+
slots.push(stageSlot(frame, stage, argId));
|
|
390
|
+
elem = next;
|
|
391
|
+
}
|
|
392
|
+
const doneId = frame.local("done", BOOL, true);
|
|
393
|
+
out.push(...stagePrologue(slots, doneId, loc));
|
|
394
|
+
// Each delivered value lands in a hidden local the loop binding reads.
|
|
395
|
+
const valueId = frame.local("hv", elem, false);
|
|
396
|
+
const binds = generatorLoopBinding(lowerer, stmt, varRef(valueId, elem, loc), elem);
|
|
397
|
+
let body = lowerer.inCtl("loop", () => lowerer.lowerScopedBlock(stmt.statement), source.kind === "collection" ? undefined : labels);
|
|
398
|
+
if (source.kind === "collection") {
|
|
399
|
+
// A return from the body ends the live walk first, as for-of does.
|
|
400
|
+
const t = source.type;
|
|
401
|
+
body = exitBeforeReturns(body, () => ({
|
|
402
|
+
kind: "exprStmt",
|
|
403
|
+
expr: t.kind === "map"
|
|
404
|
+
? {
|
|
405
|
+
kind: "mapIntrinsic",
|
|
406
|
+
method: "iterExit",
|
|
407
|
+
receiver: varRef(itemsId, t, loc),
|
|
408
|
+
args: [],
|
|
409
|
+
type: VOID,
|
|
410
|
+
loc,
|
|
411
|
+
}
|
|
412
|
+
: {
|
|
413
|
+
kind: "setIntrinsic",
|
|
414
|
+
method: "iterExit",
|
|
415
|
+
receiver: varRef(itemsId, t, loc),
|
|
416
|
+
args: [],
|
|
417
|
+
type: VOID,
|
|
418
|
+
loc,
|
|
419
|
+
},
|
|
420
|
+
loc,
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
423
|
+
const emit = foldStages(lowerer, frame, slots, (value) => [{ kind: "varDecl", localId: valueId, init: value, loc }, ...binds, ...body], doneId, loc);
|
|
424
|
+
out.push(...sourceLoop(lowerer, frame, itemsId, source, doneId, emit, loc, source.kind === "collection" ? undefined : labels));
|
|
425
|
+
return { kind: "block", body: out, loc };
|
|
426
|
+
}
|
|
427
|
+
finally {
|
|
428
|
+
lowerer.scopes.pop();
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
/** The argument of an `Iterator.from(x)` call, or null. As a chain's root,
|
|
432
|
+
* the call is the argument's own iterator, so the chain can walk the
|
|
433
|
+
* argument directly. */
|
|
434
|
+
function iteratorFromArgument(lowerer, expr) {
|
|
435
|
+
if (!ts.isCallExpression(expr) || !ts.isPropertyAccessExpression(expr.expression))
|
|
436
|
+
return null;
|
|
437
|
+
if (expr.questionDotToken ||
|
|
438
|
+
expr.expression.questionDotToken ||
|
|
439
|
+
expr.arguments.nodes.length !== 1)
|
|
440
|
+
return null;
|
|
441
|
+
const arg = expr.arguments.nodes[0];
|
|
442
|
+
if (ts.isSpreadElement(arg) || expr.expression.name.text !== "from")
|
|
443
|
+
return null;
|
|
444
|
+
if (!lowerer.isStdlibGlobal(expr.expression.expression, "Iterator"))
|
|
445
|
+
return null;
|
|
446
|
+
return lowerer.isStdlibMember(expr.expression) ? arg : null;
|
|
447
|
+
}
|
|
448
|
+
/** `arr.values()`, `arr.entries()` or `Iterator.from(arr)` on an array value,
|
|
449
|
+
* as the root of a helper chain. */
|
|
450
|
+
function arrayIteratorCall(lowerer, expr) {
|
|
451
|
+
const fromArg = iteratorFromArgument(lowerer, expr);
|
|
452
|
+
if (fromArg !== null)
|
|
453
|
+
return lowerer.mapTypeOf(lowerer.typeOf(fromArg))?.kind === "array"
|
|
454
|
+
? { receiver: fromArg, proj: "values" }
|
|
455
|
+
: null;
|
|
456
|
+
if (!ts.isCallExpression(expr) || !ts.isPropertyAccessExpression(expr.expression))
|
|
457
|
+
return null;
|
|
458
|
+
if (expr.questionDotToken ||
|
|
459
|
+
expr.expression.questionDotToken ||
|
|
460
|
+
expr.arguments.nodes.length !== 0)
|
|
461
|
+
return null;
|
|
462
|
+
const proj = expr.expression.name.text;
|
|
463
|
+
if (proj !== "values" && proj !== "entries")
|
|
464
|
+
return null;
|
|
465
|
+
if (lowerer.mapTypeOf(lowerer.typeOf(expr.expression.expression))?.kind !== "array")
|
|
466
|
+
return null;
|
|
467
|
+
if (!lowerer.isStdlibMember(expr.expression))
|
|
468
|
+
return null;
|
|
469
|
+
return { receiver: expr.expression.expression, proj };
|
|
470
|
+
}
|
|
471
|
+
/** `m.keys()`, `m.values()` or `m.entries()` (or a Set's) on a Map or
|
|
472
|
+
* Set value, as the root of a helper chain. */
|
|
473
|
+
function collectionIteratorCall(lowerer, expr) {
|
|
474
|
+
// Iterator.from(set) is the Set's values iterator, Iterator.from(map) the
|
|
475
|
+
// Map's entries iterator.
|
|
476
|
+
const fromArg = iteratorFromArgument(lowerer, expr);
|
|
477
|
+
if (fromArg !== null) {
|
|
478
|
+
const kind = lowerer.mapTypeOf(lowerer.typeOf(fromArg))?.kind;
|
|
479
|
+
return kind === "set"
|
|
480
|
+
? { receiver: fromArg, proj: "values" }
|
|
481
|
+
: kind === "map"
|
|
482
|
+
? { receiver: fromArg, proj: "entries" }
|
|
483
|
+
: null;
|
|
484
|
+
}
|
|
485
|
+
if (!ts.isCallExpression(expr) || !ts.isPropertyAccessExpression(expr.expression))
|
|
486
|
+
return null;
|
|
487
|
+
if (expr.questionDotToken ||
|
|
488
|
+
expr.expression.questionDotToken ||
|
|
489
|
+
expr.arguments.nodes.length !== 0)
|
|
490
|
+
return null;
|
|
491
|
+
const proj = expr.expression.name.text;
|
|
492
|
+
if (proj !== "keys" && proj !== "values" && proj !== "entries")
|
|
493
|
+
return null;
|
|
494
|
+
const kind = lowerer.mapTypeOf(lowerer.typeOf(expr.expression.expression))?.kind;
|
|
495
|
+
if (kind !== "map" && kind !== "set")
|
|
496
|
+
return null;
|
|
497
|
+
if (!lowerer.isStdlibMember(expr.expression))
|
|
498
|
+
return null;
|
|
499
|
+
return { receiver: expr.expression.expression, proj };
|
|
500
|
+
}
|
|
501
|
+
/** The element a collection chain starts from: a key (a Set's element),
|
|
502
|
+
* a Map's value, or the interned [key, value] pair (a Set's [v, v]). */
|
|
503
|
+
function collectionSeed(lowerer, source) {
|
|
504
|
+
const t = source.type;
|
|
505
|
+
const keyT = t.kind === "map" ? t.key : t.elem;
|
|
506
|
+
if (source.proj === "keys" || (t.kind === "set" && source.proj === "values"))
|
|
507
|
+
return keyT;
|
|
508
|
+
if (source.proj === "values")
|
|
509
|
+
return t.value;
|
|
510
|
+
return {
|
|
511
|
+
kind: "record",
|
|
512
|
+
shapeId: lowerer.shapes.intern([
|
|
513
|
+
{ name: "0", type: keyT },
|
|
514
|
+
{ name: "1", type: t.kind === "map" ? t.value : keyT },
|
|
515
|
+
], true),
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
/** The interned [number, T] pair an array's entries() yields. */
|
|
519
|
+
function entryPairType(lowerer, elem) {
|
|
520
|
+
return {
|
|
521
|
+
kind: "record",
|
|
522
|
+
shapeId: lowerer.shapes.intern([
|
|
523
|
+
{ name: "0", type: F64 },
|
|
524
|
+
{ name: "1", type: elem },
|
|
525
|
+
], true),
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
/** Whether `expr` is an iterator object the helpers lower over: a
|
|
529
|
+
* synchronous generator-typed value, or a Map/Set iterator. */
|
|
530
|
+
function isHelperReceiver(lowerer, expr) {
|
|
531
|
+
const mapped = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
532
|
+
if (mapped?.kind === "generator")
|
|
533
|
+
return mapped.async !== true;
|
|
534
|
+
const symbol = lowerer.typeOf(expr).getSymbol();
|
|
535
|
+
return (mapped?.kind === "dyn" &&
|
|
536
|
+
symbol !== undefined &&
|
|
537
|
+
ADAPTED_ITERATOR_TYPES.has(ts.symbolName(symbol)) &&
|
|
538
|
+
lowerer.isStdlibSymbol(symbol));
|
|
539
|
+
}
|
|
540
|
+
/** Whether `expr` is a stage call (`src.map(f)`) on a helper receiver. */
|
|
541
|
+
function isStageCall(lowerer, expr) {
|
|
542
|
+
if (!ts.isCallExpression(expr) || !ts.isPropertyAccessExpression(expr.expression))
|
|
543
|
+
return false;
|
|
544
|
+
if (expr.questionDotToken || expr.expression.questionDotToken)
|
|
545
|
+
return false;
|
|
546
|
+
if (!ITER_STAGES.has(expr.expression.name.text))
|
|
547
|
+
return false;
|
|
548
|
+
if (expr.arguments.nodes.length !== 1 || ts.isSpreadElement(expr.arguments.nodes[0]))
|
|
549
|
+
return false;
|
|
550
|
+
return (isHelperReceiver(lowerer, expr.expression.expression) && lowerer.isStdlibMember(expr.expression));
|
|
551
|
+
}
|
|
552
|
+
/** The source of a helper call as a synchronous generator — the receiver
|
|
553
|
+
* itself, or a Map/Set iterator adapted into a generator over the live
|
|
554
|
+
* collection — and its element type. A generator whose yield channel is
|
|
555
|
+
* checked-dynamic beside a declared element type (`Generator<P>` boxes a
|
|
556
|
+
* record yield next to its `any` return channel) has each value converted
|
|
557
|
+
* to the declared type as it is pulled. */
|
|
558
|
+
function lowerHelperSource(lowerer, expr) {
|
|
559
|
+
// Iterator.from(gen) is the generator itself; the call's IteratorObject
|
|
560
|
+
// type would add an adapter generator over it.
|
|
561
|
+
const fromArg = iteratorFromArgument(lowerer, expr);
|
|
562
|
+
if (fromArg !== null && lowerer.mapTypeOf(lowerer.typeOf(fromArg))?.kind === "generator")
|
|
563
|
+
return lowerHelperSource(lowerer, fromArg);
|
|
564
|
+
const tsType = lowerer.typeOf(expr);
|
|
565
|
+
const mapped = lowerer.mapTypeOf(tsType);
|
|
566
|
+
const arg = lowerer.checker.getTypeArguments(tsType)[0];
|
|
567
|
+
if (mapped?.kind === "generator") {
|
|
568
|
+
const gen = lowerer.lowerExpr(expr);
|
|
569
|
+
if (gen.type.kind !== "generator" || gen.type.async)
|
|
570
|
+
lowerer.badType(expr, tsType);
|
|
571
|
+
const genT = gen.type;
|
|
572
|
+
const declared = genT.yieldT.kind === "dyn" && arg ? lowerer.mapTypeOf(arg) : null;
|
|
573
|
+
const elem = declared !== null &&
|
|
574
|
+
declared.kind !== "dyn" &&
|
|
575
|
+
declared.kind !== "void" &&
|
|
576
|
+
!isUnitType(declared)
|
|
577
|
+
? declared
|
|
578
|
+
: genT.yieldT;
|
|
579
|
+
return { gen: gen, elem };
|
|
580
|
+
}
|
|
581
|
+
const yieldT = arg ? lowerer.mapTypeOf(arg) : null;
|
|
582
|
+
if (!yieldT ||
|
|
583
|
+
yieldT.kind === "void" ||
|
|
584
|
+
!genResultRecord(yieldT, VOID, lowerer.shapes, lowerer.unions))
|
|
585
|
+
lowerer.badType(expr, tsType);
|
|
586
|
+
const target = { kind: "generator", yieldT, retT: VOID, nextT: UNDEFINED_T };
|
|
587
|
+
// m.keys()/values()/entries() (or a Set's) on a typed collection: a
|
|
588
|
+
// generator over the collection with typed reads.
|
|
589
|
+
const collection = collectionIteratorCall(lowerer, expr);
|
|
590
|
+
if (collection !== null) {
|
|
591
|
+
const coll = lowerer.lowerExpr(collection.receiver);
|
|
592
|
+
const walk = lowerCollectionIteratorValue(lowerer, coll, collection.proj, target, locOf(expr));
|
|
593
|
+
if (walk !== null)
|
|
594
|
+
return { gen: walk, elem: yieldT };
|
|
595
|
+
}
|
|
596
|
+
const adapted = iteratorSlotAdapter(lowerer, lowerer.lowerExpr(expr), target);
|
|
597
|
+
if (adapted === null || adapted.type.kind !== "generator")
|
|
598
|
+
lowerer.badType(expr, tsType);
|
|
599
|
+
return { gen: adapted, elem: yieldT };
|
|
600
|
+
}
|
|
601
|
+
/** Lower one stage's argument against its input element type: the
|
|
602
|
+
* callback (value) or (value, counter), or the take/drop budget with
|
|
603
|
+
* Node's eager RangeError check at the argument's position. `out` is
|
|
604
|
+
* the stage's output element type. */
|
|
605
|
+
function lowerStage(lowerer, s, elem, loc, source = null) {
|
|
606
|
+
if (s.name === "take" || s.name === "drop") {
|
|
607
|
+
const n = lowerer.lowerExpr(s.argNode);
|
|
608
|
+
if (n.type.kind !== "f64")
|
|
609
|
+
lowerer.badType(s.argNode, lowerer.typeOf(s.argNode));
|
|
610
|
+
// Node validates at the take()/drop() call — the checked budget
|
|
611
|
+
// rides an interned helper call AT this argument position. A
|
|
612
|
+
// generator source is closed before the RangeError, as Node closes
|
|
613
|
+
// the iterator the helper was called on.
|
|
614
|
+
return {
|
|
615
|
+
stage: {
|
|
96
616
|
kind: s.name,
|
|
97
617
|
budget: {
|
|
98
618
|
kind: "call",
|
|
99
|
-
callee: internBudgetChecker(lowerer, loc),
|
|
100
|
-
args: [n],
|
|
619
|
+
callee: internBudgetChecker(lowerer, loc, source?.type ?? null),
|
|
620
|
+
args: source === null ? [n] : [n, source],
|
|
101
621
|
type: F64,
|
|
102
622
|
loc,
|
|
103
623
|
},
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
624
|
+
},
|
|
625
|
+
out: elem,
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
// A flatMap callback returns its own array or generator type (an
|
|
629
|
+
// unannotated JavaScript arrow would otherwise return checked values).
|
|
630
|
+
let expectedReturn;
|
|
631
|
+
if (s.name === "flatMap") {
|
|
632
|
+
const sig = lowerer.checker.getCallSignatures(lowerer.typeOf(s.argNode))[0];
|
|
633
|
+
const ret = sig ? lowerer.mapTypeOf(lowerer.checker.getReturnTypeOfSignature(sig)) : null;
|
|
634
|
+
if (ret?.kind === "array" || ret?.kind === "generator")
|
|
635
|
+
expectedReturn = ret;
|
|
636
|
+
}
|
|
637
|
+
// Unannotated JavaScript parameters bind the element type.
|
|
638
|
+
const f = lowerArrayCallback(lowerer, s.argNode, [elem], UNDEFINED_T, false, expectedReturn).fnArg;
|
|
639
|
+
if (f.type.kind !== "func" ||
|
|
640
|
+
f.type.params.length > 2 ||
|
|
641
|
+
(f.type.params.length >= 1 && !typeEquals(f.type.params[0], elem)) ||
|
|
642
|
+
(f.type.params.length === 2 && f.type.params[1].kind !== "f64")) {
|
|
643
|
+
lowerer.badType(s.argNode, lowerer.typeOf(s.argNode));
|
|
644
|
+
}
|
|
645
|
+
const fn = f;
|
|
646
|
+
if (s.name === "map")
|
|
647
|
+
return { stage: { kind: "map", fn }, out: fn.type.ret };
|
|
648
|
+
if (s.name === "filter") {
|
|
649
|
+
if (fn.type.ret.kind !== "bool")
|
|
112
650
|
lowerer.badType(s.argNode, lowerer.typeOf(s.argNode));
|
|
113
|
-
}
|
|
114
|
-
const fn = f;
|
|
115
|
-
if (s.name === "map") {
|
|
116
|
-
stageIrs.push({ kind: "map", fn, out: fn.type.ret });
|
|
117
|
-
elem = fn.type.ret;
|
|
118
|
-
}
|
|
119
|
-
else if (s.name === "filter") {
|
|
120
|
-
if (fn.type.ret.kind !== "bool")
|
|
121
|
-
lowerer.badType(s.argNode, lowerer.typeOf(s.argNode));
|
|
122
|
-
stageIrs.push({ kind: "filter", fn, out: elem });
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
if (fn.type.ret.kind !== "array") {
|
|
126
|
-
lowerer.noLowering(`.flatMap over a callback returning '${lowerer.fmt(fn.type.ret)}'`, s.argNode, "an array-returning callback is the supported form (iterators/strings have no lowering here)");
|
|
127
|
-
}
|
|
128
|
-
stageIrs.push({ kind: "flatMap", fn, out: fn.type.ret.elem });
|
|
129
|
-
elem = fn.type.ret.elem;
|
|
130
|
-
}
|
|
651
|
+
return { stage: { kind: "filter", fn }, out: elem };
|
|
131
652
|
}
|
|
132
|
-
|
|
653
|
+
const ret = fn.type.ret;
|
|
654
|
+
if (ret.kind === "array")
|
|
655
|
+
return { stage: { kind: "flatMap", fn }, out: ret.elem };
|
|
656
|
+
if (ret.kind === "generator" && ret.async !== true && stepDrivable(ret))
|
|
657
|
+
return { stage: { kind: "flatMap", fn }, out: ret.yieldT };
|
|
658
|
+
// A Set flattens its values and a Map its entries, walked live. A string
|
|
659
|
+
// is rejected at run time with Node's TypeError (strings are not
|
|
660
|
+
// iterator objects).
|
|
661
|
+
if (ret.kind === "set")
|
|
662
|
+
return { stage: { kind: "flatMap", fn }, out: ret.elem };
|
|
663
|
+
if (ret.kind === "map")
|
|
664
|
+
return { stage: { kind: "flatMap", fn }, out: entryPairTypeOf(lowerer, ret.key, ret.value) };
|
|
665
|
+
if (ret.kind === "string")
|
|
666
|
+
return { stage: { kind: "flatMap", fn }, out: STRING };
|
|
667
|
+
lowerer.noLowering(`.flatMap over a callback returning '${lowerer.fmt(ret)}'`, s.argNode, "callbacks returning an array, a generator, a Set or a Map are the supported forms");
|
|
668
|
+
}
|
|
669
|
+
/** The terminal's arguments and result type over elements of `elem`. */
|
|
670
|
+
function lowerTerminal(lowerer, call, terminal, elem) {
|
|
133
671
|
const termArgs = [];
|
|
134
|
-
let resultT;
|
|
135
672
|
if (terminal === "toArray") {
|
|
136
|
-
if (call.arguments.length !== 0)
|
|
137
|
-
lowerer.noLowering(`.toArray with ${call.arguments.length} arguments`, call);
|
|
138
|
-
resultT
|
|
673
|
+
if (call.arguments.nodes.length !== 0)
|
|
674
|
+
lowerer.noLowering(`.toArray with ${call.arguments.nodes.length} arguments`, call);
|
|
675
|
+
return { termArgs, resultT: arrayOf(elem) };
|
|
139
676
|
}
|
|
140
|
-
|
|
677
|
+
if (terminal === "forEach" ||
|
|
141
678
|
terminal === "some" ||
|
|
142
679
|
terminal === "every" ||
|
|
143
680
|
terminal === "find") {
|
|
144
|
-
const argNode = call.arguments[0];
|
|
145
|
-
if (call.arguments.length !== 1 || argNode === undefined || ts.isSpreadElement(argNode)) {
|
|
146
|
-
lowerer.noLowering(`.${terminal} with ${call.arguments.length} arguments`, call);
|
|
681
|
+
const argNode = call.arguments.nodes[0];
|
|
682
|
+
if (call.arguments.nodes.length !== 1 || argNode === undefined || ts.isSpreadElement(argNode)) {
|
|
683
|
+
lowerer.noLowering(`.${terminal} with ${call.arguments.nodes.length} arguments`, call);
|
|
147
684
|
}
|
|
148
|
-
const f = lowerer
|
|
685
|
+
const f = lowerArrayCallback(lowerer, argNode, [elem], UNDEFINED_T).fnArg;
|
|
149
686
|
if (f.type.kind !== "func" ||
|
|
150
687
|
f.type.params.length > 2 ||
|
|
151
688
|
(f.type.params.length >= 1 && !typeEquals(f.type.params[0], elem)) ||
|
|
@@ -154,79 +691,118 @@ export function lowerIteratorHelperCall(lowerer, call, access) {
|
|
|
154
691
|
lowerer.badType(argNode, lowerer.typeOf(argNode));
|
|
155
692
|
}
|
|
156
693
|
termArgs.push(f);
|
|
157
|
-
|
|
158
|
-
|
|
694
|
+
return {
|
|
695
|
+
termArgs,
|
|
696
|
+
resultT: terminal === "forEach" ? VOID : terminal === "find" ? lowerer.withUndefinedArm(elem) : BOOL,
|
|
697
|
+
};
|
|
159
698
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
lowerer.noLowering(`.reduce with ${call.arguments.length} arguments`, call);
|
|
168
|
-
}
|
|
169
|
-
const f = lowerer.lowerExpr(fNode);
|
|
170
|
-
if (f.type.kind !== "func" ||
|
|
171
|
-
f.type.params.length < 2 ||
|
|
172
|
-
f.type.params.length > 3 ||
|
|
173
|
-
!typeEquals(f.type.params[1], elem) ||
|
|
174
|
-
(f.type.params.length === 3 && f.type.params[2].kind !== "f64") ||
|
|
175
|
-
!typeEquals(f.type.params[0], f.type.ret)) {
|
|
176
|
-
lowerer.badType(fNode, lowerer.typeOf(fNode));
|
|
177
|
-
}
|
|
178
|
-
const accT = f.type.ret;
|
|
179
|
-
if (call.arguments.length === 1 && !typeEquals(accT, elem)) {
|
|
180
|
-
lowerer.noLowering(".reduce without an initial value where the accumulator's type differs from the elements'", call, "pass the initial value: .reduce(f, init)");
|
|
181
|
-
}
|
|
182
|
-
termArgs.push(f);
|
|
183
|
-
if (call.arguments[1] !== undefined)
|
|
184
|
-
termArgs.push(lowerer.lowerExprExpecting(call.arguments[1], accT));
|
|
185
|
-
resultT = accT;
|
|
699
|
+
// reduce(f[, initial])
|
|
700
|
+
const fNode = call.arguments.nodes[0];
|
|
701
|
+
if (call.arguments.nodes.length < 1 ||
|
|
702
|
+
call.arguments.nodes.length > 2 ||
|
|
703
|
+
fNode === undefined ||
|
|
704
|
+
call.arguments.nodes.some((a) => ts.isSpreadElement(a))) {
|
|
705
|
+
lowerer.noLowering(`.reduce with ${call.arguments.nodes.length} arguments`, call);
|
|
186
706
|
}
|
|
707
|
+
// The accumulator binds the checker's result type.
|
|
708
|
+
const accLead = lowerer.mapTypeOf(lowerer.typeOf(call)) ?? elem;
|
|
709
|
+
const f = lowerArrayCallback(lowerer, fNode, [accLead, elem], UNDEFINED_T).fnArg;
|
|
710
|
+
if (f.type.kind !== "func" ||
|
|
711
|
+
f.type.params.length < 2 ||
|
|
712
|
+
f.type.params.length > 3 ||
|
|
713
|
+
!typeEquals(f.type.params[1], elem) ||
|
|
714
|
+
(f.type.params.length === 3 && f.type.params[2].kind !== "f64") ||
|
|
715
|
+
!typeEquals(f.type.params[0], f.type.ret)) {
|
|
716
|
+
lowerer.badType(fNode, lowerer.typeOf(fNode));
|
|
717
|
+
}
|
|
718
|
+
const accT = f.type.ret;
|
|
719
|
+
if (call.arguments.nodes.length === 1 && !typeEquals(accT, elem)) {
|
|
720
|
+
lowerer.noLowering(".reduce without an initial value where the accumulator's type differs from the elements'", call, "pass the initial value: .reduce(f, init)");
|
|
721
|
+
}
|
|
722
|
+
termArgs.push(f);
|
|
723
|
+
if (call.arguments.nodes[1] !== undefined)
|
|
724
|
+
termArgs.push(lowerer.lowerExprExpecting(call.arguments.nodes[1], accT));
|
|
725
|
+
return { termArgs, resultT: accT };
|
|
726
|
+
}
|
|
727
|
+
/** A terminal over a chain of stages from `source`: one interned fused
|
|
728
|
+
* function, called with the source, each stage's budget or callback and
|
|
729
|
+
* the terminal's arguments (lowered in that, the chain's own, order). */
|
|
730
|
+
function lowerFusedChain(lowerer, call, terminal, stages, source, items, seed) {
|
|
731
|
+
const loc = locOf(call);
|
|
732
|
+
if (source.kind === "generator" && !stepDrivable(source.type)) {
|
|
733
|
+
lowerer.noLowering(`.${terminal} over an iterator yielding '${lowerer.fmt(source.type.yieldT)}'`, call, "helpers over iterators of numbers, booleans, strings, arrays, records and class instances are the supported forms");
|
|
734
|
+
}
|
|
735
|
+
// A take/drop budget check closes a generator source, so the source is
|
|
736
|
+
// bound before the stage arguments.
|
|
737
|
+
const bound = source.kind === "generator" && stages.some((s) => s.name === "take" || s.name === "drop")
|
|
738
|
+
? bindSource(lowerer, items, loc)
|
|
739
|
+
: null;
|
|
740
|
+
if (bound !== null)
|
|
741
|
+
items = bound.ref;
|
|
742
|
+
let elem = seed;
|
|
743
|
+
const stageIrs = [];
|
|
744
|
+
for (const s of stages) {
|
|
745
|
+
const lowered = lowerStage(lowerer, s, elem, loc, bound?.ref ?? null);
|
|
746
|
+
stageIrs.push(lowered.stage);
|
|
747
|
+
elem = lowered.out;
|
|
748
|
+
}
|
|
749
|
+
const { termArgs, resultT } = lowerTerminal(lowerer, call, terminal, elem);
|
|
187
750
|
// The checker's own result type must agree (annotation drift fences).
|
|
188
751
|
const checkerT = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
189
752
|
if (terminal !== "forEach" && (checkerT === null || !typeEquals(checkerT, resultT))) {
|
|
190
753
|
lowerer.noLowering(`.${terminal} at this result type`, call, "the chain's element and result types must be representable — annotate the callbacks' types");
|
|
191
754
|
}
|
|
192
|
-
const stageKeys = stageIrs.map((s) => {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
})
|
|
197
|
-
const key = `iter:${srcProj}:${typeKey(items.type)}:${stageKeys.join(",")}:${terminal}:${termArgs.map((a) => typeKey(a.type)).join(",")}`;
|
|
755
|
+
const stageKeys = stageIrs.map((s) => "budget" in s ? s.kind : `${s.kind}:${typeKey(s.fn.type)}`);
|
|
756
|
+
const srcKey = source.kind === "generator"
|
|
757
|
+
? `${typeKey(source.type)}:${typeKey(source.elem)}`
|
|
758
|
+
: `${source.proj}:${typeKey(source.type)}`;
|
|
759
|
+
const key = `iter:${srcKey}:${stageKeys.join(",")}:${terminal}:${termArgs.map((a) => typeKey(a.type)).join(",")}`;
|
|
198
760
|
let helper = lowerer.arrHofHelpers.get(key);
|
|
199
761
|
if (!helper) {
|
|
200
762
|
helper = `%iter.${terminal}.${lowerer.arrHofHelpers.size}`;
|
|
201
763
|
lowerer.arrHofHelpers.set(key, helper);
|
|
202
|
-
lowerer.liftedFns.push(buildIterChainFn(lowerer, helper,
|
|
764
|
+
lowerer.liftedFns.push(buildIterChainFn(lowerer, helper, source, stageIrs, terminal, termArgs.map((a) => a.type), resultT, loc));
|
|
203
765
|
}
|
|
204
|
-
const budgetOrFn = stageIrs.map((s) =>
|
|
205
|
-
|
|
206
|
-
throw new InternalCompilerError("missing iterator stage");
|
|
207
|
-
return "budget" in s ? s.budget : s.fn;
|
|
208
|
-
});
|
|
209
|
-
return {
|
|
766
|
+
const budgetOrFn = stageIrs.map((s) => ("budget" in s ? s.budget : s.fn));
|
|
767
|
+
const fused = {
|
|
210
768
|
kind: "call",
|
|
211
769
|
callee: helper,
|
|
212
770
|
args: [items, ...budgetOrFn, ...termArgs],
|
|
213
771
|
type: resultT,
|
|
214
772
|
loc,
|
|
215
773
|
};
|
|
774
|
+
return bound === null
|
|
775
|
+
? fused
|
|
776
|
+
: { kind: "seqExpr", stmts: [bound.decl], result: fused, type: resultT, loc };
|
|
216
777
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
778
|
+
/** An iterator helper object for one stage over `src`: an interned
|
|
779
|
+
* generator `%iter.<stage>.N(src, f | n)` typed as the call's checker
|
|
780
|
+
* type (IteratorObject<out>). */
|
|
781
|
+
function lowerHelperObject(lowerer, call, src, source, srcElem, stage, out, loc) {
|
|
782
|
+
const outT = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
783
|
+
const resultType = outT?.kind === "generator"
|
|
784
|
+
? genResultRecord(outT.yieldT, outT.retT, lowerer.shapes, lowerer.unions)
|
|
785
|
+
: null;
|
|
786
|
+
if (outT?.kind !== "generator" ||
|
|
787
|
+
outT.async === true ||
|
|
788
|
+
!typeEquals(outT.yieldT, out) ||
|
|
789
|
+
outT.retT.kind !== "void" ||
|
|
790
|
+
resultType === null) {
|
|
791
|
+
lowerer.noLowering(`.${stage.kind} at this result type`, call, "the helper's element type must be representable — annotate the callback's types");
|
|
792
|
+
}
|
|
793
|
+
if (source.kind === "generator" && !stepDrivable(source.type)) {
|
|
794
|
+
lowerer.noLowering(`.${stage.kind} over an iterator yielding '${lowerer.fmt(source.type.yieldT)}'`, call, "helpers over iterators of numbers, booleans, strings, arrays, records and class instances are the supported forms");
|
|
795
|
+
}
|
|
796
|
+
const arg = "budget" in stage ? stage.budget : stage.fn;
|
|
797
|
+
const srcKey = source.kind === "collection" ? `${source.proj}:${typeKey(source.type)}` : typeKey(source.type);
|
|
798
|
+
const key = `iterHelper:${stage.kind}:${srcKey}:${typeKey(srcElem)}:${typeKey(arg.type)}:${typeKey(outT)}`;
|
|
799
|
+
let name = lowerer.arrHofHelpers.get(key);
|
|
800
|
+
if (!name) {
|
|
801
|
+
name = `%iter.${stage.kind}.${lowerer.arrHofHelpers.size}`;
|
|
802
|
+
lowerer.arrHofHelpers.set(key, name);
|
|
803
|
+
lowerer.liftedFns.push(buildHelperGenFn(lowerer, name, source, srcElem, stage, arg.type, outT, resultType, loc));
|
|
228
804
|
}
|
|
229
|
-
return
|
|
805
|
+
return { kind: "call", callee: name, args: [src, arg], type: outT, loc };
|
|
230
806
|
}
|
|
231
807
|
/** The eager take/drop budget check, interned once per program:
|
|
232
808
|
*
|
|
@@ -235,12 +811,12 @@ function findStageAccess(call, s) {
|
|
|
235
811
|
* Node's exact behavior: NaN and negative INTEGER budgets throw (the
|
|
236
812
|
* message carries the RAW argument — take(-1.5) says "-1.5"), -0.5
|
|
237
813
|
* truncates to 0 and passes, Infinity passes through. */
|
|
238
|
-
function internBudgetChecker(lowerer, loc) {
|
|
239
|
-
const key = "iter:budget"
|
|
814
|
+
function internBudgetChecker(lowerer, loc, srcT) {
|
|
815
|
+
const key = srcT === null ? "iter:budget" : `iter:budget:close:${typeKey(srcT)}`;
|
|
240
816
|
let name = lowerer.arrHofHelpers.get(key);
|
|
241
817
|
if (name !== undefined)
|
|
242
818
|
return name;
|
|
243
|
-
name = "%iter.budget"
|
|
819
|
+
name = srcT === null ? "%iter.budget" : `%iter.budget.close.${lowerer.arrHofHelpers.size}`;
|
|
244
820
|
lowerer.arrHofHelpers.set(key, name);
|
|
245
821
|
const v = () => ({ kind: "varRef", localId: "v.0", type: F64, loc });
|
|
246
822
|
// trunc without an Infinity-poisoned fmod: values at or past 2^53 are
|
|
@@ -286,80 +862,741 @@ function internBudgetChecker(lowerer, loc) {
|
|
|
286
862
|
{ kind: "strLit", value: " must be positive", type: STRING, loc },
|
|
287
863
|
], loc),
|
|
288
864
|
],
|
|
289
|
-
type: { kind: "object", className: "%RangeError" },
|
|
865
|
+
type: { kind: "object", className: "%RangeError" },
|
|
866
|
+
loc,
|
|
867
|
+
},
|
|
868
|
+
loc,
|
|
869
|
+
};
|
|
870
|
+
// The source closes first; an error from its return() is dropped, so
|
|
871
|
+
// the RangeError is what propagates.
|
|
872
|
+
const closeSource = srcT === null
|
|
873
|
+
? []
|
|
874
|
+
: [
|
|
875
|
+
{
|
|
876
|
+
kind: "tryCatch",
|
|
877
|
+
tryBody: [
|
|
878
|
+
{
|
|
879
|
+
kind: "exprStmt",
|
|
880
|
+
expr: {
|
|
881
|
+
kind: "genResume",
|
|
882
|
+
mode: "close",
|
|
883
|
+
gen: varRef("src.0", srcT, loc),
|
|
884
|
+
arg: null,
|
|
885
|
+
type: VOID,
|
|
886
|
+
loc,
|
|
887
|
+
},
|
|
888
|
+
loc,
|
|
889
|
+
},
|
|
890
|
+
],
|
|
891
|
+
catchBody: [],
|
|
892
|
+
catchLocalId: "exc.0",
|
|
893
|
+
finallyBody: null,
|
|
894
|
+
loc,
|
|
895
|
+
},
|
|
896
|
+
];
|
|
897
|
+
lowerer.liftedFns.push({
|
|
898
|
+
name,
|
|
899
|
+
params: [
|
|
900
|
+
{ localId: "v.0", name: "v", type: F64 },
|
|
901
|
+
...(srcT === null ? [] : [{ localId: "src.0", name: "src", type: srcT }]),
|
|
902
|
+
],
|
|
903
|
+
returnType: F64,
|
|
904
|
+
locals: [
|
|
905
|
+
{ id: "v.0", name: "v", type: F64, mutable: true },
|
|
906
|
+
...(srcT === null
|
|
907
|
+
? []
|
|
908
|
+
: [
|
|
909
|
+
{ id: "src.0", name: "src", type: srcT, mutable: false },
|
|
910
|
+
{ id: "exc.0", name: "exc", type: CAUGHT, mutable: false },
|
|
911
|
+
]),
|
|
912
|
+
],
|
|
913
|
+
body: [
|
|
914
|
+
{ kind: "if", cond: bad, then: [...closeSource, throwStmt], else_: null, loc },
|
|
915
|
+
{ kind: "return", value: t(), loc },
|
|
916
|
+
],
|
|
917
|
+
loc,
|
|
918
|
+
});
|
|
919
|
+
return name;
|
|
920
|
+
}
|
|
921
|
+
/** A hidden local holding `gen`, and its declaration. */
|
|
922
|
+
function bindSource(lowerer, gen, loc) {
|
|
923
|
+
const local = lowerer.declareHiddenLocal("%helperSource", gen.type);
|
|
924
|
+
return {
|
|
925
|
+
ref: varRef(local.id, gen.type, loc),
|
|
926
|
+
decl: { kind: "varDecl", localId: local.id, init: gen, loc },
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
/** `id = id + 1` over a number local. */
|
|
930
|
+
function bumpLocal(id, loc) {
|
|
931
|
+
return {
|
|
932
|
+
kind: "assign",
|
|
933
|
+
localId: id,
|
|
934
|
+
value: {
|
|
935
|
+
kind: "bin",
|
|
936
|
+
op: "+",
|
|
937
|
+
left: varRef(id, F64, loc),
|
|
938
|
+
right: numLit(1, loc),
|
|
939
|
+
type: F64,
|
|
940
|
+
loc,
|
|
941
|
+
},
|
|
942
|
+
loc,
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
/** Hidden locals of the function being lowered. */
|
|
946
|
+
class HostFrame {
|
|
947
|
+
lowerer;
|
|
948
|
+
loc;
|
|
949
|
+
constructor(lowerer, loc) {
|
|
950
|
+
this.lowerer = lowerer;
|
|
951
|
+
this.loc = loc;
|
|
952
|
+
}
|
|
953
|
+
local(base, type, mutable) {
|
|
954
|
+
const local = this.lowerer.declareHiddenLocal(`%${base}`, type);
|
|
955
|
+
local.mutable = mutable;
|
|
956
|
+
return local.id;
|
|
957
|
+
}
|
|
958
|
+
bump(id) {
|
|
959
|
+
return bumpLocal(id, this.loc);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
/** The locals and parameters of a lifted helper function under
|
|
963
|
+
* construction. */
|
|
964
|
+
class LiftedFrame {
|
|
965
|
+
loc;
|
|
966
|
+
locals = [];
|
|
967
|
+
params = [];
|
|
968
|
+
n = 0;
|
|
969
|
+
constructor(loc) {
|
|
970
|
+
this.loc = loc;
|
|
971
|
+
}
|
|
972
|
+
local(base, type, mutable) {
|
|
973
|
+
const id = `${base}.${this.n++}`;
|
|
974
|
+
this.locals.push({ id, name: base, type, mutable });
|
|
975
|
+
return id;
|
|
976
|
+
}
|
|
977
|
+
param(base, type) {
|
|
978
|
+
const id = `${base}.${this.n++}`;
|
|
979
|
+
this.locals.push({ id, name: base, type, mutable: true });
|
|
980
|
+
this.params.push({ localId: id, name: base, type });
|
|
981
|
+
return id;
|
|
982
|
+
}
|
|
983
|
+
bump(id) {
|
|
984
|
+
return bumpLocal(id, this.loc);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
/** Statements that drive the synchronous generator in local `genId` the
|
|
988
|
+
* way for-of does. Each pass runs `pre` (which may `break`), steps the
|
|
989
|
+
* generator, binds the yielded value and runs `body` over it (`continue`
|
|
990
|
+
* moves to the next pass). Leaving the loop while the generator is
|
|
991
|
+
* unfinished closes it: a `break` in `pre` or `body`, a throw from the
|
|
992
|
+
* body, or a `return()` at a yield inside it. Exhaustion and a throwing
|
|
993
|
+
* step leave it unclosed, as in Node. The generator counts as unfinished
|
|
994
|
+
* before the first step, so a `pre` that breaks at once (take(0)) closes
|
|
995
|
+
* a source it never pulled. `genT` must be stepDrivable. */
|
|
996
|
+
function driveGenerator(lowerer, frame, genId, genT, elemT, pre, body, loc, labels) {
|
|
997
|
+
const g = () => varRef(genId, genT, loc);
|
|
998
|
+
const openId = frame.local("open", BOOL, true);
|
|
999
|
+
const setOpen = (value) => ({
|
|
1000
|
+
kind: "assign",
|
|
1001
|
+
localId: openId,
|
|
1002
|
+
value: boolLit(value, loc),
|
|
1003
|
+
loc,
|
|
1004
|
+
});
|
|
1005
|
+
const vId = frame.local("gv", genT.yieldT, false);
|
|
1006
|
+
// A checked-dynamic yield converts once into the element type.
|
|
1007
|
+
const converted = typeEquals(elemT, genT.yieldT)
|
|
1008
|
+
? null
|
|
1009
|
+
: lowerer.coerceToExpected(varRef(vId, genT.yieldT, loc), elemT);
|
|
1010
|
+
if (converted !== null && !typeEquals(converted.type, elemT))
|
|
1011
|
+
throw new InternalCompilerError("lowerer bug: helper source element has no conversion");
|
|
1012
|
+
const eId = converted === null ? vId : frame.local("ev", elemT, false);
|
|
1013
|
+
return [
|
|
1014
|
+
{ kind: "varDecl", localId: openId, init: boolLit(true, loc), loc },
|
|
1015
|
+
{
|
|
1016
|
+
kind: "tryCatch",
|
|
1017
|
+
tryBody: [
|
|
1018
|
+
{
|
|
1019
|
+
kind: "while",
|
|
1020
|
+
cond: boolLit(true, loc),
|
|
1021
|
+
body: [
|
|
1022
|
+
...pre,
|
|
1023
|
+
setOpen(false),
|
|
1024
|
+
{
|
|
1025
|
+
kind: "if",
|
|
1026
|
+
cond: genStep(g(), loc),
|
|
1027
|
+
then: [{ kind: "break", loc }],
|
|
1028
|
+
else_: null,
|
|
1029
|
+
loc,
|
|
1030
|
+
},
|
|
1031
|
+
setOpen(true),
|
|
1032
|
+
{ kind: "varDecl", localId: vId, init: genValue(g(), loc), loc },
|
|
1033
|
+
...(converted === null
|
|
1034
|
+
? []
|
|
1035
|
+
: [{ kind: "varDecl", localId: eId, init: converted, loc }]),
|
|
1036
|
+
...body(varRef(eId, elemT, loc)),
|
|
1037
|
+
],
|
|
1038
|
+
...(labels && { labels }),
|
|
1039
|
+
loc,
|
|
1040
|
+
},
|
|
1041
|
+
],
|
|
1042
|
+
catchBody: null,
|
|
1043
|
+
catchLocalId: null,
|
|
1044
|
+
// After a throw, an error from closing the source is dropped.
|
|
1045
|
+
dropFinallyErrors: true,
|
|
1046
|
+
finallyBody: [
|
|
1047
|
+
{
|
|
1048
|
+
kind: "if",
|
|
1049
|
+
cond: varRef(openId, BOOL, loc),
|
|
1050
|
+
then: [
|
|
1051
|
+
{
|
|
1052
|
+
kind: "exprStmt",
|
|
1053
|
+
expr: { kind: "genResume", mode: "close", gen: g(), arg: null, type: VOID, loc },
|
|
1054
|
+
loc,
|
|
1055
|
+
},
|
|
1056
|
+
],
|
|
1057
|
+
else_: null,
|
|
1058
|
+
loc,
|
|
1059
|
+
},
|
|
1060
|
+
],
|
|
1061
|
+
loc,
|
|
1062
|
+
},
|
|
1063
|
+
];
|
|
1064
|
+
}
|
|
1065
|
+
/** Statements that walk the Map or Set in local `collId` from inside a
|
|
1066
|
+
* helper's generator: each pass runs `pre` (which may `break`), takes the
|
|
1067
|
+
* next live entry index from the runtime's native iterator, which keeps
|
|
1068
|
+
* the walk live and ends it when exhausted or released, and runs `body`
|
|
1069
|
+
* over the projected element read with the typed intrinsics. */
|
|
1070
|
+
function driveCollectionNative(lowerer, frame, collId, source, pre, body, loc) {
|
|
1071
|
+
const t = source.type;
|
|
1072
|
+
const coll = () => varRef(collId, t, loc);
|
|
1073
|
+
const nativeId = frame.local("native", DYN, false);
|
|
1074
|
+
const iId = frame.local("i", F64, false);
|
|
1075
|
+
const read = (method, type) => t.kind === "map"
|
|
1076
|
+
? { kind: "mapIntrinsic", method, receiver: coll(), args: [varRef(iId, F64, loc)], type, loc }
|
|
1077
|
+
: {
|
|
1078
|
+
kind: "setIntrinsic",
|
|
1079
|
+
method: "iterKey",
|
|
1080
|
+
receiver: coll(),
|
|
1081
|
+
args: [varRef(iId, F64, loc)],
|
|
1082
|
+
type,
|
|
1083
|
+
loc,
|
|
1084
|
+
};
|
|
1085
|
+
const keyT = t.kind === "map" ? t.key : t.elem;
|
|
1086
|
+
const valueT = t.kind === "map" ? t.value : t.elem;
|
|
1087
|
+
const seedT = collectionSeed(lowerer, source);
|
|
1088
|
+
const seed = source.proj === "entries"
|
|
1089
|
+
? {
|
|
1090
|
+
kind: "recordLit",
|
|
1091
|
+
fields: [
|
|
1092
|
+
{ name: "0", value: read("iterKey", keyT) },
|
|
1093
|
+
{ name: "1", value: read("iterValue", valueT) },
|
|
1094
|
+
],
|
|
1095
|
+
type: seedT,
|
|
1096
|
+
loc,
|
|
1097
|
+
}
|
|
1098
|
+
: source.proj === "values" && t.kind === "map"
|
|
1099
|
+
? read("iterValue", valueT)
|
|
1100
|
+
: read("iterKey", keyT);
|
|
1101
|
+
const vId = frame.local("v", seedT, false);
|
|
1102
|
+
return [
|
|
1103
|
+
{
|
|
1104
|
+
kind: "varDecl",
|
|
1105
|
+
localId: nativeId,
|
|
1106
|
+
init: {
|
|
1107
|
+
kind: "dynInvoke",
|
|
1108
|
+
recv: lowerer.coerceToExpected(coll(), DYN),
|
|
1109
|
+
method: "values",
|
|
1110
|
+
calleeName: t.kind === "map" ? "map.values" : "set.values",
|
|
1111
|
+
args: [],
|
|
1112
|
+
type: DYN,
|
|
1113
|
+
loc,
|
|
1114
|
+
},
|
|
1115
|
+
loc,
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
kind: "while",
|
|
1119
|
+
cond: boolLit(true, loc),
|
|
1120
|
+
body: [
|
|
1121
|
+
...pre,
|
|
1122
|
+
{
|
|
1123
|
+
kind: "varDecl",
|
|
1124
|
+
localId: iId,
|
|
1125
|
+
init: {
|
|
1126
|
+
kind: "libCall",
|
|
1127
|
+
fn: "dyn.collectionIteratorIndex",
|
|
1128
|
+
args: [varRef(nativeId, DYN, loc)],
|
|
1129
|
+
type: F64,
|
|
1130
|
+
loc,
|
|
1131
|
+
},
|
|
1132
|
+
loc,
|
|
1133
|
+
},
|
|
1134
|
+
{
|
|
1135
|
+
kind: "if",
|
|
1136
|
+
cond: {
|
|
1137
|
+
kind: "bin",
|
|
1138
|
+
op: "<",
|
|
1139
|
+
left: varRef(iId, F64, loc),
|
|
1140
|
+
right: numLit(0, loc),
|
|
1141
|
+
type: BOOL,
|
|
1142
|
+
loc,
|
|
1143
|
+
},
|
|
1144
|
+
then: [{ kind: "break", loc }],
|
|
1145
|
+
else_: null,
|
|
1146
|
+
loc,
|
|
1147
|
+
},
|
|
1148
|
+
{ kind: "varDecl", localId: vId, init: seed, loc },
|
|
1149
|
+
...body(varRef(vId, seedT, loc)),
|
|
1150
|
+
],
|
|
1151
|
+
loc,
|
|
1152
|
+
},
|
|
1153
|
+
];
|
|
1154
|
+
}
|
|
1155
|
+
/** `for (j = 0; j < arr.length && !stop; j++) body(arr[j])` over a live
|
|
1156
|
+
* array local (the array iterator's per-step length read). */
|
|
1157
|
+
function walkArray(frame, arrId, arrT, stop, body, loc) {
|
|
1158
|
+
const jId = frame.local("j", F64, true);
|
|
1159
|
+
const wId = frame.local("w", arrT.elem, false);
|
|
1160
|
+
const inBounds = {
|
|
1161
|
+
kind: "bin",
|
|
1162
|
+
op: "<",
|
|
1163
|
+
left: varRef(jId, F64, loc),
|
|
1164
|
+
right: {
|
|
1165
|
+
kind: "arrIntrinsic",
|
|
1166
|
+
method: "length",
|
|
1167
|
+
receiver: varRef(arrId, arrT, loc),
|
|
1168
|
+
args: [],
|
|
1169
|
+
type: F64,
|
|
1170
|
+
loc,
|
|
1171
|
+
},
|
|
1172
|
+
type: BOOL,
|
|
1173
|
+
loc,
|
|
1174
|
+
};
|
|
1175
|
+
return {
|
|
1176
|
+
kind: "for",
|
|
1177
|
+
init: { kind: "varDecl", localId: jId, init: numLit(0, loc), loc },
|
|
1178
|
+
cond: stop === null
|
|
1179
|
+
? inBounds
|
|
1180
|
+
: {
|
|
1181
|
+
kind: "logical",
|
|
1182
|
+
op: "&&",
|
|
1183
|
+
left: inBounds,
|
|
1184
|
+
right: { kind: "unary", op: "!", operand: stop, type: BOOL, loc },
|
|
1185
|
+
type: BOOL,
|
|
1186
|
+
loc,
|
|
1187
|
+
},
|
|
1188
|
+
update: frame.bump(jId),
|
|
1189
|
+
body: [
|
|
1190
|
+
{
|
|
1191
|
+
kind: "varDecl",
|
|
1192
|
+
localId: wId,
|
|
1193
|
+
init: {
|
|
1194
|
+
kind: "arrayGet",
|
|
1195
|
+
arr: varRef(arrId, arrT, loc),
|
|
1196
|
+
index: varRef(jId, F64, loc),
|
|
1197
|
+
type: arrT.elem,
|
|
1198
|
+
loc,
|
|
1199
|
+
},
|
|
1200
|
+
loc,
|
|
1201
|
+
},
|
|
1202
|
+
...body(varRef(wId, arrT.elem, loc)),
|
|
1203
|
+
],
|
|
1204
|
+
loc,
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
/** The live walk over the Map or Set in local `collId` that for-of does:
|
|
1208
|
+
* iterEnter, then each live index from iterStart below the current
|
|
1209
|
+
* iterCount until `stop`, then iterExit on every exit (a throw exits
|
|
1210
|
+
* before rethrowing). The body sees the projected element. */
|
|
1211
|
+
function walkCollection(lowerer, frame, collId, source, stop, body, loc, labels) {
|
|
1212
|
+
const t = source.type;
|
|
1213
|
+
const iId = frame.local("i", F64, true);
|
|
1214
|
+
const iter = (method, args, type) => t.kind === "map"
|
|
1215
|
+
? {
|
|
1216
|
+
kind: "mapIntrinsic",
|
|
1217
|
+
method: method,
|
|
1218
|
+
receiver: varRef(collId, t, loc),
|
|
1219
|
+
args,
|
|
1220
|
+
type,
|
|
1221
|
+
loc,
|
|
1222
|
+
}
|
|
1223
|
+
: {
|
|
1224
|
+
kind: "setIntrinsic",
|
|
1225
|
+
method: method,
|
|
1226
|
+
receiver: varRef(collId, t, loc),
|
|
1227
|
+
args,
|
|
1228
|
+
type,
|
|
1229
|
+
loc,
|
|
1230
|
+
};
|
|
1231
|
+
const keyT = t.kind === "map" ? t.key : t.elem;
|
|
1232
|
+
const keyRead = () => iter("iterKey", [varRef(iId, F64, loc)], keyT);
|
|
1233
|
+
const valRead = () => t.kind === "map" ? iter("iterValue", [varRef(iId, F64, loc)], t.value) : keyRead();
|
|
1234
|
+
const seedT = collectionSeed(lowerer, source);
|
|
1235
|
+
const seed = source.proj === "entries"
|
|
1236
|
+
? {
|
|
1237
|
+
kind: "recordLit",
|
|
1238
|
+
fields: [
|
|
1239
|
+
{ name: "0", value: keyRead() },
|
|
1240
|
+
{ name: "1", value: valRead() },
|
|
1241
|
+
],
|
|
1242
|
+
type: seedT,
|
|
1243
|
+
loc,
|
|
1244
|
+
}
|
|
1245
|
+
: source.proj === "values" && t.kind === "map"
|
|
1246
|
+
? valRead()
|
|
1247
|
+
: keyRead();
|
|
1248
|
+
const vId = frame.local("v", seedT, false);
|
|
1249
|
+
const exit = () => ({ kind: "exprStmt", expr: iter("iterExit", [], VOID), loc });
|
|
1250
|
+
const caughtId = frame.local("exc", CAUGHT, false);
|
|
1251
|
+
const loop = {
|
|
1252
|
+
kind: "for",
|
|
1253
|
+
init: { kind: "varDecl", localId: iId, init: iter("iterStart", [], F64), loc },
|
|
1254
|
+
cond: {
|
|
1255
|
+
kind: "logical",
|
|
1256
|
+
op: "&&",
|
|
1257
|
+
left: {
|
|
1258
|
+
kind: "bin",
|
|
1259
|
+
op: "<",
|
|
1260
|
+
left: varRef(iId, F64, loc),
|
|
1261
|
+
right: iter("iterCount", [], F64),
|
|
1262
|
+
type: BOOL,
|
|
1263
|
+
loc,
|
|
1264
|
+
},
|
|
1265
|
+
right: { kind: "unary", op: "!", operand: stop, type: BOOL, loc },
|
|
1266
|
+
type: BOOL,
|
|
1267
|
+
loc,
|
|
1268
|
+
},
|
|
1269
|
+
update: frame.bump(iId),
|
|
1270
|
+
body: [
|
|
1271
|
+
{
|
|
1272
|
+
kind: "if",
|
|
1273
|
+
cond: iter("iterLive", [varRef(iId, F64, loc)], BOOL),
|
|
1274
|
+
then: [
|
|
1275
|
+
{ kind: "varDecl", localId: vId, init: seed, loc },
|
|
1276
|
+
...body(varRef(vId, seedT, loc)),
|
|
1277
|
+
],
|
|
1278
|
+
else_: null,
|
|
1279
|
+
loc,
|
|
1280
|
+
},
|
|
1281
|
+
],
|
|
1282
|
+
...(labels && { labels }),
|
|
1283
|
+
loc,
|
|
1284
|
+
};
|
|
1285
|
+
return [
|
|
1286
|
+
{ kind: "exprStmt", expr: iter("iterEnter", [], VOID), loc },
|
|
1287
|
+
{
|
|
1288
|
+
kind: "tryCatch",
|
|
1289
|
+
tryBody: [loop],
|
|
1290
|
+
catchBody: [exit(), { kind: "rethrow", localId: caughtId, loc }],
|
|
1291
|
+
catchLocalId: caughtId,
|
|
1292
|
+
finallyBody: null,
|
|
1293
|
+
loc,
|
|
1294
|
+
},
|
|
1295
|
+
exit(),
|
|
1296
|
+
];
|
|
1297
|
+
}
|
|
1298
|
+
/** A flatMap stage's inner walk over the callback's result in local
|
|
1299
|
+
* `innerId`: an array by index, a Set's values or a Map's entries walked
|
|
1300
|
+
* live, or a generator driven (and closed on early exit) like the source.
|
|
1301
|
+
* A string result throws Node's TypeError. `stop` ends the walk early. */
|
|
1302
|
+
function walkInner(lowerer, frame, innerId, innerT, stop, body, loc) {
|
|
1303
|
+
if (innerT.kind === "array")
|
|
1304
|
+
return [walkArray(frame, innerId, innerT, stop, body, loc)];
|
|
1305
|
+
if (innerT.kind === "set" || innerT.kind === "map") {
|
|
1306
|
+
const source = {
|
|
1307
|
+
kind: "collection",
|
|
1308
|
+
type: innerT,
|
|
1309
|
+
proj: innerT.kind === "set" ? "values" : "entries",
|
|
1310
|
+
};
|
|
1311
|
+
return walkCollection(lowerer, frame, innerId, source, stop ?? boolLit(false, loc), body, loc);
|
|
1312
|
+
}
|
|
1313
|
+
if (innerT.kind === "string") {
|
|
1314
|
+
return [
|
|
1315
|
+
throwTypeError({
|
|
1316
|
+
kind: "strLit",
|
|
1317
|
+
value: "Iterator.prototype.flatMap called on non-object",
|
|
1318
|
+
type: STRING,
|
|
1319
|
+
loc,
|
|
1320
|
+
}, loc),
|
|
1321
|
+
];
|
|
1322
|
+
}
|
|
1323
|
+
if (innerT.kind !== "generator")
|
|
1324
|
+
throw new InternalCompilerError("lowerer bug: flatMap over a non-iterable result");
|
|
1325
|
+
const pre = stop === null
|
|
1326
|
+
? []
|
|
1327
|
+
: [{ kind: "if", cond: stop, then: [{ kind: "break", loc }], else_: null, loc }];
|
|
1328
|
+
return driveGenerator(lowerer, frame, innerId, innerT, innerT.yieldT, pre, body, loc);
|
|
1329
|
+
}
|
|
1330
|
+
/** A stage callback call with (value) or (value, counter), as declared. */
|
|
1331
|
+
function callStage(fnT, fnId, value, cntId, loc) {
|
|
1332
|
+
const args = [];
|
|
1333
|
+
if (fnT.params.length >= 1)
|
|
1334
|
+
args.push(value);
|
|
1335
|
+
if (cntId !== undefined && fnT.params.length >= 2)
|
|
1336
|
+
args.push(varRef(cntId, F64, loc));
|
|
1337
|
+
return { kind: "callValue", callee: varRef(fnId, fnT, loc), args, type: fnT.ret, loc };
|
|
1338
|
+
}
|
|
1339
|
+
/** The slot for `stage` whose budget or callback is in local `argId`. */
|
|
1340
|
+
function stageSlot(frame, stage, argId) {
|
|
1341
|
+
if ("budget" in stage) {
|
|
1342
|
+
return {
|
|
1343
|
+
kind: stage.kind,
|
|
1344
|
+
argId,
|
|
1345
|
+
cntId: frame.local(stage.kind === "take" ? "taken" : "dropped", F64, true),
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1348
|
+
const fnT = stage.fn.type;
|
|
1349
|
+
return {
|
|
1350
|
+
kind: stage.kind,
|
|
1351
|
+
argId,
|
|
1352
|
+
fnT,
|
|
1353
|
+
cntId: fnT.params.length === 2 ? frame.local("c", F64, true) : undefined,
|
|
1354
|
+
};
|
|
1355
|
+
}
|
|
1356
|
+
/** The declarations fused chain code starts with: the `done` flag —
|
|
1357
|
+
* already true when a take budget is zero, so nothing pulls — and each
|
|
1358
|
+
* stage counter at zero. */
|
|
1359
|
+
function stagePrologue(slots, doneId, loc) {
|
|
1360
|
+
let doneInit = boolLit(false, loc);
|
|
1361
|
+
for (const s of slots) {
|
|
1362
|
+
if (s.kind !== "take")
|
|
1363
|
+
continue;
|
|
1364
|
+
const isZero = {
|
|
1365
|
+
kind: "bin",
|
|
1366
|
+
op: "===",
|
|
1367
|
+
left: varRef(s.argId, F64, loc),
|
|
1368
|
+
right: numLit(0, loc),
|
|
1369
|
+
type: BOOL,
|
|
1370
|
+
loc,
|
|
1371
|
+
};
|
|
1372
|
+
doneInit =
|
|
1373
|
+
doneInit.kind === "boolLit"
|
|
1374
|
+
? isZero
|
|
1375
|
+
: { kind: "logical", op: "||", left: doneInit, right: isZero, type: BOOL, loc };
|
|
1376
|
+
}
|
|
1377
|
+
const out = [{ kind: "varDecl", localId: doneId, init: doneInit, loc }];
|
|
1378
|
+
for (const s of slots) {
|
|
1379
|
+
if (s.cntId !== undefined)
|
|
1380
|
+
out.push({ kind: "varDecl", localId: s.cntId, init: numLit(0, loc), loc });
|
|
1381
|
+
}
|
|
1382
|
+
return out;
|
|
1383
|
+
}
|
|
1384
|
+
/** The per-element code of a chain: each stage nested in source order
|
|
1385
|
+
* around `last` (the terminal's statements, or a for-of body), folded
|
|
1386
|
+
* from the end outward. filter and drop skip with `continue`; take spends
|
|
1387
|
+
* its budget before delivery and sets `done`, so the nth element flows on
|
|
1388
|
+
* and nothing pulls after it (every pass tests done); flatMap walks its
|
|
1389
|
+
* callback's array or generator in an inner loop that also tests done. */
|
|
1390
|
+
function foldStages(lowerer, frame, slots, last, doneId, loc) {
|
|
1391
|
+
const done = () => varRef(doneId, BOOL, loc);
|
|
1392
|
+
const setDone = { kind: "assign", localId: doneId, value: boolLit(true, loc), loc };
|
|
1393
|
+
let emit = last;
|
|
1394
|
+
for (let si = slots.length - 1; si >= 0; si--) {
|
|
1395
|
+
const s = slots[si];
|
|
1396
|
+
const inner = emit;
|
|
1397
|
+
if (s.kind === "map") {
|
|
1398
|
+
emit = (value) => {
|
|
1399
|
+
const vId = frame.local("m", s.fnT.ret, false);
|
|
1400
|
+
return [
|
|
1401
|
+
{
|
|
1402
|
+
kind: "varDecl",
|
|
1403
|
+
localId: vId,
|
|
1404
|
+
init: callStage(s.fnT, s.argId, value, s.cntId, loc),
|
|
1405
|
+
loc,
|
|
1406
|
+
},
|
|
1407
|
+
...(s.cntId !== undefined ? [frame.bump(s.cntId)] : []),
|
|
1408
|
+
...inner(varRef(vId, s.fnT.ret, loc)),
|
|
1409
|
+
];
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
else if (s.kind === "filter") {
|
|
1413
|
+
emit = (value) => {
|
|
1414
|
+
const okId = frame.local("ok", BOOL, false);
|
|
1415
|
+
return [
|
|
1416
|
+
{
|
|
1417
|
+
kind: "varDecl",
|
|
1418
|
+
localId: okId,
|
|
1419
|
+
init: callStage(s.fnT, s.argId, value, s.cntId, loc),
|
|
1420
|
+
loc,
|
|
1421
|
+
},
|
|
1422
|
+
...(s.cntId !== undefined ? [frame.bump(s.cntId)] : []),
|
|
1423
|
+
{
|
|
1424
|
+
kind: "if",
|
|
1425
|
+
cond: { kind: "unary", op: "!", operand: varRef(okId, BOOL, loc), type: BOOL, loc },
|
|
1426
|
+
then: [{ kind: "continue", loc }],
|
|
1427
|
+
else_: null,
|
|
1428
|
+
loc,
|
|
1429
|
+
},
|
|
1430
|
+
...inner(value),
|
|
1431
|
+
];
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
else if (s.kind === "drop") {
|
|
1435
|
+
emit = (value) => [
|
|
1436
|
+
{
|
|
1437
|
+
kind: "if",
|
|
1438
|
+
cond: {
|
|
1439
|
+
kind: "bin",
|
|
1440
|
+
op: "<",
|
|
1441
|
+
left: varRef(s.cntId, F64, loc),
|
|
1442
|
+
right: varRef(s.argId, F64, loc),
|
|
1443
|
+
type: BOOL,
|
|
1444
|
+
loc,
|
|
1445
|
+
},
|
|
1446
|
+
then: [frame.bump(s.cntId), { kind: "continue", loc }],
|
|
1447
|
+
else_: null,
|
|
1448
|
+
loc,
|
|
1449
|
+
},
|
|
1450
|
+
...inner(value),
|
|
1451
|
+
];
|
|
1452
|
+
}
|
|
1453
|
+
else if (s.kind === "take") {
|
|
1454
|
+
emit = (value) => [
|
|
1455
|
+
frame.bump(s.cntId),
|
|
1456
|
+
{
|
|
1457
|
+
kind: "if",
|
|
1458
|
+
cond: {
|
|
1459
|
+
kind: "bin",
|
|
1460
|
+
op: ">=",
|
|
1461
|
+
left: varRef(s.cntId, F64, loc),
|
|
1462
|
+
right: varRef(s.argId, F64, loc),
|
|
1463
|
+
type: BOOL,
|
|
1464
|
+
loc,
|
|
1465
|
+
},
|
|
1466
|
+
then: [setDone],
|
|
1467
|
+
else_: null,
|
|
1468
|
+
loc,
|
|
1469
|
+
},
|
|
1470
|
+
...inner(value),
|
|
1471
|
+
];
|
|
1472
|
+
}
|
|
1473
|
+
else {
|
|
1474
|
+
// A take before this stage sets `done` as it delivers its last
|
|
1475
|
+
// value, which still flattens in full: the inner walk runs with the
|
|
1476
|
+
// flag clear, and keeps it set afterwards.
|
|
1477
|
+
const afterTake = slots.slice(0, si).some((slot) => slot.kind === "take");
|
|
1478
|
+
emit = (value) => {
|
|
1479
|
+
const innerT = s.fnT.ret;
|
|
1480
|
+
const innerId = frame.local("fm", innerT, false);
|
|
1481
|
+
const heldId = afterTake ? frame.local("held", BOOL, false) : undefined;
|
|
1482
|
+
const walk = walkInner(lowerer, frame, innerId, innerT, done(), inner, loc);
|
|
1483
|
+
return [
|
|
1484
|
+
{
|
|
1485
|
+
kind: "varDecl",
|
|
1486
|
+
localId: innerId,
|
|
1487
|
+
init: callStage(s.fnT, s.argId, value, s.cntId, loc),
|
|
1488
|
+
loc,
|
|
1489
|
+
},
|
|
1490
|
+
...(s.cntId !== undefined ? [frame.bump(s.cntId)] : []),
|
|
1491
|
+
...(heldId === undefined
|
|
1492
|
+
? walk
|
|
1493
|
+
: [
|
|
1494
|
+
{ kind: "varDecl", localId: heldId, init: done(), loc },
|
|
1495
|
+
{ kind: "assign", localId: doneId, value: boolLit(false, loc), loc },
|
|
1496
|
+
...walk,
|
|
1497
|
+
{
|
|
1498
|
+
kind: "assign",
|
|
1499
|
+
localId: doneId,
|
|
1500
|
+
value: {
|
|
1501
|
+
kind: "logical",
|
|
1502
|
+
op: "||",
|
|
1503
|
+
left: varRef(heldId, BOOL, loc),
|
|
1504
|
+
right: done(),
|
|
1505
|
+
type: BOOL,
|
|
1506
|
+
loc,
|
|
1507
|
+
},
|
|
1508
|
+
loc,
|
|
1509
|
+
},
|
|
1510
|
+
]),
|
|
1511
|
+
];
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
return emit;
|
|
1516
|
+
}
|
|
1517
|
+
/** The loop over a chain's source in local `itemsId`, running `emit` per
|
|
1518
|
+
* element until `done`: a live array (length re-read per pass), a Map or
|
|
1519
|
+
* Set walked live, or a generator driven like for-of (closed when the
|
|
1520
|
+
* loop leaves it unfinished). `labels` name the loop for a fused for-of
|
|
1521
|
+
* body's labeled jumps. */
|
|
1522
|
+
function sourceLoop(lowerer, frame, itemsId, source, doneId, emit, loc, labels) {
|
|
1523
|
+
const done = () => varRef(doneId, BOOL, loc);
|
|
1524
|
+
if (source.kind === "collection")
|
|
1525
|
+
return walkCollection(lowerer, frame, itemsId, source, done(), emit, loc, labels);
|
|
1526
|
+
if (source.kind === "generator") {
|
|
1527
|
+
return driveGenerator(lowerer, frame, itemsId, source.type, source.elem, [{ kind: "if", cond: done(), then: [{ kind: "break", loc }], else_: null, loc }], emit, loc, labels);
|
|
1528
|
+
}
|
|
1529
|
+
const itemsT = source.type;
|
|
1530
|
+
const seedT = source.proj === "entries" ? entryPairType(lowerer, itemsT.elem) : itemsT.elem;
|
|
1531
|
+
const iId = frame.local("i", F64, true);
|
|
1532
|
+
const vId = frame.local("v", seedT, false);
|
|
1533
|
+
const elemRead = () => ({
|
|
1534
|
+
kind: "arrayGet",
|
|
1535
|
+
arr: varRef(itemsId, itemsT, loc),
|
|
1536
|
+
index: varRef(iId, F64, loc),
|
|
1537
|
+
type: itemsT.elem,
|
|
1538
|
+
loc,
|
|
1539
|
+
});
|
|
1540
|
+
const seedInit = source.proj === "entries"
|
|
1541
|
+
? {
|
|
1542
|
+
kind: "recordLit",
|
|
1543
|
+
fields: [
|
|
1544
|
+
{ name: "0", value: varRef(iId, F64, loc) },
|
|
1545
|
+
{ name: "1", value: elemRead() },
|
|
1546
|
+
],
|
|
1547
|
+
type: seedT,
|
|
1548
|
+
loc,
|
|
1549
|
+
}
|
|
1550
|
+
: elemRead();
|
|
1551
|
+
return [
|
|
1552
|
+
{
|
|
1553
|
+
kind: "for",
|
|
1554
|
+
init: { kind: "varDecl", localId: iId, init: numLit(0, loc), loc },
|
|
1555
|
+
cond: {
|
|
1556
|
+
kind: "logical",
|
|
1557
|
+
op: "&&",
|
|
1558
|
+
left: {
|
|
1559
|
+
kind: "bin",
|
|
1560
|
+
op: "<",
|
|
1561
|
+
left: varRef(iId, F64, loc),
|
|
1562
|
+
right: {
|
|
1563
|
+
kind: "arrIntrinsic",
|
|
1564
|
+
method: "length",
|
|
1565
|
+
receiver: varRef(itemsId, itemsT, loc),
|
|
1566
|
+
args: [],
|
|
1567
|
+
type: F64,
|
|
1568
|
+
loc,
|
|
1569
|
+
},
|
|
1570
|
+
type: BOOL,
|
|
1571
|
+
loc,
|
|
1572
|
+
},
|
|
1573
|
+
right: { kind: "unary", op: "!", operand: done(), type: BOOL, loc },
|
|
1574
|
+
type: BOOL,
|
|
1575
|
+
loc,
|
|
1576
|
+
},
|
|
1577
|
+
update: frame.bump(iId),
|
|
1578
|
+
body: [
|
|
1579
|
+
{ kind: "varDecl", localId: vId, init: seedInit, loc },
|
|
1580
|
+
...emit(varRef(vId, seedT, loc)),
|
|
1581
|
+
],
|
|
1582
|
+
...(labels && { labels }),
|
|
290
1583
|
loc,
|
|
291
1584
|
},
|
|
292
|
-
|
|
293
|
-
};
|
|
294
|
-
lowerer.liftedFns.push({
|
|
295
|
-
name,
|
|
296
|
-
params: [{ localId: "v.0", name: "v", type: F64 }],
|
|
297
|
-
returnType: F64,
|
|
298
|
-
locals: [{ id: "v.0", name: "v", type: F64, mutable: true }],
|
|
299
|
-
body: [
|
|
300
|
-
{ kind: "if", cond: bad, then: [throwStmt], else_: null, loc },
|
|
301
|
-
{ kind: "return", value: t(), loc },
|
|
302
|
-
],
|
|
303
|
-
loc,
|
|
304
|
-
});
|
|
305
|
-
return name;
|
|
1585
|
+
];
|
|
306
1586
|
}
|
|
307
|
-
/** The fused chain
|
|
308
|
-
*
|
|
309
|
-
* the
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const
|
|
315
|
-
const
|
|
316
|
-
let n = 0;
|
|
317
|
-
const addLocal = (base, type, mutable) => {
|
|
318
|
-
const id = `${base}.${n++}`;
|
|
319
|
-
locals.push({ id, name: base, type, mutable });
|
|
320
|
-
return id;
|
|
321
|
-
};
|
|
322
|
-
const addParam = (base, type) => {
|
|
323
|
-
const id = `${base}.${n++}`;
|
|
324
|
-
locals.push({ id, name: base, type, mutable: true });
|
|
325
|
-
params.push({ localId: id, name: base, type });
|
|
326
|
-
return id;
|
|
327
|
-
};
|
|
328
|
-
const doneId = addLocal("done", BOOL, true);
|
|
329
|
-
const done = () => varRef(doneId, BOOL, loc);
|
|
1587
|
+
/** The fused chain function: the source, each stage's budget or callback
|
|
1588
|
+
* and the terminal's arguments as parameters; one loop over the source
|
|
1589
|
+
* with the stages nested in it and the terminal's statements innermost.
|
|
1590
|
+
* A zero take budget marks done before the first pass: Node pulls nothing
|
|
1591
|
+
* through a take(0), and closes a generator source. */
|
|
1592
|
+
function buildIterChainFn(lowerer, name, source, stages, terminal, termArgTs, resultT, loc) {
|
|
1593
|
+
const frame = new LiftedFrame(loc);
|
|
1594
|
+
const itemsId = frame.param("items", source.type);
|
|
1595
|
+
const doneId = frame.local("done", BOOL, true);
|
|
330
1596
|
const setDone = { kind: "assign", localId: doneId, value: boolLit(true, loc), loc };
|
|
331
|
-
//
|
|
332
|
-
|
|
333
|
-
const
|
|
334
|
-
? {
|
|
335
|
-
kind: "record",
|
|
336
|
-
shapeId: lowerer.shapes.intern([
|
|
337
|
-
{ name: "0", type: F64 },
|
|
338
|
-
{ name: "1", type: itemsT.elem },
|
|
339
|
-
], true),
|
|
340
|
-
}
|
|
341
|
-
: itemsT.elem;
|
|
342
|
-
let elem = seedT;
|
|
343
|
-
const slots = [];
|
|
344
|
-
for (const s of stages) {
|
|
345
|
-
if (s.kind === "take" || s.kind === "drop") {
|
|
346
|
-
const paramId = addParam("n", F64);
|
|
347
|
-
const cntId = addLocal(s.kind === "take" ? "taken" : "dropped", F64, true);
|
|
348
|
-
slots.push({ kind: s.kind, paramId, cntId, elem });
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
const fnT = s.fn.type;
|
|
352
|
-
const paramId = addParam("f", fnT);
|
|
353
|
-
const cntId = fnT.params.length === 2 ? addLocal("c", F64, true) : undefined;
|
|
354
|
-
const out = s.kind === "map"
|
|
355
|
-
? fnT.ret
|
|
356
|
-
: s.kind === "flatMap"
|
|
357
|
-
? fnT.ret.elem
|
|
358
|
-
: elem;
|
|
359
|
-
slots.push({ kind: s.kind, paramId, fnT, cntId, elem: out });
|
|
360
|
-
elem = out;
|
|
361
|
-
}
|
|
362
|
-
const termIds = termArgTs.map((t, i) => addParam(i === 0 ? "tf" : "init", t));
|
|
1597
|
+
// Parameters in call order: per-stage budget/callback, then terminal's.
|
|
1598
|
+
const slots = stages.map((s) => stageSlot(frame, s, frame.param("budget" in s ? "n" : "f", "budget" in s ? F64 : s.fn.type)));
|
|
1599
|
+
const termIds = termArgTs.map((t, i) => frame.param(i === 0 ? "tf" : "init", t));
|
|
363
1600
|
const termFnT = termArgTs[0]?.kind === "func" ? termArgTs[0] : null;
|
|
364
1601
|
const termCntId = (terminal === "reduce" && termFnT !== null && termFnT.params.length === 3) ||
|
|
365
1602
|
(terminal !== "reduce" &&
|
|
@@ -367,29 +1604,8 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
367
1604
|
termFnT !== null &&
|
|
368
1605
|
termFnT.params.length === 2) ||
|
|
369
1606
|
terminal === "reduce"
|
|
370
|
-
?
|
|
1607
|
+
? frame.local("k", F64, true)
|
|
371
1608
|
: undefined;
|
|
372
|
-
const bump = (id) => ({
|
|
373
|
-
kind: "assign",
|
|
374
|
-
localId: id,
|
|
375
|
-
value: {
|
|
376
|
-
kind: "bin",
|
|
377
|
-
op: "+",
|
|
378
|
-
left: varRef(id, F64, loc),
|
|
379
|
-
right: numLit(1, loc),
|
|
380
|
-
type: F64,
|
|
381
|
-
loc,
|
|
382
|
-
},
|
|
383
|
-
loc,
|
|
384
|
-
});
|
|
385
|
-
const callWith = (fnT, fnId, value, cntId) => {
|
|
386
|
-
const args = [];
|
|
387
|
-
if (fnT.params.length >= 1)
|
|
388
|
-
args.push(value);
|
|
389
|
-
if (cntId !== undefined && fnT.params.length >= 2)
|
|
390
|
-
args.push(varRef(cntId, F64, loc));
|
|
391
|
-
return { kind: "callValue", callee: varRef(fnId, fnT, loc), args, type: fnT.ret, loc };
|
|
392
|
-
};
|
|
393
1609
|
// Terminal state.
|
|
394
1610
|
const preLoop = [];
|
|
395
1611
|
const postLoop = [];
|
|
@@ -398,7 +1614,7 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
398
1614
|
let hasAccId = "";
|
|
399
1615
|
let resId = "";
|
|
400
1616
|
if (terminal === "toArray") {
|
|
401
|
-
outId =
|
|
1617
|
+
outId = frame.local("out", resultT, false);
|
|
402
1618
|
preLoop.push({
|
|
403
1619
|
kind: "varDecl",
|
|
404
1620
|
localId: outId,
|
|
@@ -408,7 +1624,7 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
408
1624
|
postLoop.push({ kind: "return", value: varRef(outId, resultT, loc), loc });
|
|
409
1625
|
}
|
|
410
1626
|
else if (terminal === "some" || terminal === "every") {
|
|
411
|
-
resId =
|
|
1627
|
+
resId = frame.local("res", BOOL, true);
|
|
412
1628
|
preLoop.push({
|
|
413
1629
|
kind: "varDecl",
|
|
414
1630
|
localId: resId,
|
|
@@ -418,7 +1634,7 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
418
1634
|
postLoop.push({ kind: "return", value: varRef(resId, BOOL, loc), loc });
|
|
419
1635
|
}
|
|
420
1636
|
else if (terminal === "find") {
|
|
421
|
-
resId =
|
|
1637
|
+
resId = frame.local("res", resultT, true);
|
|
422
1638
|
const undef = lowerer.wrappedUndefined(resultT, loc);
|
|
423
1639
|
if (undef === null)
|
|
424
1640
|
throw new InternalCompilerError("lowerer bug: find result union lacks undefined");
|
|
@@ -426,7 +1642,7 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
426
1642
|
postLoop.push({ kind: "return", value: varRef(resId, resultT, loc), loc });
|
|
427
1643
|
}
|
|
428
1644
|
else if (terminal === "reduce") {
|
|
429
|
-
accId =
|
|
1645
|
+
accId = frame.local("acc", resultT, true);
|
|
430
1646
|
if (termIds.length === 2) {
|
|
431
1647
|
preLoop.push({
|
|
432
1648
|
kind: "varDecl",
|
|
@@ -436,7 +1652,7 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
436
1652
|
});
|
|
437
1653
|
}
|
|
438
1654
|
else {
|
|
439
|
-
hasAccId =
|
|
1655
|
+
hasAccId = frame.local("hasAcc", BOOL, true);
|
|
440
1656
|
preLoop.push({ kind: "varDecl", localId: hasAccId, init: boolLit(false, loc), loc });
|
|
441
1657
|
postLoop.push({
|
|
442
1658
|
kind: "if",
|
|
@@ -460,29 +1676,7 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
460
1676
|
}
|
|
461
1677
|
if (termCntId !== undefined)
|
|
462
1678
|
preLoop.push({ kind: "varDecl", localId: termCntId, init: numLit(0, loc), loc });
|
|
463
|
-
|
|
464
|
-
let doneInit = boolLit(false, loc);
|
|
465
|
-
for (const s of slots) {
|
|
466
|
-
if (s.kind !== "take")
|
|
467
|
-
continue;
|
|
468
|
-
const isZero = {
|
|
469
|
-
kind: "bin",
|
|
470
|
-
op: "===",
|
|
471
|
-
left: varRef(s.paramId, F64, loc),
|
|
472
|
-
right: numLit(0, loc),
|
|
473
|
-
type: BOOL,
|
|
474
|
-
loc,
|
|
475
|
-
};
|
|
476
|
-
doneInit =
|
|
477
|
-
doneInit.kind === "boolLit"
|
|
478
|
-
? isZero
|
|
479
|
-
: { kind: "logical", op: "||", left: doneInit, right: isZero, type: BOOL, loc };
|
|
480
|
-
}
|
|
481
|
-
preLoop.unshift({ kind: "varDecl", localId: doneId, init: doneInit, loc });
|
|
482
|
-
for (const s of slots) {
|
|
483
|
-
if (s.cntId !== undefined)
|
|
484
|
-
preLoop.push({ kind: "varDecl", localId: s.cntId, init: numLit(0, loc), loc });
|
|
485
|
-
}
|
|
1679
|
+
preLoop.unshift(...stagePrologue(slots, doneId, loc));
|
|
486
1680
|
// The terminal's per-element statements over `value`.
|
|
487
1681
|
const terminalBody = (value) => {
|
|
488
1682
|
const out = [];
|
|
@@ -501,10 +1695,14 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
501
1695
|
});
|
|
502
1696
|
}
|
|
503
1697
|
else if (terminal === "forEach") {
|
|
504
|
-
out.push({
|
|
1698
|
+
out.push({
|
|
1699
|
+
kind: "exprStmt",
|
|
1700
|
+
expr: callStage(termFnT, termIds[0], value, termCntId, loc),
|
|
1701
|
+
loc,
|
|
1702
|
+
});
|
|
505
1703
|
}
|
|
506
1704
|
else if (terminal === "some" || terminal === "every") {
|
|
507
|
-
const hit =
|
|
1705
|
+
const hit = callStage(termFnT, termIds[0], value, termCntId, loc);
|
|
508
1706
|
const cond = terminal === "some" ? hit : { kind: "unary", op: "!", operand: hit, type: BOOL, loc };
|
|
509
1707
|
out.push({
|
|
510
1708
|
kind: "if",
|
|
@@ -524,7 +1722,7 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
524
1722
|
throw new InternalCompilerError("lowerer bug: find result is not the undefined-armed union");
|
|
525
1723
|
out.push({
|
|
526
1724
|
kind: "if",
|
|
527
|
-
cond:
|
|
1725
|
+
cond: callStage(termFnT, termIds[0], value, termCntId, loc),
|
|
528
1726
|
then: [
|
|
529
1727
|
{
|
|
530
1728
|
kind: "assign",
|
|
@@ -576,233 +1774,154 @@ function buildIterChainFn(lowerer, name, itemsT, srcProj, stages, terminal, term
|
|
|
576
1774
|
}
|
|
577
1775
|
}
|
|
578
1776
|
if (termCntId !== undefined)
|
|
579
|
-
out.push(bump(termCntId));
|
|
1777
|
+
out.push(frame.bump(termCntId));
|
|
580
1778
|
return out;
|
|
581
1779
|
};
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
1780
|
+
const emit = foldStages(lowerer, frame, slots, terminalBody, doneId, loc);
|
|
1781
|
+
return {
|
|
1782
|
+
name,
|
|
1783
|
+
params: frame.params,
|
|
1784
|
+
returnType: resultT,
|
|
1785
|
+
locals: frame.locals,
|
|
1786
|
+
body: [
|
|
1787
|
+
...preLoop,
|
|
1788
|
+
...sourceLoop(lowerer, frame, itemsId, source, doneId, emit, loc),
|
|
1789
|
+
...postLoop,
|
|
1790
|
+
],
|
|
1791
|
+
loc,
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
/** An iterator helper object's generator for one stage over `src`:
|
|
1795
|
+
*
|
|
1796
|
+
* map: for (v of src) yield f(v, c++)
|
|
1797
|
+
* filter: for (v of src) if (f(v, c++)) yield v
|
|
1798
|
+
* take: for (;;) { if (rem === 0) { close src; return } rem--; pull; yield v }
|
|
1799
|
+
* drop: for (v of src) { if (dropped < n) { dropped++; continue } yield v }
|
|
1800
|
+
* flatMap: for (v of src) for (w of f(v, c++)) yield w
|
|
1801
|
+
*
|
|
1802
|
+
* The source drive closes `src` on every early exit, including a
|
|
1803
|
+
* `return()` at one of the yields; `closesSource` closes it on a
|
|
1804
|
+
* `return()` before the first `next()`. */
|
|
1805
|
+
function buildHelperGenFn(lowerer, name, source, srcElem, stage, argT, outT, resultType, loc) {
|
|
1806
|
+
const frame = new LiftedFrame(loc);
|
|
1807
|
+
const srcId = frame.param("src", source.type);
|
|
1808
|
+
const argId = frame.param(stage.kind === "take" || stage.kind === "drop" ? "n" : "f", argT);
|
|
1809
|
+
const drive = (pre, each, at) => source.kind === "generator"
|
|
1810
|
+
? driveGenerator(lowerer, frame, srcId, source.type, srcElem, pre, each, at)
|
|
1811
|
+
: driveCollectionNative(lowerer, frame, srcId, source, pre, each, at);
|
|
1812
|
+
const yieldOf = (value) => ({
|
|
1813
|
+
kind: "exprStmt",
|
|
1814
|
+
expr: {
|
|
1815
|
+
kind: "yieldExpr",
|
|
1816
|
+
value,
|
|
1817
|
+
type: outT.nextT.kind === "undefinedT" ? VOID : outT.nextT,
|
|
1818
|
+
loc,
|
|
1819
|
+
},
|
|
1820
|
+
loc,
|
|
1821
|
+
});
|
|
1822
|
+
const fnT = argT.kind === "func" ? argT : null;
|
|
1823
|
+
const counted = fnT !== null && fnT.params.length === 2;
|
|
1824
|
+
const cntId = counted ? frame.local("c", F64, true) : null;
|
|
1825
|
+
const callF = (value) => {
|
|
1826
|
+
const args = [];
|
|
1827
|
+
if (fnT.params.length >= 1)
|
|
1828
|
+
args.push(value);
|
|
1829
|
+
if (cntId !== null)
|
|
1830
|
+
args.push(varRef(cntId, F64, loc));
|
|
1831
|
+
return { kind: "callValue", callee: varRef(argId, fnT, loc), args, type: fnT.ret, loc };
|
|
1832
|
+
};
|
|
1833
|
+
const body = [];
|
|
1834
|
+
if (cntId !== null)
|
|
1835
|
+
body.push({ kind: "varDecl", localId: cntId, init: numLit(0, loc), loc });
|
|
1836
|
+
const bumpCount = () => (cntId !== null ? [frame.bump(cntId)] : []);
|
|
1837
|
+
const n = () => varRef(argId, F64, loc);
|
|
1838
|
+
if (stage.kind === "map") {
|
|
1839
|
+
body.push(...drive([], (value) => {
|
|
1840
|
+
const mId = frame.local("m", fnT.ret, false);
|
|
1841
|
+
return [
|
|
1842
|
+
{ kind: "varDecl", localId: mId, init: callF(value), loc },
|
|
1843
|
+
...bumpCount(),
|
|
1844
|
+
yieldOf(varRef(mId, fnT.ret, loc)),
|
|
636
1845
|
];
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
{
|
|
646
|
-
kind: "if",
|
|
647
|
-
cond: {
|
|
648
|
-
kind: "bin",
|
|
649
|
-
op: ">=",
|
|
650
|
-
left: varRef(s.cntId, F64, loc),
|
|
651
|
-
right: varRef(s.paramId, F64, loc),
|
|
652
|
-
type: BOOL,
|
|
653
|
-
loc,
|
|
654
|
-
},
|
|
655
|
-
then: [setDone],
|
|
656
|
-
else_: null,
|
|
657
|
-
loc,
|
|
658
|
-
},
|
|
659
|
-
...inner(value),
|
|
1846
|
+
}, loc));
|
|
1847
|
+
}
|
|
1848
|
+
else if (stage.kind === "filter") {
|
|
1849
|
+
body.push(...drive([], (value) => {
|
|
1850
|
+
const okId = frame.local("ok", BOOL, false);
|
|
1851
|
+
return [
|
|
1852
|
+
{ kind: "varDecl", localId: okId, init: callF(value), loc },
|
|
1853
|
+
...bumpCount(),
|
|
1854
|
+
{ kind: "if", cond: varRef(okId, BOOL, loc), then: [yieldOf(value)], else_: null, loc },
|
|
660
1855
|
];
|
|
661
|
-
}
|
|
662
|
-
else {
|
|
663
|
-
// flatMap: an inner loop over the returned array, `!done` carried.
|
|
664
|
-
emit = (value) => {
|
|
665
|
-
const innerT = s.fnT.ret;
|
|
666
|
-
const arrId = addLocal("fm", innerT, false);
|
|
667
|
-
const jId = addLocal("j", F64, true);
|
|
668
|
-
const wId = addLocal("w", innerT.elem, false);
|
|
669
|
-
return [
|
|
670
|
-
{
|
|
671
|
-
kind: "varDecl",
|
|
672
|
-
localId: arrId,
|
|
673
|
-
init: callWith(s.fnT, s.paramId, value, s.cntId),
|
|
674
|
-
loc,
|
|
675
|
-
},
|
|
676
|
-
...(s.cntId !== undefined ? [bump(s.cntId)] : []),
|
|
677
|
-
{
|
|
678
|
-
kind: "for",
|
|
679
|
-
init: { kind: "varDecl", localId: jId, init: numLit(0, loc), loc },
|
|
680
|
-
cond: {
|
|
681
|
-
kind: "logical",
|
|
682
|
-
op: "&&",
|
|
683
|
-
left: {
|
|
684
|
-
kind: "bin",
|
|
685
|
-
op: "<",
|
|
686
|
-
left: varRef(jId, F64, loc),
|
|
687
|
-
right: {
|
|
688
|
-
kind: "arrIntrinsic",
|
|
689
|
-
method: "length",
|
|
690
|
-
receiver: varRef(arrId, innerT, loc),
|
|
691
|
-
args: [],
|
|
692
|
-
type: F64,
|
|
693
|
-
loc,
|
|
694
|
-
},
|
|
695
|
-
type: BOOL,
|
|
696
|
-
loc,
|
|
697
|
-
},
|
|
698
|
-
right: { kind: "unary", op: "!", operand: done(), type: BOOL, loc },
|
|
699
|
-
type: BOOL,
|
|
700
|
-
loc,
|
|
701
|
-
},
|
|
702
|
-
update: {
|
|
703
|
-
kind: "assign",
|
|
704
|
-
localId: jId,
|
|
705
|
-
value: {
|
|
706
|
-
kind: "bin",
|
|
707
|
-
op: "+",
|
|
708
|
-
left: varRef(jId, F64, loc),
|
|
709
|
-
right: numLit(1, loc),
|
|
710
|
-
type: F64,
|
|
711
|
-
loc,
|
|
712
|
-
},
|
|
713
|
-
loc,
|
|
714
|
-
},
|
|
715
|
-
body: [
|
|
716
|
-
{
|
|
717
|
-
kind: "varDecl",
|
|
718
|
-
localId: wId,
|
|
719
|
-
init: {
|
|
720
|
-
kind: "arrayGet",
|
|
721
|
-
arr: varRef(arrId, innerT, loc),
|
|
722
|
-
index: varRef(jId, F64, loc),
|
|
723
|
-
type: innerT.elem,
|
|
724
|
-
loc,
|
|
725
|
-
},
|
|
726
|
-
loc,
|
|
727
|
-
},
|
|
728
|
-
...inner(varRef(wId, innerT.elem, loc)),
|
|
729
|
-
],
|
|
730
|
-
loc,
|
|
731
|
-
},
|
|
732
|
-
];
|
|
733
|
-
};
|
|
734
|
-
}
|
|
1856
|
+
}, loc));
|
|
735
1857
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
const seedInit = srcProj === "entries"
|
|
746
|
-
? {
|
|
747
|
-
kind: "recordLit",
|
|
748
|
-
fields: [
|
|
749
|
-
{ name: "0", value: varRef(iId, F64, loc) },
|
|
750
|
-
{ name: "1", value: elemRead() },
|
|
751
|
-
],
|
|
752
|
-
type: seedT,
|
|
753
|
-
loc,
|
|
754
|
-
}
|
|
755
|
-
: elemRead();
|
|
756
|
-
const loop = {
|
|
757
|
-
kind: "for",
|
|
758
|
-
init: { kind: "varDecl", localId: iId, init: numLit(0, loc), loc },
|
|
759
|
-
cond: {
|
|
760
|
-
kind: "logical",
|
|
761
|
-
op: "&&",
|
|
762
|
-
left: {
|
|
763
|
-
kind: "bin",
|
|
764
|
-
op: "<",
|
|
765
|
-
left: varRef(iId, F64, loc),
|
|
766
|
-
right: {
|
|
767
|
-
kind: "arrIntrinsic",
|
|
768
|
-
method: "length",
|
|
769
|
-
receiver: varRef("items.0", itemsT, loc),
|
|
770
|
-
args: [],
|
|
771
|
-
type: F64,
|
|
772
|
-
loc,
|
|
773
|
-
},
|
|
774
|
-
type: BOOL,
|
|
1858
|
+
else if (stage.kind === "take") {
|
|
1859
|
+
// The budget is spent before each pull; a spent budget closes the
|
|
1860
|
+
// source on the next pass instead of pulling.
|
|
1861
|
+
const pre = [
|
|
1862
|
+
{
|
|
1863
|
+
kind: "if",
|
|
1864
|
+
cond: { kind: "bin", op: "===", left: n(), right: numLit(0, loc), type: BOOL, loc },
|
|
1865
|
+
then: [{ kind: "break", loc }],
|
|
1866
|
+
else_: null,
|
|
775
1867
|
loc,
|
|
776
1868
|
},
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
update: {
|
|
782
|
-
kind: "assign",
|
|
783
|
-
localId: iId,
|
|
784
|
-
value: {
|
|
785
|
-
kind: "bin",
|
|
786
|
-
op: "+",
|
|
787
|
-
left: varRef(iId, F64, loc),
|
|
788
|
-
right: numLit(1, loc),
|
|
789
|
-
type: F64,
|
|
1869
|
+
{
|
|
1870
|
+
kind: "assign",
|
|
1871
|
+
localId: argId,
|
|
1872
|
+
value: { kind: "bin", op: "-", left: n(), right: numLit(1, loc), type: F64, loc },
|
|
790
1873
|
loc,
|
|
791
1874
|
},
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
1875
|
+
];
|
|
1876
|
+
body.push(...drive(pre, (value) => [yieldOf(value)], loc));
|
|
1877
|
+
}
|
|
1878
|
+
else if (stage.kind === "drop") {
|
|
1879
|
+
const droppedId = frame.local("dropped", F64, true);
|
|
1880
|
+
body.push({ kind: "varDecl", localId: droppedId, init: numLit(0, loc), loc });
|
|
1881
|
+
body.push(...drive([], (value) => [
|
|
1882
|
+
{
|
|
1883
|
+
kind: "if",
|
|
1884
|
+
cond: {
|
|
1885
|
+
kind: "bin",
|
|
1886
|
+
op: "<",
|
|
1887
|
+
left: varRef(droppedId, F64, loc),
|
|
1888
|
+
right: n(),
|
|
1889
|
+
type: BOOL,
|
|
1890
|
+
loc,
|
|
1891
|
+
},
|
|
1892
|
+
then: [frame.bump(droppedId), { kind: "continue", loc }],
|
|
1893
|
+
else_: null,
|
|
1894
|
+
loc,
|
|
1895
|
+
},
|
|
1896
|
+
yieldOf(value),
|
|
1897
|
+
], loc));
|
|
1898
|
+
}
|
|
1899
|
+
else {
|
|
1900
|
+
body.push(...drive([], (value) => {
|
|
1901
|
+
const innerT = fnT.ret;
|
|
1902
|
+
const innerId = frame.local("fm", innerT, false);
|
|
1903
|
+
return [
|
|
1904
|
+
{ kind: "varDecl", localId: innerId, init: callF(value), loc },
|
|
1905
|
+
...bumpCount(),
|
|
1906
|
+
...walkInner(lowerer, frame, innerId, innerT, null, (w) => [yieldOf(w)], loc),
|
|
1907
|
+
];
|
|
1908
|
+
}, loc));
|
|
1909
|
+
}
|
|
1910
|
+
body.push({ kind: "return", value: null, loc });
|
|
800
1911
|
return {
|
|
801
1912
|
name,
|
|
802
|
-
params,
|
|
803
|
-
returnType:
|
|
804
|
-
locals,
|
|
805
|
-
body
|
|
1913
|
+
params: frame.params,
|
|
1914
|
+
returnType: VOID,
|
|
1915
|
+
locals: frame.locals,
|
|
1916
|
+
body,
|
|
1917
|
+
generator: {
|
|
1918
|
+
yieldT: outT.yieldT,
|
|
1919
|
+
nextT: outT.nextT,
|
|
1920
|
+
resultType,
|
|
1921
|
+
tag: "Iterator Helper",
|
|
1922
|
+
// A native Map or Set iterator has no return() to call.
|
|
1923
|
+
...(source.kind === "generator" ? { closesSource: true } : {}),
|
|
1924
|
+
},
|
|
806
1925
|
loc,
|
|
807
1926
|
};
|
|
808
1927
|
}
|