@scriptc/compiler 0.4.1 → 0.4.2
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 +582 -78
- package/dist/backend/cycle-analysis.d.ts +2 -1
- package/dist/backend/cycle-analysis.js +4 -4
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-mutability.d.ts +2 -1
- package/dist/backend/cycle-mutability.js +2 -2
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +4 -1
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.d.ts +2 -1
- package/dist/backend/immutability.js +2 -2
- package/dist/backend/immutability.js.map +1 -1
- package/dist/backend/library-pack.js +4 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +7 -3
- package/dist/backend/llvm/alloc.js +7 -4
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/array-search.js +2 -1
- package/dist/backend/llvm/array-search.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.d.ts +23 -2
- package/dist/backend/llvm/bytes-loop-versions.js +115 -19
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.test.js +131 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +72 -1
- package/dist/backend/llvm/classes.js +331 -45
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +223 -16
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +1 -3
- package/dist/backend/llvm/common.js +1 -3
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.js +8 -4
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +4 -4
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +4 -1
- package/dist/backend/llvm/counted-loops.js +62 -23
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +19 -16
- package/dist/backend/llvm/dense-array-loops.js +46 -10
- package/dist/backend/llvm/dense-array-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.test.js +50 -14
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +25 -1
- package/dist/backend/llvm/dyn.js +331 -8
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +22 -6
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-module.js +17 -11
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emit-statements.d.ts +0 -23
- package/dist/backend/llvm/emit-statements.js +325 -25
- package/dist/backend/llvm/emit-statements.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +141 -15
- package/dist/backend/llvm/emitter.js +537 -64
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +19 -0
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +5 -2
- package/dist/backend/llvm/expr-bytes.js +110 -40
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +34 -22
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +21 -5
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +2 -3
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +54 -6
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +26 -8
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +38 -6
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.js +131 -35
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +10 -0
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +61 -0
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.d.ts +4 -0
- package/dist/backend/llvm/lib-http2.js +20 -17
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +65 -14
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +53 -1
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +65 -28
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/lib-tls.js +23 -0
- package/dist/backend/llvm/lib-tls.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +66 -45
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +14 -0
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/publish.d.ts +8 -1
- package/dist/backend/llvm/publish.js +64 -25
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/publish.test.js +3 -0
- package/dist/backend/llvm/publish.test.js.map +1 -1
- package/dist/backend/llvm/receivers.js +1 -1
- package/dist/backend/llvm/receivers.js.map +1 -1
- package/dist/backend/llvm/reference-writes.js +2 -0
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.js +161 -14
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +18 -0
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +9 -7
- package/dist/backend/llvm/shapes.js +12 -10
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +2 -1
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +3 -0
- package/dist/backend/llvm/string-reads.js +84 -0
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/wasm-modules.d.ts +6 -5
- package/dist/backend/llvm/wasm-modules.js +32 -9
- package/dist/backend/llvm/wasm-modules.js.map +1 -1
- package/dist/backend/mangle.d.ts +3 -0
- package/dist/backend/mangle.js +5 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +22 -4
- package/dist/backend/native/executable.js +24 -8
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -0
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +11 -6
- package/dist/backend/native-codegen.js +36 -9
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +0 -23
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +14 -4
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/optimization.d.ts +2 -2
- 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 +1 -1
- package/dist/backend/runtime-pack-core.js +1 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +4 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.d.ts +0 -21
- package/dist/backend/runtime-pack.js +0 -29
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +9 -69
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/target-diagnostics.js +31 -1
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/warm-cache.js +3 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/cli/command.js +26 -6
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +5 -1
- package/dist/cli/usage.js +7 -2
- package/dist/cli/usage.js.map +1 -1
- package/dist/contracts/check.js +1 -1
- package/dist/contracts/check.js.map +1 -1
- package/dist/coverage/report.d.ts +7 -2
- package/dist/coverage/report.js +18 -0
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +1 -0
- package/dist/coverage/verdict-cache.js +4 -0
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/coverage/verdict-semantic.js +4 -0
- package/dist/coverage/verdict-semantic.js.map +1 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/dynamic-tier.d.ts +40 -0
- package/dist/diagnostics/dynamic-tier.js +57 -0
- package/dist/diagnostics/dynamic-tier.js.map +1 -0
- package/dist/diagnostics/envelope.d.ts +2 -1
- package/dist/diagnostics/envelope.js +5 -2
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +23 -1
- package/dist/executable/executable-cache.js +59 -7
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +45 -3
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +3 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +1 -0
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/dispose-hook.d.ts +2 -0
- package/dist/frontend/dispose-hook.js +14 -0
- package/dist/frontend/dispose-hook.js.map +1 -0
- package/dist/frontend/jsx-entities.d.ts +4 -0
- package/dist/frontend/jsx-entities.js +259 -0
- package/dist/frontend/jsx-entities.js.map +1 -0
- package/dist/frontend/jsx-source.d.ts +71 -0
- package/dist/frontend/jsx-source.js +781 -0
- package/dist/frontend/jsx-source.js.map +1 -0
- package/dist/frontend/jsx-source.test.d.ts +1 -0
- package/dist/frontend/jsx-source.test.js +200 -0
- package/dist/frontend/jsx-source.test.js.map +1 -0
- package/dist/frontend/literal-values.test.js +8 -9
- package/dist/frontend/literal-values.test.js.map +1 -1
- package/dist/frontend/lowering/array-indexed-mutation.js +2 -1
- package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
- package/dist/frontend/lowering/array-values.js +3 -2
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/binding-analysis.d.ts +1 -1
- package/dist/frontend/lowering/binding-analysis.js +2 -2
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtins/arguments.d.ts +3 -0
- package/dist/frontend/lowering/builtins/arguments.js +30 -15
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.js +10 -6
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-async.js +2 -1
- package/dist/frontend/lowering/builtins/child-process-async.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js +2 -1
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +4 -2
- package/dist/frontend/lowering/builtins/crypto.js +59 -3
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/date-classes.d.ts +46 -0
- package/dist/frontend/lowering/builtins/date-classes.js +477 -0
- package/dist/frontend/lowering/builtins/date-classes.js.map +1 -0
- package/dist/frontend/lowering/builtins/dates.d.ts +11 -1
- package/dist/frontend/lowering/builtins/dates.js +55 -26
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/dh.d.ts +15 -0
- package/dist/frontend/lowering/builtins/dh.js +151 -0
- package/dist/frontend/lowering/builtins/dh.js.map +1 -0
- package/dist/frontend/lowering/builtins/disposable-stack.js +2 -1
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -1
- package/dist/frontend/lowering/builtins/ecdh.d.ts +12 -1
- package/dist/frontend/lowering/builtins/ecdh.js +7 -7
- package/dist/frontend/lowering/builtins/ecdh.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +15 -0
- package/dist/frontend/lowering/builtins/errors.js +110 -0
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +23 -17
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.js +6 -4
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-paths.d.ts +15 -0
- package/dist/frontend/lowering/builtins/fs-paths.js +209 -0
- package/dist/frontend/lowering/builtins/fs-paths.js.map +1 -0
- package/dist/frontend/lowering/builtins/hash-stream.d.ts +16 -4
- package/dist/frontend/lowering/builtins/hash-stream.js +86 -23
- package/dist/frontend/lowering/builtins/hash-stream.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +2 -1
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/key-object.d.ts +2 -1
- package/dist/frontend/lowering/builtins/key-object.js +20 -7
- package/dist/frontend/lowering/builtins/key-object.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +11 -4
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/numbers.js +9 -5
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.js +4 -3
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.js +3 -2
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.js +3 -2
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.js +3 -2
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.js +2 -1
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +2 -1
- package/dist/frontend/lowering/builtins/readline.js +23 -6
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/strings.js +13 -5
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +2 -1
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/timers.js +1 -1
- package/dist/frontend/lowering/builtins/timers.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.js +4 -3
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.js +2 -1
- package/dist/frontend/lowering/builtins/v8.js.map +1 -1
- package/dist/frontend/lowering/builtins/webcrypto.js +39 -20
- package/dist/frontend/lowering/builtins/webcrypto.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +2 -1
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.js +13 -6
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/caught-value-dispatch.d.ts +18 -1
- package/dist/frontend/lowering/caught-value-dispatch.js +201 -32
- package/dist/frontend/lowering/caught-value-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-assertions.js +3 -2
- package/dist/frontend/lowering/class-assertions.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +2 -1
- package/dist/frontend/lowering/class-construction.js +8 -13
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.js +1 -1
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +34 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +568 -151
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +77 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +3 -0
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.js +1 -1
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +7 -0
- package/dist/frontend/lowering/class-protocols.js +64 -4
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +5 -0
- package/dist/frontend/lowering/class-prototypes.js +36 -3
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.js +25 -5
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -1
- package/dist/frontend/lowering/class-unions.js +2 -1
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/coercions/function-adapters.js +6 -5
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +8 -7
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.js +8 -7
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.js +2 -1
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +7 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +14 -13
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +2 -1
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +25 -4
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +6 -5
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +2 -1
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +1 -1
- package/dist/frontend/lowering/containers/bytes.js +129 -28
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +52 -2
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.js +3 -2
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +8 -7
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +8 -7
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +32 -1
- package/dist/frontend/lowering/containers/iterator-helpers.js +6 -5
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +36 -9
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +2 -1
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.js +25 -4
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.d.ts +18 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +226 -115
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.test.js +28 -0
- package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -1
- package/dist/frontend/lowering/dispatch-sites.d.ts +59 -0
- package/dist/frontend/lowering/dispatch-sites.js +204 -0
- package/dist/frontend/lowering/dispatch-sites.js.map +1 -0
- package/dist/frontend/lowering/dispatch-sites.test.d.ts +1 -0
- package/dist/frontend/lowering/dispatch-sites.test.js +59 -0
- package/dist/frontend/lowering/dispatch-sites.test.js.map +1 -0
- package/dist/frontend/lowering/dyn-streams.d.ts +3 -0
- package/dist/frontend/lowering/dyn-streams.js +1 -1
- package/dist/frontend/lowering/dyn-streams.js.map +1 -1
- package/dist/frontend/lowering/dynamic-tier.d.ts +25 -0
- package/dist/frontend/lowering/dynamic-tier.js +327 -0
- package/dist/frontend/lowering/dynamic-tier.js.map +1 -0
- package/dist/frontend/lowering/error-methods.js +4 -0
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/expressions/array-literals.js +15 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +45 -3
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +17 -1
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +46 -7
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/narrowing.js +35 -5
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +0 -3
- package/dist/frontend/lowering/expressions/object-literals.js +27 -6
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +5 -5
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +0 -4
- package/dist/frontend/lowering/expressions/property-access.js +99 -7
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/relational.js +63 -5
- package/dist/frontend/lowering/expressions/relational.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +63 -9
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +6 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +20 -30
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +42 -1
- package/dist/frontend/lowering/generic-functions.js +448 -18
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/intern-tables.js +2 -1
- package/dist/frontend/lowering/intern-tables.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.js +9 -8
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-dynamic-objects.js +3 -2
- package/dist/frontend/lowering/js-dynamic-objects.js.map +1 -1
- package/dist/frontend/lowering/json-require.js +2 -1
- package/dist/frontend/lowering/json-require.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.d.ts +7 -2
- package/dist/frontend/lowering/key-order-witness.js +21 -4
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.test.js +38 -2
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
- package/dist/frontend/lowering/lifetime-regions.js +2 -1
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +6 -5
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js +3 -1
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +4 -0
- package/dist/frontend/lowering/lower-calls.js +339 -91
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +18 -0
- package/dist/frontend/lowering/lower-classes.js +280 -25
- package/dist/frontend/lowering/lower-classes.js.map +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-event-emitter.d.ts +14 -0
- package/dist/frontend/lowering/lower-event-emitter.js +267 -20
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +19 -2
- package/dist/frontend/lowering/lower-exprs.js +116 -11
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +304 -72
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +10 -6
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.js +2 -1
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-mock.js +2 -1
- package/dist/frontend/lowering/lower-mock.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +15 -5
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.js +2 -2
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +2 -1
- package/dist/frontend/lowering/lower-namespaces.js +4 -3
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +10 -0
- package/dist/frontend/lowering/lower-server.js +237 -59
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.js +12 -10
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +168 -20
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.test.js +1 -1
- package/dist/frontend/lowering/lower-stmts.test.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +575 -165
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +4 -3
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +125 -28
- package/dist/frontend/lowering/lowerer.js +557 -63
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +21 -9
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.js +5 -0
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +1 -1
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/object-enumeration-receiver.js +2 -1
- package/dist/frontend/lowering/object-enumeration-receiver.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/private-brands.d.ts +9 -0
- package/dist/frontend/lowering/private-brands.js +66 -15
- package/dist/frontend/lowering/private-brands.js.map +1 -1
- package/dist/frontend/lowering/promise-executor-adapter.js +2 -1
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -1
- package/dist/frontend/lowering/require-initialization.js +2 -1
- package/dist/frontend/lowering/require-initialization.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-elements.d.ts +5 -0
- package/dist/frontend/lowering/runtime-optional-elements.js +17 -1
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-records.d.ts +2 -0
- package/dist/frontend/lowering/runtime-optional-records.js +18 -5
- package/dist/frontend/lowering/runtime-optional-records.js.map +1 -1
- package/dist/frontend/lowering/site-dependencies.d.ts +35 -0
- package/dist/frontend/lowering/site-dependencies.js +84 -0
- package/dist/frontend/lowering/site-dependencies.js.map +1 -0
- package/dist/frontend/lowering/site-dependencies.test.d.ts +1 -0
- package/dist/frontend/lowering/site-dependencies.test.js +53 -0
- package/dist/frontend/lowering/site-dependencies.test.js.map +1 -0
- package/dist/frontend/lowering/stable-names.d.ts +11 -0
- package/dist/frontend/lowering/stable-names.js +35 -0
- package/dist/frontend/lowering/stable-names.js.map +1 -0
- package/dist/frontend/lowering/static-typeof.d.ts +2 -2
- package/dist/frontend/lowering/static-typeof.js +42 -3
- package/dist/frontend/lowering/static-typeof.js.map +1 -1
- package/dist/frontend/lowering/strict-equality.js +2 -1
- package/dist/frontend/lowering/strict-equality.js.map +1 -1
- package/dist/frontend/lowering/structural-positions.d.ts +32 -0
- package/dist/frontend/lowering/structural-positions.js +108 -0
- package/dist/frontend/lowering/structural-positions.js.map +1 -0
- package/dist/frontend/lowering/surfaces.js +42 -26
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.js +37 -3
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/npm-static-tsc-helpers.d.ts +5 -0
- package/dist/frontend/npm-static-tsc-helpers.js +106 -0
- package/dist/frontend/npm-static-tsc-helpers.js.map +1 -0
- package/dist/frontend/npm-static-tsc-helpers.test.d.ts +1 -0
- package/dist/frontend/npm-static-tsc-helpers.test.js +58 -0
- package/dist/frontend/npm-static-tsc-helpers.test.js.map +1 -0
- package/dist/frontend/npm-static-type-exports-host.d.ts +8 -0
- package/dist/frontend/npm-static-type-exports-host.js +214 -0
- package/dist/frontend/npm-static-type-exports-host.js.map +1 -0
- package/dist/frontend/npm-static-type-exports-host.test.d.ts +1 -0
- package/dist/frontend/npm-static-type-exports-host.test.js +53 -0
- package/dist/frontend/npm-static-type-exports-host.test.js.map +1 -0
- package/dist/frontend/npm-static-type-exports.d.ts +52 -0
- package/dist/frontend/npm-static-type-exports.js +261 -0
- package/dist/frontend/npm-static-type-exports.js.map +1 -0
- package/dist/frontend/npm-static-type-exports.test.d.ts +1 -0
- package/dist/frontend/npm-static-type-exports.test.js +103 -0
- package/dist/frontend/npm-static-type-exports.test.js.map +1 -0
- package/dist/frontend/npm-static-umd.d.ts +6 -0
- package/dist/frontend/npm-static-umd.js +203 -0
- package/dist/frontend/npm-static-umd.js.map +1 -0
- package/dist/frontend/npm-static-umd.test.d.ts +1 -0
- package/dist/frontend/npm-static-umd.test.js +105 -0
- package/dist/frontend/npm-static-umd.test.js.map +1 -0
- package/dist/frontend/npm-static.d.ts +8 -0
- package/dist/frontend/npm-static.js +47 -2
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/program.d.ts +13 -0
- package/dist/frontend/program.js +103 -6
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +1 -1
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/services.d.ts +6 -0
- package/dist/frontend/services.js +18 -0
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +21 -7
- package/dist/frontend/ts7/ast-node.js +131 -29
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +60 -0
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.d.ts +27 -2
- package/dist/frontend/ts7/ast-wire.js +124 -21
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/ast.d.ts +23 -2
- package/dist/frontend/ts7/ast.js +143 -2
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +13 -1
- package/dist/frontend/ts7/checker.js +75 -1
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +9 -6
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/enums.d.ts +3 -3
- package/dist/frontend/ts7/enums.generated.d.ts +10 -0
- package/dist/frontend/ts7/enums.generated.js +21 -0
- package/dist/frontend/ts7/enums.generated.js.map +1 -1
- package/dist/frontend/ts7/enums.js +19 -0
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/program-host.js +5 -2
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.d.ts +10 -0
- package/dist/frontend/ts7/semantic-checker.js +25 -20
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-json.d.ts +13 -0
- package/dist/frontend/ts7/semantic-json.js +146 -0
- package/dist/frontend/ts7/semantic-json.js.map +1 -1
- package/dist/frontend/ts7/semantic-json.test.js +57 -1
- package/dist/frontend/ts7/semantic-json.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +15 -0
- package/dist/frontend/ts7/semantic-model.js +67 -19
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +3 -2
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/session.js +1 -1
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/tsc-codes.d.ts +1 -1
- package/dist/frontend/tsc-codes.js +7 -0
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +38 -6
- package/dist/frontend/type-mapper.js +265 -32
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.js +1 -1
- package/dist/frontend/type-mapper.test.js.map +1 -1
- package/dist/frontend-process-args.d.ts +4 -0
- package/dist/frontend-process-args.js +52 -0
- package/dist/frontend-process-args.js.map +1 -0
- package/dist/frontend-process-args.test.d.ts +1 -0
- package/dist/frontend-process-args.test.js +47 -0
- package/dist/frontend-process-args.test.js.map +1 -0
- package/dist/frontend-process.d.ts +1 -0
- package/dist/frontend-process.js +23 -0
- package/dist/frontend-process.js.map +1 -0
- package/dist/heap-collection.d.ts +16 -0
- package/dist/heap-collection.js +42 -0
- package/dist/heap-collection.js.map +1 -0
- package/dist/heap-collection.test.d.ts +1 -0
- package/dist/heap-collection.test.js +59 -0
- package/dist/heap-collection.test.js.map +1 -0
- package/dist/heap-pressure.d.ts +2 -0
- package/dist/heap-pressure.js +12 -0
- package/dist/heap-pressure.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +402 -86
- package/dist/index.js.map +1 -1
- package/dist/ir/array-length-stability.js +7 -0
- package/dist/ir/array-length-stability.js.map +1 -1
- package/dist/ir/array-length-stability.test.js +25 -0
- package/dist/ir/array-length-stability.test.js.map +1 -1
- package/dist/ir/builtin-effects.js +28 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +5 -1
- package/dist/ir/builtin-signatures.js +141 -12
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/final-fields.d.ts +2 -1
- package/dist/ir/final-fields.js +2 -2
- package/dist/ir/final-fields.js.map +1 -1
- package/dist/ir/function-references.test.js +2 -0
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/int32-slots.d.ts +13 -5
- package/dist/ir/int32-slots.js +112 -115
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +3 -1
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loop-facts.d.ts +9 -4
- package/dist/ir/integer-loop-facts.js +93 -18
- package/dist/ir/integer-loop-facts.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +49 -0
- package/dist/ir/integer-loops.js +193 -39
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +201 -1
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +64 -0
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/ir.d.ts +17 -2
- package/dist/ir/ir.js +3 -1
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +31 -7
- package/dist/ir/runtime-features.js +138 -11
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/tiers.js +1 -0
- package/dist/ir/tiers.js.map +1 -1
- package/dist/ir/traverse.d.ts +2 -0
- package/dist/ir/traverse.js +14 -2
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +56 -16
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/ir-policy.js +10 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +2 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/prepare.js +2 -0
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +5 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/prepare.js +5 -1
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +4 -1
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/text-parts.d.ts +7 -0
- package/dist/text-parts.js +44 -0
- package/dist/text-parts.js.map +1 -1
- package/dist/text-parts.test.d.ts +1 -0
- package/dist/text-parts.test.js +46 -0
- package/dist/text-parts.test.js.map +1 -0
- package/dist/timing.d.ts +9 -2
- package/dist/timing.js +7 -4
- package/dist/timing.js.map +1 -1
- package/dist/wasm/translate.d.ts +4 -0
- package/dist/wasm/translate.js +2 -2
- package/dist/wasm/translate.js.map +1 -1
- package/package.json +21 -21
- package/shims/undici/core/client.ts +4 -4
- package/surface-manifest.json +19 -49
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { relieveHeapPressure } from "../../heap-pressure.js";
|
|
1
2
|
import { wasmBoundsChecks } from "./wasm-modules.js";
|
|
2
3
|
import { jsTruthy } from "./jsval.js";
|
|
3
4
|
import { JsIcSites } from "../../ir/js-ic.js";
|
|
@@ -12,7 +13,7 @@ import { createHash } from "node:crypto";
|
|
|
12
13
|
import { endsWithJump, matchFieldSelfConcat, readsArraySlot, streamTypedRefEligible, undefinedArmTag, } from "../../ir/analysis.js";
|
|
13
14
|
import { loopTestsEveryIteration } from "../loop-polls.js";
|
|
14
15
|
import { isDynTypedRefType, isRefCounted, isUnitType, POINTER_KINDS, RUNTIME_EMITTER_CLASS, RUNTIME_EVENT_CLASS, RUNTIME_EVENT_TARGET_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, typeEquals, typeKey, VOID, classJsName, } from "../../ir/ir.js";
|
|
15
|
-
import { moduleRuntimeFeatures
|
|
16
|
+
import { moduleRuntimeFeatures } from "../../ir/runtime-features.js";
|
|
16
17
|
import { captureFreeFunctions, observesStacks } from "../stack-observations.js";
|
|
17
18
|
import {} from "./dense-array-loops.js";
|
|
18
19
|
import { findInitializedByteLoopBindings } from "./byte-windows.js";
|
|
@@ -90,7 +91,7 @@ import { emitChildProcessLibCall, emitAsyncContextLibCall, emitProcessLibCall, e
|
|
|
90
91
|
import { emitStreamLibCall } from "./lib-stream.js";
|
|
91
92
|
import { emitNetworkHttpLibCall } from "./lib-network.js";
|
|
92
93
|
import { emitAssertInspectLibCall, emitIoLibCall, emitGenericLibCall, emitLibCall, } from "./lib-dispatch.js";
|
|
93
|
-
import { buildClassGraph, classMembershipIntervals, classFieldIndex, classPreLines, classStructSym, programLifetimeClass, } from "./classes.js";
|
|
94
|
+
import { assignCompactLayouts, buildClassGraph, classFieldTypes, classMembershipIntervals, classFieldIndex, compactRefLoadLines, compactRefStoreLines, classPreLines, classStructSym, programLifetimeClass, } from "./classes.js";
|
|
94
95
|
import { LifetimeRegions, REGION_TYPES } from "./regions.js";
|
|
95
96
|
import { LlDyn, recordDynKeepsIdentity } from "./dyn.js";
|
|
96
97
|
import { VirtualBorrows } from "./virtual-borrows.js";
|
|
@@ -99,7 +100,7 @@ import { LlWalkers } from "./walkers.js";
|
|
|
99
100
|
import { isObjectArm, NULLABLE_ABSENT, NULLABLE_NULL, NullableUnions } from "./nullable-unions.js";
|
|
100
101
|
import { emitNullablePresent, emitUnionPeek, emitUnionTag } from "./union-repr.js";
|
|
101
102
|
import { emitConcatInputs, emitMixedConcat, numberPart, stringParts, } from "./string-construction.js";
|
|
102
|
-
import { arrNewCall, boxAccess, boxNewCall, boxReleaseSym, computeTraced, emitInlineRcHelpers, emitNullableRetainWrappers, emitShapeUnionHelpers, FN_ATTRS, inlineRcDecls, llFieldType, mapFlagsOffset, releaseSym, retainSym, traceArg, vAdapters, } from "./shapes.js";
|
|
103
|
+
import { arrNewCall, boxAccess, elemAccess, boxNewCall, boxReleaseSym, computeTraced, emitInlineRcHelpers, emitNullableRetainWrappers, emitShapeUnionHelpers, FN_ATTRS, inlineRcDecls, llFieldType, mapFlagsOffset, releaseSym, retainSym, traceArg, vAdapters, } from "./shapes.js";
|
|
103
104
|
import { INLINE_LITERAL_BYTES } from "./string-literal-equality.js";
|
|
104
105
|
import { emitFfiCallbackDefs, emitLibDefs, emitModuleParts, emitParts, helperDefs, } from "./emit-module.js";
|
|
105
106
|
import { emitLoopCopies, emitSpeculativeWrite, emitStmtBody, emitStringSelfConcatAssign, emitSwitch, emitTryCatch, } from "./emit-statements.js";
|
|
@@ -131,6 +132,14 @@ export function ffiCallbackDummyLl(callback) {
|
|
|
131
132
|
return "i32 0";
|
|
132
133
|
}
|
|
133
134
|
}
|
|
135
|
+
/** LlvmTargetOptions.lowRegion for an executable: Linux targets without
|
|
136
|
+
* sanitizers, whose address space below 32 GiB is free (ASan keeps its
|
|
137
|
+
* shadow memory there; other systems map their own images and libraries
|
|
138
|
+
* there). `platform` is a target platform (`linux`, `darwin`, `win32`,
|
|
139
|
+
* `wasi`). */
|
|
140
|
+
export function lowRegionTarget(platform, sanitize) {
|
|
141
|
+
return platform === "linux" && !sanitize;
|
|
142
|
+
}
|
|
134
143
|
export function emitLlvmModule(input, options = {}) {
|
|
135
144
|
// Facts are keyed by node identity: emit the same module whether it was
|
|
136
145
|
// lowered in memory or read back from its serialized form.
|
|
@@ -142,6 +151,8 @@ export function emitLlvmModule(input, options = {}) {
|
|
|
142
151
|
}
|
|
143
152
|
/** Keep large translation units below the host's single-string limit. */
|
|
144
153
|
export function emitLlvmModuleSource(input, options = {}) {
|
|
154
|
+
// IR validation, contracts and the frontend's disposal run after lowering without checks.
|
|
155
|
+
relieveHeapPressure(true);
|
|
145
156
|
const mod = unshareNodes(input);
|
|
146
157
|
const parts = new LlEmitter(options.debugSources === undefined
|
|
147
158
|
? addRecordResultEntries(scalarizeNumericRecords(specializeCallbackCalls(specializeNumericCalls(foldConstantGlobals(copyStableCaptures(resolveSelfCaptures(hoistFinalFieldReads(freezeInitOnlyGlobals(dropUnwrittenPropertyBags(mod)))))), mangleFunction), mangleFunction)))
|
|
@@ -231,6 +242,34 @@ function mentionsLocal(e, localId) {
|
|
|
231
242
|
expr(e);
|
|
232
243
|
return found;
|
|
233
244
|
}
|
|
245
|
+
/** The IR nodes in `body` that name local `id`: its declaration, reads,
|
|
246
|
+
* writes and closure captures. */
|
|
247
|
+
function countLocalMentions(body, id) {
|
|
248
|
+
let count = 0;
|
|
249
|
+
const visit = (node) => {
|
|
250
|
+
if (node === null || typeof node !== "object")
|
|
251
|
+
return;
|
|
252
|
+
if (Array.isArray(node)) {
|
|
253
|
+
for (const item of node)
|
|
254
|
+
visit(item);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const record = node;
|
|
258
|
+
if (record["localId"] === id)
|
|
259
|
+
count++;
|
|
260
|
+
const captures = record["captures"];
|
|
261
|
+
if (Array.isArray(captures))
|
|
262
|
+
for (const c of captures)
|
|
263
|
+
if (c === id ||
|
|
264
|
+
(typeof c === "object" && c !== null && c.localId === id))
|
|
265
|
+
count++;
|
|
266
|
+
for (const [key, value] of Object.entries(record))
|
|
267
|
+
if (key !== "type" && key !== "loc" && key !== "captures")
|
|
268
|
+
visit(value);
|
|
269
|
+
};
|
|
270
|
+
visit(body);
|
|
271
|
+
return count;
|
|
272
|
+
}
|
|
234
273
|
export class LlEmitter {
|
|
235
274
|
mod;
|
|
236
275
|
localArrayReads = new Map();
|
|
@@ -254,6 +293,13 @@ export class LlEmitter {
|
|
|
254
293
|
integerArrayBindings = new Set();
|
|
255
294
|
fieldAliasTags = new Map();
|
|
256
295
|
fieldPointerTags = new Map();
|
|
296
|
+
/** The field pointers (classFieldPtr) of this function whose fields hold
|
|
297
|
+
* 32-bit references to compact class instances (LlClassMeta.compressed):
|
|
298
|
+
* loadField/loadRef decode them and storeField/storeRef encode them. */
|
|
299
|
+
compressedFieldPtrs = new Set();
|
|
300
|
+
/** Whether a class has compressed fields: main reserves the region before
|
|
301
|
+
* compiled code runs (scr_plr_init). */
|
|
302
|
+
usesCompactRefs = false;
|
|
257
303
|
/** Native class fields with different property names cannot occupy the
|
|
258
304
|
* same slot of one object. Inherited views of the same property share a
|
|
259
305
|
* tag. Array storage has its own disjoint categories; untagged runtime
|
|
@@ -432,6 +478,12 @@ export class LlEmitter {
|
|
|
432
478
|
callLifetimes;
|
|
433
479
|
constantCallbacks;
|
|
434
480
|
currentConstantCallbacks = new Map();
|
|
481
|
+
/** Callback bindings whose closures an enclosing callback loop version
|
|
482
|
+
* proved to hold their known function: calls take the direct entry with
|
|
483
|
+
* no fallback (emitCallbackVersionedLoop). */
|
|
484
|
+
knownCallbacks = new Set();
|
|
485
|
+
callbackVersioning = new Set();
|
|
486
|
+
callbackVersionsEnabled = false;
|
|
435
487
|
stackCallbacks;
|
|
436
488
|
receiverReaders;
|
|
437
489
|
stackCaptures;
|
|
@@ -513,9 +565,15 @@ export class LlEmitter {
|
|
|
513
565
|
/** Fiberless async functions a stackless coroutine body awaits directly;
|
|
514
566
|
* each gets an inline await entry (emitCoroInlineAwait). */
|
|
515
567
|
inlineAwaitCallees = new Set();
|
|
568
|
+
/** Stackless async functions some coroutine body awaits directly: each
|
|
569
|
+
* gets a direct spawn entry (emitCoroDirectAwait). */
|
|
570
|
+
directAwaitCallees = new Set();
|
|
516
571
|
/** The async functions whose bodies never suspend and that a direct
|
|
517
572
|
* await may enter in place (selectStacklessAsync). */
|
|
518
573
|
inlineAwaitable = new Set();
|
|
574
|
+
/** Locals whose array literal emitStmts left for the `await Promise.all`
|
|
575
|
+
* that reads them (deferredPromiseAllLocal). */
|
|
576
|
+
deferredPromiseAllEntries = new Map();
|
|
519
577
|
/** The promise a `return` emitted past its finally regions already
|
|
520
578
|
* produced for its adopting await (borrowed from the return's parked
|
|
521
579
|
* slot); that await takes it instead of evaluating its operand. */
|
|
@@ -531,13 +589,16 @@ export class LlEmitter {
|
|
|
531
589
|
/** The program calls mock.timers members (moduleUsesMockTimers): timer
|
|
532
590
|
* calls emit scr_test.c's mock-aware entry points. */
|
|
533
591
|
mockTimers;
|
|
534
|
-
|
|
592
|
+
runtimeFeaturesValue;
|
|
593
|
+
/** The module's runtime features (moduleRuntimeFeatures), found with one
|
|
594
|
+
* walk of the module the first time any of them is read. */
|
|
595
|
+
get runtimeFeatures() {
|
|
596
|
+
return (this.runtimeFeaturesValue ??= moduleRuntimeFeatures(this.mod));
|
|
597
|
+
}
|
|
535
598
|
/** Whether timer and tick scheduling goes through the *_als entry
|
|
536
599
|
* points (RuntimeFeatures asyncContext). */
|
|
537
600
|
get schedulesInContext() {
|
|
538
|
-
|
|
539
|
-
this.schedulesInContextValue = moduleRuntimeFeatures(this.mod).asyncContext;
|
|
540
|
-
return this.schedulesInContextValue;
|
|
601
|
+
return this.runtimeFeatures.asyncContext;
|
|
541
602
|
}
|
|
542
603
|
/** Emitted ref-kind resolve thunks for new Promise, interned per inner
|
|
543
604
|
* typeKey → thunk symbol. */
|
|
@@ -553,10 +614,9 @@ export class LlEmitter {
|
|
|
553
614
|
/** Identity-preserving static→dyn capsules for program classes and Web
|
|
554
615
|
* APIs whose values remain directly observable. */
|
|
555
616
|
liveDynRefAdapters = new Map();
|
|
556
|
-
dynBuiltinStreamUse;
|
|
557
617
|
/** See moduleUsesDynBuiltinStream. */
|
|
558
618
|
get usesDynBuiltinStream() {
|
|
559
|
-
return
|
|
619
|
+
return this.runtimeFeatures.dynBuiltinStream;
|
|
560
620
|
}
|
|
561
621
|
/** Runtime-arm dispatchers for live union values. */
|
|
562
622
|
liveDynUnionRefAdapters = new Map();
|
|
@@ -657,14 +717,28 @@ export class LlEmitter {
|
|
|
657
717
|
captureIds = new Set();
|
|
658
718
|
/** Active induction bindings retain their width independently of size_t. */
|
|
659
719
|
integerLoopBindings = new Map();
|
|
720
|
+
/** Constant number locals whose latest emitted declaration stored an
|
|
721
|
+
* exact integer beside the double, such as `const j = i * 4` in a
|
|
722
|
+
* typed-array loop version: an i64 slot and the integer's range. */
|
|
723
|
+
integerTemps = new Map();
|
|
724
|
+
/** Integer temps are kept only in optimized synchronous functions: an
|
|
725
|
+
* async or generator body resumes with its locals in its frame, which
|
|
726
|
+
* an entry alloca is not part of. */
|
|
727
|
+
integerTempsEnabled = false;
|
|
660
728
|
countedLoopsEnabled = false;
|
|
661
729
|
/** Speculative integer loops (speculative-integers.ts) run in this function. */
|
|
662
730
|
speculativeLoopsEnabled = false;
|
|
663
731
|
/** The fast copy of a speculative integer loop being emitted: its
|
|
664
732
|
* integer-computed writes and where each resumes in the ordinary copy. */
|
|
665
733
|
speculation = null;
|
|
734
|
+
/** Speculative loop sites numbered so far in the module. */
|
|
735
|
+
speculativeLoopSites = 0;
|
|
666
736
|
/** The ordinary copy being emitted: resume labels still to place. */
|
|
667
737
|
speculationResume = null;
|
|
738
|
+
/** Run once at the top of the next loop copy's header
|
|
739
|
+
* (`enterLoopHeader`): records the ordinary copy's header, or sends the
|
|
740
|
+
* third copy's header there. */
|
|
741
|
+
speculationHeader = null;
|
|
668
742
|
/** The function being emitted, for speculative globals. */
|
|
669
743
|
speculativeFunction = "";
|
|
670
744
|
/** Every function that writes each number global (computed on demand). */
|
|
@@ -696,6 +770,9 @@ export class LlEmitter {
|
|
|
696
770
|
* guard already passed. */
|
|
697
771
|
provenCountedGuards = new Set();
|
|
698
772
|
bytesBounds = new Set();
|
|
773
|
+
/** Worker programs: typed-array accesses whose views an enclosing version
|
|
774
|
+
* guard proved thread-owned. */
|
|
775
|
+
bytesOwned = new Set();
|
|
699
776
|
integerViews = new Map();
|
|
700
777
|
/** Module globals the current function owns outright (initializer
|
|
701
778
|
* bindings): their function-local slot, which stands in for the global. */
|
|
@@ -752,21 +829,25 @@ export class LlEmitter {
|
|
|
752
829
|
this.mod = mod;
|
|
753
830
|
this.stackTraces = observesStacks(mod);
|
|
754
831
|
this.nullableUnions = new NullableUnions(mod, options.debugSources === undefined);
|
|
755
|
-
this.mockTimers =
|
|
832
|
+
this.mockTimers = this.runtimeFeatures.mockTimers;
|
|
756
833
|
this.debug =
|
|
757
834
|
options.debugSources === undefined
|
|
758
835
|
? null
|
|
759
836
|
: new LlvmDebugInfo(mod.sourceFile, options.debugSources, options.pointerBits, mod.unions, this.nullableUnions.armTypes());
|
|
760
837
|
this.constantNumericTables = findConstantNumericTables(mod);
|
|
761
838
|
this.initializerBindings = findInitializerBindings(mod);
|
|
762
|
-
|
|
839
|
+
// One walk finds the dynamic field stores every analysis below consults.
|
|
763
840
|
const dynamicStores = dynamicFieldStores(mod);
|
|
841
|
+
this.int32Slots = analyzeInt32Slots(mod, {
|
|
842
|
+
dynamicStores,
|
|
843
|
+
initializerBindings: this.initializerBindings,
|
|
844
|
+
});
|
|
764
845
|
this.liveViewsReadOnly =
|
|
765
846
|
mod.lib === undefined && !dynamicStores.all && dynamicStores.names.size === 0;
|
|
766
847
|
this.int32Abis = this.debug === null ? findInt32Abis(mod, this.int32Slots) : new Map();
|
|
767
848
|
this.immortalGlobals = new Set(mod.contracts?.immortalGlobals ?? []);
|
|
768
849
|
this.programLifetime = new Set(mod.contracts?.programLifetime ?? []);
|
|
769
|
-
this.finalFields = analyzeFinalFields(mod);
|
|
850
|
+
this.finalFields = analyzeFinalFields(mod, false, dynamicStores);
|
|
770
851
|
this.sizeType = options.pointerBits === 32 ? "i32" : "i64";
|
|
771
852
|
this.ffiExtendNarrowIntegers =
|
|
772
853
|
options.wasi === true || ffiExtendsNarrowIntegers(options.targetTriple);
|
|
@@ -837,7 +918,7 @@ export class LlEmitter {
|
|
|
837
918
|
this.unframedFunctions = this.stackTraces
|
|
838
919
|
? captureFreeFunctions(mod, this.stackChecks, this.publishedTypes)
|
|
839
920
|
: new Set();
|
|
840
|
-
this.immutableFields = computeImmutableFields(mod);
|
|
921
|
+
this.immutableFields = computeImmutableFields(mod, dynamicStores);
|
|
841
922
|
this.constructorFunctions = new Set((mod.classes ?? []).map((c) => `%${c.name}.constructor`));
|
|
842
923
|
this.indirectMayThrow = mt.indirect || mod.workers === true;
|
|
843
924
|
for (const cls of mod.classes ?? []) {
|
|
@@ -941,7 +1022,7 @@ export class LlEmitter {
|
|
|
941
1022
|
this.receiverReaders = new AmbientReceiverReaders(this.fnByName);
|
|
942
1023
|
this.stackCaptures = new StackCaptures(this.fnByName, this.callLifetimes, this.stackCallbacks);
|
|
943
1024
|
this.lazyCaptures = new LazyCaptures(this.fnByName);
|
|
944
|
-
const traced = computeTraced(mod);
|
|
1025
|
+
const traced = computeTraced(mod, dynamicStores);
|
|
945
1026
|
this.tracedShapes = traced.shapes;
|
|
946
1027
|
this.tracedUnions = traced.unions;
|
|
947
1028
|
// A shape union's value is whichever record it holds, and the collector
|
|
@@ -1068,6 +1149,37 @@ export class LlEmitter {
|
|
|
1068
1149
|
classDefinitions: (cls, sizeOf) => regions.classDefs(cls, sizeOf),
|
|
1069
1150
|
};
|
|
1070
1151
|
}
|
|
1152
|
+
// ProgramLifetime hierarchies count nothing: their instances get the
|
|
1153
|
+
// 32-bit header and packed fields (classes.ts LlClassMeta.compact),
|
|
1154
|
+
// except where regions count them or a slot word follows the header.
|
|
1155
|
+
if (this.sizeType === "i64" && mod.lifetimeRegions !== true)
|
|
1156
|
+
assignCompactLayouts(this.classMeta, (root) => programLifetimeClass(this.shapeHost, root) && !root.threadSlot, (cls) => classFieldTypes(this.shapeHost, cls, this.int32Slots),
|
|
1157
|
+
// Executables whose region lies below 32 GiB hold compact class
|
|
1158
|
+
// instances there (scr_plr_alloc), so fields referring to one store
|
|
1159
|
+
// a 32-bit reference: the field's type, the class of a
|
|
1160
|
+
// `C | undefined` or `C | null` pointer, or the reference arm of a
|
|
1161
|
+
// nullable pointer field, is a compact class. `C | null | undefined`
|
|
1162
|
+
// keeps the pointer: its null is a sentinel outside the region.
|
|
1163
|
+
mod.lib === undefined && options.lowRegion === true
|
|
1164
|
+
? (cls, i, isCompact) => {
|
|
1165
|
+
const f = cls.fields[i];
|
|
1166
|
+
if (this.inlineUnions.classField(cls.name, f.name))
|
|
1167
|
+
return false;
|
|
1168
|
+
const t = f.type;
|
|
1169
|
+
if (t.kind === "object")
|
|
1170
|
+
return isCompact(t.className);
|
|
1171
|
+
if (t.kind !== "union")
|
|
1172
|
+
return false;
|
|
1173
|
+
const single = this.nullableUnions.single(t.unionId);
|
|
1174
|
+
if (single !== null)
|
|
1175
|
+
return (single.nullTag < 0 &&
|
|
1176
|
+
single.arm.kind === "object" &&
|
|
1177
|
+
isCompact(single.arm.className));
|
|
1178
|
+
const nullable = this.nullableFields.get(cls.name, f.name);
|
|
1179
|
+
return nullable !== null && isCompact(nullable.arm.className);
|
|
1180
|
+
}
|
|
1181
|
+
: undefined);
|
|
1182
|
+
this.usesCompactRefs = [...this.classMeta.values()].some((m) => m.compressed.some(Boolean));
|
|
1071
1183
|
for (const [name, rec] of RUNTIME_ERROR_CLASSES) {
|
|
1072
1184
|
const meta = this.classMeta.get(name);
|
|
1073
1185
|
if (!meta)
|
|
@@ -1330,16 +1442,33 @@ export class LlEmitter {
|
|
|
1330
1442
|
this.fnDefText.set(fn.name, coroText);
|
|
1331
1443
|
});
|
|
1332
1444
|
}
|
|
1445
|
+
/** Whether a fiberless body running on its caller's stack needs the
|
|
1446
|
+
* frame scr_async_inline_enter/exit keep: it isolates the Error.stack
|
|
1447
|
+
* frame chain, which only stack-observing programs push, as a fresh fiber
|
|
1448
|
+
* would. Other programs run the body with a plain call. The body runs in
|
|
1449
|
+
* its caller's AsyncLocalStorage context either way, as Node runs an async
|
|
1450
|
+
* body up to its first await. The frame also counts the bodies running on
|
|
1451
|
+
* a fiber's stack for the runtime's trap on a fiberless body that
|
|
1452
|
+
* suspends. */
|
|
1453
|
+
get fiberlessFrames() {
|
|
1454
|
+
return this.stackTraces;
|
|
1455
|
+
}
|
|
1333
1456
|
/** The spawn wrapper of a fiberless async function: runs the body on the
|
|
1334
|
-
* caller's stack between scr_async_inline_enter/leave
|
|
1335
|
-
* fresh promise from its outcome — the
|
|
1336
|
-
* without the fiber. */
|
|
1457
|
+
* caller's stack (between scr_async_inline_enter/leave when
|
|
1458
|
+
* fiberlessFrames) and settles a fresh promise from its outcome — the
|
|
1459
|
+
* fiber trampoline's epilogue, without the fiber. */
|
|
1337
1460
|
emitFiberlessAsyncSpawn(fn, spawnParams) {
|
|
1338
1461
|
const ret = fn.returnType;
|
|
1339
1462
|
const retTy = this.llType(ret);
|
|
1340
1463
|
const lifted = fn.captures !== undefined;
|
|
1341
|
-
this.
|
|
1342
|
-
|
|
1464
|
+
const framed = this.fiberlessFrames;
|
|
1465
|
+
if (framed) {
|
|
1466
|
+
this.declare(`declare void @scr_async_inline_enter(ptr)`);
|
|
1467
|
+
this.declare(`declare ptr @scr_async_inline_leave(ptr)`);
|
|
1468
|
+
}
|
|
1469
|
+
else {
|
|
1470
|
+
this.declare(`declare ptr @scr_promise_new()`);
|
|
1471
|
+
}
|
|
1343
1472
|
this.declare(`declare void @scr_promise_reject_pending(ptr)`);
|
|
1344
1473
|
if (lifted) {
|
|
1345
1474
|
this.declare(`declare ptr @scr_closure_retain_v(ptr)`);
|
|
@@ -1349,15 +1478,17 @@ export class LlEmitter {
|
|
|
1349
1478
|
const out = [
|
|
1350
1479
|
`define internal ptr @${mangleAsyncSpawn(fn.name)}(${spawnParams.join(", ")}) ${FN_ATTRS} { ; fiberless ${fn.name}`,
|
|
1351
1480
|
`entry:`,
|
|
1352
|
-
` %frame = alloca { ptr, ptr }
|
|
1481
|
+
...(framed ? [` %frame = alloca { ptr, ptr }`] : []),
|
|
1353
1482
|
// The fiber path holds +1 on a lifted environment for the body's
|
|
1354
1483
|
// duration (packed, released by the trampoline); keep that lifetime.
|
|
1355
1484
|
...(lifted ? [` %env = call ptr @scr_closure_retain_v(ptr %a0)`] : []),
|
|
1356
|
-
` call void @scr_async_inline_enter(ptr %frame)
|
|
1485
|
+
...(framed ? [` call void @scr_async_inline_enter(ptr %frame)`] : []),
|
|
1357
1486
|
retTy === "void" ? ` ${bodyCall}` : ` %r = ${bodyCall}`,
|
|
1358
1487
|
...(lifted ? [` call void @scr_closure_release(ptr %a0)`] : []),
|
|
1359
1488
|
...this.pendingTestLines("%pend"),
|
|
1360
|
-
|
|
1489
|
+
framed
|
|
1490
|
+
? ` %p = call ptr @scr_async_inline_leave(ptr %frame)`
|
|
1491
|
+
: ` %p = call ptr @scr_promise_new()`,
|
|
1361
1492
|
` br i1 %pend, label %thrown, label %clean`,
|
|
1362
1493
|
`clean:`,
|
|
1363
1494
|
...this.asyncFulfillLines(ret, "%p"),
|
|
@@ -1397,24 +1528,94 @@ export class LlEmitter {
|
|
|
1397
1528
|
return false;
|
|
1398
1529
|
return fn.captures === undefined;
|
|
1399
1530
|
}
|
|
1531
|
+
/** Whether a stackless coroutine body's `await f(...)` may await f's
|
|
1532
|
+
* fiber record instead of its promise (emitCoroDirectAwait): f is a
|
|
1533
|
+
* stackless async function whose direct call an await-call entry could
|
|
1534
|
+
* take. The await consumes the promise, so nothing else can observe it.
|
|
1535
|
+
* Worker programs keep the promise for their stop checkpoint. */
|
|
1536
|
+
directAwaitEligible(fnName) {
|
|
1537
|
+
if (this.wasi || this.mod.workers === true || this.currentCoro?.kind !== "async")
|
|
1538
|
+
return false;
|
|
1539
|
+
const fn = this.fnByName.get(fnName);
|
|
1540
|
+
if (fn === undefined || fn.async !== true || fn.generator !== undefined)
|
|
1541
|
+
return false;
|
|
1542
|
+
if (!this.stacklessAsync.has(fnName) || fn.captures !== undefined)
|
|
1543
|
+
return false;
|
|
1544
|
+
if (fn.returnType.kind === "dyn")
|
|
1545
|
+
return false;
|
|
1546
|
+
return fn.asyncCacheGlobal === undefined && fn.asyncCycleCacheGlobal === undefined;
|
|
1547
|
+
}
|
|
1548
|
+
/** A stackless coroutine body's `await f(...)` of a stackless f, without
|
|
1549
|
+
* f's promise object: f's prefix runs as the spawn of a fiber record that
|
|
1550
|
+
* keeps the promise inside. A body still running wakes this coroutine
|
|
1551
|
+
* when it finishes, where its promise's settlement would wake its one
|
|
1552
|
+
* waiter; a finished one takes the settled await's turn. The result (or
|
|
1553
|
+
* the rejection, re-thrown) comes out of the record, which goes. */
|
|
1554
|
+
emitCoroDirectAwait(call, type) {
|
|
1555
|
+
const coro = this.currentCoro;
|
|
1556
|
+
if (coro === null)
|
|
1557
|
+
throw new InternalCompilerError("llvm emitter bug: direct await outside a coroutine");
|
|
1558
|
+
const B = this.B;
|
|
1559
|
+
const record = emitCallExpr(this, call, "direct").name;
|
|
1560
|
+
this.declare(`declare zeroext i1 @scr_coro_direct_prepare(ptr, ptr)`);
|
|
1561
|
+
const suspend = B.tmp();
|
|
1562
|
+
B.line(`${suspend} = call zeroext i1 @scr_coro_direct_prepare(ptr ${coro.self}, ptr ${record})`);
|
|
1563
|
+
const park = B.newLabel("await.suspend");
|
|
1564
|
+
const ready = B.newLabel("await.ready");
|
|
1565
|
+
B.condBr(suspend, park, ready);
|
|
1566
|
+
B.startBlock(park);
|
|
1567
|
+
this.emitCoroSuspendPrepared();
|
|
1568
|
+
B.br(ready);
|
|
1569
|
+
B.startBlock(ready);
|
|
1570
|
+
if (type.kind === "void") {
|
|
1571
|
+
this.declare(`declare void @scr_coro_direct_void(ptr)`);
|
|
1572
|
+
B.line(`call void @scr_coro_direct_void(ptr ${record})`);
|
|
1573
|
+
this.emitPendingCheck();
|
|
1574
|
+
return { name: "", type };
|
|
1575
|
+
}
|
|
1576
|
+
const t = B.tmp();
|
|
1577
|
+
if (type.kind === "f64" || type.kind === "date") {
|
|
1578
|
+
this.declare(`declare double @scr_coro_direct_f64(ptr)`);
|
|
1579
|
+
B.line(`${t} = call double @scr_coro_direct_f64(ptr ${record})`);
|
|
1580
|
+
}
|
|
1581
|
+
else if (type.kind === "bool") {
|
|
1582
|
+
this.declare(`declare zeroext i1 @scr_coro_direct_bool(ptr)`);
|
|
1583
|
+
B.line(`${t} = call zeroext i1 @scr_coro_direct_bool(ptr ${record})`);
|
|
1584
|
+
}
|
|
1585
|
+
else if (type.kind === "string") {
|
|
1586
|
+
this.declare(`declare ptr @scr_coro_direct_str(ptr)`);
|
|
1587
|
+
B.line(`${t} = call ptr @scr_coro_direct_str(ptr ${record})`);
|
|
1588
|
+
}
|
|
1589
|
+
else {
|
|
1590
|
+
this.declare(`declare ptr @scr_coro_direct_ref(ptr)`);
|
|
1591
|
+
B.line(`${t} = call ptr @scr_coro_direct_ref(ptr ${record})`);
|
|
1592
|
+
}
|
|
1593
|
+
const out = this.own({ name: this.adoptHeap(t, type), type });
|
|
1594
|
+
this.emitPendingCheck();
|
|
1595
|
+
return out;
|
|
1596
|
+
}
|
|
1400
1597
|
/** The inline await entry of a fiberless async function (`sc_ai_*`): its
|
|
1401
|
-
* body on the caller's stack between scr_async_inline_enter/exit
|
|
1402
|
-
* its spawn wrapper, returning the result and
|
|
1403
|
-
* the awaiting coroutine (emitCoroInlineAwait). */
|
|
1598
|
+
* body on the caller's stack (between scr_async_inline_enter/exit when
|
|
1599
|
+
* fiberlessFrames), as in its spawn wrapper, returning the result and
|
|
1600
|
+
* leaving a throw pending for the awaiting coroutine (emitCoroInlineAwait). */
|
|
1404
1601
|
emitAsyncInlineAwaitCall(fn) {
|
|
1405
1602
|
const retTy = this.llType(fn.returnType);
|
|
1406
1603
|
const params = fn.params.map((p, i) => `${this.llType(p.type)} %a${i}`);
|
|
1407
1604
|
const args = params.join(", ");
|
|
1408
|
-
this.
|
|
1409
|
-
|
|
1605
|
+
const framed = this.fiberlessFrames;
|
|
1606
|
+
if (framed) {
|
|
1607
|
+
this.declare(`declare void @scr_async_inline_enter(ptr)`);
|
|
1608
|
+
this.declare(`declare void @scr_async_inline_exit(ptr)`);
|
|
1609
|
+
}
|
|
1410
1610
|
const bodyCall = `call ${retTy} @${mangleFunction(fn.name)}(${args})`;
|
|
1411
1611
|
return [
|
|
1412
1612
|
`define internal ${retTy} @${mangleAsyncInlineAwaitCall(fn.name)}(${args}) ${FN_ATTRS} { ; inline await ${fn.name}`,
|
|
1413
1613
|
`entry:`,
|
|
1414
|
-
|
|
1415
|
-
|
|
1614
|
+
...(framed
|
|
1615
|
+
? [` %frame = alloca { ptr, ptr }`, ` call void @scr_async_inline_enter(ptr %frame)`]
|
|
1616
|
+
: []),
|
|
1416
1617
|
retTy === "void" ? ` ${bodyCall}` : ` %r = ${bodyCall}`,
|
|
1417
|
-
` call void @scr_async_inline_exit(ptr %frame)
|
|
1618
|
+
...(framed ? [` call void @scr_async_inline_exit(ptr %frame)`] : []),
|
|
1418
1619
|
retTy === "void" ? ` ret void` : ` ret ${retTy} %r`,
|
|
1419
1620
|
`}`,
|
|
1420
1621
|
``,
|
|
@@ -1457,6 +1658,193 @@ export class LlEmitter {
|
|
|
1457
1658
|
this.emitPendingCheck();
|
|
1458
1659
|
return value;
|
|
1459
1660
|
}
|
|
1661
|
+
/** The entries of `Promise.all(arg)` that a stackless coroutine body's
|
|
1662
|
+
* await may run in place (emitCoroInlinePromiseAll): `arg` is a non-empty
|
|
1663
|
+
* array literal, or the local whose declaration emitStmts deferred to this
|
|
1664
|
+
* await (deferredPromiseAllEntries), whose every entry is a call to a
|
|
1665
|
+
* never-suspending async function, and the result is an array. Null
|
|
1666
|
+
* otherwise. Consumes a deferred local's entries. */
|
|
1667
|
+
inlinePromiseAllEntries(all) {
|
|
1668
|
+
if (all.name !== "promise.all" || all.type.kind !== "promise")
|
|
1669
|
+
return null;
|
|
1670
|
+
if (all.type.inner.kind !== "array")
|
|
1671
|
+
return null;
|
|
1672
|
+
const arg = all.args[0];
|
|
1673
|
+
if (arg?.kind === "varRef") {
|
|
1674
|
+
const deferred = this.deferredPromiseAllEntries.get(arg.localId);
|
|
1675
|
+
if (deferred === undefined)
|
|
1676
|
+
return null;
|
|
1677
|
+
this.deferredPromiseAllEntries.delete(arg.localId);
|
|
1678
|
+
return deferred;
|
|
1679
|
+
}
|
|
1680
|
+
return arg?.kind === "arrayLit" && this.promiseAllInlineable(arg) ? arg : null;
|
|
1681
|
+
}
|
|
1682
|
+
/** Whether every entry of `entries` is a call an await could run in place
|
|
1683
|
+
* (inlineAwaitEligible) that yields its promise's inner type. */
|
|
1684
|
+
promiseAllInlineable(entries) {
|
|
1685
|
+
if (entries.elems.length === 0 || (entries.spreads?.length ?? 0) > 0)
|
|
1686
|
+
return false;
|
|
1687
|
+
if (entries.type.kind !== "array" || entries.type.elem.kind !== "promise")
|
|
1688
|
+
return false;
|
|
1689
|
+
const inner = entries.type.elem.inner;
|
|
1690
|
+
return entries.elems.every((el) => {
|
|
1691
|
+
if (el.kind !== "call" || !this.inlineAwaitEligible(el.callee))
|
|
1692
|
+
return false;
|
|
1693
|
+
const callee = this.fnByName.get(el.callee);
|
|
1694
|
+
return typeEquals(callee.returnType, inner) && !this.callLifetimes.borrowed.has(el.callee);
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
/** Whether `stmts[i]` declares a local holding an array literal that only
|
|
1698
|
+
* `stmts[i + 1]` reads, as the operand of `await Promise.all(local)` that
|
|
1699
|
+
* runs first in that statement and may run its entries in place. Nothing
|
|
1700
|
+
* runs between the literal and the await, so the await evaluates the
|
|
1701
|
+
* literal itself (inlinePromiseAllEntries). Debug builds keep the local. */
|
|
1702
|
+
deferredPromiseAllLocal(stmts, i) {
|
|
1703
|
+
const decl = stmts[i];
|
|
1704
|
+
const next = stmts[i + 1];
|
|
1705
|
+
if (this.debug !== null || decl?.kind !== "varDecl" || decl.init?.kind !== "arrayLit")
|
|
1706
|
+
return null;
|
|
1707
|
+
if (this.currentCoro?.kind !== "async" || next === undefined)
|
|
1708
|
+
return null;
|
|
1709
|
+
const operand = next.kind === "varDecl"
|
|
1710
|
+
? next.init
|
|
1711
|
+
: next.kind === "exprStmt"
|
|
1712
|
+
? next.expr
|
|
1713
|
+
: next.kind === "assign"
|
|
1714
|
+
? next.value
|
|
1715
|
+
: null;
|
|
1716
|
+
if (operand?.kind !== "awaitExpr" || operand.adopt === true)
|
|
1717
|
+
return null;
|
|
1718
|
+
const all = operand.value;
|
|
1719
|
+
if (all.kind !== "intrinsic" || all.name !== "promise.all" || all.type.kind !== "promise")
|
|
1720
|
+
return null;
|
|
1721
|
+
if (all.type.inner.kind !== "array")
|
|
1722
|
+
return null;
|
|
1723
|
+
const arg = all.args[0];
|
|
1724
|
+
if (arg?.kind !== "varRef" || arg.localId !== decl.localId)
|
|
1725
|
+
return null;
|
|
1726
|
+
if (!this.promiseAllInlineable(decl.init))
|
|
1727
|
+
return null;
|
|
1728
|
+
if (this.currentLocals.get(decl.localId)?.boxed)
|
|
1729
|
+
return null;
|
|
1730
|
+
// The declaration and this read are the local's only mentions.
|
|
1731
|
+
return countLocalMentions(this.currentFunctionBody, decl.localId) === 2 ? decl.init : null;
|
|
1732
|
+
}
|
|
1733
|
+
/** A stackless coroutine body's `await Promise.all([f(...), ...])` of
|
|
1734
|
+
* never-suspending calls, with Promise.all's turns and without its
|
|
1735
|
+
* promises: the entries run in place in order and their values fill the
|
|
1736
|
+
* result array. Promise.all queues one reaction job per entry, back to
|
|
1737
|
+
* back, and the last of them settles the result, whose await then takes a
|
|
1738
|
+
* turn: here one turn stands for the entries' jobs and a second for the
|
|
1739
|
+
* await. A throwing entry becomes the rejection the await re-throws from
|
|
1740
|
+
* its turn; the remaining entries still run, and later throws are handled
|
|
1741
|
+
* rejections, as Promise.all's subscriptions make them. */
|
|
1742
|
+
emitCoroInlinePromiseAll(entries, type) {
|
|
1743
|
+
if (type.kind !== "array")
|
|
1744
|
+
throw new InternalCompilerError("llvm emitter bug: inline Promise.all result");
|
|
1745
|
+
const B = this.B;
|
|
1746
|
+
const elem = type.elem;
|
|
1747
|
+
const acc = elemAccess(elem);
|
|
1748
|
+
const values = B.tmp();
|
|
1749
|
+
// Up to three values fit in the array's own block (scr_arr_new_*_small).
|
|
1750
|
+
const small = entries.elems.length <= 3;
|
|
1751
|
+
B.line(`${values} = ${arrNewCall(this.shapeHost, elem, small ? "0" : String(entries.elems.length), small)}`);
|
|
1752
|
+
const out = this.own({ name: values, type });
|
|
1753
|
+
this.declare(`declare ptr @scr_promise_new()`);
|
|
1754
|
+
this.declare(`declare void @scr_promise_reject_pending(ptr)`);
|
|
1755
|
+
this.declare(`declare void @scr_promise_mark_handled(ptr)`);
|
|
1756
|
+
const promiseType = entries.type.kind === "array" ? entries.type.elem : type;
|
|
1757
|
+
// Each entry's rejection, owned by the frame: unobserved until the
|
|
1758
|
+
// entries have all run, as Promise.all subscribes only then, so an
|
|
1759
|
+
// entry argument's synchronous throw leaves them unhandled.
|
|
1760
|
+
const rejections = [];
|
|
1761
|
+
for (const entry of entries.elems) {
|
|
1762
|
+
if (entry.kind !== "call")
|
|
1763
|
+
throw new InternalCompilerError("llvm emitter bug: inline Promise.all entry");
|
|
1764
|
+
const slot = B.tmp();
|
|
1765
|
+
B.entryAllocas.push(`${slot} = alloca ptr`);
|
|
1766
|
+
B.line(`store ptr null, ptr ${slot}`);
|
|
1767
|
+
this.ownSlot(slot, promiseType);
|
|
1768
|
+
rejections.push(slot);
|
|
1769
|
+
const value = emitCallExpr(this, entry, "inline");
|
|
1770
|
+
const thrown = B.tmp();
|
|
1771
|
+
for (const line of this.pendingTestLines(thrown))
|
|
1772
|
+
B.line(line.trim());
|
|
1773
|
+
const clean = B.newLabel("pa.clean");
|
|
1774
|
+
const rejected = B.newLabel("pa.rejected");
|
|
1775
|
+
const next = B.newLabel("pa.next");
|
|
1776
|
+
B.condBr(thrown, rejected, clean);
|
|
1777
|
+
B.startBlock(clean);
|
|
1778
|
+
if (acc === "ref")
|
|
1779
|
+
this.toHeap(value);
|
|
1780
|
+
this.arrPush(values, acc, value.name);
|
|
1781
|
+
B.br(next);
|
|
1782
|
+
B.startBlock(rejected);
|
|
1783
|
+
const promise = B.tmp();
|
|
1784
|
+
B.line(`${promise} = call ptr @scr_promise_new()`);
|
|
1785
|
+
B.line(`call void @scr_promise_reject_pending(ptr ${promise})`);
|
|
1786
|
+
B.line(`store ptr ${promise}, ptr ${slot}`);
|
|
1787
|
+
B.br(next);
|
|
1788
|
+
B.startBlock(next);
|
|
1789
|
+
}
|
|
1790
|
+
// Promise.all's subscriptions handle every rejection, and the first
|
|
1791
|
+
// (in entry order) rejects the result.
|
|
1792
|
+
let first = "null";
|
|
1793
|
+
for (let k = rejections.length - 1; k >= 0; k--) {
|
|
1794
|
+
const slot = rejections[k];
|
|
1795
|
+
const rejection = B.tmp();
|
|
1796
|
+
const present = B.tmp();
|
|
1797
|
+
B.line(`${rejection} = load ptr, ptr ${slot}`);
|
|
1798
|
+
B.line(`${present} = icmp ne ptr ${rejection}, null`);
|
|
1799
|
+
const mark = B.newLabel("pa.handled");
|
|
1800
|
+
const after = B.newLabel("pa.unrejected");
|
|
1801
|
+
B.condBr(present, mark, after);
|
|
1802
|
+
B.startBlock(mark);
|
|
1803
|
+
B.line(`call void @scr_promise_mark_handled(ptr ${rejection})`);
|
|
1804
|
+
B.br(after);
|
|
1805
|
+
B.startBlock(after);
|
|
1806
|
+
const chosen = B.tmp();
|
|
1807
|
+
B.line(`${chosen} = select i1 ${present}, ptr ${rejection}, ptr ${first}`);
|
|
1808
|
+
first = chosen;
|
|
1809
|
+
}
|
|
1810
|
+
// The entries' reaction jobs.
|
|
1811
|
+
this.emitCoroAwait(null);
|
|
1812
|
+
const failed = B.tmp();
|
|
1813
|
+
B.line(`${failed} = icmp ne ptr ${first}, null`);
|
|
1814
|
+
const fulfilled = B.newLabel("pa.fulfilled");
|
|
1815
|
+
const rejected = B.newLabel("pa.reject");
|
|
1816
|
+
const join = B.newLabel("pa.join");
|
|
1817
|
+
B.condBr(failed, rejected, fulfilled);
|
|
1818
|
+
B.startBlock(fulfilled);
|
|
1819
|
+
this.emitCoroAwait(null);
|
|
1820
|
+
B.br(join);
|
|
1821
|
+
B.startBlock(rejected);
|
|
1822
|
+
this.declare(`declare void @scr_coro_await_void(ptr)`);
|
|
1823
|
+
this.emitCoroAwait(first);
|
|
1824
|
+
B.line(`call void @scr_coro_await_void(ptr ${first})`);
|
|
1825
|
+
B.br(join);
|
|
1826
|
+
B.startBlock(join);
|
|
1827
|
+
// The rejections are released here, only where an entry threw, rather
|
|
1828
|
+
// than by the frame, which releases each slot whether or not it holds a
|
|
1829
|
+
// promise.
|
|
1830
|
+
this.declare(`declare void @scr_promise_release(ptr)`);
|
|
1831
|
+
for (const slot of rejections) {
|
|
1832
|
+
const rejection = B.tmp();
|
|
1833
|
+
const present = B.tmp();
|
|
1834
|
+
B.line(`${rejection} = load ptr, ptr ${slot}`);
|
|
1835
|
+
B.line(`${present} = icmp ne ptr ${rejection}, null`);
|
|
1836
|
+
const release = B.newLabel("pa.release");
|
|
1837
|
+
const after = B.newLabel("pa.released");
|
|
1838
|
+
B.condBr(present, release, after);
|
|
1839
|
+
B.startBlock(release);
|
|
1840
|
+
B.line(`call void @scr_promise_release(ptr ${rejection})`);
|
|
1841
|
+
B.br(after);
|
|
1842
|
+
B.startBlock(after);
|
|
1843
|
+
}
|
|
1844
|
+
this.disownSlots(rejections.map((ptr) => ({ ptr })));
|
|
1845
|
+
this.emitPendingCheck();
|
|
1846
|
+
return out;
|
|
1847
|
+
}
|
|
1460
1848
|
emitAsyncAwaitCall(fn, argPackLines, adopt = false) {
|
|
1461
1849
|
return emitAsyncAwaitCall(this, fn, argPackLines, adopt);
|
|
1462
1850
|
}
|
|
@@ -1998,8 +2386,10 @@ export class LlEmitter {
|
|
|
1998
2386
|
* releases the dummy (NULL for refcounted kinds) harmlessly. A scalar
|
|
1999
2387
|
* call result of the function's return type may be passed as the unwind's
|
|
2000
2388
|
* dummy value (see emitUnwind). `poll` marks a worker termination poll
|
|
2001
|
-
* (function entry or loop budget), whose test must stay ordered.
|
|
2002
|
-
|
|
2389
|
+
* (function entry or loop budget), whose test must stay ordered. A
|
|
2390
|
+
* `guard` (an i1) limits the test to the paths where it is true: false
|
|
2391
|
+
* where the joined call could not have left anything pending. */
|
|
2392
|
+
emitPendingCheck(passThrough, poll = false, guard) {
|
|
2003
2393
|
const through = passThrough !== undefined &&
|
|
2004
2394
|
this.llType(passThrough.type) === this.llType(this.currentReturnType) &&
|
|
2005
2395
|
(passThrough.type.kind === "f64" || passThrough.type.kind === "bool")
|
|
@@ -2008,6 +2398,13 @@ export class LlEmitter {
|
|
|
2008
2398
|
const B = this.B;
|
|
2009
2399
|
if (B.isTerminated())
|
|
2010
2400
|
return;
|
|
2401
|
+
let skip;
|
|
2402
|
+
if (guard !== undefined) {
|
|
2403
|
+
const test = B.newLabel("exc.t");
|
|
2404
|
+
skip = B.newLabel("exc.n");
|
|
2405
|
+
B.condBr(guard, test, skip);
|
|
2406
|
+
B.startBlock(test);
|
|
2407
|
+
}
|
|
2011
2408
|
if (this.mod.lib !== undefined) {
|
|
2012
2409
|
this.declare(`declare zeroext i1 @scr_exc_pending()`);
|
|
2013
2410
|
const p = B.tmp();
|
|
@@ -2018,6 +2415,10 @@ export class LlEmitter {
|
|
|
2018
2415
|
B.startBlock(lu);
|
|
2019
2416
|
this.emitUnwind(through);
|
|
2020
2417
|
B.startBlock(lk);
|
|
2418
|
+
if (skip !== undefined) {
|
|
2419
|
+
B.br(skip);
|
|
2420
|
+
B.startBlock(skip);
|
|
2421
|
+
}
|
|
2021
2422
|
return;
|
|
2022
2423
|
}
|
|
2023
2424
|
// Executables test the active exception cell's kind inline (its first
|
|
@@ -2094,6 +2495,10 @@ export class LlEmitter {
|
|
|
2094
2495
|
B.startBlock(lu);
|
|
2095
2496
|
this.emitUnwind(through);
|
|
2096
2497
|
B.startBlock(lk);
|
|
2498
|
+
if (skip !== undefined) {
|
|
2499
|
+
B.br(skip);
|
|
2500
|
+
B.startBlock(skip);
|
|
2501
|
+
}
|
|
2097
2502
|
}
|
|
2098
2503
|
/** After a runtime call that ALWAYS leaves an exception pending (the
|
|
2099
2504
|
* compiler-resolved Node throws): the pending test would always answer
|
|
@@ -2641,13 +3046,45 @@ export class LlEmitter {
|
|
|
2641
3046
|
* 1 on hierarchy members, then the flattened field list. Runtime error
|
|
2642
3047
|
* classes GEP through %ScrError (their structs live in the runtime; the
|
|
2643
3048
|
* def's [name, message, %code, %cause] order matches the layout). */
|
|
2644
|
-
classFieldPtr(objName, className, field) {
|
|
3049
|
+
classFieldPtr(objName, className, field, refs = "pointer") {
|
|
2645
3050
|
const meta = this.classMetaOf(className);
|
|
2646
|
-
const { index, type } = classFieldIndex(meta, field);
|
|
3051
|
+
const { index, type, compressed } = classFieldIndex(meta, field, refs);
|
|
2647
3052
|
const p = this.B.tmp();
|
|
2648
3053
|
this.B.line(`${p} = getelementptr inbounds %${classStructSym(className)}, ptr ${objName}, i64 0, i32 ${index}`);
|
|
2649
3054
|
this.markFieldPointer(p, field);
|
|
2650
|
-
|
|
3055
|
+
if (compressed)
|
|
3056
|
+
this.compressedFieldPtrs.add(p);
|
|
3057
|
+
return { ptr: p, type, inline: this.inlineUnions.classField(className, field), compressed };
|
|
3058
|
+
}
|
|
3059
|
+
/** Loads the reference a field pointer addresses: a pointer, or the
|
|
3060
|
+
* decoded 32-bit reference of a compressed field (compressedFieldPtrs).
|
|
3061
|
+
* `tagged`: the load carries the field's alias tags. */
|
|
3062
|
+
loadRef(ptr, tagged = true) {
|
|
3063
|
+
const B = this.B;
|
|
3064
|
+
const v = B.tmp();
|
|
3065
|
+
const tags = tagged ? this.fieldAliasAttachment(ptr) : "";
|
|
3066
|
+
if (!this.compressedFieldPtrs.has(ptr)) {
|
|
3067
|
+
B.line(`${v} = load ptr, ptr ${ptr}${tags}`);
|
|
3068
|
+
return v;
|
|
3069
|
+
}
|
|
3070
|
+
const idx = B.tmp();
|
|
3071
|
+
B.line(`${idx} = load i32, ptr ${ptr}${tags}`);
|
|
3072
|
+
for (const line of compactRefLoadLines(idx, v, `${v}.r`))
|
|
3073
|
+
B.line(line.trimStart());
|
|
3074
|
+
return v;
|
|
3075
|
+
}
|
|
3076
|
+
/** Stores `value` (a pointer) through a field pointer: as is, or encoded
|
|
3077
|
+
* as the 32-bit reference of a compressed field. */
|
|
3078
|
+
storeRef(ptr, value) {
|
|
3079
|
+
const B = this.B;
|
|
3080
|
+
if (!this.compressedFieldPtrs.has(ptr)) {
|
|
3081
|
+
B.line(`store ptr ${value}, ptr ${ptr}${this.fieldAliasAttachment(ptr)}`);
|
|
3082
|
+
return;
|
|
3083
|
+
}
|
|
3084
|
+
const idx = B.tmp();
|
|
3085
|
+
for (const line of compactRefStoreLines(value, idx, `${idx}.r`))
|
|
3086
|
+
B.line(line.trimStart());
|
|
3087
|
+
B.line(`store i32 ${idx}, ptr ${ptr}${this.fieldAliasAttachment(ptr)}`);
|
|
2651
3088
|
}
|
|
2652
3089
|
/** The dynamic class's preorder number (borrowed object; the static class
|
|
2653
3090
|
* names the struct spelling and where the number is, classPreLines). */
|
|
@@ -2754,6 +3191,8 @@ export class LlEmitter {
|
|
|
2754
3191
|
const { tag, bits } = loadInlineUnion(B, ptr);
|
|
2755
3192
|
return stackUnionBox(B, this.sizeType, tag, bits);
|
|
2756
3193
|
}
|
|
3194
|
+
if (this.compressedFieldPtrs.has(ptr))
|
|
3195
|
+
return this.loadRef(ptr);
|
|
2757
3196
|
const fieldTy = llFieldType(t, false);
|
|
2758
3197
|
const raw = B.tmp();
|
|
2759
3198
|
B.line(`${raw} = load ${fieldTy}, ptr ${ptr}${this.fieldAliasAttachment(ptr)}`);
|
|
@@ -2778,8 +3217,7 @@ export class LlEmitter {
|
|
|
2778
3217
|
replaceField(ptr, type, inline, v) {
|
|
2779
3218
|
if (!inline && isRefCounted(type)) {
|
|
2780
3219
|
this.toHeap(v);
|
|
2781
|
-
const old = this.
|
|
2782
|
-
this.B.line(`${old} = load ptr, ptr ${ptr}`);
|
|
3220
|
+
const old = this.loadRef(ptr, false);
|
|
2783
3221
|
this.storeField(ptr, type, v.name, false);
|
|
2784
3222
|
this.releaseHeap(old, type);
|
|
2785
3223
|
return;
|
|
@@ -2802,6 +3240,10 @@ export class LlEmitter {
|
|
|
2802
3240
|
storeInlineUnion(B, ptr, tag, bits);
|
|
2803
3241
|
return;
|
|
2804
3242
|
}
|
|
3243
|
+
if (this.compressedFieldPtrs.has(ptr)) {
|
|
3244
|
+
this.storeRef(ptr, value);
|
|
3245
|
+
return;
|
|
3246
|
+
}
|
|
2805
3247
|
const fieldTy = llFieldType(t, false);
|
|
2806
3248
|
if (fieldTy !== "i8") {
|
|
2807
3249
|
B.line(`store ${fieldTy} ${value}, ptr ${ptr}${this.fieldAliasAttachment(ptr)}`);
|
|
@@ -2868,6 +3310,8 @@ export class LlEmitter {
|
|
|
2868
3310
|
ranges: this.integerRanges,
|
|
2869
3311
|
initialized,
|
|
2870
3312
|
proven: this.bytesBounds,
|
|
3313
|
+
workers: this.mod.workers === true,
|
|
3314
|
+
owned: this.bytesOwned,
|
|
2871
3315
|
});
|
|
2872
3316
|
}
|
|
2873
3317
|
/** The alias tag of a whole-slot load of a binding (module globals only). */
|
|
@@ -2907,6 +3351,24 @@ export class LlEmitter {
|
|
|
2907
3351
|
this.B.line(`${b} = load ptr, ptr ${slot}`);
|
|
2908
3352
|
return b;
|
|
2909
3353
|
}
|
|
3354
|
+
/** The function a call through `callee` is known to reach (a literal
|
|
3355
|
+
* closure, or a binding the constant-callback census resolves) and the
|
|
3356
|
+
* entry it calls directly. Async and generator functions stay indirect. */
|
|
3357
|
+
knownCallbackTarget(callee) {
|
|
3358
|
+
const knownName = callee.kind === "closure"
|
|
3359
|
+
? callee.fnName
|
|
3360
|
+
: callee.kind === "varRef"
|
|
3361
|
+
? this.currentConstantCallbacks.get(callee.localId)
|
|
3362
|
+
: undefined;
|
|
3363
|
+
const known = knownName ? this.fnByName.get(knownName) : undefined;
|
|
3364
|
+
if (!known || known.async || known.generator)
|
|
3365
|
+
return undefined;
|
|
3366
|
+
if (known.captures === undefined) {
|
|
3367
|
+
this.fnValues.add(known.name);
|
|
3368
|
+
return { known, direct: `@${mangleWrapper(known.name)}` };
|
|
3369
|
+
}
|
|
3370
|
+
return { known, direct: `@${this.callTarget(known.name)}` };
|
|
3371
|
+
}
|
|
2910
3372
|
/** The payload slot of a capture box (ScrBox.slot, field 5). */
|
|
2911
3373
|
boxSlot(box) {
|
|
2912
3374
|
const slot = this.B.tmp();
|
|
@@ -2919,13 +3381,15 @@ export class LlEmitter {
|
|
|
2919
3381
|
const r = B.tmp();
|
|
2920
3382
|
// Scalar payloads are read in place (scr_box_get_f64/bool are a
|
|
2921
3383
|
// memcpy and a nonzero test of the same slot), so LLVM can keep a
|
|
2922
|
-
// captured number in a register across a loop of calls.
|
|
3384
|
+
// captured number in a register across a loop of calls. They have an
|
|
3385
|
+
// alias category of their own: every other access to a box's payload
|
|
3386
|
+
// is untagged or a runtime call.
|
|
2923
3387
|
if (acc === "f64") {
|
|
2924
|
-
B.line(`${r} = load double, ptr ${this.boxSlot(box)}`);
|
|
3388
|
+
B.line(`${r} = load double, ptr ${this.boxSlot(box)}${this.memoryAliasAttachment("box:scalar")}`);
|
|
2925
3389
|
}
|
|
2926
3390
|
else if (acc === "bool") {
|
|
2927
3391
|
const raw = B.tmp();
|
|
2928
|
-
B.line(`${raw} = load i64, ptr ${this.boxSlot(box)}`);
|
|
3392
|
+
B.line(`${raw} = load i64, ptr ${this.boxSlot(box)}${this.memoryAliasAttachment("box:scalar")}`);
|
|
2929
3393
|
B.line(`${r} = icmp ne i64 ${raw}, 0`);
|
|
2930
3394
|
}
|
|
2931
3395
|
else {
|
|
@@ -2939,12 +3403,12 @@ export class LlEmitter {
|
|
|
2939
3403
|
const B = this.B;
|
|
2940
3404
|
const acc = boxAccess(t);
|
|
2941
3405
|
if (acc === "f64") {
|
|
2942
|
-
B.line(`store double ${value}, ptr ${this.boxSlot(box)}`);
|
|
3406
|
+
B.line(`store double ${value}, ptr ${this.boxSlot(box)}${this.memoryAliasAttachment("box:scalar")}`);
|
|
2943
3407
|
}
|
|
2944
3408
|
else if (acc === "bool") {
|
|
2945
3409
|
const raw = B.tmp();
|
|
2946
3410
|
B.line(`${raw} = zext i1 ${value} to i64`);
|
|
2947
|
-
B.line(`store i64 ${raw}, ptr ${this.boxSlot(box)}`);
|
|
3411
|
+
B.line(`store i64 ${raw}, ptr ${this.boxSlot(box)}${this.memoryAliasAttachment("box:scalar")}`);
|
|
2948
3412
|
}
|
|
2949
3413
|
else {
|
|
2950
3414
|
this.declare(`declare void @scr_box_set_ref(ptr, ptr)`);
|
|
@@ -3833,6 +4297,11 @@ export class LlEmitter {
|
|
|
3833
4297
|
if (cursor)
|
|
3834
4298
|
cursor.index = i;
|
|
3835
4299
|
this.stmtCursor = cursor;
|
|
4300
|
+
const deferred = this.deferredPromiseAllLocal(stmts, i);
|
|
4301
|
+
if (deferred !== null) {
|
|
4302
|
+
this.deferredPromiseAllEntries.set(stmts[i].localId, deferred);
|
|
4303
|
+
continue;
|
|
4304
|
+
}
|
|
3836
4305
|
this.emitStmt(stmts[i]);
|
|
3837
4306
|
}
|
|
3838
4307
|
}
|
|
@@ -4376,14 +4845,16 @@ export class LlEmitter {
|
|
|
4376
4845
|
post: meta.post,
|
|
4377
4846
|
runtimeRooted: meta.root.def.runtime === true,
|
|
4378
4847
|
idInRc: meta.idInRc,
|
|
4848
|
+
compact: meta.compact,
|
|
4379
4849
|
// Inline scalar-union fields are plain bits: nothing to push.
|
|
4380
4850
|
fields: meta.def.fields.flatMap((f) => this.inlineUnions.classField(className, f.name)
|
|
4381
4851
|
? []
|
|
4382
4852
|
: [
|
|
4383
4853
|
{
|
|
4384
4854
|
name: f.name,
|
|
4385
|
-
index: classFieldIndex(meta, f.name).index,
|
|
4855
|
+
index: classFieldIndex(meta, f.name, "compressed").index,
|
|
4386
4856
|
type: this.nullableFields.storageType(className, f.name, f.type),
|
|
4857
|
+
compressed: classFieldIndex(meta, f.name, "compressed").compressed,
|
|
4387
4858
|
},
|
|
4388
4859
|
]),
|
|
4389
4860
|
};
|
|
@@ -4414,13 +4885,20 @@ export class LlEmitter {
|
|
|
4414
4885
|
}
|
|
4415
4886
|
/** Branches on "`obj` is published" (rc == SIZE_MAX, or a count of
|
|
4416
4887
|
* UINT32_MAX in the low half for `count` i32: classes.ts
|
|
4417
|
-
* LlClassMeta.idInRc
|
|
4418
|
-
* the
|
|
4888
|
+
* LlClassMeta.idInRc, or the top bit of a compact header word for
|
|
4889
|
+
* "compact": classes.ts COMPACT_PUBLISHED); leaves the builder in the cold
|
|
4890
|
+
* block and answers the continuation label. */
|
|
4419
4891
|
emitPublishedTest(obj, count = this.sizeType) {
|
|
4420
4892
|
const B = this.B;
|
|
4421
4893
|
const rc = B.tmp(), frozen = B.tmp(), expected = B.tmp();
|
|
4422
|
-
|
|
4423
|
-
|
|
4894
|
+
if (count === "compact") {
|
|
4895
|
+
B.line(`${rc} = load i32, ptr ${obj}`);
|
|
4896
|
+
B.line(`${frozen} = icmp slt i32 ${rc}, 0`);
|
|
4897
|
+
}
|
|
4898
|
+
else {
|
|
4899
|
+
B.line(`${rc} = load ${count}, ptr ${obj}`);
|
|
4900
|
+
B.line(`${frozen} = icmp eq ${count} ${rc}, -1`);
|
|
4901
|
+
}
|
|
4424
4902
|
this.declare(`declare i1 @llvm.expect.i1(i1, i1)`);
|
|
4425
4903
|
B.line(`${expected} = call i1 @llvm.expect.i1(i1 ${frozen}, i1 false)`);
|
|
4426
4904
|
const cold = B.newLabel("pub.frozen"), ok = B.newLabel("pub.ok");
|
|
@@ -4461,7 +4939,7 @@ export class LlEmitter {
|
|
|
4461
4939
|
return;
|
|
4462
4940
|
const B = this.B;
|
|
4463
4941
|
const meta = className === null ? undefined : this.classMeta.get(className);
|
|
4464
|
-
const ok = this.emitPublishedTest(obj, meta?.idInRc === true ? "i32" : this.sizeType);
|
|
4942
|
+
const ok = this.emitPublishedTest(obj, meta?.compact === true ? "compact" : meta?.idInRc === true ? "i32" : this.sizeType);
|
|
4465
4943
|
let owner;
|
|
4466
4944
|
if (meta === undefined)
|
|
4467
4945
|
owner = this.cstr("Object");
|
|
@@ -4556,11 +5034,9 @@ export class LlEmitter {
|
|
|
4556
5034
|
const nullable = this.nullableFieldGet(e);
|
|
4557
5035
|
if (!nullable || e.kind !== "fieldGet")
|
|
4558
5036
|
return this.emitReadReceiver(e);
|
|
4559
|
-
const B = this.B;
|
|
4560
5037
|
const receiver = this.emitReadReceiver(e.obj);
|
|
4561
|
-
const { ptr } = this.classFieldPtr(receiver.name, e.className, e.field);
|
|
4562
|
-
const p =
|
|
4563
|
-
B.line(`${p} = load ptr, ptr ${ptr}${this.fieldAliasAttachment(ptr)}`);
|
|
5038
|
+
const { ptr } = this.classFieldPtr(receiver.name, e.className, e.field, "compressed");
|
|
5039
|
+
const p = this.loadRef(ptr);
|
|
4564
5040
|
return { name: this.stackNullableBox(p, nullable), type: e.type };
|
|
4565
5041
|
}
|
|
4566
5042
|
/** A private stack box over a nullable-pointer field read whose payload
|
|
@@ -4572,9 +5048,8 @@ export class LlEmitter {
|
|
|
4572
5048
|
if (!nullable || e.kind !== "fieldGet")
|
|
4573
5049
|
throw new InternalCompilerError("llvm emitter bug: owned nullable stack of non-field");
|
|
4574
5050
|
const receiver = this.emitReadReceiver(e.obj);
|
|
4575
|
-
const { ptr } = this.classFieldPtr(receiver.name, e.className, e.field);
|
|
4576
|
-
const p = this.
|
|
4577
|
-
this.B.line(`${p} = load ptr, ptr ${ptr}${this.fieldAliasAttachment(ptr)}`);
|
|
5051
|
+
const { ptr } = this.classFieldPtr(receiver.name, e.className, e.field, "compressed");
|
|
5052
|
+
const p = this.loadRef(ptr);
|
|
4578
5053
|
const owner = this.own({ name: this.retainFrame(p, nullable.arm), type: nullable.arm });
|
|
4579
5054
|
return { box: this.stackNullableBox(owner.name, nullable), owner };
|
|
4580
5055
|
}
|
|
@@ -4635,7 +5110,6 @@ export class LlEmitter {
|
|
|
4635
5110
|
* retained payload of a borrowed box otherwise. Unlink-then-release like
|
|
4636
5111
|
* every field store. */
|
|
4637
5112
|
emitNullableFieldStore(obj, className, field, nullable, value) {
|
|
4638
|
-
const B = this.B;
|
|
4639
5113
|
let next;
|
|
4640
5114
|
if (value.kind === "unionWrap" &&
|
|
4641
5115
|
value.unionId === nullable.unionId &&
|
|
@@ -4660,10 +5134,9 @@ export class LlEmitter {
|
|
|
4660
5134
|
else {
|
|
4661
5135
|
next = this.unionToNullable(this.emitUnionProjection(value).name, nullable);
|
|
4662
5136
|
}
|
|
4663
|
-
const { ptr } = this.classFieldPtr(obj, className, field);
|
|
4664
|
-
const old =
|
|
4665
|
-
|
|
4666
|
-
B.line(`store ptr ${next}, ptr ${ptr}${this.fieldAliasAttachment(ptr)}`);
|
|
5137
|
+
const { ptr } = this.classFieldPtr(obj, className, field, "compressed");
|
|
5138
|
+
const old = this.loadRef(ptr, false);
|
|
5139
|
+
this.storeRef(ptr, next);
|
|
4667
5140
|
this.releaseHeap(old, nullable.arm);
|
|
4668
5141
|
}
|
|
4669
5142
|
/** A union binding whose slot may hold a private stack box: stack locals
|
|
@@ -4903,8 +5376,8 @@ export class LlEmitter {
|
|
|
4903
5376
|
emitBytesLength(elem, receiver, bytes) {
|
|
4904
5377
|
return emitBytesLength(this, elem, receiver, bytes);
|
|
4905
5378
|
}
|
|
4906
|
-
emitBytesGet(elem, receiver, index, expr, inBounds = false, invalidNaN = false) {
|
|
4907
|
-
return emitBytesGet(this, elem, receiver, index, expr, inBounds, invalidNaN);
|
|
5379
|
+
emitBytesGet(elem, receiver, index, expr, inBounds = false, invalidNaN = false, owned = false) {
|
|
5380
|
+
return emitBytesGet(this, elem, receiver, index, expr, inBounds, invalidNaN, owned);
|
|
4908
5381
|
}
|
|
4909
5382
|
emitToUint32(value, expr, uint32) {
|
|
4910
5383
|
return emitToUint32(this, value, expr, uint32);
|
|
@@ -4959,8 +5432,8 @@ export class LlEmitter {
|
|
|
4959
5432
|
const integer = this.emitToUint32(value.name, expr, value.uint32);
|
|
4960
5433
|
this.B.line(`store i32 ${integer}, ptr ${slot}`);
|
|
4961
5434
|
}
|
|
4962
|
-
emitBytesSet(elem, receiver, index, value, indexExpr, expr, inBounds = false) {
|
|
4963
|
-
return emitBytesSet(this, elem, receiver, index, value, indexExpr, expr, inBounds);
|
|
5435
|
+
emitBytesSet(elem, receiver, index, value, indexExpr, expr, inBounds = false, owned = false) {
|
|
5436
|
+
return emitBytesSet(this, elem, receiver, index, value, indexExpr, expr, inBounds, owned);
|
|
4964
5437
|
}
|
|
4965
5438
|
emitBytesIntrinsic(e) {
|
|
4966
5439
|
return emitBytesIntrinsic(this, e);
|