@scriptc/compiler 0.2.7 → 0.2.9
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 +3 -0
- package/dist/backend/cycle-analysis.js +50 -17
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +138 -14
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.d.ts +31 -6
- package/dist/backend/cycle-mutability.js +120 -18
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +16 -3
- package/dist/backend/llvm/alloc.js +78 -23
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +5 -5
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/blocks.d.ts +9 -0
- package/dist/backend/llvm/blocks.js +9 -0
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/borrowed-receivers.d.ts +7 -0
- package/dist/backend/llvm/borrowed-receivers.js +39 -0
- package/dist/backend/llvm/borrowed-receivers.js.map +1 -1
- package/dist/backend/llvm/byte-numbers.js +2 -3
- package/dist/backend/llvm/byte-numbers.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.d.ts +4 -1
- package/dist/backend/llvm/call-lifetimes.js +14 -3
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +8 -3
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.d.ts +24 -0
- package/dist/backend/llvm/checked-narrows.js +108 -0
- package/dist/backend/llvm/checked-narrows.js.map +1 -0
- package/dist/backend/llvm/checked-narrows.test.d.ts +1 -0
- package/dist/backend/llvm/checked-narrows.test.js +208 -0
- package/dist/backend/llvm/checked-narrows.test.js.map +1 -0
- package/dist/backend/llvm/classes.d.ts +13 -1
- package/dist/backend/llvm/classes.js +32 -23
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +32 -3
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +17 -0
- package/dist/backend/llvm/common.js +28 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/debug-info.d.ts +6 -2
- package/dist/backend/llvm/debug-info.js +11 -1
- package/dist/backend/llvm/debug-info.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.js +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +89 -0
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +8 -4
- package/dist/backend/llvm/dyn.js +58 -31
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +227 -12
- package/dist/backend/llvm/emitter.js +1492 -169
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +54 -1
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +4 -4
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -1
- package/dist/backend/llvm/expr-bytes.js +116 -32
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.js +29 -21
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +5 -0
- package/dist/backend/llvm/expr-calls.js +55 -10
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +7 -1
- package/dist/backend/llvm/expr-containers.js +231 -28
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +2 -0
- package/dist/backend/llvm/expr-control.js +70 -14
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +75 -21
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-island.js +3 -8
- package/dist/backend/llvm/expr-island.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +41 -12
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +50 -2
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +28 -14
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +3 -0
- package/dist/backend/llvm/expr-stream-bridges.js +114 -42
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.js +6 -3
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/layouts.d.ts +2 -1
- package/dist/backend/llvm/layouts.js +2 -2
- package/dist/backend/llvm/layouts.js.map +1 -1
- package/dist/backend/llvm/lib-abi.js +10 -0
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +25 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +8 -8
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +2 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +17 -6
- package/dist/backend/llvm/local-array-reads.js +223 -51
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +7 -3
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.js +10 -6
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +3 -2
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.d.ts +18 -0
- package/dist/backend/llvm/map-number-lookup.js +62 -0
- package/dist/backend/llvm/map-number-lookup.js.map +1 -0
- package/dist/backend/llvm/map-read-lifetimes.d.ts +6 -0
- package/dist/backend/llvm/map-read-lifetimes.js +24 -3
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +38 -19
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.d.ts +68 -0
- package/dist/backend/llvm/nullable-unions.js +132 -0
- package/dist/backend/llvm/nullable-unions.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +58 -0
- package/dist/backend/llvm/publish.js +286 -0
- package/dist/backend/llvm/publish.js.map +1 -0
- package/dist/backend/llvm/rebound-parameters.d.ts +12 -0
- package/dist/backend/llvm/rebound-parameters.js +72 -0
- package/dist/backend/llvm/rebound-parameters.js.map +1 -0
- package/dist/backend/llvm/rebound-parameters.test.d.ts +1 -0
- package/dist/backend/llvm/rebound-parameters.test.js +67 -0
- package/dist/backend/llvm/rebound-parameters.test.js.map +1 -0
- package/dist/backend/llvm/reference-effects.d.ts +18 -2
- package/dist/backend/llvm/reference-effects.js +140 -17
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-effects.test.js +52 -1
- package/dist/backend/llvm/reference-effects.test.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +58 -19
- package/dist/backend/llvm/shapes.js +171 -62
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +36 -11
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +5 -2
- package/dist/backend/llvm/stack-unions.test.js.map +1 -1
- package/dist/backend/llvm/string-construction.d.ts +10 -0
- package/dist/backend/llvm/string-construction.js +42 -0
- package/dist/backend/llvm/string-construction.js.map +1 -1
- package/dist/backend/llvm/string-key-hash.d.ts +9 -2
- package/dist/backend/llvm/string-key-hash.js +20 -3
- package/dist/backend/llvm/string-key-hash.js.map +1 -1
- package/dist/backend/llvm/string-key-hash.test.js +14 -3
- package/dist/backend/llvm/string-key-hash.test.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +24 -11
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +7 -0
- package/dist/backend/llvm/string-reads.js +79 -0
- package/dist/backend/llvm/string-reads.js.map +1 -0
- package/dist/backend/llvm/string-slices.js +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
- package/dist/backend/llvm/test-boxed-unions.d.ts +5 -0
- package/dist/backend/llvm/test-boxed-unions.js +13 -0
- package/dist/backend/llvm/test-boxed-unions.js.map +1 -0
- package/dist/backend/llvm/trunc.d.ts +8 -0
- package/dist/backend/llvm/trunc.js +28 -0
- package/dist/backend/llvm/trunc.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +15 -0
- package/dist/backend/llvm/union-repr.js +89 -0
- package/dist/backend/llvm/union-repr.js.map +1 -0
- package/dist/backend/llvm/virtual-borrows.d.ts +31 -0
- package/dist/backend/llvm/virtual-borrows.js +82 -0
- package/dist/backend/llvm/virtual-borrows.js.map +1 -0
- package/dist/backend/llvm/walk-borrows.d.ts +43 -0
- package/dist/backend/llvm/walk-borrows.js +150 -0
- package/dist/backend/llvm/walk-borrows.js.map +1 -0
- package/dist/backend/llvm/walk-borrows.test.d.ts +1 -0
- package/dist/backend/llvm/walk-borrows.test.js +119 -0
- package/dist/backend/llvm/walk-borrows.test.js.map +1 -0
- package/dist/backend/llvm/walkers.d.ts +5 -1
- package/dist/backend/llvm/walkers.js +24 -21
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/loop-polls.d.ts +14 -0
- package/dist/backend/loop-polls.js +100 -0
- package/dist/backend/loop-polls.js.map +1 -0
- package/dist/backend/loop-polls.test.d.ts +1 -0
- package/dist/backend/loop-polls.test.js +86 -0
- package/dist/backend/loop-polls.test.js.map +1 -0
- package/dist/backend/may-throw.d.ts +29 -1
- package/dist/backend/may-throw.js +365 -3
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +136 -1
- package/dist/backend/may-throw.test.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +7 -5
- package/dist/backend/native-codegen-core.js +14 -9
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +2 -0
- package/dist/backend/native-codegen.js +21 -2
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +41 -10
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-tools.d.ts +2 -0
- package/dist/backend/native-tools.js +3 -0
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/publication.d.ts +28 -0
- package/dist/backend/publication.js +155 -0
- package/dist/backend/publication.js.map +1 -0
- package/dist/backend/publication.test.d.ts +1 -0
- package/dist/backend/publication.test.js +72 -0
- package/dist/backend/publication.test.js.map +1 -0
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-abi.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +1 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/cli/command.js +78 -8
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/output-options.d.ts +1 -0
- package/dist/cli/output-options.js +3 -0
- package/dist/cli/output-options.js.map +1 -1
- package/dist/cli/usage.d.ts +8 -1
- package/dist/cli/usage.js +14 -1
- package/dist/cli/usage.js.map +1 -1
- package/dist/compile-types.d.ts +17 -3
- package/dist/coverage/report.d.ts +25 -2
- package/dist/coverage/report.js +161 -33
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +63 -0
- package/dist/coverage/verdict-cache.js +193 -0
- package/dist/coverage/verdict-cache.js.map +1 -0
- package/dist/coverage/verdict-cache.test.d.ts +1 -0
- package/dist/coverage/verdict-cache.test.js +52 -0
- package/dist/coverage/verdict-cache.test.js.map +1 -0
- package/dist/coverage/verdict-semantic.d.ts +2 -0
- package/dist/coverage/verdict-semantic.js +24 -0
- package/dist/coverage/verdict-semantic.js.map +1 -0
- package/dist/coverage/verdict-startup.d.ts +15 -0
- package/dist/coverage/verdict-startup.js +66 -0
- package/dist/coverage/verdict-startup.js.map +1 -0
- package/dist/diagnostics/diagnostic.d.ts +29 -1
- package/dist/diagnostics/diagnostic.js +74 -4
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +130 -0
- package/dist/diagnostics/envelope.js +257 -0
- package/dist/diagnostics/envelope.js.map +1 -0
- package/dist/diagnostics/envelope.test.d.ts +1 -0
- package/dist/diagnostics/envelope.test.js +91 -0
- package/dist/diagnostics/envelope.test.js.map +1 -0
- package/dist/diagnostics/render.d.ts +3 -0
- package/dist/diagnostics/render.js +13 -2
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +2 -0
- package/dist/executable/executable-cache.js +3 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +1 -0
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.d.ts +4 -0
- package/dist/executable/prepare.js +7 -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/lowering/array-values.d.ts +7 -0
- package/dist/frontend/lowering/array-values.js +157 -5
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtins/numbers.js +29 -1
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +4 -0
- package/dist/frontend/lowering/builtins/process.js +10 -0
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/strings.js +4 -1
- package/dist/frontend/lowering/builtins/strings.js.map +1 -1
- package/dist/frontend/lowering/builtins/workers.js +4 -2
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +96 -4
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/class-assertions.d.ts +8 -0
- package/dist/frontend/lowering/class-assertions.js +217 -1
- package/dist/frontend/lowering/class-assertions.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.js +8 -5
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +88 -0
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/coercions/state.d.ts +6 -0
- package/dist/frontend/lowering/coercions/state.js +2 -0
- package/dist/frontend/lowering/coercions/state.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +8 -0
- package/dist/frontend/lowering/coercions/unions.js +67 -2
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collation-repertoire.d.ts +1 -0
- package/dist/frontend/lowering/collation-repertoire.js +19 -0
- package/dist/frontend/lowering/collation-repertoire.js.map +1 -0
- package/dist/frontend/lowering/construction-escapes.d.ts +38 -0
- package/dist/frontend/lowering/construction-escapes.js +146 -0
- package/dist/frontend/lowering/construction-escapes.js.map +1 -0
- package/dist/frontend/lowering/construction-escapes.test.d.ts +1 -0
- package/dist/frontend/lowering/construction-escapes.test.js +150 -0
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +81 -44
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +15 -2
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +231 -12
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +15 -4
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +43 -1
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +7 -63
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +6 -1
- package/dist/frontend/lowering/cycle-initialization.js +59 -33
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +9 -0
- package/dist/frontend/lowering/divergences.js +630 -0
- package/dist/frontend/lowering/divergences.js.map +1 -0
- package/dist/frontend/lowering/expressions/object-literals.js +40 -2
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-fields.d.ts +19 -0
- package/dist/frontend/lowering/expressions/union-fields.js +236 -0
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -0
- package/dist/frontend/lowering/lower-calls.d.ts +5 -0
- package/dist/frontend/lowering/lower-calls.js +237 -158
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +4 -0
- package/dist/frontend/lowering/lower-classes.js +72 -22
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +19 -0
- package/dist/frontend/lowering/lower-exprs.js +592 -109
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +19 -13
- package/dist/frontend/lowering/lower-generators.js +67 -44
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +3 -2
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +1 -1
- package/dist/frontend/lowering/lower-island.js +10 -7
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +90 -1
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +47 -7
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +83 -2
- package/dist/frontend/lowering/lowerer.js +1158 -79
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +161 -0
- package/dist/frontend/lowering/nan-coded-reads.js +1342 -0
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.d.ts +31 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +360 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.d.ts +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.js +94 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-elements.d.ts +117 -0
- package/dist/frontend/lowering/runtime-optional-elements.js +738 -0
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-guards.d.ts +36 -0
- package/dist/frontend/lowering/runtime-optional-guards.js +375 -0
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-guards.test.d.ts +1 -0
- package/dist/frontend/lowering/runtime-optional-guards.test.js +92 -0
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-ownership.d.ts +63 -0
- package/dist/frontend/lowering/runtime-optional-ownership.js +382 -0
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-provenance.d.ts +2 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js +2 -1
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/string-index-bounds.d.ts +36 -0
- package/dist/frontend/lowering/string-index-bounds.js +537 -0
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.test.d.ts +1 -0
- package/dist/frontend/lowering/string-index-bounds.test.js +223 -0
- package/dist/frontend/lowering/string-index-bounds.test.js.map +1 -0
- package/dist/frontend/lowering/surfaces.js +8 -0
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/union-narrow.d.ts +2 -0
- package/dist/frontend/lowering/union-narrow.js +10 -6
- package/dist/frontend/lowering/union-narrow.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +10 -0
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +25 -0
- package/dist/frontend/program.js +613 -17
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +64 -1
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.d.ts +6 -0
- package/dist/frontend/resolve.js +14 -0
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/threads-import.d.ts +5 -0
- package/dist/frontend/threads-import.js +21 -0
- package/dist/frontend/threads-import.js.map +1 -0
- package/dist/frontend/type-mapper.d.ts +3 -0
- package/dist/frontend/type-mapper.js +72 -6
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/worker-target.d.ts +4 -0
- package/dist/frontend/worker-target.js +8 -1
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +67 -17
- package/dist/index.js.map +1 -1
- package/dist/ir/build.d.ts +5 -0
- package/dist/ir/build.js +7 -0
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +5 -0
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/constant-globals.d.ts +14 -0
- package/dist/ir/constant-globals.js +81 -0
- package/dist/ir/constant-globals.js.map +1 -0
- package/dist/ir/constant-globals.test.d.ts +1 -0
- package/dist/ir/constant-globals.test.js +97 -0
- package/dist/ir/constant-globals.test.js.map +1 -0
- package/dist/ir/final-fields.d.ts +35 -0
- package/dist/ir/final-fields.js +187 -0
- package/dist/ir/final-fields.js.map +1 -0
- package/dist/ir/final-fields.test.d.ts +1 -0
- package/dist/ir/final-fields.test.js +106 -0
- package/dist/ir/final-fields.test.js.map +1 -0
- package/dist/ir/int32-slots.d.ts +81 -0
- package/dist/ir/int32-slots.js +850 -0
- package/dist/ir/int32-slots.js.map +1 -0
- package/dist/ir/int32-slots.test.d.ts +1 -0
- package/dist/ir/int32-slots.test.js +249 -0
- package/dist/ir/int32-slots.test.js.map +1 -0
- package/dist/ir/integer-loops.d.ts +5 -0
- package/dist/ir/integer-loops.js +20 -4
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +17 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +19 -3
- package/dist/ir/integer-ranges.js +168 -23
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +74 -2
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/ir.d.ts +30 -7
- package/dist/ir/ir.js +4 -0
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/serialize.d.ts +12 -2
- package/dist/ir/serialize.js +190 -39
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +65 -1
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/validate.js +21 -2
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +39 -0
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/native/cache.d.ts +11 -1
- package/dist/native/cache.js +87 -2
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cache.test.js +32 -1
- package/dist/native/cache.test.js.map +1 -1
- package/dist/native/cli.js +1 -1
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.d.ts +5 -0
- package/dist/native/compiler.js +55 -7
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/prepare.d.ts +7 -1
- package/dist/native/prepare.js +65 -29
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +23 -1
- package/dist/native/prepare.test.js.map +1 -1
- package/dist/native/text-file.d.ts +10 -0
- package/dist/native/text-file.js +41 -0
- package/dist/native/text-file.js.map +1 -0
- package/dist/startup-cache.d.ts +2 -0
- package/dist/startup-cache.js +2 -0
- package/dist/startup-cache.js.map +1 -1
- package/dist/text-parts.d.ts +5 -0
- package/dist/text-parts.js +36 -0
- package/dist/text-parts.js.map +1 -0
- package/package.json +20 -20
- package/surface-manifest.json +7 -1
- package/dist/frontend/lowering/expressions/union-field-write.d.ts +0 -8
- package/dist/frontend/lowering/expressions/union-field-write.js +0 -108
- package/dist/frontend/lowering/expressions/union-field-write.js.map +0 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* Inline UTF-16 reads of proven-ASCII strings.
|
|
2
|
+
*
|
|
3
|
+
* Strings are UTF-8, so `length` and `charCodeAt` need a UTF-16 mapping in
|
|
4
|
+
* general. Bit 31 of a string's capacity word (SCR_STR_ASCII_BIT in
|
|
5
|
+
* scr_runtime.h) proves every byte is ASCII, where units are bytes. Sites
|
|
6
|
+
* call the internal sc_str_* helpers below, which LLVM inlines: the proven
|
|
7
|
+
* case is a header load and, for charCodeAt, one byte load; every other
|
|
8
|
+
* string or index defers to the runtime function, which keeps the complete
|
|
9
|
+
* semantics (surrogate halves, out-of-range NaN, fractional, negative and
|
|
10
|
+
* NaN indices). On little-endian targets the bit is the sign bit of the
|
|
11
|
+
* capacity word's low 32 bits on both i64 and i32 layouts.
|
|
12
|
+
*/
|
|
13
|
+
import { exactIndexLines } from "./common.js";
|
|
14
|
+
export const STRING_UTF16_LEN_DECL = "declare double @scr_str_utf16_len(ptr)";
|
|
15
|
+
export const STRING_CHAR_CODE_AT_DECL = "declare double @scr_str_char_code_at(ptr, double)";
|
|
16
|
+
/** Load the proven-ASCII flag of `%s` into `%ascii`. */
|
|
17
|
+
function asciiTest() {
|
|
18
|
+
return [
|
|
19
|
+
` %cw.p = getelementptr inbounds %ScrStr, ptr %s, i32 0, i32 2`,
|
|
20
|
+
` %cw = load i32, ptr %cw.p`,
|
|
21
|
+
` %ascii = icmp slt i32 %cw, 0`,
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
function loadLength(sz) {
|
|
25
|
+
return [
|
|
26
|
+
` %len.p = getelementptr inbounds %ScrStr, ptr %s, i32 0, i32 1`,
|
|
27
|
+
` %len = load ${sz}, ptr %len.p`,
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
export const STRING_READ_HELPERS = [
|
|
31
|
+
{
|
|
32
|
+
decl: STRING_UTF16_LEN_DECL,
|
|
33
|
+
define: (sz, attrs) => [
|
|
34
|
+
`define internal double @sc_str_utf16_len(ptr %s) ${attrs} {`,
|
|
35
|
+
`entry:`,
|
|
36
|
+
...asciiTest(),
|
|
37
|
+
` br i1 %ascii, label %fast, label %slow`,
|
|
38
|
+
`fast:`,
|
|
39
|
+
...loadLength(sz),
|
|
40
|
+
` %n = sitofp ${sz} %len to double`,
|
|
41
|
+
` ret double %n`,
|
|
42
|
+
`slow:`,
|
|
43
|
+
` %r = call double @scr_str_utf16_len(ptr %s)`,
|
|
44
|
+
` ret double %r`,
|
|
45
|
+
`}`,
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
decl: STRING_CHAR_CODE_AT_DECL,
|
|
50
|
+
define: (sz, attrs) => {
|
|
51
|
+
let n = 0;
|
|
52
|
+
const exactIndex = exactIndexLines("%i", "%len", sz, () => `%ix${n++}`);
|
|
53
|
+
return [
|
|
54
|
+
`define internal double @sc_str_char_code_at(ptr %s, double %i) ${attrs} {`,
|
|
55
|
+
`entry:`,
|
|
56
|
+
...asciiTest(),
|
|
57
|
+
` br i1 %ascii, label %bounds, label %slow`,
|
|
58
|
+
`bounds:`,
|
|
59
|
+
...loadLength(sz),
|
|
60
|
+
...exactIndex.lines.map((line) => ` ${line}`),
|
|
61
|
+
` br i1 ${exactIndex.ok}, label %read, label %slow`,
|
|
62
|
+
`read:`,
|
|
63
|
+
sz === "i64"
|
|
64
|
+
? ` %k = add i64 ${exactIndex.wide}, 0`
|
|
65
|
+
: ` %k = trunc i64 ${exactIndex.wide} to ${sz}`,
|
|
66
|
+
` %data = getelementptr inbounds %ScrStr, ptr %s, i32 1`,
|
|
67
|
+
` %p = getelementptr inbounds i8, ptr %data, ${sz} %k`,
|
|
68
|
+
` %byte = load i8, ptr %p`,
|
|
69
|
+
` %unit = uitofp i8 %byte to double`,
|
|
70
|
+
` ret double %unit`,
|
|
71
|
+
`slow:`,
|
|
72
|
+
` %r = call double @scr_str_char_code_at(ptr %s, double %i)`,
|
|
73
|
+
` ret double %r`,
|
|
74
|
+
`}`,
|
|
75
|
+
];
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
//# sourceMappingURL=string-reads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string-reads.js","sourceRoot":"","sources":["../../../src/backend/llvm/string-reads.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,MAAM,qBAAqB,GAAG,wCAAwC,CAAC;AAC9E,MAAM,CAAC,MAAM,wBAAwB,GAAG,mDAAmD,CAAC;AAE5F,wDAAwD;AACxD,SAAS,SAAS;IAChB,OAAO;QACL,gEAAgE;QAChE,6BAA6B;QAC7B,gCAAgC;KACjC,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,EAAU;IAC5B,OAAO;QACL,iEAAiE;QACjE,iBAAiB,EAAE,cAAc;KAClC,CAAC;AACJ,CAAC;AAOD,MAAM,CAAC,MAAM,mBAAmB,GAAgC;IAC9D;QACE,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;YACrB,oDAAoD,KAAK,IAAI;YAC7D,QAAQ;YACR,GAAG,SAAS,EAAE;YACd,0CAA0C;YAC1C,OAAO;YACP,GAAG,UAAU,CAAC,EAAE,CAAC;YACjB,iBAAiB,EAAE,iBAAiB;YACpC,iBAAiB;YACjB,OAAO;YACP,+CAA+C;YAC/C,iBAAiB;YACjB,GAAG;SACJ;KACF;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,MAAM,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;YACpB,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;YACxE,OAAO;gBACL,kEAAkE,KAAK,IAAI;gBAC3E,QAAQ;gBACR,GAAG,SAAS,EAAE;gBACd,4CAA4C;gBAC5C,SAAS;gBACT,GAAG,UAAU,CAAC,EAAE,CAAC;gBACjB,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC9C,WAAW,UAAU,CAAC,EAAE,4BAA4B;gBACpD,OAAO;gBACP,EAAE,KAAK,KAAK;oBACV,CAAC,CAAC,kBAAkB,UAAU,CAAC,IAAI,KAAK;oBACxC,CAAC,CAAC,oBAAoB,UAAU,CAAC,IAAI,OAAO,EAAE,EAAE;gBAClD,yDAAyD;gBACzD,gDAAgD,EAAE,KAAK;gBACvD,2BAA2B;gBAC3B,qCAAqC;gBACrC,oBAAoB;gBACpB,OAAO;gBACP,6DAA6D;gBAC7D,iBAAiB;gBACjB,GAAG;aACJ,CAAC;QACJ,CAAC;KACF;CACF,CAAC"}
|
|
@@ -72,7 +72,7 @@ export function emitStringSliceRead(host, value) {
|
|
|
72
72
|
const pointer = B.tmp(), length = B.tmp(), number = B.tmp();
|
|
73
73
|
B.line(`${pointer} = getelementptr inbounds { ${host.sizeType}, ${host.sizeType}, i32 }, ptr ${snapshot.range}, i32 0, i32 1`);
|
|
74
74
|
B.line(`${length} = load ${host.sizeType}, ptr ${pointer}`);
|
|
75
|
-
B.line(`${number} =
|
|
75
|
+
B.line(`${number} = sitofp ${host.sizeType} ${length} to double`);
|
|
76
76
|
return { name: number, type: value.type };
|
|
77
77
|
}
|
|
78
78
|
if (value.method !== "charCodeAt")
|
|
@@ -73,7 +73,7 @@ test("string dispatch uses target-width byte lengths and checks equality inside
|
|
|
73
73
|
const body = emit(STRING, ["", "a", "é", "😀", "tail", "é"].map(string), bits);
|
|
74
74
|
expect(body).toContain(`load i${bits}, ptr`);
|
|
75
75
|
expect(body).toContain(`switch i${bits}`);
|
|
76
|
-
expect(body).not.toContain("
|
|
76
|
+
expect(body).not.toContain("_str_utf16_len");
|
|
77
77
|
expect(body.match(/call zeroext i1 @sc_str_eq/g)).toHaveLength(5);
|
|
78
78
|
const dispatch = body.split("\n").find((line) => line.includes(`switch i${bits}`));
|
|
79
79
|
expect(dispatch).toContain(`i${bits} 2, label`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch-dispatch.test.js","sourceRoot":"","sources":["../../../src/backend/llvm/switch-dispatch.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"switch-dispatch.test.js","sourceRoot":"","sources":["../../../src/backend/llvm/switch-dispatch.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IrModule } from "../../ir/ir.js";
|
|
2
|
+
/** Test helper: a Set of each union keeps it a tagged `%ScrUnion` box (Set
|
|
3
|
+
* elements are runtime-inspected boxes), so stack-box tests exercise the
|
|
4
|
+
* paths that nullable-pointer unions (nullable-unions.ts) bypass. */
|
|
5
|
+
export declare function keepUnionsBoxed(mod: IrModule): IrModule;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Test helper: a Set of each union keeps it a tagged `%ScrUnion` box (Set
|
|
2
|
+
* elements are runtime-inspected boxes), so stack-box tests exercise the
|
|
3
|
+
* paths that nullable-pointer unions (nullable-unions.ts) bypass. */
|
|
4
|
+
export function keepUnionsBoxed(mod) {
|
|
5
|
+
const keep = (mod.unions ?? []).map((union) => ({
|
|
6
|
+
id: `%g.keep.${union.id}`,
|
|
7
|
+
name: `keep_${union.id}`,
|
|
8
|
+
type: { kind: "set", elem: { kind: "union", unionId: union.id } },
|
|
9
|
+
mutable: false,
|
|
10
|
+
}));
|
|
11
|
+
return { ...mod, globals: [...(mod.globals ?? []), ...keep] };
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=test-boxed-unions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-boxed-unions.js","sourceRoot":"","sources":["../../../src/backend/llvm/test-boxed-unions.ts"],"names":[],"mappings":"AAEA;;qEAEqE;AACrE,MAAM,UAAU,eAAe,CAAC,GAAa;IAC3C,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC9C,EAAE,EAAE,WAAW,KAAK,CAAC,EAAE,EAAE;QACzB,IAAI,EAAE,QAAQ,KAAK,CAAC,EAAE,EAAE;QACxB,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,EAAY;QAC3E,OAAO,EAAE,KAAK;KACf,CAAC,CAAC,CAAC;IACJ,OAAO,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LlvmEmitterContext } from "./expr-context.js";
|
|
2
|
+
/** `Math.trunc(value)`. Targets with a rounding instruction use
|
|
3
|
+
* `llvm.trunc`; on baseline x86-64 that intrinsic is a libm call, so the
|
|
4
|
+
* value instead takes an integer round trip. Every double of magnitude at
|
|
5
|
+
* least 2^52 is already an integer, and NaN and the infinities fail the
|
|
6
|
+
* magnitude test, so those keep their value; the round trip of a smaller
|
|
7
|
+
* value restores its sign so that `-0.5` and `-0` truncate to `-0`. */
|
|
8
|
+
export declare function emitTruncF64(host: LlvmEmitterContext, value: string): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { f64Lit } from "./common.js";
|
|
2
|
+
/** `Math.trunc(value)`. Targets with a rounding instruction use
|
|
3
|
+
* `llvm.trunc`; on baseline x86-64 that intrinsic is a libm call, so the
|
|
4
|
+
* value instead takes an integer round trip. Every double of magnitude at
|
|
5
|
+
* least 2^52 is already an integer, and NaN and the infinities fail the
|
|
6
|
+
* magnitude test, so those keep their value; the round trip of a smaller
|
|
7
|
+
* value restores its sign so that `-0.5` and `-0` truncate to `-0`. */
|
|
8
|
+
export function emitTruncF64(host, value) {
|
|
9
|
+
const B = host.B;
|
|
10
|
+
if (!host.inlineTrunc) {
|
|
11
|
+
host.declare("declare double @llvm.trunc.f64(double)");
|
|
12
|
+
const out = B.tmp();
|
|
13
|
+
B.line(`${out} = call double @llvm.trunc.f64(double ${value})`);
|
|
14
|
+
return out;
|
|
15
|
+
}
|
|
16
|
+
host.declare("declare double @llvm.fabs.f64(double)");
|
|
17
|
+
host.declare("declare double @llvm.copysign.f64(double, double)");
|
|
18
|
+
const magnitude = B.tmp(), small = B.tmp(), integer = B.tmp(), back = B.tmp(), signed = B.tmp(), out = B.tmp();
|
|
19
|
+
B.line(`${magnitude} = call double @llvm.fabs.f64(double ${value})`);
|
|
20
|
+
B.line(`${small} = fcmp olt double ${magnitude}, ${f64Lit(2 ** 52)}`);
|
|
21
|
+
// Poison for a large or non-finite value, which the select never picks.
|
|
22
|
+
B.line(`${integer} = fptosi double ${value} to i64`);
|
|
23
|
+
B.line(`${back} = sitofp i64 ${integer} to double`);
|
|
24
|
+
B.line(`${signed} = call double @llvm.copysign.f64(double ${back}, double ${value})`);
|
|
25
|
+
B.line(`${out} = select i1 ${small}, double ${signed}, double ${value}`);
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=trunc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trunc.js","sourceRoot":"","sources":["../../../src/backend/llvm/trunc.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;uEAKuE;AACvE,MAAM,UAAU,YAAY,CAAC,IAAwB,EAAE,KAAa;IAClE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACjB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACpB,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,yCAAyC,KAAK,GAAG,CAAC,CAAC;QAChE,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,EACvB,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,EACf,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,EACjB,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,EACd,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,EAChB,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,wCAAwC,KAAK,GAAG,CAAC,CAAC;IACrE,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,sBAAsB,SAAS,KAAK,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACtE,wEAAwE;IACxE,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,oBAAoB,KAAK,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,iBAAiB,OAAO,YAAY,CAAC,CAAC;IACpD,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,4CAA4C,IAAI,YAAY,KAAK,GAAG,CAAC,CAAC;IACtF,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,gBAAgB,KAAK,YAAY,MAAM,YAAY,KAAK,EAAE,CAAC,CAAC;IACzE,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BlockBuilder } from "./blocks.js";
|
|
2
|
+
import { type NullableUnion } from "./nullable-unions.js";
|
|
3
|
+
/** The i32 tag of a union value. */
|
|
4
|
+
export declare function emitUnionTag(B: BlockBuilder, nullable: NullableUnion | null, u: string): string;
|
|
5
|
+
/** i1: a nullable union value holds its reference arm (neither NULL nor
|
|
6
|
+
* the `null` sentinel). */
|
|
7
|
+
export declare function emitNullablePresent(B: BlockBuilder, nullable: NullableUnion, u: string): string;
|
|
8
|
+
/** i1: a nullable union value holds the arm `tag` (`negated`: does not). */
|
|
9
|
+
export declare function emitNullableIsTag(B: BlockBuilder, nullable: NullableUnion, u: string, tag: number, negated: boolean): string;
|
|
10
|
+
/** The BORROWED payload pointer of a reference arm. */
|
|
11
|
+
export declare function emitUnionPeek(B: BlockBuilder, nullable: NullableUnion | null, u: string): string;
|
|
12
|
+
/** Text-template forms for helpers written as raw LLVM lines: `%out`
|
|
13
|
+
* receives the tag / payload of `u`. */
|
|
14
|
+
export declare function unionTagLines(nullable: NullableUnion | null, u: string, out: string): string[];
|
|
15
|
+
export declare function unionPeekLines(nullable: NullableUnion | null, u: string, out: string): string[];
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { NULLABLE_NULL } from "./nullable-unions.js";
|
|
2
|
+
/** The i32 tag of a union value. */
|
|
3
|
+
export function emitUnionTag(B, nullable, u) {
|
|
4
|
+
const t = B.tmp();
|
|
5
|
+
if (nullable) {
|
|
6
|
+
const isNull = B.tmp();
|
|
7
|
+
B.line(`${isNull} = icmp eq ptr ${u}, null`);
|
|
8
|
+
if (nullable.nullTag < 0) {
|
|
9
|
+
B.line(`${t} = select i1 ${isNull}, i32 ${nullable.unitTag}, i32 ${nullable.refTag}`);
|
|
10
|
+
return t;
|
|
11
|
+
}
|
|
12
|
+
const isNullArm = B.tmp(), present = B.tmp();
|
|
13
|
+
B.line(`${isNullArm} = icmp eq ptr ${u}, ${NULLABLE_NULL}`);
|
|
14
|
+
B.line(`${present} = select i1 ${isNullArm}, i32 ${nullable.nullTag}, i32 ${nullable.refTag}`);
|
|
15
|
+
B.line(`${t} = select i1 ${isNull}, i32 ${nullable.unitTag}, i32 ${present}`);
|
|
16
|
+
return t;
|
|
17
|
+
}
|
|
18
|
+
const p = B.tmp();
|
|
19
|
+
B.line(`${p} = getelementptr inbounds %ScrUnion, ptr ${u}, i64 0, i32 1`);
|
|
20
|
+
B.line(`${t} = load i32, ptr ${p}`);
|
|
21
|
+
return t;
|
|
22
|
+
}
|
|
23
|
+
/** i1: a nullable union value holds its reference arm (neither NULL nor
|
|
24
|
+
* the `null` sentinel). */
|
|
25
|
+
export function emitNullablePresent(B, nullable, u) {
|
|
26
|
+
const present = B.tmp();
|
|
27
|
+
B.line(`${present} = icmp ne ptr ${u}, null`);
|
|
28
|
+
if (nullable.nullTag < 0)
|
|
29
|
+
return present;
|
|
30
|
+
const notNullArm = B.tmp(), both = B.tmp();
|
|
31
|
+
B.line(`${notNullArm} = icmp ne ptr ${u}, ${NULLABLE_NULL}`);
|
|
32
|
+
B.line(`${both} = and i1 ${present}, ${notNullArm}`);
|
|
33
|
+
return both;
|
|
34
|
+
}
|
|
35
|
+
/** i1: a nullable union value holds the arm `tag` (`negated`: does not). */
|
|
36
|
+
export function emitNullableIsTag(B, nullable, u, tag, negated) {
|
|
37
|
+
if (tag === nullable.refTag) {
|
|
38
|
+
const present = emitNullablePresent(B, nullable, u);
|
|
39
|
+
if (!negated)
|
|
40
|
+
return present;
|
|
41
|
+
const t = B.tmp();
|
|
42
|
+
B.line(`${t} = xor i1 ${present}, true`);
|
|
43
|
+
return t;
|
|
44
|
+
}
|
|
45
|
+
const t = B.tmp();
|
|
46
|
+
const target = tag === nullable.nullTag ? NULLABLE_NULL : "null";
|
|
47
|
+
B.line(`${t} = icmp ${negated ? "ne" : "eq"} ptr ${u}, ${target}`);
|
|
48
|
+
return t;
|
|
49
|
+
}
|
|
50
|
+
/** The BORROWED payload pointer of a reference arm. */
|
|
51
|
+
export function emitUnionPeek(B, nullable, u) {
|
|
52
|
+
if (nullable)
|
|
53
|
+
return u;
|
|
54
|
+
const p = B.tmp();
|
|
55
|
+
const t = B.tmp();
|
|
56
|
+
B.line(`${p} = getelementptr inbounds %ScrUnion, ptr ${u}, i64 0, i32 5`);
|
|
57
|
+
B.line(`${t} = load ptr, ptr ${p}`);
|
|
58
|
+
return t;
|
|
59
|
+
}
|
|
60
|
+
/** Text-template forms for helpers written as raw LLVM lines: `%out`
|
|
61
|
+
* receives the tag / payload of `u`. */
|
|
62
|
+
export function unionTagLines(nullable, u, out) {
|
|
63
|
+
if (nullable && nullable.nullTag < 0)
|
|
64
|
+
return [
|
|
65
|
+
` ${out}.isnull = icmp eq ptr ${u}, null`,
|
|
66
|
+
` ${out} = select i1 ${out}.isnull, i32 ${nullable.unitTag}, i32 ${nullable.refTag}`,
|
|
67
|
+
];
|
|
68
|
+
if (nullable)
|
|
69
|
+
return [
|
|
70
|
+
` ${out}.isnull = icmp eq ptr ${u}, null`,
|
|
71
|
+
` ${out}.isnullarm = icmp eq ptr ${u}, ${NULLABLE_NULL}`,
|
|
72
|
+
` ${out}.present = select i1 ${out}.isnullarm, i32 ${nullable.nullTag}, i32 ${nullable.refTag}`,
|
|
73
|
+
` ${out} = select i1 ${out}.isnull, i32 ${nullable.unitTag}, i32 ${out}.present`,
|
|
74
|
+
];
|
|
75
|
+
return [
|
|
76
|
+
` ${out}.p = getelementptr inbounds %ScrUnion, ptr ${u}, i64 0, i32 1`,
|
|
77
|
+
` ${out} = load i32, ptr ${out}.p`,
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
export function unionPeekLines(nullable, u, out) {
|
|
81
|
+
// A plain copy of the pointer (NULL included) under the template's name.
|
|
82
|
+
if (nullable)
|
|
83
|
+
return [` ${out} = getelementptr i8, ptr ${u}, i64 0`];
|
|
84
|
+
return [
|
|
85
|
+
` ${out}.p = getelementptr inbounds %ScrUnion, ptr ${u}, i64 0, i32 5`,
|
|
86
|
+
` ${out} = load ptr, ptr ${out}.p`,
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=union-repr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"union-repr.js","sourceRoot":"","sources":["../../../src/backend/llvm/union-repr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { IrFunction, IrModule } from "../../ir/ir.js";
|
|
2
|
+
import { type LlClassMeta } from "./classes.js";
|
|
3
|
+
/** Virtual dispatch normally keeps the owned ABI: the caller passes +1 and
|
|
4
|
+
* the method's owned entry releases what its body borrows. When every
|
|
5
|
+
* implementation of a slot has a borrowing body for the same parameter
|
|
6
|
+
* (call-lifetimes proves this per function, independent of the caller), the
|
|
7
|
+
* slot borrows that parameter instead: call sites pass it like a direct call
|
|
8
|
+
* to a borrowing body, so a receiver that survives the call is neither
|
|
9
|
+
* retained nor released (and, being cycle-capable, not buffered as a
|
|
10
|
+
* candidate either). Implementations that borrow more parameters than the
|
|
11
|
+
* slot get an adapter that releases the difference.
|
|
12
|
+
*
|
|
13
|
+
* Shared by the emitter and the self-hosted layout stage, so both store the
|
|
14
|
+
* same vtable entries. */
|
|
15
|
+
export declare class VirtualBorrows {
|
|
16
|
+
private readonly functions;
|
|
17
|
+
private readonly borrowed;
|
|
18
|
+
/** Parameters every implementation of a vtable slot borrows, keyed by
|
|
19
|
+
* `root\0slot index`, and each implementation's slot key. */
|
|
20
|
+
private readonly slotBorrowed;
|
|
21
|
+
private readonly implSlot;
|
|
22
|
+
constructor(mod: IrModule, classMeta: ReadonlyMap<string, LlClassMeta>, functions: ReadonlyMap<string, IrFunction>, borrowed: ReadonlyMap<string, ReadonlySet<number>>);
|
|
23
|
+
/** The borrowed parameters of a hierarchy's vtable slot (empty: owned). */
|
|
24
|
+
slot(rootName: string, slotIndex: number): ReadonlySet<number>;
|
|
25
|
+
/** The borrowed parameters of the slot an implementation fills. */
|
|
26
|
+
implSlotBorrowed(implFn: string): ReadonlySet<number>;
|
|
27
|
+
/** The vtable entry for one implementation: its owned entry for an owned
|
|
28
|
+
* slot, its borrowing body when that borrows exactly the slot's
|
|
29
|
+
* parameters, otherwise its virtual adapter (emitOwnedCallAdapter). */
|
|
30
|
+
entry(implFn: string): string;
|
|
31
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { mangleBorrowedFunction, mangleFunction } from "../mangle.js";
|
|
2
|
+
import { vtEntriesFor } from "./classes.js";
|
|
3
|
+
const NO_BORROWED = new Set();
|
|
4
|
+
/** Virtual dispatch normally keeps the owned ABI: the caller passes +1 and
|
|
5
|
+
* the method's owned entry releases what its body borrows. When every
|
|
6
|
+
* implementation of a slot has a borrowing body for the same parameter
|
|
7
|
+
* (call-lifetimes proves this per function, independent of the caller), the
|
|
8
|
+
* slot borrows that parameter instead: call sites pass it like a direct call
|
|
9
|
+
* to a borrowing body, so a receiver that survives the call is neither
|
|
10
|
+
* retained nor released (and, being cycle-capable, not buffered as a
|
|
11
|
+
* candidate either). Implementations that borrow more parameters than the
|
|
12
|
+
* slot get an adapter that releases the difference.
|
|
13
|
+
*
|
|
14
|
+
* Shared by the emitter and the self-hosted layout stage, so both store the
|
|
15
|
+
* same vtable entries. */
|
|
16
|
+
export class VirtualBorrows {
|
|
17
|
+
functions;
|
|
18
|
+
borrowed;
|
|
19
|
+
/** Parameters every implementation of a vtable slot borrows, keyed by
|
|
20
|
+
* `root\0slot index`, and each implementation's slot key. */
|
|
21
|
+
slotBorrowed = new Map();
|
|
22
|
+
implSlot = new Map();
|
|
23
|
+
constructor(mod, classMeta, functions, borrowed) {
|
|
24
|
+
this.functions = functions;
|
|
25
|
+
this.borrowed = borrowed;
|
|
26
|
+
const impls = new Map();
|
|
27
|
+
const emitted = new Set((mod.classes ?? []).filter((c) => !c.runtime).map((c) => c.name));
|
|
28
|
+
for (const meta of classMeta.values()) {
|
|
29
|
+
if (!meta.hierarchy || !emitted.has(meta.def.name))
|
|
30
|
+
continue;
|
|
31
|
+
vtEntriesFor(meta).forEach(({ slot, impl }, index) => {
|
|
32
|
+
if (impl === null)
|
|
33
|
+
return;
|
|
34
|
+
const key = `${meta.root.def.name}\0${index}`;
|
|
35
|
+
const name = `%${impl.def.name}.${slot.method}`;
|
|
36
|
+
let set = impls.get(key);
|
|
37
|
+
if (!set)
|
|
38
|
+
impls.set(key, (set = new Set()));
|
|
39
|
+
set.add(name);
|
|
40
|
+
this.implSlot.set(name, key);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
for (const [key, names] of impls) {
|
|
44
|
+
let common = null;
|
|
45
|
+
for (const name of names) {
|
|
46
|
+
const fn = this.functions.get(name);
|
|
47
|
+
const own = this.borrowed.get(name);
|
|
48
|
+
if (!fn || !own || fn.captures !== undefined || fn.async || fn.generator) {
|
|
49
|
+
common = [];
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
common = (common ?? [...own]).filter((index) => own.has(index));
|
|
53
|
+
}
|
|
54
|
+
if (common !== null && common.length > 0)
|
|
55
|
+
this.slotBorrowed.set(key, new Set(common));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** The borrowed parameters of a hierarchy's vtable slot (empty: owned). */
|
|
59
|
+
slot(rootName, slotIndex) {
|
|
60
|
+
return this.slotBorrowed.get(`${rootName}\0${slotIndex}`) ?? NO_BORROWED;
|
|
61
|
+
}
|
|
62
|
+
/** The borrowed parameters of the slot an implementation fills. */
|
|
63
|
+
implSlotBorrowed(implFn) {
|
|
64
|
+
const key = this.implSlot.get(implFn);
|
|
65
|
+
if (key === undefined)
|
|
66
|
+
return NO_BORROWED;
|
|
67
|
+
return this.slotBorrowed.get(key) ?? NO_BORROWED;
|
|
68
|
+
}
|
|
69
|
+
/** The vtable entry for one implementation: its owned entry for an owned
|
|
70
|
+
* slot, its borrowing body when that borrows exactly the slot's
|
|
71
|
+
* parameters, otherwise its virtual adapter (emitOwnedCallAdapter). */
|
|
72
|
+
entry(implFn) {
|
|
73
|
+
const slot = this.implSlotBorrowed(implFn);
|
|
74
|
+
if (slot.size === 0)
|
|
75
|
+
return mangleFunction(implFn);
|
|
76
|
+
const own = this.borrowed.get(implFn);
|
|
77
|
+
return own.size === slot.size
|
|
78
|
+
? mangleBorrowedFunction(implFn)
|
|
79
|
+
: `${mangleBorrowedFunction(implFn)}.virtual`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=virtual-borrows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual-borrows.js","sourceRoot":"","sources":["../../../src/backend/llvm/virtual-borrows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type IrExpr, type IrFunction, type IrLocal } from "../../ir/ir.js";
|
|
2
|
+
/** What the emitter knows about a projection's storage. */
|
|
3
|
+
export interface WalkBorrowHost {
|
|
4
|
+
/** The local holds one plain reference pointer (instances, records,
|
|
5
|
+
* arrays, strings, nullable-pointer unions). Tagged union boxes, closures
|
|
6
|
+
* and dynamic values keep ownership. */
|
|
7
|
+
pointerLocal(local: IrLocal): boolean;
|
|
8
|
+
/** emitReadReceiver yields this expression's pointer without acquiring a
|
|
9
|
+
* reference (class casts, nullable wraps, plain field reads, checked
|
|
10
|
+
* ternaries). */
|
|
11
|
+
borrowsWithoutOwning(e: IrExpr): boolean;
|
|
12
|
+
/** The callee returns a borrowed walk of its arguments (findWalkBorrows'
|
|
13
|
+
* returnsWalk); a call to it with walk arguments is itself a walk. */
|
|
14
|
+
borrowedReturn?(callee: string): boolean;
|
|
15
|
+
/** Parameters that may become candidates; once calling conventions are
|
|
16
|
+
* fixed, only borrowed parameters qualify. Defaults to every parameter. */
|
|
17
|
+
parameterAllowed?(localId: string): boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface WalkFacts {
|
|
20
|
+
locals: ReadonlySet<string>;
|
|
21
|
+
/** Every return yields a walk (or a throw), so the body can return its
|
|
22
|
+
* pointer without a reference: no try statement, at least one return. */
|
|
23
|
+
returnsWalk: boolean;
|
|
24
|
+
}
|
|
25
|
+
/** Locals (including rebound parameters) that may hold borrowed pointers
|
|
26
|
+
* for their whole lifetime: every definition (declaration or statement
|
|
27
|
+
* assignment) is a projection of an unwritten parameter or of another such
|
|
28
|
+
* local, for example the parent walk `let p = node.parent; while (p.parent)
|
|
29
|
+
* p = p.parent;`. A rebound parameter in the result keeps the borrowed
|
|
30
|
+
* calling convention.
|
|
31
|
+
*
|
|
32
|
+
* Soundness rests on the whole body preserving heap edges (the caller
|
|
33
|
+
* passes only functions in ReferenceEffects.functions): neither the body
|
|
34
|
+
* nor anything it calls removes a field, element or global reference, so
|
|
35
|
+
* every object reachable from a parameter at entry stays reachable (and
|
|
36
|
+
* alive) until the function returns. Such a local therefore needs no
|
|
37
|
+
* retain on definition, no release on rebinding and none at scope exit.
|
|
38
|
+
* Whole-value uses (returns, stores, owned arguments) still retain their
|
|
39
|
+
* own copies when they read the binding. Other locals may be rebound
|
|
40
|
+
* freely: they never root a walk, so releasing their old values cannot free
|
|
41
|
+
* an object the walk reaches. */
|
|
42
|
+
export declare function findWalkBorrows(fn: IrFunction, host: WalkBorrowHost): ReadonlySet<string>;
|
|
43
|
+
export declare function analyzeWalks(fn: IrFunction, host: WalkBorrowHost): WalkFacts;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { isRefCounted } from "../../ir/ir.js";
|
|
2
|
+
import { everyStmtList } from "../../ir/traverse.js";
|
|
3
|
+
/** Locals (including rebound parameters) that may hold borrowed pointers
|
|
4
|
+
* for their whole lifetime: every definition (declaration or statement
|
|
5
|
+
* assignment) is a projection of an unwritten parameter or of another such
|
|
6
|
+
* local, for example the parent walk `let p = node.parent; while (p.parent)
|
|
7
|
+
* p = p.parent;`. A rebound parameter in the result keeps the borrowed
|
|
8
|
+
* calling convention.
|
|
9
|
+
*
|
|
10
|
+
* Soundness rests on the whole body preserving heap edges (the caller
|
|
11
|
+
* passes only functions in ReferenceEffects.functions): neither the body
|
|
12
|
+
* nor anything it calls removes a field, element or global reference, so
|
|
13
|
+
* every object reachable from a parameter at entry stays reachable (and
|
|
14
|
+
* alive) until the function returns. Such a local therefore needs no
|
|
15
|
+
* retain on definition, no release on rebinding and none at scope exit.
|
|
16
|
+
* Whole-value uses (returns, stores, owned arguments) still retain their
|
|
17
|
+
* own copies when they read the binding. Other locals may be rebound
|
|
18
|
+
* freely: they never root a walk, so releasing their old values cannot free
|
|
19
|
+
* an object the walk reaches. */
|
|
20
|
+
export function findWalkBorrows(fn, host) {
|
|
21
|
+
return analyzeWalks(fn, host).locals;
|
|
22
|
+
}
|
|
23
|
+
export function analyzeWalks(fn, host) {
|
|
24
|
+
const result = new Set();
|
|
25
|
+
if (fn.async || fn.generator || fn.captures || fn.classCaptures)
|
|
26
|
+
return { locals: result, returnsWalk: false };
|
|
27
|
+
const returns = [];
|
|
28
|
+
let guarded = false;
|
|
29
|
+
const params = new Set(fn.params.map((param) => param.localId));
|
|
30
|
+
const locals = new Map(fn.locals.map((local) => [local.id, local]));
|
|
31
|
+
const definitions = new Map();
|
|
32
|
+
// Locals written in any other way (expression assignments, loop and catch
|
|
33
|
+
// bindings, captures) keep the ordinary owned representation.
|
|
34
|
+
const excluded = new Set();
|
|
35
|
+
const define = (id, value) => {
|
|
36
|
+
let list = definitions.get(id);
|
|
37
|
+
if (!list)
|
|
38
|
+
definitions.set(id, (list = []));
|
|
39
|
+
list.push(value);
|
|
40
|
+
};
|
|
41
|
+
everyStmtList(fn.body, {
|
|
42
|
+
stmt: (s) => {
|
|
43
|
+
switch (s.kind) {
|
|
44
|
+
case "varDecl":
|
|
45
|
+
define(s.localId, s.init);
|
|
46
|
+
break;
|
|
47
|
+
case "assign":
|
|
48
|
+
define(s.localId, s.value);
|
|
49
|
+
break;
|
|
50
|
+
case "forOf":
|
|
51
|
+
excluded.add(s.localId);
|
|
52
|
+
break;
|
|
53
|
+
case "rethrow":
|
|
54
|
+
excluded.add(s.localId);
|
|
55
|
+
break;
|
|
56
|
+
case "tryCatch":
|
|
57
|
+
guarded = true;
|
|
58
|
+
if (s.catchLocalId !== null)
|
|
59
|
+
excluded.add(s.catchLocalId);
|
|
60
|
+
break;
|
|
61
|
+
case "return":
|
|
62
|
+
returns.push(s.value);
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
},
|
|
67
|
+
expr: (e) => {
|
|
68
|
+
switch (e.kind) {
|
|
69
|
+
case "assignExpr":
|
|
70
|
+
case "incDec":
|
|
71
|
+
excluded.add(e.localId);
|
|
72
|
+
break;
|
|
73
|
+
case "closure":
|
|
74
|
+
case "classRef":
|
|
75
|
+
for (const id of e.captures ?? [])
|
|
76
|
+
excluded.add(id);
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
return true;
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
const plain = (id) => {
|
|
83
|
+
const local = locals.get(id);
|
|
84
|
+
return (!!local &&
|
|
85
|
+
!local.boxed &&
|
|
86
|
+
!local.tdz &&
|
|
87
|
+
!excluded.has(id) &&
|
|
88
|
+
host.pointerLocal(local) &&
|
|
89
|
+
(!params.has(id) || host.parameterAllowed?.(id) !== false));
|
|
90
|
+
};
|
|
91
|
+
// Parameters are roots only while no definition rebinds them. A
|
|
92
|
+
// parameter rebound by statement assignments alone (`t = t.regular`) is a
|
|
93
|
+
// candidate like any local: its incoming value is the caller's borrow.
|
|
94
|
+
const roots = new Set([...params].filter((id) => !definitions.has(id) && plain(id)));
|
|
95
|
+
const candidates = new Set();
|
|
96
|
+
for (const [id, values] of definitions) {
|
|
97
|
+
if (!plain(id))
|
|
98
|
+
continue;
|
|
99
|
+
if (params.has(id) && values.some((value) => value === null))
|
|
100
|
+
continue;
|
|
101
|
+
candidates.add(id);
|
|
102
|
+
}
|
|
103
|
+
// A walk projects roots or candidates through reads that never acquire a
|
|
104
|
+
// reference. Drop candidates until every definition is such a walk.
|
|
105
|
+
const walk = (e) => {
|
|
106
|
+
switch (e.kind) {
|
|
107
|
+
case "varRef":
|
|
108
|
+
return roots.has(e.localId) || candidates.has(e.localId);
|
|
109
|
+
case "fieldGet":
|
|
110
|
+
case "recordGet":
|
|
111
|
+
return host.borrowsWithoutOwning(e) && walk(e.obj);
|
|
112
|
+
case "unionNarrow":
|
|
113
|
+
case "downcast":
|
|
114
|
+
case "upcast":
|
|
115
|
+
return host.borrowsWithoutOwning(e) && walk(e.value);
|
|
116
|
+
case "unionWrap":
|
|
117
|
+
if (!host.borrowsWithoutOwning(e))
|
|
118
|
+
return false;
|
|
119
|
+
return e.value.kind === "unitLit" || walk(e.value);
|
|
120
|
+
// Each arm is itself a walk (or a throw), which emitReadReceiver reads
|
|
121
|
+
// without owning.
|
|
122
|
+
case "ternary":
|
|
123
|
+
return host.borrowsWithoutOwning(e) && walkOrThrow(e.then) && walkOrThrow(e.else_);
|
|
124
|
+
// A borrowed result is reachable from walk arguments.
|
|
125
|
+
case "call":
|
|
126
|
+
return (host.borrowedReturn?.(e.callee) === true &&
|
|
127
|
+
host.borrowsWithoutOwning(e) &&
|
|
128
|
+
e.args.every((arg) => !isRefCounted(arg.type) || walk(arg)));
|
|
129
|
+
default:
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const walkOrThrow = (e) => (e.kind === "libCall" && e.fn === "error.nodeThrow") || walk(e);
|
|
134
|
+
for (let changed = true; changed;) {
|
|
135
|
+
changed = false;
|
|
136
|
+
for (const id of candidates) {
|
|
137
|
+
if (definitions.get(id).every((value) => value === null || walk(value)))
|
|
138
|
+
continue;
|
|
139
|
+
candidates.delete(id);
|
|
140
|
+
changed = true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
for (const id of candidates)
|
|
144
|
+
result.add(id);
|
|
145
|
+
const returnsWalk = !guarded &&
|
|
146
|
+
returns.length > 0 &&
|
|
147
|
+
returns.every((value) => value !== null && walkOrThrow(value));
|
|
148
|
+
return { locals: result, returnsWalk };
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=walk-borrows.js.map
|