@scriptc/compiler 0.2.6 → 0.2.8
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 +7 -18
- package/dist/backend/cycle-analysis.d.ts +21 -9
- package/dist/backend/cycle-analysis.js +139 -67
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +283 -3
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.d.ts +39 -0
- package/dist/backend/cycle-mutability.js +205 -0
- package/dist/backend/cycle-mutability.js.map +1 -0
- package/dist/backend/link-plan-core.d.ts +2 -1
- package/dist/backend/link-plan-core.js +15 -3
- package/dist/backend/link-plan-core.js.map +1 -1
- package/dist/backend/link-plan.d.ts +2 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +43 -0
- package/dist/backend/llvm/alloc.js +246 -0
- package/dist/backend/llvm/alloc.js.map +1 -0
- package/dist/backend/llvm/alloc.test.d.ts +1 -0
- package/dist/backend/llvm/alloc.test.js +102 -0
- package/dist/backend/llvm/alloc.test.js.map +1 -0
- 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/call-lifetimes.d.ts +18 -3
- package/dist/backend/llvm/call-lifetimes.js +54 -19
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +178 -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 +16 -1
- package/dist/backend/llvm/classes.js +60 -49
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +68 -6
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +13 -0
- package/dist/backend/llvm/common.js +30 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +19 -3
- package/dist/backend/llvm/constant-callbacks.js +289 -52
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +140 -3
- package/dist/backend/llvm/constant-callbacks.test.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.d.ts +29 -0
- package/dist/backend/llvm/dense-array-access.js +335 -0
- package/dist/backend/llvm/dense-array-access.js.map +1 -0
- package/dist/backend/llvm/dense-array-access.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-access.test.js +238 -0
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +38 -0
- package/dist/backend/llvm/dyn.js +213 -14
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +308 -15
- package/dist/backend/llvm/emitter.js +1788 -206
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +89 -7
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +62 -8
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.d.ts +1 -0
- package/dist/backend/llvm/expr-async.test.js +62 -0
- package/dist/backend/llvm/expr-async.test.js.map +1 -0
- package/dist/backend/llvm/expr-bytes.d.ts +1 -1
- package/dist/backend/llvm/expr-bytes.js +85 -8
- 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 +118 -15
- 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 +246 -32
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +113 -8
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +2 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +244 -44
- 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.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +93 -36
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +51 -3
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +31 -17
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +96 -29
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +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/integer-remainder.d.ts +11 -0
- package/dist/backend/llvm/integer-remainder.js +91 -0
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/layouts.d.ts +3 -1
- package/dist/backend/llvm/layouts.js +3 -2
- package/dist/backend/llvm/layouts.js.map +1 -1
- package/dist/backend/llvm/lazy-captures.d.ts +16 -0
- package/dist/backend/llvm/lazy-captures.js +96 -0
- package/dist/backend/llvm/lazy-captures.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.test.d.ts +1 -0
- package/dist/backend/llvm/lazy-captures.test.js +78 -0
- package/dist/backend/llvm/lazy-captures.test.js.map +1 -0
- 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 +10 -15
- 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 +1 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +5 -1
- package/dist/backend/llvm/local-array-reads.js +147 -26
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +85 -4
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.d.ts +5 -1
- package/dist/backend/llvm/local-union-storage.js +54 -8
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +94 -6
- 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 +39 -20
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/nullable-fields.d.ts +28 -0
- package/dist/backend/llvm/nullable-fields.js +45 -0
- package/dist/backend/llvm/nullable-fields.js.map +1 -0
- package/dist/backend/llvm/nullable-fields.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-fields.test.js +48 -0
- package/dist/backend/llvm/nullable-fields.test.js.map +1 -0
- 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 +106 -16
- 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/serialized-ir-emission.test.d.ts +1 -0
- package/dist/backend/llvm/serialized-ir-emission.test.js +52 -0
- package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +104 -9
- package/dist/backend/llvm/shapes.js +356 -46
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +139 -5
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/stack-callbacks.js +2 -3
- package/dist/backend/llvm/stack-callbacks.js.map +1 -1
- package/dist/backend/llvm/stack-captures.d.ts +3 -1
- package/dist/backend/llvm/stack-captures.js +5 -3
- package/dist/backend/llvm/stack-captures.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +43 -3
- 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-construction.test.js +1 -1
- package/dist/backend/llvm/string-key-hash.d.ts +15 -0
- package/dist/backend/llvm/string-key-hash.js +76 -0
- package/dist/backend/llvm/string-key-hash.js.map +1 -0
- package/dist/backend/llvm/string-key-hash.test.d.ts +1 -0
- package/dist/backend/llvm/string-key-hash.test.js +45 -0
- package/dist/backend/llvm/string-key-hash.test.js.map +1 -0
- package/dist/backend/llvm/string-lifetimes.test.js +65 -15
- 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 +76 -0
- package/dist/backend/llvm/string-reads.js.map +1 -0
- package/dist/backend/llvm/switch-dispatch.js +1 -1
- package/dist/backend/llvm/switch-dispatch.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +3 -3
- 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/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/may-throw.d.ts +29 -1
- package/dist/backend/may-throw.js +349 -3
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +114 -2
- package/dist/backend/may-throw.test.js.map +1 -1
- package/dist/backend/native/cache-warm.d.ts +2 -1
- package/dist/backend/native/cache-warm.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +3 -2
- package/dist/backend/native/contracts.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +2 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +7 -4
- 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 +9 -0
- package/dist/backend/native-codegen.js +53 -2
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +64 -10
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +3 -2
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-link-info.d.ts +2 -1
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-link-info.test.js +2 -2
- package/dist/backend/native-link-info.test.js.map +1 -1
- package/dist/backend/native-tools.d.ts +5 -1
- package/dist/backend/native-tools.js +3 -1
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/optimization.d.ts +25 -0
- package/dist/backend/optimization.js +21 -0
- package/dist/backend/optimization.js.map +1 -0
- package/dist/backend/optimization.test.d.ts +1 -0
- package/dist/backend/optimization.test.js +24 -0
- package/dist/backend/optimization.test.js.map +1 -0
- 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-pack-core.d.ts +15 -4
- package/dist/backend/runtime-pack-core.js +23 -12
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.d.ts +7 -3
- package/dist/backend/runtime-pack-native.js +0 -3
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.d.ts +20 -2
- package/dist/backend/runtime-pack.js +23 -0
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +115 -2
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/targets.d.ts +2 -1
- package/dist/backend/targets.js +1 -1
- package/dist/backend/targets.js.map +1 -1
- package/dist/cli/command.js +75 -11
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +2 -1
- package/dist/cli/usage.d.ts +4 -1
- package/dist/cli/usage.js +13 -3
- package/dist/cli/usage.js.map +1 -1
- package/dist/compile-types.d.ts +17 -5
- 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 +84 -12
- 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 -2
- package/dist/executable/executable-cache.js +7 -4
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +20 -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/abstract-equality.js +5 -49
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +30 -0
- package/dist/frontend/lowering/array-values.js +246 -1
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.js +17 -2
- package/dist/frontend/lowering/builtins/errors.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 +10 -17
- package/dist/frontend/lowering/builtins/process.js +66 -29
- package/dist/frontend/lowering/builtins/process.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/caught-value-dispatch.d.ts +11 -0
- package/dist/frontend/lowering/caught-value-dispatch.js +87 -0
- package/dist/frontend/lowering/caught-value-dispatch.js.map +1 -0
- package/dist/frontend/lowering/class-assertions.d.ts +12 -0
- package/dist/frontend/lowering/class-assertions.js +229 -5
- package/dist/frontend/lowering/class-assertions.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
- package/dist/frontend/lowering/class-callbacks.js +18 -5
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +12 -6
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.d.ts +5 -0
- package/dist/frontend/lowering/class-method-mutations.js +472 -0
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -0
- package/dist/frontend/lowering/class-method-values.js +25 -5
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.js +8 -2
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-unions.d.ts +16 -0
- package/dist/frontend/lowering/class-unions.js +127 -0
- package/dist/frontend/lowering/class-unions.js.map +1 -0
- package/dist/frontend/lowering/coercions/builders.js +8 -1
- package/dist/frontend/lowering/coercions/builders.js.map +1 -1
- package/dist/frontend/lowering/coercions/function-adapters.js +2 -0
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/identity.d.ts +7 -0
- package/dist/frontend/lowering/coercions/identity.js +26 -0
- package/dist/frontend/lowering/coercions/identity.js.map +1 -0
- 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/structural.js +9 -6
- package/dist/frontend/lowering/coercions/structural.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/collection-narrowing.d.ts +6 -0
- package/dist/frontend/lowering/collection-narrowing.js +31 -0
- package/dist/frontend/lowering/collection-narrowing.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-callback-call.d.ts +7 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +52 -0
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +416 -65
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.d.ts +7 -0
- package/dist/frontend/lowering/containers/array-concat.js +130 -0
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -0
- package/dist/frontend/lowering/containers/array-construction.d.ts +2 -0
- package/dist/frontend/lowering/containers/array-construction.js +110 -5
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.d.ts +1 -11
- package/dist/frontend/lowering/containers/array-methods.js +274 -144
- package/dist/frontend/lowering/containers/array-methods.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/collection-methods.js +10 -1
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +56 -70
- package/dist/frontend/lowering/containers/indexed-objects.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 +46 -0
- package/dist/frontend/lowering/cycle-initialization.js +303 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -0
- 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/evaluation-safety.js +4 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +178 -34
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-field-write.d.ts +4 -4
- package/dist/frontend/lowering/expressions/union-field-write.js +54 -44
- package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +20 -0
- package/dist/frontend/lowering/iterator-adapters.js +605 -0
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -0
- package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
- package/dist/frontend/lowering/lower-array-sort.js +44 -5
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-array-sort.test.js +31 -0
- package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -0
- package/dist/frontend/lowering/lower-assert.js +7 -0
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.js +1 -0
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +8 -3
- package/dist/frontend/lowering/lower-calls.js +388 -278
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +6 -0
- package/dist/frontend/lowering/lower-classes.js +117 -65
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +22 -2
- package/dist/frontend/lowering/lower-exprs.js +811 -254
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +32 -19
- package/dist/frontend/lowering/lower-functions.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 +29 -4
- 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 +24 -7
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +100 -3
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +82 -64
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +115 -2
- package/dist/frontend/lowering/lowerer.js +1266 -88
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +3 -1
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-bounds.d.ts +19 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +354 -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 +66 -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 +16 -0
- package/dist/frontend/lowering/runtime-optional-provenance.js +41 -0
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -0
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/strict-equality.d.ts +9 -0
- package/dist/frontend/lowering/strict-equality.js +116 -0
- package/dist/frontend/lowering/strict-equality.js.map +1 -0
- 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 +3 -0
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/union-comparison.d.ts +5 -0
- package/dist/frontend/lowering/union-comparison.js +47 -0
- package/dist/frontend/lowering/union-comparison.js.map +1 -0
- 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 +63 -2
- package/dist/frontend/program.js +1038 -61
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +122 -6
- 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 +4 -1
- package/dist/frontend/type-mapper.js +161 -20
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.js +15 -3
- package/dist/frontend/type-mapper.test.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 +6 -1
- package/dist/index.js +70 -16
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +3 -1
- package/dist/ir/analysis.js +4 -0
- package/dist/ir/analysis.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 -3
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +72 -0
- package/dist/ir/int32-slots.js +837 -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 +222 -0
- package/dist/ir/int32-slots.test.js.map +1 -0
- 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 +101 -20
- package/dist/ir/ir.js +20 -6
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +3 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/traverse.js +8 -0
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +139 -22
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +308 -8
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +2 -1
- package/dist/library/library-profile.js +4 -3
- package/dist/library/library-profile.js.map +1 -1
- package/dist/native/cache.d.ts +3 -0
- package/dist/native/cache.js +49 -1
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cache.test.js +21 -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 +51 -4
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/library.d.ts +2 -1
- package/dist/native/library.js.map +1 -1
- package/dist/native/prepare.d.ts +4 -0
- package/dist/native/prepare.js +28 -3
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.d.ts +3 -2
- package/dist/native/sanitizer.js +3 -13
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/startup-cache.d.ts +2 -0
- package/dist/startup-cache.js +2 -0
- package/dist/startup-cache.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +8 -2
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { isRefCounted, typeEquals, } from "../../ir/ir.js";
|
|
2
|
+
import { mangleBorrowedFunction } from "../mangle.js";
|
|
3
|
+
import { emitCallArrayRead } from "./local-array-reads.js";
|
|
4
|
+
/** Recognize the complete checked-extraction body, not the helper's name:
|
|
5
|
+
* one test per arm of the parameter's union, where the target arm returns
|
|
6
|
+
* its payload and every other arm throws, followed by a final throw. A
|
|
7
|
+
* helper that returns a default for some arm is not a checked extraction. */
|
|
8
|
+
function checkedNarrowShape(fn) {
|
|
9
|
+
if (fn.async ||
|
|
10
|
+
fn.generator ||
|
|
11
|
+
fn.captures ||
|
|
12
|
+
fn.classCaptures ||
|
|
13
|
+
fn.params.length !== 1 ||
|
|
14
|
+
fn.locals.length !== 1 ||
|
|
15
|
+
fn.locals.some((local) => local.boxed || local.tdz) ||
|
|
16
|
+
!isRefCounted(fn.returnType))
|
|
17
|
+
return null;
|
|
18
|
+
const param = fn.params[0];
|
|
19
|
+
if (param.type.kind !== "union")
|
|
20
|
+
return null;
|
|
21
|
+
const unionId = param.type.unionId;
|
|
22
|
+
const last = fn.body[fn.body.length - 1];
|
|
23
|
+
if (last?.kind !== "throw")
|
|
24
|
+
return null;
|
|
25
|
+
let tag = -1;
|
|
26
|
+
for (const [index, stmt] of fn.body.slice(0, -1).entries()) {
|
|
27
|
+
if (stmt.kind !== "if" ||
|
|
28
|
+
stmt.else_ !== null ||
|
|
29
|
+
stmt.cond.kind !== "unionIsTag" ||
|
|
30
|
+
stmt.cond.negated ||
|
|
31
|
+
stmt.cond.tag !== index ||
|
|
32
|
+
stmt.cond.unionId !== unionId ||
|
|
33
|
+
stmt.cond.value.kind !== "varRef" ||
|
|
34
|
+
stmt.cond.value.localId !== param.localId ||
|
|
35
|
+
stmt.then.length !== 1)
|
|
36
|
+
return null;
|
|
37
|
+
const branch = stmt.then[0];
|
|
38
|
+
if (branch.kind === "throw")
|
|
39
|
+
continue;
|
|
40
|
+
const value = branch.kind === "return" ? branch.value : null;
|
|
41
|
+
if (tag >= 0 ||
|
|
42
|
+
value?.kind !== "unionNarrow" ||
|
|
43
|
+
value.unionId !== unionId ||
|
|
44
|
+
value.tag !== index ||
|
|
45
|
+
value.value.kind !== "varRef" ||
|
|
46
|
+
value.value.localId !== param.localId ||
|
|
47
|
+
!typeEquals(value.type, fn.returnType))
|
|
48
|
+
return null;
|
|
49
|
+
tag = index;
|
|
50
|
+
}
|
|
51
|
+
return tag < 0 ? null : { unionId, tag, target: fn.returnType };
|
|
52
|
+
}
|
|
53
|
+
/** Checked extractions in finalized IR, indexed once per module. */
|
|
54
|
+
export class CheckedNarrows {
|
|
55
|
+
shapes = new Map();
|
|
56
|
+
constructor(functions) {
|
|
57
|
+
for (const fn of functions.values()) {
|
|
58
|
+
const shape = checkedNarrowShape(fn);
|
|
59
|
+
if (shape)
|
|
60
|
+
this.shapes.set(fn.name, shape);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
get(e) {
|
|
64
|
+
if (e.kind !== "call" || e.args.length !== 1)
|
|
65
|
+
return null;
|
|
66
|
+
const shape = this.shapes.get(e.callee);
|
|
67
|
+
const value = e.args[0];
|
|
68
|
+
if (!shape ||
|
|
69
|
+
!typeEquals(shape.target, e.type) ||
|
|
70
|
+
value.type.kind !== "union" ||
|
|
71
|
+
value.type.unionId !== shape.unionId)
|
|
72
|
+
return null;
|
|
73
|
+
return { call: e, value, tag: shape.tag };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** A checked extraction consumed at once by a field or tag load. The
|
|
77
|
+
* successful arm borrows the payload from the union, which itself borrows
|
|
78
|
+
* from its source: a dense array read keeps the element in the array slot,
|
|
79
|
+
* and no user code runs before the consumer loads from it. Every other arm
|
|
80
|
+
* calls the helper with the same union, so the thrown error is unchanged.
|
|
81
|
+
* Returns null, having emitted nothing, when the helper would own its
|
|
82
|
+
* argument. */
|
|
83
|
+
export function emitCheckedNarrowReceiver(host, narrow) {
|
|
84
|
+
const callee = narrow.call.callee;
|
|
85
|
+
if (!host.callLifetimes.borrowed.get(callee)?.has(0) || !host.mayThrow.has(callee))
|
|
86
|
+
return null;
|
|
87
|
+
const B = host.B;
|
|
88
|
+
const read = host.optionalArrayReads.get(narrow.value);
|
|
89
|
+
const union = read
|
|
90
|
+
? emitCallArrayRead(host, { ...read, borrow: true }, true)
|
|
91
|
+
: host.emitUnionProjection(narrow.value);
|
|
92
|
+
// Nullable unions (nullable-unions.ts) are the payload pointer itself;
|
|
93
|
+
// the representation-aware tag and peek cover both forms.
|
|
94
|
+
const unionId = narrow.value.type.unionId;
|
|
95
|
+
const tag = host.unionTag(union.name, unionId);
|
|
96
|
+
const present = B.tmp();
|
|
97
|
+
B.line(`${present} = icmp eq i32 ${tag}, ${narrow.tag}`);
|
|
98
|
+
const yes = B.newLabel("narrow.present"), no = B.newLabel("narrow.other");
|
|
99
|
+
B.condBr(present, yes, no);
|
|
100
|
+
B.startBlock(no);
|
|
101
|
+
B.line(`call ptr @${mangleBorrowedFunction(callee)}(ptr ${union.name})`);
|
|
102
|
+
host.emitPendingCheck();
|
|
103
|
+
// Every arm but the target throws, so the helper never returns here.
|
|
104
|
+
B.terminate("unreachable");
|
|
105
|
+
B.startBlock(yes);
|
|
106
|
+
return { name: host.unionPeek(union.name, unionId), type: narrow.call.type };
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=checked-narrows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checked-narrows.js","sourceRoot":"","sources":["../../../src/backend/llvm/checked-narrows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
import { BOOL, F64, STRING, VOID, UNDEFINED_T, arrayOf, } from "../../ir/ir.js";
|
|
3
|
+
import { validateModule } from "../../ir/validate.js";
|
|
4
|
+
import { CheckedNarrows } from "./checked-narrows.js";
|
|
5
|
+
import { emitLlvmModule } from "./emitter.js";
|
|
6
|
+
const loc = { file: "checked-narrow.ts", start: 0, end: 0 };
|
|
7
|
+
const element = { kind: "record", shapeId: "cell" };
|
|
8
|
+
const optional = { kind: "union", unionId: "optional" };
|
|
9
|
+
const array = arrayOf(element);
|
|
10
|
+
const ref = (localId, type) => ({ kind: "varRef", localId, type, loc });
|
|
11
|
+
const params = [
|
|
12
|
+
{ localId: "a", name: "a", type: array },
|
|
13
|
+
{ localId: "i", name: "i", type: F64 },
|
|
14
|
+
];
|
|
15
|
+
const locals = params.map((p) => ({ id: p.localId, name: p.name, type: p.type, mutable: false }));
|
|
16
|
+
/** The optional array read the frontend emits for `a[i]`. */
|
|
17
|
+
const read = {
|
|
18
|
+
name: "read",
|
|
19
|
+
params,
|
|
20
|
+
returnType: optional,
|
|
21
|
+
locals,
|
|
22
|
+
loc,
|
|
23
|
+
body: [
|
|
24
|
+
{
|
|
25
|
+
kind: "return",
|
|
26
|
+
loc,
|
|
27
|
+
value: {
|
|
28
|
+
kind: "ternary",
|
|
29
|
+
type: optional,
|
|
30
|
+
loc,
|
|
31
|
+
cond: {
|
|
32
|
+
kind: "bin",
|
|
33
|
+
op: "===",
|
|
34
|
+
left: { kind: "arrayState", arr: ref("a", array), index: ref("i", F64), type: F64, loc },
|
|
35
|
+
right: { kind: "numLit", value: 1, type: F64, loc },
|
|
36
|
+
type: BOOL,
|
|
37
|
+
loc,
|
|
38
|
+
},
|
|
39
|
+
then: {
|
|
40
|
+
kind: "unionWrap",
|
|
41
|
+
unionId: "optional",
|
|
42
|
+
tag: 0,
|
|
43
|
+
value: {
|
|
44
|
+
kind: "arrayGet",
|
|
45
|
+
arr: ref("a", array),
|
|
46
|
+
index: ref("i", F64),
|
|
47
|
+
type: element,
|
|
48
|
+
loc,
|
|
49
|
+
},
|
|
50
|
+
type: optional,
|
|
51
|
+
loc,
|
|
52
|
+
},
|
|
53
|
+
else_: {
|
|
54
|
+
kind: "unionWrap",
|
|
55
|
+
unionId: "optional",
|
|
56
|
+
tag: 1,
|
|
57
|
+
value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc },
|
|
58
|
+
type: optional,
|
|
59
|
+
loc,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
/** A checked extraction of the element arm; `undefinedArm` replaces the
|
|
66
|
+
* throwing undefined branch, as a defaulting helper would. */
|
|
67
|
+
function check(name, undefinedArm) {
|
|
68
|
+
const u = ref("u.0", optional);
|
|
69
|
+
const thrown = {
|
|
70
|
+
kind: "throw",
|
|
71
|
+
value: {
|
|
72
|
+
kind: "libCall",
|
|
73
|
+
fn: "error.new",
|
|
74
|
+
args: [{ kind: "strLit", value: "undefined is not an element", type: STRING, loc }],
|
|
75
|
+
type: { kind: "object", className: "%TypeError" },
|
|
76
|
+
loc,
|
|
77
|
+
},
|
|
78
|
+
loc,
|
|
79
|
+
};
|
|
80
|
+
const arm = (tag, then) => ({
|
|
81
|
+
kind: "if",
|
|
82
|
+
cond: {
|
|
83
|
+
kind: "unionIsTag",
|
|
84
|
+
unionId: "optional",
|
|
85
|
+
tag,
|
|
86
|
+
negated: false,
|
|
87
|
+
value: u,
|
|
88
|
+
type: BOOL,
|
|
89
|
+
loc,
|
|
90
|
+
},
|
|
91
|
+
then: [then],
|
|
92
|
+
else_: null,
|
|
93
|
+
loc,
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
name,
|
|
97
|
+
params: [{ localId: "u.0", name: "u", type: optional }],
|
|
98
|
+
returnType: element,
|
|
99
|
+
locals: [{ id: "u.0", name: "u", type: optional, mutable: false }],
|
|
100
|
+
loc,
|
|
101
|
+
body: [
|
|
102
|
+
arm(0, {
|
|
103
|
+
kind: "return",
|
|
104
|
+
value: { kind: "unionNarrow", unionId: "optional", tag: 0, value: u, type: element, loc },
|
|
105
|
+
loc,
|
|
106
|
+
}),
|
|
107
|
+
arm(1, undefinedArm ?? thrown),
|
|
108
|
+
{ kind: "throw", value: { kind: "strLit", value: "invalid tag", type: STRING, loc }, loc },
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function fixture(helper) {
|
|
113
|
+
const narrowed = {
|
|
114
|
+
kind: "call",
|
|
115
|
+
callee: helper.name,
|
|
116
|
+
args: [
|
|
117
|
+
{ kind: "call", callee: "read", args: [ref("a", array), ref("i", F64)], type: optional, loc },
|
|
118
|
+
],
|
|
119
|
+
type: element,
|
|
120
|
+
loc,
|
|
121
|
+
};
|
|
122
|
+
const work = {
|
|
123
|
+
name: "work",
|
|
124
|
+
params,
|
|
125
|
+
returnType: F64,
|
|
126
|
+
locals,
|
|
127
|
+
loc,
|
|
128
|
+
body: [
|
|
129
|
+
{
|
|
130
|
+
kind: "return",
|
|
131
|
+
value: { kind: "recordGet", obj: narrowed, shapeId: "cell", field: "x", type: F64, loc },
|
|
132
|
+
loc,
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
};
|
|
136
|
+
return {
|
|
137
|
+
irVersion: 15,
|
|
138
|
+
sourceFile: loc.file,
|
|
139
|
+
entry: "main",
|
|
140
|
+
records: [{ id: "cell", fields: [{ name: "x", type: F64 }] }],
|
|
141
|
+
unions: [{ id: "optional", arms: [element, UNDEFINED_T] }],
|
|
142
|
+
functions: [
|
|
143
|
+
{ name: "main", params: [], returnType: VOID, locals: [], body: [], loc },
|
|
144
|
+
read,
|
|
145
|
+
helper,
|
|
146
|
+
work,
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function workBody(mod, pointerBits = 64) {
|
|
151
|
+
return /^define internal [^\n]*@sc_(?:b)?f_work\([^]*?^}/m.exec(emitLlvmModule(mod, { pointerBits }))[0];
|
|
152
|
+
}
|
|
153
|
+
test("recognizes checked extractions by their complete body", () => {
|
|
154
|
+
const defaulted = check("defaulted", {
|
|
155
|
+
kind: "return",
|
|
156
|
+
value: {
|
|
157
|
+
kind: "unionNarrow",
|
|
158
|
+
unionId: "optional",
|
|
159
|
+
tag: 0,
|
|
160
|
+
value: ref("u.0", optional),
|
|
161
|
+
type: element,
|
|
162
|
+
loc,
|
|
163
|
+
},
|
|
164
|
+
loc,
|
|
165
|
+
});
|
|
166
|
+
const narrows = new CheckedNarrows(new Map([check("check"), defaulted, read].map((fn) => [fn.name, fn])));
|
|
167
|
+
const call = (callee) => ({
|
|
168
|
+
kind: "call",
|
|
169
|
+
callee,
|
|
170
|
+
args: [ref("value", optional)],
|
|
171
|
+
type: element,
|
|
172
|
+
loc,
|
|
173
|
+
});
|
|
174
|
+
expect(narrows.get(call("check"))?.tag).toBe(0);
|
|
175
|
+
// Two successful arms, or any non-throwing arm, is not a checked extraction.
|
|
176
|
+
expect(narrows.get(call("defaulted"))).toBeNull();
|
|
177
|
+
expect(narrows.get(call("read"))).toBeNull();
|
|
178
|
+
});
|
|
179
|
+
test("a field read through a checked array element borrows the element on both ABIs", () => {
|
|
180
|
+
const mod = fixture(check("check"));
|
|
181
|
+
expect(validateModule(mod)).toEqual([]);
|
|
182
|
+
for (const pointerBits of [32, 64]) {
|
|
183
|
+
const body = workBody(mod, pointerBits);
|
|
184
|
+
expect(body).toContain("narrow.present");
|
|
185
|
+
expect(body).not.toContain("@sc_bf_read(");
|
|
186
|
+
expect(body).not.toContain("@sc_rretain_");
|
|
187
|
+
expect(body).not.toContain("@sc_rrelease_");
|
|
188
|
+
// The helper still runs, and throws, for every other arm.
|
|
189
|
+
expect(body).toMatch(/call ptr @\S*check\S*\(ptr /);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
test("a helper that does not throw for every other arm keeps the ordinary call", () => {
|
|
193
|
+
const mod = fixture(check("fallback", {
|
|
194
|
+
kind: "return",
|
|
195
|
+
value: {
|
|
196
|
+
kind: "recordLit",
|
|
197
|
+
fields: [{ name: "x", value: { kind: "numLit", value: 0, type: F64, loc } }],
|
|
198
|
+
type: element,
|
|
199
|
+
loc,
|
|
200
|
+
},
|
|
201
|
+
loc,
|
|
202
|
+
}));
|
|
203
|
+
expect(validateModule(mod)).toEqual([]);
|
|
204
|
+
const body = workBody(mod);
|
|
205
|
+
expect(body).not.toContain("narrow.present");
|
|
206
|
+
expect(body).toContain("fallback");
|
|
207
|
+
});
|
|
208
|
+
//# sourceMappingURL=checked-narrows.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checked-narrows.test.js","sourceRoot":"","sources":["../../../src/backend/llvm/checked-narrows.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* implementations directly. Runtime EventEmitter and stream subclasses embed
|
|
4
4
|
* their runtime prefixes ahead of user fields. */
|
|
5
5
|
import type { IrClassDef, IrFunction, IrModule, IrType, IrUnionDef } from "../../ir/ir.js";
|
|
6
|
+
import { NullableRefFields } from "./nullable-fields.js";
|
|
7
|
+
import type { Int32Slots } from "../../ir/int32-slots.js";
|
|
6
8
|
import { type ShapeHost } from "./shapes.js";
|
|
7
9
|
/** One virtual method slot of a hierarchy: the ROOT-MOST declaring class
|
|
8
10
|
* owns the slot; its declaration's IrFunction fixes the slot's ABI (the
|
|
@@ -27,6 +29,8 @@ export declare class LlClassMeta {
|
|
|
27
29
|
pre: number;
|
|
28
30
|
post: number;
|
|
29
31
|
}[];
|
|
32
|
+
/** Type-only references retain layouts without retaining construction. */
|
|
33
|
+
constructorRetained: boolean;
|
|
30
34
|
constructor(def: IrClassDef);
|
|
31
35
|
}
|
|
32
36
|
/** The class graph: link base/children, number the forest in preorder
|
|
@@ -45,6 +49,13 @@ export declare function classMembershipIntervals(classes: ReadonlyMap<string, Ll
|
|
|
45
49
|
/** Runtime class-value tests normally use one interval. Only generic
|
|
46
50
|
* families with disjoint storage subtrees require this shared dispatch. */
|
|
47
51
|
export declare function emitClassMembershipHelper(classes: ReadonlyMap<string, LlClassMeta>, sizeType: string): string[];
|
|
52
|
+
/** The root's slot list as seen by one class: the implementation the class
|
|
53
|
+
* dispatches to, or null outside the slot's declaring subtree / on a
|
|
54
|
+
* fully-abstract chain (vtEntriesFor, ported). */
|
|
55
|
+
export declare function vtEntriesFor(meta: LlClassMeta): {
|
|
56
|
+
slot: LlVtSlot;
|
|
57
|
+
impl: LlClassMeta | null;
|
|
58
|
+
}[];
|
|
48
59
|
/** The LLVM struct type name a class's instances GEP through: the runtime
|
|
49
60
|
* error classes share the runtime's ScrError layout (emitted subclasses
|
|
50
61
|
* embed it as their prefix); every emitted class has its own %sc_o_*. */
|
|
@@ -65,13 +76,17 @@ export interface ClassHost extends ShapeHost {
|
|
|
65
76
|
readonly unionsById: Map<string, IrUnionDef>;
|
|
66
77
|
unitInstanceRef(unionId: string, tag: number): string;
|
|
67
78
|
cstr(text: string): string;
|
|
79
|
+
/** The symbol a vtable stores for a method implementation (its owned
|
|
80
|
+
* entry point unless the slot's calling convention borrows; see
|
|
81
|
+
* LlEmitter.virtualEntry). */
|
|
82
|
+
virtualEntry?(implFn: string): string;
|
|
68
83
|
}
|
|
69
84
|
/** Per-class LLVM emission for every non-runtime class: the struct types
|
|
70
85
|
* (`typeDefs`), the vtable struct types + per-class constant instances,
|
|
71
86
|
* and the new/retain/release (+releaseDirect for hierarchy members,
|
|
72
87
|
* +trace/gcFree for cycle-capable shapes) definitions (`defs`). Mirrors
|
|
73
88
|
* emitStructDefs + emitHierarchyClassHelpers. */
|
|
74
|
-
export declare function emitClassShapes(host: ClassHost, mod: IrModule, metaMap: Map<string, LlClassMeta
|
|
89
|
+
export declare function emitClassShapes(host: ClassHost, mod: IrModule, metaMap: Map<string, LlClassMeta>, nullable?: NullableRefFields, int32?: Int32Slots): {
|
|
75
90
|
typeDefs: string[];
|
|
76
91
|
defs: string[];
|
|
77
92
|
};
|
|
@@ -2,8 +2,10 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
2
2
|
import { isRefCounted, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, } from "../../ir/ir.js";
|
|
3
3
|
import { streamRooted, undefinedArmTag } from "../../ir/analysis.js";
|
|
4
4
|
import { mangleClassGcFree, mangleClassNew, mangleClassObj, mangleClassRelease, mangleClassReleaseDirect, mangleClassRetain, mangleClassStruct, mangleClassTrace, mangleCtorThunk, mangleFunction, mangleGlobal, mangleVtInstance, mangleVtStruct, } from "../mangle.js";
|
|
5
|
+
import { emitObjectAlloc, emitObjectFree } from "./alloc.js";
|
|
5
6
|
import { llvmCommentText } from "./common.js";
|
|
6
|
-
import {
|
|
7
|
+
import { NullableRefFields } from "./nullable-fields.js";
|
|
8
|
+
import { cycleRootLines, FN_ATTRS, cycleDeadLines, llFieldType, releaseBody, releaseFastPath, needsBoundedRelease, releaseSym, retainBody, traceAdapter, } from "./shapes.js";
|
|
7
9
|
/** Per-class node of the class graph. */
|
|
8
10
|
export class LlClassMeta {
|
|
9
11
|
def;
|
|
@@ -16,6 +18,8 @@ export class LlClassMeta {
|
|
|
16
18
|
/** Root classes: the hierarchy's slots in DFS-declaration order. */
|
|
17
19
|
slots = [];
|
|
18
20
|
membership = [];
|
|
21
|
+
/** Type-only references retain layouts without retaining construction. */
|
|
22
|
+
constructorRetained = false;
|
|
19
23
|
constructor(def) {
|
|
20
24
|
this.def = def;
|
|
21
25
|
this.root = this;
|
|
@@ -30,7 +34,9 @@ export class LlClassMeta {
|
|
|
30
34
|
export function buildClassGraph(mod, fnByName) {
|
|
31
35
|
const metaMap = new Map();
|
|
32
36
|
for (const cls of mod.classes ?? []) {
|
|
33
|
-
|
|
37
|
+
const meta = new LlClassMeta(cls);
|
|
38
|
+
meta.constructorRetained = fnByName.has(`%${cls.name}.constructor`);
|
|
39
|
+
metaMap.set(cls.name, meta);
|
|
34
40
|
}
|
|
35
41
|
for (const meta of metaMap.values()) {
|
|
36
42
|
if (meta.def.base === undefined)
|
|
@@ -153,7 +159,7 @@ export function emitClassMembershipHelper(classes, sizeType) {
|
|
|
153
159
|
/** The root's slot list as seen by one class: the implementation the class
|
|
154
160
|
* dispatches to, or null outside the slot's declaring subtree / on a
|
|
155
161
|
* fully-abstract chain (vtEntriesFor, ported). */
|
|
156
|
-
function vtEntriesFor(meta) {
|
|
162
|
+
export function vtEntriesFor(meta) {
|
|
157
163
|
return meta.root.slots.map((slot) => {
|
|
158
164
|
if (!(slot.declarer.pre <= meta.pre && meta.pre <= slot.declarer.post)) {
|
|
159
165
|
return { slot, impl: null };
|
|
@@ -163,7 +169,7 @@ function vtEntriesFor(meta) {
|
|
|
163
169
|
return { slot, impl: c };
|
|
164
170
|
}
|
|
165
171
|
}
|
|
166
|
-
if (meta.def.abstract === true)
|
|
172
|
+
if (meta.def.abstract === true || !meta.constructorRetained)
|
|
167
173
|
return { slot, impl: null };
|
|
168
174
|
throw new InternalCompilerError(`llvm emitter bug: no implementation of ${slot.method} for ${meta.def.name}`);
|
|
169
175
|
});
|
|
@@ -215,13 +221,16 @@ export function classFieldIndex(meta, field) {
|
|
|
215
221
|
* at the interned unit instance; dyn fields start at native undefined;
|
|
216
222
|
* jsval fields (an `any` class field under --dynamic) start at the engine's
|
|
217
223
|
* undefined cell. */
|
|
218
|
-
function undefFieldInits(host, meta) {
|
|
224
|
+
function undefFieldInits(host, meta, nullable) {
|
|
219
225
|
const out = [];
|
|
220
226
|
meta.def.fields.forEach((f, i) => {
|
|
221
227
|
// Error.cause uses NULL for absence; an options constructor installs
|
|
222
228
|
// a value only when the cause property is present.
|
|
223
229
|
if (f.name === "%cause")
|
|
224
230
|
return;
|
|
231
|
+
// A nullable-pointer field's zeroed slot already is its unit arm.
|
|
232
|
+
if (nullable?.get(meta.def.name, f.name))
|
|
233
|
+
return;
|
|
225
234
|
const { index } = classFieldIndex(meta, f.name);
|
|
226
235
|
if (f.type.kind === "jsval" || f.type.kind === "dyn") {
|
|
227
236
|
const undefinedFn = f.type.kind === "dyn" ? "scr_dyn_undefined" : "scr_jsval_undefined";
|
|
@@ -243,17 +252,21 @@ function undefFieldInits(host, meta) {
|
|
|
243
252
|
* and the new/retain/release (+releaseDirect for hierarchy members,
|
|
244
253
|
* +trace/gcFree for cycle-capable shapes) definitions (`defs`). Mirrors
|
|
245
254
|
* emitStructDefs + emitHierarchyClassHelpers. */
|
|
246
|
-
export function emitClassShapes(host, mod, metaMap) {
|
|
255
|
+
export function emitClassShapes(host, mod, metaMap, nullable, int32) {
|
|
247
256
|
const typeDefs = [];
|
|
248
257
|
const defs = [];
|
|
249
258
|
const emitted = (mod.classes ?? []).filter((c) => !c.runtime);
|
|
250
259
|
if (emitted.length === 0)
|
|
251
260
|
return { typeDefs, defs };
|
|
252
|
-
host.
|
|
253
|
-
|
|
261
|
+
const audit = host.objectAudit !== false;
|
|
262
|
+
if (audit) {
|
|
263
|
+
host.declare(`declare void @scr_obj_alloc_note()`);
|
|
264
|
+
host.declare(`declare void @scr_obj_free_note()`);
|
|
265
|
+
}
|
|
254
266
|
for (const cls of emitted) {
|
|
255
267
|
const meta = metaMap.get(cls.name);
|
|
256
|
-
|
|
268
|
+
// Whole-program int32 fields (int32-slots.ts) store the exact i32.
|
|
269
|
+
const fieldTys = cls.fields.map((f) => int32?.isField(cls.name, f.name) ? "i32" : llFieldType(f.type));
|
|
257
270
|
// Emitter subclasses embed ScrEmitter's remaining prefix (the registry
|
|
258
271
|
// and display-name slots) between the vtable word and the field list;
|
|
259
272
|
// stream subclasses add the state pointer — upcasts to ScrEmitter* /
|
|
@@ -294,7 +307,7 @@ export function emitClassShapes(host, mod, metaMap) {
|
|
|
294
307
|
continue;
|
|
295
308
|
const entries = vtEntriesFor(meta).map(({ slot, impl }) => impl === null
|
|
296
309
|
? `ptr null` // outside the declaring subtree / fully-abstract chain
|
|
297
|
-
: `ptr @${mangleFunction(`%${impl.def.name}.${slot.method}`)}`);
|
|
310
|
+
: `ptr @${host.virtualEntry?.(`%${impl.def.name}.${slot.method}`) ?? mangleFunction(`%${impl.def.name}.${slot.method}`)}`);
|
|
298
311
|
const head = `%ScrVt { ${host.sizeType} ${meta.pre}, ${host.sizeType} ${meta.post}, ptr @${mangleClassReleaseDirect(cls.name)} }`;
|
|
299
312
|
defs.push(`@${mangleVtInstance(cls.name)} = internal constant %${mangleVtStruct(meta.root.def.name)} ` +
|
|
300
313
|
`{ ${[head, ...entries].join(", ")} } ; class ${cls.name}`, ``);
|
|
@@ -306,8 +319,15 @@ export function emitClassShapes(host, mod, metaMap) {
|
|
|
306
319
|
const isEmitterRooted = emitterRooted(meta);
|
|
307
320
|
const isStreamRooted = streamRooted(meta);
|
|
308
321
|
const fieldIndex = (i) => fieldBase(meta) + i;
|
|
322
|
+
// Teardown, trace and gcFree see each slot's storage type: a nullable
|
|
323
|
+
// class field holds the instance pointer (NULL for the unit arm), and
|
|
324
|
+
// every class retain/release/visit entry point is NULL-tolerant.
|
|
309
325
|
const indexedFields = [
|
|
310
|
-
...cls.fields.map((f, i) => ({
|
|
326
|
+
...cls.fields.map((f, i) => ({
|
|
327
|
+
name: f.name,
|
|
328
|
+
type: nullable?.storageType(cls.name, f.name, f.type) ?? f.type,
|
|
329
|
+
index: fieldIndex(i),
|
|
330
|
+
})),
|
|
311
331
|
];
|
|
312
332
|
const refFields = indexedFields.filter((f) => isRefCounted(f.type));
|
|
313
333
|
const bounded = isEmitterRooted ||
|
|
@@ -327,9 +347,9 @@ export function emitClassShapes(host, mod, metaMap) {
|
|
|
327
347
|
};
|
|
328
348
|
const regCall = (tag, entry, tail) => prefixCall(tag, 2, entry, tail, "EventEmitter prefix");
|
|
329
349
|
const stCall = (tag, entry, tail) => prefixCall(tag, 4, entry, tail, "stream state (ScrStream prefix)");
|
|
330
|
-
// retain: NULL-tolerant, immortal-skip
|
|
331
|
-
//
|
|
332
|
-
defs.push(...retainBody(host, mangleClassRetain(cls.name),
|
|
350
|
+
// retain: NULL-tolerant, immortal-skip — layout-generic (rc at 0), so
|
|
351
|
+
// hierarchy members need no dispatch.
|
|
352
|
+
defs.push(...retainBody(host, mangleClassRetain(cls.name), `retain ${cls.name}`), ``);
|
|
333
353
|
// The field-releasing teardown body shared by both release shapes
|
|
334
354
|
// (the public one on standalone classes, the DIRECT one on hierarchy
|
|
335
355
|
// members). Runs at rc == 0.
|
|
@@ -341,22 +361,24 @@ export function emitClassShapes(host, mod, metaMap) {
|
|
|
341
361
|
lines.push(...regCall("td", "scr_emitter_reg_drop", ""));
|
|
342
362
|
if (isStreamRooted)
|
|
343
363
|
lines.push(...stCall("tds", "scr_stream_st_release", ""));
|
|
344
|
-
lines.push(
|
|
345
|
-
if (traced) {
|
|
346
|
-
host.declare(`declare void @scr_cyc_free(ptr)`);
|
|
347
|
-
lines.push(` call void @scr_cyc_free(ptr %o)`);
|
|
348
|
-
}
|
|
349
|
-
else {
|
|
350
|
-
host.declare(`declare void @free(ptr)`);
|
|
351
|
-
host.declare(`declare void @scr_weak_dispose(ptr)`);
|
|
352
|
-
lines.push(` call void @scr_weak_dispose(ptr %o)`, ` call void @free(ptr %o)`);
|
|
353
|
-
}
|
|
364
|
+
lines.push(...emitObjectFree(host, traced));
|
|
354
365
|
};
|
|
355
366
|
if (meta.hierarchy) {
|
|
356
367
|
// Public release: NULL/immortal checks, then dispatch through the
|
|
357
368
|
// object's vtable so a base-typed release tears down the DERIVED
|
|
358
|
-
// object (scr_error_release's contract exactly).
|
|
359
|
-
|
|
369
|
+
// object (scr_error_release's contract exactly). In a hierarchy the
|
|
370
|
+
// program owns end to end (no runtime root), every member shares the
|
|
371
|
+
// rc word and the header decision (cycle-analysis groups hierarchies),
|
|
372
|
+
// so a release that leaves the object alive is the same for every
|
|
373
|
+
// class: the inlinable fast path decrements without the indirect call,
|
|
374
|
+
// and only the last reference reaches the dispatching release.
|
|
375
|
+
const userRooted = meta.root.def.runtime !== true;
|
|
376
|
+
const dispatchName = userRooted
|
|
377
|
+
? `${mangleClassRelease(cls.name)}_slow`
|
|
378
|
+
: mangleClassRelease(cls.name);
|
|
379
|
+
if (userRooted)
|
|
380
|
+
defs.push(...releaseFastPath(host, mangleClassRelease(cls.name), dispatchName, traced, `release ${cls.name}`), ``);
|
|
381
|
+
defs.push(`define internal void @${dispatchName}(ptr %o) ${userRooted ? "noinline " : ""}${FN_ATTRS} { ; release ${cls.name} (dispatches)`, `entry:`, ` %isnull = icmp eq ptr %o, null`, ` br i1 %isnull, label %done, label %check`, `check:`, ` %rc = load ${host.sizeType}, ptr %o`, ` %imm = icmp eq ${host.sizeType} %rc, -1`, ` br i1 %imm, label %done, label %disp`, `disp:`, ` %vtp = getelementptr inbounds %${struct}, ptr %o, i64 0, i32 1`, ` %vt = load ptr, ptr %vtp`, ` %relp = getelementptr inbounds %ScrVt, ptr %vt, i64 0, i32 2`, ` %rel = load ptr, ptr %relp`, ` call void %rel(ptr %o) ; the DYNAMIC class's teardown`, ` br label %done`, `done:`, ` ret void`, `}`, ``);
|
|
360
382
|
// Direct release (the vtable entry): the class's own teardown. The
|
|
361
383
|
// caller already handled NULL/immortal.
|
|
362
384
|
const reld = [
|
|
@@ -369,10 +391,8 @@ export function emitClassShapes(host, mod, metaMap) {
|
|
|
369
391
|
` br i1 %dead, label %free, label %${traced ? "root" : "done"}`,
|
|
370
392
|
`free:`,
|
|
371
393
|
];
|
|
372
|
-
if (traced)
|
|
373
|
-
|
|
374
|
-
reld.push(` call void @scr_cyc_on_dead(ptr %o)`);
|
|
375
|
-
}
|
|
394
|
+
if (traced)
|
|
395
|
+
reld.push(...cycleDeadLines(host, "teardown"));
|
|
376
396
|
if (bounded) {
|
|
377
397
|
const destroy = `${mangleClassReleaseDirect(cls.name)}_destroy`;
|
|
378
398
|
const destroyBody = [
|
|
@@ -388,10 +408,8 @@ export function emitClassShapes(host, mod, metaMap) {
|
|
|
388
408
|
else
|
|
389
409
|
teardown(reld);
|
|
390
410
|
reld.push(` br label %done`);
|
|
391
|
-
if (traced)
|
|
392
|
-
|
|
393
|
-
reld.push(`root:`, ` call void @scr_cyc_on_release(ptr %o) ; possible cycle root; may collect`, ` br label %done`);
|
|
394
|
-
}
|
|
411
|
+
if (traced)
|
|
412
|
+
reld.push(`root:`, ...cycleRootLines(host, "done"));
|
|
395
413
|
reld.push(`done:`, ` ret void`, `}`, ``);
|
|
396
414
|
defs.push(...reld);
|
|
397
415
|
}
|
|
@@ -402,21 +420,15 @@ export function emitClassShapes(host, mod, metaMap) {
|
|
|
402
420
|
}
|
|
403
421
|
// new: zeroed allocation, rc = 1, the vtable word on hierarchy
|
|
404
422
|
// members, undefined-admitting union fields at the interned unit
|
|
405
|
-
// instance
|
|
406
|
-
//
|
|
423
|
+
// instance. Traced shapes allocate with the collector header; alloc.ts
|
|
424
|
+
// inlines the allocator fast paths and the alloc note.
|
|
407
425
|
const nw = [
|
|
408
426
|
`define internal ptr @${mangleClassNew(cls.name)}() ${FN_ATTRS} { ; new ${cls.name}`,
|
|
409
427
|
`entry:`,
|
|
410
428
|
];
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
host.declare(`declare ptr @calloc(${host.sizeType}, ${host.sizeType})`);
|
|
417
|
-
host.needOom();
|
|
418
|
-
nw.push(` %o = call ptr @calloc(${host.sizeType} 1, ${host.sizeType} ${sizeOf})`, ` %isnull = icmp eq ptr %o, null`, ` br i1 %isnull, label %oom, label %ok`, `oom:`, ` call void @sc_oom()`, ` unreachable`, `ok:`);
|
|
419
|
-
}
|
|
429
|
+
nw.push(...emitObjectAlloc(host, sizeOf, traced
|
|
430
|
+
? { trace: `@${mangleClassTrace(cls.name)}`, free: `@${mangleClassGcFree(cls.name)}` }
|
|
431
|
+
: null, meta.hierarchy ? 16 : 8));
|
|
420
432
|
nw.push(` store ${host.sizeType} 1, ptr %o`);
|
|
421
433
|
if (meta.hierarchy) {
|
|
422
434
|
nw.push(` %vtp = getelementptr inbounds %${struct}, ptr %o, i64 0, i32 1`, ` store ptr @${mangleVtInstance(cls.name)}, ptr %vtp`);
|
|
@@ -430,8 +442,8 @@ export function emitClassShapes(host, mod, metaMap) {
|
|
|
430
442
|
: cls.name;
|
|
431
443
|
nw.push(` %clsp = getelementptr inbounds %${struct}, ptr %o, i64 0, i32 3`, ` store ptr ${host.cstr(displayName)}, ptr %clsp ; EventEmitter prefix display name`);
|
|
432
444
|
}
|
|
433
|
-
nw.push(...undefFieldInits(host, meta));
|
|
434
|
-
nw.push(`
|
|
445
|
+
nw.push(...undefFieldInits(host, meta, nullable));
|
|
446
|
+
nw.push(` ret ptr %o`, `}`, ``);
|
|
435
447
|
defs.push(...nw);
|
|
436
448
|
if (traced) {
|
|
437
449
|
// trace: visit exactly the cycle-capable fields; gcFree: release
|
|
@@ -464,8 +476,7 @@ export function emitClassShapes(host, mod, metaMap) {
|
|
|
464
476
|
untracedRefFields.forEach((f, i) => {
|
|
465
477
|
gf.push(` %f${i} = getelementptr inbounds %${struct}, ptr %o, i64 0, i32 ${f.index}`, ` %v${i} = load ptr, ptr %f${i}`, ` call void ${releaseSym(host, f.type)}(ptr %v${i}) ; ${llvmCommentText(f.name)} (acyclic)`);
|
|
466
478
|
});
|
|
467
|
-
|
|
468
|
-
gf.push(` call void @scr_obj_free_note()`, ` call void @scr_cyc_free(ptr %o)`, ` ret void`, `}`, ``);
|
|
479
|
+
gf.push(...emitObjectFree(host, true), ` ret void`, `}`, ``);
|
|
469
480
|
defs.push(...gf);
|
|
470
481
|
}
|
|
471
482
|
}
|