@scriptc/compiler 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +682 -50
- package/ambient/scriptc.d.ts +134 -0
- package/dist/backend/cycle-analysis.d.ts +1 -1
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +13 -1
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.js +16 -5
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +6 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +41 -4
- package/dist/backend/llvm/alloc.js +138 -7
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +30 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +1 -1
- package/dist/backend/llvm/array-search.test.js +1 -1
- package/dist/backend/llvm/blocks.d.ts +8 -0
- package/dist/backend/llvm/blocks.js +43 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.js +22 -1
- package/dist/backend/llvm/blocks.test.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +15 -5
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +14 -0
- package/dist/backend/llvm/bytes-alias.js +20 -0
- package/dist/backend/llvm/bytes-alias.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +86 -0
- package/dist/backend/llvm/bytes-loop-versions.js +506 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.d.ts +1 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js +244 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.js +50 -1
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +34 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +4 -1
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +11 -0
- package/dist/backend/llvm/classes.js +71 -14
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +58 -8
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.js +1 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +5 -1
- package/dist/backend/llvm/constant-callbacks.js +55 -12
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +88 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -0
- package/dist/backend/llvm/counted-loops.js +37 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +12 -3
- package/dist/backend/llvm/dense-array-access.js +72 -14
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +59 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +51 -0
- package/dist/backend/llvm/dense-array-loops.js +162 -0
- package/dist/backend/llvm/dense-array-loops.js.map +1 -0
- package/dist/backend/llvm/dense-array-loops.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-loops.test.js +128 -0
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.d.ts +1 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js +38 -0
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +28 -4
- package/dist/backend/llvm/dyn.js +293 -178
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.d.ts +64 -0
- package/dist/backend/llvm/emit-function.js +1190 -0
- package/dist/backend/llvm/emit-function.js.map +1 -0
- package/dist/backend/llvm/emit-module.d.ts +24 -0
- package/dist/backend/llvm/emit-module.js +1535 -0
- package/dist/backend/llvm/emit-module.js.map +1 -0
- package/dist/backend/llvm/emit-statements.d.ts +58 -0
- package/dist/backend/llvm/emit-statements.js +1964 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +547 -283
- package/dist/backend/llvm/emitter.js +689 -4643
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +57 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +73 -46
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -0
- package/dist/backend/llvm/expr-bytes.js +76 -29
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +6 -2
- package/dist/backend/llvm/expr-callbacks.js +48 -11
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +71 -53
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +1 -1
- package/dist/backend/llvm/expr-containers.js +39 -15
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +16 -16
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +3 -0
- package/dist/backend/llvm/expr-dynamic.js +67 -62
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +121 -25
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +2 -2
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +32 -11
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +54 -12
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +22 -1
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-abi.test.js +2 -2
- package/dist/backend/llvm/integer-clones.test.js +3 -3
- package/dist/backend/llvm/integer-remainder.d.ts +34 -13
- package/dist/backend/llvm/integer-remainder.js +156 -22
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/intern-tables.test.js +1 -1
- package/dist/backend/llvm/jsval-encoding.d.ts +21 -0
- package/dist/backend/llvm/jsval-encoding.js +20 -0
- package/dist/backend/llvm/jsval-encoding.js.map +1 -0
- package/dist/backend/llvm/jsval.d.ts +12 -0
- package/dist/backend/llvm/jsval.js +488 -0
- package/dist/backend/llvm/jsval.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.d.ts +12 -2
- package/dist/backend/llvm/lazy-captures.js +39 -17
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +1 -1
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +14 -8
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +189 -23
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +42 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +3 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +2 -2
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +56 -22
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +90 -50
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +12 -0
- package/dist/backend/llvm/lib-shared.js +187 -6
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +46 -16
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +43 -7
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +4 -9
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +2 -2
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-extents.d.ts +19 -0
- package/dist/backend/llvm/local-extents.js +169 -0
- package/dist/backend/llvm/local-extents.js.map +1 -0
- package/dist/backend/llvm/local-extents.test.d.ts +1 -0
- package/dist/backend/llvm/local-extents.test.js +92 -0
- package/dist/backend/llvm/local-extents.test.js.map +1 -0
- package/dist/backend/llvm/local-union-storage.js +7 -7
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +2 -2
- package/dist/backend/llvm/map-entry-fusion.test.js +1 -1
- package/dist/backend/llvm/map-number-lookup.js +2 -2
- package/dist/backend/llvm/map-number-lookup.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/narrow-guards.d.ts +38 -0
- package/dist/backend/llvm/narrow-guards.js +151 -0
- package/dist/backend/llvm/narrow-guards.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +64 -6
- package/dist/backend/llvm/nullable-unions.js +103 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-unions.test.js +65 -0
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +4 -0
- package/dist/backend/llvm/publish.js +14 -2
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +1 -1
- package/dist/backend/llvm/receivers.d.ts +31 -0
- package/dist/backend/llvm/receivers.js +395 -0
- package/dist/backend/llvm/receivers.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +12 -1
- package/dist/backend/llvm/record-results.js +64 -4
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +9 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +4 -0
- package/dist/backend/llvm/reference-writes.js +142 -6
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.d.ts +1 -0
- package/dist/backend/llvm/reference-writes.test.js +88 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.d.ts +8 -0
- package/dist/backend/llvm/regex-matchers.js +33 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +23 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/regions.d.ts +1 -1
- package/dist/backend/llvm/regions.js +9 -6
- package/dist/backend/llvm/regions.js.map +1 -1
- package/dist/backend/llvm/regions.test.js +1 -1
- package/dist/backend/llvm/shapes.d.ts +66 -43
- package/dist/backend/llvm/shapes.js +280 -21
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -3
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/split-loops.js +2 -2
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +26 -6
- package/dist/backend/llvm/stack-objects.js +133 -10
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +55 -1
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +15 -14
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-slices.d.ts +25 -0
- package/dist/backend/llvm/string-slices.js +207 -1
- package/dist/backend/llvm/string-slices.js.map +1 -1
- package/dist/backend/llvm/string-slices.test.js +139 -2
- package/dist/backend/llvm/string-slices.test.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +2 -2
- package/dist/backend/llvm/thread-slots.d.ts +5 -0
- package/dist/backend/llvm/thread-slots.js +142 -0
- package/dist/backend/llvm/thread-slots.js.map +1 -0
- package/dist/backend/llvm/thread-slots.test.d.ts +1 -0
- package/dist/backend/llvm/thread-slots.test.js +110 -0
- package/dist/backend/llvm/thread-slots.test.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +7 -7
- package/dist/backend/llvm/union-repr.js +18 -2
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +17 -3
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -2
- package/dist/backend/llvm/walkers.js +51 -26
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +16 -0
- package/dist/backend/llvm/wasm-modules.js +66 -0
- package/dist/backend/llvm/wasm-modules.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +7 -0
- package/dist/backend/llvm/wrapping-sums.js +11 -3
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/mangle.d.ts +7 -0
- package/dist/backend/mangle.js +11 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +3 -0
- package/dist/backend/may-throw.js +4 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/contracts.d.ts +37 -0
- package/dist/backend/native/executable.js +192 -137
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +30 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-pack-core.d.ts +9 -1
- package/dist/backend/runtime-pack-core.js +10 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.js +1 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.d.ts +1 -0
- package/dist/backend/runtime-pack-native.test.js +31 -0
- package/dist/backend/runtime-pack-native.test.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +5 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +5 -0
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +22 -0
- package/dist/backend/stack-observations.js +382 -0
- package/dist/backend/stack-observations.js.map +1 -0
- package/dist/backend/stack-observations.test.d.ts +1 -0
- package/dist/backend/stack-observations.test.js +233 -0
- package/dist/backend/stack-observations.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +8 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/warm-cache.js +5 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/backend/young-nursery.d.ts +7 -0
- package/dist/backend/young-nursery.js +10 -0
- package/dist/backend/young-nursery.js.map +1 -0
- package/dist/cli/command.js +44 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +11 -1
- package/dist/cli/usage.js +20 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +10 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +13 -0
- package/dist/contracts/check.js +24 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +115 -0
- package/dist/contracts/int32-elements.js +1179 -0
- package/dist/contracts/int32-elements.js.map +1 -0
- package/dist/coverage/report.d.ts +16 -0
- package/dist/coverage/report.js +182 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +12 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-cache.test.js +2 -1
- package/dist/coverage/verdict-cache.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -6
- package/dist/diagnostics/diagnostic.js +29 -21
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +39 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/render.d.ts +7 -0
- package/dist/diagnostics/render.js +50 -13
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/diagnostics/render.test.d.ts +1 -0
- package/dist/diagnostics/render.test.js +49 -0
- package/dist/diagnostics/render.test.js.map +1 -0
- package/dist/executable/executable-cache.d.ts +17 -0
- package/dist/executable/executable-cache.js +13 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +7 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +6 -1
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +16 -2
- package/dist/frontend/builtin-modules.js +40 -7
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +52 -51
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/contract-types.d.ts +3 -0
- package/dist/frontend/contract-types.js +36 -7
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +5 -1
- package/dist/frontend/experimental-import.js +26 -7
- package/dist/frontend/experimental-import.js.map +1 -1
- package/dist/frontend/fork-target.js +20 -22
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +2 -1
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/function-completion.js +6 -6
- package/dist/frontend/function-completion.js.map +1 -1
- package/dist/frontend/helper-tokens.js +15 -3
- package/dist/frontend/helper-tokens.js.map +1 -1
- package/dist/frontend/helper-tokens.test.js +7 -1
- package/dist/frontend/helper-tokens.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.js +14 -17
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +3 -0
- package/dist/frontend/input-tracker.js +32 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.js +36 -32
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.js +3 -3
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +8 -3
- package/dist/frontend/lowering/array-values.js +60 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assert-instances.js +4 -4
- package/dist/frontend/lowering/assert-instances.js.map +1 -1
- package/dist/frontend/lowering/assertion-identity.d.ts +12 -0
- package/dist/frontend/lowering/assertion-identity.js +70 -0
- package/dist/frontend/lowering/assertion-identity.js.map +1 -0
- package/dist/frontend/lowering/assertion-members.d.ts +28 -0
- package/dist/frontend/lowering/assertion-members.js +185 -0
- package/dist/frontend/lowering/assertion-members.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.js +27 -20
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +63 -5
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-function-fences.d.ts +14 -0
- package/dist/frontend/lowering/builtin-function-fences.js +42 -0
- package/dist/frontend/lowering/builtin-function-fences.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.js +1 -1
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.js +53 -52
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +6 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/blob.js +8 -6
- package/dist/frontend/lowering/builtins/blob.js.map +1 -1
- package/dist/frontend/lowering/builtins/builtin-class-dyn.d.ts +23 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js +156 -0
- package/dist/frontend/lowering/builtins/builtin-class-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +16 -5
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +7 -7
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process-methods.js +310 -57
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +16 -10
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +6 -4
- package/dist/frontend/lowering/builtins/child-process.js +85 -61
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/class-values.d.ts +60 -0
- package/dist/frontend/lowering/builtins/class-values.js +226 -0
- package/dist/frontend/lowering/builtins/class-values.js.map +1 -0
- package/dist/frontend/lowering/builtins/compression.d.ts +9 -0
- package/dist/frontend/lowering/builtins/compression.js +107 -44
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.d.ts +9 -1
- package/dist/frontend/lowering/builtins/constants.js +28 -7
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +19 -0
- package/dist/frontend/lowering/builtins/crypto.js +211 -37
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +7 -1
- package/dist/frontend/lowering/builtins/dates.js +92 -16
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.d.ts +18 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +137 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -0
- package/dist/frontend/lowering/builtins/environment.js +3 -3
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +14 -10
- package/dist/frontend/lowering/builtins/errors.js +169 -3
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +128 -116
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.js +77 -77
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +3 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-streams.js +10 -11
- package/dist/frontend/lowering/builtins/fs-streams.js.map +1 -1
- package/dist/frontend/lowering/builtins/ipc.js +45 -8
- package/dist/frontend/lowering/builtins/ipc.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +232 -24
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.js +4 -4
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +71 -22
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +55 -44
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +4 -3
- package/dist/frontend/lowering/builtins/module-resolution.js +24 -23
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +13 -0
- package/dist/frontend/lowering/builtins/navigator.js +40 -0
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -0
- package/dist/frontend/lowering/builtins/net-address.d.ts +19 -0
- package/dist/frontend/lowering/builtins/net-address.js +156 -0
- package/dist/frontend/lowering/builtins/net-address.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +25 -9
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +4 -0
- package/dist/frontend/lowering/builtins/operating-system.js +25 -12
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.d.ts +12 -0
- package/dist/frontend/lowering/builtins/performance.js +259 -8
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +32 -1
- package/dist/frontend/lowering/builtins/process.js +461 -99
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +5 -1
- package/dist/frontend/lowering/builtins/promises.js +326 -43
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +37 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js +320 -0
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -0
- package/dist/frontend/lowering/builtins/properties.js +37 -1
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.js +14 -14
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +12 -2
- package/dist/frontend/lowering/builtins/readline.js +136 -39
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/receiver-types.js +3 -5
- package/dist/frontend/lowering/builtins/receiver-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +16 -14
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/runtime-constructor.d.ts +26 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js +165 -0
- package/dist/frontend/lowering/builtins/runtime-constructor.js.map +1 -0
- package/dist/frontend/lowering/builtins/strings.js +101 -12
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +41 -38
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +75 -30
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.d.ts +3 -0
- package/dist/frontend/lowering/builtins/url.js +120 -17
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/util-types.js +20 -4
- package/dist/frontend/lowering/builtins/util-types.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +11 -0
- package/dist/frontend/lowering/builtins/v8.js +105 -0
- package/dist/frontend/lowering/builtins/v8.js.map +1 -0
- package/dist/frontend/lowering/builtins/webassembly.d.ts +33 -0
- package/dist/frontend/lowering/builtins/webassembly.js +388 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -0
- package/dist/frontend/lowering/builtins/webcrypto.d.ts +20 -0
- package/dist/frontend/lowering/builtins/webcrypto.js +112 -0
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -0
- package/dist/frontend/lowering/builtins/workers.d.ts +12 -0
- package/dist/frontend/lowering/builtins/workers.js +193 -8
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +69 -14
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +19 -1
- package/dist/frontend/lowering/call-signatures.js +254 -47
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +3 -0
- package/dist/frontend/lowering/checked-promise-all.js +1 -1
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +53 -0
- package/dist/frontend/lowering/cjs-exports-object.js +528 -0
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +86 -0
- package/dist/frontend/lowering/cjs-inline-require.js +314 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -0
- package/dist/frontend/lowering/cjs-tsc-interop.d.ts +28 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js +208 -0
- package/dist/frontend/lowering/cjs-tsc-interop.js.map +1 -0
- package/dist/frontend/lowering/class-attributes.d.ts +19 -0
- package/dist/frontend/lowering/class-attributes.js +378 -0
- package/dist/frontend/lowering/class-attributes.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -1
- package/dist/frontend/lowering/class-callbacks.js +21 -10
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.js +49 -4
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -0
- package/dist/frontend/lowering/class-descriptors.js +8 -8
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +64 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1115 -89
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +11 -0
- package/dist/frontend/lowering/class-iterables.js +31 -0
- package/dist/frontend/lowering/class-iterables.js.map +1 -0
- package/dist/frontend/lowering/class-method-mutations.js +73 -35
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +56 -10
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +24 -22
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +25 -44
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +6 -0
- package/dist/frontend/lowering/class-prototypes.js +80 -18
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +25 -0
- package/dist/frontend/lowering/class-to-primitive.js +261 -0
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -0
- package/dist/frontend/lowering/class-unions.d.ts +25 -0
- package/dist/frontend/lowering/class-unions.js +102 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/code-generation.d.ts +14 -0
- package/dist/frontend/lowering/code-generation.js +127 -0
- package/dist/frontend/lowering/code-generation.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +16 -2
- package/dist/frontend/lowering/coercions/function-adapters.js +145 -3
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +25 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +35 -3
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +15 -0
- package/dist/frontend/lowering/coercions/unions.js +57 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -2
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/collection-narrowing.js +2 -4
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.js +8 -8
- package/dist/frontend/lowering/construction-escapes.js.map +1 -1
- package/dist/frontend/lowering/construction-escapes.test.js +4 -4
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +61 -0
- package/dist/frontend/lowering/constructor-returns.js +477 -0
- package/dist/frontend/lowering/constructor-returns.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +9 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +266 -100
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +1 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +0 -1
- package/dist/frontend/lowering/containers/array-construction.js +51 -13
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.d.ts +6 -5
- package/dist/frontend/lowering/containers/array-from-async.js +159 -14
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +89 -77
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +1 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +161 -101
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +9 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +55 -5
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.d.ts +7 -8
- package/dist/frontend/lowering/containers/collection-grouping.js +217 -26
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +54 -25
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js +1 -1
- package/dist/frontend/lowering/containers/dynamic-receivers.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.js +2 -2
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -1
- package/dist/frontend/lowering/containers/for-of.d.ts +6 -0
- package/dist/frontend/lowering/containers/for-of.js +19 -19
- package/dist/frontend/lowering/containers/for-of.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +142 -57
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +53 -4
- package/dist/frontend/lowering/containers/iterator-helpers.js +1581 -462
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/match-row-uses.d.ts +17 -0
- package/dist/frontend/lowering/containers/match-row-uses.js +264 -0
- package/dist/frontend/lowering/containers/match-row-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +14 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +419 -30
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +4 -0
- package/dist/frontend/lowering/cycle-initialization.js +39 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +47 -43
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +1 -1
- package/dist/frontend/lowering/devirtualize.js +27 -7
- package/dist/frontend/lowering/devirtualize.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +0 -5
- package/dist/frontend/lowering/divergences.js +62 -125
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dyn-streams.d.ts +25 -0
- package/dist/frontend/lowering/dyn-streams.js +257 -0
- package/dist/frontend/lowering/dyn-streams.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +19 -0
- package/dist/frontend/lowering/error-name-order.js +93 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +21 -0
- package/dist/frontend/lowering/expressions/array-literals.js +703 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.d.ts +35 -0
- package/dist/frontend/lowering/expressions/binary.js +2483 -0
- package/dist/frontend/lowering/expressions/binary.js.map +1 -0
- package/dist/frontend/lowering/expressions/element-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/element-access.js +1797 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +38 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +160 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/identifiers.d.ts +4 -0
- package/dist/frontend/lowering/expressions/identifiers.js +830 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +40 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +226 -0
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.d.ts +37 -0
- package/dist/frontend/lowering/expressions/narrowing.js +1322 -0
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +4 -4
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +45 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +253 -85
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +2 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +91 -14
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +110 -0
- package/dist/frontend/lowering/expressions/property-access.js +3544 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -0
- package/dist/frontend/lowering/expressions/relational.d.ts +28 -0
- package/dist/frontend/lowering/expressions/relational.js +1679 -0
- package/dist/frontend/lowering/expressions/relational.js.map +1 -0
- package/dist/frontend/lowering/expressions/typeof.d.ts +22 -0
- package/dist/frontend/lowering/expressions/typeof.js +538 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -0
- package/dist/frontend/lowering/expressions/union-fields.js +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.d.ts +21 -0
- package/dist/frontend/lowering/expressions/updates.js +780 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +11 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +52 -28
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.d.ts +25 -0
- package/dist/frontend/lowering/general-streams.js +108 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +7 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +172 -69
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +39 -0
- package/dist/frontend/lowering/generic-functions.js +393 -75
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/import-meta.js +2 -2
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +10 -9
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +19 -0
- package/dist/frontend/lowering/iterator-adapters.js +331 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +28 -0
- package/dist/frontend/lowering/js-class-fields.js +170 -0
- package/dist/frontend/lowering/js-class-fields.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.d.ts +15 -0
- package/dist/frontend/lowering/js-dynamic-objects.js +299 -0
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.d.ts +1 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js +35 -0
- package/dist/frontend/lowering/js-dynamic-objects.test.js.map +1 -0
- package/dist/frontend/lowering/json-require.d.ts +22 -0
- package/dist/frontend/lowering/json-require.js +131 -0
- package/dist/frontend/lowering/json-require.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.d.ts +44 -0
- package/dist/frontend/lowering/key-order-witness.js +641 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.test.d.ts +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js +239 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -0
- package/dist/frontend/lowering/lifetime-regions.js +7 -7
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +61 -60
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +10 -1
- package/dist/frontend/lowering/lower-async-iteration.js +34 -6
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +5 -0
- package/dist/frontend/lowering/lower-builtin-values.js +32 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +1239 -442
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +50 -3
- package/dist/frontend/lowering/lower-classes.js +1473 -468
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +4 -2
- package/dist/frontend/lowering/lower-comptime.js +111 -13
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +13 -11
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +10 -0
- package/dist/frontend/lowering/lower-dgram.js +179 -8
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.js +113 -14
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +16 -7
- package/dist/frontend/lowering/lower-event-emitter.js +258 -70
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-event-target.js +2 -2
- package/dist/frontend/lowering/lower-event-target.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +17 -13
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +188 -186
- package/dist/frontend/lowering/lower-exprs.js +1481 -12489
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +68 -22
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -0
- package/dist/frontend/lowering/lower-generators.js +29 -16
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +5 -1
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +331 -96
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +23 -20
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.d.ts +8 -1
- package/dist/frontend/lowering/lower-mock.js +185 -18
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +267 -61
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +6 -0
- package/dist/frontend/lowering/lower-namespaces.js +45 -33
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +16 -0
- package/dist/frontend/lowering/lower-node-module.js +147 -14
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +6 -6
- package/dist/frontend/lowering/lower-server.js +488 -100
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +151 -109
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +28 -2
- package/dist/frontend/lowering/lower-stmts.js +1541 -391
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +398 -56
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +3 -0
- package/dist/frontend/lowering/lower-test.js +437 -62
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +80 -32
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +1 -1
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +399 -26
- package/dist/frontend/lowering/lowerer.js +1910 -305
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +10 -4
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +46 -0
- package/dist/frontend/lowering/maybe-promise.js +249 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -0
- package/dist/frontend/lowering/module-member-this.d.ts +3 -0
- package/dist/frontend/lowering/module-member-this.js +262 -0
- package/dist/frontend/lowering/module-member-this.js.map +1 -0
- package/dist/frontend/lowering/module-namespace-elements.js +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +3 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -32
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +18 -3
- package/dist/frontend/lowering/narrowing-stability.js +104 -32
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +11 -11
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.js +6 -8
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/private-brands.d.ts +46 -0
- package/dist/frontend/lowering/private-brands.js +265 -0
- package/dist/frontend/lowering/private-brands.js.map +1 -0
- package/dist/frontend/lowering/promise-executor-adapter.d.ts +11 -0
- package/dist/frontend/lowering/promise-executor-adapter.js +87 -0
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -0
- package/dist/frontend/lowering/require-initialization.d.ts +32 -0
- package/dist/frontend/lowering/require-initialization.js +246 -0
- package/dist/frontend/lowering/require-initialization.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +7 -7
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +12 -12
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.js +10 -10
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-ownership.js +10 -9
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -2
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +35 -0
- package/dist/frontend/lowering/runtime-optional-records.js +205 -32
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js +19 -1
- package/dist/frontend/lowering/runtime-optional-records.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +4 -4
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/static-function-names.d.ts +28 -0
- package/dist/frontend/lowering/static-function-names.js +212 -0
- package/dist/frontend/lowering/static-function-names.js.map +1 -0
- package/dist/frontend/lowering/static-this.js +6 -6
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/strict-mode.d.ts +5 -0
- package/dist/frontend/lowering/strict-mode.js +31 -0
- package/dist/frontend/lowering/strict-mode.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.js +10 -10
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +12 -0
- package/dist/frontend/lowering/string-index.js +72 -1
- package/dist/frontend/lowering/string-index.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +12 -3
- package/dist/frontend/lowering/surfaces.js +252 -41
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +204 -36
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/symbol-methods.d.ts +2 -1
- package/dist/frontend/lowering/symbol-methods.js +24 -6
- package/dist/frontend/lowering/symbol-methods.js.map +1 -1
- package/dist/frontend/lowering/thread-slots.d.ts +13 -0
- package/dist/frontend/lowering/thread-slots.js +208 -0
- package/dist/frontend/lowering/thread-slots.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +74 -0
- package/dist/frontend/lowering/typed-arguments.js +472 -0
- package/dist/frontend/lowering/typed-arguments.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +8 -0
- package/dist/frontend/lowering/union-retag.js +27 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +24 -1
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +6 -6
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +4 -0
- package/dist/frontend/mock-shapes.js +13 -6
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/module-source-candidates.js +1 -1
- package/dist/frontend/module-source-candidates.js.map +1 -1
- package/dist/frontend/module-source-candidates.test.js +2 -1
- package/dist/frontend/module-source-candidates.test.js.map +1 -1
- package/dist/frontend/module-syntax.js +8 -8
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.d.ts +51 -0
- package/dist/frontend/npm-static-bundled-chunks.js +810 -0
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js +287 -0
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.js +24 -23
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -1
- package/dist/frontend/npm-static-bundled-esm.d.ts +9 -0
- package/dist/frontend/npm-static-bundled-esm.js +768 -0
- package/dist/frontend/npm-static-bundled-esm.js.map +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-esm.test.js +207 -0
- package/dist/frontend/npm-static-bundled-esm.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js +186 -0
- package/dist/frontend/npm-static-cjs-exports-alias.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.d.ts +1 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js +73 -0
- package/dist/frontend/npm-static-cjs-exports-alias.test.js.map +1 -0
- package/dist/frontend/npm-static-cjs-exports-var.d.ts +2 -0
- package/dist/frontend/npm-static-cjs-exports-var.js +236 -0
- package/dist/frontend/npm-static-cjs-exports-var.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.js +102 -101
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +36 -24
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -1
- package/dist/frontend/npm-static-rewrite-host.js +14 -3
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +19 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +274 -101
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.js +7 -9
- package/dist/frontend/npm-static-subtyping.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +17 -1
- package/dist/frontend/npm-static.js +167 -16
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +22 -1
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/pipeline.js +164 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +22 -1
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -1
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +92 -2
- package/dist/frontend/program.js +1557 -255
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +76 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +36 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +49 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +20 -1
- package/dist/frontend/services.js +40 -3
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +2 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/threads-import.js +1 -1
- package/dist/frontend/threads-import.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +71 -0
- package/dist/frontend/tier-analysis.js +522 -0
- package/dist/frontend/tier-analysis.js.map +1 -0
- package/dist/frontend/ts7/api-conformance.d.ts +234 -0
- package/dist/frontend/ts7/api-conformance.js +7 -0
- package/dist/frontend/ts7/api-conformance.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.js +2 -1
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +47 -25
- package/dist/frontend/ts7/ast-node.js +64 -18
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +36 -12
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-types.d.ts +10 -3
- package/dist/frontend/ts7/ast-types.generated.d.ts +39 -39
- package/dist/frontend/ts7/ast.d.ts +1 -0
- package/dist/frontend/ts7/ast.js +3 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +23 -0
- package/dist/frontend/ts7/checker-backend.js +88 -0
- package/dist/frontend/ts7/checker-backend.js.map +1 -0
- package/dist/frontend/ts7/checker-backend.test.d.ts +1 -0
- package/dist/frontend/ts7/checker-backend.test.js +63 -0
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -0
- package/dist/frontend/ts7/checker-cache.d.ts +0 -3
- package/dist/frontend/ts7/checker-cache.js +0 -6
- package/dist/frontend/ts7/checker-cache.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +18 -11
- package/dist/frontend/ts7/checker.js +42 -55
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +10 -7
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/diagnostic.d.ts +19 -0
- package/dist/frontend/ts7/diagnostic.js +22 -0
- package/dist/frontend/ts7/diagnostic.js.map +1 -0
- package/dist/frontend/ts7/node-functions.d.ts +8 -0
- package/dist/frontend/ts7/node-functions.js +18 -0
- package/dist/frontend/ts7/node-functions.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +5 -1
- package/dist/frontend/ts7/program-host.js +12 -0
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/rpc-api.d.ts +5 -1
- package/dist/frontend/ts7/rpc-api.js +8 -1
- package/dist/frontend/ts7/rpc-api.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +13 -6
- package/dist/frontend/ts7/semantic-checker.js +26 -8
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +12 -9
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +54 -24
- package/dist/frontend/ts7/semantic-model.js +88 -16
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +4 -4
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +7 -3
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +11 -11
- package/dist/frontend/ts7/session.js +8 -5
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +9 -5
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +6 -2
- package/dist/frontend/ts7/source-parser.js +24 -3
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +38 -17
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +122 -2
- package/dist/frontend/type-mapper.js +2545 -719
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-only-imports.d.ts +28 -0
- package/dist/frontend/type-only-imports.js +122 -0
- package/dist/frontend/type-only-imports.js.map +1 -0
- package/dist/frontend/worker-target.js +8 -8
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +29 -2
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +4 -2
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +30 -0
- package/dist/ir/array-length-stability.js +236 -0
- package/dist/ir/array-length-stability.js.map +1 -0
- package/dist/ir/array-length-stability.test.d.ts +1 -0
- package/dist/ir/array-length-stability.test.js +113 -0
- package/dist/ir/array-length-stability.test.js.map +1 -0
- package/dist/ir/build.d.ts +2 -2
- package/dist/ir/build.js +1 -1
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +103 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +494 -25
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/byte-numbers.js +3 -0
- package/dist/ir/byte-numbers.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +37 -0
- package/dist/ir/callback-specialization.js +459 -0
- package/dist/ir/callback-specialization.js.map +1 -0
- package/dist/ir/callback-specialization.test.d.ts +1 -0
- package/dist/ir/callback-specialization.test.js +208 -0
- package/dist/ir/callback-specialization.test.js.map +1 -0
- package/dist/ir/capture-values.d.ts +0 -1
- package/dist/ir/capture-values.js +51 -40
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/field-values.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.test.js +9 -1
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +14 -0
- package/dist/ir/int32-slots.js +97 -14
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +1 -1
- package/dist/ir/integer-loop-facts.d.ts +2 -0
- package/dist/ir/integer-loop-facts.js +24 -3
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/integer-loops.js +39 -9
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +104 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +3 -0
- package/dist/ir/integer-ranges.js +3 -1
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +82 -1
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +6 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +221 -58
- package/dist/ir/ir.js +119 -12
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +10 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/jsval.d.ts +8 -0
- package/dist/ir/jsval.js +365 -0
- package/dist/ir/jsval.js.map +1 -0
- package/dist/ir/jsval.test.d.ts +1 -0
- package/dist/ir/jsval.test.js +239 -0
- package/dist/ir/jsval.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +148 -33
- package/dist/ir/runtime-features.js +629 -386
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/self-captures.d.ts +33 -0
- package/dist/ir/self-captures.js +245 -0
- package/dist/ir/self-captures.js.map +1 -0
- package/dist/ir/self-captures.test.d.ts +1 -0
- package/dist/ir/self-captures.test.js +135 -0
- package/dist/ir/self-captures.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +7 -4
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/tiers.d.ts +26 -0
- package/dist/ir/tiers.js +101 -0
- package/dist/ir/tiers.js.map +1 -0
- package/dist/ir/tiers.test.d.ts +1 -0
- package/dist/ir/tiers.test.js +140 -0
- package/dist/ir/tiers.test.js.map +1 -0
- package/dist/ir/traverse.js +103 -94
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/traverse.test.js +33 -30
- package/dist/ir/traverse.test.js.map +1 -1
- package/dist/ir/unshare.js +65 -3
- package/dist/ir/unshare.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +175 -68
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +26 -9
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/ir-policy.js +13 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +4 -4
- package/dist/library/library-profile.js +35 -7
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.js +13 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +5 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +2 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/prepare.js +7 -0
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +12 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +2 -0
- package/dist/native/toolchain.js +10 -1
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +39 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasm/base64.d.ts +5 -0
- package/dist/wasm/base64.js +62 -0
- package/dist/wasm/base64.js.map +1 -0
- package/dist/wasm/binary.d.ts +36 -0
- package/dist/wasm/binary.js +1976 -0
- package/dist/wasm/binary.js.map +1 -0
- package/dist/wasm/binary.test.d.ts +1 -0
- package/dist/wasm/binary.test.js +190 -0
- package/dist/wasm/binary.test.js.map +1 -0
- package/dist/wasm/discover.d.ts +38 -0
- package/dist/wasm/discover.js +377 -0
- package/dist/wasm/discover.js.map +1 -0
- package/dist/wasm/discover.test.d.ts +1 -0
- package/dist/wasm/discover.test.js +24 -0
- package/dist/wasm/discover.test.js.map +1 -0
- package/dist/wasm/module.d.ts +151 -0
- package/dist/wasm/module.js +575 -0
- package/dist/wasm/module.js.map +1 -0
- package/dist/wasm/translate.d.ts +48 -0
- package/dist/wasm/translate.js +2129 -0
- package/dist/wasm/translate.js.map +1 -0
- package/dist/wasm/translate.test.d.ts +1 -0
- package/dist/wasm/translate.test.js +207 -0
- package/dist/wasm/translate.test.js.map +1 -0
- package/package.json +21 -20
- package/surface-manifest.json +303 -19
|
@@ -0,0 +1,1535 @@
|
|
|
1
|
+
/* LlEmitter's module-level output: module parts, helper definitions, library declarations and FFI callback definitions. */
|
|
2
|
+
import { emitWasmModules } from "./wasm-modules.js";
|
|
3
|
+
import { ffiCallbackDummyLl, llStrBytes } from "./emitter.js";
|
|
4
|
+
import { mangleAsyncSpawn, mangleClassObj, mangleFnClosure, mangleFunction, mangleGlobal, mangleVtInstance, } from "../mangle.js";
|
|
5
|
+
import { RUNTIME_ERROR_CLASSES, RUNTIME_EVENT_CLASS, RUNTIME_EVENT_TARGET_CLASS, ffiCallbackType, isFfiContextParam, isRefCounted, typeKey, } from "../../ir/ir.js";
|
|
6
|
+
import { FN_ATTRS, limitInlineDynReleases, releaseSym, typedRefConstructor, vAdapters, } from "./shapes.js";
|
|
7
|
+
import { emitLlvmLayouts } from "./layouts.js";
|
|
8
|
+
import { moduleRuntimeFeatures } from "../../ir/runtime-features.js";
|
|
9
|
+
import { emitArraySearchHelpers } from "./array-search.js";
|
|
10
|
+
import { emitClassMembershipHelper } from "./classes.js";
|
|
11
|
+
import { compileRegexMatcher } from "./regex-matchers.js";
|
|
12
|
+
import { MAP_ITER_DECL, NUMBER_MAP_ENTRY_DECL, STRING_MAP_ENTRY_DECL, } from "./map-number-lookup.js";
|
|
13
|
+
import { RUNTIME_ABI_MARKER } from "../runtime-abi.js";
|
|
14
|
+
import { threadSlotsBlockDefinitions } from "./thread-slots.js";
|
|
15
|
+
import { ABSENT_FIELD_PAYLOAD, exactIndexLines, f64Lit, ffiNativeParamLl, ffiNativeReturnLl, ffiNativeTypeLl, } from "./common.js";
|
|
16
|
+
import { literalCapWord, literalCapWord32 } from "./string-key-hash.js";
|
|
17
|
+
import { hasLoneSurrogate, wtf8Bytes } from "../literals.js";
|
|
18
|
+
import { undefinedArmTag } from "../../ir/analysis.js";
|
|
19
|
+
import { NULLABLE_ABSENT, NULLABLE_NULL } from "./nullable-unions.js";
|
|
20
|
+
import { literalEqualityDefinition } from "./string-literal-equality.js";
|
|
21
|
+
import { STRING_READ_HELPERS, stringScanDecl } from "./string-reads.js";
|
|
22
|
+
import { emitLibraryIdentityLines } from "../library-identity-markers.js";
|
|
23
|
+
import { InternalCompilerError } from "../../errors.js";
|
|
24
|
+
export function emitModuleParts(emitter) {
|
|
25
|
+
// Function bodies first (the literal/unit/fn-value tables fill as they
|
|
26
|
+
// emit), then the file assembles around them — the runtime ABI’s order.
|
|
27
|
+
const fnDefs = [];
|
|
28
|
+
for (const fn of emitter.mod.functions) {
|
|
29
|
+
const def = emitter.emitFunction(fn);
|
|
30
|
+
fnDefs.push(def);
|
|
31
|
+
emitter.fnDefText.set(fn.name, def);
|
|
32
|
+
}
|
|
33
|
+
emitter.selectStacklessAsync(fnDefs);
|
|
34
|
+
const errorViews = [];
|
|
35
|
+
for (const property of ["name", "message"])
|
|
36
|
+
if (emitter.mod.functions.some((fn) => fn.name === `%error.${property}.read`)) {
|
|
37
|
+
emitter.declare(`declare void @scr_error_install_${property}_reader(ptr)`);
|
|
38
|
+
errorViews.push(` call void @scr_error_install_${property}_reader(ptr @${mangleFunction(`%error.${property}.read`)})`);
|
|
39
|
+
}
|
|
40
|
+
for (const meta of emitter.classMeta.values()) {
|
|
41
|
+
if (meta.def.runtime || meta.root.def.name !== "%Error")
|
|
42
|
+
continue;
|
|
43
|
+
const type = { kind: "object", className: meta.def.name };
|
|
44
|
+
const adapter = emitter.liveDynRefAdapter(type);
|
|
45
|
+
const rc = vAdapters(emitter.shapeHost, type);
|
|
46
|
+
const key = typeKey(type);
|
|
47
|
+
const name = `sc_error_view_${errorViews.length}`;
|
|
48
|
+
emitter.resolveThunkDefs.push(`define internal ptr @${name}(ptr %v) ${FN_ATTRS} {`, `entry:`, ` %d = call ptr ${typedRefConstructor(emitter.shapeHost, type)}(ptr %v, ptr ${rc.retain}, ptr ${rc.release}, ptr ${emitter.cstr(key)}, ${emitter.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr @${adapter.snapshot}, ptr ${adapter.commit})`, ` ret ptr %d`, `}`, ``);
|
|
49
|
+
emitter.declare(`declare void @scr_error_register_dyn(ptr, ptr)`);
|
|
50
|
+
errorViews.push(` call void @scr_error_register_dyn(ptr @${mangleVtInstance(meta.def.name)}, ptr @${name})`);
|
|
51
|
+
}
|
|
52
|
+
const layouts = emitLlvmLayouts(emitter.shapeHost, emitter.mod, emitter.classMeta, emitter.classObjs, emitter.fnByName, (t) => emitter.llType(t), emitter.nullableFields, emitter.int32Slots);
|
|
53
|
+
const shapes = layouts.records;
|
|
54
|
+
const classShapes = layouts.classes;
|
|
55
|
+
const classObjDefs = layouts.classObjects;
|
|
56
|
+
const wrappers = emitter.emitFnValueDefs();
|
|
57
|
+
const asyncDefs = emitter.emitAsyncScaffolding();
|
|
58
|
+
const ffiCallbacks = emitter.emitFfiCallbackDefs();
|
|
59
|
+
const hasNoInlineRecordClone = [...emitter.recordCloneShapes].some((shapeId) => (emitter.recordsById.get(shapeId)?.fields.length ?? 0) >= 16);
|
|
60
|
+
// Module globals, FIRST OCCURRENCE per id: a class-expression static
|
|
61
|
+
// instantiated through several mixin applications registers one global
|
|
62
|
+
// id several times (2041-mixin-values) — C's tentative definitions
|
|
63
|
+
// accept the duplicates without an error, LLVM rejects redefinition, so the
|
|
64
|
+
// storage AND the release emit once per id here.
|
|
65
|
+
const seenGlobalIds = new Set();
|
|
66
|
+
const globals = (emitter.mod.globals ?? []).filter((g) => {
|
|
67
|
+
if (seenGlobalIds.has(g.id))
|
|
68
|
+
return false;
|
|
69
|
+
seenGlobalIds.add(g.id);
|
|
70
|
+
return true;
|
|
71
|
+
});
|
|
72
|
+
// Refcounted globals release before main returns — the runtime ABI’s
|
|
73
|
+
// sc_release_globals, keeping the RC audit's live count exact. Built
|
|
74
|
+
// before the declaration table flushes (it adds the release symbols).
|
|
75
|
+
// Two spellings with distinct temp names: the normal exit and the
|
|
76
|
+
// uncaught-exception exit are separate blocks of the same function.
|
|
77
|
+
// Interned function-value closures are IMMORTAL (rc == SIZE_MAX), so
|
|
78
|
+
// an own-property table Object.defineProperties hung on one would
|
|
79
|
+
// outlive the RC audit — release it with the globals (the runtime ABI’s
|
|
80
|
+
// sc_release_globals tail). Only when the dispatch unit is even
|
|
81
|
+
// linked (defineProps is the only writer).
|
|
82
|
+
const runtimeFeatures = moduleRuntimeFeatures(emitter.mod);
|
|
83
|
+
const fnValueProps = [...emitter.fnValues];
|
|
84
|
+
if (fnValueProps.length > 0)
|
|
85
|
+
emitter.declare(`declare void @scr_box_release(ptr)`);
|
|
86
|
+
if (emitter.classObjs.size > 0)
|
|
87
|
+
emitter.declare(`declare void @scr_classobj_clear_properties(ptr)`);
|
|
88
|
+
const globalReleaseLines = (prefix) => {
|
|
89
|
+
const lines = [];
|
|
90
|
+
globals.forEach((g, i) => {
|
|
91
|
+
if (!isRefCounted(g.type))
|
|
92
|
+
return;
|
|
93
|
+
lines.push(` %${prefix}${i} = load ptr, ptr @${mangleGlobal(g.id)}`, ` call void ${releaseSym(emitter.shapeHost, g.type)}(ptr %${prefix}${i}) ; ${g.name}`);
|
|
94
|
+
});
|
|
95
|
+
fnValueProps.forEach((name, i) => {
|
|
96
|
+
// props sits at %ScrClosure field 3; release is NULL-tolerant —
|
|
97
|
+
// cleared so a second release path stays idempotent.
|
|
98
|
+
lines.push(` %${prefix}fp${i} = load ptr, ptr getelementptr inbounds (%ScrClosure, ptr @${mangleFnClosure(name)}, i64 0, i32 3)`, ` call void @scr_box_release(ptr %${prefix}fp${i}) ; ${name}.props`, ` store ptr null, ptr getelementptr inbounds (%ScrClosure, ptr @${mangleFnClosure(name)}, i64 0, i32 3)`);
|
|
99
|
+
});
|
|
100
|
+
for (const name of emitter.classObjs.keys())
|
|
101
|
+
lines.push(` call void @scr_classobj_clear_properties(ptr @${mangleClassObj(name)})`);
|
|
102
|
+
return lines;
|
|
103
|
+
};
|
|
104
|
+
// Exit listeners can read MODULE GLOBALS directly, so they must run
|
|
105
|
+
// BEFORE the global releases (the runtime ABI’s runExitListeners
|
|
106
|
+
// ordering — the atexit half becomes an idempotent no-op).
|
|
107
|
+
const usesEvents = runtimeFeatures.processEvents;
|
|
108
|
+
const usesChildProcess = runtimeFeatures.childProcess;
|
|
109
|
+
const usesFsWatch = runtimeFeatures.fsWatch;
|
|
110
|
+
// Stream-surface programs fill the loop's stream hook (the deferred
|
|
111
|
+
// next-tick emissions) and the emitter's post-registration flow kick
|
|
112
|
+
// before %main — scr_stream.c links only when the line is emitted
|
|
113
|
+
// (native/executable.ts gates on the same predicate).
|
|
114
|
+
const usesStream = runtimeFeatures.stream;
|
|
115
|
+
// Net-surface programs fill the loop's net hooks (and the netSocket
|
|
116
|
+
// handle-dispatch ops for the checked-dynamic boundary); http-surface
|
|
117
|
+
// programs additionally stamp the httpReq/httpRes ops — the C main's
|
|
118
|
+
// install lines, gated on the same predicates native/executable.ts links by.
|
|
119
|
+
const usesNet = runtimeFeatures.net;
|
|
120
|
+
const usesNetLookup = runtimeFeatures.netLookup;
|
|
121
|
+
const usesDgram = runtimeFeatures.dgram;
|
|
122
|
+
const usesHttp2 = runtimeFeatures.http2;
|
|
123
|
+
const usesHttp = runtimeFeatures.http;
|
|
124
|
+
// Fetch-referencing programs register native fetch before main.
|
|
125
|
+
// Runtime selection compiles scr_fetch.c on the same predicate.
|
|
126
|
+
const usesFetch = runtimeFeatures.fetch;
|
|
127
|
+
const snapshotsTlsCa = runtimeFeatures.tls || runtimeFeatures.tlsCa;
|
|
128
|
+
// The process verdict has the same precedence as the C reference
|
|
129
|
+
// emitter: node:test owns the final status when present; otherwise an
|
|
130
|
+
// embedded process.exitCode owns it; ordinary programs return zero.
|
|
131
|
+
const usesNodeTest = runtimeFeatures.nodeTest;
|
|
132
|
+
// Declared NOW — the extern block flushes before main assembles.
|
|
133
|
+
if (usesEvents)
|
|
134
|
+
emitter.declare(`declare void @scr_events_install()`);
|
|
135
|
+
if (usesChildProcess)
|
|
136
|
+
emitter.declare(`declare void @scr_child_dyn_install()`);
|
|
137
|
+
const childStreamBoxes = usesChildProcess &&
|
|
138
|
+
usesStream &&
|
|
139
|
+
emitter.classMeta.has("%Readable") &&
|
|
140
|
+
emitter.classMeta.has("%Writable")
|
|
141
|
+
? [
|
|
142
|
+
emitter.dyn.toDynHelper({ kind: "object", className: "%Readable" }),
|
|
143
|
+
emitter.dyn.toDynHelper({ kind: "object", className: "%Writable" }),
|
|
144
|
+
]
|
|
145
|
+
: null;
|
|
146
|
+
// worker.stdout and worker.stderr box the stream unit's Readable the
|
|
147
|
+
// same way, and worker.stdin its Writable when the program has one
|
|
148
|
+
// (scr_worker_stdio_install, scr_worker_events.c).
|
|
149
|
+
const workerStdioBox = emitter.mod.workers === true && usesStream && emitter.classMeta.has("%Readable")
|
|
150
|
+
? (childStreamBoxes?.[0] ??
|
|
151
|
+
emitter.dyn.toDynHelper({ kind: "object", className: "%Readable" }))
|
|
152
|
+
: null;
|
|
153
|
+
const workerStdinBox = emitter.mod.workers === true && usesStream && emitter.classMeta.has("%Writable")
|
|
154
|
+
? (childStreamBoxes?.[1] ??
|
|
155
|
+
emitter.dyn.toDynHelper({ kind: "object", className: "%Writable" }))
|
|
156
|
+
: null;
|
|
157
|
+
if (childStreamBoxes || workerStdioBox || workerStdinBox) {
|
|
158
|
+
emitter.declare(`@scr_stream_child_ops = external constant { ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }`);
|
|
159
|
+
}
|
|
160
|
+
if (childStreamBoxes)
|
|
161
|
+
emitter.declare(`declare void @scr_child_dyn_streams_install(ptr, ptr, ptr)`);
|
|
162
|
+
if (workerStdioBox || workerStdinBox)
|
|
163
|
+
emitter.declare(`declare void @scr_worker_stdio_install(ptr, ptr, ptr)`);
|
|
164
|
+
if (usesFsWatch)
|
|
165
|
+
emitter.declare(`declare void @scr_watch_install()`);
|
|
166
|
+
if (emitter.ffiHasForeignCallback)
|
|
167
|
+
emitter.declare(`declare void @scr_ffi_install()`);
|
|
168
|
+
if (usesStream)
|
|
169
|
+
emitter.declare(`declare void @scr_stream_install()`);
|
|
170
|
+
if (usesNetLookup)
|
|
171
|
+
emitter.declare(`declare void @scr_net_lookup_install()`);
|
|
172
|
+
if (usesNet) {
|
|
173
|
+
emitter.declare(`declare void @scr_net_install()`);
|
|
174
|
+
emitter.declare(`declare void @scr_net_dyn_install()`);
|
|
175
|
+
}
|
|
176
|
+
if (usesDgram)
|
|
177
|
+
emitter.declare(`declare void @scr_dgram_install()`);
|
|
178
|
+
if (usesHttp2)
|
|
179
|
+
emitter.declare(`declare void @scr_http2_dyn_install()`);
|
|
180
|
+
if (usesHttp)
|
|
181
|
+
emitter.declare(`declare void @scr_http_dyn_install()`);
|
|
182
|
+
if (usesFetch)
|
|
183
|
+
emitter.declare(`declare void @scr_fetch_install()`);
|
|
184
|
+
if (usesNodeTest) {
|
|
185
|
+
emitter.declare(`declare i32 @scr_test_exit_code()`);
|
|
186
|
+
emitter.declare(`declare void @scr_test_init()`);
|
|
187
|
+
}
|
|
188
|
+
if (snapshotsTlsCa) {
|
|
189
|
+
emitter.declare(`declare void @scr_tls_ca_install()`);
|
|
190
|
+
}
|
|
191
|
+
// Inline exit listeners run when something they must beat exists:
|
|
192
|
+
// the refcounted-global releases, or the retained-FFI atexit ledger
|
|
193
|
+
// sweep (a listener may legitimately release or pump a registration,
|
|
194
|
+
// and only the inline call orders ahead of every atexit handler —
|
|
195
|
+
// the runtime ABI’s runExitListeners stance). Plain event programs
|
|
196
|
+
// with neither keep the atexit path, so their listener timing is
|
|
197
|
+
// unchanged.
|
|
198
|
+
const hasRefGlobals = globals.some((g) => isRefCounted(g.type)) || fnValueProps.length > 0;
|
|
199
|
+
const inlineExitListeners = usesEvents && (emitter.mod.workers || hasRefGlobals || emitter.ffiHasRetainedCallback);
|
|
200
|
+
emitter.declare(`declare i32 @scr_exit_code_hint_get()`);
|
|
201
|
+
if (inlineExitListeners) {
|
|
202
|
+
emitter.declare(`declare void @scr_run_exit_listeners(double)`);
|
|
203
|
+
emitter.declare(`declare i32 @scr_exit_code_hint_get()`);
|
|
204
|
+
}
|
|
205
|
+
const exitListenerLines = (prefix) => {
|
|
206
|
+
if (!inlineExitListeners)
|
|
207
|
+
return [];
|
|
208
|
+
return [
|
|
209
|
+
` %${prefix}h = call i32 @scr_exit_code_hint_get()`,
|
|
210
|
+
` %${prefix}hd = sitofp i32 %${prefix}h to double`,
|
|
211
|
+
` call void @scr_run_exit_listeners(double %${prefix}hd)`,
|
|
212
|
+
];
|
|
213
|
+
};
|
|
214
|
+
// The entry's exits release the module globals only where the thread
|
|
215
|
+
// frees its heap when its script ends (scr_exit_frees: workers, and
|
|
216
|
+
// builds that check for leaks); the main thread of other builds leaves
|
|
217
|
+
// it to the operating system.
|
|
218
|
+
const exitReleaseLines = (prefix) => {
|
|
219
|
+
const releases = globalReleaseLines(prefix);
|
|
220
|
+
if (releases.length === 0)
|
|
221
|
+
return releases;
|
|
222
|
+
emitter.declare(`declare zeroext i1 @scr_exit_frees()`);
|
|
223
|
+
return [
|
|
224
|
+
` %${prefix}.frees = call zeroext i1 @scr_exit_frees()`,
|
|
225
|
+
` br i1 %${prefix}.frees, label %${prefix}.release, label %${prefix}.kept`,
|
|
226
|
+
`${prefix}.release:`,
|
|
227
|
+
...releases,
|
|
228
|
+
` br label %${prefix}.kept`,
|
|
229
|
+
`${prefix}.kept:`,
|
|
230
|
+
];
|
|
231
|
+
};
|
|
232
|
+
const globalReleases = exitReleaseLines("g");
|
|
233
|
+
const asyncEntry = emitter.fnByName.get(emitter.mod.entry)?.async === true;
|
|
234
|
+
const entryMayThrow = emitter.mayThrow.has(emitter.mod.entry);
|
|
235
|
+
// The event loop runs when timers appeared OR any async/generator
|
|
236
|
+
// function exists (the C main's hasAsync || hasGenerators ||
|
|
237
|
+
// usesTimers gate). Generator programs run
|
|
238
|
+
// the loop too: its exit accounting notes still-suspended generator
|
|
239
|
+
// fibers as abandoned, so the RC audit downgrades exactly like the
|
|
240
|
+
// async loop-exhaustion story.
|
|
241
|
+
const runsLoop = emitter.usesTimers ||
|
|
242
|
+
emitter.ffiHasForeignCallback ||
|
|
243
|
+
emitter.mod.functions.some((f) => f.async === true || f.generator !== undefined);
|
|
244
|
+
const uncaughtReleases = entryMayThrow && !asyncEntry ? exitReleaseLines("gu") : [];
|
|
245
|
+
const loopReleasesU = runsLoop ? exitReleaseLines("gl") : [];
|
|
246
|
+
const loopReleasesR = runsLoop ? exitReleaseLines("gr") : [];
|
|
247
|
+
const topRejectReleases = asyncEntry ? exitReleaseLines("gt") : [];
|
|
248
|
+
const topPendingReleases = asyncEntry ? exitReleaseLines("gp") : [];
|
|
249
|
+
const loopReportedReleases = runsLoop ? exitReleaseLines("gq") : [];
|
|
250
|
+
// main's epilogues read the flag / the loop entry points — declared
|
|
251
|
+
// HERE, before the extern block flushes. They run once, so they keep
|
|
252
|
+
// the out-of-line scr_exc_pending call; per-call checks inline the
|
|
253
|
+
// test (pendingTestLines).
|
|
254
|
+
if (entryMayThrow || runsLoop)
|
|
255
|
+
emitter.declare(`declare zeroext i1 @scr_exc_pending()`);
|
|
256
|
+
if (runsLoop) {
|
|
257
|
+
emitter.declare(`declare zeroext i1 @scr_loop_run(ptr)`);
|
|
258
|
+
if (emitter.mod.commonJsEntry === true)
|
|
259
|
+
emitter.declare(`declare void @scr_loop_commonjs_entry()`);
|
|
260
|
+
if (emitter.readsLoopMetrics())
|
|
261
|
+
emitter.declare(`declare void @scr_perf_loop_mark()`);
|
|
262
|
+
emitter.declare(`declare zeroext i1 @scr_report_unhandled_rejections()`);
|
|
263
|
+
emitter.declare(`declare void @scr_discard_unhandled_rejections()`);
|
|
264
|
+
}
|
|
265
|
+
if (asyncEntry) {
|
|
266
|
+
emitter.declare(`declare i32 @scr_promise_finish_top_level(ptr)`);
|
|
267
|
+
emitter.declare(`declare void @scr_promise_rethrow_top_level(ptr)`);
|
|
268
|
+
emitter.declare(`declare void @scr_promise_release(ptr)`);
|
|
269
|
+
emitter.declare(`declare void @scr_exit_code_note(i32)`);
|
|
270
|
+
}
|
|
271
|
+
const topPendingExitLines = () => {
|
|
272
|
+
if (!asyncEntry)
|
|
273
|
+
return [];
|
|
274
|
+
const lines = [];
|
|
275
|
+
// finish_top_level noted 13 unless the program set process.exitCode.
|
|
276
|
+
// A failed node:test run outranks either before exit listeners run.
|
|
277
|
+
if (usesNodeTest) {
|
|
278
|
+
lines.push(` %tla_program_exit = call i32 @scr_test_exit_code()`, ` %tla_program_exit_zero = icmp eq i32 %tla_program_exit, 0`, ` %tla_hint = call i32 @scr_exit_code_hint_get()`, ` %tla_exit_status = select i1 %tla_program_exit_zero, i32 %tla_hint, i32 %tla_program_exit`, ` call void @scr_exit_code_note(i32 %tla_exit_status)`);
|
|
279
|
+
}
|
|
280
|
+
for (const line of exitListenerLines("xp"))
|
|
281
|
+
lines.push(line);
|
|
282
|
+
for (const line of topPendingReleases)
|
|
283
|
+
lines.push(line);
|
|
284
|
+
// An exit listener may set process.exitCode again, as in Node.
|
|
285
|
+
lines.push(` %tla_exit_code = call i32 @scr_exit_code_hint_get()`, ` ret i32 %tla_exit_code`);
|
|
286
|
+
return lines;
|
|
287
|
+
};
|
|
288
|
+
// LIBRARY mode: the runtime entry points the generated library
|
|
289
|
+
// symbols delegate to — declared before the extern block flushes.
|
|
290
|
+
if (emitter.mod.lib !== undefined) {
|
|
291
|
+
if (emitter.wasi) {
|
|
292
|
+
emitter.declare(`declare ptr @malloc(${emitter.sizeType})`);
|
|
293
|
+
emitter.declare(`declare void @free(ptr)`);
|
|
294
|
+
}
|
|
295
|
+
emitter.declare(`declare void @scr_library_entry(i1 zeroext, ptr)`);
|
|
296
|
+
emitter.declare(`declare void @scr_library_reset()`);
|
|
297
|
+
emitter.declare(`declare void @scr_library_check_exc()`);
|
|
298
|
+
emitter.declare(`declare void @scr_library_set_sink(ptr, ptr)`);
|
|
299
|
+
emitter.declare(`declare void @scr_library_callback_entry_guard(ptr)`);
|
|
300
|
+
emitter.declare(`declare void @scr_library_arena_reset()`);
|
|
301
|
+
emitter.declare(`declare void @scr_library_collect()`);
|
|
302
|
+
if ((emitter.mod.lib.callbacks?.length ?? 0) > 0) {
|
|
303
|
+
// Host-callback channels: the registration define's dispatch
|
|
304
|
+
// (strcmp over the declared names + the runtime slot store).
|
|
305
|
+
// The call-site fetch pair (scr_library_cb_require/_ctx) is
|
|
306
|
+
// declared at ffiCall emission like every body-driven runtime
|
|
307
|
+
// symbol.
|
|
308
|
+
emitter.declare(`declare void @scr_library_cb_set(${emitter.sizeType}, ptr, ptr)`);
|
|
309
|
+
emitter.declare(`declare i32 @strcmp(ptr, ptr)`);
|
|
310
|
+
}
|
|
311
|
+
if (emitter.mod.lib.exports.some((e) => e.params.includes("string"))) {
|
|
312
|
+
emitter.declare(`declare ptr @scr_library_str_in(ptr, ${emitter.sizeType})`);
|
|
313
|
+
}
|
|
314
|
+
if (emitter.mod.lib.exports.some((e) => e.params.includes("bytes"))) {
|
|
315
|
+
emitter.declare(`declare ptr @scr_library_bytes_in(ptr, ${emitter.sizeType}, ptr)`);
|
|
316
|
+
}
|
|
317
|
+
if (emitter.mod.lib.exports.some((e) => e.params.includes("i64"))) {
|
|
318
|
+
emitter.declare(`declare double @scr_library_i64_in(i64, ptr)`);
|
|
319
|
+
}
|
|
320
|
+
if (emitter.mod.lib.exports.some((e) => e.params.includes("u64"))) {
|
|
321
|
+
emitter.declare(`declare double @scr_library_u64_in(i64, ptr)`);
|
|
322
|
+
}
|
|
323
|
+
if (emitter.mod.lib.exports.some((e) => e.returns === "string")) {
|
|
324
|
+
emitter.declare(`declare void @scr_library_str_out(ptr, ptr, ptr)`);
|
|
325
|
+
}
|
|
326
|
+
if (emitter.mod.lib.exports.some((e) => e.returns === "bytes")) {
|
|
327
|
+
emitter.declare(`declare void @scr_library_bytes_out(ptr, ptr, ptr)`);
|
|
328
|
+
}
|
|
329
|
+
if (emitter.mod.lib.exports.some((e) => e.params.includes("cstring"))) {
|
|
330
|
+
emitter.declare(`declare ptr @scr_library_cstr_in(ptr, ptr)`);
|
|
331
|
+
}
|
|
332
|
+
if (emitter.mod.lib.exports.some((e) => e.returns === "cstring")) {
|
|
333
|
+
emitter.declare(`declare ptr @scr_library_cstr_out(ptr)`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// Helpers assemble BEFORE the declaration table flushes (they add
|
|
337
|
+
// write/abort declarations).
|
|
338
|
+
const helpers = [
|
|
339
|
+
...emitter.helperDefs(),
|
|
340
|
+
...emitArraySearchHelpers(emitter.arraySearchKinds, emitter.sizeType, (line) => emitter.declare(line)),
|
|
341
|
+
...emitClassMembershipHelper(emitter.classMeta, emitter.sizeType),
|
|
342
|
+
...(emitter.publishWalkersCache?.defs() ?? []),
|
|
343
|
+
...emitter.publishedClassNamesDefs(),
|
|
344
|
+
...(emitter.regions?.moduleDefs() ?? []),
|
|
345
|
+
];
|
|
346
|
+
if (emitter.constantNumericTables.size > 0)
|
|
347
|
+
emitter.declare(`declare double @scr_arr_get_number(ptr, double)`);
|
|
348
|
+
// Native matchers of the regex literals inside the compiled subset.
|
|
349
|
+
const regexMatchers = new Map();
|
|
350
|
+
for (const [key, re] of emitter.regexInstances) {
|
|
351
|
+
const code = compileRegexMatcher(`${re.sym}_match`, re.pattern, re.flags, emitter.sizeType, !emitter.wasi);
|
|
352
|
+
if (code === null)
|
|
353
|
+
continue;
|
|
354
|
+
regexMatchers.set(key, code);
|
|
355
|
+
for (const decl of code.decls)
|
|
356
|
+
emitter.declare(decl);
|
|
357
|
+
}
|
|
358
|
+
const out = [
|
|
359
|
+
`; Generated by scriptc (LLVM backend) from ${emitter.mod.sourceFile}. Do not edit.`,
|
|
360
|
+
``,
|
|
361
|
+
// Type shapes shared with the runtime's C ABI. ScrStr is the header
|
|
362
|
+
// prefix only (the flexible-array tail is concrete per literal);
|
|
363
|
+
// ScrLogArg is { i32 tag; 8-byte union } — i64 at offset 8 matches
|
|
364
|
+
// the C layout (4 bytes padding after the tag). ScrUnion/ScrClosure
|
|
365
|
+
// mirror scr_runtime.h field-for-field (tag reads, slot peeks, the
|
|
366
|
+
// fn pointer, and the caps[] tail all address through them).
|
|
367
|
+
`%ScrStr = type { ${emitter.sizeType}, ${emitter.sizeType}, ${emitter.sizeType} }`,
|
|
368
|
+
`%ScrLogArg = type { i32, i64 }`,
|
|
369
|
+
`%ScrVt = type { ${emitter.sizeType}, ${emitter.sizeType}, ptr }`,
|
|
370
|
+
`%ScrUnion = type { ${emitter.sizeType}, i32, ptr, ptr, ptr, i64 }`,
|
|
371
|
+
`%ScrClosure = type { ${emitter.sizeType}, ptr, ${emitter.sizeType}, ptr, i32, i32, ptr, ptr }`,
|
|
372
|
+
`%ScrFfiTable = type { ptr, ${emitter.sizeType}, ${emitter.sizeType}, ptr, i8, ptr, ptr, ${emitter.sizeType}, ${emitter.sizeType}, ${emitter.sizeType}, ptr, ptr }`,
|
|
373
|
+
`%ScrRegex = type { ${emitter.sizeType}, ptr, ptr, ptr, double, ptr, ptr, ptr }`,
|
|
374
|
+
// ScrArr mirrors scr_runtime.h field-for-field: { rc, len, cap, elem,
|
|
375
|
+
// cyc, spare, filled, ops, data, present, ext } (field numbers in
|
|
376
|
+
// SCR_ARR_FIELD), where filled bounds the hole-free prefix, ops points at the element type's constant RC descriptor
|
|
377
|
+
// (%ScrArrOps, SCR_ELEM_REF only) and ext at the out-of-line sparse,
|
|
378
|
+
// property and metadata storage (NULL until first used). Live dynamic
|
|
379
|
+
// stream commits swap its dense, presence and out-of-line storage while
|
|
380
|
+
// preserving the target object's identity.
|
|
381
|
+
`%ScrArr = type { ${emitter.sizeType}, ${emitter.sizeType}, ${emitter.sizeType}, i8, i8, i16, i32, ptr, ptr, ptr, ptr }`,
|
|
382
|
+
`%ScrArrOps = type { ptr, ptr, ptr }`,
|
|
383
|
+
// The ScrMap prefix { rc, key_kind, val_kind, traced } — the inline
|
|
384
|
+
// RC fast paths test the traced byte (shapes.ts).
|
|
385
|
+
...(emitter.rcHelpers === null ? [] : [`%ScrMapRc = type { ${emitter.sizeType}, i8, i8, i8 }`]),
|
|
386
|
+
// The complete ScrMap and its { key, val, hash } entry, read by the
|
|
387
|
+
// inline number-key lookup (sc_map_entry_f64) and the inline
|
|
388
|
+
// iteration steps (sc_map_iter_entry): field 8 is the i32 entry
|
|
389
|
+
// count, field 10 the i64 absent-key filter, entries is field 11,
|
|
390
|
+
// nbuckets and buckets fields 13 and 14, the direct index and its i32
|
|
391
|
+
// length fields 15 and 16.
|
|
392
|
+
...(emitter.decls.has(NUMBER_MAP_ENTRY_DECL) ||
|
|
393
|
+
emitter.decls.has(STRING_MAP_ENTRY_DECL) ||
|
|
394
|
+
emitter.decls.has(MAP_ITER_DECL)
|
|
395
|
+
? [
|
|
396
|
+
`%ScrMapIx = type { ${emitter.sizeType}, i8, i8, i8, i8, i32, ptr, ptr, i32, i32, i64, ptr, i32, i32, ptr, ptr, i32, i32 }`,
|
|
397
|
+
]
|
|
398
|
+
: []),
|
|
399
|
+
// String-keyed reference reads load the value slot of the entry
|
|
400
|
+
// scr_map_entry_str returns (map-number-lookup.ts).
|
|
401
|
+
...(emitter.decls.has(NUMBER_MAP_ENTRY_DECL) ||
|
|
402
|
+
emitter.decls.has(STRING_MAP_ENTRY_DECL) ||
|
|
403
|
+
emitter.decls.has(MAP_ITER_DECL)
|
|
404
|
+
? [`%ScrMapEntry = type { i64, i64, i64 }`]
|
|
405
|
+
: []),
|
|
406
|
+
// The runtime error prefix { rc, vt, name, message, code, cause } and the
|
|
407
|
+
// class-object shape { rc, pre, post, ctor, name } — field reads on
|
|
408
|
+
// builtin errors and classval loads GEP through these.
|
|
409
|
+
`%ScrError = type { ${emitter.sizeType}, ptr, ptr, ptr, ptr, ptr, i8, i8, i8, i8, i8, ptr, ptr }`,
|
|
410
|
+
`%ScrClassObj = type { ${emitter.sizeType}, ${emitter.sizeType}, ${emitter.sizeType}, ptr, ptr, ${emitter.sizeType}, ${emitter.sizeType}, ptr, ptr }`,
|
|
411
|
+
// The runtime emitter prefix { rc, vt, reg, cls } — user subclasses
|
|
412
|
+
// embed it (classes.ts), and bare-emitter GEPs address through it.
|
|
413
|
+
`%ScrEmitter = type { ${emitter.sizeType}, ptr, ptr, ptr }`,
|
|
414
|
+
// The runtime stream layout { rc, vt, reg, cls, st } — one struct
|
|
415
|
+
// for all five stream classes; stream subclasses embed it.
|
|
416
|
+
`%ScrStream = type { ${emitter.sizeType}, ptr, ptr, ptr, ptr }`,
|
|
417
|
+
// The EventTarget and Event subclass prefixes { rc, vt, state, cls }.
|
|
418
|
+
...(emitter.classMeta.has(RUNTIME_EVENT_TARGET_CLASS)
|
|
419
|
+
? [`%ScrEventTargetObj = type { ${emitter.sizeType}, ptr, ptr, ptr }`]
|
|
420
|
+
: []),
|
|
421
|
+
...(emitter.classMeta.has(RUNTIME_EVENT_CLASS)
|
|
422
|
+
? [`%ScrEventObj = type { ${emitter.sizeType}, ptr, ptr, ptr }`]
|
|
423
|
+
: []),
|
|
424
|
+
// The catch-binding snapshot box { rc, kind, f64, b, payload,
|
|
425
|
+
// retain_fn, release_fn, trace_fn } — caughtTest kind reads and
|
|
426
|
+
// caughtNarrow payload extraction GEP through it (offsets match
|
|
427
|
+
// scr_runtime.h's natural alignment: kind at 8, f64 at 16, b at 24,
|
|
428
|
+
// payload at 32).
|
|
429
|
+
`%ScrCaught = type { ${emitter.sizeType}, i32, double, i8, ptr, ptr, ptr, ptr }`,
|
|
430
|
+
// ScrBytes { rc, len, elem(i32+pad), data, backing, brands, shared }. Indexed
|
|
431
|
+
// typed-array access GEPs through this directly: the IR type already
|
|
432
|
+
// fixes elem, so the hot path needs neither a runtime kind load nor
|
|
433
|
+
// the generic scr_bytes_get/set call.
|
|
434
|
+
`%ScrBytes = type { ${emitter.sizeType}, ${emitter.sizeType}, i32, ptr, ptr, i8, i8, i8, i8, ptr }`,
|
|
435
|
+
// The capture box { rc, kind, obj_retain, obj_release, obj_trace,
|
|
436
|
+
// slot } — TDZ reads peek the payload slot (offset 40) directly.
|
|
437
|
+
`%ScrBox = type { ${emitter.sizeType}, i32, ptr, ptr, ptr, i64 }`,
|
|
438
|
+
// The stack buffer of the emitted JSON serializers { data, len, cap }.
|
|
439
|
+
`%ScrJsonBuf = type { ptr, ${emitter.sizeType}, ${emitter.sizeType}, ptr, ${emitter.sizeType}, ${emitter.sizeType} }`,
|
|
440
|
+
// The dynCheck error-path spine { parent, key, index } — the emitted
|
|
441
|
+
// builders stack-allocate one per recursion level (dyn.ts).
|
|
442
|
+
`%ScrDynPath = type { ptr, ptr, ${emitter.sizeType} }`,
|
|
443
|
+
`%ScrIslandModule = type { ptr, ptr, ${emitter.sizeType}, ${emitter.sizeType}, i32, ptr, ${emitter.sizeType}, ${emitter.sizeType} }`,
|
|
444
|
+
`%ScrIslandEdge = type { ptr, ptr, ptr, i32 }`,
|
|
445
|
+
// A generator's prefix { rc, receiver, fiber, state, out } and its
|
|
446
|
+
// value slot { kind, f64, b, payload, release_fn } (scr_async.c pins
|
|
447
|
+
// both): number and boolean yields and drives address OUT directly.
|
|
448
|
+
...(emitter.usesGenSlots
|
|
449
|
+
? [
|
|
450
|
+
`%ScrGenSlot = type { i32, double, i8, ptr, ptr }`,
|
|
451
|
+
`%ScrGenHead = type { ${emitter.sizeType}, ptr, ptr, i32, %ScrGenSlot }`,
|
|
452
|
+
]
|
|
453
|
+
: []),
|
|
454
|
+
];
|
|
455
|
+
for (const line of shapes.typeDefs)
|
|
456
|
+
out.push(line);
|
|
457
|
+
for (const line of classShapes.typeDefs)
|
|
458
|
+
out.push(line);
|
|
459
|
+
// Thread-instanced library state (abi.instance_per_thread): the
|
|
460
|
+
// program TU's mutable globals — module globals, run-once guards, the
|
|
461
|
+
// lazily-compiled regex literal caches — and the runtime globals its
|
|
462
|
+
// init stamps live in thread-local storage, matching the runtime
|
|
463
|
+
// objects compiled with -DSCR_THREAD_INSTANCES. Immutable interned
|
|
464
|
+
// data (string literals, unit arms, template arrays, vtables) stays
|
|
465
|
+
// shared.
|
|
466
|
+
const tl = emitter.mod.workers === true || emitter.mod.lib?.threadInstances === true
|
|
467
|
+
? "thread_local "
|
|
468
|
+
: "";
|
|
469
|
+
out.push(``, `@scr_error_vts = external ${tl}global [${RUNTIME_ERROR_CLASSES.size} x %ScrVt]`, `declare void @scr_init()`, `declare void @scr_lib_init(i32, ptr)`, ...(emitter.mod.workers ? [`declare void @scr_runtime_workers_v8()`] : []), ...(emitter.stackChecks?.size ? [`declare void @scr_stack_guard_init()`] : []), ...(emitter.runtimeAbiMarker && emitter.mod.lib === undefined
|
|
470
|
+
? [`declare void @${RUNTIME_ABI_MARKER}()`]
|
|
471
|
+
: []),
|
|
472
|
+
// Overrides the runtime's weak default (scr_lib.c).
|
|
473
|
+
...(emitter.detachedExit && emitter.mod.lib === undefined
|
|
474
|
+
? [`@scr_detached_exit = constant i8 1`]
|
|
475
|
+
: []));
|
|
476
|
+
for (const d of emitter.decls)
|
|
477
|
+
out.push(d);
|
|
478
|
+
out.push(``);
|
|
479
|
+
const flushedDecls = new Set(emitter.decls);
|
|
480
|
+
{
|
|
481
|
+
const tl = emitter.mod.workers === true || emitter.mod.lib?.threadInstances === true
|
|
482
|
+
? "thread_local "
|
|
483
|
+
: "";
|
|
484
|
+
out.push(...threadSlotsBlockDefinitions(emitter.threadSlotsBlocks, tl !== ""));
|
|
485
|
+
for (let site = 0; site < emitter.dynReadIcSites; site++)
|
|
486
|
+
out.push(`@sc_dyn_read_ic_${site} = internal ${tl}global { ptr, ${emitter.sizeType}, ${emitter.sizeType}, ptr } zeroinitializer`);
|
|
487
|
+
}
|
|
488
|
+
for (const table of emitter.constantNumericTables.values()) {
|
|
489
|
+
const n = table.values.length;
|
|
490
|
+
let tableTmp = 0;
|
|
491
|
+
const tableIndex = exactIndexLines("%i", String(n), "i64", () => `%ix${tableTmp++}`);
|
|
492
|
+
out.push(`@${table.symbol} = private constant [${n} x double] [${table.values.map((v) => `double ${f64Lit(v)}`).join(", ")}]`, `define internal double @${table.symbol}_get(ptr %a, double %i) alwaysinline #0 {`, `entry:`, ` %initialized = icmp ne ptr %a, null`, ...tableIndex.lines.map((line) => ` ${line}`), ` %safe = and i1 %initialized, ${tableIndex.ok}`, ` br i1 %safe, label %read, label %fallback`, `read:`, ` %slot = getelementptr inbounds [${n} x double], ptr @${table.symbol}, i64 0, i64 ${tableIndex.wide}`, ` %value = load double, ptr %slot`, ` ret double %value`, `fallback:`, ` %generic = call double @scr_arr_get_number(ptr %a, double %i)`, ` ret double %generic`, `}`, ``);
|
|
493
|
+
}
|
|
494
|
+
for (const [text, lit] of emitter.literals) {
|
|
495
|
+
// Immortal interned ScrStr: { rc = SIZE_MAX, len, cap = len, bytes\0 } —
|
|
496
|
+
// the runtime ABI’s static table, retain/release skip rc == SIZE_MAX.
|
|
497
|
+
// 64-bit (little-endian) targets split the capacity word: the high
|
|
498
|
+
// half carries the precomputed Map key hash (SCR_STR_HASH_CACHE).
|
|
499
|
+
// Bit 31 marks all-ASCII literals (SCR_STR_ASCII_BIT) on every target.
|
|
500
|
+
const capWord = emitter.sizeType === "i64"
|
|
501
|
+
? literalCapWord(wtf8Bytes(text))
|
|
502
|
+
: literalCapWord32(wtf8Bytes(text));
|
|
503
|
+
out.push(`@${lit.sym} = internal global { ${emitter.sizeType}, ${emitter.sizeType}, ${emitter.sizeType}, [${lit.len + 1} x i8] } ` +
|
|
504
|
+
`{ ${emitter.sizeType} -1, ${emitter.sizeType} ${lit.len}, ${emitter.sizeType} ${capWord}, [${lit.len + 1} x i8] c"${llStrBytes(text)}" }`);
|
|
505
|
+
}
|
|
506
|
+
if (emitter.literals.size > 0)
|
|
507
|
+
out.push(``);
|
|
508
|
+
for (const lit of emitter.bigintLiterals.values()) {
|
|
509
|
+
// Immortal ScrBigInt: { rc = SIZE_MAX, len, sign, cap, limbs } with
|
|
510
|
+
// pointer-sized little-endian limbs (scr_bigint.c); zero keeps one
|
|
511
|
+
// zero limb so limb 0 is always readable.
|
|
512
|
+
const size = emitter.sizeType;
|
|
513
|
+
const limbBits = size === "i64" ? 64n : 32n;
|
|
514
|
+
const mask = (1n << limbBits) - 1n;
|
|
515
|
+
const limbs = [];
|
|
516
|
+
for (let m = lit.value < 0n ? -lit.value : lit.value; m > 0n; m = m >> limbBits) {
|
|
517
|
+
limbs.push(`${size} ${m & mask}`);
|
|
518
|
+
}
|
|
519
|
+
const len = limbs.length;
|
|
520
|
+
if (len === 0)
|
|
521
|
+
limbs.push(`${size} 0`);
|
|
522
|
+
const sign = lit.value < 0n ? -1 : lit.value > 0n ? 1 : 0;
|
|
523
|
+
out.push(`@${lit.sym} = internal global { ${size}, ${size}, i32, i32, [${limbs.length} x ${size}] } ` +
|
|
524
|
+
`{ ${size} -1, ${size} ${len}, i32 ${sign}, i32 ${limbs.length}, [${limbs.length} x ${size}] [${limbs.join(", ")}] }`);
|
|
525
|
+
}
|
|
526
|
+
if (emitter.bigintLiterals.size > 0)
|
|
527
|
+
out.push(``);
|
|
528
|
+
for (const [key, sym] of emitter.unitInstances) {
|
|
529
|
+
// One immortal instance per unit-armed (union, tag): tag set, payload
|
|
530
|
+
// slot and RC entry points zero — retain/release/collector all skip
|
|
531
|
+
// rc == SIZE_MAX, so these never join the RC audit or a trace walk.
|
|
532
|
+
const [unionId, tag] = key.split(":");
|
|
533
|
+
out.push(`@${sym} = internal global %ScrUnion { ${emitter.sizeType} -1, i32 ${tag}, ptr null, ptr null, ptr null, i64 0 } ; ${unionId} unit arm`);
|
|
534
|
+
}
|
|
535
|
+
if (emitter.unitInstances.size > 0)
|
|
536
|
+
out.push(``);
|
|
537
|
+
for (const [unionId, sym] of emitter.retypeGuards) {
|
|
538
|
+
// Thread-local like module globals: a thread's cast caches hold only
|
|
539
|
+
// its own boxes. Never written, the flag folds to false.
|
|
540
|
+
out.push(`@${sym} = internal ${tl}global i8 0 ; ${unionId} boxes in a cast cache`);
|
|
541
|
+
}
|
|
542
|
+
if (emitter.retypeGuards.size > 0)
|
|
543
|
+
out.push(``);
|
|
544
|
+
for (const [unionId, sym] of emitter.absentInstances) {
|
|
545
|
+
// One immortal ABSENT field-slot instance per undefined-armed union:
|
|
546
|
+
// the undefined arm's tag with payload 1 (ordinary unit instances
|
|
547
|
+
// carry 0). Every tag reader sees undefined; recordHas and the
|
|
548
|
+
// field reads compare tag and payload, never the address, so the
|
|
549
|
+
// per-object copies of separately compiled units agree.
|
|
550
|
+
const tag = undefinedArmTag({ kind: "union", unionId }, emitter.unionsById);
|
|
551
|
+
out.push(`@${sym} = internal global %ScrUnion { ${emitter.sizeType} -1, i32 ${tag}, ptr null, ptr null, ptr null, i64 ${ABSENT_FIELD_PAYLOAD} } ; ${unionId} absent field`);
|
|
552
|
+
}
|
|
553
|
+
if (emitter.absentInstances.size > 0)
|
|
554
|
+
out.push(``);
|
|
555
|
+
if (emitter.needsUnionNone)
|
|
556
|
+
out.push(`@sc_union_none = internal constant %ScrUnion zeroinitializer ; NULL union dummy read by inline stores`, ``);
|
|
557
|
+
if (emitter.nullableUnions.usesNullSentinel) {
|
|
558
|
+
// `null` in every `C | null | undefined` union (NULL is undefined):
|
|
559
|
+
// one module-scope immortal object like the ABSENT sentinel.
|
|
560
|
+
const S = emitter.sizeType;
|
|
561
|
+
out.push(`${NULLABLE_NULL} = internal global { ${S}, ${S}, ${S}, ${S} } { ${S} -1, ${S} 0, ${S} 0, ${S} 0 } ; nullable null arm`, ``);
|
|
562
|
+
}
|
|
563
|
+
if (emitter.needsNullableAbsent) {
|
|
564
|
+
// The ABSENT field-slot state of every nullable-pointer union: one
|
|
565
|
+
// module-scope immortal object (rc == SIZE_MAX), distinct from NULL
|
|
566
|
+
// (undefined) and from every instance. RC entry points and the
|
|
567
|
+
// collector skip it like any immortal; field reads compare its address.
|
|
568
|
+
const S = emitter.sizeType;
|
|
569
|
+
out.push(`${NULLABLE_ABSENT} = internal global { ${S}, ${S}, ${S}, ${S} } { ${S} -1, ${S} 0, ${S} 0, ${S} 0 } ; nullable absent field`, ``);
|
|
570
|
+
}
|
|
571
|
+
for (const [key, re] of emitter.regexInstances) {
|
|
572
|
+
// One immortal ScrRegex per (pattern, flags) literal, pointing at
|
|
573
|
+
// the interned source/flags strings. The bc and translated-program
|
|
574
|
+
// slots start null (lazy compile, cached by the runtime) — a mutable
|
|
575
|
+
// global, not constant. The last slot is the build-time matcher.
|
|
576
|
+
const matcher = regexMatchers.has(key) ? `@${re.sym}_match` : "null";
|
|
577
|
+
out.push(`@${re.sym} = internal ${tl}global %ScrRegex { ${emitter.sizeType} -1, ptr ${re.src}, ptr ${re.fl}, ptr null, double 0.0, ptr null, ptr null, ptr ${matcher} } ; ${key.replace(/\n/g, "\\n")}`);
|
|
578
|
+
}
|
|
579
|
+
if (emitter.regexInstances.size > 0)
|
|
580
|
+
out.push(``);
|
|
581
|
+
for (const code of regexMatchers.values())
|
|
582
|
+
out.push(...code.lines, ``);
|
|
583
|
+
for (const [, inst] of emitter.templateStringsInstances) {
|
|
584
|
+
// One immortal ScrArr per tagged-template site: a [N x ptr] data
|
|
585
|
+
// global of interned cooked-string literals, and the ScrArr header
|
|
586
|
+
// over it (rc == SIZE_MAX, len == cap == filled, SCR_ELEM_STR = 2,
|
|
587
|
+
// no REF entry points). Every dense slot is present; reads retain
|
|
588
|
+
// immortal strings — a no-op.
|
|
589
|
+
const n = inst.slots.length;
|
|
590
|
+
const present = n === 0 ? "zeroinitializer" : `[ ${inst.slots.map(() => "i8 1").join(", ")} ]`;
|
|
591
|
+
out.push(`@${inst.sym}_data = internal constant [${n} x ptr] [ ${inst.slots.map((s) => `ptr ${s}`).join(", ")} ]`, `@${inst.sym}_present = internal constant [${n} x i8] ${present}`, `@${inst.sym} = internal global %ScrArr { ${emitter.sizeType} -1, ${emitter.sizeType} ${n}, ${emitter.sizeType} ${n}, i8 2, i8 0, i16 0, i32 ${n}, ptr null, ptr @${inst.sym}_data, ptr @${inst.sym}_present, ptr null }`);
|
|
592
|
+
}
|
|
593
|
+
if (emitter.templateStringsInstances.size > 0)
|
|
594
|
+
out.push(``);
|
|
595
|
+
for (const [text, c] of emitter.cstrs) {
|
|
596
|
+
// NUL-terminated byte-array constants for scr_jb_puts and indentation.
|
|
597
|
+
out.push(`@${c.sym} = internal constant [${c.len + 1} x i8] c"${llStrBytes(text)}"`);
|
|
598
|
+
}
|
|
599
|
+
if (emitter.cstrs.size > 0)
|
|
600
|
+
out.push(``);
|
|
601
|
+
for (const [body, sym] of emitter.mapOpsConsts) {
|
|
602
|
+
out.push(`@${sym} = internal constant { ptr, ptr, ptr, ptr, ptr, ptr, ptr } { ${body} }`);
|
|
603
|
+
}
|
|
604
|
+
if (emitter.mapOpsConsts.size > 0)
|
|
605
|
+
out.push(``);
|
|
606
|
+
for (const line of ffiCallbacks.globals)
|
|
607
|
+
out.push(line);
|
|
608
|
+
if (ffiCallbacks.globals.length > 0)
|
|
609
|
+
out.push(``);
|
|
610
|
+
for (const g of globals) {
|
|
611
|
+
const ty = emitter.llType(g.type);
|
|
612
|
+
const zero = ty === "double" ? f64Lit(0) : ty === "ptr" ? "null" : "false";
|
|
613
|
+
const debug = emitter.debug?.global(g);
|
|
614
|
+
out.push(`@${mangleGlobal(g.id)} = internal ${tl}global ${ty} ${zero}${debug ? `, !dbg ${debug}` : ""} ; ${g.name}`);
|
|
615
|
+
}
|
|
616
|
+
if (globals.length > 0)
|
|
617
|
+
out.push(``);
|
|
618
|
+
for (const line of helpers)
|
|
619
|
+
out.push(line);
|
|
620
|
+
for (const line of ffiCallbacks.defs)
|
|
621
|
+
out.push(line);
|
|
622
|
+
for (const line of shapes.defs)
|
|
623
|
+
out.push(line);
|
|
624
|
+
for (const line of classShapes.defs)
|
|
625
|
+
out.push(line);
|
|
626
|
+
for (const line of classObjDefs)
|
|
627
|
+
out.push(line);
|
|
628
|
+
for (const line of emitter.walkers.defs)
|
|
629
|
+
out.push(line);
|
|
630
|
+
for (const line of emitter.dyn.defs)
|
|
631
|
+
out.push(line);
|
|
632
|
+
for (const line of wrappers)
|
|
633
|
+
out.push(line);
|
|
634
|
+
for (const line of asyncDefs)
|
|
635
|
+
out.push(line);
|
|
636
|
+
for (const line of emitter.resolveThunkDefs)
|
|
637
|
+
out.push(line);
|
|
638
|
+
out.push(fnDefs[0] ?? "");
|
|
639
|
+
for (let i = 1; i < fnDefs.length; i++)
|
|
640
|
+
out.push("", fnDefs[i]);
|
|
641
|
+
out.push("");
|
|
642
|
+
// WebAssembly modules translated into this program, and the registry.
|
|
643
|
+
for (const line of emitWasmModules(emitter.mod, flushedDecls, emitter.wasmBoundsChecks))
|
|
644
|
+
out.push(line);
|
|
645
|
+
// main(): scr_init, the program-dependent error-vt interval stamps,
|
|
646
|
+
// scr_lib_init(argc, argv), then the entry function. An uncaught
|
|
647
|
+
// exception escaping top-level code prints and exits 1 (Node).
|
|
648
|
+
// The exception epilogue is emitted when the entry may throw.
|
|
649
|
+
const stamps = [...errorViews];
|
|
650
|
+
for (const iv of emitter.errorIntervals) {
|
|
651
|
+
const fields = [
|
|
652
|
+
[0, iv.pre],
|
|
653
|
+
[1, iv.post],
|
|
654
|
+
];
|
|
655
|
+
for (const [field, value] of fields) {
|
|
656
|
+
stamps.push(` store ${emitter.sizeType} ${value}, ptr getelementptr inbounds ([${RUNTIME_ERROR_CLASSES.size} x %ScrVt], ptr @scr_error_vts, i64 0, i64 ${iv.kind}, i32 ${field})${field === 1 ? ` ; ${iv.lib}` : ""}`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
if (emitter.emitterInterval !== null) {
|
|
660
|
+
// The runtime emitter vtable's interval (emitterVtStampLines): bare
|
|
661
|
+
// EventEmitter instances answer instanceof and dispatch dynamic
|
|
662
|
+
// teardown under THIS module's preorder numbering.
|
|
663
|
+
out.push(`@scr_emitter_vt = external ${tl}global %ScrVt`, ``);
|
|
664
|
+
stamps.push(` store ${emitter.sizeType} ${emitter.emitterInterval.pre}, ptr getelementptr inbounds (%ScrVt, ptr @scr_emitter_vt, i64 0, i32 0)`, ` store ${emitter.sizeType} ${emitter.emitterInterval.post}, ptr getelementptr inbounds (%ScrVt, ptr @scr_emitter_vt, i64 0, i32 1) ; EventEmitter`);
|
|
665
|
+
}
|
|
666
|
+
for (const iv of emitter.streamIntervals) {
|
|
667
|
+
// The runtime stream vtables' intervals (streamVtStampLines) — the
|
|
668
|
+
// emitter story: instanceof and dynamic teardown dispatch through
|
|
669
|
+
// them.
|
|
670
|
+
out.push(`@${iv.vt} = external ${tl}global %ScrVt`);
|
|
671
|
+
stamps.push(` store ${emitter.sizeType} ${iv.pre}, ptr getelementptr inbounds (%ScrVt, ptr @${iv.vt}, i64 0, i32 0)`, ` store ${emitter.sizeType} ${iv.post}, ptr getelementptr inbounds (%ScrVt, ptr @${iv.vt}, i64 0, i32 1) ; ${iv.lib}`);
|
|
672
|
+
}
|
|
673
|
+
if (emitter.streamIntervals.length > 0)
|
|
674
|
+
out.push(``);
|
|
675
|
+
if ([...emitter.literals.keys(), ...emitter.cstrs.keys()].some(hasLoneSurrogate)) {
|
|
676
|
+
// The runtime skips surrogate work until a lone surrogate may exist
|
|
677
|
+
// (scr_wtf8_any); its own producers note one, and literals do here.
|
|
678
|
+
out.push(`declare void @scr_wtf8_note()`, ``);
|
|
679
|
+
stamps.push(` call void @scr_wtf8_note()`);
|
|
680
|
+
}
|
|
681
|
+
if (emitter.errorIntervals.length > 0 && emitter.tracedShapes.has("object:%Error")) {
|
|
682
|
+
// The cycle fixpoint marked the Error hierarchy (a user subclass
|
|
683
|
+
// holds cycle-capable fields — capability is hierarchy-uniform), so
|
|
684
|
+
// the runtime's own error allocations need collector headers too.
|
|
685
|
+
// Declared inline: the extern block already flushed (LLVM is
|
|
686
|
+
// order-free, the helper-defs precedent).
|
|
687
|
+
out.push(`declare void @scr_error_set_traced()`, ``);
|
|
688
|
+
stamps.push(` call void @scr_error_set_traced()`);
|
|
689
|
+
}
|
|
690
|
+
if ((entryMayThrow || runsLoop) && emitter.mod.lib === undefined) {
|
|
691
|
+
// Declared inline: the extern block already flushed (LLVM is
|
|
692
|
+
// order-free — the scr_error_set_traced precedent). Only the
|
|
693
|
+
// printer emits here (nothing else declares it); scr_exc_pending
|
|
694
|
+
// and the loop entry points rode the Set before the flush.
|
|
695
|
+
out.push(`declare void @scr_exc_print_uncaught()`, `declare zeroext i1 @scr_exc_handle_uncaught(i1 zeroext)`, ``);
|
|
696
|
+
}
|
|
697
|
+
if (emitter.mod.lib !== undefined) {
|
|
698
|
+
// LIBRARY mode: no @main — the profile-declared external
|
|
699
|
+
// symbols specified by the library IR instead.
|
|
700
|
+
for (const line of emitter.emitLibDefs(globals, globalReleaseLines, stamps))
|
|
701
|
+
out.push(line);
|
|
702
|
+
out.push(...emitter.inlineRcTail(flushedDecls));
|
|
703
|
+
out.push(`attributes #0 = { sanitize_address }`);
|
|
704
|
+
if (emitter.usesCoroutines)
|
|
705
|
+
out.push(`attributes #1 = { sanitize_address presplitcoroutine }`);
|
|
706
|
+
if (hasNoInlineRecordClone)
|
|
707
|
+
out.push(`attributes #2 = { noinline sanitize_address }`);
|
|
708
|
+
out.push(``);
|
|
709
|
+
out.push(...emitter.fieldAliasMetadata());
|
|
710
|
+
if (emitter.debug !== null)
|
|
711
|
+
out.push(emitter.debug.render());
|
|
712
|
+
return out;
|
|
713
|
+
}
|
|
714
|
+
out.push(`define i32 @${emitter.mod.workers ? "sc_context_entry" : emitter.wasi ? "__main_argc_argv" : "main"}(i32 %argc, ptr %argv) ${FN_ATTRS} {`, `entry:`, ...(emitter.runtimeAbiMarker ? [` call void @${RUNTIME_ABI_MARKER}()`] : []), ...(emitter.mod.workers ? [` call void @scr_runtime_workers_v8()`] : []), ` call void @scr_init()`,
|
|
715
|
+
// Each context (the main thread, every worker) installs its stack
|
|
716
|
+
// guard before running compiled code that checks it.
|
|
717
|
+
...(emitter.stackChecks?.size ? [` call void @scr_stack_guard_init()`] : []), ...stamps,
|
|
718
|
+
// Event-surface programs (signal/exit listeners) fill the loop's
|
|
719
|
+
// nullable event hooks before %main — scr_events.c links only when
|
|
720
|
+
// this line is emitted (native/executable.ts gates on the same predicate).
|
|
721
|
+
...(usesEvents ? [` call void @scr_events_install()`] : []), ...(usesChildProcess ? [` call void @scr_child_dyn_install()`] : []), ...(childStreamBoxes
|
|
722
|
+
? [
|
|
723
|
+
` call void @scr_child_dyn_streams_install(ptr @scr_stream_child_ops, ptr @${childStreamBoxes[0]}, ptr @${childStreamBoxes[1]})`,
|
|
724
|
+
]
|
|
725
|
+
: []), ...(workerStdioBox || workerStdinBox
|
|
726
|
+
? [
|
|
727
|
+
` call void @scr_worker_stdio_install(ptr @scr_stream_child_ops, ptr ${workerStdioBox ? `@${workerStdioBox}` : "null"}, ptr ${workerStdinBox ? `@${workerStdinBox}` : "null"})`,
|
|
728
|
+
]
|
|
729
|
+
: []),
|
|
730
|
+
// fs.watch programs fill the loop's watch hooks the same way —
|
|
731
|
+
// scr_watch.c links only when this line is emitted.
|
|
732
|
+
...(usesFsWatch ? [` call void @scr_watch_install()`] : []), ...(emitter.ffiHasForeignCallback ? [` call void @scr_ffi_install()`] : []), ...(snapshotsTlsCa ? [` call void @scr_tls_ca_install()`] : []), ...(usesFetch ? [` call void @scr_fetch_install()`] : []), ...(usesNet ? [` call void @scr_net_install()`, ` call void @scr_net_dyn_install()`] : []), ...(usesNetLookup ? [` call void @scr_net_lookup_install()`] : []), ...(usesHttp ? [` call void @scr_http_dyn_install()`] : []), ...(usesDgram ? [` call void @scr_dgram_install()`] : []), ...(usesHttp2 ? [` call void @scr_http2_dyn_install()`] : []), ...(usesStream ? [` call void @scr_stream_install()`] : []), ` call void @scr_lib_init(i32 %argc, ptr %argv)`,
|
|
733
|
+
// node:test takes Node's --test-update-snapshots out of argv first.
|
|
734
|
+
...(usesNodeTest ? [` call void @scr_test_init()`] : []), ...(asyncEntry
|
|
735
|
+
? [` %top = call ptr @${mangleAsyncSpawn(emitter.mod.entry)}()`]
|
|
736
|
+
: [` call void @${mangleFunction(emitter.mod.entry)}()`]),
|
|
737
|
+
// Uncaught exception from top-level code: Node exits 1.
|
|
738
|
+
...(entryMayThrow && !asyncEntry
|
|
739
|
+
? [
|
|
740
|
+
` %exc = call zeroext i1 @scr_exc_pending()`,
|
|
741
|
+
` br i1 %exc, label %uncaught, label %ok`,
|
|
742
|
+
`uncaught:`,
|
|
743
|
+
` %handled = call zeroext i1 @scr_exc_handle_uncaught(i1 false)`,
|
|
744
|
+
` br i1 %handled, label %ok, label %fatal`,
|
|
745
|
+
`fatal:`,
|
|
746
|
+
` call void @scr_exc_print_uncaught()`,
|
|
747
|
+
...exitListenerLines("xu"),
|
|
748
|
+
...uncaughtReleases,
|
|
749
|
+
` %failure_code_0 = call i32 @scr_exit_code_hint_get()`,
|
|
750
|
+
` ret i32 %failure_code_0`,
|
|
751
|
+
`ok:`,
|
|
752
|
+
]
|
|
753
|
+
: []),
|
|
754
|
+
// The event loop runs to exhaustion (microtasks before timers). A
|
|
755
|
+
// throw escaping a timer callback and unhandled promise rejections
|
|
756
|
+
// both exit 1, like Node — the C main's loop block exactly.
|
|
757
|
+
...(runsLoop
|
|
758
|
+
? [
|
|
759
|
+
...(emitter.mod.commonJsEntry === true ? [` call void @scr_loop_commonjs_entry()`] : []),
|
|
760
|
+
// performance.eventLoopUtilization measures from here on.
|
|
761
|
+
...(emitter.readsLoopMetrics() ? [` call void @scr_perf_loop_mark()`] : []),
|
|
762
|
+
` %loop_rejection = call zeroext i1 @scr_loop_run(ptr ${asyncEntry ? "%top" : "null"})`,
|
|
763
|
+
` %lexc = call zeroext i1 @scr_exc_pending()`,
|
|
764
|
+
` br i1 %lexc, label %luncaught, label %lok`,
|
|
765
|
+
`luncaught:`,
|
|
766
|
+
` call void @scr_exc_print_uncaught()`,
|
|
767
|
+
...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
|
|
768
|
+
...exitListenerLines("xl"),
|
|
769
|
+
...loopReleasesU,
|
|
770
|
+
` %failure_code_1 = call i32 @scr_exit_code_hint_get()`,
|
|
771
|
+
` ret i32 %failure_code_1`,
|
|
772
|
+
`lok:`,
|
|
773
|
+
` br i1 %loop_rejection, label %lreported, label %lclean`,
|
|
774
|
+
`lreported:`,
|
|
775
|
+
` call void @scr_discard_unhandled_rejections()`,
|
|
776
|
+
...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
|
|
777
|
+
...exitListenerLines("xq"),
|
|
778
|
+
...loopReportedReleases,
|
|
779
|
+
` %failure_code_2 = call i32 @scr_exit_code_hint_get()`,
|
|
780
|
+
` ret i32 %failure_code_2`,
|
|
781
|
+
`lclean:`,
|
|
782
|
+
...(asyncEntry
|
|
783
|
+
? [
|
|
784
|
+
` %tla_status = call i32 @scr_promise_finish_top_level(ptr %top)`,
|
|
785
|
+
` %tla_rejected = icmp eq i32 %tla_status, 1`,
|
|
786
|
+
` br i1 %tla_rejected, label %tla_fail, label %tla_not_rejected`,
|
|
787
|
+
`tla_fail:`,
|
|
788
|
+
// The loop already delivered every earlier-checkpoint
|
|
789
|
+
// rejection. Drop same-checkpoint competitors before
|
|
790
|
+
// surfacing the fatal module verdict.
|
|
791
|
+
` call void @scr_discard_unhandled_rejections()`,
|
|
792
|
+
` call void @scr_promise_rethrow_top_level(ptr %top)`,
|
|
793
|
+
` call void @scr_promise_release(ptr %top)`,
|
|
794
|
+
` call void @scr_exc_print_uncaught()`,
|
|
795
|
+
...exitListenerLines("xt"),
|
|
796
|
+
...topRejectReleases,
|
|
797
|
+
` %failure_code_3 = call i32 @scr_exit_code_hint_get()`,
|
|
798
|
+
` ret i32 %failure_code_3`,
|
|
799
|
+
`tla_not_rejected:`,
|
|
800
|
+
` call void @scr_promise_release(ptr %top)`,
|
|
801
|
+
]
|
|
802
|
+
: []),
|
|
803
|
+
` %rej = call zeroext i1 @scr_report_unhandled_rejections()`,
|
|
804
|
+
` br i1 %rej, label %lrej, label %lrok`,
|
|
805
|
+
`lrej:`,
|
|
806
|
+
...exitListenerLines("xr"),
|
|
807
|
+
...loopReleasesR,
|
|
808
|
+
` %failure_code_4 = call i32 @scr_exit_code_hint_get()`,
|
|
809
|
+
` ret i32 %failure_code_4`,
|
|
810
|
+
`lrok:`,
|
|
811
|
+
...(asyncEntry
|
|
812
|
+
? [
|
|
813
|
+
` %tla_pending = icmp eq i32 %tla_status, 13`,
|
|
814
|
+
` br i1 %tla_pending, label %tla_stuck, label %tla_ok`,
|
|
815
|
+
`tla_stuck:`,
|
|
816
|
+
...topPendingExitLines(),
|
|
817
|
+
`tla_ok:`,
|
|
818
|
+
]
|
|
819
|
+
: []),
|
|
820
|
+
]
|
|
821
|
+
: []), ...exitListenerLines("xn"), ...globalReleases, ...(usesNodeTest
|
|
822
|
+
? [` %test_exit = call i32 @scr_test_exit_code()`, ` ret i32 %test_exit`]
|
|
823
|
+
: [` %native_exit = call i32 @scr_exit_code_hint_get()`, ` ret i32 %native_exit`]), `}`, ``, ...emitter.inlineRcTail(flushedDecls),
|
|
824
|
+
// sanitize_address is inert under the plain pipeline; the sanitized
|
|
825
|
+
// lane's -fsanitize=address link activates instrumentation over the
|
|
826
|
+
// emitted functions too (the runtime TUs get theirs from clang).
|
|
827
|
+
`attributes #0 = { sanitize_address }`, ...(emitter.usesCoroutines ? [`attributes #1 = { sanitize_address presplitcoroutine }`] : []), ...(hasNoInlineRecordClone ? [`attributes #2 = { noinline sanitize_address }`] : []), ``);
|
|
828
|
+
if (emitter.mod.workers) {
|
|
829
|
+
out.push(`declare void @scr_context_cleanup()`, `declare i32 @scr_worker_argc()`, `declare ptr @scr_worker_argv()`, `define i32 @sc_worker_entry(i32 %root) ${FN_ATTRS} {`, `entry:`, ` %argc = call i32 @scr_worker_argc()`, ` %argv = call ptr @scr_worker_argv()`, ` %result = call i32 @sc_context_entry(i32 %argc, ptr %argv)`, ` ret i32 %result`, `}`, `define i32 @main(i32 %argc, ptr %argv) ${FN_ATTRS} {`, `entry:`, ` %result = call i32 @sc_context_entry(i32 %argc, ptr %argv)`, ` call void @scr_context_cleanup()`, ` ret i32 %result`, `}`);
|
|
830
|
+
}
|
|
831
|
+
out.push(...emitter.fieldAliasMetadata());
|
|
832
|
+
if (emitter.debug !== null)
|
|
833
|
+
out.push(emitter.debug.render());
|
|
834
|
+
return out;
|
|
835
|
+
}
|
|
836
|
+
/** The shared abort helpers (emitted only when referenced): the OOM
|
|
837
|
+
* abort of untraced shape allocation and the invalid-union-tag abort —
|
|
838
|
+
* both print the runtime ABI’s exact message on fd 2 and abort. */
|
|
839
|
+
export function helperDefs(emitter) {
|
|
840
|
+
const defs = [];
|
|
841
|
+
const msgHelper = (fnName, msgSym, msg) => {
|
|
842
|
+
// The message routes through the runtime's trap funnel: executable
|
|
843
|
+
// builds expand to the historical bytes-on-stderr + abort; library
|
|
844
|
+
// builds route to the registered panic sink (scr_runtime.h).
|
|
845
|
+
const bytes = Buffer.byteLength(msg, "utf8");
|
|
846
|
+
emitter.declare(`declare void @scr_trap(ptr)`);
|
|
847
|
+
defs.push(`@${msgSym} = internal constant [${bytes + 1} x i8] c"${llStrBytes(msg)}"`, `define internal void @${fnName}() ${FN_ATTRS} {`, `entry:`, ` call void @scr_trap(ptr @${msgSym})`, ` unreachable`, `}`, ``);
|
|
848
|
+
};
|
|
849
|
+
if (emitter.needsOom)
|
|
850
|
+
msgHelper("sc_oom", "sc_oom_msg", "scriptc: out of memory\n");
|
|
851
|
+
if (emitter.needsBadTag) {
|
|
852
|
+
msgHelper("sc_bad_tag", "sc_bad_tag_msg", "scriptc: internal error: invalid union tag\n");
|
|
853
|
+
}
|
|
854
|
+
if (emitter.needsBadKey) {
|
|
855
|
+
// The keyed-read miss on a result type that cannot say `undefined`:
|
|
856
|
+
// trap like an array OOB read instead of corrupting a typed slot
|
|
857
|
+
// (SEMANTICS.md; the C helper's message additionally interpolates
|
|
858
|
+
// the runtime key — a trap-path debugging nicety, never reachable
|
|
859
|
+
// by a program whose behavior matches Node).
|
|
860
|
+
msgHelper("sc_bad_key", "sc_bad_key_msg", "scriptc: TypeError: record has no key (typed slot — no undefined is representable)\n");
|
|
861
|
+
}
|
|
862
|
+
if (emitter.needsRetainBox) {
|
|
863
|
+
// scr_box_retain is a static inline (increment-unless-immortal);
|
|
864
|
+
// emitted once with internal linkage, like the record retains.
|
|
865
|
+
defs.push(`define internal ptr @sc_retain_box(ptr %b) ${FN_ATTRS} {`, `entry:`, ` %rc = load ${emitter.sizeType}, ptr %b`, ` %imm = icmp eq ${emitter.sizeType} %rc, -1`, ` br i1 %imm, label %done, label %inc`, `inc:`, ` %n = add ${emitter.sizeType} %rc, 1`, ` store ${emitter.sizeType} %n, ptr %b`, ` br label %done`, `done:`, ` ret ptr %b`, `}`, ``);
|
|
866
|
+
}
|
|
867
|
+
// Number-key Map/Set lookups probe the runtime's direct index inline:
|
|
868
|
+
// while ndense is nonzero every live key is an integer below it, so an
|
|
869
|
+
// in-range integral key reads its slot (entry index + 1, 0 = absent) and
|
|
870
|
+
// any other key is absent. Maps without the index (ndense 0) hash the
|
|
871
|
+
// key in sc_map_entry_f64_hashed, which scans the entries of a small map
|
|
872
|
+
// or probes a compact bucket table as scr_map_find_f64 does, and calls
|
|
873
|
+
// the runtime lookup for a wide table. It stays out of line so that the
|
|
874
|
+
// direct-index path stays small at every call site. Both only read
|
|
875
|
+
// memory, so LLVM merges lookups of one key when nothing is stored in
|
|
876
|
+
// between (a has() followed by get(), for example).
|
|
877
|
+
if (emitter.decls.has(NUMBER_MAP_ENTRY_DECL)) {
|
|
878
|
+
const sz = emitter.sizeType;
|
|
879
|
+
let mapTmp = 0;
|
|
880
|
+
const mapIndex = exactIndexLines("%k", "%nd", sz, () => `%ix${mapTmp++}`);
|
|
881
|
+
defs.push(`define internal ptr @sc_map_entry_f64(ptr %m, double %k) ${FN_ATTRS} {`, `entry:`, ` %ndp = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 16`, ...(sz === "i64"
|
|
882
|
+
? [` %nd32 = load i32, ptr %ndp`, ` %nd = zext i32 %nd32 to i64`]
|
|
883
|
+
: [` %nd = load i32, ptr %ndp`]),
|
|
884
|
+
// A non-integral key inside the table is as absent as one outside it.
|
|
885
|
+
...mapIndex.lines.map((line) => ` ${line}`), ` br i1 ${mapIndex.ok}, label %slot, label %outside`, `slot:`, sz === "i64"
|
|
886
|
+
? ` %i = add i64 ${mapIndex.wide}, 0`
|
|
887
|
+
: ` %i = trunc i64 ${mapIndex.wide} to ${sz}`, ` %dp = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 15`, ` %dense = load ptr, ptr %dp`, ` %sp = getelementptr inbounds i32, ptr %dense, ${sz} %i`, ` %s = load i32, ptr %sp`, ` %empty = icmp eq i32 %s, 0`, ` br i1 %empty, label %miss, label %hit`, `hit:`, ` %e32 = sub i32 %s, 1`, sz === "i32" ? ` %e = add i32 %e32, 0` : ` %e = zext i32 %e32 to ${sz}`, ` %ep = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 11`, ` %entries = load ptr, ptr %ep`, ` %found = getelementptr inbounds %ScrMapEntry, ptr %entries, ${sz} %e`, ` ret ptr %found`, `miss:`, ` ret ptr null`, `outside:`, ` %dense.any = icmp ne ${sz} %nd, 0`, ` br i1 %dense.any, label %miss, label %slow`, `slow:`, ` %hashed = call ptr @sc_map_entry_f64_hashed(ptr %m, double %k)`, ` ret ptr %hashed`, `}`, ``,
|
|
888
|
+
// Hashing (scr_map_find_f64): the SameValueZero key word, its
|
|
889
|
+
// scr_key_mix hash (zero remapped to one) and the absent-key filter.
|
|
890
|
+
`define internal ptr @sc_map_entry_f64_hashed(ptr %m, double %k) noinline ${FN_ATTRS} {`, `entry:`, ` %nan = fcmp uno double %k, %k`, ` %zero = fcmp oeq double %k, 0.0`, ` %kz = select i1 %zero, double 0.0, double %k`, ` %kzb = bitcast double %kz to i64`, ` %kb = select i1 %nan, i64 9221120237041090560, i64 %kzb`, ` %x1s = lshr i64 %kb, 30`, ` %x1 = xor i64 %kb, %x1s`, ` %x2 = mul i64 %x1, -4658895280553007687`, ` %x3s = lshr i64 %x2, 27`, ` %x3 = xor i64 %x2, %x3s`, ` %x4 = mul i64 %x3, -7723592293110705685`, ` %x5s = lshr i64 %x4, 31`, ` %x5 = xor i64 %x4, %x5s`, ` %hz = icmp eq i64 %x5, 0`, ` %h = select i1 %hz, i64 1, i64 %x5`, ` %f1s = lshr i64 %h, 44`, ` %f1a = and i64 %f1s, 63`, ` %f1 = shl i64 1, %f1a`, ` %f2s = lshr i64 %h, 50`, ` %f2a = and i64 %f2s, 63`, ` %f2 = shl i64 1, %f2a`, ` %fb = or i64 %f1, %f2`, ` %fp = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 10`, ` %filter = load i64, ptr %fp`, ` %fm = and i64 %filter, %fb`, ` %fin = icmp eq i64 %fm, %fb`, ` br i1 %fin, label %table, label %miss`, `table:`, ` %nbp = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 13`, ...(sz === "i64"
|
|
891
|
+
? [` %nb32 = load i32, ptr %nbp`, ` %nb = zext i32 %nb32 to i64`]
|
|
892
|
+
: [` %nb = load i32, ptr %nbp`]), ` %eps = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 11`, ` %ents = load ptr, ptr %eps`, ` %linear = icmp eq ${sz} %nb, 0`, ` br i1 %linear, label %scan, label %buckets`,
|
|
893
|
+
// Small maps keep no bucket table: scan the cached entry hashes.
|
|
894
|
+
`scan:`, ` %nep = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 8`, ...(sz === "i64"
|
|
895
|
+
? [` %ne32 = load i32, ptr %nep`, ` %ne = zext i32 %ne32 to i64`]
|
|
896
|
+
: [` %ne = load i32, ptr %nep`]), ` br label %scan.loop`, `scan.loop:`, ` %si = phi ${sz} [ 0, %scan ], [ %si.next, %scan.next ]`, ` %sdone = icmp eq ${sz} %si, %ne`, ` br i1 %sdone, label %miss, label %scan.entry`, `scan.entry:`, ` %se = getelementptr inbounds %ScrMapEntry, ptr %ents, ${sz} %si`, ` %seh = getelementptr inbounds %ScrMapEntry, ptr %se, i32 0, i32 2`, ` %sh = load i64, ptr %seh`, ` %sk = load i64, ptr %se`, ` %shq = icmp eq i64 %sh, %h`, ` %skq = icmp eq i64 %sk, %kb`, ` %sq = and i1 %shq, %skq`, ` br i1 %sq, label %scan.found, label %scan.next`, `scan.found:`, ` ret ptr %se`, `scan.next:`, ` %si.next = add ${sz} %si, 1`, ` br label %scan.loop`,
|
|
897
|
+
// Compact tables tag each 24-bit entry index (+1) with the hash's
|
|
898
|
+
// top byte; wider tables take the runtime lookup.
|
|
899
|
+
`buckets:`, ` %wide = icmp ugt ${sz} %nb, 16777216`, ` br i1 %wide, label %runtime, label %probe`, `probe:`, ` %bp = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 14`, ` %bk = load ptr, ptr %bp`, ` %mask = sub ${sz} %nb, 1`, ` %ht = lshr i64 %h, 32`, ` %ht32 = trunc i64 %ht to i32`, ` %tag = and i32 %ht32, -16777216`, sz === "i64" ? ` %hi = add i64 %h, 0` : ` %hi = trunc i64 %h to ${sz}`, ` %i0 = and ${sz} %hi, %mask`, ` br label %probe.loop`, `probe.loop:`, ` %pi = phi ${sz} [ %i0, %probe ], [ %pi.next, %probe.next ]`, ` %bep = getelementptr inbounds i32, ptr %bk, ${sz} %pi`, ` %b = load i32, ptr %bep`, ` %bempty = icmp eq i32 %b, 0`, ` br i1 %bempty, label %miss, label %probe.tag`, `probe.tag:`, ` %bt = and i32 %b, -16777216`, ` %btq = icmp eq i32 %bt, %tag`, ` br i1 %btq, label %probe.entry, label %probe.next`, `probe.entry:`, ` %bix = and i32 %b, 16777215`, ` %bix1 = sub i32 %bix, 1`, sz === "i32" ? ` %bi = add i32 %bix1, 0` : ` %bi = zext i32 %bix1 to ${sz}`, ` %pe = getelementptr inbounds %ScrMapEntry, ptr %ents, ${sz} %bi`, ` %peh = getelementptr inbounds %ScrMapEntry, ptr %pe, i32 0, i32 2`, ` %ph = load i64, ptr %peh`, ` %pk = load i64, ptr %pe`, ` %phq = icmp eq i64 %ph, %h`, ` %pkq = icmp eq i64 %pk, %kb`, ` %pq = and i1 %phq, %pkq`, ` br i1 %pq, label %probe.found, label %probe.next`, `probe.found:`, ` ret ptr %pe`, `probe.next:`, ` %pi.inc = add ${sz} %pi, 1`, ` %pi.next = and ${sz} %pi.inc, %mask`, ` br label %probe.loop`, `miss:`, ` ret ptr null`, `runtime:`, ` %r = call ptr @scr_map_entry_f64(ptr %m, double %k) memory(read) nounwind willreturn`, ` ret ptr %r`, `}`, ``);
|
|
900
|
+
}
|
|
901
|
+
// Map/Set iteration steps read the entries array inline: an index is
|
|
902
|
+
// live when it is below the entry count and its entry's cached hash is
|
|
903
|
+
// nonzero (a tombstone's is zero), as scr_map_iter_live decides. The
|
|
904
|
+
// entry count is read again at every step, so entries appended during
|
|
905
|
+
// the iteration are visited.
|
|
906
|
+
if (emitter.decls.has(MAP_ITER_DECL)) {
|
|
907
|
+
const sz = emitter.sizeType;
|
|
908
|
+
defs.push(`define internal ptr @sc_map_iter_entry(ptr %m, double %i) ${FN_ATTRS} {`, `entry:`, ` %np = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 8`, ` %n = load i32, ptr %np`, ` %nf = uitofp i32 %n to double`, ` %lo = fcmp oge double %i, 0.0`, ` %hi = fcmp olt double %i, %nf`, ` %in = and i1 %lo, %hi`, ` br i1 %in, label %load, label %none`, `load:`, ` %ix = fptoui double %i to ${sz}`, ` %ep = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 11`, ` %entries = load ptr, ptr %ep`, ` %e = getelementptr inbounds %ScrMapEntry, ptr %entries, ${sz} %ix`, ` %hp = getelementptr inbounds %ScrMapEntry, ptr %e, i32 0, i32 2`, ` %h = load i64, ptr %hp`, ` %live = icmp ne i64 %h, 0`, ` br i1 %live, label %yes, label %none`, `yes:`, ` ret ptr %e`, `none:`, ` ret ptr null`, `}`, ``, `define internal double @sc_map_iter_count(ptr %m) ${FN_ATTRS} {`, `entry:`, ` %np = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 8`, ` %n = load i32, ptr %np`, ` %nf = uitofp i32 %n to double`, ` ret double %nf`, `}`, ``);
|
|
909
|
+
}
|
|
910
|
+
// String-key Map/Set lookups test the map's absent-key filter inline
|
|
911
|
+
// (scr_map.c scr_map_filter_bits): a key whose two filter bits are not
|
|
912
|
+
// both set is absent, so most misses on small and medium maps return
|
|
913
|
+
// without a call. On 64-bit targets the key's cached hash h is the high
|
|
914
|
+
// half of its capacity word, the runtime's widened hash is (h << 32) | h,
|
|
915
|
+
// and the filter reads its bits 44..55, which are the capacity word's
|
|
916
|
+
// own. A key without a cached hash, and every possible hit, take the
|
|
917
|
+
// runtime lookup.
|
|
918
|
+
if (emitter.decls.has(STRING_MAP_ENTRY_DECL)) {
|
|
919
|
+
defs.push(`define internal ptr @sc_map_entry_str(ptr %m, ptr %k) ${FN_ATTRS} {`, `entry:`, ...(emitter.sizeType === "i64"
|
|
920
|
+
? [
|
|
921
|
+
` %fp = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 10`,
|
|
922
|
+
` %filter = load i64, ptr %fp`,
|
|
923
|
+
` %capp = getelementptr inbounds %ScrStr, ptr %k, i32 0, i32 2`,
|
|
924
|
+
` %cap = load i64, ptr %capp`,
|
|
925
|
+
` %cached = icmp uge i64 %cap, 4294967296`,
|
|
926
|
+
` br i1 %cached, label %test, label %slow`,
|
|
927
|
+
`test:`,
|
|
928
|
+
` %s1 = lshr i64 %cap, 44`,
|
|
929
|
+
` %i1 = and i64 %s1, 63`,
|
|
930
|
+
` %b1 = shl i64 1, %i1`,
|
|
931
|
+
` %s2 = lshr i64 %cap, 50`,
|
|
932
|
+
` %i2 = and i64 %s2, 63`,
|
|
933
|
+
` %b2 = shl i64 1, %i2`,
|
|
934
|
+
` %bits = or i64 %b1, %b2`,
|
|
935
|
+
` %have = and i64 %filter, %bits`,
|
|
936
|
+
` %maybe = icmp eq i64 %have, %bits`,
|
|
937
|
+
` br i1 %maybe, label %slow, label %absent`,
|
|
938
|
+
`absent:`,
|
|
939
|
+
` ret ptr null`,
|
|
940
|
+
]
|
|
941
|
+
: [` br label %slow`]), `slow:`, ` %r = call ptr @scr_map_entry_str(ptr %m, ptr %k)`, ` ret ptr %r`, `}`, ``);
|
|
942
|
+
}
|
|
943
|
+
// String comparisons enter through small internal wrappers that LLVM
|
|
944
|
+
// inlines at each site: interned literals and shared values compare by
|
|
945
|
+
// identity, and equality rejects different byte lengths, before any
|
|
946
|
+
// runtime call (scr_str_eq/scr_str_cmp keep the complete semantics).
|
|
947
|
+
if (emitter.decls.has(`declare zeroext i1 @scr_str_eq(ptr, ptr)`)) {
|
|
948
|
+
defs.push(`define internal zeroext i1 @sc_str_eq(ptr %a, ptr %b) ${FN_ATTRS} {`, `entry:`, ` %same = icmp eq ptr %a, %b`, ` br i1 %same, label %yes, label %lengths`, `lengths:`, ` %alen.p = getelementptr inbounds %ScrStr, ptr %a, i32 0, i32 1`, ` %blen.p = getelementptr inbounds %ScrStr, ptr %b, i32 0, i32 1`, ` %alen = load ${emitter.sizeType}, ptr %alen.p`, ` %blen = load ${emitter.sizeType}, ptr %blen.p`, ` %samelen = icmp eq ${emitter.sizeType} %alen, %blen`, ` br i1 %samelen, label %bytes, label %no`, `bytes:`, ` %eq = call zeroext i1 @scr_str_eq(ptr %a, ptr %b)`, ` ret i1 %eq`, `yes:`, ` ret i1 true`, `no:`, ` ret i1 false`, `}`, ``);
|
|
949
|
+
}
|
|
950
|
+
for (const [text, name] of emitter.literalEqualities) {
|
|
951
|
+
defs.push(...literalEqualityDefinition(name, wtf8Bytes(text), emitter.internLiteral(text), emitter.sizeType, FN_ATTRS), ``);
|
|
952
|
+
}
|
|
953
|
+
// String length and charCodeAt read proven-ASCII strings inline: bit 31
|
|
954
|
+
// of the capacity word (SCR_STR_ASCII_BIT, the low half's sign bit on
|
|
955
|
+
// little-endian targets) makes UTF-16 units bytes. Unproven strings and
|
|
956
|
+
// anything but an in-range index take the runtime's UTF-16 mapping.
|
|
957
|
+
// A scan's receiver reads inline too where runtime state is ordinary
|
|
958
|
+
// global storage (ScrStrScan; SCR_TL makes it thread-local otherwise).
|
|
959
|
+
const scanInline = emitter.mod.workers !== true && emitter.mod.lib?.threadInstances !== true;
|
|
960
|
+
let scanDeclared = false;
|
|
961
|
+
for (const helper of STRING_READ_HELPERS) {
|
|
962
|
+
if (!emitter.decls.has(helper.decl))
|
|
963
|
+
continue;
|
|
964
|
+
if (scanInline && !scanDeclared) {
|
|
965
|
+
defs.push(stringScanDecl(emitter.sizeType), ``);
|
|
966
|
+
scanDeclared = true;
|
|
967
|
+
}
|
|
968
|
+
defs.push(...helper.define(emitter.sizeType, FN_ATTRS, scanInline), ``);
|
|
969
|
+
}
|
|
970
|
+
// Ordering decides inline from the first differing bytes. The bytes
|
|
971
|
+
// before them are equal, so both strings are at the same position of a
|
|
972
|
+
// character: either both bytes continue characters with the same lead
|
|
973
|
+
// byte, or both start a character. Byte order is the UTF-16 order for
|
|
974
|
+
// two continuation bytes, and for two lead bytes when one starts a
|
|
975
|
+
// character below U+D000, whose UTF-16 unit is below every unit of a
|
|
976
|
+
// character with a lead byte of at least 0xED. Between lead bytes of at
|
|
977
|
+
// least 0xED, a supplementary character (0xF0..0xF4, a high surrogate
|
|
978
|
+
// unit) orders below U+E000..U+FFFF (0xEE, 0xEF), and a lead byte of
|
|
979
|
+
// 0xED (U+D000..U+D7FF or a lone surrogate) takes the runtime.
|
|
980
|
+
// Differing words without a byte of at least 0xED decide in byte
|
|
981
|
+
// order; other differing words decide by their first differing byte,
|
|
982
|
+
// and strings shorter than a word by their first byte. Otherwise a
|
|
983
|
+
// proven-ASCII string on either side orders by bytes (scr_str_cmp), and
|
|
984
|
+
// other pairs call scr_str_cmp_u16_bytes, which only reads the two
|
|
985
|
+
// strings, so LLVM can merge repeated comparisons of one pair. Callers
|
|
986
|
+
// only test the sign of the result.
|
|
987
|
+
if (emitter.decls.has(`declare i32 @scr_str_cmp_u16(ptr, ptr)`)) {
|
|
988
|
+
const fn = "scr_str_cmp_u16";
|
|
989
|
+
emitter.declare("declare i64 @llvm.bswap.i64(i64)");
|
|
990
|
+
emitter.declare("declare i64 @llvm.cttz.i64(i64, i1 immarg)");
|
|
991
|
+
emitter.declare("declare i8 @llvm.umin.i8(i8, i8)");
|
|
992
|
+
emitter.declare("declare i32 @scr_str_cmp(ptr, ptr)");
|
|
993
|
+
emitter.declare("declare i32 @scr_str_cmp_u16_bytes(ptr, ptr)");
|
|
994
|
+
defs.push(`define internal i32 @${fn.replace(/^scr_/, "sc_")}(ptr %a, ptr %b) ${FN_ATTRS} {`, `entry:`, ` %same = icmp eq ptr %a, %b`, ` br i1 %same, label %equal, label %lengths`, `lengths:`, ` %alen.p = getelementptr inbounds %ScrStr, ptr %a, i32 0, i32 1`, ` %blen.p = getelementptr inbounds %ScrStr, ptr %b, i32 0, i32 1`, ` %alen = load ${emitter.sizeType}, ptr %alen.p`, ` %blen = load ${emitter.sizeType}, ptr %blen.p`, ` %aempty = icmp eq ${emitter.sizeType} %alen, 0`, ` %bempty = icmp eq ${emitter.sizeType} %blen, 0`, ` %empty = or i1 %aempty, %bempty`, ` br i1 %empty, label %order, label %words`,
|
|
995
|
+
// Both at least 8 bytes: the first word of each.
|
|
996
|
+
`words:`, ` %along = icmp uge ${emitter.sizeType} %alen, 8`, ` %blong = icmp uge ${emitter.sizeType} %blen, 8`, ` %long = and i1 %along, %blong`, ` br i1 %long, label %word, label %first`, `word:`, ` %awp = getelementptr inbounds %ScrStr, ptr %a, i32 1`, ` %bwp = getelementptr inbounds %ScrStr, ptr %b, i32 1`, ` %aw = load i64, ptr %awp, align 1`, ` %bw = load i64, ptr %bwp, align 1`, ` %wdiffer = icmp ne i64 %aw, %bw`, ` br i1 %wdiffer, label %differ, label %wsame`,
|
|
997
|
+
// Equal first words and one length of at most 16 bytes: the word
|
|
998
|
+
// ending at that length covers the rest, and any difference lies
|
|
999
|
+
// past the equal first word.
|
|
1000
|
+
`wsame:`, ` %samelen = icmp eq ${emitter.sizeType} %alen, %blen`, ` %short = icmp ule ${emitter.sizeType} %alen, 16`, ` %tailable = and i1 %samelen, %short`, ` br i1 %tailable, label %tail, label %order`, `tail:`, ` %toff = sub ${emitter.sizeType} %alen, 8`, ` %atp = getelementptr inbounds i8, ptr %awp, ${emitter.sizeType} %toff`, ` %btp = getelementptr inbounds i8, ptr %bwp, ${emitter.sizeType} %toff`, ` %at = load i64, ptr %atp, align 1`, ` %bt = load i64, ptr %btp, align 1`, ` %tdiffer = icmp ne i64 %at, %bt`, ` br i1 %tdiffer, label %differ, label %equal`, `first:`, ` %adata = getelementptr inbounds %ScrStr, ptr %a, i32 1`, ` %bdata = getelementptr inbounds %ScrStr, ptr %b, i32 1`, ` %x = load i8, ptr %adata`, ` %y = load i8, ptr %bdata`, ` %fdiffer = icmp ne i8 %x, %y`, ` br i1 %fdiffer, label %bytes, label %order`,
|
|
1001
|
+
// Two differing words. When neither has a byte of at least 0xED
|
|
1002
|
+
// (a byte b is when its high bit and bit 7 of (b & 0x7f) + 0x13 are
|
|
1003
|
+
// set), byte-swapped little-endian words compare in byte order.
|
|
1004
|
+
// Otherwise the lowest set byte of their xor is the first differing
|
|
1005
|
+
// byte.
|
|
1006
|
+
`differ:`, ` %dx = phi i64 [ %aw, %word ], [ %at, %tail ]`, ` %dy = phi i64 [ %bw, %word ], [ %bt, %tail ]`, ` %xl = and i64 %dx, 9187201950435737471`, ` %yl = and i64 %dy, 9187201950435737471`, ` %xa = add i64 %xl, 1374463283923456787`, ` %ya = add i64 %yl, 1374463283923456787`, ` %xh = and i64 %dx, %xa`, ` %yh = and i64 %dy, %ya`, ` %hh = or i64 %xh, %yh`, ` %whigh = and i64 %hh, -9187201950435737472`, ` %dlow = icmp eq i64 %whigh, 0`, ` br i1 %dlow, label %wordorder, label %locate`, `wordorder:`, ` %xsw = call i64 @llvm.bswap.i64(i64 %dx)`, ` %ysw = call i64 @llvm.bswap.i64(i64 %dy)`, ` %wbelow = icmp ult i64 %xsw, %ysw`, ` %wsign = select i1 %wbelow, i32 -1, i32 1`, ` ret i32 %wsign`, `locate:`, ` %dxor = xor i64 %dx, %dy`, ` %dtz = call i64 @llvm.cttz.i64(i64 %dxor, i1 true)`, ` %dshift = and i64 %dtz, 56`, ` %dxs = lshr i64 %dx, %dshift`, ` %dys = lshr i64 %dy, %dshift`, ` %dxb = trunc i64 %dxs to i8`, ` %dyb = trunc i64 %dys to i8`, ` br label %bytes`,
|
|
1007
|
+
// The first differing bytes.
|
|
1008
|
+
`bytes:`, ` %bx = phi i8 [ %x, %first ], [ %dxb, %locate ]`, ` %by = phi i8 [ %y, %first ], [ %dyb, %locate ]`, ` %bmin = call i8 @llvm.umin.i8(i8 %bx, i8 %by)`, ` %blow = icmp ult i8 %bmin, -19`, ` br i1 %blow, label %byte, label %high`,
|
|
1009
|
+
// Both at least 0xED. A lone surrogate (0xED) takes the runtime;
|
|
1010
|
+
// supplementary lead bytes (0xF0..0xF4) order below 0xEE and 0xEF
|
|
1011
|
+
// once 0x10 is subtracted from them.
|
|
1012
|
+
`high:`, ` %xed = icmp eq i8 %bx, -19`, ` %yed = icmp eq i8 %by, -19`, ` %ed = or i1 %xed, %yed`, ` br i1 %ed, label %order, label %planes`, `planes:`, ` %xsupp = icmp uge i8 %bx, -16`, ` %ysupp = icmp uge i8 %by, -16`, ` %xlow = add i8 %bx, -16`, ` %ylow = add i8 %by, -16`, ` %xk = select i1 %xsupp, i8 %xlow, i8 %bx`, ` %yk = select i1 %ysupp, i8 %ylow, i8 %by`, ` %kbelow = icmp ult i8 %xk, %yk`, ` %ksign = select i1 %kbelow, i32 -1, i32 1`, ` ret i32 %ksign`, `byte:`, ` %below = icmp ult i8 %bx, %by`, ` %sign = select i1 %below, i32 -1, i32 1`, ` ret i32 %sign`, `order:`, ` %acw.p = getelementptr inbounds %ScrStr, ptr %a, i32 0, i32 2`, ` %bcw.p = getelementptr inbounds %ScrStr, ptr %b, i32 0, i32 2`, ` %acw = load i32, ptr %acw.p`, ` %bcw = load i32, ptr %bcw.p`, ` %cws = or i32 %acw, %bcw`, ` %anyascii = icmp slt i32 %cws, 0`, ` br i1 %anyascii, label %memorder, label %units`, `memorder:`, ` %m = call i32 @scr_str_cmp(ptr %a, ptr %b)`, ` ret i32 %m`, `units:`, ` %c = call i32 @scr_str_cmp_u16_bytes(ptr %a, ptr %b) nounwind willreturn memory(argmem: read)`, ` ret i32 %c`, `equal:`, ` ret i32 0`, `}`, ``);
|
|
1013
|
+
}
|
|
1014
|
+
// The declarations these helpers added must land in the extern block,
|
|
1015
|
+
// which already flushed — append here instead (LLVM is order-free).
|
|
1016
|
+
return defs.length > 0 ? [...defs] : defs;
|
|
1017
|
+
}
|
|
1018
|
+
/** LIBRARY mode: the profile-declared external definitions — the
|
|
1019
|
+
* export-map wrappers plus init / sink-registration / reset / collect.
|
|
1020
|
+
* Plain `define` (not `define internal`) — the exact linkage distinction
|
|
1021
|
+
* that separates the executable lane's @main from everything else. The
|
|
1022
|
+
* bodies delegate every runtime half to scr_library.c, mirroring the C
|
|
1023
|
+
* emission line for line, so the two lanes are identical by
|
|
1024
|
+
* construction. */
|
|
1025
|
+
export function emitLibDefs(emitter, globals, globalReleaseLines, stamps) {
|
|
1026
|
+
const lib = emitter.mod.lib;
|
|
1027
|
+
const autoReset = lib.resultResetSymbol === null;
|
|
1028
|
+
const out = [``, `; ── library-mode entries (profile: ${lib.profileName}) ──`, ``];
|
|
1029
|
+
// Every entry's prologue records its external symbol in the funnel's
|
|
1030
|
+
// current-entry slot (structured trap-teaching field 2); the symbols
|
|
1031
|
+
// live as internal constants, one per entry.
|
|
1032
|
+
const symConst = (sym) => `@sc_lib_sym_${sym}`;
|
|
1033
|
+
const emitSymConst = (sym) => {
|
|
1034
|
+
out.push(`${symConst(sym)} = internal constant [${Buffer.byteLength(sym, "utf8") + 1} x i8] c"${llStrBytes(sym)}"`);
|
|
1035
|
+
};
|
|
1036
|
+
emitSymConst(lib.initSymbol);
|
|
1037
|
+
emitSymConst(lib.sinkRegisterSymbol);
|
|
1038
|
+
if (lib.callbackRegisterSymbol !== null && lib.callbackRegisterSymbol !== undefined)
|
|
1039
|
+
emitSymConst(lib.callbackRegisterSymbol);
|
|
1040
|
+
if (lib.resultResetSymbol !== null)
|
|
1041
|
+
emitSymConst(lib.resultResetSymbol);
|
|
1042
|
+
if (lib.collectSymbol !== null)
|
|
1043
|
+
emitSymConst(lib.collectSymbol);
|
|
1044
|
+
for (const e of lib.exports)
|
|
1045
|
+
emitSymConst(e.symbol);
|
|
1046
|
+
out.push(``);
|
|
1047
|
+
if (emitter.wasi) {
|
|
1048
|
+
for (const symbol of ["scriptc_alloc", "scriptc_free"])
|
|
1049
|
+
emitSymConst(symbol);
|
|
1050
|
+
out.push(`define ptr @scriptc_alloc(i32 %size) ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_entry(i1 zeroext false, ptr ${symConst("scriptc_alloc")})`, ` %p = call ptr @malloc(i32 %size)`, ` ret ptr %p`, `}`, ``, `define void @scriptc_free(ptr %p) ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_entry(i1 zeroext false, ptr ${symConst("scriptc_free")})`, ` call void @free(ptr %p)`, ` ret void`, `}`, ``);
|
|
1051
|
+
}
|
|
1052
|
+
// The runtime detected-trap overlay table (scr_runtime.h declares it,
|
|
1053
|
+
// the library trap funnel consults it): flat code/teaching/remediation
|
|
1054
|
+
// triples, one per runtime trap code (SC4013–SC4019) the profile
|
|
1055
|
+
// declares text for. The funnel assembles the structured sink message.
|
|
1056
|
+
// The empty table still defines the symbols the funnel links against.
|
|
1057
|
+
const ovlCells = [];
|
|
1058
|
+
lib.trapOverlays.forEach((o, i) => {
|
|
1059
|
+
const cell = (name, text) => {
|
|
1060
|
+
if (text === undefined) {
|
|
1061
|
+
ovlCells.push("ptr null");
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
const sym = `@sc_lib_ovl_${i}_${name}`;
|
|
1065
|
+
out.push(`${sym} = internal constant [${Buffer.byteLength(text, "utf8") + 1} x i8] c"${llStrBytes(text)}"`);
|
|
1066
|
+
ovlCells.push(`ptr ${sym}`);
|
|
1067
|
+
};
|
|
1068
|
+
cell("code", o.code);
|
|
1069
|
+
cell("teach", o.teaching);
|
|
1070
|
+
cell("rem", o.remediation);
|
|
1071
|
+
});
|
|
1072
|
+
out.push(ovlCells.length === 0
|
|
1073
|
+
? `@scr_library_trap_overlays = constant [1 x ptr] zeroinitializer`
|
|
1074
|
+
: `@scr_library_trap_overlays = constant [${ovlCells.length} x ptr] [${ovlCells.join(", ")}]`, `@scr_library_trap_overlays_len = constant ${emitter.sizeType} ${lib.trapOverlays.length}`, ``);
|
|
1075
|
+
// The init entry: full deterministic reset-and-reevaluate. Program
|
|
1076
|
+
// globals release and zero first (run-once guards included), then the
|
|
1077
|
+
// runtime session reset, the error-vt interval stamps verbatim from
|
|
1078
|
+
// the executable main, %main itself, and the escaped-exception check.
|
|
1079
|
+
const zeroStores = globals.map((g) => {
|
|
1080
|
+
const ty = emitter.llType(g.type);
|
|
1081
|
+
const zero = ty === "double" ? f64Lit(0) : ty === "ptr" ? "null" : "false";
|
|
1082
|
+
return ` store ${ty} ${zero}, ptr @${mangleGlobal(g.id)} ; ${g.name}`;
|
|
1083
|
+
});
|
|
1084
|
+
out.push(`define void @${lib.initSymbol}() ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_entry(i1 zeroext true, ptr ${symConst(lib.initSymbol)}) ; init always resets the result arena`, ...globalReleaseLines("ci"), ...zeroStores, ` call void @scr_library_reset()`, ...stamps, ` call void @${mangleFunction(emitter.mod.entry)}()`, ` call void @scr_library_check_exc()`, ` ret void`, `}`, ``, `define void @${lib.sinkRegisterSymbol}(ptr %fn, ptr %ctx) ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_callback_entry_guard(ptr ${symConst(lib.sinkRegisterSymbol)})`, ` call void @scr_library_set_sink(ptr %fn, ptr %ctx)`, ` ret void`, `}`, ``);
|
|
1085
|
+
if (lib.callbacks !== undefined && lib.callbacks.length > 0) {
|
|
1086
|
+
// Host-callback channels: the per-channel name constants (the
|
|
1087
|
+
// registration dispatch's strcmp operands), the per-channel
|
|
1088
|
+
// unregistered-call trap constants (the ffiCall sites'
|
|
1089
|
+
// scr_library_cb_require operands), and the registration function:
|
|
1090
|
+
// a pure store dispatch
|
|
1091
|
+
// (the sink registration's rule — no entry prologue, no poison
|
|
1092
|
+
// guard) whose first operation rejects callback-time re-entry
|
|
1093
|
+
// (SC4026). An unknown or NULL name is a defined -1, never a store.
|
|
1094
|
+
for (const cb of lib.callbacks) {
|
|
1095
|
+
out.push(`@sc_lib_cb_name_${cb.slot} = internal constant [${Buffer.byteLength(cb.name, "utf8") + 1} x i8] c"${llStrBytes(cb.name)}"`, `@sc_lib_cb_trap_${cb.slot} = internal constant [${Buffer.byteLength(cb.unregisteredTrap, "utf8") + 1} x i8] c"${llStrBytes(cb.unregisteredTrap)}"`);
|
|
1096
|
+
}
|
|
1097
|
+
out.push(``, `define i32 @${lib.callbackRegisterSymbol}(ptr %name, ptr %fn, ptr %ctx) ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_callback_entry_guard(ptr ${symConst(lib.callbackRegisterSymbol)})`, ` %isnull = icmp eq ptr %name, null`, ` br i1 %isnull, label %miss, label %try0`);
|
|
1098
|
+
lib.callbacks.forEach((cb, i) => {
|
|
1099
|
+
const next = i + 1 < lib.callbacks.length ? `try${i + 1}` : "miss";
|
|
1100
|
+
out.push(`try${i}: ; channel '${cb.name}'`, ` %cmp${i} = call i32 @strcmp(ptr %name, ptr @sc_lib_cb_name_${cb.slot})`, ` %eq${i} = icmp eq i32 %cmp${i}, 0`, ` br i1 %eq${i}, label %set${i}, label %${next}`, `set${i}:`, ` call void @scr_library_cb_set(${emitter.sizeType} ${cb.slot}, ptr %fn, ptr %ctx)`, ` ret i32 0`);
|
|
1101
|
+
});
|
|
1102
|
+
out.push(`miss:`, ` ret i32 -1`, `}`, ``);
|
|
1103
|
+
}
|
|
1104
|
+
if (lib.identity !== undefined && emitter.emitLibraryIdentity) {
|
|
1105
|
+
// Profile-declared identity getters (the ask-2 sidecar's boot-time
|
|
1106
|
+
// pairing fence): pure data returns with NO entry prologue — exempt
|
|
1107
|
+
// from the poisoned guard and every runtime touch (ratified), so a
|
|
1108
|
+
// host can read them before init and after a trap. The u64 rides
|
|
1109
|
+
// i64 two's-complement (LLVM integer constants are signed).
|
|
1110
|
+
for (const line of emitLibraryIdentityLines(lib.identity, FN_ATTRS))
|
|
1111
|
+
out.push(line);
|
|
1112
|
+
}
|
|
1113
|
+
if (lib.resultResetSymbol !== null) {
|
|
1114
|
+
out.push(`define void @${lib.resultResetSymbol}() ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_entry(i1 zeroext false, ptr ${symConst(lib.resultResetSymbol)})`, ` call void @scr_library_arena_reset()`, ` ret void`, `}`, ``);
|
|
1115
|
+
}
|
|
1116
|
+
if (lib.collectSymbol !== null) {
|
|
1117
|
+
out.push(`define void @${lib.collectSymbol}() ${FN_ATTRS} {`, `entry:`, ` call void @scr_library_entry(i1 zeroext false, ptr ${symConst(lib.collectSymbol)})`, ` call void @scr_library_collect() ; arena reset + a full cycle collection`, ` ret void`, `}`, ``);
|
|
1118
|
+
}
|
|
1119
|
+
for (const e of lib.exports) {
|
|
1120
|
+
const params = [];
|
|
1121
|
+
const body = [
|
|
1122
|
+
` call void @scr_library_entry(i1 zeroext ${autoReset ? "true" : "false"}, ptr ${symConst(e.symbol)})`,
|
|
1123
|
+
];
|
|
1124
|
+
const args = [];
|
|
1125
|
+
if (e.inboundBytesTrap !== undefined) {
|
|
1126
|
+
// The bytes-in helper's trap message: the compiler-assembled
|
|
1127
|
+
// structured trap-teaching form (0x01 text 0x1F SC4012 0x1F symbol
|
|
1128
|
+
// [0x1F remediation]) consumed by the runtime sink.
|
|
1129
|
+
const trapBytes = Buffer.byteLength(e.inboundBytesTrap, "utf8");
|
|
1130
|
+
out.push(`@sc_lib_bytes_trap_${e.symbol} = internal constant [${trapBytes + 1} x i8] c"${llStrBytes(e.inboundBytesTrap)}"`, ``);
|
|
1131
|
+
}
|
|
1132
|
+
if (e.inboundIntTrap !== undefined) {
|
|
1133
|
+
// The i64/u64-in helpers' host-contract trap message (ask 4): an
|
|
1134
|
+
// inbound integer past ±(2^53−1) cannot ride f64 exactly. Same
|
|
1135
|
+
// assembled structured form, same SC4012 code, same
|
|
1136
|
+
// emission-invariance argument as the bytes trap.
|
|
1137
|
+
const trapBytes = Buffer.byteLength(e.inboundIntTrap, "utf8");
|
|
1138
|
+
out.push(`@sc_lib_int_trap_${e.symbol} = internal constant [${trapBytes + 1} x i8] c"${llStrBytes(e.inboundIntTrap)}"`, ``);
|
|
1139
|
+
}
|
|
1140
|
+
if (e.inboundCstringTrap !== undefined) {
|
|
1141
|
+
// The cstring-in helper's host-contract trap message (a NULL
|
|
1142
|
+
// `const char *`): same assembled structured form and SC4012 code.
|
|
1143
|
+
const trapBytes = Buffer.byteLength(e.inboundCstringTrap, "utf8");
|
|
1144
|
+
out.push(`@sc_lib_cstr_trap_${e.symbol} = internal constant [${trapBytes + 1} x i8] c"${llStrBytes(e.inboundCstringTrap)}"`, ``);
|
|
1145
|
+
}
|
|
1146
|
+
e.params.forEach((cls, i) => {
|
|
1147
|
+
switch (cls) {
|
|
1148
|
+
case "f64":
|
|
1149
|
+
params.push(`double %a${i}`);
|
|
1150
|
+
args.push(`double %a${i}`);
|
|
1151
|
+
break;
|
|
1152
|
+
case "bool":
|
|
1153
|
+
params.push(`i8 %a${i}`);
|
|
1154
|
+
body.push(` %c${i} = icmp ne i8 %a${i}, 0`);
|
|
1155
|
+
args.push(`i1 %c${i}`);
|
|
1156
|
+
break;
|
|
1157
|
+
case "u8":
|
|
1158
|
+
params.push(`i8 %a${i}`);
|
|
1159
|
+
body.push(` %c${i} = uitofp i8 %a${i} to double`);
|
|
1160
|
+
args.push(`double %c${i}`);
|
|
1161
|
+
break;
|
|
1162
|
+
case "u32":
|
|
1163
|
+
params.push(`i32 %a${i}`);
|
|
1164
|
+
body.push(` %c${i} = uitofp i32 %a${i} to double`);
|
|
1165
|
+
args.push(`double %c${i}`);
|
|
1166
|
+
break;
|
|
1167
|
+
case "i32":
|
|
1168
|
+
params.push(`i32 %a${i}`);
|
|
1169
|
+
body.push(` %c${i} = sitofp i32 %a${i} to double`);
|
|
1170
|
+
args.push(`double %c${i}`);
|
|
1171
|
+
break;
|
|
1172
|
+
case "i64":
|
|
1173
|
+
// Inbound declared-integer edge (ask 4): the helper converts
|
|
1174
|
+
// exactly or delivers the host-contract trap (past ±(2^53−1)
|
|
1175
|
+
// the value cannot ride f64 without rounding).
|
|
1176
|
+
params.push(`i64 %a${i}`);
|
|
1177
|
+
body.push(` %c${i} = call double @scr_library_i64_in(i64 %a${i}, ptr @sc_lib_int_trap_${e.symbol})`);
|
|
1178
|
+
args.push(`double %c${i}`);
|
|
1179
|
+
break;
|
|
1180
|
+
case "u64":
|
|
1181
|
+
params.push(`i64 %a${i}`);
|
|
1182
|
+
body.push(` %c${i} = call double @scr_library_u64_in(i64 %a${i}, ptr @sc_lib_int_trap_${e.symbol})`);
|
|
1183
|
+
args.push(`double %c${i}`);
|
|
1184
|
+
break;
|
|
1185
|
+
case "string":
|
|
1186
|
+
params.push(`ptr %a${i}_ptr`, `${emitter.sizeType} %a${i}_len`);
|
|
1187
|
+
body.push(` %c${i} = call ptr @scr_library_str_in(ptr %a${i}_ptr, ${emitter.sizeType} %a${i}_len)`);
|
|
1188
|
+
args.push(`ptr %c${i}`);
|
|
1189
|
+
break;
|
|
1190
|
+
case "bytes":
|
|
1191
|
+
params.push(`ptr %a${i}_ptr`, `${emitter.sizeType} %a${i}_len`);
|
|
1192
|
+
body.push(` %c${i} = call ptr @scr_library_bytes_in(ptr %a${i}_ptr, ${emitter.sizeType} %a${i}_len, ptr @sc_lib_bytes_trap_${e.symbol})`);
|
|
1193
|
+
args.push(`ptr %c${i}`);
|
|
1194
|
+
break;
|
|
1195
|
+
case "cstring":
|
|
1196
|
+
params.push(`ptr %a${i}`);
|
|
1197
|
+
body.push(` %c${i} = call ptr @scr_library_cstr_in(ptr %a${i}, ptr @sc_lib_cstr_trap_${e.symbol})`);
|
|
1198
|
+
args.push(`ptr %c${i}`);
|
|
1199
|
+
break;
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
if (e.returns === "string" || e.returns === "bytes") {
|
|
1203
|
+
params.push(`ptr %out`, `ptr %out_len`);
|
|
1204
|
+
}
|
|
1205
|
+
const target = `@${mangleFunction(e.fnName)}`;
|
|
1206
|
+
const callArgs = args.join(", ");
|
|
1207
|
+
let retType = "void";
|
|
1208
|
+
switch (e.returns) {
|
|
1209
|
+
case "void":
|
|
1210
|
+
body.push(` call void ${target}(${callArgs})`, ` call void @scr_library_check_exc()`, ` ret void`);
|
|
1211
|
+
break;
|
|
1212
|
+
case "f64":
|
|
1213
|
+
retType = "double";
|
|
1214
|
+
body.push(` %r = call double ${target}(${callArgs})`, ` call void @scr_library_check_exc()`, ` ret double %r`);
|
|
1215
|
+
break;
|
|
1216
|
+
case "i64":
|
|
1217
|
+
case "u64":
|
|
1218
|
+
// The outbound declared-integer edge (ask 4): every value
|
|
1219
|
+
// reaching this return was PROVEN whole and inside the class's
|
|
1220
|
+
// range at compile time, so the fp-to-int conversion is exact
|
|
1221
|
+
// by construction — the crossing carries the mathematically
|
|
1222
|
+
// exact integer the f64 held.
|
|
1223
|
+
retType = "i64";
|
|
1224
|
+
body.push(` %r = call double ${target}(${callArgs})`, ` call void @scr_library_check_exc()`, ` %z = ${e.returns === "i64" ? "fptosi" : "fptoui"} double %r to i64`, ` ret i64 %z`);
|
|
1225
|
+
break;
|
|
1226
|
+
case "bool":
|
|
1227
|
+
retType = "i8";
|
|
1228
|
+
body.push(` %r = call i1 ${target}(${callArgs})`, ` call void @scr_library_check_exc()`, ` %z = zext i1 %r to i8`, ` ret i8 %z`);
|
|
1229
|
+
break;
|
|
1230
|
+
case "string":
|
|
1231
|
+
body.push(` %r = call ptr ${target}(${callArgs})`, ` call void @scr_library_check_exc()`, ` call void @scr_library_str_out(ptr %r, ptr %out, ptr %out_len)`, ` ret void`);
|
|
1232
|
+
break;
|
|
1233
|
+
case "bytes":
|
|
1234
|
+
body.push(` %r = call ptr ${target}(${callArgs})`, ` call void @scr_library_check_exc()`, ` call void @scr_library_bytes_out(ptr %r, ptr %out, ptr %out_len)`, ` ret void`);
|
|
1235
|
+
break;
|
|
1236
|
+
case "cstring":
|
|
1237
|
+
// The result's arena copy, returned as `const char *`.
|
|
1238
|
+
retType = "ptr";
|
|
1239
|
+
body.push(` %r = call ptr ${target}(${callArgs})`, ` call void @scr_library_check_exc()`, ` %z = call ptr @scr_library_cstr_out(ptr %r)`, ` ret ptr %z`);
|
|
1240
|
+
break;
|
|
1241
|
+
}
|
|
1242
|
+
out.push(`define ${retType} @${e.symbol}(${params.join(", ")}) ${FN_ATTRS} { ; library export ${e.fnName}`, `entry:`, ...body, `}`, ``);
|
|
1243
|
+
}
|
|
1244
|
+
return out;
|
|
1245
|
+
}
|
|
1246
|
+
/** C-callable scalar callback trampolines. A callback with an explicit
|
|
1247
|
+
* context entry receives the closure at that exact ABI position. A raw
|
|
1248
|
+
* callback loads it from a call-scoped TLS slot installed around the
|
|
1249
|
+
* outer native call. */
|
|
1250
|
+
export function emitFfiCallbackDefs(emitter) {
|
|
1251
|
+
const globals = [];
|
|
1252
|
+
const defs = [];
|
|
1253
|
+
if (emitter.ffiCallbackAdapters.size === 0)
|
|
1254
|
+
return { globals, defs };
|
|
1255
|
+
emitter.declare(`declare void @scr_trap(ptr)`);
|
|
1256
|
+
const expired = emitter.cstr("scriptc: native callback invoked outside its call-scoped lifetime\n");
|
|
1257
|
+
const released = emitter.cstr("scriptc: native callback invoked outside its retained lifetime\n");
|
|
1258
|
+
for (const adapter of emitter.ffiCallbackAdapters.values()) {
|
|
1259
|
+
const cb = adapter.callback;
|
|
1260
|
+
if (adapter.tls !== null)
|
|
1261
|
+
globals.push(`@${adapter.tls} = internal thread_local global ptr null`);
|
|
1262
|
+
if (adapter.global !== null)
|
|
1263
|
+
globals.push(`@${adapter.global} = internal thread_local global ptr null`);
|
|
1264
|
+
if (adapter.table !== null) {
|
|
1265
|
+
globals.push(`@${adapter.table} = internal ${emitter.mod.workers ? "thread_local " : ""}global %ScrFfiTable zeroinitializer`);
|
|
1266
|
+
}
|
|
1267
|
+
const params = cb.params.flatMap((param, i) => {
|
|
1268
|
+
if (isFfiContextParam(param))
|
|
1269
|
+
return [`ptr %ctx`];
|
|
1270
|
+
if (param === "string" || param === "bytes") {
|
|
1271
|
+
return [`ptr %a${i}`, `${emitter.sizeType} %a${i}_len`];
|
|
1272
|
+
}
|
|
1273
|
+
return [`${ffiNativeParamLl(param, emitter.ffiExtendNarrowIntegers)} %a${i}`];
|
|
1274
|
+
});
|
|
1275
|
+
if (cb.invoke === "foreign") {
|
|
1276
|
+
if (adapter.table === null ||
|
|
1277
|
+
!cb.params.some(isFfiContextParam) ||
|
|
1278
|
+
cb.returns !== "void" ||
|
|
1279
|
+
cb.params.some((param) => param === "i64" || param === "u64" || param === "pointer")) {
|
|
1280
|
+
throw new InternalCompilerError("llvm emitter bug: invalid foreign FFI callback descriptor");
|
|
1281
|
+
}
|
|
1282
|
+
const dispatch = `${adapter.symbol}_dispatch`;
|
|
1283
|
+
const scriptArgs = [];
|
|
1284
|
+
const dispatchBody = [
|
|
1285
|
+
`define internal void @${dispatch}(ptr %cb, ptr %call) ${FN_ATTRS} {`,
|
|
1286
|
+
`entry:`,
|
|
1287
|
+
` %fnp = getelementptr inbounds %ScrClosure, ptr %cb, i64 0, i32 1`,
|
|
1288
|
+
` %fn = load ptr, ptr %fnp`,
|
|
1289
|
+
];
|
|
1290
|
+
for (let i = 0; i < cb.params.length; i++) {
|
|
1291
|
+
const param = cb.params[i];
|
|
1292
|
+
if (isFfiContextParam(param))
|
|
1293
|
+
continue;
|
|
1294
|
+
switch (param) {
|
|
1295
|
+
case "f64":
|
|
1296
|
+
case "f32":
|
|
1297
|
+
case "i8":
|
|
1298
|
+
case "u16":
|
|
1299
|
+
case "i16":
|
|
1300
|
+
emitter.declare(`declare double @scr_ffi_call_get_f64(ptr, ${emitter.sizeType})`);
|
|
1301
|
+
dispatchBody.push(` %s${i} = call double @scr_ffi_call_get_f64(ptr %call, ${emitter.sizeType} ${i})`);
|
|
1302
|
+
scriptArgs.push(`double %s${i}`);
|
|
1303
|
+
break;
|
|
1304
|
+
case "bool":
|
|
1305
|
+
emitter.declare(`declare zeroext i1 @scr_ffi_call_get_bool(ptr, ${emitter.sizeType})`);
|
|
1306
|
+
dispatchBody.push(` %s${i} = call zeroext i1 @scr_ffi_call_get_bool(ptr %call, ${emitter.sizeType} ${i})`);
|
|
1307
|
+
scriptArgs.push(`i1 %s${i}`);
|
|
1308
|
+
break;
|
|
1309
|
+
case "u8":
|
|
1310
|
+
case "u32":
|
|
1311
|
+
case "i32":
|
|
1312
|
+
emitter.declare(`declare double @scr_ffi_call_get_${param}(ptr, ${emitter.sizeType})`);
|
|
1313
|
+
dispatchBody.push(` %s${i} = call double @scr_ffi_call_get_${param}(ptr %call, ${emitter.sizeType} ${i})`);
|
|
1314
|
+
scriptArgs.push(`double %s${i}`);
|
|
1315
|
+
break;
|
|
1316
|
+
case "cstring":
|
|
1317
|
+
case "string":
|
|
1318
|
+
case "bytes": {
|
|
1319
|
+
emitter.declare(`declare ptr @scr_ffi_call_get_data(ptr, ${emitter.sizeType})`);
|
|
1320
|
+
emitter.declare(`declare ${emitter.sizeType} @scr_ffi_call_get_len(ptr, ${emitter.sizeType})`);
|
|
1321
|
+
dispatchBody.push(` %data${i} = call ptr @scr_ffi_call_get_data(ptr %call, ${emitter.sizeType} ${i})`, ` %len${i} = call ${emitter.sizeType} @scr_ffi_call_get_len(ptr %call, ${emitter.sizeType} ${i})`);
|
|
1322
|
+
if (param === "bytes") {
|
|
1323
|
+
emitter.declare(`declare ptr @scr_bytes_from_data(ptr, ${emitter.sizeType})`);
|
|
1324
|
+
dispatchBody.push(` %s${i} = call ptr @scr_bytes_from_data(ptr %data${i}, ${emitter.sizeType} %len${i})`);
|
|
1325
|
+
}
|
|
1326
|
+
else {
|
|
1327
|
+
emitter.declare(`declare ptr @scr_str_from_utf8_lossy(ptr, ${emitter.sizeType})`);
|
|
1328
|
+
dispatchBody.push(` %s${i} = call ptr @scr_str_from_utf8_lossy(ptr %data${i}, ${emitter.sizeType} %len${i})`);
|
|
1329
|
+
}
|
|
1330
|
+
scriptArgs.push(`ptr %s${i}`);
|
|
1331
|
+
break;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
dispatchBody.push(` call void %fn(${[`ptr %cb`, ...scriptArgs].join(", ")})`, ` ret void`, `}`, ``);
|
|
1336
|
+
for (const line of dispatchBody)
|
|
1337
|
+
defs.push(line);
|
|
1338
|
+
emitter.declare(`declare ptr @scr_ffi_call_new(ptr, ptr, ptr, ${emitter.sizeType})`);
|
|
1339
|
+
emitter.declare(`declare void @scr_ffi_post(ptr)`);
|
|
1340
|
+
defs.push(`define internal void @${adapter.symbol}(${params.join(", ")}) ${FN_ATTRS} {`, `entry:`, ` %cb = getelementptr inbounds i8, ptr %ctx, i64 0`, ` %call = call ptr @scr_ffi_call_new(ptr @${adapter.table}, ptr %cb, ptr @${dispatch}, ${emitter.sizeType} ${cb.params.length})`);
|
|
1341
|
+
for (let i = 0; i < cb.params.length; i++) {
|
|
1342
|
+
const param = cb.params[i];
|
|
1343
|
+
if (isFfiContextParam(param))
|
|
1344
|
+
continue;
|
|
1345
|
+
if (param === "cstring") {
|
|
1346
|
+
emitter.declare(`declare void @scr_ffi_call_copy_cstring(ptr, ${emitter.sizeType}, ptr)`);
|
|
1347
|
+
defs.push(` call void @scr_ffi_call_copy_cstring(ptr %call, ${emitter.sizeType} ${i}, ptr %a${i})`);
|
|
1348
|
+
}
|
|
1349
|
+
else if (param === "string" || param === "bytes") {
|
|
1350
|
+
emitter.declare(`declare void @scr_ffi_call_copy_${param}(ptr, ${emitter.sizeType}, ptr, ${emitter.sizeType})`);
|
|
1351
|
+
defs.push(` call void @scr_ffi_call_copy_${param}(ptr %call, ${emitter.sizeType} ${i}, ptr %a${i}, ${emitter.sizeType} %a${i}_len)`);
|
|
1352
|
+
}
|
|
1353
|
+
else if (param === "f32" || param === "i8" || param === "u16" || param === "i16") {
|
|
1354
|
+
const nativeTy = ffiNativeTypeLl(param);
|
|
1355
|
+
const op = param === "f32" ? "fpext" : param === "u16" ? "uitofp" : "sitofp";
|
|
1356
|
+
emitter.declare(`declare void @scr_ffi_call_set_f64(ptr, ${emitter.sizeType}, double)`);
|
|
1357
|
+
defs.push(` %wide${i} = ${op} ${nativeTy} %a${i} to double`, ` call void @scr_ffi_call_set_f64(ptr %call, ${emitter.sizeType} ${i}, double %wide${i})`);
|
|
1358
|
+
}
|
|
1359
|
+
else {
|
|
1360
|
+
const nativeTy = ffiNativeTypeLl(param);
|
|
1361
|
+
emitter.declare(`declare void @scr_ffi_call_set_${param}(ptr, ${emitter.sizeType}, ${nativeTy})`);
|
|
1362
|
+
defs.push(` call void @scr_ffi_call_set_${param}(ptr %call, ${emitter.sizeType} ${i}, ${nativeTy} %a${i})`);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
defs.push(` call void @scr_ffi_post(ptr %call)`, ` ret void`, `}`, ``);
|
|
1366
|
+
continue;
|
|
1367
|
+
}
|
|
1368
|
+
defs.push(`define internal ${ffiNativeReturnLl(cb.returns, emitter.ffiExtendNarrowIntegers)} @${adapter.symbol}(${params.join(", ")}) ${FN_ATTRS} {`, `entry:`, adapter.tls !== null
|
|
1369
|
+
? ` %cb = load ptr, ptr @${adapter.tls}`
|
|
1370
|
+
: adapter.global !== null
|
|
1371
|
+
? ` %cb = load ptr, ptr @${adapter.global}`
|
|
1372
|
+
: ` %cb = getelementptr inbounds i8, ptr %ctx, i64 0`, ` %missing = icmp eq ptr %cb, null`, ` br i1 %missing, label %expired, label %ready`, `expired:`, ` call void @scr_trap(ptr ${adapter.callback.lifetime === "call" ? expired : released})`, ` unreachable`, `ready:`, ...emitter.pendingTestLines("%pending"), ` br i1 %pending, label %skip, label %invoke`, `skip:`, ` ret ${ffiCallbackDummyLl(cb)}`, `invoke:`);
|
|
1373
|
+
// Validate every native pointer before allocating any copy-in value.
|
|
1374
|
+
// A later bad slot therefore cannot leak an earlier materialization.
|
|
1375
|
+
for (let i = 0; i < cb.params.length; i++) {
|
|
1376
|
+
const param = cb.params[i];
|
|
1377
|
+
if (param !== "cstring" && param !== "string" && param !== "bytes")
|
|
1378
|
+
continue;
|
|
1379
|
+
const invalid = `%invalid${i}`;
|
|
1380
|
+
defs.push(` %null${i} = icmp eq ptr %a${i}, null`);
|
|
1381
|
+
if (param === "cstring") {
|
|
1382
|
+
defs.push(` ${invalid} = or i1 %null${i}, false`);
|
|
1383
|
+
}
|
|
1384
|
+
else {
|
|
1385
|
+
defs.push(` %nonempty${i} = icmp ne ${emitter.sizeType} %a${i}_len, 0`, ` ${invalid} = and i1 %null${i}, %nonempty${i}`);
|
|
1386
|
+
}
|
|
1387
|
+
const message = param === "cstring"
|
|
1388
|
+
? "scriptc: native callback passed a NULL cstring\n"
|
|
1389
|
+
: `scriptc: native callback passed a NULL ${param} span with nonzero length\n`;
|
|
1390
|
+
defs.push(` br i1 ${invalid}, label %invalid_param${i}, label %param_ok${i}`, `invalid_param${i}:`, ` call void @scr_trap(ptr ${emitter.cstr(message)})`, ` unreachable`, `param_ok${i}:`);
|
|
1391
|
+
}
|
|
1392
|
+
defs.push(` %fnp = getelementptr inbounds %ScrClosure, ptr %cb, i64 0, i32 1`, ` %fn = load ptr, ptr %fnp`);
|
|
1393
|
+
const scriptArgs = [];
|
|
1394
|
+
for (let i = 0; i < cb.params.length; i++) {
|
|
1395
|
+
const param = cb.params[i];
|
|
1396
|
+
if (isFfiContextParam(param))
|
|
1397
|
+
continue;
|
|
1398
|
+
switch (param) {
|
|
1399
|
+
case "i64":
|
|
1400
|
+
case "u64":
|
|
1401
|
+
case "pointer": {
|
|
1402
|
+
const ty = ffiNativeTypeLl(param);
|
|
1403
|
+
emitter.declare(`declare ptr @scr_bigint_from_${param}(${ty})`);
|
|
1404
|
+
defs.push(` %s${i} = call ptr @scr_bigint_from_${param}(${ty} %a${i})`);
|
|
1405
|
+
scriptArgs.push(`ptr %s${i}`);
|
|
1406
|
+
break;
|
|
1407
|
+
}
|
|
1408
|
+
case "f64":
|
|
1409
|
+
scriptArgs.push(`double %a${i}`);
|
|
1410
|
+
break;
|
|
1411
|
+
case "f32":
|
|
1412
|
+
case "i8":
|
|
1413
|
+
case "u16":
|
|
1414
|
+
case "i16": {
|
|
1415
|
+
const nativeTy = ffiNativeTypeLl(param);
|
|
1416
|
+
const op = param === "f32" ? "fpext" : param === "u16" ? "uitofp" : "sitofp";
|
|
1417
|
+
defs.push(` %s${i} = ${op} ${nativeTy} %a${i} to double`);
|
|
1418
|
+
scriptArgs.push(`double %s${i}`);
|
|
1419
|
+
break;
|
|
1420
|
+
}
|
|
1421
|
+
case "bool":
|
|
1422
|
+
defs.push(` %s${i} = icmp ne i8 %a${i}, 0`);
|
|
1423
|
+
scriptArgs.push(`i1 %s${i}`);
|
|
1424
|
+
break;
|
|
1425
|
+
case "u8":
|
|
1426
|
+
defs.push(` %s${i} = uitofp i8 %a${i} to double`);
|
|
1427
|
+
scriptArgs.push(`double %s${i}`);
|
|
1428
|
+
break;
|
|
1429
|
+
case "u32":
|
|
1430
|
+
defs.push(` %s${i} = uitofp i32 %a${i} to double`);
|
|
1431
|
+
scriptArgs.push(`double %s${i}`);
|
|
1432
|
+
break;
|
|
1433
|
+
case "i32":
|
|
1434
|
+
defs.push(` %s${i} = sitofp i32 %a${i} to double`);
|
|
1435
|
+
scriptArgs.push(`double %s${i}`);
|
|
1436
|
+
break;
|
|
1437
|
+
case "cstring":
|
|
1438
|
+
emitter.declare(`declare ${emitter.sizeType} @strlen(ptr)`);
|
|
1439
|
+
emitter.declare(`declare ptr @scr_str_from_utf8_lossy(ptr, ${emitter.sizeType})`);
|
|
1440
|
+
defs.push(` %len${i} = call ${emitter.sizeType} @strlen(ptr %a${i})`, ` %s${i} = call ptr @scr_str_from_utf8_lossy(ptr %a${i}, ${emitter.sizeType} %len${i})`);
|
|
1441
|
+
scriptArgs.push(`ptr %s${i}`);
|
|
1442
|
+
break;
|
|
1443
|
+
case "string":
|
|
1444
|
+
emitter.declare(`declare ptr @scr_str_from_utf8_lossy(ptr, ${emitter.sizeType})`);
|
|
1445
|
+
defs.push(` %s${i} = call ptr @scr_str_from_utf8_lossy(ptr %a${i}, ${emitter.sizeType} %a${i}_len)`);
|
|
1446
|
+
scriptArgs.push(`ptr %s${i}`);
|
|
1447
|
+
break;
|
|
1448
|
+
case "bytes":
|
|
1449
|
+
emitter.declare(`declare ptr @scr_bytes_from_data(ptr, ${emitter.sizeType})`);
|
|
1450
|
+
defs.push(` %s${i} = call ptr @scr_bytes_from_data(ptr %a${i}, ${emitter.sizeType} %a${i}_len)`);
|
|
1451
|
+
scriptArgs.push(`ptr %s${i}`);
|
|
1452
|
+
break;
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
const ft = ffiCallbackType(cb);
|
|
1456
|
+
const internalRet = emitter.llType(ft.ret);
|
|
1457
|
+
const callArgs = [`ptr %cb`, ...scriptArgs].join(", ");
|
|
1458
|
+
if (cb.lifetime === "retained") {
|
|
1459
|
+
emitter.declare(`declare ptr @scr_closure_retain_v(ptr)`);
|
|
1460
|
+
emitter.declare(`declare void @scr_closure_release_v(ptr)`);
|
|
1461
|
+
defs.push(` %invoke_pin = call ptr @scr_closure_retain_v(ptr %cb)`);
|
|
1462
|
+
}
|
|
1463
|
+
if (cb.returns === "void") {
|
|
1464
|
+
defs.push(` call void %fn(${callArgs})`, ...(cb.lifetime === "retained"
|
|
1465
|
+
? [` call void @scr_closure_release_v(ptr %invoke_pin)`]
|
|
1466
|
+
: []), ` ret void`, `}`, ``);
|
|
1467
|
+
continue;
|
|
1468
|
+
}
|
|
1469
|
+
defs.push(` %result = call ${internalRet} %fn(${callArgs})`);
|
|
1470
|
+
if (cb.lifetime === "retained") {
|
|
1471
|
+
defs.push(` call void @scr_closure_release_v(ptr %invoke_pin)`);
|
|
1472
|
+
}
|
|
1473
|
+
switch (cb.returns) {
|
|
1474
|
+
case "i64":
|
|
1475
|
+
case "u64":
|
|
1476
|
+
case "pointer": {
|
|
1477
|
+
const ty = ffiNativeTypeLl(cb.returns);
|
|
1478
|
+
emitter.declare(`declare ${ty} @scr_bigint_to_${cb.returns}(ptr)`);
|
|
1479
|
+
emitter.declare(`declare void @scr_bigint_release(ptr)`);
|
|
1480
|
+
defs.push(` %out = call ${ty} @scr_bigint_to_${cb.returns}(ptr %result)`, ` call void @scr_bigint_release(ptr %result)`, ` ret ${ty} %out`);
|
|
1481
|
+
break;
|
|
1482
|
+
}
|
|
1483
|
+
case "f64":
|
|
1484
|
+
defs.push(` ret double %result`);
|
|
1485
|
+
break;
|
|
1486
|
+
case "f32":
|
|
1487
|
+
defs.push(` %out = fptrunc double %result to float`, ` ret float %out`);
|
|
1488
|
+
break;
|
|
1489
|
+
case "bool":
|
|
1490
|
+
defs.push(` %out = zext i1 %result to i8`, ` ret i8 %out`);
|
|
1491
|
+
break;
|
|
1492
|
+
case "u8":
|
|
1493
|
+
case "i8":
|
|
1494
|
+
case "u16":
|
|
1495
|
+
case "i16":
|
|
1496
|
+
case "u32":
|
|
1497
|
+
emitter.declare(`declare double @scr_bit_ushr(double, double)`);
|
|
1498
|
+
defs.push(` %coerced = call double @scr_bit_ushr(double %result, double ${f64Lit(0)})`, ` %wide = fptoui double %coerced to i32`);
|
|
1499
|
+
if (cb.returns !== "u32") {
|
|
1500
|
+
const nativeTy = ffiNativeTypeLl(cb.returns);
|
|
1501
|
+
defs.push(` %out = trunc i32 %wide to ${nativeTy}`, ` ret ${nativeTy} %out`);
|
|
1502
|
+
}
|
|
1503
|
+
else {
|
|
1504
|
+
defs.push(` ret i32 %wide`);
|
|
1505
|
+
}
|
|
1506
|
+
break;
|
|
1507
|
+
case "i32":
|
|
1508
|
+
emitter.declare(`declare double @scr_bit_or(double, double)`);
|
|
1509
|
+
defs.push(` %coerced = call double @scr_bit_or(double %result, double ${f64Lit(0)})`, ` %out = fptosi double %coerced to i32`, ` ret i32 %out`);
|
|
1510
|
+
break;
|
|
1511
|
+
}
|
|
1512
|
+
defs.push(`}`, ``);
|
|
1513
|
+
}
|
|
1514
|
+
return { globals, defs };
|
|
1515
|
+
}
|
|
1516
|
+
export function emitParts(emitter) {
|
|
1517
|
+
const parts = [
|
|
1518
|
+
...limitInlineDynReleases(emitter.emitModuleParts()),
|
|
1519
|
+
...emitter.disposeObserverGates(),
|
|
1520
|
+
];
|
|
1521
|
+
if (!emitter.executableTls)
|
|
1522
|
+
return parts;
|
|
1523
|
+
// A worker executable's thread-locals all live in the executable's own
|
|
1524
|
+
// TLS block: the program's internal ones, and the runtime's external
|
|
1525
|
+
// ones, because the runtime is always linked statically into the
|
|
1526
|
+
// executable. So on ELF they can all use the local-exec model: LLVM's
|
|
1527
|
+
// default general-dynamic sequence (relaxed by the linker to `mov %fs:0`
|
|
1528
|
+
// plus an add), and even initial-exec (relaxed to `mov $offset` plus an
|
|
1529
|
+
// indexed access), become one %fs-relative operand LLVM can fold into
|
|
1530
|
+
// loads and compares. Darwin's thread-local variables have one model.
|
|
1531
|
+
return parts.map((part) => part
|
|
1532
|
+
.replace(/^(@[-$._A-Za-z0-9]+ = internal )thread_local global /gm, "$1thread_local(localexec) global ")
|
|
1533
|
+
.replace(/^(@[-$._A-Za-z0-9]+ = external )thread_local global /gm, "$1thread_local(localexec) global "));
|
|
1534
|
+
}
|
|
1535
|
+
//# sourceMappingURL=emit-module.js.map
|