@scriptc/compiler 0.3.5 → 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 +960 -82
- 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 +324 -179
- 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 +576 -268
- package/dist/backend/llvm/emitter.js +801 -4447
- 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-dispatch.js +1 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +92 -63
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +132 -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 +217 -24
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +102 -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 +77 -25
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +100 -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 +229 -5
- 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 +57 -8
- 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 +70 -9
- package/dist/backend/llvm/nullable-unions.js +105 -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 +13 -2
- package/dist/backend/llvm/record-results.js +66 -6
- 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 +143 -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 +69 -43
- package/dist/backend/llvm/shapes.js +285 -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/speculative-integers.d.ts +74 -0
- package/dist/backend/llvm/speculative-integers.js +571 -0
- package/dist/backend/llvm/speculative-integers.js.map +1 -0
- package/dist/backend/llvm/speculative-integers.test.d.ts +1 -0
- package/dist/backend/llvm/speculative-integers.test.js +148 -0
- package/dist/backend/llvm/speculative-integers.test.js.map +1 -0
- 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 +6 -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 -134
- 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 +2 -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.d.ts +7 -3
- package/dist/backend/runtime-pack.js +12 -6
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +20 -6
- 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 +25 -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 +19 -6
- 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 +11 -7
- package/dist/diagnostics/diagnostic.js +35 -23
- 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 +72 -4
- 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 +45 -6
- 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 +18 -0
- package/dist/frontend/lowering/builtins/compression.js +230 -52
- 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 +223 -38
- 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 +174 -6
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +4 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +136 -113
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.d.ts +8 -0
- package/dist/frontend/lowering/builtins/filesystem.js +213 -76
- 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/hash-stream.d.ts +12 -0
- package/dist/frontend/lowering/builtins/hash-stream.js +80 -0
- package/dist/frontend/lowering/builtins/hash-stream.js.map +1 -0
- 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 +67 -46
- 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 +468 -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 +55 -13
- package/dist/frontend/lowering/builtins/readline.js +931 -69
- 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 +16 -0
- package/dist/frontend/lowering/builtins/workers.js +246 -3
- 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.d.ts +55 -0
- package/dist/frontend/lowering/class-protocols.js +738 -22
- 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 +19 -0
- package/dist/frontend/lowering/containers/array-from-async.js +427 -0
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -0
- 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 +219 -27
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +81 -48
- 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 +238 -128
- 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 +1298 -452
- 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 +1499 -456
- 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 +268 -71
- 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 +1493 -12407
- 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 +354 -99
- 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 +19 -2
- package/dist/frontend/lowering/lower-mock.js +557 -74
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +268 -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 +638 -105
- 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 +1589 -398
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +4 -3
- package/dist/frontend/lowering/lower-stream.js +714 -75
- 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 +574 -100
- 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 +409 -26
- package/dist/frontend/lowering/lowerer.js +1918 -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/null-prototype.d.ts +13 -0
- package/dist/frontend/lowering/null-prototype.js +33 -0
- package/dist/frontend/lowering/null-prototype.js.map +1 -0
- 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 +15 -6
- package/dist/frontend/lowering/surfaces.js +278 -45
- 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.d.ts +5 -0
- package/dist/frontend/mock-shapes.js +39 -7
- 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 -254
- 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 +2612 -695
- 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 +47 -10
- 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 +139 -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 +655 -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 +10 -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 +119 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +29 -1
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loop-facts.d.ts +16 -6
- package/dist/ir/integer-loop-facts.js +143 -38
- 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 +4 -6
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +142 -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 +234 -58
- package/dist/ir/ir.js +123 -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 +150 -33
- package/dist/ir/runtime-features.js +672 -339
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +62 -0
- package/dist/ir/runtime-features.test.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 +107 -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 +220 -71
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +64 -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 +18 -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 +332 -36
|
@@ -0,0 +1,2129 @@
|
|
|
1
|
+
/* WebAssembly to LLVM IR.
|
|
2
|
+
*
|
|
3
|
+
* Translates one validated module (binary.ts accepted it within the
|
|
4
|
+
* translatable feature level) to LLVM assembly that the program's emitter
|
|
5
|
+
* appends to its own module, so the native helper optimizes, partitions and
|
|
6
|
+
* caches it with the program. The runtime (scr_wasm.c) implements the
|
|
7
|
+
* JavaScript API over the descriptor this emits; scr_wasm_abi.h is the
|
|
8
|
+
* contract both sides follow.
|
|
9
|
+
*
|
|
10
|
+
* Shape of the output:
|
|
11
|
+
* - one internal function per wasm function, taking the instance as its
|
|
12
|
+
* first parameter (`ptr %inst`) and the wasm values directly (i32, i64,
|
|
13
|
+
* float, double; references are pointers). Several results return as a
|
|
14
|
+
* literal struct. An imported function is a stub that packs its
|
|
15
|
+
* arguments and calls scr_wasm_import_call.
|
|
16
|
+
* - one thunk per exported function, `void (ptr inst, ptr args, ptr
|
|
17
|
+
* results)` over 64-bit slots, which the runtime calls under its trap
|
|
18
|
+
* guard;
|
|
19
|
+
* - an init function (globals, table initializers, active element and
|
|
20
|
+
* data segments); the descriptor names the start function;
|
|
21
|
+
* - constant data (segments, names, signatures) and the descriptor.
|
|
22
|
+
*
|
|
23
|
+
* The instance layout (scr_wasm_abi.h): host at 0, memory base at 8,
|
|
24
|
+
* memory object at 16, function reference records at 24, then one pointer
|
|
25
|
+
* per table and one cell pointer per global.
|
|
26
|
+
*
|
|
27
|
+
* Memory accesses compute `base + zext(address) + offset` in 64 bits. With
|
|
28
|
+
* guard pages (64-bit hosts) the runtime reserves enough address space that
|
|
29
|
+
* every such address past the memory faults, so accesses are unchecked and
|
|
30
|
+
* the base is loaded once per function (the memory never moves). With
|
|
31
|
+
* explicit bounds checks (sanitizer builds and hosts without the fault
|
|
32
|
+
* handler) the base and byte length live in function-local slots that are
|
|
33
|
+
* reloaded after every call and memory.grow.
|
|
34
|
+
*
|
|
35
|
+
* Locals, block results and loop parameters are allocas; LLVM promotes them
|
|
36
|
+
* to SSA values. Traps call scr_wasm_trap, which never returns. Plain
|
|
37
|
+
* TypeScript without bigint, so the native compiler compiles it too. */
|
|
38
|
+
import { KIND_FUNC, KIND_GLOBAL, KIND_MEMORY, KIND_TABLE, VAL_EXTERNREF, VAL_F32, VAL_F64, VAL_FUNCREF, VAL_I32, VAL_I64, WasmCursor, parseWasmModule, readMemargFlags, skipImmediates, } from "./module.js";
|
|
39
|
+
/** Trap codes (scr_wasm_abi.h SCR_WASM_TRAP_*). */
|
|
40
|
+
export const TRAP_UNREACHABLE = 1;
|
|
41
|
+
export const TRAP_MEMORY_OOB = 2;
|
|
42
|
+
export const TRAP_DIV_BY_ZERO = 3;
|
|
43
|
+
export const TRAP_DIV_UNREPRESENTABLE = 4;
|
|
44
|
+
export const TRAP_REM_BY_ZERO = 5;
|
|
45
|
+
export const TRAP_FLOAT_UNREPRESENTABLE = 6;
|
|
46
|
+
export const TRAP_TABLE_OOB = 7;
|
|
47
|
+
export const TRAP_SIGNATURE = 8;
|
|
48
|
+
export const TRAP_NULL = 9;
|
|
49
|
+
/** scr_wasm_abi.h SCR_WASM_TRAP_EXHAUSTION. */
|
|
50
|
+
export const TRAP_EXHAUSTION = 100;
|
|
51
|
+
/** The descriptor ABI version both sides agree on. */
|
|
52
|
+
export const WASM_ABI_VERSION = 2;
|
|
53
|
+
/** Instance slot offsets (bytes). */
|
|
54
|
+
const OFF_MEMBASE = 8;
|
|
55
|
+
const OFF_MEMORY = 16;
|
|
56
|
+
const OFF_FUNCREFS = 24;
|
|
57
|
+
const OFF_TABLES = 32;
|
|
58
|
+
/** sizeof(ScrWasmFuncRef). */
|
|
59
|
+
const FUNCREF_SIZE = 24;
|
|
60
|
+
/** A construct the translator does not support in an otherwise valid module. */
|
|
61
|
+
export class WasmTranslateError extends Error {
|
|
62
|
+
}
|
|
63
|
+
/** Attributes of translated functions. Recursion must exhaust the stack
|
|
64
|
+
* as it does in V8, so LLVM may not turn self-recursion into loops (tail
|
|
65
|
+
* recursion elimination, including its accumulator form, which would make
|
|
66
|
+
* `f(x) + 1` recursion loop forever) or calls into jumps. */
|
|
67
|
+
const FUNC_ATTRS = `nounwind "disable-tail-calls"="true"`;
|
|
68
|
+
const RUNTIME_DECLS = [
|
|
69
|
+
"declare void @scr_wasm_trap(i32) noreturn nounwind cold",
|
|
70
|
+
"declare void @scr_wasm_import_call(ptr, i32, ptr, ptr)",
|
|
71
|
+
"declare i32 @scr_wasm_memory_grow(ptr, i32)",
|
|
72
|
+
"declare void @scr_wasm_memory_fill(ptr, i32, i32, i32)",
|
|
73
|
+
"declare void @scr_wasm_memory_copy(ptr, i32, i32, i32)",
|
|
74
|
+
"declare void @scr_wasm_memory_init(ptr, i32, i32, i32, i32)",
|
|
75
|
+
"declare void @scr_wasm_data_drop(ptr, i32)",
|
|
76
|
+
"declare ptr @scr_wasm_table_get(ptr, i32, i32)",
|
|
77
|
+
"declare void @scr_wasm_table_set(ptr, i32, i32, ptr)",
|
|
78
|
+
"declare i32 @scr_wasm_table_grow(ptr, i32, ptr, i32)",
|
|
79
|
+
"declare void @scr_wasm_table_fill(ptr, i32, i32, ptr, i32)",
|
|
80
|
+
"declare void @scr_wasm_table_copy(ptr, i32, i32, i32, i32, i32)",
|
|
81
|
+
"declare void @scr_wasm_table_init(ptr, i32, i32, i32, i32, i32)",
|
|
82
|
+
"declare void @scr_wasm_elem_drop(ptr, i32)",
|
|
83
|
+
"declare void @scr_wasm_global_set_ref(ptr, ptr)",
|
|
84
|
+
];
|
|
85
|
+
function llType(t) {
|
|
86
|
+
switch (t) {
|
|
87
|
+
case VAL_I32:
|
|
88
|
+
return "i32";
|
|
89
|
+
case VAL_I64:
|
|
90
|
+
return "i64";
|
|
91
|
+
case VAL_F32:
|
|
92
|
+
return "float";
|
|
93
|
+
case VAL_F64:
|
|
94
|
+
return "double";
|
|
95
|
+
case VAL_FUNCREF:
|
|
96
|
+
case VAL_EXTERNREF:
|
|
97
|
+
return "ptr";
|
|
98
|
+
default:
|
|
99
|
+
throw new WasmTranslateError(`value type 0x${t.toString(16)} is not supported`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function zeroOf(t) {
|
|
103
|
+
switch (t) {
|
|
104
|
+
case VAL_I32:
|
|
105
|
+
case VAL_I64:
|
|
106
|
+
return "0";
|
|
107
|
+
case VAL_F32:
|
|
108
|
+
case VAL_F64:
|
|
109
|
+
return "0.0";
|
|
110
|
+
default:
|
|
111
|
+
return "null";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** The runtime's signature letter of a value type. */
|
|
115
|
+
function sigChar(t) {
|
|
116
|
+
switch (t) {
|
|
117
|
+
case VAL_I32:
|
|
118
|
+
return "i";
|
|
119
|
+
case VAL_I64:
|
|
120
|
+
return "I";
|
|
121
|
+
case VAL_F32:
|
|
122
|
+
return "f";
|
|
123
|
+
case VAL_F64:
|
|
124
|
+
return "F";
|
|
125
|
+
case VAL_FUNCREF:
|
|
126
|
+
return "r";
|
|
127
|
+
case VAL_EXTERNREF:
|
|
128
|
+
return "x";
|
|
129
|
+
default:
|
|
130
|
+
throw new WasmTranslateError(`value type 0x${t.toString(16)} is not supported`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function sigString(ft) {
|
|
134
|
+
let s = "";
|
|
135
|
+
for (const p of ft.params)
|
|
136
|
+
s += sigChar(p);
|
|
137
|
+
s += ":";
|
|
138
|
+
for (const r of ft.results)
|
|
139
|
+
s += sigChar(r);
|
|
140
|
+
return s;
|
|
141
|
+
}
|
|
142
|
+
function retType(results) {
|
|
143
|
+
if (results.length === 0)
|
|
144
|
+
return "void";
|
|
145
|
+
if (results.length === 1)
|
|
146
|
+
return llType(results[0]);
|
|
147
|
+
return `{ ${results.map(llType).join(", ")} }`;
|
|
148
|
+
}
|
|
149
|
+
function hex8(n) {
|
|
150
|
+
return (n >>> 0).toString(16).padStart(8, "0");
|
|
151
|
+
}
|
|
152
|
+
/** An i64 constant from its halves, in LLVM's unsigned hexadecimal form. */
|
|
153
|
+
function i64Lit(lo, hi) {
|
|
154
|
+
return `u0x${hex8(hi)}${hex8(lo)}`;
|
|
155
|
+
}
|
|
156
|
+
/** The canonical signature identity call_indirect compares: two
|
|
157
|
+
* independent 32-bit FNV-1a hashes of the signature text. Equal signatures
|
|
158
|
+
* in different modules get the same identity. */
|
|
159
|
+
export function signatureHash(sig) {
|
|
160
|
+
let a = 0x811c9dc5;
|
|
161
|
+
let b = 0x01000193 ^ 0x5bd1e995;
|
|
162
|
+
for (let i = 0; i < sig.length; i++) {
|
|
163
|
+
const c = sig.charCodeAt(i);
|
|
164
|
+
a = Math.imul(a ^ c, 0x01000193);
|
|
165
|
+
b = Math.imul(b ^ c, 0x01000193) ^ (b >>> 13);
|
|
166
|
+
}
|
|
167
|
+
return i64Lit(a >>> 0, b >>> 0);
|
|
168
|
+
}
|
|
169
|
+
/** UTF-8 bytes of a string. */
|
|
170
|
+
function utf8Bytes(text) {
|
|
171
|
+
const out = [];
|
|
172
|
+
for (let i = 0; i < text.length; i++) {
|
|
173
|
+
const cp = text.codePointAt(i);
|
|
174
|
+
if (cp > 0xffff)
|
|
175
|
+
i++;
|
|
176
|
+
if (cp < 0x80)
|
|
177
|
+
out.push(cp);
|
|
178
|
+
else if (cp < 0x800)
|
|
179
|
+
out.push(0xc0 | (cp >> 6), 0x80 | (cp & 0x3f));
|
|
180
|
+
else if (cp < 0x10000)
|
|
181
|
+
out.push(0xe0 | (cp >> 12), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));
|
|
182
|
+
else {
|
|
183
|
+
out.push(0xf0 | (cp >> 18), 0x80 | ((cp >> 12) & 0x3f), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
/** An LLVM c"..." string body for bytes. */
|
|
189
|
+
function cBytes(bytes, start, end) {
|
|
190
|
+
let s = "";
|
|
191
|
+
for (let i = start; i < end; i++) {
|
|
192
|
+
const b = bytes[i];
|
|
193
|
+
if (b >= 0x20 && b < 0x7f && b !== 0x22 && b !== 0x5c)
|
|
194
|
+
s += String.fromCharCode(b);
|
|
195
|
+
else
|
|
196
|
+
s += "\\" + (b < 16 ? "0" : "") + b.toString(16).toUpperCase();
|
|
197
|
+
}
|
|
198
|
+
return s;
|
|
199
|
+
}
|
|
200
|
+
class Lines {
|
|
201
|
+
lines = [];
|
|
202
|
+
add(line) {
|
|
203
|
+
this.lines.push(line);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/** One module's translation. */
|
|
207
|
+
class ModuleTranslator {
|
|
208
|
+
m;
|
|
209
|
+
p;
|
|
210
|
+
opts;
|
|
211
|
+
text = [];
|
|
212
|
+
/** Functions that need a reference record. */
|
|
213
|
+
refs;
|
|
214
|
+
/** Functions whose entry checks the stack (stackCheckedFunctions). */
|
|
215
|
+
stackChecked;
|
|
216
|
+
typeHashes;
|
|
217
|
+
memoryCount;
|
|
218
|
+
constructor(m, prefix, opts) {
|
|
219
|
+
this.m = m;
|
|
220
|
+
this.p = prefix;
|
|
221
|
+
this.opts = opts;
|
|
222
|
+
this.refs = new Set(m.declaredRefs);
|
|
223
|
+
this.typeHashes = m.types.map((t) => signatureHash(sigString(t)));
|
|
224
|
+
this.memoryCount = m.memories.length;
|
|
225
|
+
if (m.memories.length > 1)
|
|
226
|
+
throw new WasmTranslateError("multiple memories are not supported");
|
|
227
|
+
this.stackChecked = stackCheckedFunctions(m);
|
|
228
|
+
}
|
|
229
|
+
fn(index) {
|
|
230
|
+
return `@${this.p}_f${index}`;
|
|
231
|
+
}
|
|
232
|
+
funcType(index) {
|
|
233
|
+
return this.m.types[this.m.funcTypes[index]];
|
|
234
|
+
}
|
|
235
|
+
globalSlot(index) {
|
|
236
|
+
return OFF_TABLES + 8 * (this.m.tables.length + index);
|
|
237
|
+
}
|
|
238
|
+
tableSlot(index) {
|
|
239
|
+
return OFF_TABLES + 8 * index;
|
|
240
|
+
}
|
|
241
|
+
signature(ft, name) {
|
|
242
|
+
const params = ["ptr %inst"];
|
|
243
|
+
for (let i = 0; i < ft.params.length; i++)
|
|
244
|
+
params.push(`${llType(ft.params[i])} %p${i}`);
|
|
245
|
+
return `${retType(ft.results)} ${name}(${params.join(", ")})`;
|
|
246
|
+
}
|
|
247
|
+
translate() {
|
|
248
|
+
const m = this.m;
|
|
249
|
+
for (let i = 0; i < m.importedFuncs; i++)
|
|
250
|
+
this.importStub(i);
|
|
251
|
+
for (let i = 0; i < m.codes.length; i++) {
|
|
252
|
+
const index = m.importedFuncs + i;
|
|
253
|
+
const f = new FunctionTranslator(this, index);
|
|
254
|
+
this.text.push(...f.translate());
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
importStub(index) {
|
|
258
|
+
const ft = this.funcType(index);
|
|
259
|
+
const out = [];
|
|
260
|
+
out.push(`define internal ${this.signature(ft, this.fn(index))} nounwind {`);
|
|
261
|
+
out.push(`entry:`);
|
|
262
|
+
const np = Math.max(1, ft.params.length);
|
|
263
|
+
const nr = Math.max(1, ft.results.length);
|
|
264
|
+
out.push(` %args = alloca [${np} x i64], align 8`);
|
|
265
|
+
out.push(` %res = alloca [${nr} x i64], align 8`);
|
|
266
|
+
for (let i = 0; i < ft.params.length; i++) {
|
|
267
|
+
const slot = toSlot(out, ft.params[i], `%p${i}`, `a${i}`);
|
|
268
|
+
out.push(` %ap${i} = getelementptr i64, ptr %args, i64 ${i}`);
|
|
269
|
+
out.push(` store i64 ${slot}, ptr %ap${i}`);
|
|
270
|
+
}
|
|
271
|
+
out.push(` %host = load ptr, ptr %inst`);
|
|
272
|
+
out.push(` call void @scr_wasm_import_call(ptr %host, i32 ${index}, ptr %args, ptr %res)`);
|
|
273
|
+
emitSlotReturn(out, ft.results, "%res");
|
|
274
|
+
out.push(`}`);
|
|
275
|
+
this.text.push(out.join("\n"));
|
|
276
|
+
}
|
|
277
|
+
/** The thunk the runtime calls for exported function `index`. */
|
|
278
|
+
exportThunk(index) {
|
|
279
|
+
const name = `@${this.p}_x${index}`;
|
|
280
|
+
const ft = this.funcType(index);
|
|
281
|
+
const out = [];
|
|
282
|
+
out.push(`define internal void ${name}(ptr %inst, ptr %a, ptr %r) nounwind {`);
|
|
283
|
+
out.push(`entry:`);
|
|
284
|
+
const args = ["ptr %inst"];
|
|
285
|
+
for (let i = 0; i < ft.params.length; i++) {
|
|
286
|
+
out.push(` %ap${i} = getelementptr i64, ptr %a, i64 ${i}`);
|
|
287
|
+
out.push(` %as${i} = load i64, ptr %ap${i}`);
|
|
288
|
+
args.push(`${llType(ft.params[i])} ${fromSlot(out, ft.params[i], `%as${i}`, `a${i}`)}`);
|
|
289
|
+
}
|
|
290
|
+
const ret = retType(ft.results);
|
|
291
|
+
if (ft.results.length === 0) {
|
|
292
|
+
out.push(` call void ${this.fn(index)}(${args.join(", ")})`);
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
out.push(` %res = call ${ret} ${this.fn(index)}(${args.join(", ")})`);
|
|
296
|
+
for (let i = 0; i < ft.results.length; i++) {
|
|
297
|
+
let v = "%res";
|
|
298
|
+
if (ft.results.length > 1) {
|
|
299
|
+
out.push(` %rv${i} = extractvalue ${ret} %res, ${i}`);
|
|
300
|
+
v = `%rv${i}`;
|
|
301
|
+
}
|
|
302
|
+
const slot = toSlot(out, ft.results[i], v, `r${i}`);
|
|
303
|
+
out.push(` %rp${i} = getelementptr i64, ptr %r, i64 ${i}`);
|
|
304
|
+
out.push(` store i64 ${slot}, ptr %rp${i}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
out.push(` ret void`);
|
|
308
|
+
out.push(`}`);
|
|
309
|
+
this.text.push(out.join("\n"));
|
|
310
|
+
return name;
|
|
311
|
+
}
|
|
312
|
+
/** A call thunk for signature `type`: `(code, inst, args, results)`
|
|
313
|
+
* calls `code` (a function of that signature) with the arguments in
|
|
314
|
+
* 64-bit slots. The runtime calls a function reference that reaches
|
|
315
|
+
* JavaScript through it when the module does not export the function. */
|
|
316
|
+
callThunk(type) {
|
|
317
|
+
const name = `@${this.p}_k${type}`;
|
|
318
|
+
const ft = this.m.types[type];
|
|
319
|
+
const out = [];
|
|
320
|
+
out.push(`define internal void ${name}(ptr %code, ptr %inst, ptr %a, ptr %r) nounwind {`);
|
|
321
|
+
out.push(`entry:`);
|
|
322
|
+
const args = ["ptr %inst"];
|
|
323
|
+
for (let i = 0; i < ft.params.length; i++) {
|
|
324
|
+
out.push(` %ap${i} = getelementptr i64, ptr %a, i64 ${i}`);
|
|
325
|
+
out.push(` %as${i} = load i64, ptr %ap${i}`);
|
|
326
|
+
args.push(`${llType(ft.params[i])} ${fromSlot(out, ft.params[i], `%as${i}`, `a${i}`)}`);
|
|
327
|
+
}
|
|
328
|
+
const ret = retType(ft.results);
|
|
329
|
+
if (ft.results.length === 0) {
|
|
330
|
+
out.push(` call void %code(${args.join(", ")})`);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
out.push(` %res = call ${ret} %code(${args.join(", ")})`);
|
|
334
|
+
for (let i = 0; i < ft.results.length; i++) {
|
|
335
|
+
let v = "%res";
|
|
336
|
+
if (ft.results.length > 1) {
|
|
337
|
+
out.push(` %rv${i} = extractvalue ${ret} %res, ${i}`);
|
|
338
|
+
v = `%rv${i}`;
|
|
339
|
+
}
|
|
340
|
+
const slot = toSlot(out, ft.results[i], v, `r${i}`);
|
|
341
|
+
out.push(` %rp${i} = getelementptr i64, ptr %r, i64 ${i}`);
|
|
342
|
+
out.push(` store i64 ${slot}, ptr %rp${i}`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
out.push(` ret void`);
|
|
346
|
+
out.push(`}`);
|
|
347
|
+
this.text.push(out.join("\n"));
|
|
348
|
+
return name;
|
|
349
|
+
}
|
|
350
|
+
/** Emits the init function: globals, table initializers and segments,
|
|
351
|
+
* in the specification's order. The runtime calls the start function
|
|
352
|
+
* (which takes and returns nothing) separately. */
|
|
353
|
+
initFunction() {
|
|
354
|
+
const m = this.m;
|
|
355
|
+
const name = `@${this.p}_init`;
|
|
356
|
+
const f = new FunctionTranslator(this, -1);
|
|
357
|
+
const body = f.lines;
|
|
358
|
+
// Globals.
|
|
359
|
+
for (let g = 0; g < m.globals.length; g++) {
|
|
360
|
+
const global = m.globals[g];
|
|
361
|
+
if (global.imported || global.init === null)
|
|
362
|
+
continue;
|
|
363
|
+
const v = f.constExpr(global.init);
|
|
364
|
+
const cell = f.loadPtrSlot(this.globalSlot(g));
|
|
365
|
+
if (global.type === VAL_EXTERNREF) {
|
|
366
|
+
// A defined externref global starts as null or another global's
|
|
367
|
+
// value; the runtime's setter retains it.
|
|
368
|
+
body.add(` call void @scr_wasm_global_set_ref(ptr ${cell}, ptr ${v})`);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
body.add(` store ${llType(global.type)} ${v}, ptr ${cell}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// Defined tables with an initializer.
|
|
375
|
+
for (let t = 0; t < m.tables.length; t++) {
|
|
376
|
+
const table = m.tables[t];
|
|
377
|
+
if (table.imported || table.init === null)
|
|
378
|
+
continue;
|
|
379
|
+
const v = f.constExpr(table.init);
|
|
380
|
+
body.add(` call void @scr_wasm_table_fill(ptr %inst, i32 ${t}, i32 0, ptr ${v}, i32 ${table.min})`);
|
|
381
|
+
}
|
|
382
|
+
// Element segments: active ones initialize their table and drop;
|
|
383
|
+
// declarative ones only drop.
|
|
384
|
+
for (let s = 0; s < m.elems.length; s++) {
|
|
385
|
+
const seg = m.elems[s];
|
|
386
|
+
if (seg.mode === "active") {
|
|
387
|
+
const offset = f.constExpr(seg.offset);
|
|
388
|
+
body.add(` call void @scr_wasm_table_init(ptr %inst, i32 ${seg.table}, i32 ${s}, i32 ${offset}, i32 0, i32 ${seg.funcs.length})`);
|
|
389
|
+
}
|
|
390
|
+
if (seg.mode !== "passive")
|
|
391
|
+
body.add(` call void @scr_wasm_elem_drop(ptr %inst, i32 ${s})`);
|
|
392
|
+
}
|
|
393
|
+
for (let s = 0; s < m.datas.length; s++) {
|
|
394
|
+
const seg = m.datas[s];
|
|
395
|
+
if (seg.mode !== "active")
|
|
396
|
+
continue;
|
|
397
|
+
const offset = f.constExpr(seg.offset);
|
|
398
|
+
const length = seg.payload.end - seg.payload.start;
|
|
399
|
+
body.add(` call void @scr_wasm_memory_init(ptr %inst, i32 ${s}, i32 ${offset}, i32 0, i32 ${length})`);
|
|
400
|
+
body.add(` call void @scr_wasm_data_drop(ptr %inst, i32 ${s})`);
|
|
401
|
+
}
|
|
402
|
+
body.add(` ret void`);
|
|
403
|
+
const out = [`define internal void ${name}(ptr %inst) nounwind {`, `entry:`];
|
|
404
|
+
out.push(...f.entry.lines);
|
|
405
|
+
out.push(...body.lines);
|
|
406
|
+
out.push(`}`);
|
|
407
|
+
this.text.push(out.join("\n"));
|
|
408
|
+
return name;
|
|
409
|
+
}
|
|
410
|
+
/** Constant data and the descriptor. */
|
|
411
|
+
descriptor(sha256) {
|
|
412
|
+
const m = this.m;
|
|
413
|
+
const p = this.p;
|
|
414
|
+
const lines = [];
|
|
415
|
+
// First, so that every function its constant expressions reference has
|
|
416
|
+
// a record in the tables below.
|
|
417
|
+
const init = this.initFunction();
|
|
418
|
+
let strings = 0;
|
|
419
|
+
const cstr = (text) => {
|
|
420
|
+
const sym = `@${p}_s${strings++}`;
|
|
421
|
+
const bytes = new Uint8Array(text);
|
|
422
|
+
lines.push(`${sym} = private unnamed_addr constant [${bytes.length + 1} x i8] c"${cBytes(bytes, 0, bytes.length)}\\00"`);
|
|
423
|
+
return sym;
|
|
424
|
+
};
|
|
425
|
+
const textStr = (text) => {
|
|
426
|
+
const bytes = utf8Bytes(text);
|
|
427
|
+
return { sym: cstr(bytes), len: bytes.length };
|
|
428
|
+
};
|
|
429
|
+
// Imports.
|
|
430
|
+
const importRows = [];
|
|
431
|
+
let funcImport = 0;
|
|
432
|
+
let tableImport = 0;
|
|
433
|
+
let memoryImport = 0;
|
|
434
|
+
let globalImport = 0;
|
|
435
|
+
for (const imp of m.imports) {
|
|
436
|
+
const mod = textStr(imp.module);
|
|
437
|
+
const name = textStr(imp.name);
|
|
438
|
+
let index = 0;
|
|
439
|
+
let type = "";
|
|
440
|
+
if (imp.kind === KIND_FUNC) {
|
|
441
|
+
index = funcImport++;
|
|
442
|
+
type = sigString(m.types[imp.type]);
|
|
443
|
+
}
|
|
444
|
+
else if (imp.kind === KIND_TABLE) {
|
|
445
|
+
index = tableImport++;
|
|
446
|
+
type = sigChar(imp.type);
|
|
447
|
+
}
|
|
448
|
+
else if (imp.kind === KIND_MEMORY) {
|
|
449
|
+
index = memoryImport++;
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
index = globalImport++;
|
|
453
|
+
type = sigChar(imp.type);
|
|
454
|
+
}
|
|
455
|
+
const typeSym = cstr(utf8Bytes(type));
|
|
456
|
+
importRows.push(`{ ptr, i64, ptr, i64, i64, i64, ptr } { ptr ${mod.sym}, i64 ${mod.len}, ptr ${name.sym}, i64 ${name.len}, i64 ${imp.kind}, i64 ${index}, ptr ${typeSym} }`);
|
|
457
|
+
}
|
|
458
|
+
const importType = "{ ptr, i64, ptr, i64, i64, i64, ptr }";
|
|
459
|
+
const importsSym = `@${p}_imports`;
|
|
460
|
+
lines.push(`${importsSym} = private constant [${importRows.length} x ${importType}] [${importRows.join(", ")}]`);
|
|
461
|
+
// Exports.
|
|
462
|
+
const thunks = new Map();
|
|
463
|
+
const exportRows = [];
|
|
464
|
+
for (const ex of m.exports) {
|
|
465
|
+
const name = textStr(ex.name);
|
|
466
|
+
let type = "";
|
|
467
|
+
let call = "null";
|
|
468
|
+
if (ex.kind === KIND_FUNC) {
|
|
469
|
+
type = sigString(this.funcType(ex.index));
|
|
470
|
+
let thunk = thunks.get(ex.index);
|
|
471
|
+
if (thunk === undefined) {
|
|
472
|
+
thunk = this.exportThunk(ex.index);
|
|
473
|
+
thunks.set(ex.index, thunk);
|
|
474
|
+
}
|
|
475
|
+
call = thunk;
|
|
476
|
+
}
|
|
477
|
+
else if (ex.kind === KIND_TABLE) {
|
|
478
|
+
type = sigChar(m.tables[ex.index].elemType);
|
|
479
|
+
}
|
|
480
|
+
else if (ex.kind === KIND_GLOBAL) {
|
|
481
|
+
type = sigChar(m.globals[ex.index].type);
|
|
482
|
+
}
|
|
483
|
+
const typeSym = cstr(utf8Bytes(type));
|
|
484
|
+
exportRows.push(`{ ptr, i64, i64, i64, ptr, ptr } { ptr ${name.sym}, i64 ${name.len}, i64 ${ex.kind}, i64 ${ex.index}, ptr ${typeSym}, ptr ${call} }`);
|
|
485
|
+
}
|
|
486
|
+
const exportType = "{ ptr, i64, i64, i64, ptr, ptr }";
|
|
487
|
+
const exportsSym = `@${p}_exports`;
|
|
488
|
+
lines.push(`${exportsSym} = private constant [${exportRows.length} x ${exportType}] [${exportRows.join(", ")}]`);
|
|
489
|
+
// Function references: code, signature identity and signature text for
|
|
490
|
+
// every function a reference can name.
|
|
491
|
+
const nf = m.funcTypes.length;
|
|
492
|
+
const codes = [];
|
|
493
|
+
const callThunks = [];
|
|
494
|
+
const callThunkSyms = new Map();
|
|
495
|
+
const types = [];
|
|
496
|
+
const sigs = [];
|
|
497
|
+
const sigSyms = new Map();
|
|
498
|
+
for (let f = 0; f < nf; f++) {
|
|
499
|
+
const referenced = this.refs.has(f);
|
|
500
|
+
codes.push(referenced ? `ptr ${this.fn(f)}` : "ptr null");
|
|
501
|
+
// Referenced functions the module does not export reach JavaScript
|
|
502
|
+
// through their signature's call thunk.
|
|
503
|
+
if (referenced && !thunks.has(f)) {
|
|
504
|
+
const type = m.funcTypes[f];
|
|
505
|
+
let thunk = callThunkSyms.get(type);
|
|
506
|
+
if (thunk === undefined) {
|
|
507
|
+
thunk = this.callThunk(type);
|
|
508
|
+
callThunkSyms.set(type, thunk);
|
|
509
|
+
}
|
|
510
|
+
callThunks.push(`ptr ${thunk}`);
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
callThunks.push("ptr null");
|
|
514
|
+
}
|
|
515
|
+
types.push(`i64 ${this.typeHashes[m.funcTypes[f]]}`);
|
|
516
|
+
const sig = sigString(this.funcType(f));
|
|
517
|
+
let sym = sigSyms.get(sig);
|
|
518
|
+
if (sym === undefined) {
|
|
519
|
+
sym = cstr(utf8Bytes(sig));
|
|
520
|
+
sigSyms.set(sig, sym);
|
|
521
|
+
}
|
|
522
|
+
sigs.push(`ptr ${sym}`);
|
|
523
|
+
}
|
|
524
|
+
const codesSym = `@${p}_codes`;
|
|
525
|
+
const typesSym = `@${p}_types`;
|
|
526
|
+
const sigsSym = `@${p}_sigs`;
|
|
527
|
+
const callThunksSym = `@${p}_calls`;
|
|
528
|
+
lines.push(`${codesSym} = private constant [${nf} x ptr] [${codes.join(", ")}]`);
|
|
529
|
+
lines.push(`${callThunksSym} = private constant [${nf} x ptr] [${callThunks.join(", ")}]`);
|
|
530
|
+
lines.push(`${typesSym} = private constant [${nf} x i64] [${types.join(", ")}]`);
|
|
531
|
+
lines.push(`${sigsSym} = private constant [${nf} x ptr] [${sigs.join(", ")}]`);
|
|
532
|
+
// Tables.
|
|
533
|
+
const tableRows = m.tables.map((t) => `{ i64, i64, i64, i64 } { i64 ${sigChar(t.elemType).charCodeAt(0)}, i64 ${t.min}, i64 ${t.max === null ? -1 : t.max}, i64 ${t.imported ? 1 : 0} }`);
|
|
534
|
+
const tablesSym = `@${p}_tables`;
|
|
535
|
+
lines.push(`${tablesSym} = private constant [${tableRows.length} x { i64, i64, i64, i64 }] [${tableRows.join(", ")}]`);
|
|
536
|
+
// Globals.
|
|
537
|
+
const globalRows = m.globals.map((g) => `{ i64, i64, i64 } { i64 ${sigChar(g.type).charCodeAt(0)}, i64 ${g.mutable ? 1 : 0}, i64 ${g.imported ? 1 : 0} }`);
|
|
538
|
+
const globalsSym = `@${p}_globals`;
|
|
539
|
+
lines.push(`${globalsSym} = private constant [${globalRows.length} x { i64, i64, i64 }] [${globalRows.join(", ")}]`);
|
|
540
|
+
// Data segments.
|
|
541
|
+
const dataRows = [];
|
|
542
|
+
for (let s = 0; s < m.datas.length; s++) {
|
|
543
|
+
const seg = m.datas[s];
|
|
544
|
+
const len = seg.payload.end - seg.payload.start;
|
|
545
|
+
if (len === 0) {
|
|
546
|
+
dataRows.push(`{ ptr, i64 } { ptr null, i64 0 }`);
|
|
547
|
+
continue;
|
|
548
|
+
}
|
|
549
|
+
const sym = `@${p}_d${s}`;
|
|
550
|
+
lines.push(`${sym} = private unnamed_addr constant [${len} x i8] c"${cBytes(m.bytes, seg.payload.start, seg.payload.end)}", align 1`);
|
|
551
|
+
dataRows.push(`{ ptr, i64 } { ptr ${sym}, i64 ${len} }`);
|
|
552
|
+
}
|
|
553
|
+
const datasSym = `@${p}_datas`;
|
|
554
|
+
lines.push(`${datasSym} = private constant [${dataRows.length} x { ptr, i64 }] [${dataRows.join(", ")}]`);
|
|
555
|
+
// Element segments: a function index, -1 for null, or -(2 + g) for the
|
|
556
|
+
// value of global g.
|
|
557
|
+
const elemRows = [];
|
|
558
|
+
for (let s = 0; s < m.elems.length; s++) {
|
|
559
|
+
const seg = m.elems[s];
|
|
560
|
+
const items = [];
|
|
561
|
+
for (let k = 0; k < seg.funcs.length; k++) {
|
|
562
|
+
const f = seg.funcs[k];
|
|
563
|
+
if (f >= 0) {
|
|
564
|
+
items.push(`i64 ${f}`);
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
items.push(`i64 ${this.elemExprCode(seg.exprs[k])}`);
|
|
568
|
+
}
|
|
569
|
+
let itemsRef = "ptr null";
|
|
570
|
+
if (items.length > 0) {
|
|
571
|
+
const sym = `@${p}_e${s}`;
|
|
572
|
+
lines.push(`${sym} = private constant [${items.length} x i64] [${items.join(", ")}]`);
|
|
573
|
+
itemsRef = `ptr ${sym}`;
|
|
574
|
+
}
|
|
575
|
+
elemRows.push(`{ i64, i64, ptr } { i64 ${sigChar(seg.elemType).charCodeAt(0)}, i64 ${items.length}, ${itemsRef} }`);
|
|
576
|
+
}
|
|
577
|
+
const elemsSym = `@${p}_elems`;
|
|
578
|
+
lines.push(`${elemsSym} = private constant [${elemRows.length} x { i64, i64, ptr }] [${elemRows.join(", ")}]`);
|
|
579
|
+
// Custom sections, when the program reads them.
|
|
580
|
+
const customRows = [];
|
|
581
|
+
if (this.opts.customSections === true) {
|
|
582
|
+
for (let s = 0; s < m.customs.length; s++) {
|
|
583
|
+
const custom = m.customs[s];
|
|
584
|
+
const name = textStr(custom.name);
|
|
585
|
+
const len = custom.payload.end - custom.payload.start;
|
|
586
|
+
let data = "ptr null";
|
|
587
|
+
if (len > 0) {
|
|
588
|
+
const sym = `@${p}_c${s}`;
|
|
589
|
+
lines.push(`${sym} = private unnamed_addr constant [${len} x i8] c"${cBytes(m.bytes, custom.payload.start, custom.payload.end)}", align 1`);
|
|
590
|
+
data = `ptr ${sym}`;
|
|
591
|
+
}
|
|
592
|
+
customRows.push(`{ ptr, i64, ptr, i64 } { ptr ${name.sym}, i64 ${name.len}, ${data}, i64 ${len} }`);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
const customsSym = `@${p}_customs`;
|
|
596
|
+
lines.push(`${customsSym} = private constant [${customRows.length} x { ptr, i64, ptr, i64 }] [${customRows.join(", ")}]`);
|
|
597
|
+
const memory = m.memories[0];
|
|
598
|
+
const sha = [];
|
|
599
|
+
for (let i = 0; i < 32; i++)
|
|
600
|
+
sha.push(`i8 ${sha256[i]}`);
|
|
601
|
+
const desc = `@${p}_desc`;
|
|
602
|
+
const fields = [
|
|
603
|
+
`[32 x i8] [${sha.join(", ")}]`,
|
|
604
|
+
`i64 ${m.bytes.length}`,
|
|
605
|
+
`i64 ${WASM_ABI_VERSION}`,
|
|
606
|
+
`i64 ${this.opts.boundsChecks ? 1 : 0}`,
|
|
607
|
+
`i64 ${m.imports.length}`,
|
|
608
|
+
`ptr ${importsSym}`,
|
|
609
|
+
`i64 ${m.exports.length}`,
|
|
610
|
+
`ptr ${exportsSym}`,
|
|
611
|
+
`i64 ${nf}`,
|
|
612
|
+
`i64 ${m.importedFuncs}`,
|
|
613
|
+
`ptr ${codesSym}`,
|
|
614
|
+
`ptr ${typesSym}`,
|
|
615
|
+
`ptr ${sigsSym}`,
|
|
616
|
+
`i64 ${m.tables.length}`,
|
|
617
|
+
`ptr ${tablesSym}`,
|
|
618
|
+
`i64 ${this.memoryCount}`,
|
|
619
|
+
`i64 ${memory === undefined ? 0 : memory.min}`,
|
|
620
|
+
`i64 ${memory === undefined || memory.max === null ? -1 : memory.max}`,
|
|
621
|
+
`i64 ${m.globals.length}`,
|
|
622
|
+
`ptr ${globalsSym}`,
|
|
623
|
+
`i64 ${m.datas.length}`,
|
|
624
|
+
`ptr ${datasSym}`,
|
|
625
|
+
`i64 ${m.elems.length}`,
|
|
626
|
+
`ptr ${elemsSym}`,
|
|
627
|
+
`ptr ${init}`,
|
|
628
|
+
`ptr ${m.start === null ? "null" : this.fn(m.start)}`,
|
|
629
|
+
`i64 ${customRows.length}`,
|
|
630
|
+
`ptr ${customsSym}`,
|
|
631
|
+
`ptr ${callThunksSym}`,
|
|
632
|
+
];
|
|
633
|
+
const descType = "{ [32 x i8], i64, i64, i64, i64, ptr, i64, ptr, i64, i64, ptr, ptr, ptr, i64, ptr, i64, i64, i64, i64, ptr, i64, ptr, i64, ptr, ptr, ptr, i64, ptr, ptr }";
|
|
634
|
+
lines.push(`${desc} = internal constant ${descType} { ${fields.join(", ")} }`);
|
|
635
|
+
this.text.push(lines.join("\n"));
|
|
636
|
+
return desc;
|
|
637
|
+
}
|
|
638
|
+
/** The element-segment code of a non-ref.func constant expression. */
|
|
639
|
+
elemExprCode(expr) {
|
|
640
|
+
const c = new WasmCursor(this.m.bytes, expr.start);
|
|
641
|
+
const op = c.u8();
|
|
642
|
+
if (op === 0xd0) {
|
|
643
|
+
c.valType();
|
|
644
|
+
if (c.u8() === 0x0b)
|
|
645
|
+
return -1;
|
|
646
|
+
}
|
|
647
|
+
else if (op === 0x23) {
|
|
648
|
+
const g = c.u32();
|
|
649
|
+
if (c.u8() === 0x0b)
|
|
650
|
+
return -(2 + g);
|
|
651
|
+
}
|
|
652
|
+
throw new WasmTranslateError("element segment initializers other than ref.null, ref.func and global.get are not supported");
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
/** Store a value as a 64-bit slot; answers the slot operand. */
|
|
656
|
+
function toSlot(out, t, v, tag) {
|
|
657
|
+
switch (t) {
|
|
658
|
+
case VAL_I32:
|
|
659
|
+
out.push(` %${tag}z = zext i32 ${v} to i64`);
|
|
660
|
+
return `%${tag}z`;
|
|
661
|
+
case VAL_I64:
|
|
662
|
+
return v;
|
|
663
|
+
case VAL_F32:
|
|
664
|
+
out.push(` %${tag}b = bitcast float ${v} to i32`);
|
|
665
|
+
out.push(` %${tag}z = zext i32 %${tag}b to i64`);
|
|
666
|
+
return `%${tag}z`;
|
|
667
|
+
case VAL_F64:
|
|
668
|
+
out.push(` %${tag}z = bitcast double ${v} to i64`);
|
|
669
|
+
return `%${tag}z`;
|
|
670
|
+
default:
|
|
671
|
+
out.push(` %${tag}z = ptrtoint ptr ${v} to i64`);
|
|
672
|
+
return `%${tag}z`;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
function fromSlot(out, t, slot, tag) {
|
|
676
|
+
switch (t) {
|
|
677
|
+
case VAL_I32:
|
|
678
|
+
out.push(` %${tag}v = trunc i64 ${slot} to i32`);
|
|
679
|
+
return `%${tag}v`;
|
|
680
|
+
case VAL_I64:
|
|
681
|
+
return slot;
|
|
682
|
+
case VAL_F32:
|
|
683
|
+
out.push(` %${tag}t = trunc i64 ${slot} to i32`);
|
|
684
|
+
out.push(` %${tag}v = bitcast i32 %${tag}t to float`);
|
|
685
|
+
return `%${tag}v`;
|
|
686
|
+
case VAL_F64:
|
|
687
|
+
out.push(` %${tag}v = bitcast i64 ${slot} to double`);
|
|
688
|
+
return `%${tag}v`;
|
|
689
|
+
default:
|
|
690
|
+
out.push(` %${tag}v = inttoptr i64 ${slot} to ptr`);
|
|
691
|
+
return `%${tag}v`;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
function emitSlotReturn(out, results, buffer) {
|
|
695
|
+
if (results.length === 0) {
|
|
696
|
+
out.push(` ret void`);
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
const vals = [];
|
|
700
|
+
for (let i = 0; i < results.length; i++) {
|
|
701
|
+
out.push(` %rp${i} = getelementptr i64, ptr ${buffer}, i64 ${i}`);
|
|
702
|
+
out.push(` %rs${i} = load i64, ptr %rp${i}`);
|
|
703
|
+
vals.push(fromSlot(out, results[i], `%rs${i}`, `r${i}`));
|
|
704
|
+
}
|
|
705
|
+
if (results.length === 1) {
|
|
706
|
+
out.push(` ret ${llType(results[0])} ${vals[0]}`);
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
const ret = retType(results);
|
|
710
|
+
let agg = "undef";
|
|
711
|
+
for (let i = 0; i < results.length; i++) {
|
|
712
|
+
out.push(` %agg${i} = insertvalue ${ret} ${agg}, ${llType(results[i])} ${vals[i]}, ${i}`);
|
|
713
|
+
agg = `%agg${i}`;
|
|
714
|
+
}
|
|
715
|
+
out.push(` ret ${ret} ${agg}`);
|
|
716
|
+
}
|
|
717
|
+
const LOAD_INFO = {
|
|
718
|
+
// opcode: [result type, memory type, bytes, extension]
|
|
719
|
+
0x28: [VAL_I32, "i32", 4, ""],
|
|
720
|
+
0x29: [VAL_I64, "i64", 8, ""],
|
|
721
|
+
0x2a: [VAL_F32, "float", 4, ""],
|
|
722
|
+
0x2b: [VAL_F64, "double", 8, ""],
|
|
723
|
+
0x2c: [VAL_I32, "i8", 1, "sext"],
|
|
724
|
+
0x2d: [VAL_I32, "i8", 1, "zext"],
|
|
725
|
+
0x2e: [VAL_I32, "i16", 2, "sext"],
|
|
726
|
+
0x2f: [VAL_I32, "i16", 2, "zext"],
|
|
727
|
+
0x30: [VAL_I64, "i8", 1, "sext"],
|
|
728
|
+
0x31: [VAL_I64, "i8", 1, "zext"],
|
|
729
|
+
0x32: [VAL_I64, "i16", 2, "sext"],
|
|
730
|
+
0x33: [VAL_I64, "i16", 2, "zext"],
|
|
731
|
+
0x34: [VAL_I64, "i32", 4, "sext"],
|
|
732
|
+
0x35: [VAL_I64, "i32", 4, "zext"],
|
|
733
|
+
};
|
|
734
|
+
const STORE_INFO = {
|
|
735
|
+
0x36: [VAL_I32, "i32", 4],
|
|
736
|
+
0x37: [VAL_I64, "i64", 8],
|
|
737
|
+
0x38: [VAL_F32, "float", 4],
|
|
738
|
+
0x39: [VAL_F64, "double", 8],
|
|
739
|
+
0x3a: [VAL_I32, "i8", 1],
|
|
740
|
+
0x3b: [VAL_I32, "i16", 2],
|
|
741
|
+
0x3c: [VAL_I64, "i8", 1],
|
|
742
|
+
0x3d: [VAL_I64, "i16", 2],
|
|
743
|
+
0x3e: [VAL_I64, "i32", 4],
|
|
744
|
+
};
|
|
745
|
+
/** Translates one function body (index >= 0) or hosts the init function's
|
|
746
|
+
* constant expressions (index -1). */
|
|
747
|
+
class FunctionTranslator {
|
|
748
|
+
mt;
|
|
749
|
+
m;
|
|
750
|
+
index;
|
|
751
|
+
ft;
|
|
752
|
+
entry = new Lines();
|
|
753
|
+
lines = new Lines();
|
|
754
|
+
stack = [];
|
|
755
|
+
frames = [];
|
|
756
|
+
localTypes = [];
|
|
757
|
+
next = 0;
|
|
758
|
+
labels = 0;
|
|
759
|
+
live = true;
|
|
760
|
+
trapLabels = new Map();
|
|
761
|
+
/** Guard mode: the memory base, loaded once in the entry block. */
|
|
762
|
+
baseValue = null;
|
|
763
|
+
checked;
|
|
764
|
+
constructor(mt, index) {
|
|
765
|
+
this.mt = mt;
|
|
766
|
+
this.m = mt.m;
|
|
767
|
+
this.index = index;
|
|
768
|
+
this.ft = index >= 0 ? mt.funcType(index) : { params: [], results: [] };
|
|
769
|
+
this.checked = mt.opts.boundsChecks;
|
|
770
|
+
}
|
|
771
|
+
tmp() {
|
|
772
|
+
return `%v${this.next++}`;
|
|
773
|
+
}
|
|
774
|
+
label(hint) {
|
|
775
|
+
return `${hint}${this.labels++}`;
|
|
776
|
+
}
|
|
777
|
+
add(line) {
|
|
778
|
+
this.lines.add(line);
|
|
779
|
+
}
|
|
780
|
+
emit(expr) {
|
|
781
|
+
const v = this.tmp();
|
|
782
|
+
this.add(` ${v} = ${expr}`);
|
|
783
|
+
return v;
|
|
784
|
+
}
|
|
785
|
+
push(v, t) {
|
|
786
|
+
this.stack.push({ v, t });
|
|
787
|
+
}
|
|
788
|
+
pop() {
|
|
789
|
+
const v = this.stack.pop();
|
|
790
|
+
if (v === undefined)
|
|
791
|
+
throw new Error("wasm translator: operand stack underflow");
|
|
792
|
+
return v;
|
|
793
|
+
}
|
|
794
|
+
/** Pops a value that must have type `t`: the type a local, global,
|
|
795
|
+
* table or memory store writes. Validation guarantees it; a mismatch
|
|
796
|
+
* means the translator and the validator disagree about the code, so
|
|
797
|
+
* the module is not translated. */
|
|
798
|
+
popType(t, what) {
|
|
799
|
+
const v = this.pop();
|
|
800
|
+
if (v.t !== t)
|
|
801
|
+
throw new WasmTranslateError(`${what} operand type does not match`);
|
|
802
|
+
return v;
|
|
803
|
+
}
|
|
804
|
+
/** The declared type of local `i` (parameters first). */
|
|
805
|
+
localType(i) {
|
|
806
|
+
const t = this.localTypes[i];
|
|
807
|
+
if (t === undefined)
|
|
808
|
+
throw new WasmTranslateError(`unknown local ${i}`);
|
|
809
|
+
return t;
|
|
810
|
+
}
|
|
811
|
+
/** The offset of a memarg over memory 0 (the only memory a translatable
|
|
812
|
+
* module has). */
|
|
813
|
+
memargOffset(c) {
|
|
814
|
+
const flags = readMemargFlags(() => c.u32());
|
|
815
|
+
if (flags.align < 0 || flags.memory !== 0)
|
|
816
|
+
throw new WasmTranslateError(`memarg of memory ${flags.memory} is not supported`);
|
|
817
|
+
return c.u32();
|
|
818
|
+
}
|
|
819
|
+
/** A memory index immediate (memory.size, memory.grow and the bulk
|
|
820
|
+
* memory instructions), which must be 0. */
|
|
821
|
+
memoryIndex(c) {
|
|
822
|
+
const index = c.u32();
|
|
823
|
+
if (index !== 0)
|
|
824
|
+
throw new WasmTranslateError(`memory ${index} is not supported`);
|
|
825
|
+
}
|
|
826
|
+
popN(n) {
|
|
827
|
+
const out = this.stack.splice(this.stack.length - n, n);
|
|
828
|
+
if (out.length !== n)
|
|
829
|
+
throw new Error("wasm translator: operand stack underflow");
|
|
830
|
+
return out;
|
|
831
|
+
}
|
|
832
|
+
/** Starts a new basic block. */
|
|
833
|
+
startBlock(label) {
|
|
834
|
+
this.add(`${label}:`);
|
|
835
|
+
}
|
|
836
|
+
alloca(type) {
|
|
837
|
+
const v = `%s${this.next++}`;
|
|
838
|
+
this.entry.add(` ${v} = alloca ${type}`);
|
|
839
|
+
return v;
|
|
840
|
+
}
|
|
841
|
+
slotPtr(offset) {
|
|
842
|
+
if (offset === 0)
|
|
843
|
+
return "%inst";
|
|
844
|
+
return this.emit(`getelementptr inbounds i8, ptr %inst, i64 ${offset}`);
|
|
845
|
+
}
|
|
846
|
+
loadPtrSlot(offset) {
|
|
847
|
+
return this.emit(`load ptr, ptr ${this.slotPtr(offset)}, align 8`);
|
|
848
|
+
}
|
|
849
|
+
trap(code) {
|
|
850
|
+
let label = this.trapLabels.get(code);
|
|
851
|
+
if (label === undefined) {
|
|
852
|
+
label = `trap${code}`;
|
|
853
|
+
this.trapLabels.set(code, label);
|
|
854
|
+
}
|
|
855
|
+
return label;
|
|
856
|
+
}
|
|
857
|
+
// ── memory ──────────────────────────────────────────────────────────
|
|
858
|
+
/** Checked mode: the slots holding the base and byte length. */
|
|
859
|
+
memSlots = null;
|
|
860
|
+
refreshMemory() {
|
|
861
|
+
if (!this.checked || this.memSlots === null)
|
|
862
|
+
return;
|
|
863
|
+
// From the memory object, not the instance: a memory another instance
|
|
864
|
+
// (or JavaScript) grew may have moved.
|
|
865
|
+
const mem = this.loadPtrSlot(OFF_MEMORY);
|
|
866
|
+
const base = this.emit(`load ptr, ptr ${mem}, align 8`);
|
|
867
|
+
this.add(` store ptr ${base}, ptr ${this.memSlots.base}`);
|
|
868
|
+
const sizePtr = this.emit(`getelementptr inbounds i8, ptr ${mem}, i64 8`);
|
|
869
|
+
const size = this.emit(`load i64, ptr ${sizePtr}, align 8`);
|
|
870
|
+
this.add(` store i64 ${size}, ptr ${this.memSlots.size}`);
|
|
871
|
+
}
|
|
872
|
+
base() {
|
|
873
|
+
if (this.checked) {
|
|
874
|
+
return this.emit(`load ptr, ptr ${this.memSlots.base}`);
|
|
875
|
+
}
|
|
876
|
+
if (this.baseValue === null) {
|
|
877
|
+
this.baseValue = "%membase";
|
|
878
|
+
}
|
|
879
|
+
return this.baseValue;
|
|
880
|
+
}
|
|
881
|
+
/** The address of an access of `bytes` bytes at `addr + offset`. */
|
|
882
|
+
address(addr, offset, bytes) {
|
|
883
|
+
const wide = this.emit(`zext i32 ${addr} to i64`);
|
|
884
|
+
const ea = offset === 0 ? wide : this.emit(`add i64 ${wide}, ${offset}`);
|
|
885
|
+
if (this.checked) {
|
|
886
|
+
const size = this.emit(`load i64, ptr ${this.memSlots.size}`);
|
|
887
|
+
const endAddr = this.emit(`add i64 ${ea}, ${bytes}`);
|
|
888
|
+
const oob = this.emit(`icmp ugt i64 ${endAddr}, ${size}`);
|
|
889
|
+
const ok = this.label("ok");
|
|
890
|
+
this.add(` br i1 ${oob}, label %${this.trap(TRAP_MEMORY_OOB)}, label %${ok}`);
|
|
891
|
+
this.startBlock(ok);
|
|
892
|
+
}
|
|
893
|
+
return this.emit(`getelementptr i8, ptr ${this.base()}, i64 ${ea}`);
|
|
894
|
+
}
|
|
895
|
+
// ── constant expressions ────────────────────────────────────────────
|
|
896
|
+
constExpr(range) {
|
|
897
|
+
const c = new WasmCursor(this.m.bytes, range.start);
|
|
898
|
+
const stack = [];
|
|
899
|
+
for (;;) {
|
|
900
|
+
const op = c.u8();
|
|
901
|
+
if (op === 0x0b)
|
|
902
|
+
break;
|
|
903
|
+
switch (op) {
|
|
904
|
+
case 0x41:
|
|
905
|
+
stack.push(String(c.s32()));
|
|
906
|
+
break;
|
|
907
|
+
case 0x42: {
|
|
908
|
+
const [lo, hi] = c.s64();
|
|
909
|
+
stack.push(i64Lit(lo, hi));
|
|
910
|
+
break;
|
|
911
|
+
}
|
|
912
|
+
case 0x43:
|
|
913
|
+
stack.push(this.emit(`bitcast i32 ${c.u32le() | 0} to float`));
|
|
914
|
+
break;
|
|
915
|
+
case 0x44: {
|
|
916
|
+
const lo = c.u32le();
|
|
917
|
+
const hi = c.u32le();
|
|
918
|
+
stack.push(this.emit(`bitcast i64 ${i64Lit(lo, hi)} to double`));
|
|
919
|
+
break;
|
|
920
|
+
}
|
|
921
|
+
case 0x23: {
|
|
922
|
+
const g = c.u32();
|
|
923
|
+
const cell = this.loadPtrSlot(this.mt.globalSlot(g));
|
|
924
|
+
stack.push(this.emit(`load ${llType(this.m.globals[g].type)}, ptr ${cell}`));
|
|
925
|
+
break;
|
|
926
|
+
}
|
|
927
|
+
case 0xd0:
|
|
928
|
+
c.valType();
|
|
929
|
+
stack.push("null");
|
|
930
|
+
break;
|
|
931
|
+
case 0xd2:
|
|
932
|
+
stack.push(this.funcRef(c.u32()));
|
|
933
|
+
break;
|
|
934
|
+
case 0x6a:
|
|
935
|
+
case 0x6b:
|
|
936
|
+
case 0x6c:
|
|
937
|
+
case 0x7c:
|
|
938
|
+
case 0x7d:
|
|
939
|
+
case 0x7e: {
|
|
940
|
+
const b = stack.pop();
|
|
941
|
+
const a = stack.pop();
|
|
942
|
+
const t = op < 0x70 ? "i32" : "i64";
|
|
943
|
+
const name = op === 0x6a || op === 0x7c ? "add" : op === 0x6b || op === 0x7d ? "sub" : "mul";
|
|
944
|
+
stack.push(this.emit(`${name} ${t} ${a}, ${b}`));
|
|
945
|
+
break;
|
|
946
|
+
}
|
|
947
|
+
default:
|
|
948
|
+
throw new WasmTranslateError(`constant expression opcode 0x${op.toString(16)} is not supported`);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
return stack[stack.length - 1];
|
|
952
|
+
}
|
|
953
|
+
funcRef(f) {
|
|
954
|
+
this.mt.refs.add(f);
|
|
955
|
+
const records = this.loadPtrSlot(OFF_FUNCREFS);
|
|
956
|
+
return this.emit(`getelementptr inbounds i8, ptr ${records}, i64 ${f * FUNCREF_SIZE}`);
|
|
957
|
+
}
|
|
958
|
+
// ── control ─────────────────────────────────────────────────────────
|
|
959
|
+
blockSig(c) {
|
|
960
|
+
const bt = c.blockType();
|
|
961
|
+
if (bt.kind === "empty")
|
|
962
|
+
return { params: [], results: [] };
|
|
963
|
+
if (bt.kind === "value")
|
|
964
|
+
return { params: [], results: [bt.type] };
|
|
965
|
+
const t = this.m.types[bt.index];
|
|
966
|
+
return { params: t.params.slice(), results: t.results.slice() };
|
|
967
|
+
}
|
|
968
|
+
slotsFor(types) {
|
|
969
|
+
return types.map((t) => this.alloca(llType(t)));
|
|
970
|
+
}
|
|
971
|
+
storeTo(slots, values) {
|
|
972
|
+
for (let i = 0; i < slots.length; i++) {
|
|
973
|
+
const v = values[i];
|
|
974
|
+
this.add(` store ${llType(v.t)} ${v.v}, ptr ${slots[i]}`);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
loadFrom(slots, types) {
|
|
978
|
+
for (let i = 0; i < slots.length; i++) {
|
|
979
|
+
const t = types[i];
|
|
980
|
+
this.push(this.emit(`load ${llType(t)}, ptr ${slots[i]}`), t);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
/** Branch to the frame `depth` levels out (the stack keeps its values). */
|
|
984
|
+
branch(depth) {
|
|
985
|
+
const f = this.frames[this.frames.length - 1 - depth];
|
|
986
|
+
const n = f.branchSlots.length;
|
|
987
|
+
if (n > 0)
|
|
988
|
+
this.storeTo(f.branchSlots, this.stack.slice(this.stack.length - n));
|
|
989
|
+
this.add(` br label %${f.target}`);
|
|
990
|
+
}
|
|
991
|
+
/** The label of a block that branches to `depth`, for conditional
|
|
992
|
+
* branches and tables: the target itself when no values travel. */
|
|
993
|
+
branchEdge(depth, pending) {
|
|
994
|
+
const f = this.frames[this.frames.length - 1 - depth];
|
|
995
|
+
if (f.branchSlots.length === 0)
|
|
996
|
+
return f.target;
|
|
997
|
+
const edge = this.label("edge");
|
|
998
|
+
const saved = this.lines;
|
|
999
|
+
const edgeLines = new Lines();
|
|
1000
|
+
this.lines = edgeLines;
|
|
1001
|
+
this.startBlock(edge);
|
|
1002
|
+
this.branch(depth);
|
|
1003
|
+
this.lines = saved;
|
|
1004
|
+
pending.push(...edgeLines.lines);
|
|
1005
|
+
return edge;
|
|
1006
|
+
}
|
|
1007
|
+
goDead() {
|
|
1008
|
+
this.live = false;
|
|
1009
|
+
}
|
|
1010
|
+
pushFrame(kind, sig) {
|
|
1011
|
+
const end = this.label("end");
|
|
1012
|
+
const frame = {
|
|
1013
|
+
kind,
|
|
1014
|
+
params: sig.params,
|
|
1015
|
+
results: sig.results,
|
|
1016
|
+
target: end,
|
|
1017
|
+
end,
|
|
1018
|
+
branchSlots: [],
|
|
1019
|
+
resultSlots: this.slotsFor(sig.results),
|
|
1020
|
+
height: this.stack.length - sig.params.length,
|
|
1021
|
+
elseLabel: null,
|
|
1022
|
+
ifParams: [],
|
|
1023
|
+
live: true,
|
|
1024
|
+
};
|
|
1025
|
+
frame.branchSlots = frame.resultSlots;
|
|
1026
|
+
this.frames.push(frame);
|
|
1027
|
+
return frame;
|
|
1028
|
+
}
|
|
1029
|
+
/** Skips dead code from just after a terminator to the `else` or `end`
|
|
1030
|
+
* of the current frame; answers the opcode it stopped at (consumed). */
|
|
1031
|
+
skipDead(c) {
|
|
1032
|
+
let depth = 0;
|
|
1033
|
+
for (;;) {
|
|
1034
|
+
const op = c.u8();
|
|
1035
|
+
if (op === 0x02 || op === 0x03 || op === 0x04) {
|
|
1036
|
+
c.blockType();
|
|
1037
|
+
depth++;
|
|
1038
|
+
continue;
|
|
1039
|
+
}
|
|
1040
|
+
if (op === 0x0b) {
|
|
1041
|
+
if (depth === 0)
|
|
1042
|
+
return op;
|
|
1043
|
+
depth--;
|
|
1044
|
+
continue;
|
|
1045
|
+
}
|
|
1046
|
+
if (op === 0x05 && depth === 0)
|
|
1047
|
+
return op;
|
|
1048
|
+
skipImmediates(c, op);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
translate() {
|
|
1052
|
+
const ft = this.ft;
|
|
1053
|
+
const code = this.m.codes[this.index - this.m.importedFuncs];
|
|
1054
|
+
// Locals.
|
|
1055
|
+
const localSlots = [];
|
|
1056
|
+
this.localTypes = ft.params.concat(code.locals);
|
|
1057
|
+
for (let i = 0; i < this.localTypes.length; i++) {
|
|
1058
|
+
const t = this.localTypes[i];
|
|
1059
|
+
const slot = `%l${i}`;
|
|
1060
|
+
localSlots.push(slot);
|
|
1061
|
+
this.entry.add(` ${slot} = alloca ${llType(t)}`);
|
|
1062
|
+
}
|
|
1063
|
+
for (let i = 0; i < ft.params.length; i++) {
|
|
1064
|
+
this.entry.add(` store ${llType(ft.params[i])} %p${i}, ptr %l${i}`);
|
|
1065
|
+
}
|
|
1066
|
+
for (let i = ft.params.length; i < this.localTypes.length; i++) {
|
|
1067
|
+
const t = this.localTypes[i];
|
|
1068
|
+
this.entry.add(` store ${llType(t)} ${zeroOf(t)}, ptr %l${i}`);
|
|
1069
|
+
}
|
|
1070
|
+
if (this.checked && this.mt.memoryCount > 0) {
|
|
1071
|
+
this.memSlots = { base: "%mbase", size: "%msize" };
|
|
1072
|
+
this.entry.add(` %mbase = alloca ptr`);
|
|
1073
|
+
this.entry.add(` %msize = alloca i64`);
|
|
1074
|
+
}
|
|
1075
|
+
// The function frame: branches to it return.
|
|
1076
|
+
const ret = this.label("ret");
|
|
1077
|
+
const fnFrame = {
|
|
1078
|
+
kind: "func",
|
|
1079
|
+
params: [],
|
|
1080
|
+
results: ft.results,
|
|
1081
|
+
target: ret,
|
|
1082
|
+
end: ret,
|
|
1083
|
+
branchSlots: [],
|
|
1084
|
+
resultSlots: this.slotsFor(ft.results),
|
|
1085
|
+
height: 0,
|
|
1086
|
+
elseLabel: null,
|
|
1087
|
+
ifParams: [],
|
|
1088
|
+
live: true,
|
|
1089
|
+
};
|
|
1090
|
+
fnFrame.branchSlots = fnFrame.resultSlots;
|
|
1091
|
+
this.frames.push(fnFrame);
|
|
1092
|
+
if (this.memSlots !== null)
|
|
1093
|
+
this.refreshMemory();
|
|
1094
|
+
const c = new WasmCursor(this.m.bytes, code.body.start);
|
|
1095
|
+
this.body(c, code.body.end);
|
|
1096
|
+
// Epilogue.
|
|
1097
|
+
const out = [];
|
|
1098
|
+
out.push(`define internal ${this.mt.signature(ft, this.mt.fn(this.index))} ${FUNC_ATTRS} {`);
|
|
1099
|
+
out.push(`entry:`);
|
|
1100
|
+
out.push(...this.entry.lines);
|
|
1101
|
+
if (!this.checked && this.baseValue !== null) {
|
|
1102
|
+
out.push(` %membase.p = getelementptr inbounds i8, ptr %inst, i64 ${OFF_MEMBASE}`);
|
|
1103
|
+
out.push(` %membase = load ptr, ptr %membase.p, align 8`);
|
|
1104
|
+
}
|
|
1105
|
+
if (this.checked && this.mt.stackChecked.has(this.index)) {
|
|
1106
|
+
// Without the fault handler, stack exhaustion is an explicit check of
|
|
1107
|
+
// the stack pointer against the runtime's guard for the running stack
|
|
1108
|
+
// (thread or async fiber), in the functions through which the stack
|
|
1109
|
+
// can grow without bound (stackCheckedFunctions).
|
|
1110
|
+
// The address of a frame slot stands for the stack pointer; unlike
|
|
1111
|
+
// llvm.stacksave it constrains no other code.
|
|
1112
|
+
out.push(` %sp = alloca i8, align 1`);
|
|
1113
|
+
out.push(` %sp.i = ptrtoint ptr %sp to i64`);
|
|
1114
|
+
out.push(` %limit.p = call ptr @llvm.threadlocal.address.p0(ptr @scr_wasm_stack_limit)`);
|
|
1115
|
+
out.push(` %limit = load i64, ptr %limit.p, align 8`);
|
|
1116
|
+
out.push(` %exhausted = icmp ult i64 %sp.i, %limit`);
|
|
1117
|
+
out.push(` br i1 %exhausted, label %exhausted.trap, label %body`);
|
|
1118
|
+
out.push(`exhausted.trap:`);
|
|
1119
|
+
out.push(` call void @scr_wasm_trap(i32 ${TRAP_EXHAUSTION})`);
|
|
1120
|
+
out.push(` unreachable`);
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
out.push(` br label %body`);
|
|
1124
|
+
}
|
|
1125
|
+
out.push(`body:`);
|
|
1126
|
+
out.push(...this.lines.lines);
|
|
1127
|
+
for (const [code2, label] of this.trapLabels) {
|
|
1128
|
+
out.push(`${label}:`);
|
|
1129
|
+
out.push(` call void @scr_wasm_trap(i32 ${code2})`);
|
|
1130
|
+
out.push(` unreachable`);
|
|
1131
|
+
}
|
|
1132
|
+
out.push(`}`);
|
|
1133
|
+
return [out.join("\n")];
|
|
1134
|
+
}
|
|
1135
|
+
/** The function body; returns at the function's final `end`. */
|
|
1136
|
+
body(c, end) {
|
|
1137
|
+
while (c.pos < end) {
|
|
1138
|
+
if (!this.live) {
|
|
1139
|
+
const op = this.skipDead(c);
|
|
1140
|
+
if (op === 0x05)
|
|
1141
|
+
this.opElse();
|
|
1142
|
+
else if (this.opEnd())
|
|
1143
|
+
return;
|
|
1144
|
+
continue;
|
|
1145
|
+
}
|
|
1146
|
+
const op = c.u8();
|
|
1147
|
+
if (op === 0x0b) {
|
|
1148
|
+
if (this.opEnd())
|
|
1149
|
+
return;
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
this.instruction(c, op);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
/** `end`: closes the innermost frame; true when that was the function. */
|
|
1156
|
+
opEnd() {
|
|
1157
|
+
const f = this.frames[this.frames.length - 1];
|
|
1158
|
+
if (this.live) {
|
|
1159
|
+
const n = f.results.length;
|
|
1160
|
+
this.storeTo(f.resultSlots, this.stack.slice(this.stack.length - n));
|
|
1161
|
+
this.add(` br label %${f.end}`);
|
|
1162
|
+
}
|
|
1163
|
+
if (f.elseLabel !== null) {
|
|
1164
|
+
// An if without else: the implicit else passes its parameters on.
|
|
1165
|
+
this.startBlock(f.elseLabel);
|
|
1166
|
+
if (f.live) {
|
|
1167
|
+
this.storeTo(f.resultSlots, f.ifParams);
|
|
1168
|
+
}
|
|
1169
|
+
this.add(` br label %${f.end}`);
|
|
1170
|
+
f.elseLabel = null;
|
|
1171
|
+
}
|
|
1172
|
+
this.frames.pop();
|
|
1173
|
+
this.stack.length = f.height;
|
|
1174
|
+
this.startBlock(f.end);
|
|
1175
|
+
if (f.kind === "func") {
|
|
1176
|
+
if (f.results.length === 0)
|
|
1177
|
+
this.add(` ret void`);
|
|
1178
|
+
else {
|
|
1179
|
+
this.loadFrom(f.resultSlots, f.results);
|
|
1180
|
+
const vals = this.popN(f.results.length);
|
|
1181
|
+
if (vals.length === 1)
|
|
1182
|
+
this.add(` ret ${llType(vals[0].t)} ${vals[0].v}`);
|
|
1183
|
+
else {
|
|
1184
|
+
const rt = retType(f.results);
|
|
1185
|
+
let agg = "undef";
|
|
1186
|
+
for (let i = 0; i < vals.length; i++) {
|
|
1187
|
+
agg = this.emit(`insertvalue ${rt} ${agg}, ${llType(vals[i].t)} ${vals[i].v}, ${i}`);
|
|
1188
|
+
}
|
|
1189
|
+
this.add(` ret ${rt} ${agg}`);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
return true;
|
|
1193
|
+
}
|
|
1194
|
+
this.loadFrom(f.resultSlots, f.results);
|
|
1195
|
+
this.live = true;
|
|
1196
|
+
return false;
|
|
1197
|
+
}
|
|
1198
|
+
opElse() {
|
|
1199
|
+
const f = this.frames[this.frames.length - 1];
|
|
1200
|
+
if (this.live) {
|
|
1201
|
+
const n = f.results.length;
|
|
1202
|
+
this.storeTo(f.resultSlots, this.stack.slice(this.stack.length - n));
|
|
1203
|
+
this.add(` br label %${f.end}`);
|
|
1204
|
+
}
|
|
1205
|
+
this.stack.length = f.height;
|
|
1206
|
+
this.startBlock(f.elseLabel);
|
|
1207
|
+
f.elseLabel = null;
|
|
1208
|
+
for (const v of f.ifParams)
|
|
1209
|
+
this.stack.push(v);
|
|
1210
|
+
this.live = f.live;
|
|
1211
|
+
if (!f.live) {
|
|
1212
|
+
// The if itself was dead: its else branch is too.
|
|
1213
|
+
this.add(` unreachable`);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
call(index) {
|
|
1217
|
+
const ft = this.mt.funcType(index);
|
|
1218
|
+
const args = this.popN(ft.params.length);
|
|
1219
|
+
const argText = ["ptr %inst", ...args.map((a) => `${llType(a.t)} ${a.v}`)].join(", ");
|
|
1220
|
+
this.callWith(this.mt.fn(index), ft, argText);
|
|
1221
|
+
}
|
|
1222
|
+
callWith(callee, ft, argText) {
|
|
1223
|
+
const rt = retType(ft.results);
|
|
1224
|
+
if (ft.results.length === 0) {
|
|
1225
|
+
this.add(` call void ${callee}(${argText})`);
|
|
1226
|
+
}
|
|
1227
|
+
else {
|
|
1228
|
+
const r = this.emit(`call ${rt} ${callee}(${argText})`);
|
|
1229
|
+
if (ft.results.length === 1)
|
|
1230
|
+
this.push(r, ft.results[0]);
|
|
1231
|
+
else
|
|
1232
|
+
for (let i = 0; i < ft.results.length; i++)
|
|
1233
|
+
this.push(this.emit(`extractvalue ${rt} ${r}, ${i}`), ft.results[i]);
|
|
1234
|
+
}
|
|
1235
|
+
this.refreshMemory();
|
|
1236
|
+
}
|
|
1237
|
+
callIndirect(typeIndex, table) {
|
|
1238
|
+
const ft = this.m.types[typeIndex];
|
|
1239
|
+
const idx = this.pop();
|
|
1240
|
+
const args = this.popN(ft.params.length);
|
|
1241
|
+
const t = this.loadPtrSlot(this.mt.tableSlot(table));
|
|
1242
|
+
const sizePtr = this.emit(`getelementptr inbounds i8, ptr ${t}, i64 8`);
|
|
1243
|
+
const size = this.emit(`load i32, ptr ${sizePtr}, align 8`);
|
|
1244
|
+
const inRange = this.emit(`icmp ult i32 ${idx.v}, ${size}`);
|
|
1245
|
+
const ok = this.label("ci");
|
|
1246
|
+
this.add(` br i1 ${inRange}, label %${ok}, label %${this.trap(TRAP_TABLE_OOB)}`);
|
|
1247
|
+
this.startBlock(ok);
|
|
1248
|
+
const elems = this.emit(`load ptr, ptr ${t}, align 8`);
|
|
1249
|
+
const wide = this.emit(`zext i32 ${idx.v} to i64`);
|
|
1250
|
+
const slot = this.emit(`getelementptr inbounds ptr, ptr ${elems}, i64 ${wide}`);
|
|
1251
|
+
const rec = this.emit(`load ptr, ptr ${slot}, align 8`);
|
|
1252
|
+
const isNull = this.emit(`icmp eq ptr ${rec}, null`);
|
|
1253
|
+
const nn = this.label("cn");
|
|
1254
|
+
this.add(` br i1 ${isNull}, label %${this.trap(TRAP_SIGNATURE)}, label %${nn}`);
|
|
1255
|
+
this.startBlock(nn);
|
|
1256
|
+
const typePtr = this.emit(`getelementptr inbounds i8, ptr ${rec}, i64 8`);
|
|
1257
|
+
const type = this.emit(`load i64, ptr ${typePtr}, align 8`);
|
|
1258
|
+
const same = this.emit(`icmp eq i64 ${type}, ${this.mt.typeHashes[typeIndex]}`);
|
|
1259
|
+
const go = this.label("cg");
|
|
1260
|
+
this.add(` br i1 ${same}, label %${go}, label %${this.trap(TRAP_SIGNATURE)}`);
|
|
1261
|
+
this.startBlock(go);
|
|
1262
|
+
const codePtr = this.emit(`load ptr, ptr ${rec}, align 8`);
|
|
1263
|
+
const instPtr = this.emit(`getelementptr inbounds i8, ptr ${rec}, i64 16`);
|
|
1264
|
+
const inst = this.emit(`load ptr, ptr ${instPtr}, align 8`);
|
|
1265
|
+
const argText = [`ptr ${inst}`, ...args.map((a) => `${llType(a.t)} ${a.v}`)].join(", ");
|
|
1266
|
+
this.callWith(codePtr, ft, argText);
|
|
1267
|
+
}
|
|
1268
|
+
/** Integer division and remainder with wasm's traps. */
|
|
1269
|
+
divRem(op, t) {
|
|
1270
|
+
const b = this.pop();
|
|
1271
|
+
const a = this.pop();
|
|
1272
|
+
const ty = b.t;
|
|
1273
|
+
const zero = this.emit(`icmp eq ${t} ${b.v}, 0`);
|
|
1274
|
+
const signed = op === 0x6d || op === 0x6f || op === 0x7f || op === 0x81;
|
|
1275
|
+
const rem = op === 0x6f || op === 0x70 || op === 0x81 || op === 0x82;
|
|
1276
|
+
const nz = this.label("nz");
|
|
1277
|
+
this.add(` br i1 ${zero}, label %${this.trap(rem ? TRAP_REM_BY_ZERO : TRAP_DIV_BY_ZERO)}, label %${nz}`);
|
|
1278
|
+
this.startBlock(nz);
|
|
1279
|
+
const min = t === "i32" ? "-2147483648" : "-9223372036854775808";
|
|
1280
|
+
if (signed && !rem) {
|
|
1281
|
+
const isMin = this.emit(`icmp eq ${t} ${a.v}, ${min}`);
|
|
1282
|
+
const isNeg1 = this.emit(`icmp eq ${t} ${b.v}, -1`);
|
|
1283
|
+
const ovf = this.emit(`and i1 ${isMin}, ${isNeg1}`);
|
|
1284
|
+
const okl = this.label("dv");
|
|
1285
|
+
this.add(` br i1 ${ovf}, label %${this.trap(TRAP_DIV_UNREPRESENTABLE)}, label %${okl}`);
|
|
1286
|
+
this.startBlock(okl);
|
|
1287
|
+
this.push(this.emit(`sdiv ${t} ${a.v}, ${b.v}`), ty);
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
if (signed && rem) {
|
|
1291
|
+
// INT_MIN % -1 is 0 in wasm (LLVM's srem would be undefined).
|
|
1292
|
+
const isNeg1 = this.emit(`icmp eq ${t} ${b.v}, -1`);
|
|
1293
|
+
const divisor = this.emit(`select i1 ${isNeg1}, ${t} 1, ${t} ${b.v}`);
|
|
1294
|
+
this.push(this.emit(`srem ${t} ${a.v}, ${divisor}`), ty);
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
this.push(this.emit(`${rem ? "urem" : "udiv"} ${t} ${a.v}, ${b.v}`), ty);
|
|
1298
|
+
}
|
|
1299
|
+
/** Trapping float-to-int conversion. */
|
|
1300
|
+
truncTrap(op) {
|
|
1301
|
+
const x = this.pop();
|
|
1302
|
+
const from = x.t === VAL_F32 ? "float" : "double";
|
|
1303
|
+
// [lower bound exclusive?, lower, upper (exclusive)] as exact doubles.
|
|
1304
|
+
let lo = "";
|
|
1305
|
+
let loInclusive = false;
|
|
1306
|
+
let hi = "";
|
|
1307
|
+
let to = "i32";
|
|
1308
|
+
let signed = true;
|
|
1309
|
+
switch (op) {
|
|
1310
|
+
case 0xa8: // i32.trunc_f32_s
|
|
1311
|
+
case 0xaa: // i32.trunc_f64_s
|
|
1312
|
+
lo = op === 0xa8 ? "-2147483648.0" : "-2147483649.0";
|
|
1313
|
+
loInclusive = op === 0xa8;
|
|
1314
|
+
hi = "2147483648.0";
|
|
1315
|
+
break;
|
|
1316
|
+
case 0xa9:
|
|
1317
|
+
case 0xab:
|
|
1318
|
+
lo = "-1.0";
|
|
1319
|
+
hi = "4294967296.0";
|
|
1320
|
+
signed = false;
|
|
1321
|
+
break;
|
|
1322
|
+
case 0xae:
|
|
1323
|
+
case 0xb0:
|
|
1324
|
+
lo = "-9223372036854775808.0";
|
|
1325
|
+
loInclusive = true;
|
|
1326
|
+
hi = "9223372036854775808.0";
|
|
1327
|
+
to = "i64";
|
|
1328
|
+
break;
|
|
1329
|
+
default:
|
|
1330
|
+
lo = "-1.0";
|
|
1331
|
+
hi = "18446744073709551616.0";
|
|
1332
|
+
to = "i64";
|
|
1333
|
+
signed = false;
|
|
1334
|
+
break;
|
|
1335
|
+
}
|
|
1336
|
+
const d = from === "double" ? x.v : this.emit(`fpext float ${x.v} to double`);
|
|
1337
|
+
const above = this.emit(`fcmp ${loInclusive ? "oge" : "ogt"} double ${d}, ${hexDouble(lo)}`);
|
|
1338
|
+
const below = this.emit(`fcmp olt double ${d}, ${hexDouble(hi)}`);
|
|
1339
|
+
const ok = this.emit(`and i1 ${above}, ${below}`);
|
|
1340
|
+
const okl = this.label("cv");
|
|
1341
|
+
this.add(` br i1 ${ok}, label %${okl}, label %${this.trap(TRAP_FLOAT_UNREPRESENTABLE)}`);
|
|
1342
|
+
this.startBlock(okl);
|
|
1343
|
+
this.push(this.emit(`${signed ? "fptosi" : "fptoui"} ${from} ${x.v} to ${to}`), to === "i32" ? VAL_I32 : VAL_I64);
|
|
1344
|
+
}
|
|
1345
|
+
unaryIntrinsic(name, t, vt, extra = "") {
|
|
1346
|
+
const a = this.pop();
|
|
1347
|
+
this.push(this.emit(`call ${t} @llvm.${name}(${t} ${a.v}${extra})`), vt);
|
|
1348
|
+
}
|
|
1349
|
+
binaryIntrinsic(name, t, vt) {
|
|
1350
|
+
const b = this.pop();
|
|
1351
|
+
const a = this.pop();
|
|
1352
|
+
this.push(this.emit(`call ${t} @llvm.${name}(${t} ${a.v}, ${t} ${b.v})`), vt);
|
|
1353
|
+
}
|
|
1354
|
+
binary(instr, t, vt) {
|
|
1355
|
+
const b = this.pop();
|
|
1356
|
+
const a = this.pop();
|
|
1357
|
+
this.push(this.emit(`${instr} ${t} ${a.v}, ${b.v}`), vt);
|
|
1358
|
+
}
|
|
1359
|
+
compare(pred, t, float) {
|
|
1360
|
+
const b = this.pop();
|
|
1361
|
+
const a = this.pop();
|
|
1362
|
+
const r = this.emit(`${float ? "fcmp" : "icmp"} ${pred} ${t} ${a.v}, ${b.v}`);
|
|
1363
|
+
this.push(this.emit(`zext i1 ${r} to i32`), VAL_I32);
|
|
1364
|
+
}
|
|
1365
|
+
eqz(t) {
|
|
1366
|
+
const a = this.pop();
|
|
1367
|
+
const r = this.emit(`icmp eq ${t} ${a.v}, 0`);
|
|
1368
|
+
this.push(this.emit(`zext i1 ${r} to i32`), VAL_I32);
|
|
1369
|
+
}
|
|
1370
|
+
shift(instr, t, vt) {
|
|
1371
|
+
const b = this.pop();
|
|
1372
|
+
const a = this.pop();
|
|
1373
|
+
const masked = this.emit(`and ${t} ${b.v}, ${t === "i32" ? 31 : 63}`);
|
|
1374
|
+
this.push(this.emit(`${instr} ${t} ${a.v}, ${masked}`), vt);
|
|
1375
|
+
}
|
|
1376
|
+
rotate(name, t, vt) {
|
|
1377
|
+
const b = this.pop();
|
|
1378
|
+
const a = this.pop();
|
|
1379
|
+
this.push(this.emit(`call ${t} @llvm.${name}.${t}(${t} ${a.v}, ${t} ${a.v}, ${t} ${b.v})`), vt);
|
|
1380
|
+
}
|
|
1381
|
+
convert(instr, from, to, vt) {
|
|
1382
|
+
const a = this.pop();
|
|
1383
|
+
this.push(this.emit(`${instr} ${from} ${a.v} to ${to}`), vt);
|
|
1384
|
+
}
|
|
1385
|
+
instruction(c, op) {
|
|
1386
|
+
switch (op) {
|
|
1387
|
+
case 0x00: // unreachable
|
|
1388
|
+
this.add(` br label %${this.trap(TRAP_UNREACHABLE)}`);
|
|
1389
|
+
this.goDead();
|
|
1390
|
+
return;
|
|
1391
|
+
case 0x01:
|
|
1392
|
+
return;
|
|
1393
|
+
case 0x02: {
|
|
1394
|
+
// block
|
|
1395
|
+
const sig = this.blockSig(c);
|
|
1396
|
+
this.pushFrame("block", sig);
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
case 0x03: {
|
|
1400
|
+
// loop
|
|
1401
|
+
const sig = this.blockSig(c);
|
|
1402
|
+
const f = this.pushFrame("loop", sig);
|
|
1403
|
+
f.target = this.label("loop");
|
|
1404
|
+
f.branchSlots = this.slotsFor(sig.params);
|
|
1405
|
+
const params = this.popN(sig.params.length);
|
|
1406
|
+
this.storeTo(f.branchSlots, params);
|
|
1407
|
+
this.add(` br label %${f.target}`);
|
|
1408
|
+
this.startBlock(f.target);
|
|
1409
|
+
this.loadFrom(f.branchSlots, sig.params);
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1412
|
+
case 0x04: {
|
|
1413
|
+
// if
|
|
1414
|
+
const sig = this.blockSig(c);
|
|
1415
|
+
const cond = this.pop();
|
|
1416
|
+
const f = this.pushFrame("if", sig);
|
|
1417
|
+
f.ifParams = this.stack.slice(this.stack.length - sig.params.length);
|
|
1418
|
+
const then = this.label("then");
|
|
1419
|
+
f.elseLabel = this.label("else");
|
|
1420
|
+
const test = this.emit(`icmp ne i32 ${cond.v}, 0`);
|
|
1421
|
+
this.add(` br i1 ${test}, label %${then}, label %${f.elseLabel}`);
|
|
1422
|
+
this.startBlock(then);
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
case 0x05:
|
|
1426
|
+
this.opElse();
|
|
1427
|
+
return;
|
|
1428
|
+
case 0x0c: {
|
|
1429
|
+
const depth = c.u32();
|
|
1430
|
+
this.branch(depth);
|
|
1431
|
+
this.goDead();
|
|
1432
|
+
return;
|
|
1433
|
+
}
|
|
1434
|
+
case 0x0d: {
|
|
1435
|
+
const depth = c.u32();
|
|
1436
|
+
const cond = this.pop();
|
|
1437
|
+
const test = this.emit(`icmp ne i32 ${cond.v}, 0`);
|
|
1438
|
+
const pending = [];
|
|
1439
|
+
const target = this.branchEdge(depth, pending);
|
|
1440
|
+
const cont = this.label("br");
|
|
1441
|
+
this.add(` br i1 ${test}, label %${target}, label %${cont}`);
|
|
1442
|
+
for (const line of pending)
|
|
1443
|
+
this.add(line);
|
|
1444
|
+
this.startBlock(cont);
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
case 0x0e: {
|
|
1448
|
+
const n = c.u32();
|
|
1449
|
+
const depths = [];
|
|
1450
|
+
for (let i = 0; i < n; i++)
|
|
1451
|
+
depths.push(c.u32());
|
|
1452
|
+
const def = c.u32();
|
|
1453
|
+
const idx = this.pop();
|
|
1454
|
+
const pending = [];
|
|
1455
|
+
const edges = new Map();
|
|
1456
|
+
const edgeOf = (d) => {
|
|
1457
|
+
let e = edges.get(d);
|
|
1458
|
+
if (e === undefined) {
|
|
1459
|
+
e = this.branchEdge(d, pending);
|
|
1460
|
+
edges.set(d, e);
|
|
1461
|
+
}
|
|
1462
|
+
return e;
|
|
1463
|
+
};
|
|
1464
|
+
const cases = depths.map((d, i) => `i32 ${i}, label %${edgeOf(d)}`);
|
|
1465
|
+
this.add(` switch i32 ${idx.v}, label %${edgeOf(def)} [${cases.join(" ")}]`);
|
|
1466
|
+
for (const line of pending)
|
|
1467
|
+
this.add(line);
|
|
1468
|
+
this.goDead();
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
case 0x0f: // return
|
|
1472
|
+
this.branch(this.frames.length - 1);
|
|
1473
|
+
this.goDead();
|
|
1474
|
+
return;
|
|
1475
|
+
case 0x10:
|
|
1476
|
+
this.call(c.u32());
|
|
1477
|
+
return;
|
|
1478
|
+
case 0x11: {
|
|
1479
|
+
const type = c.u32();
|
|
1480
|
+
const table = c.u32();
|
|
1481
|
+
this.callIndirect(type, table);
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
case 0x1a: {
|
|
1485
|
+
// A dropped load must still fault when it is out of bounds: LLVM
|
|
1486
|
+
// would delete an unused ordinary load.
|
|
1487
|
+
const v = this.pop();
|
|
1488
|
+
if (v.load !== undefined) {
|
|
1489
|
+
const line = this.lines.lines[v.load];
|
|
1490
|
+
this.lines.lines[v.load] = line.replace(" = load ", " = load volatile ");
|
|
1491
|
+
}
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
case 0x1b:
|
|
1495
|
+
case 0x1c: {
|
|
1496
|
+
if (op === 0x1c) {
|
|
1497
|
+
const n = c.u32();
|
|
1498
|
+
for (let i = 0; i < n; i++)
|
|
1499
|
+
c.valType();
|
|
1500
|
+
}
|
|
1501
|
+
const cond = this.pop();
|
|
1502
|
+
const b = this.pop();
|
|
1503
|
+
const a = this.pop();
|
|
1504
|
+
const test = this.emit(`icmp ne i32 ${cond.v}, 0`);
|
|
1505
|
+
const t = llType(a.t);
|
|
1506
|
+
this.push(this.emit(`select i1 ${test}, ${t} ${a.v}, ${t} ${b.v}`), a.t);
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
case 0x20: {
|
|
1510
|
+
const i = c.u32();
|
|
1511
|
+
const t = this.localType(i);
|
|
1512
|
+
this.push(this.emit(`load ${llType(t)}, ptr %l${i}`), t);
|
|
1513
|
+
return;
|
|
1514
|
+
}
|
|
1515
|
+
case 0x21: {
|
|
1516
|
+
const i = c.u32();
|
|
1517
|
+
const t = this.localType(i);
|
|
1518
|
+
const v = this.popType(t, "local.set");
|
|
1519
|
+
this.add(` store ${llType(t)} ${v.v}, ptr %l${i}`);
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
case 0x22: {
|
|
1523
|
+
const i = c.u32();
|
|
1524
|
+
const t = this.localType(i);
|
|
1525
|
+
const v = this.popType(t, "local.tee");
|
|
1526
|
+
this.stack.push(v);
|
|
1527
|
+
this.add(` store ${llType(t)} ${v.v}, ptr %l${i}`);
|
|
1528
|
+
return;
|
|
1529
|
+
}
|
|
1530
|
+
case 0x23: {
|
|
1531
|
+
const g = c.u32();
|
|
1532
|
+
const t = this.m.globals[g].type;
|
|
1533
|
+
const cell = this.loadPtrSlot(this.mt.globalSlot(g));
|
|
1534
|
+
this.push(this.emit(`load ${llType(t)}, ptr ${cell}, align 8`), t);
|
|
1535
|
+
return;
|
|
1536
|
+
}
|
|
1537
|
+
case 0x24: {
|
|
1538
|
+
const g = c.u32();
|
|
1539
|
+
const global = this.m.globals[g];
|
|
1540
|
+
if (global === undefined)
|
|
1541
|
+
throw new WasmTranslateError(`unknown global ${g}`);
|
|
1542
|
+
const v = this.popType(global.type, "global.set");
|
|
1543
|
+
const cell = this.loadPtrSlot(this.mt.globalSlot(g));
|
|
1544
|
+
if (v.t === VAL_EXTERNREF)
|
|
1545
|
+
this.add(` call void @scr_wasm_global_set_ref(ptr ${cell}, ptr ${v.v})`);
|
|
1546
|
+
else
|
|
1547
|
+
this.add(` store ${llType(v.t)} ${v.v}, ptr ${cell}, align 8`);
|
|
1548
|
+
return;
|
|
1549
|
+
}
|
|
1550
|
+
case 0x25: {
|
|
1551
|
+
const t = c.u32();
|
|
1552
|
+
const i = this.pop();
|
|
1553
|
+
this.push(this.emit(`call ptr @scr_wasm_table_get(ptr %inst, i32 ${t}, i32 ${i.v})`), this.m.tables[t].elemType);
|
|
1554
|
+
return;
|
|
1555
|
+
}
|
|
1556
|
+
case 0x26: {
|
|
1557
|
+
const t = c.u32();
|
|
1558
|
+
const table = this.m.tables[t];
|
|
1559
|
+
if (table === undefined)
|
|
1560
|
+
throw new WasmTranslateError(`unknown table ${t}`);
|
|
1561
|
+
const v = this.popType(table.elemType, "table.set");
|
|
1562
|
+
const i = this.popType(VAL_I32, "table.set");
|
|
1563
|
+
this.add(` call void @scr_wasm_table_set(ptr %inst, i32 ${t}, i32 ${i.v}, ptr ${v.v})`);
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
case 0x3f: {
|
|
1567
|
+
this.memoryIndex(c);
|
|
1568
|
+
const mem = this.loadPtrSlot(OFF_MEMORY);
|
|
1569
|
+
const sizePtr = this.emit(`getelementptr inbounds i8, ptr ${mem}, i64 8`);
|
|
1570
|
+
const size = this.emit(`load i64, ptr ${sizePtr}, align 8`);
|
|
1571
|
+
const pages = this.emit(`lshr i64 ${size}, 16`);
|
|
1572
|
+
this.push(this.emit(`trunc i64 ${pages} to i32`), VAL_I32);
|
|
1573
|
+
return;
|
|
1574
|
+
}
|
|
1575
|
+
case 0x40: {
|
|
1576
|
+
this.memoryIndex(c);
|
|
1577
|
+
const delta = this.pop();
|
|
1578
|
+
this.push(this.emit(`call i32 @scr_wasm_memory_grow(ptr %inst, i32 ${delta.v})`), VAL_I32);
|
|
1579
|
+
this.refreshMemory();
|
|
1580
|
+
return;
|
|
1581
|
+
}
|
|
1582
|
+
case 0x41:
|
|
1583
|
+
this.push(String(c.s32()), VAL_I32);
|
|
1584
|
+
return;
|
|
1585
|
+
case 0x42: {
|
|
1586
|
+
const [lo, hi] = c.s64();
|
|
1587
|
+
this.push(i64Lit(lo, hi), VAL_I64);
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
case 0x43:
|
|
1591
|
+
this.push(this.emit(`bitcast i32 ${c.u32le() | 0} to float`), VAL_F32);
|
|
1592
|
+
return;
|
|
1593
|
+
case 0x44: {
|
|
1594
|
+
const lo = c.u32le();
|
|
1595
|
+
const hi = c.u32le();
|
|
1596
|
+
this.push(this.emit(`bitcast i64 ${i64Lit(lo, hi)} to double`), VAL_F64);
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
case 0xd0:
|
|
1600
|
+
c.valType();
|
|
1601
|
+
this.push("null", c.bytes[c.pos - 1]);
|
|
1602
|
+
return;
|
|
1603
|
+
case 0xd1: {
|
|
1604
|
+
const a = this.pop();
|
|
1605
|
+
const r = this.emit(`icmp eq ptr ${a.v}, null`);
|
|
1606
|
+
this.push(this.emit(`zext i1 ${r} to i32`), VAL_I32);
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1609
|
+
case 0xd2:
|
|
1610
|
+
this.push(this.funcRef(c.u32()), VAL_FUNCREF);
|
|
1611
|
+
return;
|
|
1612
|
+
case 0xfc:
|
|
1613
|
+
this.prefixed(c);
|
|
1614
|
+
return;
|
|
1615
|
+
default:
|
|
1616
|
+
break;
|
|
1617
|
+
}
|
|
1618
|
+
if (op >= 0x28 && op <= 0x35) {
|
|
1619
|
+
const offset = this.memargOffset(c);
|
|
1620
|
+
const [vt, mt, bytes, ext] = LOAD_INFO[op];
|
|
1621
|
+
const addr = this.popType(VAL_I32, "load address");
|
|
1622
|
+
const p = this.address(addr.v, offset, bytes);
|
|
1623
|
+
const line = this.lines.lines.length;
|
|
1624
|
+
const loaded = this.emit(`load ${mt}, ptr ${p}, align 1`);
|
|
1625
|
+
if (ext === "")
|
|
1626
|
+
this.stack.push({ v: loaded, t: vt, load: line });
|
|
1627
|
+
else {
|
|
1628
|
+
const extended = this.emit(`${ext} ${mt} ${loaded} to ${llType(vt)}`);
|
|
1629
|
+
this.stack.push({ v: extended, t: vt, load: line });
|
|
1630
|
+
}
|
|
1631
|
+
return;
|
|
1632
|
+
}
|
|
1633
|
+
if (op >= 0x36 && op <= 0x3e) {
|
|
1634
|
+
const offset = this.memargOffset(c);
|
|
1635
|
+
const [vt, mt, bytes] = STORE_INFO[op];
|
|
1636
|
+
const v = this.popType(vt, "store");
|
|
1637
|
+
const addr = this.popType(VAL_I32, "store address");
|
|
1638
|
+
const p = this.address(addr.v, offset, bytes);
|
|
1639
|
+
let value = v.v;
|
|
1640
|
+
if (mt === "i8" || mt === "i16" || (mt === "i32" && v.t === VAL_I64)) {
|
|
1641
|
+
value = this.emit(`trunc ${llType(v.t)} ${v.v} to ${mt}`);
|
|
1642
|
+
}
|
|
1643
|
+
this.add(` store ${mt} ${value}, ptr ${p}, align 1`);
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
this.numeric(op);
|
|
1647
|
+
}
|
|
1648
|
+
numeric(op) {
|
|
1649
|
+
const I32 = VAL_I32;
|
|
1650
|
+
const I64 = VAL_I64;
|
|
1651
|
+
const F32 = VAL_F32;
|
|
1652
|
+
const F64 = VAL_F64;
|
|
1653
|
+
switch (op) {
|
|
1654
|
+
case 0x45:
|
|
1655
|
+
return this.eqz("i32");
|
|
1656
|
+
case 0x46:
|
|
1657
|
+
return this.compare("eq", "i32", false);
|
|
1658
|
+
case 0x47:
|
|
1659
|
+
return this.compare("ne", "i32", false);
|
|
1660
|
+
case 0x48:
|
|
1661
|
+
return this.compare("slt", "i32", false);
|
|
1662
|
+
case 0x49:
|
|
1663
|
+
return this.compare("ult", "i32", false);
|
|
1664
|
+
case 0x4a:
|
|
1665
|
+
return this.compare("sgt", "i32", false);
|
|
1666
|
+
case 0x4b:
|
|
1667
|
+
return this.compare("ugt", "i32", false);
|
|
1668
|
+
case 0x4c:
|
|
1669
|
+
return this.compare("sle", "i32", false);
|
|
1670
|
+
case 0x4d:
|
|
1671
|
+
return this.compare("ule", "i32", false);
|
|
1672
|
+
case 0x4e:
|
|
1673
|
+
return this.compare("sge", "i32", false);
|
|
1674
|
+
case 0x4f:
|
|
1675
|
+
return this.compare("uge", "i32", false);
|
|
1676
|
+
case 0x50:
|
|
1677
|
+
return this.eqz("i64");
|
|
1678
|
+
case 0x51:
|
|
1679
|
+
return this.compare("eq", "i64", false);
|
|
1680
|
+
case 0x52:
|
|
1681
|
+
return this.compare("ne", "i64", false);
|
|
1682
|
+
case 0x53:
|
|
1683
|
+
return this.compare("slt", "i64", false);
|
|
1684
|
+
case 0x54:
|
|
1685
|
+
return this.compare("ult", "i64", false);
|
|
1686
|
+
case 0x55:
|
|
1687
|
+
return this.compare("sgt", "i64", false);
|
|
1688
|
+
case 0x56:
|
|
1689
|
+
return this.compare("ugt", "i64", false);
|
|
1690
|
+
case 0x57:
|
|
1691
|
+
return this.compare("sle", "i64", false);
|
|
1692
|
+
case 0x58:
|
|
1693
|
+
return this.compare("ule", "i64", false);
|
|
1694
|
+
case 0x59:
|
|
1695
|
+
return this.compare("sge", "i64", false);
|
|
1696
|
+
case 0x5a:
|
|
1697
|
+
return this.compare("uge", "i64", false);
|
|
1698
|
+
case 0x5b:
|
|
1699
|
+
return this.compare("oeq", "float", true);
|
|
1700
|
+
case 0x5c:
|
|
1701
|
+
return this.compare("une", "float", true);
|
|
1702
|
+
case 0x5d:
|
|
1703
|
+
return this.compare("olt", "float", true);
|
|
1704
|
+
case 0x5e:
|
|
1705
|
+
return this.compare("ogt", "float", true);
|
|
1706
|
+
case 0x5f:
|
|
1707
|
+
return this.compare("ole", "float", true);
|
|
1708
|
+
case 0x60:
|
|
1709
|
+
return this.compare("oge", "float", true);
|
|
1710
|
+
case 0x61:
|
|
1711
|
+
return this.compare("oeq", "double", true);
|
|
1712
|
+
case 0x62:
|
|
1713
|
+
return this.compare("une", "double", true);
|
|
1714
|
+
case 0x63:
|
|
1715
|
+
return this.compare("olt", "double", true);
|
|
1716
|
+
case 0x64:
|
|
1717
|
+
return this.compare("ogt", "double", true);
|
|
1718
|
+
case 0x65:
|
|
1719
|
+
return this.compare("ole", "double", true);
|
|
1720
|
+
case 0x66:
|
|
1721
|
+
return this.compare("oge", "double", true);
|
|
1722
|
+
case 0x67:
|
|
1723
|
+
return this.unaryIntrinsic("ctlz.i32", "i32", I32, ", i1 false");
|
|
1724
|
+
case 0x68:
|
|
1725
|
+
return this.unaryIntrinsic("cttz.i32", "i32", I32, ", i1 false");
|
|
1726
|
+
case 0x69:
|
|
1727
|
+
return this.unaryIntrinsic("ctpop.i32", "i32", I32);
|
|
1728
|
+
case 0x6a:
|
|
1729
|
+
return this.binary("add", "i32", I32);
|
|
1730
|
+
case 0x6b:
|
|
1731
|
+
return this.binary("sub", "i32", I32);
|
|
1732
|
+
case 0x6c:
|
|
1733
|
+
return this.binary("mul", "i32", I32);
|
|
1734
|
+
case 0x6d:
|
|
1735
|
+
case 0x6e:
|
|
1736
|
+
case 0x6f:
|
|
1737
|
+
case 0x70:
|
|
1738
|
+
return this.divRem(op, "i32");
|
|
1739
|
+
case 0x71:
|
|
1740
|
+
return this.binary("and", "i32", I32);
|
|
1741
|
+
case 0x72:
|
|
1742
|
+
return this.binary("or", "i32", I32);
|
|
1743
|
+
case 0x73:
|
|
1744
|
+
return this.binary("xor", "i32", I32);
|
|
1745
|
+
case 0x74:
|
|
1746
|
+
return this.shift("shl", "i32", I32);
|
|
1747
|
+
case 0x75:
|
|
1748
|
+
return this.shift("ashr", "i32", I32);
|
|
1749
|
+
case 0x76:
|
|
1750
|
+
return this.shift("lshr", "i32", I32);
|
|
1751
|
+
case 0x77:
|
|
1752
|
+
return this.rotate("fshl", "i32", I32);
|
|
1753
|
+
case 0x78:
|
|
1754
|
+
return this.rotate("fshr", "i32", I32);
|
|
1755
|
+
case 0x79:
|
|
1756
|
+
return this.unaryIntrinsic("ctlz.i64", "i64", I64, ", i1 false");
|
|
1757
|
+
case 0x7a:
|
|
1758
|
+
return this.unaryIntrinsic("cttz.i64", "i64", I64, ", i1 false");
|
|
1759
|
+
case 0x7b:
|
|
1760
|
+
return this.unaryIntrinsic("ctpop.i64", "i64", I64);
|
|
1761
|
+
case 0x7c:
|
|
1762
|
+
return this.binary("add", "i64", I64);
|
|
1763
|
+
case 0x7d:
|
|
1764
|
+
return this.binary("sub", "i64", I64);
|
|
1765
|
+
case 0x7e:
|
|
1766
|
+
return this.binary("mul", "i64", I64);
|
|
1767
|
+
case 0x7f:
|
|
1768
|
+
case 0x80:
|
|
1769
|
+
case 0x81:
|
|
1770
|
+
case 0x82:
|
|
1771
|
+
return this.divRem(op, "i64");
|
|
1772
|
+
case 0x83:
|
|
1773
|
+
return this.binary("and", "i64", I64);
|
|
1774
|
+
case 0x84:
|
|
1775
|
+
return this.binary("or", "i64", I64);
|
|
1776
|
+
case 0x85:
|
|
1777
|
+
return this.binary("xor", "i64", I64);
|
|
1778
|
+
case 0x86:
|
|
1779
|
+
return this.shift("shl", "i64", I64);
|
|
1780
|
+
case 0x87:
|
|
1781
|
+
return this.shift("ashr", "i64", I64);
|
|
1782
|
+
case 0x88:
|
|
1783
|
+
return this.shift("lshr", "i64", I64);
|
|
1784
|
+
case 0x89:
|
|
1785
|
+
return this.rotate("fshl", "i64", I64);
|
|
1786
|
+
case 0x8a:
|
|
1787
|
+
return this.rotate("fshr", "i64", I64);
|
|
1788
|
+
case 0x8b:
|
|
1789
|
+
return this.unaryIntrinsic("fabs.f32", "float", F32);
|
|
1790
|
+
case 0x8c: {
|
|
1791
|
+
const a = this.pop();
|
|
1792
|
+
this.push(this.emit(`fneg float ${a.v}`), F32);
|
|
1793
|
+
return;
|
|
1794
|
+
}
|
|
1795
|
+
case 0x8d:
|
|
1796
|
+
return this.unaryIntrinsic("ceil.f32", "float", F32);
|
|
1797
|
+
case 0x8e:
|
|
1798
|
+
return this.unaryIntrinsic("floor.f32", "float", F32);
|
|
1799
|
+
case 0x8f:
|
|
1800
|
+
return this.unaryIntrinsic("trunc.f32", "float", F32);
|
|
1801
|
+
case 0x90:
|
|
1802
|
+
return this.unaryIntrinsic("roundeven.f32", "float", F32);
|
|
1803
|
+
case 0x91:
|
|
1804
|
+
return this.unaryIntrinsic("sqrt.f32", "float", F32);
|
|
1805
|
+
case 0x92:
|
|
1806
|
+
return this.binary("fadd", "float", F32);
|
|
1807
|
+
case 0x93:
|
|
1808
|
+
return this.binary("fsub", "float", F32);
|
|
1809
|
+
case 0x94:
|
|
1810
|
+
return this.binary("fmul", "float", F32);
|
|
1811
|
+
case 0x95:
|
|
1812
|
+
return this.binary("fdiv", "float", F32);
|
|
1813
|
+
case 0x96:
|
|
1814
|
+
return this.binaryIntrinsic("minimum.f32", "float", F32);
|
|
1815
|
+
case 0x97:
|
|
1816
|
+
return this.binaryIntrinsic("maximum.f32", "float", F32);
|
|
1817
|
+
case 0x98:
|
|
1818
|
+
return this.binaryIntrinsic("copysign.f32", "float", F32);
|
|
1819
|
+
case 0x99:
|
|
1820
|
+
return this.unaryIntrinsic("fabs.f64", "double", F64);
|
|
1821
|
+
case 0x9a: {
|
|
1822
|
+
const a = this.pop();
|
|
1823
|
+
this.push(this.emit(`fneg double ${a.v}`), F64);
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1826
|
+
case 0x9b:
|
|
1827
|
+
return this.unaryIntrinsic("ceil.f64", "double", F64);
|
|
1828
|
+
case 0x9c:
|
|
1829
|
+
return this.unaryIntrinsic("floor.f64", "double", F64);
|
|
1830
|
+
case 0x9d:
|
|
1831
|
+
return this.unaryIntrinsic("trunc.f64", "double", F64);
|
|
1832
|
+
case 0x9e:
|
|
1833
|
+
return this.unaryIntrinsic("roundeven.f64", "double", F64);
|
|
1834
|
+
case 0x9f:
|
|
1835
|
+
return this.unaryIntrinsic("sqrt.f64", "double", F64);
|
|
1836
|
+
case 0xa0:
|
|
1837
|
+
return this.binary("fadd", "double", F64);
|
|
1838
|
+
case 0xa1:
|
|
1839
|
+
return this.binary("fsub", "double", F64);
|
|
1840
|
+
case 0xa2:
|
|
1841
|
+
return this.binary("fmul", "double", F64);
|
|
1842
|
+
case 0xa3:
|
|
1843
|
+
return this.binary("fdiv", "double", F64);
|
|
1844
|
+
case 0xa4:
|
|
1845
|
+
return this.binaryIntrinsic("minimum.f64", "double", F64);
|
|
1846
|
+
case 0xa5:
|
|
1847
|
+
return this.binaryIntrinsic("maximum.f64", "double", F64);
|
|
1848
|
+
case 0xa6:
|
|
1849
|
+
return this.binaryIntrinsic("copysign.f64", "double", F64);
|
|
1850
|
+
case 0xa7:
|
|
1851
|
+
return this.convert("trunc", "i64", "i32", I32);
|
|
1852
|
+
case 0xa8:
|
|
1853
|
+
case 0xa9:
|
|
1854
|
+
case 0xaa:
|
|
1855
|
+
case 0xab:
|
|
1856
|
+
case 0xae:
|
|
1857
|
+
case 0xaf:
|
|
1858
|
+
case 0xb0:
|
|
1859
|
+
case 0xb1:
|
|
1860
|
+
return this.truncTrap(op);
|
|
1861
|
+
case 0xac:
|
|
1862
|
+
return this.convert("sext", "i32", "i64", I64);
|
|
1863
|
+
case 0xad:
|
|
1864
|
+
return this.convert("zext", "i32", "i64", I64);
|
|
1865
|
+
case 0xb2:
|
|
1866
|
+
return this.convert("sitofp", "i32", "float", F32);
|
|
1867
|
+
case 0xb3:
|
|
1868
|
+
return this.convert("uitofp", "i32", "float", F32);
|
|
1869
|
+
case 0xb4:
|
|
1870
|
+
return this.convert("sitofp", "i64", "float", F32);
|
|
1871
|
+
case 0xb5:
|
|
1872
|
+
return this.convert("uitofp", "i64", "float", F32);
|
|
1873
|
+
case 0xb6:
|
|
1874
|
+
return this.convert("fptrunc", "double", "float", F32);
|
|
1875
|
+
case 0xb7:
|
|
1876
|
+
return this.convert("sitofp", "i32", "double", F64);
|
|
1877
|
+
case 0xb8:
|
|
1878
|
+
return this.convert("uitofp", "i32", "double", F64);
|
|
1879
|
+
case 0xb9:
|
|
1880
|
+
return this.convert("sitofp", "i64", "double", F64);
|
|
1881
|
+
case 0xba:
|
|
1882
|
+
return this.convert("uitofp", "i64", "double", F64);
|
|
1883
|
+
case 0xbb:
|
|
1884
|
+
return this.convert("fpext", "float", "double", F64);
|
|
1885
|
+
case 0xbc:
|
|
1886
|
+
return this.convert("bitcast", "float", "i32", I32);
|
|
1887
|
+
case 0xbd:
|
|
1888
|
+
return this.convert("bitcast", "double", "i64", I64);
|
|
1889
|
+
case 0xbe:
|
|
1890
|
+
return this.convert("bitcast", "i32", "float", F32);
|
|
1891
|
+
case 0xbf:
|
|
1892
|
+
return this.convert("bitcast", "i64", "double", F64);
|
|
1893
|
+
case 0xc0:
|
|
1894
|
+
case 0xc1: {
|
|
1895
|
+
const a = this.pop();
|
|
1896
|
+
const n = op === 0xc0 ? "i8" : "i16";
|
|
1897
|
+
const narrow = this.emit(`trunc i32 ${a.v} to ${n}`);
|
|
1898
|
+
this.push(this.emit(`sext ${n} ${narrow} to i32`), I32);
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1901
|
+
case 0xc2:
|
|
1902
|
+
case 0xc3:
|
|
1903
|
+
case 0xc4: {
|
|
1904
|
+
const a = this.pop();
|
|
1905
|
+
const n = op === 0xc2 ? "i8" : op === 0xc3 ? "i16" : "i32";
|
|
1906
|
+
const narrow = this.emit(`trunc i64 ${a.v} to ${n}`);
|
|
1907
|
+
this.push(this.emit(`sext ${n} ${narrow} to i64`), I64);
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1910
|
+
default:
|
|
1911
|
+
throw new WasmTranslateError(`opcode 0x${op.toString(16)} is not supported`);
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
prefixed(c) {
|
|
1915
|
+
const sub = c.u32();
|
|
1916
|
+
if (sub <= 7) {
|
|
1917
|
+
// Saturating float-to-int conversions.
|
|
1918
|
+
const a = this.pop();
|
|
1919
|
+
const from = a.t === VAL_F32 ? "f32" : "f64";
|
|
1920
|
+
const fromTy = a.t === VAL_F32 ? "float" : "double";
|
|
1921
|
+
const to = sub < 4 ? "i32" : "i64";
|
|
1922
|
+
const signed = (sub & 1) === 0;
|
|
1923
|
+
this.push(this.emit(`call ${to} @llvm.${signed ? "fptosi" : "fptoui"}.sat.${to}.${from}(${fromTy} ${a.v})`), to === "i32" ? VAL_I32 : VAL_I64);
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1926
|
+
switch (sub) {
|
|
1927
|
+
case 8: {
|
|
1928
|
+
// memory.init
|
|
1929
|
+
const seg = c.u32();
|
|
1930
|
+
this.memoryIndex(c);
|
|
1931
|
+
const n = this.pop();
|
|
1932
|
+
const s = this.pop();
|
|
1933
|
+
const d = this.pop();
|
|
1934
|
+
this.add(` call void @scr_wasm_memory_init(ptr %inst, i32 ${seg}, i32 ${d.v}, i32 ${s.v}, i32 ${n.v})`);
|
|
1935
|
+
return;
|
|
1936
|
+
}
|
|
1937
|
+
case 9:
|
|
1938
|
+
this.add(` call void @scr_wasm_data_drop(ptr %inst, i32 ${c.u32()})`);
|
|
1939
|
+
return;
|
|
1940
|
+
case 10: {
|
|
1941
|
+
this.memoryIndex(c);
|
|
1942
|
+
this.memoryIndex(c);
|
|
1943
|
+
const n = this.pop();
|
|
1944
|
+
const s = this.pop();
|
|
1945
|
+
const d = this.pop();
|
|
1946
|
+
this.add(` call void @scr_wasm_memory_copy(ptr %inst, i32 ${d.v}, i32 ${s.v}, i32 ${n.v})`);
|
|
1947
|
+
return;
|
|
1948
|
+
}
|
|
1949
|
+
case 11: {
|
|
1950
|
+
this.memoryIndex(c);
|
|
1951
|
+
const n = this.pop();
|
|
1952
|
+
const v = this.pop();
|
|
1953
|
+
const d = this.pop();
|
|
1954
|
+
this.add(` call void @scr_wasm_memory_fill(ptr %inst, i32 ${d.v}, i32 ${v.v}, i32 ${n.v})`);
|
|
1955
|
+
return;
|
|
1956
|
+
}
|
|
1957
|
+
case 12: {
|
|
1958
|
+
const seg = c.u32();
|
|
1959
|
+
const t = c.u32();
|
|
1960
|
+
const n = this.pop();
|
|
1961
|
+
const s = this.pop();
|
|
1962
|
+
const d = this.pop();
|
|
1963
|
+
this.add(` call void @scr_wasm_table_init(ptr %inst, i32 ${t}, i32 ${seg}, i32 ${d.v}, i32 ${s.v}, i32 ${n.v})`);
|
|
1964
|
+
return;
|
|
1965
|
+
}
|
|
1966
|
+
case 13:
|
|
1967
|
+
this.add(` call void @scr_wasm_elem_drop(ptr %inst, i32 ${c.u32()})`);
|
|
1968
|
+
return;
|
|
1969
|
+
case 14: {
|
|
1970
|
+
const dt = c.u32();
|
|
1971
|
+
const st = c.u32();
|
|
1972
|
+
const n = this.pop();
|
|
1973
|
+
const s = this.pop();
|
|
1974
|
+
const d = this.pop();
|
|
1975
|
+
this.add(` call void @scr_wasm_table_copy(ptr %inst, i32 ${dt}, i32 ${st}, i32 ${d.v}, i32 ${s.v}, i32 ${n.v})`);
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
case 15: {
|
|
1979
|
+
const t = c.u32();
|
|
1980
|
+
const n = this.pop();
|
|
1981
|
+
const v = this.pop();
|
|
1982
|
+
this.push(this.emit(`call i32 @scr_wasm_table_grow(ptr %inst, i32 ${t}, ptr ${v.v}, i32 ${n.v})`), VAL_I32);
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
1985
|
+
case 16: {
|
|
1986
|
+
const t = c.u32();
|
|
1987
|
+
const tab = this.loadPtrSlot(this.mt.tableSlot(t));
|
|
1988
|
+
const sizePtr = this.emit(`getelementptr inbounds i8, ptr ${tab}, i64 8`);
|
|
1989
|
+
this.push(this.emit(`load i32, ptr ${sizePtr}, align 8`), VAL_I32);
|
|
1990
|
+
return;
|
|
1991
|
+
}
|
|
1992
|
+
case 17: {
|
|
1993
|
+
const t = c.u32();
|
|
1994
|
+
const n = this.pop();
|
|
1995
|
+
const v = this.pop();
|
|
1996
|
+
const d = this.pop();
|
|
1997
|
+
this.add(` call void @scr_wasm_table_fill(ptr %inst, i32 ${t}, i32 ${d.v}, ptr ${v.v}, i32 ${n.v})`);
|
|
1998
|
+
return;
|
|
1999
|
+
}
|
|
2000
|
+
default:
|
|
2001
|
+
throw new WasmTranslateError(`opcode 0xfc ${sub} is not supported`);
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
/** The functions through which the stack can grow without bound, which
|
|
2006
|
+
* check the stack pointer on entry: members of a cycle of direct calls
|
|
2007
|
+
* (including self-recursion), and functions that call through a table or
|
|
2008
|
+
* call an import (an indirect call can reach any function, and an import
|
|
2009
|
+
* can call back into an export). Every other call chain is finite, so its
|
|
2010
|
+
* depth is bounded by the module and the guard's reserve absorbs it. */
|
|
2011
|
+
export function stackCheckedFunctions(m) {
|
|
2012
|
+
const n = m.funcTypes.length;
|
|
2013
|
+
const callees = [];
|
|
2014
|
+
const checked = new Set();
|
|
2015
|
+
for (let f = 0; f < n; f++)
|
|
2016
|
+
callees.push([]);
|
|
2017
|
+
for (let i = 0; i < m.codes.length; i++) {
|
|
2018
|
+
const f = m.importedFuncs + i;
|
|
2019
|
+
const body = m.codes[i].body;
|
|
2020
|
+
const c = new WasmCursor(m.bytes, body.start);
|
|
2021
|
+
while (c.pos < body.end) {
|
|
2022
|
+
const op = c.u8();
|
|
2023
|
+
if (op === 0x10) {
|
|
2024
|
+
const callee = c.u32();
|
|
2025
|
+
if (callee < m.importedFuncs)
|
|
2026
|
+
checked.add(f);
|
|
2027
|
+
else
|
|
2028
|
+
callees[f].push(callee);
|
|
2029
|
+
}
|
|
2030
|
+
else if (op === 0x11) {
|
|
2031
|
+
c.u32();
|
|
2032
|
+
c.u32();
|
|
2033
|
+
checked.add(f);
|
|
2034
|
+
}
|
|
2035
|
+
else {
|
|
2036
|
+
skipImmediates(c, op);
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
// Tarjan's strongly connected components, iteratively.
|
|
2041
|
+
const index = new Int32Array(n).fill(-1);
|
|
2042
|
+
const low = new Int32Array(n);
|
|
2043
|
+
const onStack = new Uint8Array(n);
|
|
2044
|
+
const stack = [];
|
|
2045
|
+
let next = 0;
|
|
2046
|
+
for (let root = m.importedFuncs; root < n; root++) {
|
|
2047
|
+
if (index[root] !== -1)
|
|
2048
|
+
continue;
|
|
2049
|
+
const workNode = [root];
|
|
2050
|
+
const workEdge = [0];
|
|
2051
|
+
index[root] = low[root] = next++;
|
|
2052
|
+
stack.push(root);
|
|
2053
|
+
onStack[root] = 1;
|
|
2054
|
+
while (workNode.length > 0) {
|
|
2055
|
+
const top = workNode.length - 1;
|
|
2056
|
+
const v = workNode[top];
|
|
2057
|
+
const edges = callees[v];
|
|
2058
|
+
const e = workEdge[top];
|
|
2059
|
+
if (e < edges.length) {
|
|
2060
|
+
workEdge[top] = e + 1;
|
|
2061
|
+
const w = edges[e];
|
|
2062
|
+
if (index[w] === -1) {
|
|
2063
|
+
index[w] = low[w] = next++;
|
|
2064
|
+
stack.push(w);
|
|
2065
|
+
onStack[w] = 1;
|
|
2066
|
+
workNode.push(w);
|
|
2067
|
+
workEdge.push(0);
|
|
2068
|
+
}
|
|
2069
|
+
else if (onStack[w]) {
|
|
2070
|
+
low[v] = Math.min(low[v], index[w]);
|
|
2071
|
+
}
|
|
2072
|
+
continue;
|
|
2073
|
+
}
|
|
2074
|
+
workNode.pop();
|
|
2075
|
+
workEdge.pop();
|
|
2076
|
+
if (workNode.length > 0) {
|
|
2077
|
+
const parent = workNode[workNode.length - 1];
|
|
2078
|
+
low[parent] = Math.min(low[parent], low[v]);
|
|
2079
|
+
}
|
|
2080
|
+
if (low[v] === index[v]) {
|
|
2081
|
+
const component = [];
|
|
2082
|
+
for (;;) {
|
|
2083
|
+
const w = stack.pop();
|
|
2084
|
+
onStack[w] = 0;
|
|
2085
|
+
component.push(w);
|
|
2086
|
+
if (w === v)
|
|
2087
|
+
break;
|
|
2088
|
+
}
|
|
2089
|
+
if (component.length > 1 || edges.includes(v))
|
|
2090
|
+
for (const w of component)
|
|
2091
|
+
checked.add(w);
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
return checked;
|
|
2096
|
+
}
|
|
2097
|
+
/** A decimal double literal as LLVM's exact hexadecimal form. */
|
|
2098
|
+
function hexDouble(text) {
|
|
2099
|
+
const view = new DataView(new ArrayBuffer(8));
|
|
2100
|
+
view.setFloat64(0, Number(text));
|
|
2101
|
+
return `0x${hex8(view.getUint32(0))}${hex8(view.getUint32(4))}`.toUpperCase().replace("0X", "0x");
|
|
2102
|
+
}
|
|
2103
|
+
function hexOf(bytes) {
|
|
2104
|
+
let s = "";
|
|
2105
|
+
for (let i = 0; i < bytes.length; i++)
|
|
2106
|
+
s += bytes[i].toString(16).padStart(2, "0");
|
|
2107
|
+
return s;
|
|
2108
|
+
}
|
|
2109
|
+
/** The symbol prefix of a module's translation. */
|
|
2110
|
+
export function wasmSymbolPrefix(sha256) {
|
|
2111
|
+
return `scr_wasm_${hexOf(sha256).slice(0, 16)}`;
|
|
2112
|
+
}
|
|
2113
|
+
/** Translates a module that binary.ts validated within the translatable
|
|
2114
|
+
* feature level. Throws WasmTranslateError for constructs outside it. */
|
|
2115
|
+
export function translateWasmModule(bytes, sha256, opts) {
|
|
2116
|
+
const m = parseWasmModule(bytes);
|
|
2117
|
+
for (const t of m.tables)
|
|
2118
|
+
llType(t.elemType);
|
|
2119
|
+
const mt = new ModuleTranslator(m, wasmSymbolPrefix(sha256), opts);
|
|
2120
|
+
mt.translate();
|
|
2121
|
+
const descriptor = mt.descriptor(sha256);
|
|
2122
|
+
const decls = RUNTIME_DECLS.slice();
|
|
2123
|
+
// Initial-exec: executables and their static runtime define it, so the
|
|
2124
|
+
// check is one thread-pointer-relative load, not a TLS lookup call.
|
|
2125
|
+
if (opts.boundsChecks)
|
|
2126
|
+
decls.push("@scr_wasm_stack_limit = external thread_local(initialexec) global i64");
|
|
2127
|
+
return { decls, text: mt.text, descriptor };
|
|
2128
|
+
}
|
|
2129
|
+
//# sourceMappingURL=translate.js.map
|