@scriptc/compiler 0.1.7 → 0.2.1
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 +98 -39
- package/ambient/scriptc-overrides.d.ts +10 -6
- package/ambient/scriptc.d.ts +15 -0
- package/dist/backend/build-cache.d.ts +1 -3
- package/dist/backend/build-cache.js +3 -22
- package/dist/backend/build-cache.js.map +1 -1
- package/dist/backend/cache-root.d.ts +3 -0
- package/dist/backend/cache-root.js +23 -0
- package/dist/backend/cache-root.js.map +1 -0
- package/dist/backend/cycle-analysis.d.ts +15 -0
- package/dist/backend/cycle-analysis.js +108 -0
- package/dist/backend/cycle-analysis.js.map +1 -0
- package/dist/backend/cycle-analysis.test.js +124 -0
- package/dist/backend/cycle-analysis.test.js.map +1 -0
- package/dist/backend/executable-features.d.ts +4 -0
- package/dist/backend/executable-features.js +42 -0
- package/dist/backend/executable-features.js.map +1 -0
- package/dist/backend/external-c.d.ts +5 -27
- package/dist/backend/external-c.js +5 -40
- package/dist/backend/external-c.js.map +1 -1
- package/dist/backend/ffi-callbacks.d.ts +2 -3
- package/dist/backend/ffi-callbacks.js +2 -3
- package/dist/backend/ffi-callbacks.js.map +1 -1
- package/dist/backend/library-identity-markers.d.ts +4 -9
- package/dist/backend/library-identity-markers.js +11 -49
- package/dist/backend/library-identity-markers.js.map +1 -1
- package/dist/backend/library-pack.d.ts +5 -0
- package/dist/backend/library-pack.js +123 -0
- package/dist/backend/library-pack.js.map +1 -0
- package/dist/backend/link-plan-core.d.ts +20 -0
- package/dist/backend/link-plan-core.js +18 -0
- package/dist/backend/link-plan-core.js.map +1 -0
- package/dist/backend/link-plan.d.ts +1 -1
- package/dist/backend/link-plan.js +16 -17
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/link-trace.d.ts +2 -0
- package/dist/backend/link-trace.js +24 -0
- package/dist/backend/link-trace.js.map +1 -0
- package/dist/backend/linker.js +1 -1
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/literals.d.ts +9 -0
- package/dist/backend/literals.js +35 -0
- package/dist/backend/literals.js.map +1 -0
- package/dist/backend/literals.test.d.ts +1 -0
- package/dist/backend/literals.test.js +53 -0
- package/dist/backend/literals.test.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +2 -0
- package/dist/backend/llvm/blocks.js +9 -4
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/blocks.test.d.ts +1 -0
- package/dist/backend/llvm/blocks.test.js +91 -0
- package/dist/backend/llvm/blocks.test.js.map +1 -0
- package/dist/backend/llvm/classes.d.ts +14 -8
- package/dist/backend/llvm/classes.js +88 -30
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +5 -1
- package/dist/backend/llvm/common.js +45 -4
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/debug-info.js +2 -7
- package/dist/backend/llvm/debug-info.js.map +1 -1
- package/dist/backend/llvm/debug-info.test.d.ts +1 -0
- package/dist/backend/llvm/debug-info.test.js +110 -0
- package/dist/backend/llvm/debug-info.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +21 -2
- package/dist/backend/llvm/dyn.js +647 -251
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +596 -1
- package/dist/backend/llvm/emitter.js +769 -425
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.d.ts +1 -0
- package/dist/backend/llvm/emitter.test.js +179 -0
- package/dist/backend/llvm/emitter.test.js.map +1 -0
- package/dist/backend/llvm/expr-async.js +23 -14
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +2 -2
- package/dist/backend/llvm/expr-bytes.js +60 -31
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +1 -1
- package/dist/backend/llvm/expr-callbacks.js +25 -22
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +136 -35
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +1 -1
- package/dist/backend/llvm/expr-containers.js +43 -14
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +5 -260
- package/dist/backend/llvm/expr-control.js +10 -6
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.d.ts +1 -1
- package/dist/backend/llvm/expr-dispatch.js +2 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +78 -81
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-island.d.ts +1 -1
- package/dist/backend/llvm/expr-island.js +11 -7
- package/dist/backend/llvm/expr-island.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +62 -31
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +1 -1
- package/dist/backend/llvm/expr-records.d.ts +5 -1
- package/dist/backend/llvm/expr-records.js +54 -7
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +4 -4
- package/dist/backend/llvm/expr-stream-bridges.js +220 -131
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.d.ts +1 -0
- package/dist/backend/llvm/expr-stream-bridges.test.js +55 -0
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.js +12 -12
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/layouts.d.ts +19 -0
- package/dist/backend/llvm/layouts.js +12 -0
- package/dist/backend/llvm/layouts.js.map +1 -0
- package/dist/backend/llvm/lib-abi.d.ts +19 -0
- package/dist/backend/llvm/lib-abi.js +82 -0
- package/dist/backend/llvm/lib-abi.js.map +1 -0
- package/dist/backend/llvm/lib-connect.d.ts +2 -0
- package/dist/backend/llvm/lib-connect.js +51 -0
- package/dist/backend/llvm/lib-connect.js.map +1 -0
- package/dist/backend/llvm/lib-datagram.d.ts +2 -0
- package/dist/backend/llvm/lib-datagram.js +135 -0
- package/dist/backend/llvm/lib-datagram.js.map +1 -0
- package/dist/backend/llvm/lib-dispatch.js +50 -6
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +30 -18
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.d.ts +2 -0
- package/dist/backend/llvm/lib-http2.js +215 -0
- package/dist/backend/llvm/lib-http2.js.map +1 -0
- package/dist/backend/llvm/lib-lookup.d.ts +2 -0
- package/dist/backend/llvm/lib-lookup.js +39 -0
- package/dist/backend/llvm/lib-lookup.js.map +1 -0
- package/dist/backend/llvm/lib-network.js +25 -2
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +44 -19
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +162 -3
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +3 -2
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-test.d.ts +2 -0
- package/dist/backend/llvm/lib-test.js +34 -0
- package/dist/backend/llvm/lib-test.js.map +1 -0
- package/dist/backend/llvm/lib-tls.d.ts +2 -0
- package/dist/backend/llvm/lib-tls.js +82 -0
- package/dist/backend/llvm/lib-tls.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +10 -9
- package/dist/backend/llvm/shapes.js +42 -131
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/unsupported.d.ts +1 -0
- package/dist/backend/llvm/unsupported.js +1 -2
- package/dist/backend/llvm/unsupported.js.map +1 -1
- package/dist/backend/llvm/walkers.js +1 -7
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/mangle.d.ts +2 -2
- package/dist/backend/mangle.js +16 -5
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/{c/may-throw.d.ts → may-throw.d.ts} +1 -1
- package/dist/backend/{c/may-throw.js → may-throw.js} +51 -46
- package/dist/backend/may-throw.js.map +1 -0
- package/dist/backend/may-throw.test.d.ts +1 -0
- package/dist/backend/may-throw.test.js +58 -0
- package/dist/backend/may-throw.test.js.map +1 -0
- package/dist/backend/native-codegen-core.d.ts +22 -0
- package/dist/backend/native-codegen-core.js +44 -0
- package/dist/backend/native-codegen-core.js.map +1 -0
- package/dist/backend/native-codegen.d.ts +3 -19
- package/dist/backend/native-codegen.js +5 -44
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +2 -2
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +94 -0
- package/dist/backend/native-link-info-core.js +62 -0
- package/dist/backend/native-link-info-core.js.map +1 -0
- package/dist/backend/native-link-info.d.ts +3 -88
- package/dist/backend/native-link-info.js +12 -243
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-link-info.test.js +41 -146
- package/dist/backend/native-link-info.test.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +12 -30
- package/dist/backend/native-toolchain.js +83 -233
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +77 -5
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/native-tools.d.ts +24 -0
- package/dist/backend/native-tools.js +33 -0
- package/dist/backend/native-tools.js.map +1 -0
- package/dist/backend/object-localize.js +19 -8
- package/dist/backend/object-localize.js.map +1 -1
- package/dist/backend/object-localize.test.js +22 -0
- package/dist/backend/object-localize.test.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +101 -0
- package/dist/backend/runtime-pack-core.js +172 -0
- package/dist/backend/runtime-pack-core.js.map +1 -0
- package/dist/backend/runtime-pack-native.d.ts +21 -0
- package/dist/backend/runtime-pack-native.js +73 -0
- package/dist/backend/runtime-pack-native.js.map +1 -0
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.d.ts +3 -83
- package/dist/backend/runtime-pack.js +8 -151
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +24 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/target-diagnostics.d.ts +22 -0
- package/dist/backend/target-diagnostics.js +108 -0
- package/dist/backend/target-diagnostics.js.map +1 -0
- package/dist/backend/target-platform.d.ts +15 -0
- package/dist/backend/target-platform.js +72 -0
- package/dist/backend/target-platform.js.map +1 -0
- package/dist/backend/targets.d.ts +13 -4
- package/dist/backend/targets.js +103 -34
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +72 -4
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/backend/toolchain-environment.d.ts +6 -0
- package/dist/backend/toolchain-environment.js +99 -0
- package/dist/backend/toolchain-environment.js.map +1 -0
- package/dist/backend/vendor-archives.d.ts +1 -9
- package/dist/backend/vendor-archives.js +2 -9
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.d.ts +9 -0
- package/dist/backend/vendor-inputs.js +10 -0
- package/dist/backend/vendor-inputs.js.map +1 -0
- package/dist/backend/warm-cache.d.ts +3 -0
- package/dist/backend/warm-cache.js +41 -0
- package/dist/backend/warm-cache.js.map +1 -0
- package/dist/cli/command.d.ts +3 -0
- package/dist/cli/command.js +328 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/host.d.ts +24 -0
- package/dist/cli/host.js +2 -0
- package/dist/cli/host.js.map +1 -0
- package/dist/cli/output-options.d.ts +26 -0
- package/dist/cli/output-options.js +60 -0
- package/dist/cli/output-options.js.map +1 -0
- package/dist/cli/paths.d.ts +12 -0
- package/dist/cli/paths.js +42 -0
- package/dist/cli/paths.js.map +1 -0
- package/dist/cli/usage.d.ts +74 -0
- package/dist/cli/usage.js +86 -0
- package/dist/cli/usage.js.map +1 -0
- package/dist/cli/wasi-paths.d.ts +8 -0
- package/dist/cli/wasi-paths.js +41 -0
- package/dist/cli/wasi-paths.js.map +1 -0
- package/dist/cli/wasi-runner.d.ts +2 -0
- package/dist/cli/wasi-runner.js +28 -0
- package/dist/cli/wasi-runner.js.map +1 -0
- package/dist/compat/fetch-profile.js +37 -7
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +162 -0
- package/dist/compile-types.js +2 -0
- package/dist/compile-types.js.map +1 -0
- package/dist/coverage/report.js +11 -5
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +5 -2
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +5 -10
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +3 -4
- package/dist/executable/executable-cache.js +5 -6
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +16 -17
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.d.ts +14 -0
- package/dist/executable/prepare.js +66 -0
- package/dist/executable/prepare.js.map +1 -0
- package/dist/ffi/ffi-manifest.d.ts +11 -4
- package/dist/ffi/ffi-manifest.js +170 -58
- package/dist/ffi/ffi-manifest.js.map +1 -1
- package/dist/ffi/ffi-manifest.test.d.ts +1 -0
- package/dist/ffi/ffi-manifest.test.js +111 -0
- package/dist/ffi/ffi-manifest.test.js.map +1 -0
- package/dist/format-integer.d.ts +3 -0
- package/dist/format-integer.js +14 -0
- package/dist/format-integer.js.map +1 -0
- package/dist/frontend/analysis.d.ts +5 -0
- package/dist/frontend/analysis.js +88 -0
- package/dist/frontend/analysis.js.map +1 -0
- package/dist/frontend/arguments-usage.d.ts +1 -3
- package/dist/frontend/arguments-usage.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +1 -1
- package/dist/frontend/builtin-modules.js +1 -1
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/cjs-lexer.d.ts +4 -25
- package/dist/frontend/cjs-lexer.js +6 -806
- package/dist/frontend/cjs-lexer.js.map +1 -1
- package/dist/frontend/cjs-resolve.d.ts +5 -0
- package/dist/frontend/cjs-resolve.js +429 -0
- package/dist/frontend/cjs-resolve.js.map +1 -0
- package/dist/frontend/cjs-syntax.d.ts +26 -0
- package/dist/frontend/cjs-syntax.js +806 -0
- package/dist/frontend/cjs-syntax.js.map +1 -0
- package/dist/frontend/comptime-node.d.ts +4 -0
- package/dist/frontend/comptime-node.js +16 -0
- package/dist/frontend/comptime-node.js.map +1 -0
- package/dist/frontend/comptime-node.test.d.ts +1 -0
- package/dist/frontend/comptime-node.test.js +37 -0
- package/dist/frontend/comptime-node.test.js.map +1 -0
- package/dist/frontend/dts-paths.d.ts +3 -4
- package/dist/frontend/dts-paths.js +15 -8
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/fork-target.js +2 -2
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/helper-tokens.d.ts +1 -0
- package/dist/frontend/helper-tokens.js +147 -0
- package/dist/frontend/helper-tokens.js.map +1 -0
- package/dist/frontend/helper-tokens.test.d.ts +1 -0
- package/dist/frontend/helper-tokens.test.js +35 -0
- package/dist/frontend/helper-tokens.test.js.map +1 -0
- package/dist/frontend/inferred-js-diagnostics.d.ts +5 -0
- package/dist/frontend/inferred-js-diagnostics.js +69 -0
- package/dist/frontend/inferred-js-diagnostics.js.map +1 -0
- package/dist/frontend/inferred-js-diagnostics.test.d.ts +1 -0
- package/dist/frontend/inferred-js-diagnostics.test.js +58 -0
- package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -0
- package/dist/frontend/input-tracker.d.ts +5 -2
- package/dist/frontend/input-tracker.js +24 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +23 -0
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lib-contract.js +32 -24
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/literal-values.d.ts +4 -0
- package/dist/frontend/literal-values.js +21 -0
- package/dist/frontend/literal-values.js.map +1 -0
- package/dist/frontend/literal-values.test.d.ts +1 -0
- package/dist/frontend/literal-values.test.js +91 -0
- package/dist/frontend/literal-values.test.js.map +1 -0
- package/dist/frontend/lowering/abstract-equality.d.ts +1 -1
- package/dist/frontend/lowering/abstract-equality.js +3 -0
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-indexed-mutation.js +11 -6
- package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +4 -1
- package/dist/frontend/lowering/array-values.js +43 -1
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/callback-arg.js +1 -0
- package/dist/frontend/lowering/callback-arg.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +12 -0
- package/dist/frontend/lowering/class-callbacks.js +74 -0
- package/dist/frontend/lowering/class-callbacks.js.map +1 -0
- package/dist/frontend/lowering/class-construction.d.ts +12 -0
- package/dist/frontend/lowering/class-construction.js +156 -0
- package/dist/frontend/lowering/class-construction.js.map +1 -0
- package/dist/frontend/lowering/class-descriptors.d.ts +10 -0
- package/dist/frontend/lowering/class-descriptors.js +114 -0
- package/dist/frontend/lowering/class-descriptors.js.map +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +51 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1158 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.d.ts +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +93 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -0
- package/dist/frontend/lowering/class-instance-constructor.d.ts +7 -0
- package/dist/frontend/lowering/class-instance-constructor.js +67 -0
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -0
- package/dist/frontend/lowering/class-method-values.d.ts +13 -0
- package/dist/frontend/lowering/class-method-values.js +235 -0
- package/dist/frontend/lowering/class-method-values.js.map +1 -0
- package/dist/frontend/lowering/class-prototypes.d.ts +19 -0
- package/dist/frontend/lowering/class-prototypes.js +242 -0
- package/dist/frontend/lowering/class-prototypes.js.map +1 -0
- package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
- package/dist/frontend/lowering/class-runtime-statics.js +66 -0
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
- package/dist/frontend/lowering/class-static-data.d.ts +6 -0
- package/dist/frontend/lowering/class-static-data.js +56 -0
- package/dist/frontend/lowering/class-static-data.js.map +1 -0
- package/dist/frontend/lowering/containers/buffer-numeric-methods.d.ts +4 -0
- package/dist/frontend/lowering/containers/buffer-numeric-methods.js +26 -0
- package/dist/frontend/lowering/containers/buffer-numeric-methods.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.d.ts +11 -7
- package/dist/frontend/lowering/containers/bytes.js +208 -163
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +2 -2
- package/dist/frontend/lowering/containers/string-and-regexp.js +58 -63
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.d.ts +7 -0
- package/dist/frontend/lowering/containers/string-replacement.js +217 -0
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -0
- package/dist/frontend/lowering/error-methods.d.ts +14 -0
- package/dist/frontend/lowering/error-methods.js +177 -0
- package/dist/frontend/lowering/error-methods.js.map +1 -0
- package/dist/frontend/lowering/expressions/global-symbols.d.ts +6 -0
- package/dist/frontend/lowering/expressions/global-symbols.js +11 -0
- package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -0
- package/dist/frontend/lowering/expressions/native-proxy.d.ts +7 -0
- package/dist/frontend/lowering/expressions/native-proxy.js +51 -0
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.d.ts +6 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js +132 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -0
- package/dist/frontend/lowering/expressions/object-literals.d.ts +8 -8
- package/dist/frontend/lowering/expressions/object-literals.js +509 -183
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
- package/dist/frontend/lowering/expressions/optional-chains.js +88 -24
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/try-lower-expression.js +1 -0
- package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-field-write.d.ts +8 -0
- package/dist/frontend/lowering/expressions/union-field-write.js +71 -0
- package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -0
- package/dist/frontend/lowering/function-context.d.ts +101 -0
- package/dist/frontend/lowering/function-context.js +109 -0
- package/dist/frontend/lowering/function-context.js.map +1 -0
- package/dist/frontend/lowering/generator-delegation.d.ts +7 -0
- package/dist/frontend/lowering/generator-delegation.js +85 -0
- package/dist/frontend/lowering/generator-delegation.js.map +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +11 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +143 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.d.ts +4 -1
- package/dist/frontend/lowering/lib-boundary.js +112 -20
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.test.d.ts +1 -0
- package/dist/frontend/lowering/lib-boundary.test.js +45 -0
- package/dist/frontend/lowering/lib-boundary.test.js.map +1 -0
- package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
- package/dist/frontend/lowering/lower-assert.d.ts +1 -1
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +18 -0
- package/dist/frontend/lowering/lower-builtin-values.js +249 -0
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.d.ts +33 -46
- package/dist/frontend/lowering/lower-builtins.js +676 -365
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +28 -22
- package/dist/frontend/lowering/lower-calls.js +1660 -412
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +95 -57
- package/dist/frontend/lowering/lower-classes.js +1491 -404
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +1 -1
- package/dist/frontend/lowering/lower-comptime.js +23 -32
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +36 -32
- package/dist/frontend/lowering/lower-containers.js +925 -181
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +1 -1
- package/dist/frontend/lowering/lower-dgram.js +3 -2
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.d.ts +1 -1
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +30 -1
- package/dist/frontend/lowering/lower-event-emitter.js +58 -26
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.d.ts +7 -1
- package/dist/frontend/lowering/lower-expando.js +14 -6
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +37 -13
- package/dist/frontend/lowering/lower-exprs.js +2163 -863
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +2 -5
- package/dist/frontend/lowering/lower-generators.js +88 -46
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.d.ts +7 -0
- package/dist/frontend/lowering/lower-global-value.js +17 -0
- package/dist/frontend/lowering/lower-global-value.js.map +1 -0
- package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
- package/dist/frontend/lowering/lower-inspect.js +17 -8
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +7 -8
- package/dist/frontend/lowering/lower-island.js +66 -33
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.d.ts +2 -2
- package/dist/frontend/lowering/lower-mixins.js +5 -3
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +1 -1
- package/dist/frontend/lowering/lower-modules.js +445 -39
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-modules.test.js +39 -0
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
- package/dist/frontend/lowering/lower-namespaces.d.ts +1 -1
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +1 -1
- package/dist/frontend/lowering/lower-node-module.js +13 -10
- package/dist/frontend/lowering/lower-node-module.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +1 -1
- package/dist/frontend/lowering/lower-server.js +6 -10
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +17 -17
- package/dist/frontend/lowering/lower-stmts.js +855 -514
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +1 -1
- package/dist/frontend/lowering/lower-stream.js +20 -11
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +1 -1
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lower-url.d.ts +6 -0
- package/dist/frontend/lowering/lower-url.js +77 -0
- package/dist/frontend/lowering/lower-url.js.map +1 -0
- package/dist/frontend/lowering/lowerer.d.ts +140 -190
- package/dist/frontend/lowering/lowerer.js +1193 -712
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.d.ts +1 -0
- package/dist/frontend/lowering/lowerer.test.js +172 -0
- package/dist/frontend/lowering/lowerer.test.js.map +1 -0
- package/dist/frontend/lowering/native-ffi.d.ts +5 -0
- package/dist/frontend/lowering/native-ffi.js +40 -0
- package/dist/frontend/lowering/native-ffi.js.map +1 -0
- package/dist/frontend/lowering/object-enumeration-receiver.d.ts +7 -0
- package/dist/frontend/lowering/object-enumeration-receiver.js +33 -0
- package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -0
- package/dist/frontend/lowering/object-factory-new.d.ts +8 -0
- package/dist/frontend/lowering/object-factory-new.js +68 -0
- package/dist/frontend/lowering/object-factory-new.js.map +1 -0
- package/dist/frontend/lowering/optional-arguments.js +6 -1
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.js +2 -1
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-locals.d.ts +14 -0
- package/dist/frontend/lowering/runtime-optional-locals.js +41 -0
- package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-locals.test.d.ts +1 -0
- package/dist/frontend/lowering/runtime-optional-locals.test.js +85 -0
- package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -0
- package/dist/frontend/lowering/sanitize-class-types.d.ts +8 -0
- package/dist/frontend/lowering/sanitize-class-types.js +79 -0
- package/dist/frontend/lowering/sanitize-class-types.js.map +1 -0
- package/dist/frontend/lowering/sanitize-class-types.test.d.ts +1 -0
- package/dist/frontend/lowering/sanitize-class-types.test.js +60 -0
- package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -0
- package/dist/frontend/lowering/static-this.d.ts +5 -1
- package/dist/frontend/lowering/static-this.js +28 -2
- package/dist/frontend/lowering/static-this.js.map +1 -1
- package/dist/frontend/lowering/string-index.d.ts +7 -0
- package/dist/frontend/lowering/string-index.js +39 -0
- package/dist/frontend/lowering/string-index.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +10 -3
- package/dist/frontend/lowering/surfaces.js +86 -37
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +22 -0
- package/dist/frontend/lowering/symbol-fields.js +183 -0
- package/dist/frontend/lowering/symbol-fields.js.map +1 -0
- package/dist/frontend/lowering/symbol-methods.d.ts +7 -0
- package/dist/frontend/lowering/symbol-methods.js +30 -0
- package/dist/frontend/lowering/symbol-methods.js.map +1 -0
- package/dist/frontend/lowering/text-decoder-encoding.d.ts +12 -0
- package/dist/frontend/lowering/text-decoder-encoding.js +82 -0
- package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -0
- package/dist/frontend/lowering/text-decoder-encoding.test.d.ts +1 -0
- package/dist/frontend/lowering/text-decoder-encoding.test.js +38 -0
- package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -0
- package/dist/frontend/lowering/union-narrow.d.ts +9 -0
- package/dist/frontend/lowering/union-narrow.js +59 -0
- package/dist/frontend/lowering/union-narrow.js.map +1 -0
- package/dist/frontend/lowering/union-narrow.test.d.ts +1 -0
- package/dist/frontend/lowering/union-narrow.test.js +72 -0
- package/dist/frontend/lowering/union-narrow.test.js.map +1 -0
- package/dist/frontend/lowering/union-retag.d.ts +43 -0
- package/dist/frontend/lowering/union-retag.js +259 -0
- package/dist/frontend/lowering/union-retag.js.map +1 -0
- package/dist/frontend/lowering/union-retag.test.d.ts +1 -0
- package/dist/frontend/lowering/union-retag.test.js +405 -0
- package/dist/frontend/lowering/union-retag.test.js.map +1 -0
- package/dist/frontend/lowering/unregistered-class-types.d.ts +14 -0
- package/dist/frontend/lowering/unregistered-class-types.js +94 -0
- package/dist/frontend/lowering/unregistered-class-types.js.map +1 -0
- package/dist/frontend/lowering/unregistered-class-types.test.d.ts +1 -0
- package/dist/frontend/lowering/unregistered-class-types.test.js +65 -0
- package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -0
- package/dist/frontend/lowering/width-lift.d.ts +40 -0
- package/dist/frontend/lowering/width-lift.js +2 -0
- package/dist/frontend/lowering/width-lift.js.map +1 -0
- package/dist/frontend/module-syntax.d.ts +58 -0
- package/dist/frontend/module-syntax.js +123 -0
- package/dist/frontend/module-syntax.js.map +1 -0
- package/dist/frontend/module-syntax.test.d.ts +1 -0
- package/dist/frontend/module-syntax.test.js +78 -0
- package/dist/frontend/module-syntax.test.js.map +1 -0
- package/dist/frontend/npm-fetch-analysis.d.ts +17 -0
- package/dist/frontend/npm-fetch-analysis.js +100 -0
- package/dist/frontend/npm-fetch-analysis.js.map +1 -0
- package/dist/frontend/npm-fetch-analysis.test.d.ts +1 -0
- package/dist/frontend/npm-fetch-analysis.test.js +107 -0
- package/dist/frontend/npm-fetch-analysis.test.js.map +1 -0
- package/dist/frontend/npm-fetch-node.d.ts +2 -0
- package/dist/frontend/npm-fetch-node.js +12 -0
- package/dist/frontend/npm-fetch-node.js.map +1 -0
- package/dist/frontend/npm-fetch-syntax.d.ts +6 -0
- package/dist/frontend/npm-fetch-syntax.js +207 -0
- package/dist/frontend/npm-fetch-syntax.js.map +1 -0
- package/dist/frontend/npm-node.d.ts +10 -0
- package/dist/frontend/npm-node.js +14 -0
- package/dist/frontend/npm-node.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.d.ts +8 -0
- package/dist/frontend/npm-static-bundled-cjs.js +236 -0
- package/dist/frontend/npm-static-bundled-cjs.js.map +1 -0
- package/dist/frontend/npm-static-bundled-cjs.test.d.ts +1 -0
- package/dist/frontend/npm-static-bundled-cjs.test.js +69 -0
- package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -0
- package/dist/frontend/npm-static-declaration-syntax.d.ts +57 -0
- package/dist/frontend/npm-static-declaration-syntax.js +944 -0
- package/dist/frontend/npm-static-declaration-syntax.js.map +1 -0
- package/dist/frontend/npm-static-declarations.d.ts +11 -39
- package/dist/frontend/npm-static-declarations.js +22 -561
- package/dist/frontend/npm-static-declarations.js.map +1 -1
- package/dist/frontend/npm-static-declarations.test.js +245 -6
- package/dist/frontend/npm-static-declarations.test.js.map +1 -1
- package/dist/frontend/npm-static-prune.d.ts +1 -1
- package/dist/frontend/npm-static-prune.js +121 -38
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-prune.test.js +9 -1
- package/dist/frontend/npm-static-prune.test.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-host.d.ts +4 -0
- package/dist/frontend/npm-static-rewrite-host.js +179 -0
- package/dist/frontend/npm-static-rewrite-host.js.map +1 -0
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +16 -0
- package/dist/frontend/npm-static-rewrite-syntax.js +905 -0
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -0
- package/dist/frontend/npm-static-rewrite.d.ts +0 -5
- package/dist/frontend/npm-static-rewrite.js +2 -1079
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static-subtyping.d.ts +5 -0
- package/dist/frontend/npm-static-subtyping.js +55 -0
- package/dist/frontend/npm-static-subtyping.js.map +1 -0
- package/dist/frontend/npm-static-subtyping.test.d.ts +1 -0
- package/dist/frontend/npm-static-subtyping.test.js +58 -0
- package/dist/frontend/npm-static-subtyping.test.js.map +1 -0
- package/dist/frontend/npm-static.d.ts +7 -15
- package/dist/frontend/npm-static.js +19 -28
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +8 -69
- package/dist/frontend/npm.js +21 -361
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +2 -2
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/pipeline-native.d.ts +6 -0
- package/dist/frontend/pipeline-native.js +32 -0
- package/dist/frontend/pipeline-native.js.map +1 -0
- package/dist/frontend/pipeline.d.ts +54 -0
- package/dist/frontend/pipeline.js +382 -0
- package/dist/frontend/pipeline.js.map +1 -0
- package/dist/frontend/pipeline.test.d.ts +1 -0
- package/dist/frontend/pipeline.test.js +77 -0
- package/dist/frontend/pipeline.test.js.map +1 -0
- package/dist/frontend/program-analysis.d.ts +10 -0
- package/dist/frontend/program-analysis.js +14 -0
- package/dist/frontend/program-analysis.js.map +1 -0
- package/dist/frontend/program-node.d.ts +9 -0
- package/dist/frontend/program-node.js +48 -0
- package/dist/frontend/program-node.js.map +1 -0
- package/dist/frontend/program.d.ts +39 -20
- package/dist/frontend/program.js +393 -189
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +105 -2
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/provenance-core.d.ts +9 -0
- package/dist/frontend/provenance-core.js +435 -0
- package/dist/frontend/provenance-core.js.map +1 -0
- package/dist/frontend/provenance.d.ts +0 -4
- package/dist/frontend/provenance.js +4 -459
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/resolve.d.ts +3 -1
- package/dist/frontend/resolve.js +6 -3
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.d.ts +4 -3
- package/dist/frontend/runtime-resolve.js +22 -18
- package/dist/frontend/runtime-resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.test.js +53 -0
- package/dist/frontend/runtime-resolve.test.js.map +1 -1
- package/dist/frontend/services-node.d.ts +5 -0
- package/dist/frontend/services-node.js +19 -0
- package/dist/frontend/services-node.js.map +1 -0
- package/dist/frontend/services-node.test.d.ts +1 -0
- package/dist/frontend/services-node.test.js +70 -0
- package/dist/frontend/services-node.test.js.map +1 -0
- package/dist/frontend/services.d.ts +44 -0
- package/dist/frontend/services.js +90 -0
- package/dist/frontend/services.js.map +1 -0
- package/dist/frontend/services.test.d.ts +1 -0
- package/dist/frontend/services.test.js +174 -0
- package/dist/frontend/services.test.js.map +1 -0
- package/dist/frontend/ts7/adapter.d.ts +3 -3
- package/dist/frontend/ts7/adapter.js +14 -31
- package/dist/frontend/ts7/adapter.js.map +1 -1
- package/dist/frontend/ts7/api.d.ts +16 -0
- package/dist/frontend/ts7/api.js +24 -0
- package/dist/frontend/ts7/api.js.map +1 -0
- package/dist/frontend/ts7/ast-bytes.d.ts +31 -0
- package/dist/frontend/ts7/ast-bytes.js +137 -0
- package/dist/frontend/ts7/ast-bytes.js.map +1 -0
- package/dist/frontend/ts7/ast-bytes.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-bytes.test.js +73 -0
- package/dist/frontend/ts7/ast-bytes.test.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.generated.d.ts +353 -0
- package/dist/frontend/ts7/ast-guards.generated.js +1951 -0
- package/dist/frontend/ts7/ast-guards.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-guards.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-guards.test.js +43 -0
- package/dist/frontend/ts7/ast-guards.test.js.map +1 -0
- package/dist/frontend/ts7/ast-node.d.ts +194 -0
- package/dist/frontend/ts7/ast-node.js +448 -0
- package/dist/frontend/ts7/ast-node.js.map +1 -0
- package/dist/frontend/ts7/ast-node.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-node.test.js +266 -0
- package/dist/frontend/ts7/ast-node.test.js.map +1 -0
- package/dist/frontend/ts7/ast-schema.generated.d.ts +503 -0
- package/dist/frontend/ts7/ast-schema.generated.js +1446 -0
- package/dist/frontend/ts7/ast-schema.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-text.d.ts +6 -0
- package/dist/frontend/ts7/ast-text.js +124 -0
- package/dist/frontend/ts7/ast-text.js.map +1 -0
- package/dist/frontend/ts7/ast-text.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-text.test.js +38 -0
- package/dist/frontend/ts7/ast-text.test.js.map +1 -0
- package/dist/frontend/ts7/ast-tokens.generated.d.ts +2 -0
- package/dist/frontend/ts7/ast-tokens.generated.js +155 -0
- package/dist/frontend/ts7/ast-tokens.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-types.d.ts +42 -0
- package/dist/frontend/ts7/ast-types.generated.d.ts +1615 -0
- package/dist/frontend/ts7/ast-types.generated.js +5 -0
- package/dist/frontend/ts7/ast-types.generated.js.map +1 -0
- package/dist/frontend/ts7/ast-types.js +3 -0
- package/dist/frontend/ts7/ast-types.js.map +1 -0
- package/dist/frontend/ts7/ast-wire.d.ts +58 -0
- package/dist/frontend/ts7/ast-wire.js +267 -0
- package/dist/frontend/ts7/ast-wire.js.map +1 -0
- package/dist/frontend/ts7/ast-wire.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-wire.test.js +151 -0
- package/dist/frontend/ts7/ast-wire.test.js.map +1 -0
- package/dist/frontend/ts7/ast.d.ts +14 -14
- package/dist/frontend/ts7/ast.js +25 -18
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/census-check.js +1 -0
- package/dist/frontend/ts7/census-check.js.map +1 -1
- package/dist/frontend/ts7/checker-cache.d.ts +48 -0
- package/dist/frontend/ts7/checker-cache.js +92 -0
- package/dist/frontend/ts7/checker-cache.js.map +1 -0
- package/dist/frontend/ts7/checker.d.ts +19 -46
- package/dist/frontend/ts7/checker.js +231 -161
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.d.ts +1 -0
- package/dist/frontend/ts7/checker.test.js +335 -0
- package/dist/frontend/ts7/checker.test.js.map +1 -0
- package/dist/frontend/ts7/enums.d.ts +4 -27
- package/dist/frontend/ts7/enums.generated.d.ts +878 -0
- package/dist/frontend/ts7/enums.generated.js +1313 -0
- package/dist/frontend/ts7/enums.generated.js.map +1 -0
- package/dist/frontend/ts7/enums.js +4 -45
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/enums.test.d.ts +1 -0
- package/dist/frontend/ts7/enums.test.js +48 -0
- package/dist/frontend/ts7/enums.test.js.map +1 -0
- package/dist/frontend/ts7/native-api.d.ts +10 -0
- package/dist/frontend/ts7/native-api.js +10 -0
- package/dist/frontend/ts7/native-api.js.map +1 -0
- package/dist/frontend/ts7/native-host.d.ts +2 -0
- package/dist/frontend/ts7/native-host.js +11 -0
- package/dist/frontend/ts7/native-host.js.map +1 -0
- package/dist/frontend/ts7/native-process.d.ts +14 -0
- package/dist/frontend/ts7/native-process.js +62 -0
- package/dist/frontend/ts7/native-process.js.map +1 -0
- package/dist/frontend/ts7/program-adapter.d.ts +10 -98
- package/dist/frontend/ts7/program-adapter.js +16 -310
- package/dist/frontend/ts7/program-adapter.js.map +1 -1
- package/dist/frontend/ts7/program-host.d.ts +115 -0
- package/dist/frontend/ts7/program-host.js +347 -0
- package/dist/frontend/ts7/program-host.js.map +1 -0
- package/dist/frontend/ts7/program-host.test.d.ts +1 -0
- package/dist/frontend/ts7/program-host.test.js +207 -0
- package/dist/frontend/ts7/program-host.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-api.d.ts +12 -0
- package/dist/frontend/ts7/rpc-api.js +23 -0
- package/dist/frontend/ts7/rpc-api.js.map +1 -0
- package/dist/frontend/ts7/rpc-client.d.ts +27 -0
- package/dist/frontend/ts7/rpc-client.js +102 -0
- package/dist/frontend/ts7/rpc-client.js.map +1 -0
- package/dist/frontend/ts7/rpc-client.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-client.test.js +133 -0
- package/dist/frontend/ts7/rpc-client.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-filesystem.d.ts +16 -0
- package/dist/frontend/ts7/rpc-filesystem.js +42 -0
- package/dist/frontend/ts7/rpc-filesystem.js.map +1 -0
- package/dist/frontend/ts7/rpc-filesystem.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-filesystem.test.js +89 -0
- package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-process.d.ts +2 -0
- package/dist/frontend/ts7/rpc-process.js +148 -0
- package/dist/frontend/ts7/rpc-process.js.map +1 -0
- package/dist/frontend/ts7/rpc-process.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-process.test.js +29 -0
- package/dist/frontend/ts7/rpc-process.test.js.map +1 -0
- package/dist/frontend/ts7/rpc-wire.d.ts +46 -0
- package/dist/frontend/ts7/rpc-wire.js +195 -0
- package/dist/frontend/ts7/rpc-wire.js.map +1 -0
- package/dist/frontend/ts7/rpc-wire.test.d.ts +1 -0
- package/dist/frontend/ts7/rpc-wire.test.js +168 -0
- package/dist/frontend/ts7/rpc-wire.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-checker.d.ts +137 -0
- package/dist/frontend/ts7/semantic-checker.js +221 -0
- package/dist/frontend/ts7/semantic-checker.js.map +1 -0
- package/dist/frontend/ts7/semantic-checker.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-checker.test.js +119 -0
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-json.d.ts +5 -0
- package/dist/frontend/ts7/semantic-json.js +47 -0
- package/dist/frontend/ts7/semantic-json.js.map +1 -0
- package/dist/frontend/ts7/semantic-json.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-json.test.js +42 -0
- package/dist/frontend/ts7/semantic-json.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-model.d.ts +222 -0
- package/dist/frontend/ts7/semantic-model.js +423 -0
- package/dist/frontend/ts7/semantic-model.js.map +1 -0
- package/dist/frontend/ts7/semantic-model.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-model.test.js +322 -0
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-schema.generated.d.ts +283 -0
- package/dist/frontend/ts7/semantic-schema.generated.js +222 -0
- package/dist/frontend/ts7/semantic-schema.generated.js.map +1 -0
- package/dist/frontend/ts7/semantic-types.d.ts +5 -0
- package/dist/frontend/ts7/semantic-types.js +2 -0
- package/dist/frontend/ts7/semantic-types.js.map +1 -0
- package/dist/frontend/ts7/session-cache.d.ts +17 -0
- package/dist/frontend/ts7/session-cache.js +97 -0
- package/dist/frontend/ts7/session-cache.js.map +1 -0
- package/dist/frontend/ts7/session-cache.test.d.ts +1 -0
- package/dist/frontend/ts7/session-cache.test.js +87 -0
- package/dist/frontend/ts7/session-cache.test.js.map +1 -0
- package/dist/frontend/ts7/session-path.d.ts +18 -0
- package/dist/frontend/ts7/session-path.js +203 -0
- package/dist/frontend/ts7/session-path.js.map +1 -0
- package/dist/frontend/ts7/session-path.test.d.ts +1 -0
- package/dist/frontend/ts7/session-path.test.js +34 -0
- package/dist/frontend/ts7/session-path.test.js.map +1 -0
- package/dist/frontend/ts7/session-schema.generated.d.ts +167 -0
- package/dist/frontend/ts7/session-schema.generated.js +5 -0
- package/dist/frontend/ts7/session-schema.generated.js.map +1 -0
- package/dist/frontend/ts7/session-timing.d.ts +50 -0
- package/dist/frontend/ts7/session-timing.js +61 -0
- package/dist/frontend/ts7/session-timing.js.map +1 -0
- package/dist/frontend/ts7/session-timing.test.d.ts +1 -0
- package/dist/frontend/ts7/session-timing.test.js +52 -0
- package/dist/frontend/ts7/session-timing.test.js.map +1 -0
- package/dist/frontend/ts7/session.d.ts +105 -0
- package/dist/frontend/ts7/session.js +233 -0
- package/dist/frontend/ts7/session.js.map +1 -0
- package/dist/frontend/ts7/session.test.d.ts +1 -0
- package/dist/frontend/ts7/session.test.js +215 -0
- package/dist/frontend/ts7/session.test.js.map +1 -0
- package/dist/frontend/ts7/source-parser-node.d.ts +6 -0
- package/dist/frontend/ts7/source-parser-node.js +15 -0
- package/dist/frontend/ts7/source-parser-node.js.map +1 -0
- package/dist/frontend/ts7/source-parser.d.ts +25 -0
- package/dist/frontend/ts7/source-parser.js +96 -0
- package/dist/frontend/ts7/source-parser.js.map +1 -0
- package/dist/frontend/ts7/source-parser.test.d.ts +1 -0
- package/dist/frontend/ts7/source-parser.test.js +151 -0
- package/dist/frontend/ts7/source-parser.test.js.map +1 -0
- package/dist/frontend/ts7/syntax.d.ts +3 -0
- package/dist/frontend/ts7/syntax.js +4 -0
- package/dist/frontend/ts7/syntax.js.map +1 -0
- package/dist/frontend/tsc-codes.js +3 -0
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +34 -18
- package/dist/frontend/type-mapper.js +552 -131
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.js +146 -2
- package/dist/frontend/type-mapper.test.js.map +1 -1
- package/dist/frontend/union-discriminants.d.ts +16 -0
- package/dist/frontend/union-discriminants.js +98 -0
- package/dist/frontend/union-discriminants.js.map +1 -0
- package/dist/frontend/union-discriminants.test.d.ts +1 -0
- package/dist/frontend/union-discriminants.test.js +182 -0
- package/dist/frontend/union-discriminants.test.js.map +1 -0
- package/dist/index.d.ts +7 -198
- package/dist/index.js +369 -1572
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +16 -4
- package/dist/ir/analysis.js +23 -4
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +15 -2
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/constant-tables.js +67 -49
- package/dist/ir/constant-tables.js.map +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/control-flow.d.ts +6 -0
- package/dist/ir/control-flow.js +142 -0
- package/dist/ir/control-flow.js.map +1 -0
- package/dist/ir/control-flow.test.d.ts +1 -0
- package/dist/ir/control-flow.test.js +113 -0
- package/dist/ir/control-flow.test.js.map +1 -0
- package/dist/ir/integer-loops.js +7 -18
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-ranges.js +53 -27
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/ir.d.ts +334 -176
- package/dist/ir/ir.js +710 -903
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +162 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/scalar-records.js +165 -134
- package/dist/ir/scalar-records.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/serialize.d.ts +4 -2
- package/dist/ir/serialize.js +33 -14
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.d.ts +1 -0
- package/dist/ir/serialize.test.js +57 -0
- package/dist/ir/serialize.test.js.map +1 -0
- package/dist/ir/traverse.d.ts +41 -0
- package/dist/ir/traverse.js +660 -0
- package/dist/ir/traverse.js.map +1 -0
- package/dist/ir/traverse.test.d.ts +1 -0
- package/dist/ir/traverse.test.js +242 -0
- package/dist/ir/traverse.test.js.map +1 -0
- package/dist/ir/validate.js +2018 -1498
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +536 -2
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/cache-primitives.d.ts +2 -3
- package/dist/library/cache-primitives.js +4 -6
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/fence-eval.js +2 -2
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.js +7 -6
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/library-cache.d.ts +3 -2
- package/dist/library/library-cache.js +5 -17
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +54 -41
- package/dist/library/library-cache.test.js.map +1 -1
- package/dist/library/library-profile.d.ts +3 -1
- package/dist/library/library-profile.js +15 -6
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/prepare.d.ts +15 -0
- package/dist/library/prepare.js +584 -0
- package/dist/library/prepare.js.map +1 -0
- package/dist/library/semantic-source.d.ts +1 -1
- package/dist/library/semantic-source.js +8 -6
- package/dist/library/semantic-source.js.map +1 -1
- package/dist/library/sidecar-validate.js +4 -4
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.d.ts +2 -0
- package/dist/library/sidecar.js +10 -3
- package/dist/library/sidecar.js.map +1 -1
- package/dist/native/cache.d.ts +11 -0
- package/dist/native/cache.js +113 -0
- package/dist/native/cache.js.map +1 -0
- package/dist/native/cache.test.d.ts +1 -0
- package/dist/native/cache.test.js +66 -0
- package/dist/native/cache.test.js.map +1 -0
- package/dist/native/cli.d.ts +1 -0
- package/dist/native/cli.js +112 -0
- package/dist/native/cli.js.map +1 -0
- package/dist/native/compiler.d.ts +15 -0
- package/dist/native/compiler.js +336 -0
- package/dist/native/compiler.js.map +1 -0
- package/dist/native/compiler.test.d.ts +1 -0
- package/dist/native/compiler.test.js +174 -0
- package/dist/native/compiler.test.js.map +1 -0
- package/dist/native/comptime.d.ts +5 -0
- package/dist/native/comptime.js +73 -0
- package/dist/native/comptime.js.map +1 -0
- package/dist/native/comptime.test.d.ts +1 -0
- package/dist/native/comptime.test.js +65 -0
- package/dist/native/comptime.test.js.map +1 -0
- package/dist/native/executable-cache.d.ts +26 -0
- package/dist/native/executable-cache.js +228 -0
- package/dist/native/executable-cache.js.map +1 -0
- package/dist/native/executable-cache.test.d.ts +1 -0
- package/dist/native/executable-cache.test.js +151 -0
- package/dist/native/executable-cache.test.js.map +1 -0
- package/dist/native/file-identity.d.ts +4 -0
- package/dist/native/file-identity.js +14 -0
- package/dist/native/file-identity.js.map +1 -0
- package/dist/native/file-identity.test.d.ts +1 -0
- package/dist/native/file-identity.test.js +43 -0
- package/dist/native/file-identity.test.js.map +1 -0
- package/dist/native/library.d.ts +22 -0
- package/dist/native/library.js +83 -0
- package/dist/native/library.js.map +1 -0
- package/dist/native/prepare.d.ts +21 -0
- package/dist/native/prepare.js +174 -0
- package/dist/native/prepare.js.map +1 -0
- package/dist/native/prepare.test.d.ts +1 -0
- package/dist/native/prepare.test.js +70 -0
- package/dist/native/prepare.test.js.map +1 -0
- package/dist/native/sanitizer.d.ts +11 -0
- package/dist/native/sanitizer.js +137 -0
- package/dist/native/sanitizer.js.map +1 -0
- package/dist/native/sanitizer.test.d.ts +1 -0
- package/dist/native/sanitizer.test.js +58 -0
- package/dist/native/sanitizer.test.js.map +1 -0
- package/dist/native/task.d.ts +4 -0
- package/dist/native/task.js +16 -0
- package/dist/native/task.js.map +1 -0
- package/dist/native/task.test.d.ts +1 -0
- package/dist/native/task.test.js +17 -0
- package/dist/native/task.test.js.map +1 -0
- package/dist/native/toolchain.d.ts +45 -0
- package/dist/native/toolchain.js +94 -0
- package/dist/native/toolchain.js.map +1 -0
- package/dist/native/toolchain.test.d.ts +1 -0
- package/dist/native/toolchain.test.js +85 -0
- package/dist/native/toolchain.test.js.map +1 -0
- package/dist/startup-cache.d.ts +1 -1
- package/dist/startup-cache.js +2 -5
- package/dist/startup-cache.js.map +1 -1
- package/dist/timing.d.ts +4 -0
- package/dist/timing.js +19 -0
- package/dist/timing.js.map +1 -0
- package/dist/wasi-paths.js +10 -7
- package/dist/wasi-paths.js.map +1 -1
- package/package.json +28 -19
- package/surface-manifest.json +107 -98
- package/dist/backend/c/async.d.ts +0 -171
- package/dist/backend/c/async.js +0 -1317
- package/dist/backend/c/async.js.map +0 -1
- package/dist/backend/c/c-emitter.d.ts +0 -536
- package/dist/backend/c/c-emitter.js +0 -1932
- package/dist/backend/c/c-emitter.js.map +0 -1
- package/dist/backend/c/exprs.d.ts +0 -15
- package/dist/backend/c/exprs.js +0 -8847
- package/dist/backend/c/exprs.js.map +0 -1
- package/dist/backend/c/island.d.ts +0 -45
- package/dist/backend/c/island.js +0 -281
- package/dist/backend/c/island.js.map +0 -1
- package/dist/backend/c/may-throw.js.map +0 -1
- package/dist/backend/c/shapes.d.ts +0 -142
- package/dist/backend/c/shapes.js +0 -603
- package/dist/backend/c/shapes.js.map +0 -1
- package/dist/backend/c/stmts.d.ts +0 -76
- package/dist/backend/c/stmts.js +0 -1108
- package/dist/backend/c/stmts.js.map +0 -1
- package/dist/backend/c/types.d.ts +0 -71
- package/dist/backend/c/types.js +0 -459
- package/dist/backend/c/types.js.map +0 -1
- package/dist/backend/c/types.test.js +0 -32
- package/dist/backend/c/types.test.js.map +0 -1
- package/dist/backend/c/walkers.d.ts +0 -134
- package/dist/backend/c/walkers.js +0 -1772
- package/dist/backend/c/walkers.js.map +0 -1
- /package/dist/backend/{c/types.test.d.ts → cycle-analysis.test.d.ts} +0 -0
|
@@ -1,81 +1,40 @@
|
|
|
1
|
+
import { emitLlvmLayouts } from "./layouts.js";
|
|
2
|
+
import { llvmBytes as llBytes } from "../literals.js";
|
|
1
3
|
import { InternalCompilerError } from "../../errors.js";
|
|
2
|
-
|
|
3
|
-
* IrModule the C backend does (never the JSON dump — see the -0 lesson in
|
|
4
|
-
* the survey). Its textual module is either lowered by scriptc's native
|
|
5
|
-
* helper and linked with a runtime pack or occupies the legacy compiler
|
|
6
|
-
* driver's program-TU seat. Both paths use the same scr_* C ABI.
|
|
4
|
+
/** Lower typed IR to LLVM, using the runtime's C ABI.
|
|
7
5
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* TIER: module globals and locals of every in-tier ref kind (arrays,
|
|
12
|
-
* record shapes, unions, function values/closures), the full array and
|
|
13
|
-
* string intrinsic surfaces, per-record-shape RC helpers (cycle headers
|
|
14
|
-
* included — the C emitter's fixpoint, ported in shapes.ts), tagged-union
|
|
15
|
-
* construction/narrowing/equality with interned immortal unit instances,
|
|
16
|
-
* capture boxes and the closure calling convention, switch/for-of
|
|
17
|
-
* lowering, and the non-throwing slice of the libCall table. EVERYTHING
|
|
18
|
-
* ELSE REFUSES loudly at the first unhandled node (LlvmUnsupportedError
|
|
19
|
-
* naming the kind) — this backend never guesses and never emits wrong
|
|
20
|
-
* code for a construct it does not model. compile() surfaces the refusal
|
|
21
|
-
* as diagnostic SC3001.
|
|
6
|
+
* Reference-counted temporaries own one reference. Declarations, assignments,
|
|
7
|
+
* returns and arguments move that ownership; frame and scope exits release
|
|
8
|
+
* everything remaining. Slot-backed entries release the slot's current value.
|
|
22
9
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* callees own their params; return/break/continue release everything the
|
|
29
|
-
* jump bypasses (releaseForJump). Releases are type-directed through
|
|
30
|
-
* shapes.ts (the releaseCallC table's LLVM twin); frame entries can be
|
|
31
|
-
* SLOT-based (the entry names a pointer whose CURRENT value releases —
|
|
32
|
-
* conditional results like optional chains need that indirection).
|
|
10
|
+
* Exceptions use a pending flag and explicit cleanup edges. Throwing calls
|
|
11
|
+
* test scr_exc_pending before consuming results, release the scopes crossed,
|
|
12
|
+
* and branch to the innermost handler or return to the caller. Catch bindings
|
|
13
|
+
* hold ScrCaught snapshots; finally runs on normal, throwing and returning
|
|
14
|
+
* paths. This keeps ownership cleanup intact without nonlocal jumps.
|
|
33
15
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* scr_exc_pending() and unwinds — releasing frames/scopes down to the
|
|
39
|
-
* innermost try handler's depths and branching to its label, or releasing
|
|
40
|
-
* everything and returning a dummy value (never read: callers of a
|
|
41
|
-
* may-throw function test the flag before using the result). No
|
|
42
|
-
* setjmp/longjmp: longjmp would skip the emitted RC releases. try/catch
|
|
43
|
-
* follows stmts.ts's shape exactly — a compile-time tryStack entry
|
|
44
|
-
* per region, the catch block taking the exception (scr_exc_take into the
|
|
45
|
-
* binding's snapshot box, or scr_exc_clear for the bindingless form), the
|
|
46
|
-
* finally body emitted once per path (normal, exception-with-stash,
|
|
47
|
-
* pending-return) with fresh temps each time. Catch bindings ride
|
|
48
|
-
* ScrCaught snapshot boxes (caughtTest/caughtNarrow/caughtCheck read
|
|
49
|
-
* them); TDZ reads test the box's payload slot and throw Node's
|
|
50
|
-
* ReferenceError. main() gains the uncaught epilogue when the entry
|
|
51
|
-
* function may throw.
|
|
52
|
-
*
|
|
53
|
-
* The dyn surface (phase 5): ScrDyn dyn values are in the tier — dyn.ts
|
|
54
|
-
* ports walkers.ts's dyn slice (match/check/toDyn walkers, the
|
|
55
|
-
* String(unknown)/caught→dyn/keyed-read singletons, the checked-dynamic
|
|
56
|
-
* function boundary's thunk/box/adapter triple) and the emitter lowers
|
|
57
|
-
* the dyn expression kinds (dynFrom/dynCall/dynInvoke/dynTest/dynKeyGet/
|
|
58
|
-
* dynCheck/destructuring), the JSON.parse family, dyn record fields and
|
|
59
|
-
* overflow maps, dyn capture boxes, and generator unknown channels.
|
|
60
|
-
* The island surface (jsval/jsExit and embedded npm tables) is in the
|
|
61
|
-
* tier too; the module text and resolution tables use the same compressed,
|
|
62
|
-
* lazy-inflate representation as the C debugging backend.
|
|
16
|
+
* Program objects are emitted by the packaged LLVM helper and linked with
|
|
17
|
+
* runtime packs. Sanitizer development builds use an external LLVM driver.
|
|
18
|
+
* Dynamic values and islands share the runtime ABI; embedded npm modules use
|
|
19
|
+
* compressed source tables that the runtime inflates on demand.
|
|
63
20
|
*/
|
|
64
21
|
import { deflateRawSync } from "node:zlib";
|
|
65
22
|
import { endsWithJump, matchStringSelfConcat, streamTypedRefEligible } from "../../ir/analysis.js";
|
|
66
23
|
import { emitLibraryIdentityLines } from "../library-identity-markers.js";
|
|
67
|
-
import { CAUGHT, ffiCallbackType, isDynTypedRefType, isFfiContextParam, isRefCounted, isUnitType, moduleEmbedsBuiltin, moduleEmbedsCompressedNpm,
|
|
24
|
+
import { CAUGHT, ffiCallbackType, isDynTypedRefType, isFfiContextParam, isRefCounted, isUnitType, moduleRuntimeFeatures, moduleEmbedsBuiltin, moduleEmbedsCompressedNpm, NPM_COMPRESS_MIN, POINTER_KINDS, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, typeKey, VOID } from "../../ir/ir.js";
|
|
68
25
|
import { matchIntegerBytesForLoop } from "../../ir/integer-loops.js";
|
|
69
26
|
import { scalarizeNumericRecords } from "../../ir/scalar-records.js";
|
|
27
|
+
import { everyStmtList } from "../../ir/traverse.js";
|
|
70
28
|
import { analyzeIntegerRanges } from "../../ir/integer-ranges.js";
|
|
71
29
|
import { findConstantNumericTables } from "../../ir/constant-tables.js";
|
|
72
30
|
import { allocateFfiCallbackAdapters, hasForeignFfiCallback, hasRetainedFfiCallback } from "../ffi-callbacks.js";
|
|
73
31
|
import { RUNTIME_ABI_MARKER } from "../runtime-abi.js";
|
|
74
|
-
import { computeMayThrow } from "../
|
|
75
|
-
import { mangleArgPack, mangleAsyncSpawn, mangleClassObj, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordStruct, mangleTrampoline, mangleWrapper } from "../mangle.js";
|
|
32
|
+
import { computeMayThrow } from "../may-throw.js";
|
|
33
|
+
import { mangleArgPack, mangleAsyncSpawn, mangleClassObj, mangleClassStruct, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordStruct, mangleTrampoline, mangleWrapper, mangleVtInstance } from "../mangle.js";
|
|
76
34
|
import { BlockBuilder } from "./blocks.js";
|
|
77
35
|
import { LlvmDebugInfo } from "./debug-info.js";
|
|
78
|
-
import { f64Lit, ffiNativeTypeLl, llvmCommentText } from "./common.js";
|
|
36
|
+
import { f64Lit, ffiNativeTypeLl, ffiNativeParamLl, ffiNativeReturnLl, llvmCommentText } from "./common.js";
|
|
37
|
+
import { ffiExtendsNarrowIntegers } from "../targets.js";
|
|
79
38
|
import { emitLiteralExpr, emitOperatorExpr, emitStringExpr, emitContainerExpr, emitRecordExpr } from "./expr-primitives.js";
|
|
80
39
|
import { emitControlExpr } from "./expr-control.js";
|
|
81
40
|
import { emitCallExpr } from "./expr-calls.js";
|
|
@@ -94,21 +53,32 @@ import { emitChildProcessLibCall, emitAsyncContextLibCall, emitProcessLibCall, e
|
|
|
94
53
|
import { emitStreamLibCall } from "./lib-stream.js";
|
|
95
54
|
import { emitNetworkHttpLibCall } from "./lib-network.js";
|
|
96
55
|
import { emitAssertInspectLibCall, emitIoLibCall, emitGenericLibCall, emitLibCall } from "./lib-dispatch.js";
|
|
97
|
-
import { buildClassGraph, classFieldIndex, classStructSym,
|
|
56
|
+
import { buildClassGraph, classEnvironmentIndex, classFieldIndex, classStructSym, } from "./classes.js";
|
|
98
57
|
import { LlDyn } from "./dyn.js";
|
|
99
58
|
import { LlvmUnsupportedError } from "./unsupported.js";
|
|
100
59
|
import { LlWalkers } from "./walkers.js";
|
|
101
|
-
import { arrNewCall, boxAccess, boxNewCall, computeTraced, elemAccess,
|
|
60
|
+
import { arrNewCall, boxAccess, boxNewCall, computeTraced, elemAccess, FN_ATTRS, llFieldType, releaseSym, retainSym, traceArg, typedRefConstructor, vAdapters, } from "./shapes.js";
|
|
102
61
|
export { LlvmUnsupportedError } from "./unsupported.js";
|
|
103
62
|
function ffiCallbackDummyLl(callback) {
|
|
104
63
|
switch (callback.returns) {
|
|
64
|
+
case "i64":
|
|
65
|
+
case "u64":
|
|
66
|
+
return "i64 0";
|
|
67
|
+
case "pointer":
|
|
68
|
+
return "ptr null";
|
|
105
69
|
case "void":
|
|
106
70
|
return "void";
|
|
107
71
|
case "f64":
|
|
108
72
|
return "double 0.0";
|
|
73
|
+
case "f32":
|
|
74
|
+
return "float 0.0";
|
|
109
75
|
case "bool":
|
|
110
76
|
case "u8":
|
|
77
|
+
case "i8":
|
|
111
78
|
return "i8 0";
|
|
79
|
+
case "u16":
|
|
80
|
+
case "i16":
|
|
81
|
+
return "i16 0";
|
|
112
82
|
case "u32":
|
|
113
83
|
case "i32":
|
|
114
84
|
return "i32 0";
|
|
@@ -118,39 +88,28 @@ export function emitLlvmModule(mod, options = {}) {
|
|
|
118
88
|
// Keep source storage intact for debugger inspection in dev builds.
|
|
119
89
|
return new LlEmitter(options.debugSources === undefined ? scalarizeNumericRecords(mod) : mod, options).emit();
|
|
120
90
|
}
|
|
121
|
-
/** LLVM c"..." payload for a UTF-8 literal, NUL-terminated like the C
|
|
122
|
-
* emitter's flexible-array-member initializer. */
|
|
123
|
-
function llBytes(bytes) {
|
|
124
|
-
let s = "";
|
|
125
|
-
for (const b of bytes) {
|
|
126
|
-
s +=
|
|
127
|
-
b >= 0x20 && b < 0x7f && b !== 0x22 && b !== 0x5c
|
|
128
|
-
? String.fromCharCode(b)
|
|
129
|
-
: `\\${b.toString(16).padStart(2, "0").toUpperCase()}`;
|
|
130
|
-
}
|
|
131
|
-
return `${s}\\00`;
|
|
132
|
-
}
|
|
133
91
|
function llStrBytes(text) {
|
|
134
92
|
return llBytes(Buffer.from(text, "utf8"));
|
|
135
93
|
}
|
|
136
|
-
class LlEmitter {
|
|
94
|
+
export class LlEmitter {
|
|
137
95
|
mod;
|
|
138
96
|
debug;
|
|
139
97
|
debugScope = null;
|
|
140
98
|
sizeType;
|
|
99
|
+
ffiExtendNarrowIntegers;
|
|
141
100
|
cycleColorOffset;
|
|
142
101
|
wasi;
|
|
143
102
|
emitLibraryIdentity;
|
|
144
103
|
runtimeAbiMarker;
|
|
145
104
|
/** Interned string literals: UTF-8 text → { symbol, byte length } —
|
|
146
|
-
* first-use order, the
|
|
105
|
+
* first-use order, the runtime ABI’s determinism discipline. */
|
|
147
106
|
literals = new Map();
|
|
148
107
|
/** Interned unit-armed union instances: "unionId:tag" → symbol — one
|
|
149
|
-
* immortal (rc == SIZE_MAX) static per (union, unit tag)
|
|
150
|
-
*
|
|
108
|
+
* immortal (rc == SIZE_MAX) static per (union, unit tag).
|
|
109
|
+
* RC entry points and the collector skip immortals. */
|
|
151
110
|
unitInstances = new Map();
|
|
152
|
-
/**
|
|
153
|
-
* source/flags literal refs } — one immortal ScrRegex per distinct
|
|
111
|
+
/** Regex literal templates: "<flags>/<pattern>" → { symbol, interned
|
|
112
|
+
* source/flags literal refs } — one immortal ScrRegex template per distinct
|
|
154
113
|
* (pattern, flags) pair; the bytecode slot starts null and the runtime
|
|
155
114
|
* compiles it lazily on first use. The source/flags strings intern at
|
|
156
115
|
* REGISTRATION (bodies emit before the literal table flushes). */
|
|
@@ -166,10 +125,12 @@ class LlEmitter {
|
|
|
166
125
|
/** Type-directed walker functions (JSON serializers, the indent
|
|
167
126
|
* rewriter, union ToString/join) — interned per typeKey/unionId, defs
|
|
168
127
|
* flushed with the shape helpers. */
|
|
169
|
-
walkers
|
|
128
|
+
walkers;
|
|
170
129
|
/** The dyn (ScrDyn dyn) helper registry — dyn.ts's interned ports of
|
|
171
130
|
* walkers.ts's dyn slice. */
|
|
172
|
-
dyn
|
|
131
|
+
dyn;
|
|
132
|
+
/** Explicit callback boundary for standalone layout and walker stages. */
|
|
133
|
+
shapeHost;
|
|
173
134
|
/** External declarations, in first-use order. */
|
|
174
135
|
decls = new Set();
|
|
175
136
|
/** Declared functions referenced as values: each needs an env-signature
|
|
@@ -192,19 +153,20 @@ class LlEmitter {
|
|
|
192
153
|
ffiHasRetainedCallback;
|
|
193
154
|
ffiHasForeignCallback;
|
|
194
155
|
globalTypes = new Map();
|
|
156
|
+
tdzGlobals = new Map();
|
|
195
157
|
constantNumericTables;
|
|
196
|
-
/** May-throw analysis (
|
|
158
|
+
/** May-throw analysis (computeMayThrow): pending
|
|
197
159
|
* checks are emitted only after calls that can actually raise. */
|
|
198
160
|
mayThrow;
|
|
199
161
|
indirectMayThrow;
|
|
200
162
|
/** Method names with at least one may-throw implementation — the
|
|
201
|
-
* virtualCall pending check's key
|
|
163
|
+
* virtualCall pending check's key. */
|
|
202
164
|
mayThrowMethods = new Set();
|
|
203
165
|
/** setTimeout and friends appeared somewhere: main must run the event
|
|
204
|
-
* loop even in programs with no async functions
|
|
166
|
+
* loop even in programs with no async functions. */
|
|
205
167
|
usesTimers = false;
|
|
206
168
|
/** Emitted ref-kind resolve thunks for new Promise, interned per inner
|
|
207
|
-
* typeKey → thunk symbol
|
|
169
|
+
* typeKey → thunk symbol. */
|
|
208
170
|
resolveThunks = new Map();
|
|
209
171
|
resolveThunkDefs = [];
|
|
210
172
|
/** ReadableStream.from adapters keep typed arrays by reference and box
|
|
@@ -222,15 +184,16 @@ class LlEmitter {
|
|
|
222
184
|
tracedShapes;
|
|
223
185
|
tracedUnions;
|
|
224
186
|
/** The class graph (buildClassGraph): preorder numbering, hierarchy
|
|
225
|
-
* membership, virtual slot lists
|
|
187
|
+
* membership, virtual slot lists. */
|
|
226
188
|
classMeta;
|
|
227
189
|
/** Class objects (classes as first-class values): className → the
|
|
228
190
|
* interned .name literal ref — registered during body emission, the
|
|
229
191
|
* statics and construct thunks assemble around the bodies. */
|
|
230
192
|
classObjs = new Map();
|
|
193
|
+
unionFieldReadGroups = new Map();
|
|
231
194
|
/** Preorder intervals of the runtime error classes under THIS module's
|
|
232
195
|
* class-forest numbering (main() stamps scr_error_vts with them, exactly
|
|
233
|
-
* like the
|
|
196
|
+
* like the runtime ABI’s errorVtStampLines). */
|
|
234
197
|
errorIntervals = [];
|
|
235
198
|
/** The runtime emitter vtable's preorder interval, when the program
|
|
236
199
|
* touches node:events (the class def rides the module exactly then) —
|
|
@@ -245,6 +208,10 @@ class LlEmitter {
|
|
|
245
208
|
B = new BlockBuilder();
|
|
246
209
|
frames = [];
|
|
247
210
|
scopes = [];
|
|
211
|
+
/** Scope slots dominate every throw site. Share their exceptional cleanup
|
|
212
|
+
* for identical live bindings and handlers; statement temporaries stay at
|
|
213
|
+
* their own throw sites because their SSA values are path-dependent. */
|
|
214
|
+
unwindCleanups = new Map();
|
|
248
215
|
/** Enclosing break/continue targets. `kind` separates loops from
|
|
249
216
|
* switches and labeled blocks: an unlabeled break binds to the innermost
|
|
250
217
|
* NON-BLOCK entry (loop or switch — blocks only enter the stack when
|
|
@@ -260,7 +227,7 @@ class LlEmitter {
|
|
|
260
227
|
integerRanges = new Map();
|
|
261
228
|
/** Enclosing try-with-FINALLY regions, innermost last: a `return`
|
|
262
229
|
* inside one runs every crossed finally (innermost first) before the
|
|
263
|
-
* actual ret — the
|
|
230
|
+
* actual ret — the runtime ABI’s pending-return path, with the finally
|
|
264
231
|
* bodies emitted inline at the return site instead of behind a goto.
|
|
265
232
|
* `tryDepth` snapshots tryStack.length at region entry: a throw inside
|
|
266
233
|
* a pending-return finally copy propagates OUT of the completing try
|
|
@@ -269,7 +236,7 @@ class LlEmitter {
|
|
|
269
236
|
* emitFinallysForJump. */
|
|
270
237
|
finallyStack = [];
|
|
271
238
|
/** Enclosing try contexts, innermost last — the compile-time unwind
|
|
272
|
-
* targets
|
|
239
|
+
* targets: a pending check or `throw` inside a try
|
|
273
240
|
* releases frames/scopes down to the recorded depths and branches to
|
|
274
241
|
* `label` (the catch, or the exception-path finally) instead of
|
|
275
242
|
* returning out of the function. Entering a try emits no code. */
|
|
@@ -287,17 +254,22 @@ class LlEmitter {
|
|
|
287
254
|
/** Active optional-chain bind slots, by chain id (chainRecv reads). */
|
|
288
255
|
chainSlots = new Map();
|
|
289
256
|
logArgSlots = 0;
|
|
257
|
+
stackTraces;
|
|
290
258
|
constructor(mod, options) {
|
|
291
259
|
this.mod = mod;
|
|
260
|
+
this.stackTraces = mod.functions.some((fn) => !everyStmtList(fn.body, {
|
|
261
|
+
stmt: () => true, expr: (expr) => !(expr.kind === "libCall" && expr.fn === "error.stack"),
|
|
262
|
+
}));
|
|
292
263
|
this.debug = options.debugSources === undefined ? null : new LlvmDebugInfo(mod.sourceFile, options.debugSources, options.pointerBits, mod.unions);
|
|
293
264
|
this.constantNumericTables = findConstantNumericTables(mod);
|
|
294
265
|
this.sizeType = options.pointerBits === 32 ? "i32" : "i64";
|
|
266
|
+
this.ffiExtendNarrowIntegers = options.wasi === true || ffiExtendsNarrowIntegers(options.targetTriple);
|
|
295
267
|
this.wasi = options.wasi === true;
|
|
296
268
|
this.emitLibraryIdentity = options.emitLibraryIdentity !== false;
|
|
297
269
|
this.runtimeAbiMarker = options.runtimeAbiMarker === true;
|
|
298
|
-
// ScrCycHdr
|
|
299
|
-
//
|
|
300
|
-
//
|
|
270
|
+
// ScrCycHdr.color stays 12 bytes behind a wasm32 object and 16 bytes
|
|
271
|
+
// behind a 64-bit object. The wasm32 header pads before color so its
|
|
272
|
+
// payload remains double-aligned without changing this ABI offset.
|
|
301
273
|
this.cycleColorOffset = options.pointerBits === 32 ? 12 : 16;
|
|
302
274
|
this.ffiCallbackAdapters = allocateFfiCallbackAdapters(mod.ffiImports ?? []);
|
|
303
275
|
this.ffiHasRetainedCallback = hasRetainedFfiCallback(mod.ffiImports ?? []);
|
|
@@ -323,11 +295,35 @@ class LlEmitter {
|
|
|
323
295
|
const traced = computeTraced(mod);
|
|
324
296
|
this.tracedShapes = traced.shapes;
|
|
325
297
|
this.tracedUnions = traced.unions;
|
|
298
|
+
this.shapeHost = {
|
|
299
|
+
sizeType: this.sizeType,
|
|
300
|
+
cycleColorOffset: this.cycleColorOffset,
|
|
301
|
+
tracedShapes: this.tracedShapes,
|
|
302
|
+
tracedUnions: this.tracedUnions,
|
|
303
|
+
recordsById: this.recordsById,
|
|
304
|
+
recordCloneShapes: this.recordCloneShapes,
|
|
305
|
+
unionsById: this.unionsById,
|
|
306
|
+
declare: (decl) => this.declare(decl),
|
|
307
|
+
needOom: () => this.needOom(),
|
|
308
|
+
needBadTag: () => this.needBadTag(),
|
|
309
|
+
internLiteral: (text) => this.internLiteral(text),
|
|
310
|
+
cstr: (text) => this.cstr(text),
|
|
311
|
+
unitInstanceRef: (unionId, tag) => this.unitInstanceRef(unionId, tag),
|
|
312
|
+
liveDynRefAdapter: (type) => this.liveDynRefAdapter(type),
|
|
313
|
+
dynPromiseAdapter: (type) => this.dynPromiseAdapter(type),
|
|
314
|
+
isErrorClass: (name) => this.classMeta.get(name)?.root.def.name === "%Error",
|
|
315
|
+
classSubtypes: (name) => {
|
|
316
|
+
const target = this.classMetaOf(name);
|
|
317
|
+
return [...this.classMeta.values()].filter((meta) => target.pre <= meta.pre && meta.pre <= target.post).map((meta) => meta.def.name);
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
this.walkers = new LlWalkers(this.shapeHost);
|
|
321
|
+
this.dyn = new LlDyn(this.shapeHost);
|
|
326
322
|
for (const g of mod.globals ?? []) {
|
|
327
323
|
// Module globals: scalar (f64/bool) storage is a zero-initialized
|
|
328
324
|
// LLVM global, ref-kind storage a null-initialized ptr — load/store
|
|
329
325
|
// like a local, assigned by the %init functions. Refcounted globals
|
|
330
|
-
// are released at the end of main (the
|
|
326
|
+
// are released at the end of main (the runtime ABI’s
|
|
331
327
|
// sc_release_globals), before the RC audit would run.
|
|
332
328
|
try {
|
|
333
329
|
this.llType(g.type); // refuses out-of-tier kinds
|
|
@@ -338,12 +334,11 @@ class LlEmitter {
|
|
|
338
334
|
throw err;
|
|
339
335
|
}
|
|
340
336
|
this.globalTypes.set(g.id, g.type);
|
|
337
|
+
if (g.tdz)
|
|
338
|
+
this.tdzGlobals.set(g.id, g.name);
|
|
341
339
|
}
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
// — subclasses embed the ScrEmitter/ScrStream prefixes, classes.ts).
|
|
345
|
-
// Anything else runtime-flagged refuses by name, exactly the
|
|
346
|
-
// classDef:* histogram key.
|
|
340
|
+
// Runtime error, EventEmitter, and stream classes have known layouts.
|
|
341
|
+
// Subclasses embed the ScrEmitter/ScrStream prefixes from classes.ts.
|
|
347
342
|
const classes = mod.classes ?? [];
|
|
348
343
|
for (const cls of classes) {
|
|
349
344
|
if (cls.runtime &&
|
|
@@ -354,9 +349,8 @@ class LlEmitter {
|
|
|
354
349
|
}
|
|
355
350
|
}
|
|
356
351
|
// The class graph: base/children links, hierarchy membership, the
|
|
357
|
-
// whole-program preorder numbering
|
|
358
|
-
//
|
|
359
|
-
// either backend), and the per-hierarchy virtual slot lists.
|
|
352
|
+
// whole-program preorder numbering for instanceof over runtime and
|
|
353
|
+
// compiled error objects, and the per-hierarchy virtual slot lists.
|
|
360
354
|
this.classMeta = buildClassGraph(mod, this.fnByName);
|
|
361
355
|
for (const [name, rec] of RUNTIME_ERROR_CLASSES) {
|
|
362
356
|
const meta = this.classMeta.get(name);
|
|
@@ -384,7 +378,7 @@ class LlEmitter {
|
|
|
384
378
|
}
|
|
385
379
|
// ── types ───────────────────────────────────────────────────────────────
|
|
386
380
|
llType(t) {
|
|
387
|
-
if (POINTER_KINDS.has(t.kind)
|
|
381
|
+
if (POINTER_KINDS.has(t.kind))
|
|
388
382
|
return "ptr";
|
|
389
383
|
switch (t.kind) {
|
|
390
384
|
case "f64":
|
|
@@ -427,7 +421,7 @@ class LlEmitter {
|
|
|
427
421
|
if (adapter.tls !== null)
|
|
428
422
|
globals.push(`@${adapter.tls} = internal thread_local global ptr null`);
|
|
429
423
|
if (adapter.global !== null)
|
|
430
|
-
globals.push(`@${adapter.global} = internal global ptr null`);
|
|
424
|
+
globals.push(`@${adapter.global} = internal thread_local global ptr null`);
|
|
431
425
|
if (adapter.table !== null) {
|
|
432
426
|
globals.push(`@${adapter.table} = internal global %ScrFfiTable zeroinitializer`);
|
|
433
427
|
}
|
|
@@ -437,11 +431,11 @@ class LlEmitter {
|
|
|
437
431
|
if (param === "string" || param === "bytes") {
|
|
438
432
|
return [`ptr %a${i}`, `${this.sizeType} %a${i}_len`];
|
|
439
433
|
}
|
|
440
|
-
return [`${
|
|
434
|
+
return [`${ffiNativeParamLl(param, this.ffiExtendNarrowIntegers)} %a${i}`];
|
|
441
435
|
});
|
|
442
|
-
const ret = ffiNativeTypeLl(cb.returns);
|
|
443
436
|
if (cb.invoke === "foreign") {
|
|
444
|
-
if (adapter.table === null || !cb.params.some(isFfiContextParam) || cb.returns !== "void"
|
|
437
|
+
if (adapter.table === null || !cb.params.some(isFfiContextParam) || cb.returns !== "void" ||
|
|
438
|
+
cb.params.some(param => param === "i64" || param === "u64" || param === "pointer")) {
|
|
445
439
|
throw new InternalCompilerError("llvm emitter bug: invalid foreign FFI callback descriptor");
|
|
446
440
|
}
|
|
447
441
|
const dispatch = `${adapter.symbol}_dispatch`;
|
|
@@ -458,6 +452,10 @@ class LlEmitter {
|
|
|
458
452
|
continue;
|
|
459
453
|
switch (param) {
|
|
460
454
|
case "f64":
|
|
455
|
+
case "f32":
|
|
456
|
+
case "i8":
|
|
457
|
+
case "u16":
|
|
458
|
+
case "i16":
|
|
461
459
|
this.declare(`declare double @scr_ffi_call_get_f64(ptr, ${this.sizeType})`);
|
|
462
460
|
dispatchBody.push(` %s${i} = call double @scr_ffi_call_get_f64(ptr %call, ${this.sizeType} ${i})`);
|
|
463
461
|
scriptArgs.push(`double %s${i}`);
|
|
@@ -494,7 +492,8 @@ class LlEmitter {
|
|
|
494
492
|
}
|
|
495
493
|
}
|
|
496
494
|
dispatchBody.push(` call void %fn(${[`ptr %cb`, ...scriptArgs].join(", ")})`, ` ret void`, `}`, ``);
|
|
497
|
-
|
|
495
|
+
for (const line of dispatchBody)
|
|
496
|
+
defs.push(line);
|
|
498
497
|
this.declare(`declare ptr @scr_ffi_call_new(ptr, ptr, ptr, ${this.sizeType})`);
|
|
499
498
|
this.declare(`declare void @scr_ffi_post(ptr)`);
|
|
500
499
|
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}, ${this.sizeType} ${cb.params.length})`);
|
|
@@ -510,6 +509,12 @@ class LlEmitter {
|
|
|
510
509
|
this.declare(`declare void @scr_ffi_call_copy_${param}(ptr, ${this.sizeType}, ptr, ${this.sizeType})`);
|
|
511
510
|
defs.push(` call void @scr_ffi_call_copy_${param}(ptr %call, ${this.sizeType} ${i}, ptr %a${i}, ${this.sizeType} %a${i}_len)`);
|
|
512
511
|
}
|
|
512
|
+
else if (param === "f32" || param === "i8" || param === "u16" || param === "i16") {
|
|
513
|
+
const nativeTy = ffiNativeTypeLl(param);
|
|
514
|
+
const op = param === "f32" ? "fpext" : param === "u16" ? "uitofp" : "sitofp";
|
|
515
|
+
this.declare(`declare void @scr_ffi_call_set_f64(ptr, ${this.sizeType}, double)`);
|
|
516
|
+
defs.push(` %wide${i} = ${op} ${nativeTy} %a${i} to double`, ` call void @scr_ffi_call_set_f64(ptr %call, ${this.sizeType} ${i}, double %wide${i})`);
|
|
517
|
+
}
|
|
513
518
|
else {
|
|
514
519
|
const nativeTy = ffiNativeTypeLl(param);
|
|
515
520
|
this.declare(`declare void @scr_ffi_call_set_${param}(ptr, ${this.sizeType}, ${nativeTy})`);
|
|
@@ -519,7 +524,7 @@ class LlEmitter {
|
|
|
519
524
|
defs.push(` call void @scr_ffi_post(ptr %call)`, ` ret void`, `}`, ``);
|
|
520
525
|
continue;
|
|
521
526
|
}
|
|
522
|
-
defs.push(`define internal ${
|
|
527
|
+
defs.push(`define internal ${ffiNativeReturnLl(cb.returns, this.ffiExtendNarrowIntegers)} @${adapter.symbol}(${params.join(", ")}) ${FN_ATTRS} {`, `entry:`, adapter.tls !== null
|
|
523
528
|
? ` %cb = load ptr, ptr @${adapter.tls}`
|
|
524
529
|
: adapter.global !== null
|
|
525
530
|
? ` %cb = load ptr, ptr @${adapter.global}`
|
|
@@ -550,9 +555,28 @@ class LlEmitter {
|
|
|
550
555
|
if (isFfiContextParam(param))
|
|
551
556
|
continue;
|
|
552
557
|
switch (param) {
|
|
558
|
+
case "i64":
|
|
559
|
+
case "u64":
|
|
560
|
+
case "pointer": {
|
|
561
|
+
const ty = ffiNativeTypeLl(param);
|
|
562
|
+
this.declare(`declare ptr @scr_bigint_from_${param}(${ty})`);
|
|
563
|
+
defs.push(` %s${i} = call ptr @scr_bigint_from_${param}(${ty} %a${i})`);
|
|
564
|
+
scriptArgs.push(`ptr %s${i}`);
|
|
565
|
+
break;
|
|
566
|
+
}
|
|
553
567
|
case "f64":
|
|
554
568
|
scriptArgs.push(`double %a${i}`);
|
|
555
569
|
break;
|
|
570
|
+
case "f32":
|
|
571
|
+
case "i8":
|
|
572
|
+
case "u16":
|
|
573
|
+
case "i16": {
|
|
574
|
+
const nativeTy = ffiNativeTypeLl(param);
|
|
575
|
+
const op = param === "f32" ? "fpext" : param === "u16" ? "uitofp" : "sitofp";
|
|
576
|
+
defs.push(` %s${i} = ${op} ${nativeTy} %a${i} to double`);
|
|
577
|
+
scriptArgs.push(`double %s${i}`);
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
556
580
|
case "bool":
|
|
557
581
|
defs.push(` %s${i} = icmp ne i8 %a${i}, 0`);
|
|
558
582
|
scriptArgs.push(`i1 %s${i}`);
|
|
@@ -604,18 +628,34 @@ class LlEmitter {
|
|
|
604
628
|
defs.push(` call void @scr_closure_release_v(ptr %invoke_pin)`);
|
|
605
629
|
}
|
|
606
630
|
switch (cb.returns) {
|
|
631
|
+
case "i64":
|
|
632
|
+
case "u64":
|
|
633
|
+
case "pointer": {
|
|
634
|
+
const ty = ffiNativeTypeLl(cb.returns);
|
|
635
|
+
this.declare(`declare ${ty} @scr_bigint_to_${cb.returns}(ptr)`);
|
|
636
|
+
this.declare(`declare void @scr_bigint_release(ptr)`);
|
|
637
|
+
defs.push(` %out = call ${ty} @scr_bigint_to_${cb.returns}(ptr %result)`, ` call void @scr_bigint_release(ptr %result)`, ` ret ${ty} %out`);
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
607
640
|
case "f64":
|
|
608
641
|
defs.push(` ret double %result`);
|
|
609
642
|
break;
|
|
643
|
+
case "f32":
|
|
644
|
+
defs.push(` %out = fptrunc double %result to float`, ` ret float %out`);
|
|
645
|
+
break;
|
|
610
646
|
case "bool":
|
|
611
647
|
defs.push(` %out = zext i1 %result to i8`, ` ret i8 %out`);
|
|
612
648
|
break;
|
|
613
649
|
case "u8":
|
|
650
|
+
case "i8":
|
|
651
|
+
case "u16":
|
|
652
|
+
case "i16":
|
|
614
653
|
case "u32":
|
|
615
654
|
this.declare(`declare double @scr_bit_ushr(double, double)`);
|
|
616
655
|
defs.push(` %coerced = call double @scr_bit_ushr(double %result, double ${f64Lit(0)})`, ` %wide = fptoui double %coerced to i32`);
|
|
617
|
-
if (cb.returns
|
|
618
|
-
|
|
656
|
+
if (cb.returns !== "u32") {
|
|
657
|
+
const nativeTy = ffiNativeTypeLl(cb.returns);
|
|
658
|
+
defs.push(` %out = trunc i32 %wide to ${nativeTy}`, ` ret ${nativeTy} %out`);
|
|
619
659
|
}
|
|
620
660
|
else {
|
|
621
661
|
defs.push(` ret i32 %wide`);
|
|
@@ -632,13 +672,32 @@ class LlEmitter {
|
|
|
632
672
|
}
|
|
633
673
|
emit() {
|
|
634
674
|
// Function bodies first (the literal/unit/fn-value tables fill as they
|
|
635
|
-
// emit), then the file assembles around them — the
|
|
675
|
+
// emit), then the file assembles around them — the runtime ABI’s order.
|
|
636
676
|
const fnDefs = [];
|
|
637
677
|
for (const fn of this.mod.functions)
|
|
638
678
|
fnDefs.push(this.emitFunction(fn));
|
|
639
|
-
const
|
|
640
|
-
const
|
|
641
|
-
|
|
679
|
+
const errorViews = [];
|
|
680
|
+
for (const property of ["name", "message"])
|
|
681
|
+
if (this.mod.functions.some((fn) => fn.name === `%error.${property}.read`)) {
|
|
682
|
+
this.declare(`declare void @scr_error_install_${property}_reader(ptr)`);
|
|
683
|
+
errorViews.push(` call void @scr_error_install_${property}_reader(ptr @${mangleFunction(`%error.${property}.read`)})`);
|
|
684
|
+
}
|
|
685
|
+
for (const meta of this.classMeta.values()) {
|
|
686
|
+
if (meta.def.runtime || meta.root.def.name !== "%Error")
|
|
687
|
+
continue;
|
|
688
|
+
const type = { kind: "object", className: meta.def.name };
|
|
689
|
+
const adapter = this.liveDynRefAdapter(type);
|
|
690
|
+
const rc = vAdapters(this.shapeHost, type);
|
|
691
|
+
const key = typeKey(type);
|
|
692
|
+
const name = `sc_error_view_${errorViews.length}`;
|
|
693
|
+
this.resolveThunkDefs.push(`define internal ptr @${name}(ptr %v) ${FN_ATTRS} {`, `entry:`, ` %d = call ptr ${typedRefConstructor(this.shapeHost, type)}(ptr %v, ptr ${rc.retain}, ptr ${rc.release}, ptr ${this.cstr(key)}, ${this.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr @${adapter.snapshot}, ptr ${adapter.commit})`, ` ret ptr %d`, `}`, ``);
|
|
694
|
+
this.declare(`declare void @scr_error_register_dyn(ptr, ptr)`);
|
|
695
|
+
errorViews.push(` call void @scr_error_register_dyn(ptr @${mangleVtInstance(meta.def.name)}, ptr @${name})`);
|
|
696
|
+
}
|
|
697
|
+
const layouts = emitLlvmLayouts(this.shapeHost, this.mod, this.classMeta, this.classObjs, this.fnByName, (t) => this.llType(t));
|
|
698
|
+
const shapes = layouts.records;
|
|
699
|
+
const classShapes = layouts.classes;
|
|
700
|
+
const classObjDefs = layouts.classObjects;
|
|
642
701
|
const wrappers = this.emitFnValueDefs();
|
|
643
702
|
const asyncDefs = this.emitAsyncScaffolding();
|
|
644
703
|
const ffiCallbacks = this.emitFfiCallbackDefs();
|
|
@@ -672,72 +731,88 @@ class LlEmitter {
|
|
|
672
731
|
seenGlobalIds.add(g.id);
|
|
673
732
|
return true;
|
|
674
733
|
});
|
|
675
|
-
// Refcounted globals release before main returns — the
|
|
734
|
+
// Refcounted globals release before main returns — the runtime ABI’s
|
|
676
735
|
// sc_release_globals, keeping the RC audit's live count exact. Built
|
|
677
736
|
// before the declaration table flushes (it adds the release symbols).
|
|
678
737
|
// Two spellings with distinct temp names: the normal exit and the
|
|
679
738
|
// uncaught-exception exit are separate blocks of the same function.
|
|
680
739
|
// Interned function-value closures are IMMORTAL (rc == SIZE_MAX), so
|
|
681
740
|
// an own-property table Object.defineProperties hung on one would
|
|
682
|
-
// outlive the RC audit — release it with the globals (the
|
|
741
|
+
// outlive the RC audit — release it with the globals (the runtime ABI’s
|
|
683
742
|
// sc_release_globals tail). Only when the dispatch unit is even
|
|
684
743
|
// linked (defineProps is the only writer).
|
|
685
|
-
const
|
|
744
|
+
const runtimeFeatures = moduleRuntimeFeatures(this.mod);
|
|
745
|
+
const fnValueProps = [...this.fnValues];
|
|
686
746
|
if (fnValueProps.length > 0)
|
|
687
747
|
this.declare(`declare void @scr_box_release(ptr)`);
|
|
748
|
+
if (this.classObjs.size > 0)
|
|
749
|
+
this.declare(`declare void @scr_classobj_clear_properties(ptr)`);
|
|
688
750
|
const globalReleaseLines = (prefix) => {
|
|
689
751
|
const lines = [];
|
|
690
752
|
globals.forEach((g, i) => {
|
|
691
753
|
if (!isRefCounted(g.type))
|
|
692
754
|
return;
|
|
693
|
-
lines.push(` %${prefix}${i} = load ptr, ptr @${mangleGlobal(g.id)}`, ` call void ${releaseSym(this, g.type)}(ptr %${prefix}${i}) ; ${g.name}`);
|
|
755
|
+
lines.push(` %${prefix}${i} = load ptr, ptr @${mangleGlobal(g.id)}`, ` call void ${releaseSym(this.shapeHost, g.type)}(ptr %${prefix}${i}) ; ${g.name}`);
|
|
694
756
|
});
|
|
695
757
|
fnValueProps.forEach((name, i) => {
|
|
696
758
|
// props sits at %ScrClosure field 3; release is NULL-tolerant —
|
|
697
759
|
// cleared so a second release path stays idempotent.
|
|
698
760
|
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)`);
|
|
699
761
|
});
|
|
762
|
+
for (const name of this.classObjs.keys())
|
|
763
|
+
lines.push(` call void @scr_classobj_clear_properties(ptr @${mangleClassObj(name)})`);
|
|
700
764
|
return lines;
|
|
701
765
|
};
|
|
702
766
|
// Exit listeners can read MODULE GLOBALS directly, so they must run
|
|
703
|
-
// BEFORE the global releases (the
|
|
767
|
+
// BEFORE the global releases (the runtime ABI’s runExitListeners
|
|
704
768
|
// ordering — the atexit half becomes an idempotent no-op).
|
|
705
|
-
const usesEvents =
|
|
706
|
-
const usesChildProcess =
|
|
707
|
-
const usesFsWatch =
|
|
769
|
+
const usesEvents = runtimeFeatures.processEvents;
|
|
770
|
+
const usesChildProcess = runtimeFeatures.childProcess;
|
|
771
|
+
const usesFsWatch = runtimeFeatures.fsWatch;
|
|
708
772
|
// Stream-surface programs fill the loop's stream hook (the deferred
|
|
709
773
|
// next-tick emissions) and the emitter's post-registration flow kick
|
|
710
774
|
// before %main — scr_stream.c links only when the line is emitted
|
|
711
775
|
// (native-toolchain.ts gates on the same predicate).
|
|
712
|
-
const usesStream =
|
|
776
|
+
const usesStream = runtimeFeatures.stream;
|
|
713
777
|
// Net-surface programs fill the loop's net hooks (and the netSocket
|
|
714
778
|
// handle-dispatch ops for the checked-dynamic boundary); http-surface
|
|
715
779
|
// programs additionally stamp the httpReq/httpRes ops — the C main's
|
|
716
780
|
// install lines, gated on the same predicates native-toolchain.ts links by.
|
|
717
|
-
const usesNet =
|
|
718
|
-
const
|
|
781
|
+
const usesNet = runtimeFeatures.net;
|
|
782
|
+
const usesDgram = runtimeFeatures.dgram;
|
|
783
|
+
const usesHttp2 = runtimeFeatures.http2;
|
|
784
|
+
const usesHttp = runtimeFeatures.http;
|
|
719
785
|
// Fetch-referencing programs register the native fetch bridge before
|
|
720
786
|
// any island entry (the engine's lazy boot consults it) — native-toolchain.ts
|
|
721
787
|
// compiles scr_fetch.c on the same predicate.
|
|
722
|
-
const usesFetch =
|
|
788
|
+
const usesFetch = runtimeFeatures.fetch;
|
|
723
789
|
const embedsZlib = moduleEmbedsBuiltin(this.mod, "node:zlib");
|
|
724
790
|
const embedsNet = moduleEmbedsBuiltin(this.mod, "node:http") ||
|
|
725
791
|
moduleEmbedsBuiltin(this.mod, "node:https") ||
|
|
726
792
|
moduleEmbedsBuiltin(this.mod, "node:net") ||
|
|
727
793
|
moduleEmbedsBuiltin(this.mod, "node:tls");
|
|
728
|
-
const snapshotsTlsCa =
|
|
794
|
+
const snapshotsTlsCa = runtimeFeatures.tls || runtimeFeatures.tlsCa ||
|
|
729
795
|
moduleEmbedsBuiltin(this.mod, "node:https") ||
|
|
730
796
|
moduleEmbedsBuiltin(this.mod, "node:tls");
|
|
731
797
|
// The process verdict has the same precedence as the C reference
|
|
732
798
|
// emitter: node:test owns the final status when present; otherwise an
|
|
733
799
|
// embedded process.exitCode owns it; ordinary programs return zero.
|
|
734
|
-
const usesNodeTest =
|
|
800
|
+
const usesNodeTest = runtimeFeatures.nodeTest;
|
|
735
801
|
const programExitUsesIsland = !usesNodeTest && usesIsland;
|
|
736
802
|
// Declared NOW — the extern block flushes before main assembles.
|
|
737
803
|
if (usesEvents)
|
|
738
804
|
this.declare(`declare void @scr_events_install()`);
|
|
739
805
|
if (usesChildProcess)
|
|
740
806
|
this.declare(`declare void @scr_child_dyn_install()`);
|
|
807
|
+
const childStreamBoxes = usesChildProcess && usesStream &&
|
|
808
|
+
this.classMeta.has("%Readable") && this.classMeta.has("%Writable")
|
|
809
|
+
? [this.dyn.toDynHelper({ kind: "object", className: "%Readable" }),
|
|
810
|
+
this.dyn.toDynHelper({ kind: "object", className: "%Writable" })]
|
|
811
|
+
: null;
|
|
812
|
+
if (childStreamBoxes) {
|
|
813
|
+
this.declare(`@scr_stream_child_ops = external constant { ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }`);
|
|
814
|
+
this.declare(`declare void @scr_child_dyn_streams_install(ptr, ptr, ptr)`);
|
|
815
|
+
}
|
|
741
816
|
if (usesFsWatch)
|
|
742
817
|
this.declare(`declare void @scr_watch_install()`);
|
|
743
818
|
if (this.ffiHasForeignCallback)
|
|
@@ -748,6 +823,10 @@ class LlEmitter {
|
|
|
748
823
|
this.declare(`declare void @scr_net_install()`);
|
|
749
824
|
this.declare(`declare void @scr_net_dyn_install()`);
|
|
750
825
|
}
|
|
826
|
+
if (usesDgram)
|
|
827
|
+
this.declare(`declare void @scr_dgram_install()`);
|
|
828
|
+
if (usesHttp2)
|
|
829
|
+
this.declare(`declare void @scr_http2_dyn_install()`);
|
|
751
830
|
if (usesHttp)
|
|
752
831
|
this.declare(`declare void @scr_http_dyn_install()`);
|
|
753
832
|
if (usesFetch)
|
|
@@ -773,13 +852,12 @@ class LlEmitter {
|
|
|
773
852
|
// the refcounted-global releases, or the retained-FFI atexit ledger
|
|
774
853
|
// sweep (a listener may legitimately release or pump a registration,
|
|
775
854
|
// and only the inline call orders ahead of every atexit handler —
|
|
776
|
-
// the
|
|
855
|
+
// the runtime ABI’s runExitListeners stance). Plain event programs
|
|
777
856
|
// with neither keep the atexit path, so their listener timing is
|
|
778
857
|
// unchanged.
|
|
779
858
|
const hasRefGlobals = globals.some((g) => isRefCounted(g.type)) || fnValueProps.length > 0;
|
|
780
859
|
const inlineExitListeners = usesEvents && (hasRefGlobals || this.ffiHasRetainedCallback);
|
|
781
|
-
|
|
782
|
-
this.declare(`declare i32 @scr_exit_code_hint_get()`);
|
|
860
|
+
this.declare(`declare i32 @scr_exit_code_hint_get()`);
|
|
783
861
|
if (inlineExitListeners) {
|
|
784
862
|
this.declare(`declare void @scr_run_exit_listeners(double)`);
|
|
785
863
|
this.declare(`declare i32 @scr_exit_code_hint_get()`);
|
|
@@ -852,17 +930,23 @@ class LlEmitter {
|
|
|
852
930
|
// finish_top_level initially notes 13. Replace that hint before exit
|
|
853
931
|
// listeners run when a higher-priority verdict was already selected.
|
|
854
932
|
lines.push(` call void @scr_exit_code_note(i32 ${exitStatus})`);
|
|
855
|
-
|
|
933
|
+
for (const line of exitListenerLines("xp"))
|
|
934
|
+
lines.push(line);
|
|
856
935
|
if (tracksIslandExit) {
|
|
857
936
|
lines.push(` %tla_exit_version_after = call ${this.sizeType} @scr_island_exit_code_version()`, ` %tla_exit_changed = icmp ne ${this.sizeType} %tla_exit_version_after, %tla_exit_version`, ` br i1 %tla_exit_changed, label %tla_exit_updated, label %tla_exit_unchanged`, `tla_exit_updated:`, ` %tla_listener_exit = call i32 @scr_island_exit_code()`, ` call void @scr_exit_code_note(i32 %tla_listener_exit)`, ` br label %tla_exit_done`, `tla_exit_unchanged:`, ` br label %tla_exit_done`, `tla_exit_done:`, ` %tla_final_exit = phi i32 [ %tla_listener_exit, %tla_exit_updated ], [ ${exitStatus}, %tla_exit_unchanged ]`);
|
|
858
937
|
}
|
|
859
|
-
|
|
938
|
+
for (const line of topPendingReleases)
|
|
939
|
+
lines.push(line);
|
|
860
940
|
lines.push(` ret i32 ${tracksIslandExit ? "%tla_final_exit" : exitStatus}`);
|
|
861
941
|
return lines;
|
|
862
942
|
};
|
|
863
943
|
// LIBRARY mode: the runtime entry points the generated library
|
|
864
944
|
// symbols delegate to — declared before the extern block flushes.
|
|
865
945
|
if (this.mod.lib !== undefined) {
|
|
946
|
+
if (this.wasi) {
|
|
947
|
+
this.declare(`declare ptr @malloc(${this.sizeType})`);
|
|
948
|
+
this.declare(`declare void @free(ptr)`);
|
|
949
|
+
}
|
|
866
950
|
this.declare(`declare void @scr_library_entry(i1 zeroext, ptr)`);
|
|
867
951
|
this.declare(`declare void @scr_library_reset()`);
|
|
868
952
|
this.declare(`declare void @scr_library_check_exc()`);
|
|
@@ -916,18 +1000,18 @@ class LlEmitter {
|
|
|
916
1000
|
`%ScrLogArg = type { i32, i64 }`,
|
|
917
1001
|
`%ScrVt = type { ${this.sizeType}, ${this.sizeType}, ptr }`,
|
|
918
1002
|
`%ScrUnion = type { ${this.sizeType}, i32, ptr, ptr, ptr, i64 }`,
|
|
919
|
-
`%ScrClosure = type { ${this.sizeType}, ptr, ${this.sizeType}, ptr }`,
|
|
1003
|
+
`%ScrClosure = type { ${this.sizeType}, ptr, ${this.sizeType}, ptr, i32 }`,
|
|
920
1004
|
`%ScrFfiTable = type { ptr, ${this.sizeType}, ${this.sizeType}, ptr, i8, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
|
|
921
|
-
`%ScrRegex = type { ${this.sizeType}, ptr, ptr, ptr }`,
|
|
1005
|
+
`%ScrRegex = type { ${this.sizeType}, ptr, ptr, ptr, double, ptr }`,
|
|
922
1006
|
// ScrArr mirrors scr_runtime.h field-for-field. Live dynamic stream
|
|
923
1007
|
// commits swap its mutable dense, sparse, presence, and property
|
|
924
1008
|
// storage while preserving the target object's identity.
|
|
925
|
-
`%ScrArr = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, ptr, ptr, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ${this.sizeType}, ${this.sizeType} }`,
|
|
926
|
-
// The runtime error prefix { rc, vt, name, message, code } and the
|
|
1009
|
+
`%ScrArr = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, ptr, ptr, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ${this.sizeType}, ${this.sizeType}, ptr }`,
|
|
1010
|
+
// The runtime error prefix { rc, vt, name, message, code, cause } and the
|
|
927
1011
|
// class-object shape { rc, pre, post, ctor, name } — field reads on
|
|
928
1012
|
// builtin errors and classval loads GEP through these.
|
|
929
|
-
`%ScrError = type { ${this.sizeType}, ptr, ptr, ptr, ptr }`,
|
|
930
|
-
`%ScrClassObj = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
|
|
1013
|
+
`%ScrError = type { ${this.sizeType}, ptr, ptr, ptr, ptr, ptr, i8, i8, i8, i8, i8, ptr, ptr }`,
|
|
1014
|
+
`%ScrClassObj = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
|
|
931
1015
|
// The runtime emitter prefix { rc, vt, reg, cls } — user subclasses
|
|
932
1016
|
// embed it (classes.ts), and bare-emitter GEPs address through it.
|
|
933
1017
|
`%ScrEmitter = type { ${this.sizeType}, ptr, ptr, ptr }`,
|
|
@@ -944,7 +1028,7 @@ class LlEmitter {
|
|
|
944
1028
|
// typed-array access GEPs through this directly: the IR type already
|
|
945
1029
|
// fixes elem, so the hot path needs neither a runtime kind load nor
|
|
946
1030
|
// the generic scr_bytes_get/set call.
|
|
947
|
-
`%ScrBytes = type { ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr }`,
|
|
1031
|
+
`%ScrBytes = type { ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, i8 }`,
|
|
948
1032
|
// The capture box { rc, kind, obj_retain, obj_release, obj_trace,
|
|
949
1033
|
// slot } — TDZ reads peek the payload slot (offset 40) directly.
|
|
950
1034
|
`%ScrBox = type { ${this.sizeType}, i32, ptr, ptr, ptr, i64 }`,
|
|
@@ -956,8 +1040,10 @@ class LlEmitter {
|
|
|
956
1040
|
`%ScrIslandModule = type { ptr, ptr, ${this.sizeType}, ${this.sizeType}, i32, ptr, ${this.sizeType}, ${this.sizeType} }`,
|
|
957
1041
|
`%ScrIslandEdge = type { ptr, ptr, ptr, i32 }`,
|
|
958
1042
|
];
|
|
959
|
-
|
|
960
|
-
|
|
1043
|
+
for (const line of shapes.typeDefs)
|
|
1044
|
+
out.push(line);
|
|
1045
|
+
for (const line of classShapes.typeDefs)
|
|
1046
|
+
out.push(line);
|
|
961
1047
|
// Thread-instanced library state (abi.instance_per_thread): the
|
|
962
1048
|
// program TU's mutable globals — module globals, run-once guards, the
|
|
963
1049
|
// lazily-compiled regex literal caches — and the runtime globals its
|
|
@@ -966,7 +1052,7 @@ class LlEmitter {
|
|
|
966
1052
|
// data (string literals, unit arms, template arrays, vtables) stays
|
|
967
1053
|
// shared.
|
|
968
1054
|
const tl = this.mod.lib?.threadInstances === true ? "thread_local " : "";
|
|
969
|
-
out.push(``, `@scr_error_vts = external ${tl}global [
|
|
1055
|
+
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)`, ...(this.runtimeAbiMarker && this.mod.lib === undefined
|
|
970
1056
|
? [`declare void @${RUNTIME_ABI_MARKER}()`]
|
|
971
1057
|
: []));
|
|
972
1058
|
for (const d of this.decls)
|
|
@@ -981,7 +1067,7 @@ class LlEmitter {
|
|
|
981
1067
|
}
|
|
982
1068
|
for (const [text, lit] of this.literals) {
|
|
983
1069
|
// Immortal interned ScrStr: { rc = SIZE_MAX, len, cap = len, bytes\0 } —
|
|
984
|
-
// the
|
|
1070
|
+
// the runtime ABI’s static table, retain/release skip rc == SIZE_MAX.
|
|
985
1071
|
out.push(`@${lit.sym} = internal global { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, [${lit.len + 1} x i8] } ` +
|
|
986
1072
|
`{ ${this.sizeType} -1, ${this.sizeType} ${lit.len}, ${this.sizeType} ${lit.len}, [${lit.len + 1} x i8] c"${llStrBytes(text)}" }`);
|
|
987
1073
|
}
|
|
@@ -1000,7 +1086,7 @@ class LlEmitter {
|
|
|
1000
1086
|
// One immortal ScrRegex per (pattern, flags) literal, pointing at
|
|
1001
1087
|
// the interned source/flags strings. The bc slot starts null (lazy
|
|
1002
1088
|
// compile, cached by the runtime) — a mutable global, not constant.
|
|
1003
|
-
out.push(`@${re.sym} = internal ${tl}global %ScrRegex { ${this.sizeType} -1, ptr ${re.src}, ptr ${re.fl}, ptr null } ; ${key.replace(/\n/g, "\\n")}`);
|
|
1089
|
+
out.push(`@${re.sym} = internal ${tl}global %ScrRegex { ${this.sizeType} -1, ptr ${re.src}, ptr ${re.fl}, ptr null, double 0.0, ptr null } ; ${key.replace(/\n/g, "\\n")}`);
|
|
1004
1090
|
}
|
|
1005
1091
|
if (this.regexInstances.size > 0)
|
|
1006
1092
|
out.push(``);
|
|
@@ -1014,13 +1100,12 @@ class LlEmitter {
|
|
|
1014
1100
|
const present = n === 0
|
|
1015
1101
|
? "zeroinitializer"
|
|
1016
1102
|
: `[ ${inst.slots.map(() => "i8 1").join(", ")} ]`;
|
|
1017
|
-
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 { ${this.sizeType} -1, ${this.sizeType} ${n}, ${this.sizeType} ${n}, i32 2, ptr null, ptr null, ptr null, ptr @${inst.sym}_data, ptr @${inst.sym}_present, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null, ${this.sizeType} 0, ${this.sizeType} 0 }`);
|
|
1103
|
+
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 { ${this.sizeType} -1, ${this.sizeType} ${n}, ${this.sizeType} ${n}, i32 2, ptr null, ptr null, ptr null, ptr @${inst.sym}_data, ptr @${inst.sym}_present, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null }`);
|
|
1018
1104
|
}
|
|
1019
1105
|
if (this.templateStringsInstances.size > 0)
|
|
1020
1106
|
out.push(``);
|
|
1021
1107
|
for (const [text, c] of this.cstrs) {
|
|
1022
|
-
// NUL-terminated byte-array constants
|
|
1023
|
-
// currency (the C emitter passes string literals; these are theirs).
|
|
1108
|
+
// NUL-terminated byte-array constants for scr_jb_puts and indentation.
|
|
1024
1109
|
out.push(`@${c.sym} = internal constant [${c.len + 1} x i8] c"${llStrBytes(text)}"`);
|
|
1025
1110
|
}
|
|
1026
1111
|
if (this.cstrs.size > 0)
|
|
@@ -1047,7 +1132,8 @@ class LlEmitter {
|
|
|
1047
1132
|
});
|
|
1048
1133
|
out.push(`@sc_npm_modules = internal constant [${moduleRows.length} x %ScrIslandModule] [ ${moduleRows.join(", ")} ]`);
|
|
1049
1134
|
embedded.edges.forEach((edge, i) => {
|
|
1050
|
-
|
|
1135
|
+
const parts = [["from", edge.from], ["spec", edge.specifier], ["to", edge.to]];
|
|
1136
|
+
for (const [part, text] of parts) {
|
|
1051
1137
|
const bytes = Buffer.from(text, "utf8");
|
|
1052
1138
|
out.push(`@sc_npm_edge_${i}_${part} = internal constant [${bytes.length + 1} x i8] c"${llBytes(bytes)}"`);
|
|
1053
1139
|
}
|
|
@@ -1059,7 +1145,8 @@ class LlEmitter {
|
|
|
1059
1145
|
}
|
|
1060
1146
|
out.push(``);
|
|
1061
1147
|
}
|
|
1062
|
-
|
|
1148
|
+
for (const line of ffiCallbacks.globals)
|
|
1149
|
+
out.push(line);
|
|
1063
1150
|
if (ffiCallbacks.globals.length > 0)
|
|
1064
1151
|
out.push(``);
|
|
1065
1152
|
for (const g of globals) {
|
|
@@ -1070,26 +1157,36 @@ class LlEmitter {
|
|
|
1070
1157
|
}
|
|
1071
1158
|
if (globals.length > 0)
|
|
1072
1159
|
out.push(``);
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1160
|
+
for (const line of helpers)
|
|
1161
|
+
out.push(line);
|
|
1162
|
+
for (const line of ffiCallbacks.defs)
|
|
1163
|
+
out.push(line);
|
|
1164
|
+
for (const line of shapes.defs)
|
|
1165
|
+
out.push(line);
|
|
1166
|
+
for (const line of classShapes.defs)
|
|
1167
|
+
out.push(line);
|
|
1168
|
+
for (const line of classObjDefs)
|
|
1169
|
+
out.push(line);
|
|
1170
|
+
for (const line of this.walkers.defs)
|
|
1171
|
+
out.push(line);
|
|
1172
|
+
for (const line of this.dyn.defs)
|
|
1173
|
+
out.push(line);
|
|
1174
|
+
for (const line of wrappers)
|
|
1175
|
+
out.push(line);
|
|
1176
|
+
for (const line of asyncDefs)
|
|
1177
|
+
out.push(line);
|
|
1178
|
+
for (const line of this.resolveThunkDefs)
|
|
1179
|
+
out.push(line);
|
|
1083
1180
|
out.push(fnDefs.join("\n\n"), ``);
|
|
1084
1181
|
// main(): scr_init, the program-dependent error-vt interval stamps,
|
|
1085
1182
|
// scr_lib_init(argc, argv), then the entry function. An uncaught
|
|
1086
|
-
// exception escaping top-level code prints and exits 1 (Node)
|
|
1087
|
-
//
|
|
1088
|
-
|
|
1089
|
-
const stamps = [];
|
|
1183
|
+
// exception escaping top-level code prints and exits 1 (Node).
|
|
1184
|
+
// The exception epilogue is emitted when the entry may throw.
|
|
1185
|
+
const stamps = [...errorViews];
|
|
1090
1186
|
for (const iv of this.errorIntervals) {
|
|
1091
|
-
|
|
1092
|
-
|
|
1187
|
+
const fields = [[0, iv.pre], [1, iv.post]];
|
|
1188
|
+
for (const [field, value] of fields) {
|
|
1189
|
+
stamps.push(` store ${this.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}` : ""}`);
|
|
1093
1190
|
}
|
|
1094
1191
|
}
|
|
1095
1192
|
if (this.emitterInterval !== null) {
|
|
@@ -1122,12 +1219,13 @@ class LlEmitter {
|
|
|
1122
1219
|
// order-free — the scr_error_set_traced precedent). Only the
|
|
1123
1220
|
// printer emits here (nothing else declares it); scr_exc_pending
|
|
1124
1221
|
// and the loop entry points rode the Set before the flush.
|
|
1125
|
-
out.push(`declare void @scr_exc_print_uncaught()`, ``);
|
|
1222
|
+
out.push(`declare void @scr_exc_print_uncaught()`, `declare zeroext i1 @scr_exc_handle_uncaught(i1 zeroext)`, ``);
|
|
1126
1223
|
}
|
|
1127
1224
|
if (this.mod.lib !== undefined) {
|
|
1128
1225
|
// LIBRARY mode: no @main — the profile-declared external
|
|
1129
|
-
// symbols
|
|
1130
|
-
|
|
1226
|
+
// symbols specified by the library IR instead.
|
|
1227
|
+
for (const line of this.emitLibDefs(globals, globalReleaseLines, stamps))
|
|
1228
|
+
out.push(line);
|
|
1131
1229
|
out.push(`attributes #0 = { sanitize_address }`);
|
|
1132
1230
|
if (this.wasi)
|
|
1133
1231
|
out.push(`attributes #1 = { sanitize_address presplitcoroutine }`);
|
|
@@ -1142,10 +1240,10 @@ class LlEmitter {
|
|
|
1142
1240
|
// Event-surface programs (signal/exit listeners) fill the loop's
|
|
1143
1241
|
// nullable event hooks before %main — scr_events.c links only when
|
|
1144
1242
|
// this line is emitted (native-toolchain.ts gates on the same predicate).
|
|
1145
|
-
...(usesEvents ? [` call void @scr_events_install()`] : []), ...(usesChildProcess ? [` call void @scr_child_dyn_install()`] : []),
|
|
1243
|
+
...(usesEvents ? [` call void @scr_events_install()`] : []), ...(usesChildProcess ? [` call void @scr_child_dyn_install()`] : []), ...(childStreamBoxes ? [` call void @scr_child_dyn_streams_install(ptr @scr_stream_child_ops, ptr @${childStreamBoxes[0]}, ptr @${childStreamBoxes[1]})`] : []),
|
|
1146
1244
|
// fs.watch programs fill the loop's watch hooks the same way —
|
|
1147
1245
|
// scr_watch.c links only when this line is emitted.
|
|
1148
|
-
...(usesFsWatch ? [` call void @scr_watch_install()`] : []), ...(this.ffiHasForeignCallback ? [` call void @scr_ffi_install()`] : []), ...(snapshotsTlsCa ? [` call void @scr_tls_ca_install()`] : []), ...(usesFetch ? [` call void @scr_fetch_install()`] : []), ...(embedsZlib ? [` call void @scr_zlib_island_install()`] : []), ...(embedsNet ? [` call void @scr_net_island_install()`] : []), ...(usesNet ? [` call void @scr_net_install()`, ` call void @scr_net_dyn_install()`] : []), ...(usesHttp ? [` call void @scr_http_dyn_install()`] : []), ...(usesStream ? [` call void @scr_stream_install()`] : []), ` call void @scr_lib_init(i32 %argc, ptr %argv)`, ...(usesIsland
|
|
1246
|
+
...(usesFsWatch ? [` call void @scr_watch_install()`] : []), ...(this.ffiHasForeignCallback ? [` call void @scr_ffi_install()`] : []), ...(snapshotsTlsCa ? [` call void @scr_tls_ca_install()`] : []), ...(usesFetch ? [` call void @scr_fetch_install()`] : []), ...(embedsZlib ? [` call void @scr_zlib_island_install()`] : []), ...(embedsNet ? [` call void @scr_net_island_install()`] : []), ...(usesNet ? [` call void @scr_net_install()`, ` call void @scr_net_dyn_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)`, ...(usesIsland
|
|
1149
1247
|
? [
|
|
1150
1248
|
...(moduleEmbedsCompressedNpm(this.mod)
|
|
1151
1249
|
? [` call void @scr_island_set_inflate(ptr @scr_zlib_inflate_exact)`]
|
|
@@ -1162,10 +1260,14 @@ class LlEmitter {
|
|
|
1162
1260
|
` %exc = call zeroext i1 @scr_exc_pending()`,
|
|
1163
1261
|
` br i1 %exc, label %uncaught, label %ok`,
|
|
1164
1262
|
`uncaught:`,
|
|
1263
|
+
` %handled = call zeroext i1 @scr_exc_handle_uncaught(i1 false)`,
|
|
1264
|
+
` br i1 %handled, label %ok, label %fatal`,
|
|
1265
|
+
`fatal:`,
|
|
1165
1266
|
` call void @scr_exc_print_uncaught()`,
|
|
1166
1267
|
...exitListenerLines("xu"),
|
|
1167
1268
|
...uncaughtReleases,
|
|
1168
|
-
`
|
|
1269
|
+
` %failure_code_0 = call i32 @scr_exit_code_hint_get()`,
|
|
1270
|
+
` ret i32 %failure_code_0`,
|
|
1169
1271
|
`ok:`,
|
|
1170
1272
|
]
|
|
1171
1273
|
: []),
|
|
@@ -1182,7 +1284,8 @@ class LlEmitter {
|
|
|
1182
1284
|
...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
|
|
1183
1285
|
...exitListenerLines("xl"),
|
|
1184
1286
|
...loopReleasesU,
|
|
1185
|
-
`
|
|
1287
|
+
` %failure_code_1 = call i32 @scr_exit_code_hint_get()`,
|
|
1288
|
+
` ret i32 %failure_code_1`,
|
|
1186
1289
|
`lok:`,
|
|
1187
1290
|
` br i1 %loop_rejection, label %lreported, label %lclean`,
|
|
1188
1291
|
`lreported:`,
|
|
@@ -1190,7 +1293,8 @@ class LlEmitter {
|
|
|
1190
1293
|
...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
|
|
1191
1294
|
...exitListenerLines("xq"),
|
|
1192
1295
|
...loopReportedReleases,
|
|
1193
|
-
`
|
|
1296
|
+
` %failure_code_2 = call i32 @scr_exit_code_hint_get()`,
|
|
1297
|
+
` ret i32 %failure_code_2`,
|
|
1194
1298
|
`lclean:`,
|
|
1195
1299
|
...(asyncEntry
|
|
1196
1300
|
? [
|
|
@@ -1207,7 +1311,8 @@ class LlEmitter {
|
|
|
1207
1311
|
` call void @scr_exc_print_uncaught()`,
|
|
1208
1312
|
...exitListenerLines("xt"),
|
|
1209
1313
|
...topRejectReleases,
|
|
1210
|
-
`
|
|
1314
|
+
` %failure_code_3 = call i32 @scr_exit_code_hint_get()`,
|
|
1315
|
+
` ret i32 %failure_code_3`,
|
|
1211
1316
|
`tla_not_rejected:`,
|
|
1212
1317
|
` call void @scr_promise_release(ptr %top)`,
|
|
1213
1318
|
]
|
|
@@ -1217,7 +1322,8 @@ class LlEmitter {
|
|
|
1217
1322
|
`lrej:`,
|
|
1218
1323
|
...exitListenerLines("xr"),
|
|
1219
1324
|
...loopReleasesR,
|
|
1220
|
-
`
|
|
1325
|
+
` %failure_code_4 = call i32 @scr_exit_code_hint_get()`,
|
|
1326
|
+
` ret i32 %failure_code_4`,
|
|
1221
1327
|
`lrok:`,
|
|
1222
1328
|
...(asyncEntry
|
|
1223
1329
|
? [
|
|
@@ -1271,11 +1377,15 @@ class LlEmitter {
|
|
|
1271
1377
|
for (const e of lib.exports)
|
|
1272
1378
|
emitSymConst(e.symbol);
|
|
1273
1379
|
out.push(``);
|
|
1380
|
+
if (this.wasi) {
|
|
1381
|
+
for (const symbol of ["scriptc_alloc", "scriptc_free"])
|
|
1382
|
+
emitSymConst(symbol);
|
|
1383
|
+
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`, `}`, ``);
|
|
1384
|
+
}
|
|
1274
1385
|
// The runtime detected-trap overlay table (scr_runtime.h declares it,
|
|
1275
1386
|
// the library trap funnel consults it): flat code/teaching/remediation
|
|
1276
1387
|
// triples, one per runtime trap code (SC4013–SC4019) the profile
|
|
1277
|
-
// declares text for
|
|
1278
|
-
// funnel-assembled sink message is emission-invariant by construction.
|
|
1388
|
+
// declares text for. The funnel assembles the structured sink message.
|
|
1279
1389
|
// The empty table still defines the symbols the funnel links against.
|
|
1280
1390
|
const ovlCells = [];
|
|
1281
1391
|
lib.trapOverlays.forEach((o, i) => {
|
|
@@ -1309,8 +1419,8 @@ class LlEmitter {
|
|
|
1309
1419
|
// Host-callback channels: the per-channel name constants (the
|
|
1310
1420
|
// registration dispatch's strcmp operands), the per-channel
|
|
1311
1421
|
// unregistered-call trap constants (the ffiCall sites'
|
|
1312
|
-
// scr_library_cb_require operands
|
|
1313
|
-
//
|
|
1422
|
+
// scr_library_cb_require operands), and the registration function:
|
|
1423
|
+
// a pure store dispatch
|
|
1314
1424
|
// (the sink registration's rule — no entry prologue, no poison
|
|
1315
1425
|
// guard) whose first operation rejects callback-time re-entry
|
|
1316
1426
|
// (SC4026). An unknown or NULL name is a defined -1, never a store.
|
|
@@ -1330,7 +1440,8 @@ class LlEmitter {
|
|
|
1330
1440
|
// from the poisoned guard and every runtime touch (ratified), so a
|
|
1331
1441
|
// host can read them before init and after a trap. The u64 rides
|
|
1332
1442
|
// i64 two's-complement (LLVM integer constants are signed).
|
|
1333
|
-
|
|
1443
|
+
for (const line of emitLibraryIdentityLines(lib.identity, FN_ATTRS))
|
|
1444
|
+
out.push(line);
|
|
1334
1445
|
}
|
|
1335
1446
|
if (lib.resultResetSymbol !== null) {
|
|
1336
1447
|
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`, `}`, ``);
|
|
@@ -1345,8 +1456,7 @@ class LlEmitter {
|
|
|
1345
1456
|
if (e.inboundBytesTrap !== undefined) {
|
|
1346
1457
|
// The bytes-in helper's trap message: the compiler-assembled
|
|
1347
1458
|
// structured trap-teaching form (0x01 text 0x1F SC4012 0x1F symbol
|
|
1348
|
-
// [0x1F remediation])
|
|
1349
|
-
// the sink message is emission-invariant by construction.
|
|
1459
|
+
// [0x1F remediation]) consumed by the runtime sink.
|
|
1350
1460
|
const trapBytes = Buffer.byteLength(e.inboundBytesTrap, "utf8");
|
|
1351
1461
|
out.push(`@sc_lib_bytes_trap_${e.symbol} = internal constant [${trapBytes + 1} x i8] c"${llStrBytes(e.inboundBytesTrap)}"`, ``);
|
|
1352
1462
|
}
|
|
@@ -1450,7 +1560,7 @@ class LlEmitter {
|
|
|
1450
1560
|
}
|
|
1451
1561
|
/** The shared abort helpers (emitted only when referenced): the OOM
|
|
1452
1562
|
* abort of untraced shape allocation and the invalid-union-tag abort —
|
|
1453
|
-
* both print the
|
|
1563
|
+
* both print the runtime ABI’s exact message on fd 2 and abort. */
|
|
1454
1564
|
helperDefs() {
|
|
1455
1565
|
const defs = [];
|
|
1456
1566
|
const msgHelper = (fnName, msgSym, msg) => {
|
|
@@ -1485,7 +1595,7 @@ class LlEmitter {
|
|
|
1485
1595
|
return defs.length > 0 ? [...defs] : defs;
|
|
1486
1596
|
}
|
|
1487
1597
|
/** Env-signature wrappers + interned immortal closures for declared
|
|
1488
|
-
* functions used as values (the
|
|
1598
|
+
* functions used as values (the runtime ABI’s sc_w_/sc_fc_ pair): every
|
|
1489
1599
|
* mention of `f` yields the same pointer, so `f === f` holds. */
|
|
1490
1600
|
emitFnValueDefs() {
|
|
1491
1601
|
const out = [];
|
|
@@ -1498,7 +1608,7 @@ class LlEmitter {
|
|
|
1498
1608
|
// never the inner return type.
|
|
1499
1609
|
const ret = fn.async === true || fn.generator !== undefined ? "ptr" : this.llType(fn.returnType);
|
|
1500
1610
|
const call = `call ${ret} @${this.callTarget(name)}(${args})`;
|
|
1501
|
-
out.push(`define internal ${ret} @${mangleWrapper(name)}(ptr %env${params.length ? ", " + params.join(", ") : ""}) ${FN_ATTRS} { ; ${name} as a value`, `entry:`, ret === "void" ? ` ${call}` : ` %r = ${call}`, ret === "void" ? ` ret void` : ` ret ${ret} %r`, `}`, `@${mangleFnClosure(name)} = internal global %ScrClosure { ${this.sizeType} -1, ptr @${mangleWrapper(name)}, ${this.sizeType} 0, ptr null }`, ``);
|
|
1611
|
+
out.push(`define internal ${ret} @${mangleWrapper(name)}(ptr %env${params.length ? ", " + params.join(", ") : ""}) ${FN_ATTRS} { ; ${name} as a value`, `entry:`, ret === "void" ? ` ${call}` : ` %r = ${call}`, ret === "void" ? ` ret void` : ` ret ${ret} %r`, `}`, `@${mangleFnClosure(name)} = internal global %ScrClosure { ${this.sizeType} -1, ptr @${mangleWrapper(name)}, ${this.sizeType} 0, ptr null, i32 ${(fn.generator ? 1 : 0) + (fn.async ? 2 : 0) + (fn.ownsPrototype ? 4 : 0)} }`, ``);
|
|
1502
1612
|
}
|
|
1503
1613
|
return out;
|
|
1504
1614
|
}
|
|
@@ -1570,7 +1680,8 @@ class LlEmitter {
|
|
|
1570
1680
|
if (fn.async !== true || fn.generator !== undefined)
|
|
1571
1681
|
continue;
|
|
1572
1682
|
const { definitions, ret, tr, spawnParams, argPackLines } = this.emitArgPackAndTrampolinePrologue(fn);
|
|
1573
|
-
|
|
1683
|
+
for (const line of definitions)
|
|
1684
|
+
out.push(line);
|
|
1574
1685
|
this.declare(`declare ptr @scr_fiber_promise(ptr)`);
|
|
1575
1686
|
this.declare(`declare ptr @scr_async_spawn(ptr, ptr)`);
|
|
1576
1687
|
this.needOom();
|
|
@@ -1603,20 +1714,25 @@ class LlEmitter {
|
|
|
1603
1714
|
this.declare(`declare void @scr_promise_fulfill_str(ptr, ptr)`);
|
|
1604
1715
|
tr.push(` call void @scr_promise_fulfill_str(ptr %pr, ptr %r) ; moves in`);
|
|
1605
1716
|
break;
|
|
1717
|
+
case "dyn":
|
|
1718
|
+
this.declare(`declare void @scr_promise_resolve_dyn(ptr, ptr)`);
|
|
1719
|
+
tr.push(` call void @scr_promise_resolve_dyn(ptr %pr, ptr %r) ; moves in`);
|
|
1720
|
+
break;
|
|
1606
1721
|
default: {
|
|
1607
|
-
const v = vAdapters(this, ret);
|
|
1722
|
+
const v = vAdapters(this.shapeHost, ret);
|
|
1608
1723
|
this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
|
|
1609
|
-
tr.push(` call void @scr_promise_fulfill_ref(ptr %pr, ptr %r, ptr ${v.retain}, ptr ${v.release}, ptr ${traceArg(this, ret)})`);
|
|
1724
|
+
tr.push(` call void @scr_promise_fulfill_ref(ptr %pr, ptr %r, ptr ${v.retain}, ptr ${v.release}, ptr ${traceArg(this.shapeHost, ret)})`);
|
|
1610
1725
|
}
|
|
1611
1726
|
}
|
|
1612
1727
|
tr.push(` ret void`, `thrown:`);
|
|
1613
1728
|
if (ret.kind !== "void" && isRefCounted(ret)) {
|
|
1614
1729
|
// An escaping throw means %r is the never-read dummy (NULL).
|
|
1615
|
-
tr.push(` call void ${releaseSym(this, ret)}(ptr %r)`);
|
|
1730
|
+
tr.push(` call void ${releaseSym(this.shapeHost, ret)}(ptr %r)`);
|
|
1616
1731
|
}
|
|
1617
1732
|
tr.push(` ret void`, `}`, ``);
|
|
1618
1733
|
}
|
|
1619
|
-
|
|
1734
|
+
for (const line of tr)
|
|
1735
|
+
out.push(line);
|
|
1620
1736
|
// Spawn wrapper: pack the args (+1 moves in), spawn the fiber.
|
|
1621
1737
|
const cache = fn.asyncCacheGlobal !== undefined ? mangleGlobal(fn.asyncCacheGlobal) : null;
|
|
1622
1738
|
const cycleCache = fn.asyncCycleCacheGlobal !== undefined ? mangleGlobal(fn.asyncCycleCacheGlobal) : null;
|
|
@@ -1676,9 +1792,11 @@ class LlEmitter {
|
|
|
1676
1792
|
` store ptr %cycle_cache_owned, ptr @${cycleCache}`,
|
|
1677
1793
|
]
|
|
1678
1794
|
: []), ` ret ptr %p`, `}`, ``);
|
|
1679
|
-
|
|
1795
|
+
for (const line of sp)
|
|
1796
|
+
out.push(line);
|
|
1680
1797
|
}
|
|
1681
|
-
|
|
1798
|
+
for (const line of this.emitGenScaffolding())
|
|
1799
|
+
out.push(line);
|
|
1682
1800
|
return out;
|
|
1683
1801
|
}
|
|
1684
1802
|
/** Per-generator-function machinery — the async scaffolding's lazy
|
|
@@ -1693,7 +1811,8 @@ class LlEmitter {
|
|
|
1693
1811
|
if (fn.generator === undefined)
|
|
1694
1812
|
continue;
|
|
1695
1813
|
const { definitions, pack, lifted, fieldTys, ret, tr, spawnParams, argPackLines, } = this.emitArgPackAndTrampolinePrologue(fn);
|
|
1696
|
-
|
|
1814
|
+
for (const line of definitions)
|
|
1815
|
+
out.push(line);
|
|
1697
1816
|
this.declare(`declare zeroext i1 @scr_exc_genret_pending()`);
|
|
1698
1817
|
this.declare(`declare void @scr_exc_clear()`);
|
|
1699
1818
|
this.declare(`declare ptr @scr_gen_of_fiber(ptr)`);
|
|
@@ -1726,18 +1845,19 @@ class LlEmitter {
|
|
|
1726
1845
|
tr.push(` call void @scr_gen_out_bool(ptr %g, i1 %r)`, ` br label %done`);
|
|
1727
1846
|
break;
|
|
1728
1847
|
default: {
|
|
1729
|
-
const v = vAdapters(this, ret);
|
|
1848
|
+
const v = vAdapters(this.shapeHost, ret);
|
|
1730
1849
|
this.declare(`declare void @scr_gen_out_ref(ptr, ptr, ptr)`);
|
|
1731
1850
|
tr.push(` call void @scr_gen_out_ref(ptr %g, ptr %r, ptr ${v.release})`, ` br label %done`);
|
|
1732
1851
|
}
|
|
1733
1852
|
}
|
|
1734
1853
|
tr.push(`thrown:`, ` %genret = call zeroext i1 @scr_exc_genret_pending()`, ` br i1 %genret, label %promote, label %dropdummy`, `promote:`, ` call void @scr_exc_clear()`, ` call void @scr_gen_ret_to_out(ptr %g)`, ` br label %dropdummy`, `dropdummy:`);
|
|
1735
1854
|
if (ret.kind !== "void" && isRefCounted(ret)) {
|
|
1736
|
-
tr.push(` call void ${releaseSym(this, ret)}(ptr %r) ; unwound: the never-read dummy`);
|
|
1855
|
+
tr.push(` call void ${releaseSym(this.shapeHost, ret)}(ptr %r) ; unwound: the never-read dummy`);
|
|
1737
1856
|
}
|
|
1738
1857
|
tr.push(` br label %done`, `done:`, ` ret void`, `}`, ``);
|
|
1739
1858
|
}
|
|
1740
|
-
|
|
1859
|
+
for (const line of tr)
|
|
1860
|
+
out.push(line);
|
|
1741
1861
|
let settleAsync = null;
|
|
1742
1862
|
if (fn.async) {
|
|
1743
1863
|
this.declare(`declare ptr @scr_async_gen_new(ptr, ptr, ptr, ptr)`);
|
|
@@ -1754,8 +1874,8 @@ class LlEmitter {
|
|
|
1754
1874
|
const settleKey = `ags:${typeKey(genT)}`;
|
|
1755
1875
|
if (!this.resolveThunks.has(settleKey)) {
|
|
1756
1876
|
this.resolveThunks.set(settleKey, settleAsync);
|
|
1757
|
-
const adapters = vAdapters(this, resultT);
|
|
1758
|
-
this.resolveThunkDefs.push(`define internal void @${settleAsync}(ptr %g, ptr %p) ${FN_ATTRS} {`, `entry:`, ` %r = call ptr @${build}(ptr %g)`, ` call void @scr_promise_fulfill_ref(ptr %p, ptr %r, ptr ${adapters.retain}, ptr ${adapters.release}, ptr ${traceArg(this, resultT)})`, ` ret void`, `}`, ``);
|
|
1877
|
+
const adapters = vAdapters(this.shapeHost, resultT);
|
|
1878
|
+
this.resolveThunkDefs.push(`define internal void @${settleAsync}(ptr %g, ptr %p) ${FN_ATTRS} {`, `entry:`, ` %r = call ptr @${build}(ptr %g)`, ` call void @scr_promise_fulfill_ref(ptr %p, ptr %r, ptr ${adapters.retain}, ptr ${adapters.release}, ptr ${traceArg(this.shapeHost, resultT)})`, ` ret void`, `}`, ``);
|
|
1759
1879
|
}
|
|
1760
1880
|
this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
|
|
1761
1881
|
}
|
|
@@ -1775,11 +1895,12 @@ class LlEmitter {
|
|
|
1775
1895
|
dr.push(` call void @scr_closure_release(ptr %dv${i})`);
|
|
1776
1896
|
}
|
|
1777
1897
|
else {
|
|
1778
|
-
dr.push(` call void ${releaseSym(this, pType)}(ptr %dv${i})`);
|
|
1898
|
+
dr.push(` call void ${releaseSym(this.shapeHost, pType)}(ptr %dv${i})`);
|
|
1779
1899
|
}
|
|
1780
1900
|
});
|
|
1781
1901
|
dr.push(` call void @free(ptr %ap)`, ` ret void`, `}`, ``);
|
|
1782
|
-
|
|
1902
|
+
for (const line of dr)
|
|
1903
|
+
out.push(line);
|
|
1783
1904
|
// Spawn wrapper: pack the args (+1 moves in), allocate the
|
|
1784
1905
|
// SUSPENDED fiber — nothing runs until the first .next().
|
|
1785
1906
|
if (lifted) {
|
|
@@ -1793,11 +1914,12 @@ class LlEmitter {
|
|
|
1793
1914
|
sp.push(settleAsync === null
|
|
1794
1915
|
? ` %gg = call ptr @scr_gen_new(ptr @${mangleTrampoline(fn.name)}, ptr %ap, ptr @${mangleGenDrop(fn.name)})`
|
|
1795
1916
|
: ` %gg = call ptr @scr_async_gen_new(ptr @${mangleTrampoline(fn.name)}, ptr %ap, ptr @${mangleGenDrop(fn.name)}, ptr @${settleAsync})`, ` ret ptr %gg`, `}`, ``);
|
|
1796
|
-
|
|
1917
|
+
for (const line of sp)
|
|
1918
|
+
out.push(line);
|
|
1797
1919
|
}
|
|
1798
1920
|
return out;
|
|
1799
1921
|
}
|
|
1800
|
-
// ── plumbing (
|
|
1922
|
+
// ── plumbing (frame and scope ownership) ──────
|
|
1801
1923
|
internLiteral(text) {
|
|
1802
1924
|
let lit = this.literals.get(text);
|
|
1803
1925
|
if (!lit) {
|
|
@@ -1877,20 +1999,26 @@ class LlEmitter {
|
|
|
1877
1999
|
* the `_v` table (immortals skip, exactly the C retain calls). */
|
|
1878
2000
|
retainValue(name, type) {
|
|
1879
2001
|
const t = this.B.tmp();
|
|
1880
|
-
this.B.line(`${t} = call ptr ${retainSym(this, type)}(ptr ${name})`);
|
|
2002
|
+
this.B.line(`${t} = call ptr ${retainSym(this.shapeHost, type)}(ptr ${name})`);
|
|
1881
2003
|
return t;
|
|
1882
2004
|
}
|
|
1883
2005
|
/** The release call for one owned refcounted value — type-directed like
|
|
1884
2006
|
* releaseCallC (all runtime releases are NULL-tolerant). */
|
|
1885
2007
|
releaseValue(name, type) {
|
|
1886
|
-
this.B.line(`call void ${releaseSym(this, type)}(ptr ${name})`);
|
|
2008
|
+
this.B.line(`call void ${releaseSym(this.shapeHost, type)}(ptr ${name})`);
|
|
1887
2009
|
}
|
|
1888
2010
|
releaseFrame(frame) {
|
|
1889
2011
|
for (const v of frame) {
|
|
1890
2012
|
if (v.slot) {
|
|
1891
2013
|
const t = this.B.tmp();
|
|
1892
2014
|
this.B.line(`${t} = load ptr, ptr ${v.name}`);
|
|
1893
|
-
|
|
2015
|
+
if (v.boxed) {
|
|
2016
|
+
this.declare(`declare void @scr_box_release(ptr)`);
|
|
2017
|
+
this.B.line(`call void @scr_box_release(ptr ${t})`);
|
|
2018
|
+
}
|
|
2019
|
+
else {
|
|
2020
|
+
this.releaseValue(t, v.type);
|
|
2021
|
+
}
|
|
1894
2022
|
}
|
|
1895
2023
|
else {
|
|
1896
2024
|
this.releaseValue(v.name, v.type);
|
|
@@ -1913,7 +2041,7 @@ class LlEmitter {
|
|
|
1913
2041
|
/** THE release-on-jump path (break/continue/return): pending statement
|
|
1914
2042
|
* frames and entered scopes down to the given depths, innermost first —
|
|
1915
2043
|
* everything whose normal fall-through releases the jump bypasses.
|
|
1916
|
-
*
|
|
2044
|
+
* Release every scope crossed by the control-flow edge. */
|
|
1917
2045
|
releaseForJump(frameDepth, scopeDepth) {
|
|
1918
2046
|
for (let i = this.frames.length - 1; i >= frameDepth; i--)
|
|
1919
2047
|
this.releaseFrame(this.frames[i]);
|
|
@@ -1953,29 +2081,47 @@ class LlEmitter {
|
|
|
1953
2081
|
* function — and branch to the handler / return a dummy value (never
|
|
1954
2082
|
* read: callers of a may-throw function test the pending flag before
|
|
1955
2083
|
* using the result). Callers own the surrounding pending branch; a
|
|
1956
|
-
* `throw` unwinds unconditionally.
|
|
2084
|
+
* `throw` unwinds unconditionally. */
|
|
1957
2085
|
emitUnwind() {
|
|
1958
2086
|
const target = this.tryStack[this.tryStack.length - 1];
|
|
2087
|
+
const frameDepth = target?.frameDepth ?? 0;
|
|
2088
|
+
const scopeDepth = target?.scopeDepth ?? 0;
|
|
2089
|
+
for (let i = this.frames.length - 1; i >= frameDepth; i--)
|
|
2090
|
+
this.releaseFrame(this.frames[i]);
|
|
2091
|
+
let terminator;
|
|
1959
2092
|
if (target) {
|
|
1960
|
-
this.releaseForJump(target.frameDepth, target.scopeDepth);
|
|
1961
2093
|
target.used = true;
|
|
1962
|
-
|
|
1963
|
-
return;
|
|
2094
|
+
terminator = `br label %${target.label}`;
|
|
1964
2095
|
}
|
|
1965
|
-
this.
|
|
1966
|
-
|
|
1967
|
-
|
|
2096
|
+
else if (this.currentWasiCoro !== null) {
|
|
2097
|
+
terminator = `br label %${this.currentWasiCoro.finalLabel}`;
|
|
2098
|
+
}
|
|
2099
|
+
else {
|
|
2100
|
+
const t = this.currentReturnType;
|
|
2101
|
+
terminator = t.kind === "void" ? "ret void"
|
|
2102
|
+
: t.kind === "f64" || t.kind === "date" ? `ret double ${f64Lit(0)}`
|
|
2103
|
+
: t.kind === "bool" ? "ret i1 false" : "ret ptr null";
|
|
2104
|
+
}
|
|
2105
|
+
// Copy the entries now: later declarations extend these lexical scopes.
|
|
2106
|
+
// Release order and the handler are part of the shared block's identity.
|
|
2107
|
+
const entries = [];
|
|
2108
|
+
let key = terminator;
|
|
2109
|
+
for (let i = this.scopes.length - 1; i >= scopeDepth; i--) {
|
|
2110
|
+
for (const entry of this.scopes[i]) {
|
|
2111
|
+
entries.push(entry);
|
|
2112
|
+
key += `\0${entry.slot}\0${entry.boxed ? "@scr_box_release" : releaseSym(this.shapeHost, entry.type)}`;
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
if (entries.length === 0) {
|
|
2116
|
+
this.B.terminate(terminator);
|
|
1968
2117
|
return;
|
|
1969
2118
|
}
|
|
1970
|
-
|
|
1971
|
-
if (
|
|
1972
|
-
this.B.
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
this.B.terminate("ret i1 false");
|
|
1977
|
-
else
|
|
1978
|
-
this.B.terminate("ret ptr null");
|
|
2119
|
+
let cleanup = this.unwindCleanups.get(key);
|
|
2120
|
+
if (!cleanup) {
|
|
2121
|
+
cleanup = { label: this.B.newLabel("exc.cleanup"), entries, terminator };
|
|
2122
|
+
this.unwindCleanups.set(key, cleanup);
|
|
2123
|
+
}
|
|
2124
|
+
this.B.br(cleanup.label);
|
|
1979
2125
|
}
|
|
1980
2126
|
/** The emitter contract for exceptions: after EVERY call that can throw
|
|
1981
2127
|
* (per the may-throw analysis), test the pending flag and unwind. The
|
|
@@ -2021,28 +2167,32 @@ class LlEmitter {
|
|
|
2021
2167
|
// Hierarchy instances carry a vtable word: the OBJ kind keeps the
|
|
2022
2168
|
// dynamic class inspectable (catch-binding instanceof, the uncaught
|
|
2023
2169
|
// printer's "name: message" for Error instances).
|
|
2024
|
-
const rc = vAdapters(this, t);
|
|
2170
|
+
const rc = vAdapters(this.shapeHost, t);
|
|
2025
2171
|
this.declare(`declare void @scr_throw_obj(ptr, ptr, ptr, ptr)`);
|
|
2026
|
-
B.line(`call void @scr_throw_obj(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)})`);
|
|
2172
|
+
B.line(`call void @scr_throw_obj(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, t)})`);
|
|
2027
2173
|
}
|
|
2028
2174
|
else if (t.kind === "symbol" || t.kind === "bigint" || t.kind === "func" || t.kind === "classval") {
|
|
2029
|
-
const rc = vAdapters(this, t);
|
|
2175
|
+
const rc = vAdapters(this.shapeHost, t);
|
|
2030
2176
|
this.declare(`declare void @scr_throw_primitive_ref(ptr, ptr, ptr, ptr)`);
|
|
2031
2177
|
B.line(`call void @scr_throw_primitive_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr null)`);
|
|
2032
2178
|
}
|
|
2033
|
-
else if (t.kind === "dyn"
|
|
2034
|
-
|
|
2035
|
-
|
|
2179
|
+
else if (t.kind === "dyn") {
|
|
2180
|
+
this.declare(`declare void @scr_dyn_throw(ptr)`);
|
|
2181
|
+
B.line(`call void @scr_dyn_throw(ptr ${v.name})`);
|
|
2182
|
+
}
|
|
2183
|
+
else if (t.kind === "jsval") {
|
|
2184
|
+
const rc = vAdapters(this.shapeHost, t);
|
|
2185
|
+
const test = "scr_jsval_is_object";
|
|
2036
2186
|
this.declare(`declare zeroext i1 @${test}(ptr)`);
|
|
2037
2187
|
this.declare(`declare void @scr_throw_ref_classified(ptr, ptr, ptr, ptr, i1 zeroext)`);
|
|
2038
2188
|
const object = B.tmp();
|
|
2039
2189
|
B.line(`${object} = call zeroext i1 @${test}(ptr ${v.name})`);
|
|
2040
|
-
B.line(`call void @scr_throw_ref_classified(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)}, i1 zeroext ${object})`);
|
|
2190
|
+
B.line(`call void @scr_throw_ref_classified(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, t)}, i1 zeroext ${object})`);
|
|
2041
2191
|
}
|
|
2042
2192
|
else {
|
|
2043
|
-
const rc = vAdapters(this, t);
|
|
2193
|
+
const rc = vAdapters(this.shapeHost, t);
|
|
2044
2194
|
this.declare(`declare void @scr_throw_ref(ptr, ptr, ptr, ptr)`);
|
|
2045
|
-
B.line(`call void @scr_throw_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)})`);
|
|
2195
|
+
B.line(`call void @scr_throw_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, t)})`);
|
|
2046
2196
|
}
|
|
2047
2197
|
}
|
|
2048
2198
|
/** JS truthiness of a value (falsy: false, 0, -0, NaN, "", nullish
|
|
@@ -2052,7 +2202,7 @@ class LlEmitter {
|
|
|
2052
2202
|
truthy(v) {
|
|
2053
2203
|
const B = this.B;
|
|
2054
2204
|
if (v.type.kind === "union") {
|
|
2055
|
-
// The ARM value's ToBoolean: an inline tag switch (the
|
|
2205
|
+
// The ARM value's ToBoolean: an inline tag switch (the runtime ABI’s
|
|
2056
2206
|
// per-union interned helper, emitted at the use site instead).
|
|
2057
2207
|
const def = this.unionsById.get(v.type.unionId);
|
|
2058
2208
|
if (!def)
|
|
@@ -2062,7 +2212,7 @@ class LlEmitter {
|
|
|
2062
2212
|
const join = B.newLabel("ut.j");
|
|
2063
2213
|
this.unionTagSwitch(v.name, def, (arm) => {
|
|
2064
2214
|
let valueName = "false";
|
|
2065
|
-
if (arm.kind === "f64") {
|
|
2215
|
+
if (arm.kind === "f64" || arm.kind === "procStream") {
|
|
2066
2216
|
valueName = B.tmp();
|
|
2067
2217
|
this.declare(`declare double @scr_union_get_f64(ptr)`);
|
|
2068
2218
|
B.line(`${valueName} = call double @scr_union_get_f64(ptr ${v.name})`);
|
|
@@ -2075,7 +2225,7 @@ class LlEmitter {
|
|
|
2075
2225
|
else if (arm.kind === "string") {
|
|
2076
2226
|
valueName = this.unionPeek(v.name);
|
|
2077
2227
|
}
|
|
2078
|
-
else if (arm.kind === "bigint") {
|
|
2228
|
+
else if (arm.kind === "bigint" || arm.kind === "dyn" || arm.kind === "jsval") {
|
|
2079
2229
|
valueName = this.unionPeek(v.name);
|
|
2080
2230
|
}
|
|
2081
2231
|
const truthy = this.truthyOf(arm.kind, valueName, true);
|
|
@@ -2096,15 +2246,10 @@ class LlEmitter {
|
|
|
2096
2246
|
switch (kind) {
|
|
2097
2247
|
case "undefinedT":
|
|
2098
2248
|
case "nullT":
|
|
2099
|
-
if (!unionArm)
|
|
2100
|
-
throw new LlvmUnsupportedError(`truthy:${kind}`);
|
|
2101
2249
|
return "false";
|
|
2102
2250
|
case "bool":
|
|
2103
2251
|
return valueName;
|
|
2104
|
-
case "f64":
|
|
2105
|
-
case "procStream": {
|
|
2106
|
-
if (unionArm && kind === "procStream")
|
|
2107
|
-
throw new LlvmUnsupportedError(`truthy:union:${kind}`);
|
|
2252
|
+
case "f64": {
|
|
2108
2253
|
const truthy = B.tmp();
|
|
2109
2254
|
B.line(`${truthy} = fcmp one double ${valueName}, ${f64Lit(0)}`);
|
|
2110
2255
|
return truthy;
|
|
@@ -2125,6 +2270,9 @@ class LlEmitter {
|
|
|
2125
2270
|
return truthy;
|
|
2126
2271
|
}
|
|
2127
2272
|
case "date":
|
|
2273
|
+
// Process streams use a numeric descriptor internally, including zero
|
|
2274
|
+
// for stdin. They remain JavaScript objects in boolean contexts.
|
|
2275
|
+
case "procStream":
|
|
2128
2276
|
return "true";
|
|
2129
2277
|
case "array":
|
|
2130
2278
|
case "record":
|
|
@@ -2148,7 +2296,17 @@ class LlEmitter {
|
|
|
2148
2296
|
case "generator":
|
|
2149
2297
|
case "fsWatcher":
|
|
2150
2298
|
case "cryptoHash":
|
|
2151
|
-
case "cryptoHmac":
|
|
2299
|
+
case "cryptoHmac":
|
|
2300
|
+
case "netSocket":
|
|
2301
|
+
case "netServer":
|
|
2302
|
+
case "httpReq":
|
|
2303
|
+
case "httpRes":
|
|
2304
|
+
case "httpClientReq":
|
|
2305
|
+
case "http2Session":
|
|
2306
|
+
case "http2Stream":
|
|
2307
|
+
case "dgramSocket":
|
|
2308
|
+
case "secureCtx":
|
|
2309
|
+
case "testCtx": {
|
|
2152
2310
|
if (unionArm)
|
|
2153
2311
|
return "true";
|
|
2154
2312
|
const truthy = B.tmp();
|
|
@@ -2156,16 +2314,12 @@ class LlEmitter {
|
|
|
2156
2314
|
return truthy;
|
|
2157
2315
|
}
|
|
2158
2316
|
case "dyn": {
|
|
2159
|
-
if (unionArm)
|
|
2160
|
-
throw new LlvmUnsupportedError(`truthy:union:${kind}`);
|
|
2161
2317
|
this.declare(`declare zeroext i1 @scr_dyn_truthy(ptr)`);
|
|
2162
2318
|
const truthy = B.tmp();
|
|
2163
2319
|
B.line(`${truthy} = call zeroext i1 @scr_dyn_truthy(ptr ${valueName})`);
|
|
2164
2320
|
return truthy;
|
|
2165
2321
|
}
|
|
2166
2322
|
case "jsval": {
|
|
2167
|
-
if (unionArm)
|
|
2168
|
-
throw new LlvmUnsupportedError(`truthy:union:${kind}`);
|
|
2169
2323
|
this.declare(`declare i32 @scr_jsval_truthy(ptr)`);
|
|
2170
2324
|
const raw = B.tmp();
|
|
2171
2325
|
const truthy = B.tmp();
|
|
@@ -2197,17 +2351,48 @@ class LlEmitter {
|
|
|
2197
2351
|
}
|
|
2198
2352
|
/** Emits `switch` over a union's tag with one block per arm; each arm
|
|
2199
2353
|
* body must TERMINATE its block (the callers branch to a join). The
|
|
2200
|
-
* default block is the
|
|
2201
|
-
|
|
2354
|
+
* default block is the runtime ABI’s invalid-tag abort. Shared field
|
|
2355
|
+
* reads can group equivalent storage prefixes and emit one representative. */
|
|
2356
|
+
unionTagSwitch(uName, def, arm, fieldGroups) {
|
|
2202
2357
|
const B = this.B;
|
|
2203
2358
|
const tag = this.unionTag(uName);
|
|
2204
2359
|
const bad = B.newLabel("u.bad");
|
|
2205
|
-
const labels =
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2360
|
+
const labels = [];
|
|
2361
|
+
if (fieldGroups) {
|
|
2362
|
+
for (const group of fieldGroups) {
|
|
2363
|
+
const label = B.newLabel("u.a");
|
|
2364
|
+
for (const member of group) {
|
|
2365
|
+
if (member === undefined)
|
|
2366
|
+
throw new InternalCompilerError("llvm emitter bug: missing union field tag");
|
|
2367
|
+
labels[member] = label;
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
else {
|
|
2372
|
+
for (let i = 0; i < def.arms.length; i++)
|
|
2373
|
+
labels.push(B.newLabel("u.a"));
|
|
2374
|
+
}
|
|
2375
|
+
if (fieldGroups?.length === 1) {
|
|
2376
|
+
const valid = B.tmp();
|
|
2377
|
+
B.line(`${valid} = icmp ult i32 ${tag}, ${def.arms.length}`);
|
|
2378
|
+
B.condBr(valid, labels[0], bad);
|
|
2379
|
+
}
|
|
2380
|
+
else {
|
|
2381
|
+
B.terminate(`switch i32 ${tag}, label %${bad} [ ${def.arms.map((_, i) => `i32 ${i}, label %${labels[i]}`).join(" ")} ]`);
|
|
2382
|
+
}
|
|
2383
|
+
if (fieldGroups) {
|
|
2384
|
+
for (const group of fieldGroups) {
|
|
2385
|
+
const representative = group[0];
|
|
2386
|
+
B.startBlock(labels[representative]);
|
|
2387
|
+
arm(def.arms[representative], representative);
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
else {
|
|
2391
|
+
def.arms.forEach((a, i) => {
|
|
2392
|
+
B.startBlock(labels[i]);
|
|
2393
|
+
arm(a, i);
|
|
2394
|
+
});
|
|
2395
|
+
}
|
|
2211
2396
|
B.startBlock(bad);
|
|
2212
2397
|
this.needsBadTag = true;
|
|
2213
2398
|
B.line(`call void @sc_bad_tag()`);
|
|
@@ -2248,9 +2433,9 @@ class LlEmitter {
|
|
|
2248
2433
|
B.line(`${t} = call ptr @scr_union_new_bool(i32 ${tag}, i1 ${v.name})`);
|
|
2249
2434
|
return t;
|
|
2250
2435
|
}
|
|
2251
|
-
const rc = vAdapters(this, v.type);
|
|
2436
|
+
const rc = vAdapters(this.shapeHost, v.type);
|
|
2252
2437
|
this.declare(`declare ptr @scr_union_new_ref(i32, ptr, ptr, ptr, ptr)`);
|
|
2253
|
-
B.line(`${t} = call ptr @scr_union_new_ref(i32 ${tag}, ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, v.type)})`);
|
|
2438
|
+
B.line(`${t} = call ptr @scr_union_new_ref(i32 ${tag}, ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, v.type)})`);
|
|
2254
2439
|
return t;
|
|
2255
2440
|
}
|
|
2256
2441
|
// ── class plumbing ──────────────────────────────────────────────────────
|
|
@@ -2263,7 +2448,7 @@ class LlEmitter {
|
|
|
2263
2448
|
/** The field-slot pointer of a class member: rc at 0, the vtable word at
|
|
2264
2449
|
* 1 on hierarchy members, then the flattened field list. Runtime error
|
|
2265
2450
|
* classes GEP through %ScrError (their structs live in the runtime; the
|
|
2266
|
-
* def's [name, message, %code] order matches the layout). */
|
|
2451
|
+
* def's [name, message, %code, %cause] order matches the layout). */
|
|
2267
2452
|
classFieldPtr(objName, className, field) {
|
|
2268
2453
|
const meta = this.classMetaOf(className);
|
|
2269
2454
|
const { index, type } = classFieldIndex(meta, field);
|
|
@@ -2302,6 +2487,37 @@ class LlEmitter {
|
|
|
2302
2487
|
throw new InternalCompilerError(`llvm emitter bug: unknown record shape ${shapeId}`);
|
|
2303
2488
|
return shape;
|
|
2304
2489
|
}
|
|
2490
|
+
/** Record prefixes with the same LLVM storage types put a field at the
|
|
2491
|
+
* same offset on every target. Share one field-read block per matching
|
|
2492
|
+
* prefix; class variants retain their own concrete layout dispatch. */
|
|
2493
|
+
unionFieldGroups(def, field) {
|
|
2494
|
+
const key = `${def.id}\0${field}`;
|
|
2495
|
+
const cached = this.unionFieldReadGroups.get(key);
|
|
2496
|
+
if (cached !== undefined)
|
|
2497
|
+
return cached;
|
|
2498
|
+
const groups = new Map();
|
|
2499
|
+
for (let tag = 0; tag < def.arms.length; tag++) {
|
|
2500
|
+
const arm = def.arms[tag];
|
|
2501
|
+
let layout = `variant:${tag}`;
|
|
2502
|
+
if (arm.kind === "record") {
|
|
2503
|
+
const shape = this.recordShape(arm.shapeId);
|
|
2504
|
+
const index = shape.fields.findIndex((entry) => entry.name === field);
|
|
2505
|
+
if (index < 0)
|
|
2506
|
+
throw new InternalCompilerError(`llvm emitter bug: missing union field ${field}`);
|
|
2507
|
+
layout = "record:";
|
|
2508
|
+
for (let i = 0; i <= index; i++)
|
|
2509
|
+
layout += `${llFieldType(shape.fields[i].type)};`;
|
|
2510
|
+
}
|
|
2511
|
+
const group = groups.get(layout);
|
|
2512
|
+
if (group)
|
|
2513
|
+
group.push(tag);
|
|
2514
|
+
else
|
|
2515
|
+
groups.set(layout, [tag]);
|
|
2516
|
+
}
|
|
2517
|
+
const result = [...groups.values()];
|
|
2518
|
+
this.unionFieldReadGroups.set(key, result);
|
|
2519
|
+
return result;
|
|
2520
|
+
}
|
|
2305
2521
|
/** The field-slot pointer of a record member (rc header at index 0). */
|
|
2306
2522
|
recordFieldPtr(objName, shapeId, field) {
|
|
2307
2523
|
const shape = this.recordShape(shapeId);
|
|
@@ -2426,7 +2642,7 @@ class LlEmitter {
|
|
|
2426
2642
|
const B = this.B;
|
|
2427
2643
|
const acc = boxAccess(t);
|
|
2428
2644
|
const cell = B.tmp();
|
|
2429
|
-
B.line(`${cell} = ${arrNewCall(this, t, "1")} ; TDZ cell`);
|
|
2645
|
+
B.line(`${cell} = ${arrNewCall(this.shapeHost, t, "1")} ; TDZ cell`);
|
|
2430
2646
|
this.arrPush(cell, acc === "bool" ? "bool" : "f64", value);
|
|
2431
2647
|
this.declare(`declare void @scr_box_set_ref(ptr, ptr)`);
|
|
2432
2648
|
B.line(`call void @scr_box_set_ref(ptr ${box}, ptr ${cell})`);
|
|
@@ -2435,7 +2651,7 @@ class LlEmitter {
|
|
|
2435
2651
|
* the temporal dead zone — throw Node's exact catchable ReferenceError
|
|
2436
2652
|
* (exprs.ts's varRef guard). Scalars then peek the one-element
|
|
2437
2653
|
* array cell; ref kinds read the box normally (+1). */
|
|
2438
|
-
|
|
2654
|
+
checkTdz(box, name) {
|
|
2439
2655
|
const B = this.B;
|
|
2440
2656
|
const slotp = B.tmp();
|
|
2441
2657
|
const slotv = B.tmp();
|
|
@@ -2443,6 +2659,22 @@ class LlEmitter {
|
|
|
2443
2659
|
B.line(`${slotp} = getelementptr inbounds %ScrBox, ptr ${box}, i64 0, i32 5`);
|
|
2444
2660
|
B.line(`${slotv} = load i64, ptr ${slotp}`);
|
|
2445
2661
|
B.line(`${empty} = icmp eq i64 ${slotv}, 0`);
|
|
2662
|
+
this.throwIfUninitialized(empty, name);
|
|
2663
|
+
return slotv;
|
|
2664
|
+
}
|
|
2665
|
+
checkGlobalTdz(id) {
|
|
2666
|
+
const name = this.tdzGlobals.get(id);
|
|
2667
|
+
if (name === undefined)
|
|
2668
|
+
return;
|
|
2669
|
+
const B = this.B;
|
|
2670
|
+
const value = B.tmp();
|
|
2671
|
+
const empty = B.tmp();
|
|
2672
|
+
B.line(`${value} = load ptr, ptr @${mangleGlobal(id)}`);
|
|
2673
|
+
B.line(`${empty} = icmp eq ptr ${value}, null`);
|
|
2674
|
+
this.throwIfUninitialized(empty, name);
|
|
2675
|
+
}
|
|
2676
|
+
throwIfUninitialized(empty, name) {
|
|
2677
|
+
const B = this.B;
|
|
2446
2678
|
const lt = B.newLabel("tdz.t");
|
|
2447
2679
|
const lk = B.newLabel("tdz.k");
|
|
2448
2680
|
B.condBr(empty, lt, lk);
|
|
@@ -2455,6 +2687,10 @@ class LlEmitter {
|
|
|
2455
2687
|
B.line(`call void @scr_throw_error_named(ptr ${errName}, ptr ${msg})`);
|
|
2456
2688
|
this.emitUnwind();
|
|
2457
2689
|
B.startBlock(lk);
|
|
2690
|
+
}
|
|
2691
|
+
tdzBoxRead(box, t, name) {
|
|
2692
|
+
const slotv = this.checkTdz(box, name);
|
|
2693
|
+
const B = this.B;
|
|
2458
2694
|
const acc = boxAccess(t);
|
|
2459
2695
|
if (acc === "ref")
|
|
2460
2696
|
return this.boxGet(box, t);
|
|
@@ -2468,12 +2704,34 @@ class LlEmitter {
|
|
|
2468
2704
|
B.line(`${v} = call ${accTy} @scr_arr_get_${acc}(ptr ${cell}, double ${f64Lit(0)})`);
|
|
2469
2705
|
return v;
|
|
2470
2706
|
}
|
|
2707
|
+
/** Declaration stores initialize an empty TDZ box. Later stores check
|
|
2708
|
+
* it after the RHS and update scalar cells in place. References move in. */
|
|
2709
|
+
writeBindingBox(box, local, value, initializes = false, borrowed = false) {
|
|
2710
|
+
if (local.tdz) {
|
|
2711
|
+
const first = initializes || !local.mutable;
|
|
2712
|
+
const slotv = first ? null : this.checkTdz(box, local.name);
|
|
2713
|
+
const acc = boxAccess(local.type);
|
|
2714
|
+
if (acc !== "ref") {
|
|
2715
|
+
if (first)
|
|
2716
|
+
this.tdzScalarInit(box, local.type, value);
|
|
2717
|
+
else {
|
|
2718
|
+
const cell = this.B.tmp();
|
|
2719
|
+
this.B.line(`${cell} = inttoptr i64 ${slotv} to ptr`);
|
|
2720
|
+
const ty = acc === "bool" ? "i1" : "double";
|
|
2721
|
+
this.declare(`declare void @scr_arr_set_${acc}(ptr, double, ${acc === "bool" ? "i1 zeroext" : ty})`);
|
|
2722
|
+
this.B.line(`call void @scr_arr_set_${acc}(ptr ${cell}, double ${f64Lit(0)}, ${ty} ${value})`);
|
|
2723
|
+
}
|
|
2724
|
+
return;
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
this.boxSet(box, local.type, borrowed && isRefCounted(local.type) ? this.retainValue(value, local.type) : value);
|
|
2728
|
+
}
|
|
2471
2729
|
// ── functions ───────────────────────────────────────────────────────────
|
|
2472
2730
|
/** The LLVM symbol a direct call or closure enters a function through:
|
|
2473
2731
|
* async bodies are entered via their emitted spawn wrapper (which runs
|
|
2474
2732
|
* the fiber eagerly to its first suspension and returns the promise);
|
|
2475
2733
|
* generator bodies via theirs (which only ALLOCATES the suspended
|
|
2476
|
-
* fiber and returns the generator object)
|
|
2734
|
+
* fiber and returns the generator object). */
|
|
2477
2735
|
callTarget(fnName) {
|
|
2478
2736
|
const fn = this.fnByName.get(fnName);
|
|
2479
2737
|
if (fn?.generator !== undefined)
|
|
@@ -2537,7 +2795,7 @@ class LlEmitter {
|
|
|
2537
2795
|
return;
|
|
2538
2796
|
default:
|
|
2539
2797
|
this.declare(`declare void @scr_gen_out_ref(ptr, ptr, ptr)`);
|
|
2540
|
-
this.B.line(`call void @scr_gen_out_ref(ptr ${gen}, ptr ${v.name}, ptr ${vAdapters(this, ret).release})`);
|
|
2798
|
+
this.B.line(`call void @scr_gen_out_ref(ptr ${gen}, ptr ${v.name}, ptr ${vAdapters(this.shapeHost, ret).release})`);
|
|
2541
2799
|
return;
|
|
2542
2800
|
}
|
|
2543
2801
|
}
|
|
@@ -2562,10 +2820,14 @@ class LlEmitter {
|
|
|
2562
2820
|
this.declare(`declare void @scr_promise_fulfill_str(ptr, ptr)`);
|
|
2563
2821
|
this.B.line(`call void @scr_promise_fulfill_str(ptr ${pr}, ptr ${v.name}) ; moves in`);
|
|
2564
2822
|
break;
|
|
2823
|
+
case "dyn":
|
|
2824
|
+
this.declare(`declare void @scr_promise_resolve_dyn(ptr, ptr)`);
|
|
2825
|
+
this.B.line(`call void @scr_promise_resolve_dyn(ptr ${pr}, ptr ${v.name}) ; moves in`);
|
|
2826
|
+
break;
|
|
2565
2827
|
default: {
|
|
2566
|
-
const rc = vAdapters(this, ret);
|
|
2828
|
+
const rc = vAdapters(this.shapeHost, ret);
|
|
2567
2829
|
this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
|
|
2568
|
-
this.B.line(`call void @scr_promise_fulfill_ref(ptr ${pr}, ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, ret)})`);
|
|
2830
|
+
this.B.line(`call void @scr_promise_fulfill_ref(ptr ${pr}, ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this.shapeHost, ret)})`);
|
|
2569
2831
|
}
|
|
2570
2832
|
}
|
|
2571
2833
|
}
|
|
@@ -2576,9 +2838,10 @@ class LlEmitter {
|
|
|
2576
2838
|
B.debugLocation = this.debug?.location(fn.loc, this.debugScope) ?? null;
|
|
2577
2839
|
this.frames = [];
|
|
2578
2840
|
this.scopes = [];
|
|
2841
|
+
this.unwindCleanups.clear();
|
|
2579
2842
|
this.jumpTargets = [];
|
|
2580
2843
|
this.currentLocals = new Map(fn.locals.map((l) => [l.id, l]));
|
|
2581
|
-
this.captureIds = new Set((fn.captures ?? []).map((c) => c.localId));
|
|
2844
|
+
this.captureIds = new Set([...(fn.captures ?? []), ...(fn.classCaptures ?? [])].map((c) => c.localId));
|
|
2582
2845
|
this.integerLoopBindings.clear();
|
|
2583
2846
|
this.integerRanges = analyzeIntegerRanges(fn);
|
|
2584
2847
|
this.chainSlots.clear();
|
|
@@ -2595,7 +2858,7 @@ class LlEmitter {
|
|
|
2595
2858
|
this.declare(`declare token @llvm.coro.save(ptr)`);
|
|
2596
2859
|
this.declare(`declare i8 @llvm.coro.suspend(token, i1)`);
|
|
2597
2860
|
this.declare(`declare ptr @llvm.coro.free(token, ptr)`);
|
|
2598
|
-
this.declare(`declare
|
|
2861
|
+
this.declare(`declare void @llvm.coro.end(ptr, i1, token)`);
|
|
2599
2862
|
this.declare(`declare ptr @malloc(${this.sizeType})`);
|
|
2600
2863
|
this.declare(`declare void @free(ptr)`);
|
|
2601
2864
|
this.declare(`declare void @scr_wasi_coro_started(ptr)`);
|
|
@@ -2651,6 +2914,22 @@ class LlEmitter {
|
|
|
2651
2914
|
B.line(`${box} = load ptr, ptr ${p}`);
|
|
2652
2915
|
B.line(`store ptr ${box}, ptr %${mangleLocal(c.localId)} ; captured ${c.name}`);
|
|
2653
2916
|
});
|
|
2917
|
+
(fn.classCaptures ?? []).forEach((c) => {
|
|
2918
|
+
const self = fn.params[0];
|
|
2919
|
+
if (self.type.kind !== "object")
|
|
2920
|
+
throw new InternalCompilerError("class captures require an instance receiver");
|
|
2921
|
+
const classSlot = B.tmp();
|
|
2922
|
+
const classValue = B.tmp();
|
|
2923
|
+
const caps = B.tmp();
|
|
2924
|
+
const slot = B.tmp();
|
|
2925
|
+
const box = B.tmp();
|
|
2926
|
+
B.line(`${classSlot} = getelementptr inbounds %${mangleClassStruct(self.type.className)}, ptr %p_${mangleLocal(self.localId)}, i64 0, i32 ${classEnvironmentIndex(this.classMeta.get(self.type.className))}`);
|
|
2927
|
+
B.line(`${classValue} = load ptr, ptr ${classSlot}`);
|
|
2928
|
+
B.line(`${caps} = getelementptr inbounds %ScrClassObj, ptr ${classValue}, i64 1`);
|
|
2929
|
+
B.line(`${slot} = getelementptr inbounds ptr, ptr ${caps}, ${this.sizeType} ${c.slot}`);
|
|
2930
|
+
B.line(`${box} = load ptr, ptr ${slot}`);
|
|
2931
|
+
B.line(`store ptr ${box}, ptr %${mangleLocal(c.localId)} ; class capture ${c.name}`);
|
|
2932
|
+
});
|
|
2654
2933
|
// Params spill into their slots; the function scope owns refcounted
|
|
2655
2934
|
// params (callees own their params — callers passed +1). Boxed params
|
|
2656
2935
|
// allocate the shared binding and move the raw value in.
|
|
@@ -2660,7 +2939,7 @@ class LlEmitter {
|
|
|
2660
2939
|
const slot = `%${mangleLocal(p.localId)}`;
|
|
2661
2940
|
if (local.boxed) {
|
|
2662
2941
|
const box = B.tmp();
|
|
2663
|
-
B.line(`${box} = ${boxNewCall(this, p.type)} ; ${p.name} (boxed param)`);
|
|
2942
|
+
B.line(`${box} = ${boxNewCall(this.shapeHost, p.type)} ; ${p.name} (boxed param)`);
|
|
2664
2943
|
this.boxSet(box, p.type, `%p_${mangleLocal(p.localId)}`);
|
|
2665
2944
|
B.line(`store ptr ${box}, ptr ${slot}`);
|
|
2666
2945
|
fnScope.push({ slot, type: p.type, boxed: true });
|
|
@@ -2671,6 +2950,16 @@ class LlEmitter {
|
|
|
2671
2950
|
fnScope.push({ slot, type: p.type });
|
|
2672
2951
|
}
|
|
2673
2952
|
this.scopes.push(fnScope);
|
|
2953
|
+
// Stackful native fibers retain these frames while suspended. The
|
|
2954
|
+
// active exception context owns the chain, so concurrent fibers isolate it.
|
|
2955
|
+
if (this.stackTraces && !this.wasi && fn.sourceName !== undefined) {
|
|
2956
|
+
this.declare(`declare void @scr_stack_enter(ptr, ptr)`);
|
|
2957
|
+
this.declare(`declare void @scr_stack_leave(ptr)`);
|
|
2958
|
+
B.entryAllocas.push(`%source_frame = alloca { ptr, ptr }`);
|
|
2959
|
+
const frame = ` at ${fn.sourceName} (${fn.loc.file})`;
|
|
2960
|
+
B.line(`call void @scr_stack_enter(ptr %source_frame, ptr ${this.cstr(frame)})`);
|
|
2961
|
+
B.returnEpilogue = `call void @scr_stack_leave(ptr %source_frame)`;
|
|
2962
|
+
}
|
|
2674
2963
|
this.emitStmts(fn.body);
|
|
2675
2964
|
// Implicit exit of a void function: release the function scope unless
|
|
2676
2965
|
// the body already terminated its final block (return, or a throw
|
|
@@ -2710,8 +2999,7 @@ class LlEmitter {
|
|
|
2710
2999
|
B.line(`call void @free(ptr ${frame})`);
|
|
2711
3000
|
B.br(coro.suspendLabel);
|
|
2712
3001
|
B.startBlock(coro.suspendLabel);
|
|
2713
|
-
|
|
2714
|
-
B.line(`${ended} = call i1 @llvm.coro.end(ptr ${coro.handle}, i1 false, token none)`);
|
|
3002
|
+
B.line(`call void @llvm.coro.end(ptr ${coro.handle}, i1 false, token none)`);
|
|
2715
3003
|
const ret = this.llType(fn.returnType);
|
|
2716
3004
|
if (ret === "void")
|
|
2717
3005
|
B.terminate(`ret void`);
|
|
@@ -2722,6 +3010,14 @@ class LlEmitter {
|
|
|
2722
3010
|
else
|
|
2723
3011
|
B.terminate(`ret ptr null`);
|
|
2724
3012
|
}
|
|
3013
|
+
// Shared blocks have multiple source locations. Keep the location on
|
|
3014
|
+
// each incoming exception check instead of assigning one to the cleanup.
|
|
3015
|
+
B.debugLocation = null;
|
|
3016
|
+
for (const cleanup of this.unwindCleanups.values()) {
|
|
3017
|
+
B.startBlock(cleanup.label);
|
|
3018
|
+
this.releaseScope(cleanup.entries);
|
|
3019
|
+
B.terminate(cleanup.terminator);
|
|
3020
|
+
}
|
|
2725
3021
|
if (this.logArgSlots > 0) {
|
|
2726
3022
|
B.entryAllocas.push(`%logargs = alloca [${this.logArgSlots} x %ScrLogArg]`);
|
|
2727
3023
|
}
|
|
@@ -2738,15 +3034,15 @@ class LlEmitter {
|
|
|
2738
3034
|
emitStmts(stmts) {
|
|
2739
3035
|
for (const s of stmts) {
|
|
2740
3036
|
// Statements after a terminator are unreachable (dead code after
|
|
2741
|
-
// return/break/continue)
|
|
2742
|
-
//
|
|
3037
|
+
// return/break/continue). Skip them so no dropped SSA definition
|
|
3038
|
+
// can leak forward.
|
|
2743
3039
|
if (this.B.isTerminated())
|
|
2744
3040
|
return;
|
|
2745
3041
|
this.emitStmt(s);
|
|
2746
3042
|
}
|
|
2747
3043
|
}
|
|
2748
3044
|
/** Emits a block in its own lexical scope (refcounted locals released at
|
|
2749
|
-
* end)
|
|
3045
|
+
* end). `setup` runs after the
|
|
2750
3046
|
* scope opens, before the statements — the catch-binding hook: it may
|
|
2751
3047
|
* emit prelude lines and register entries the scope owns (released on
|
|
2752
3048
|
* every exit, jumps and unwinds included). */
|
|
@@ -2785,7 +3081,7 @@ class LlEmitter {
|
|
|
2785
3081
|
// bit pattern to spend on it (stmts.ts's varDecl).
|
|
2786
3082
|
const boxNew = b.local.tdz === true && boxAccess(b.type) !== "ref"
|
|
2787
3083
|
? (this.declare(`declare ptr @scr_box_new(i32)`), `call ptr @scr_box_new(i32 3)`)
|
|
2788
|
-
: boxNewCall(this, b.type);
|
|
3084
|
+
: boxNewCall(this.shapeHost, b.type);
|
|
2789
3085
|
const box = B.tmp();
|
|
2790
3086
|
B.line(`${box} = ${boxNew} ; let ${b.local.name} (boxed)`);
|
|
2791
3087
|
B.line(`store ptr ${box}, ptr ${b.slot}`);
|
|
@@ -2830,17 +3126,13 @@ class LlEmitter {
|
|
|
2830
3126
|
}
|
|
2831
3127
|
const b = this.binding(s.localId);
|
|
2832
3128
|
const v = this.emitExpr(s.value);
|
|
3129
|
+
if (b.kind === "global" && !s.initializes)
|
|
3130
|
+
this.checkGlobalTdz(s.localId);
|
|
2833
3131
|
if (b.kind === "boxed") {
|
|
3132
|
+
this.writeBindingBox(this.loadBox(b.slot), b.local, v.name, s.initializes);
|
|
3133
|
+
// The RHS remains frame-owned until a possible TDZ throw passes.
|
|
2834
3134
|
if (isRefCounted(v.type))
|
|
2835
|
-
this.moveTemp(v);
|
|
2836
|
-
// A scalar TDZ box (forward-captured const): the initializing
|
|
2837
|
-
// write mints the one-element array cell — set_ref moves it in
|
|
2838
|
-
// (and the empty-slot sentinel ends here).
|
|
2839
|
-
if (b.local.tdz === true && boxAccess(b.type) !== "ref") {
|
|
2840
|
-
this.tdzScalarInit(this.loadBox(b.slot), b.type, v.name);
|
|
2841
|
-
break;
|
|
2842
|
-
}
|
|
2843
|
-
this.boxSet(this.loadBox(b.slot), b.type, v.name);
|
|
3135
|
+
this.moveTemp(v);
|
|
2844
3136
|
break;
|
|
2845
3137
|
}
|
|
2846
3138
|
this.moveTemp(v);
|
|
@@ -2899,8 +3191,8 @@ class LlEmitter {
|
|
|
2899
3191
|
case "bytesSet": {
|
|
2900
3192
|
// Typed-array element write: same evaluation order as arraySet;
|
|
2901
3193
|
// the value is a scalar (the kind-specific inline path coerces
|
|
2902
|
-
// JS-exactly), so no ownership moves.
|
|
2903
|
-
//
|
|
3194
|
+
// JS-exactly), so no ownership moves. Invalid writes are ignored.
|
|
3195
|
+
// IrBytesElem is static, so never rediscover it through the
|
|
2904
3196
|
// generic runtime switch in a hot loop.
|
|
2905
3197
|
const arr = this.emitStableReceiver(s.arr, [s.index, s.value]);
|
|
2906
3198
|
const integerIndex = this.emitIntegerLoopIndex(s.index);
|
|
@@ -2933,6 +3225,17 @@ class LlEmitter {
|
|
|
2933
3225
|
else {
|
|
2934
3226
|
this.storeField(ptr, type, v.name);
|
|
2935
3227
|
}
|
|
3228
|
+
if (s.kind === "fieldSet" && s.field === "name" && this.classMeta.get(s.className)?.root.def.name === "%Error") {
|
|
3229
|
+
const present = this.classFieldPtr(obj.name, s.className, "%namePresent").ptr;
|
|
3230
|
+
const enumerable = this.classFieldPtr(obj.name, s.className, "%nameEnumerable").ptr;
|
|
3231
|
+
const wasPresent = B.tmp(), wasEnumerable = B.tmp(), isPresent = B.tmp(), nextEnumerable = B.tmp();
|
|
3232
|
+
B.line(`${wasPresent} = load i8, ptr ${present}`);
|
|
3233
|
+
B.line(`${wasEnumerable} = load i8, ptr ${enumerable}`);
|
|
3234
|
+
B.line(`${isPresent} = icmp ne i8 ${wasPresent}, 0`);
|
|
3235
|
+
B.line(`${nextEnumerable} = select i1 ${isPresent}, i8 ${wasEnumerable}, i8 1`);
|
|
3236
|
+
B.line(`store i8 1, ptr ${present}`);
|
|
3237
|
+
B.line(`store i8 ${nextEnumerable}, ptr ${enumerable}`);
|
|
3238
|
+
}
|
|
2936
3239
|
break;
|
|
2937
3240
|
}
|
|
2938
3241
|
case "recordKeyDelete": {
|
|
@@ -3130,7 +3433,7 @@ class LlEmitter {
|
|
|
3130
3433
|
kind: "loop",
|
|
3131
3434
|
brkLabel: le,
|
|
3132
3435
|
contLabel: lc,
|
|
3133
|
-
|
|
3436
|
+
labels: s.labels,
|
|
3134
3437
|
frameDepth: this.frames.length,
|
|
3135
3438
|
scopeDepth: this.scopes.length,
|
|
3136
3439
|
finallyDepth: this.finallyStack.length,
|
|
@@ -3152,7 +3455,7 @@ class LlEmitter {
|
|
|
3152
3455
|
kind: "loop",
|
|
3153
3456
|
brkLabel: le,
|
|
3154
3457
|
contLabel: lc,
|
|
3155
|
-
|
|
3458
|
+
labels: s.labels,
|
|
3156
3459
|
frameDepth: this.frames.length,
|
|
3157
3460
|
scopeDepth: this.scopes.length,
|
|
3158
3461
|
finallyDepth: this.finallyStack.length,
|
|
@@ -3178,7 +3481,12 @@ class LlEmitter {
|
|
|
3178
3481
|
this.integerLoopBindings.set(integerLoop.localId, integerSlot);
|
|
3179
3482
|
}
|
|
3180
3483
|
else if (s.init) {
|
|
3181
|
-
|
|
3484
|
+
// A multi-declarator head shares the loop's scope. Emitting its
|
|
3485
|
+
// IR block as an ordinary block would release captured/ref locals
|
|
3486
|
+
// before the first condition.
|
|
3487
|
+
const initializers = s.init.kind === "block" ? s.init.body : [s.init];
|
|
3488
|
+
for (const initializer of initializers)
|
|
3489
|
+
this.emitStmt(initializer);
|
|
3182
3490
|
}
|
|
3183
3491
|
const lc = B.newLabel("loop.c");
|
|
3184
3492
|
const lb = B.newLabel("loop.b");
|
|
@@ -3186,11 +3494,29 @@ class LlEmitter {
|
|
|
3186
3494
|
// JS `for (let i ...)`: each iteration gets a FRESH binding holding
|
|
3187
3495
|
// a copy of the previous one (closures made in iteration k keep
|
|
3188
3496
|
// seeing iteration k's value) — only observable, and only emitted,
|
|
3189
|
-
// when
|
|
3190
|
-
//
|
|
3191
|
-
const
|
|
3192
|
-
const
|
|
3193
|
-
|
|
3497
|
+
// when a let variable is captured (boxed). Freshen before the first
|
|
3498
|
+
// condition and again in the continue-target block before updating.
|
|
3499
|
+
const initializers = s.init?.kind === "block" ? s.init.body : s.init ? [s.init] : [];
|
|
3500
|
+
const capturedLets = initializers.flatMap((init) => {
|
|
3501
|
+
const local = init.kind === "varDecl" ? this.currentLocals.get(init.localId) : undefined;
|
|
3502
|
+
return local?.boxed && local.mutable ? [local] : [];
|
|
3503
|
+
});
|
|
3504
|
+
const freshenBindings = () => {
|
|
3505
|
+
for (const local of capturedLets) {
|
|
3506
|
+
const slot = `%${mangleLocal(local.id)}`;
|
|
3507
|
+
const fresh = B.tmp();
|
|
3508
|
+
const old = B.tmp();
|
|
3509
|
+
B.line(`${fresh} = ${boxNewCall(this.shapeHost, local.type)} ; per-iteration ${local.name}`);
|
|
3510
|
+
B.line(`${old} = load ptr, ptr ${slot}`);
|
|
3511
|
+
const val = this.boxGet(old, local.type);
|
|
3512
|
+
this.boxSet(fresh, local.type, val);
|
|
3513
|
+
this.declare(`declare void @scr_box_release(ptr)`);
|
|
3514
|
+
B.line(`call void @scr_box_release(ptr ${old})`);
|
|
3515
|
+
B.line(`store ptr ${fresh}, ptr ${slot}`);
|
|
3516
|
+
}
|
|
3517
|
+
};
|
|
3518
|
+
const lu = s.update || capturedLets.length > 0 ? B.newLabel("loop.u") : lc;
|
|
3519
|
+
freshenBindings();
|
|
3194
3520
|
B.br(lc);
|
|
3195
3521
|
B.startBlock(lc);
|
|
3196
3522
|
if (integerLoop && integerSlot) {
|
|
@@ -3214,7 +3540,7 @@ class LlEmitter {
|
|
|
3214
3540
|
kind: "loop",
|
|
3215
3541
|
brkLabel: le,
|
|
3216
3542
|
contLabel: lu,
|
|
3217
|
-
|
|
3543
|
+
labels: s.labels,
|
|
3218
3544
|
frameDepth: this.frames.length,
|
|
3219
3545
|
scopeDepth: this.scopes.length,
|
|
3220
3546
|
finallyDepth: this.finallyStack.length,
|
|
@@ -3224,20 +3550,7 @@ class LlEmitter {
|
|
|
3224
3550
|
B.br(lu);
|
|
3225
3551
|
if (lu !== lc) {
|
|
3226
3552
|
B.startBlock(lu);
|
|
3227
|
-
|
|
3228
|
-
const slot = `%${mangleLocal(initLocal.id)}`;
|
|
3229
|
-
const fresh = B.tmp();
|
|
3230
|
-
const old = B.tmp();
|
|
3231
|
-
B.line(`${fresh} = ${boxNewCall(this, initLocal.type)} ; per-iteration ${initLocal.name}`);
|
|
3232
|
-
B.line(`${old} = load ptr, ptr ${slot}`);
|
|
3233
|
-
const val = this.boxGet(old, initLocal.type); // ref: +1 out
|
|
3234
|
-
this.boxSet(fresh, initLocal.type, val); // takes ownership
|
|
3235
|
-
this.declare(`declare void @scr_box_release(ptr)`);
|
|
3236
|
-
B.line(`call void @scr_box_release(ptr ${old})`);
|
|
3237
|
-
B.line(`store ptr ${fresh}, ptr ${slot}`);
|
|
3238
|
-
// The wrapper scope's entry releases whatever the slot points
|
|
3239
|
-
// to at loop exit — now the freshest binding. Nothing to fix.
|
|
3240
|
-
}
|
|
3553
|
+
freshenBindings();
|
|
3241
3554
|
if (integerLoop && integerSlot) {
|
|
3242
3555
|
const old = B.tmp();
|
|
3243
3556
|
const next = B.tmp();
|
|
@@ -3286,7 +3599,7 @@ class LlEmitter {
|
|
|
3286
3599
|
kind: "loop",
|
|
3287
3600
|
brkLabel: le,
|
|
3288
3601
|
contLabel: lu,
|
|
3289
|
-
|
|
3602
|
+
labels: s.labels,
|
|
3290
3603
|
frameDepth: this.frames.length,
|
|
3291
3604
|
scopeDepth: this.scopes.length,
|
|
3292
3605
|
finallyDepth: this.finallyStack.length,
|
|
@@ -3307,7 +3620,7 @@ class LlEmitter {
|
|
|
3307
3620
|
// fresh const binding. The box takes ownership of a ref element's
|
|
3308
3621
|
// +1 and is released with the iteration's scope.
|
|
3309
3622
|
const box = B.tmp();
|
|
3310
|
-
B.line(`${box} = ${boxNewCall(this, elem)} ; per-iteration ${localInfo.name}`);
|
|
3623
|
+
B.line(`${box} = ${boxNewCall(this.shapeHost, elem)} ; per-iteration ${localInfo.name}`);
|
|
3311
3624
|
this.boxSet(box, elem, cur);
|
|
3312
3625
|
B.line(`store ptr ${box}, ptr ${slot}`);
|
|
3313
3626
|
this.scopes[this.scopes.length - 1].push({ slot, type: elem, boxed: true });
|
|
@@ -3380,10 +3693,7 @@ class LlEmitter {
|
|
|
3380
3693
|
// tryStack it sees truncated to its region (its releases already
|
|
3381
3694
|
// ran; a throw inside a copy propagates OUT of the completing
|
|
3382
3695
|
// try, past its own catch), then the function-level releases and
|
|
3383
|
-
// the actual ret. The
|
|
3384
|
-
// finally copies behind gotos with the value parked in sc_pret;
|
|
3385
|
-
// the inline copies here are the same code at the same depths,
|
|
3386
|
-
// with the parked value's ownership riding a synthetic slot-based
|
|
3696
|
+
// the actual ret. The parked value owns a synthetic slot-backed
|
|
3387
3697
|
// scope entry during each copy so a throwing finally releases it.
|
|
3388
3698
|
let v = null;
|
|
3389
3699
|
if (s.value !== null) {
|
|
@@ -3450,10 +3760,9 @@ class LlEmitter {
|
|
|
3450
3760
|
case "rethrow": {
|
|
3451
3761
|
// Re-raise the saved snapshot (payload retained — the binding
|
|
3452
3762
|
// local releases with its scope) and unwind like `throw`.
|
|
3453
|
-
const c =
|
|
3454
|
-
B.line(`${c} = load ptr, ptr %${mangleLocal(s.localId)}`);
|
|
3763
|
+
const c = this.emitExpr({ kind: "varRef", localId: s.localId, type: CAUGHT, loc: s.loc });
|
|
3455
3764
|
this.declare(`declare void @scr_rethrow(ptr)`);
|
|
3456
|
-
B.line(`call void @scr_rethrow(ptr ${c})`);
|
|
3765
|
+
B.line(`call void @scr_rethrow(ptr ${c.name})`);
|
|
3457
3766
|
this.emitUnwind();
|
|
3458
3767
|
break;
|
|
3459
3768
|
}
|
|
@@ -3571,8 +3880,17 @@ class LlEmitter {
|
|
|
3571
3880
|
this.emitBlock(s.catchBody, (scope) => {
|
|
3572
3881
|
const c = B.tmp();
|
|
3573
3882
|
B.line(`${c} = call ptr @scr_exc_take() ; catch binding`);
|
|
3574
|
-
|
|
3575
|
-
|
|
3883
|
+
if (this.currentLocals.get(s.catchLocalId)?.boxed) {
|
|
3884
|
+
const box = B.tmp();
|
|
3885
|
+
B.line(`${box} = ${boxNewCall(this.shapeHost, CAUGHT)} ; captured exception`);
|
|
3886
|
+
this.boxSet(box, CAUGHT, c);
|
|
3887
|
+
B.line(`store ptr ${box}, ptr ${slot}`);
|
|
3888
|
+
scope.push({ slot, type: CAUGHT, boxed: true });
|
|
3889
|
+
}
|
|
3890
|
+
else {
|
|
3891
|
+
B.line(`store ptr ${c}, ptr ${slot}`);
|
|
3892
|
+
scope.push({ slot, type: CAUGHT });
|
|
3893
|
+
}
|
|
3576
3894
|
});
|
|
3577
3895
|
}
|
|
3578
3896
|
else {
|
|
@@ -3638,7 +3956,7 @@ class LlEmitter {
|
|
|
3638
3956
|
}
|
|
3639
3957
|
/** JS-exact switch: lazily evaluated, arbitrary-expression case tests in
|
|
3640
3958
|
* source order, bodies falling through in source order until a break —
|
|
3641
|
-
*
|
|
3959
|
+
* A chain of conditional branches. All case bodies
|
|
3642
3960
|
* share ONE scope; because dispatch can jump PAST a varDecl into a later
|
|
3643
3961
|
* case, refcounted/boxed case-body locals are NULL-reset up front and
|
|
3644
3962
|
* the scope-exit releases rely on NULL tolerance. */
|
|
@@ -3696,7 +4014,7 @@ class LlEmitter {
|
|
|
3696
4014
|
kind: "switch",
|
|
3697
4015
|
brkLabel: end,
|
|
3698
4016
|
contLabel: null,
|
|
3699
|
-
|
|
4017
|
+
labels: s.labels,
|
|
3700
4018
|
frameDepth: this.frames.length,
|
|
3701
4019
|
scopeDepth: this.scopes.length,
|
|
3702
4020
|
finallyDepth: this.finallyStack.length,
|
|
@@ -3721,7 +4039,7 @@ class LlEmitter {
|
|
|
3721
4039
|
/** Evaluates a condition (IR conds are bool-typed) and releases its
|
|
3722
4040
|
* temps BEFORE the branch — safe because the result is a scalar i1, and
|
|
3723
4041
|
* required in loop-condition blocks (their temps must not survive into
|
|
3724
|
-
* later blocks across the back edge).
|
|
4042
|
+
* later blocks across the back edge). */
|
|
3725
4043
|
emitCondition(cond) {
|
|
3726
4044
|
const v = this.emitExpr(cond);
|
|
3727
4045
|
const frame = this.currentFrame();
|
|
@@ -3732,7 +4050,7 @@ class LlEmitter {
|
|
|
3732
4050
|
/** Evaluates `expr` in its own statement frame inside an already-open
|
|
3733
4051
|
* branch and moves the result into `slot`: the chosen value's ownership
|
|
3734
4052
|
* transfers, every other temp the arm allocated releases inside the
|
|
3735
|
-
* branch. The shared core of ternary/logical.
|
|
4053
|
+
* branch. The shared core of ternary/logical. */
|
|
3736
4054
|
emitBranchInto(slot, expr) {
|
|
3737
4055
|
this.frames.push([]);
|
|
3738
4056
|
const v = this.emitExpr(expr);
|
|
@@ -3741,24 +4059,28 @@ class LlEmitter {
|
|
|
3741
4059
|
this.releaseFrame(this.frames.pop());
|
|
3742
4060
|
}
|
|
3743
4061
|
// ── expressions ─────────────────────────────────────────────────────────
|
|
3744
|
-
/** One audited escape hatch for the type-only boundary used by the
|
|
3745
|
-
* extracted expression modules. LlEmitter remains the sole owner of the
|
|
3746
|
-
* mutable emission state; the context exposes only the operations those
|
|
3747
|
-
* modules require. */
|
|
3748
|
-
expressionContext() {
|
|
3749
|
-
return this;
|
|
3750
|
-
}
|
|
3751
4062
|
emitLiteralExpr(e) {
|
|
3752
|
-
return emitLiteralExpr(this
|
|
4063
|
+
return emitLiteralExpr(this, e);
|
|
3753
4064
|
}
|
|
3754
4065
|
emitOperatorExpr(e) {
|
|
3755
|
-
|
|
4066
|
+
if (e.kind === "seqExpr") {
|
|
4067
|
+
// Saved operands can feed later call arguments. Transfer ownership
|
|
4068
|
+
// to this expression's frame so they survive those reads and still
|
|
4069
|
+
// die on the path that created them, including inside lazy branches.
|
|
4070
|
+
this.scopes.push([]);
|
|
4071
|
+
const result = emitOperatorExpr(this, e);
|
|
4072
|
+
for (const local of this.scopes.pop()) {
|
|
4073
|
+
this.currentFrame().push({ name: local.slot, type: local.type, slot: true, ...(local.boxed ? { boxed: true } : {}) });
|
|
4074
|
+
}
|
|
4075
|
+
return result;
|
|
4076
|
+
}
|
|
4077
|
+
return emitOperatorExpr(this, e);
|
|
3756
4078
|
}
|
|
3757
4079
|
emitControlExpr(e) {
|
|
3758
|
-
return emitControlExpr(this
|
|
4080
|
+
return emitControlExpr(this, e);
|
|
3759
4081
|
}
|
|
3760
4082
|
emitStringExpr(e) {
|
|
3761
|
-
return emitStringExpr(this
|
|
4083
|
+
return emitStringExpr(this, e);
|
|
3762
4084
|
}
|
|
3763
4085
|
/**
|
|
3764
4086
|
* Lower canonical `target = target + suffix` after evaluating the old
|
|
@@ -3802,251 +4124,273 @@ class LlEmitter {
|
|
|
3802
4124
|
return result;
|
|
3803
4125
|
}
|
|
3804
4126
|
emitContainerExpr(e) {
|
|
3805
|
-
return emitContainerExpr(this
|
|
4127
|
+
return emitContainerExpr(this, e);
|
|
3806
4128
|
}
|
|
3807
4129
|
emitCallExpr(e) {
|
|
3808
|
-
return emitCallExpr(this
|
|
4130
|
+
return emitCallExpr(this, e);
|
|
3809
4131
|
}
|
|
3810
4132
|
emitRecordExpr(e) {
|
|
3811
|
-
return emitRecordExpr(this
|
|
4133
|
+
return emitRecordExpr(this, e);
|
|
3812
4134
|
}
|
|
3813
4135
|
emitDynamicExpr(e) {
|
|
3814
|
-
return emitDynamicExpr(this
|
|
4136
|
+
return emitDynamicExpr(this, e);
|
|
3815
4137
|
}
|
|
3816
4138
|
emitIntrinsicExpr(e) {
|
|
3817
|
-
return emitIntrinsicExpr(this
|
|
4139
|
+
return emitIntrinsicExpr(this, e);
|
|
3818
4140
|
}
|
|
3819
4141
|
emitSerializationExpr(e) {
|
|
3820
|
-
return emitSerializationExpr(this
|
|
4142
|
+
return emitSerializationExpr(this, e);
|
|
3821
4143
|
}
|
|
3822
4144
|
emitAsyncExpr(e) {
|
|
3823
|
-
return emitAsyncExpr(this
|
|
4145
|
+
return emitAsyncExpr(this, e);
|
|
3824
4146
|
}
|
|
3825
4147
|
emitJsInteropExpr(e) {
|
|
3826
|
-
return emitJsInteropExpr(this
|
|
4148
|
+
return emitJsInteropExpr(this, e);
|
|
4149
|
+
}
|
|
4150
|
+
/** Read a receiver whose value is consumed immediately by a field or tag
|
|
4151
|
+
* load. No user code may run between this read and its consumer. Locals
|
|
4152
|
+
* and their projections already have an owner; other expressions keep
|
|
4153
|
+
* their ordinary statement-frame ownership. The caller must retain any
|
|
4154
|
+
* reference result before evaluating another expression. */
|
|
4155
|
+
emitReadReceiver(e) {
|
|
4156
|
+
if (!isRefCounted(e.type))
|
|
4157
|
+
return this.emitExpr(e);
|
|
4158
|
+
if (e.kind === "varRef") {
|
|
4159
|
+
const binding = this.binding(e.localId);
|
|
4160
|
+
// Capture boxes can carry TDZ and caught-value conversion semantics.
|
|
4161
|
+
if (binding.kind === "boxed")
|
|
4162
|
+
return this.emitExpr(e);
|
|
4163
|
+
if (binding.kind === "global")
|
|
4164
|
+
this.checkGlobalTdz(e.localId);
|
|
4165
|
+
const value = this.B.tmp();
|
|
4166
|
+
this.B.line(`${value} = load ptr, ptr ${binding.slot}`);
|
|
4167
|
+
return { name: value, type: e.type };
|
|
4168
|
+
}
|
|
4169
|
+
if (e.kind === "unionNarrow") {
|
|
4170
|
+
const union = this.emitReadReceiver(e.value);
|
|
4171
|
+
return { name: this.unionPeek(union.name), type: e.type };
|
|
4172
|
+
}
|
|
4173
|
+
if (e.kind === "recordGet" || e.kind === "fieldGet") {
|
|
4174
|
+
const receiver = this.emitReadReceiver(e.obj);
|
|
4175
|
+
const { ptr, type } = e.kind === "recordGet"
|
|
4176
|
+
? this.recordFieldPtr(receiver.name, e.shapeId, e.field)
|
|
4177
|
+
: this.classFieldPtr(receiver.name, e.className, e.field);
|
|
4178
|
+
return { name: this.loadField(ptr, type), type: e.type };
|
|
4179
|
+
}
|
|
4180
|
+
return this.emitExpr(e);
|
|
3827
4181
|
}
|
|
3828
4182
|
emitExpr(e) {
|
|
3829
|
-
return emitExpr(this
|
|
4183
|
+
return emitExpr(this, e);
|
|
3830
4184
|
}
|
|
3831
4185
|
emitJsMarshal(e) {
|
|
3832
|
-
return emitJsMarshal(this
|
|
4186
|
+
return emitJsMarshal(this, e);
|
|
3833
4187
|
}
|
|
3834
4188
|
emitJsOp(e) {
|
|
3835
|
-
return emitJsOp(this
|
|
4189
|
+
return emitJsOp(this, e);
|
|
3836
4190
|
}
|
|
3837
4191
|
emitJsExit(e) {
|
|
3838
|
-
return emitJsExit(this
|
|
4192
|
+
return emitJsExit(this, e);
|
|
3839
4193
|
}
|
|
3840
4194
|
islandAdapter(arity, retKind) {
|
|
3841
|
-
return islandAdapter(this
|
|
4195
|
+
return islandAdapter(this, arity, retKind);
|
|
3842
4196
|
}
|
|
3843
4197
|
islandTypedAdapter(fn) {
|
|
3844
|
-
return islandTypedAdapter(this
|
|
4198
|
+
return islandTypedAdapter(this, fn);
|
|
3845
4199
|
}
|
|
3846
4200
|
dynKind(d) {
|
|
3847
|
-
return dynKind(this
|
|
4201
|
+
return dynKind(this, d);
|
|
3848
4202
|
}
|
|
3849
4203
|
raceAdapterFor(from, to) {
|
|
3850
|
-
return raceAdapterFor(this
|
|
4204
|
+
return raceAdapterFor(this, from, to);
|
|
3851
4205
|
}
|
|
3852
4206
|
genResultThunkFor(genT, recT) {
|
|
3853
|
-
return genResultThunkFor(this
|
|
4207
|
+
return genResultThunkFor(this, genT, recT);
|
|
3854
4208
|
}
|
|
3855
4209
|
childExitThunkFor(param) {
|
|
3856
|
-
return childExitThunkFor(this
|
|
4210
|
+
return childExitThunkFor(this, param);
|
|
3857
4211
|
}
|
|
3858
4212
|
execFileThunkFor(cbT) {
|
|
3859
|
-
return execFileThunkFor(this
|
|
4213
|
+
return execFileThunkFor(this, cbT);
|
|
3860
4214
|
}
|
|
3861
4215
|
ipcMessageThunkFor(cbT) {
|
|
3862
|
-
return ipcMessageThunkFor(this
|
|
4216
|
+
return ipcMessageThunkFor(this, cbT);
|
|
3863
4217
|
}
|
|
3864
4218
|
ipcSendThunkFor(cbT) {
|
|
3865
|
-
return ipcSendThunkFor(this
|
|
4219
|
+
return ipcSendThunkFor(this, cbT);
|
|
3866
4220
|
}
|
|
3867
4221
|
childExitSignalThunkFor(codeParam, sigParam) {
|
|
3868
|
-
return childExitSignalThunkFor(this
|
|
4222
|
+
return childExitSignalThunkFor(this, codeParam, sigParam);
|
|
3869
4223
|
}
|
|
3870
4224
|
childDataThunkFor(param) {
|
|
3871
|
-
return childDataThunkFor(this
|
|
4225
|
+
return childDataThunkFor(this, param);
|
|
3872
4226
|
}
|
|
3873
4227
|
emitterFixedAdapter(cbT) {
|
|
3874
|
-
return emitterFixedAdapter(this
|
|
4228
|
+
return emitterFixedAdapter(this, cbT);
|
|
3875
4229
|
}
|
|
3876
4230
|
wrapEmitterListener(target, adapterFn) {
|
|
3877
|
-
return wrapEmitterListener(this
|
|
4231
|
+
return wrapEmitterListener(this, target, adapterFn);
|
|
3878
4232
|
}
|
|
3879
4233
|
unwrapNullableClosure(u, funcTag) {
|
|
3880
|
-
return unwrapNullableClosure(this
|
|
4234
|
+
return unwrapNullableClosure(this, u, funcTag);
|
|
3881
4235
|
}
|
|
3882
4236
|
closeBindThunkFor(cbUnion, retServer) {
|
|
3883
|
-
return closeBindThunkFor(this
|
|
4237
|
+
return closeBindThunkFor(this, cbUnion, retServer);
|
|
3884
4238
|
}
|
|
3885
4239
|
closeOverrideWrapFor(cbUnion, retServer) {
|
|
3886
|
-
return closeOverrideWrapFor(this
|
|
4240
|
+
return closeOverrideWrapFor(this, cbUnion, retServer);
|
|
3887
4241
|
}
|
|
3888
4242
|
streamDataAdapter(cbT) {
|
|
3889
|
-
return streamDataAdapter(this
|
|
4243
|
+
return streamDataAdapter(this, cbT);
|
|
3890
4244
|
}
|
|
3891
4245
|
streamDoneFnFor(kind, doneT) {
|
|
3892
|
-
return streamDoneFnFor(this
|
|
4246
|
+
return streamDoneFnFor(this, kind, doneT);
|
|
3893
4247
|
}
|
|
3894
4248
|
fsRenameThunkFor(cbT) {
|
|
3895
|
-
return fsRenameThunkFor(this
|
|
4249
|
+
return fsRenameThunkFor(this, cbT);
|
|
3896
4250
|
}
|
|
3897
4251
|
cryptoBytesThunkFor(cbT) {
|
|
3898
|
-
return cryptoBytesThunkFor(this
|
|
4252
|
+
return cryptoBytesThunkFor(this, cbT);
|
|
3899
4253
|
}
|
|
3900
4254
|
zlibBytesThunkFor(cbT) {
|
|
3901
|
-
return zlibBytesThunkFor(this
|
|
4255
|
+
return zlibBytesThunkFor(this, cbT);
|
|
3902
4256
|
}
|
|
3903
4257
|
streamCbThunkFor(kind, cbT) {
|
|
3904
|
-
return streamCbThunkFor(this
|
|
4258
|
+
return streamCbThunkFor(this, kind, cbT);
|
|
3905
4259
|
}
|
|
3906
4260
|
resolveThunkFor(inner) {
|
|
3907
|
-
return resolveThunkFor(this
|
|
4261
|
+
return resolveThunkFor(this, inner);
|
|
3908
4262
|
}
|
|
3909
4263
|
tagInSet(uName, tags) {
|
|
3910
|
-
return tagInSet(this
|
|
4264
|
+
return tagInSet(this, uName, tags);
|
|
3911
4265
|
}
|
|
3912
4266
|
arrPush(arr, acc, value) {
|
|
3913
|
-
return arrPush(this
|
|
4267
|
+
return arrPush(this, arr, acc, value);
|
|
3914
4268
|
}
|
|
3915
4269
|
emitArrayCopyLoop(dst, src, acc) {
|
|
3916
|
-
return emitArrayCopyLoop(this
|
|
4270
|
+
return emitArrayCopyLoop(this, dst, src, acc);
|
|
3917
4271
|
}
|
|
3918
4272
|
emitStrIntrinsic(e) {
|
|
3919
|
-
return emitStrIntrinsic(this
|
|
4273
|
+
return emitStrIntrinsic(this, e);
|
|
3920
4274
|
}
|
|
3921
4275
|
emitArrIntrinsic(e) {
|
|
3922
|
-
return emitArrIntrinsic(this
|
|
4276
|
+
return emitArrIntrinsic(this, e);
|
|
3923
4277
|
}
|
|
3924
4278
|
wrapNullable(raw, present, valueType, valueTag, resultType, absentTag) {
|
|
3925
|
-
return wrapNullable(this
|
|
4279
|
+
return wrapNullable(this, raw, present, valueType, valueTag, resultType, absentTag);
|
|
3926
4280
|
}
|
|
3927
4281
|
emitMapNew(e) {
|
|
3928
|
-
return emitMapNew(this
|
|
4282
|
+
return emitMapNew(this, e);
|
|
3929
4283
|
}
|
|
3930
4284
|
mapSet(m, kAcc, vAcc, key, value) {
|
|
3931
|
-
return mapSet(this
|
|
4285
|
+
return mapSet(this, m, kAcc, vAcc, key, value);
|
|
3932
4286
|
}
|
|
3933
4287
|
emitMapLikeIntrinsic(e) {
|
|
3934
|
-
return emitMapLikeIntrinsic(this
|
|
4288
|
+
return emitMapLikeIntrinsic(this, e);
|
|
3935
4289
|
}
|
|
3936
4290
|
emitSetNew(e) {
|
|
3937
|
-
return emitSetNew(this
|
|
4291
|
+
return emitSetNew(this, e);
|
|
3938
4292
|
}
|
|
3939
4293
|
emitStableReceiver(receiver, following) {
|
|
3940
|
-
return emitStableReceiver(this
|
|
4294
|
+
return emitStableReceiver(this, receiver, following);
|
|
3941
4295
|
}
|
|
3942
4296
|
emitIntegerLoopIndex(expr) {
|
|
3943
|
-
return emitIntegerLoopIndex(this
|
|
4297
|
+
return emitIntegerLoopIndex(this, expr);
|
|
3944
4298
|
}
|
|
3945
4299
|
emitBytesIndex(receiver, index, integerIndex = false) {
|
|
3946
|
-
return emitBytesIndex(this
|
|
4300
|
+
return emitBytesIndex(this, receiver, index, integerIndex);
|
|
3947
4301
|
}
|
|
3948
4302
|
emitBytesData(receiver) {
|
|
3949
|
-
return emitBytesData(this
|
|
4303
|
+
return emitBytesData(this, receiver);
|
|
3950
4304
|
}
|
|
3951
4305
|
emitBytesLength(elem, receiver, bytes) {
|
|
3952
|
-
return emitBytesLength(this
|
|
4306
|
+
return emitBytesLength(this, elem, receiver, bytes);
|
|
3953
4307
|
}
|
|
3954
4308
|
emitBytesGet(elem, receiver, index, integerIndex = false) {
|
|
3955
|
-
return emitBytesGet(this
|
|
4309
|
+
return emitBytesGet(this, elem, receiver, index, integerIndex);
|
|
3956
4310
|
}
|
|
3957
4311
|
emitToUint32(value, expr) {
|
|
3958
|
-
return emitToUint32(this
|
|
4312
|
+
return emitToUint32(this, value, expr);
|
|
3959
4313
|
}
|
|
3960
4314
|
emitBytesSet(elem, receiver, index, value, integerIndex = false) {
|
|
3961
|
-
return emitBytesSet(this
|
|
4315
|
+
return emitBytesSet(this, elem, receiver, index, value, integerIndex);
|
|
3962
4316
|
}
|
|
3963
4317
|
emitBytesIntrinsic(e) {
|
|
3964
|
-
return emitBytesIntrinsic(this
|
|
4318
|
+
return emitBytesIntrinsic(this, e);
|
|
3965
4319
|
}
|
|
3966
4320
|
emitRegexIntrinsic(e) {
|
|
3967
|
-
return emitRegexIntrinsic(this
|
|
4321
|
+
return emitRegexIntrinsic(this, e);
|
|
3968
4322
|
}
|
|
3969
4323
|
emitRecordKeyGet(e) {
|
|
3970
|
-
return emitRecordKeyGet(this
|
|
4324
|
+
return emitRecordKeyGet(this, e);
|
|
3971
4325
|
}
|
|
3972
4326
|
keyedRecordReadInto(slot, join, objName, keyName, shapeId, resultType, overflowOnly, loc) {
|
|
3973
|
-
return keyedRecordReadInto(this
|
|
4327
|
+
return keyedRecordReadInto(this, slot, join, objName, keyName, shapeId, resultType, overflowOnly, loc);
|
|
3974
4328
|
}
|
|
3975
4329
|
dynPromiseAdapter(inner) {
|
|
3976
|
-
return dynPromiseAdapter(this
|
|
4330
|
+
return dynPromiseAdapter(this, inner);
|
|
3977
4331
|
}
|
|
3978
4332
|
streamTypedRefCommitAdapter(t, snapshot) {
|
|
3979
|
-
return streamTypedRefCommitAdapter(this
|
|
4333
|
+
return streamTypedRefCommitAdapter(this, t, snapshot);
|
|
3980
4334
|
}
|
|
3981
4335
|
liveDynRefAdapter(t) {
|
|
3982
|
-
const key = typeKey(t);
|
|
3983
|
-
const existing = this.liveDynRefAdapters.get(key);
|
|
3984
|
-
if (existing)
|
|
3985
|
-
return existing;
|
|
3986
4336
|
if (!streamTypedRefEligible(t) && !isDynTypedRefType(t)) {
|
|
3987
|
-
throw new InternalCompilerError(`llvm emitter bug: live dyn ref of ${
|
|
4337
|
+
throw new InternalCompilerError(`llvm emitter bug: live dyn ref of ${typeKey(t)}`);
|
|
3988
4338
|
}
|
|
3989
|
-
|
|
3990
|
-
const adapter = streamTypedRefMaterializeAdapter(this.expressionContext(), t, { prefix, adapters: new Map() }, `${prefix}_materialize`);
|
|
3991
|
-
this.liveDynRefAdapters.set(key, adapter);
|
|
3992
|
-
return adapter;
|
|
4339
|
+
return streamTypedRefMaterializeAdapter(this, t);
|
|
3993
4340
|
}
|
|
3994
4341
|
liveDynUnionRefAdapter(t) {
|
|
3995
|
-
return liveDynUnionRefAdapter(this
|
|
3996
|
-
}
|
|
3997
|
-
streamTypedRefBoxValue(B, t, value, ctx) {
|
|
3998
|
-
return streamTypedRefBoxValue(this.expressionContext(), B, t, value, ctx);
|
|
4342
|
+
return liveDynUnionRefAdapter(this, t);
|
|
3999
4343
|
}
|
|
4000
|
-
|
|
4001
|
-
return
|
|
4344
|
+
streamTypedRefBoxValue(B, t, value) {
|
|
4345
|
+
return streamTypedRefBoxValue(this, B, t, value);
|
|
4002
4346
|
}
|
|
4003
4347
|
streamFromArrayAdapter(t) {
|
|
4004
|
-
return streamFromArrayAdapter(this
|
|
4348
|
+
return streamFromArrayAdapter(this, t);
|
|
4005
4349
|
}
|
|
4006
4350
|
emitWebLibCall(e) {
|
|
4007
|
-
return emitWebLibCall(this
|
|
4351
|
+
return emitWebLibCall(this, e);
|
|
4008
4352
|
}
|
|
4009
4353
|
emitDynamicLibCall(e) {
|
|
4010
|
-
return emitDynamicLibCall(this
|
|
4354
|
+
return emitDynamicLibCall(this, e);
|
|
4011
4355
|
}
|
|
4012
4356
|
emitFilesystemLibCall(e) {
|
|
4013
|
-
return emitFilesystemLibCall(this
|
|
4357
|
+
return emitFilesystemLibCall(this, e);
|
|
4014
4358
|
}
|
|
4015
4359
|
emitPathUrlLibCall(e) {
|
|
4016
|
-
return emitPathUrlLibCall(this
|
|
4360
|
+
return emitPathUrlLibCall(this, e);
|
|
4017
4361
|
}
|
|
4018
4362
|
emitPrimitiveLibCall(e) {
|
|
4019
|
-
return emitPrimitiveLibCall(this
|
|
4363
|
+
return emitPrimitiveLibCall(this, e);
|
|
4020
4364
|
}
|
|
4021
4365
|
emitChildProcessLibCall(e) {
|
|
4022
|
-
return emitChildProcessLibCall(this
|
|
4366
|
+
return emitChildProcessLibCall(this, e);
|
|
4023
4367
|
}
|
|
4024
4368
|
emitAsyncContextLibCall(e) {
|
|
4025
|
-
return emitAsyncContextLibCall(this
|
|
4369
|
+
return emitAsyncContextLibCall(this, e);
|
|
4026
4370
|
}
|
|
4027
4371
|
emitProcessLibCall(e) {
|
|
4028
|
-
return emitProcessLibCall(this
|
|
4372
|
+
return emitProcessLibCall(this, e);
|
|
4029
4373
|
}
|
|
4030
4374
|
emitErrorsEventsLibCall(e) {
|
|
4031
|
-
return emitErrorsEventsLibCall(this
|
|
4375
|
+
return emitErrorsEventsLibCall(this, e);
|
|
4032
4376
|
}
|
|
4033
4377
|
emitStreamLibCall(e) {
|
|
4034
|
-
return emitStreamLibCall(this
|
|
4378
|
+
return emitStreamLibCall(this, e);
|
|
4035
4379
|
}
|
|
4036
4380
|
emitNetworkHttpLibCall(e) {
|
|
4037
|
-
return emitNetworkHttpLibCall(this
|
|
4381
|
+
return emitNetworkHttpLibCall(this, e);
|
|
4038
4382
|
}
|
|
4039
4383
|
emitAssertInspectLibCall(e) {
|
|
4040
|
-
return emitAssertInspectLibCall(this
|
|
4384
|
+
return emitAssertInspectLibCall(this, e);
|
|
4041
4385
|
}
|
|
4042
4386
|
emitIoLibCall(e) {
|
|
4043
|
-
return emitIoLibCall(this
|
|
4387
|
+
return emitIoLibCall(this, e);
|
|
4044
4388
|
}
|
|
4045
4389
|
emitGenericLibCall(e) {
|
|
4046
|
-
return emitGenericLibCall(this
|
|
4390
|
+
return emitGenericLibCall(this, e);
|
|
4047
4391
|
}
|
|
4048
4392
|
emitLibCall(e) {
|
|
4049
|
-
return emitLibCall(this
|
|
4393
|
+
return emitLibCall(this, e);
|
|
4050
4394
|
}
|
|
4051
4395
|
}
|
|
4052
4396
|
//# sourceMappingURL=emitter.js.map
|