@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,81 @@
|
|
|
1
|
+
import { everyStmtList, mapExprChildren, mapStmtChildren } from "./traverse.js";
|
|
2
|
+
/** Module constants such as `const DOT = 0x2e` read as their literal.
|
|
3
|
+
*
|
|
4
|
+
* A module-level binding is a global that the module initializer stores
|
|
5
|
+
* once; every other function loads it (a thread-local load in worker
|
|
6
|
+
* programs), which also hides the value from integer ranges, switch
|
|
7
|
+
* dispatch and LLVM's constant folding. When the global is immutable, has
|
|
8
|
+
* exactly one write in the program and that write stores a number or
|
|
9
|
+
* boolean literal, every read sees that literal: reads that could run before
|
|
10
|
+
* the store carry the frontend's initialization flag (`initFlag`) or a TDZ
|
|
11
|
+
* sentinel, and those globals are left alone. The store stays, so module
|
|
12
|
+
* namespace views and debuggers still find the value in the global. Library
|
|
13
|
+
* builds keep their globals: a host may observe them across the boundary. */
|
|
14
|
+
export function foldConstantGlobals(mod) {
|
|
15
|
+
if (mod.lib || !mod.globals?.length)
|
|
16
|
+
return mod;
|
|
17
|
+
const candidates = new Set();
|
|
18
|
+
for (const g of mod.globals)
|
|
19
|
+
if (!g.mutable &&
|
|
20
|
+
g.tdz !== true &&
|
|
21
|
+
g.initFlag === undefined &&
|
|
22
|
+
(g.type.kind === "f64" || g.type.kind === "bool"))
|
|
23
|
+
candidates.add(g.id);
|
|
24
|
+
if (candidates.size === 0)
|
|
25
|
+
return mod;
|
|
26
|
+
const writes = new Map();
|
|
27
|
+
const values = new Map();
|
|
28
|
+
const write = (id, value) => {
|
|
29
|
+
if (!candidates.has(id))
|
|
30
|
+
return;
|
|
31
|
+
writes.set(id, (writes.get(id) ?? 0) + 1);
|
|
32
|
+
if (value && (value.kind === "numLit" || value.kind === "boolLit"))
|
|
33
|
+
values.set(id, value);
|
|
34
|
+
else
|
|
35
|
+
values.delete(id);
|
|
36
|
+
};
|
|
37
|
+
for (const fn of mod.functions)
|
|
38
|
+
everyStmtList(fn.body, {
|
|
39
|
+
// Every node other than a read that names the binding is a write
|
|
40
|
+
// (assignments, loop and catch bindings, compound updates); only a
|
|
41
|
+
// plain assignment or declaration contributes a value.
|
|
42
|
+
stmt: (s) => {
|
|
43
|
+
if (s.kind === "assign")
|
|
44
|
+
write(s.localId, s.value);
|
|
45
|
+
else if (s.kind === "varDecl")
|
|
46
|
+
write(s.localId, s.init);
|
|
47
|
+
else if ("localId" in s && typeof s.localId === "string")
|
|
48
|
+
write(s.localId, null);
|
|
49
|
+
return true;
|
|
50
|
+
},
|
|
51
|
+
expr: (e) => {
|
|
52
|
+
if (e.kind !== "varRef" && "localId" in e && typeof e.localId === "string")
|
|
53
|
+
write(e.localId, null);
|
|
54
|
+
return true;
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
const constants = new Map();
|
|
58
|
+
for (const [id, value] of values)
|
|
59
|
+
if (writes.get(id) === 1)
|
|
60
|
+
constants.set(id, value);
|
|
61
|
+
if (constants.size === 0)
|
|
62
|
+
return mod;
|
|
63
|
+
const reads = (e) => !(e.kind === "varRef" && constants.has(e.localId));
|
|
64
|
+
const rewriteExpr = (e) => {
|
|
65
|
+
if (e.kind === "varRef") {
|
|
66
|
+
const value = constants.get(e.localId);
|
|
67
|
+
return value ? { ...value, type: e.type, loc: e.loc } : e;
|
|
68
|
+
}
|
|
69
|
+
return mapExprChildren(e, rewriteExpr, rewriteStmt);
|
|
70
|
+
};
|
|
71
|
+
const rewriteStmt = (s) => mapStmtChildren(s, rewriteExpr, rewriteStmt);
|
|
72
|
+
let changed = false;
|
|
73
|
+
const functions = mod.functions.map((fn) => {
|
|
74
|
+
if (everyStmtList(fn.body, { stmt: () => true, expr: reads }))
|
|
75
|
+
return fn;
|
|
76
|
+
changed = true;
|
|
77
|
+
return { ...fn, body: fn.body.map(rewriteStmt) };
|
|
78
|
+
});
|
|
79
|
+
return changed ? { ...mod, functions } : mod;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=constant-globals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constant-globals.js","sourceRoot":"","sources":["../../src/ir/constant-globals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
import { foldConstantGlobals } from "./constant-globals.js";
|
|
3
|
+
import { F64, VOID } from "./ir.js";
|
|
4
|
+
const loc = { file: "constant-globals.ts", start: 0, end: 0 };
|
|
5
|
+
const num = (value) => ({ loc, kind: "numLit", value, type: F64 });
|
|
6
|
+
const ref = (localId) => ({ loc, kind: "varRef", localId, type: F64 });
|
|
7
|
+
const assign = (localId, value) => ({
|
|
8
|
+
loc,
|
|
9
|
+
kind: "assign",
|
|
10
|
+
localId,
|
|
11
|
+
value,
|
|
12
|
+
});
|
|
13
|
+
const ret = (value) => ({ loc, kind: "return", value });
|
|
14
|
+
const fn = (name, body) => ({
|
|
15
|
+
loc,
|
|
16
|
+
name,
|
|
17
|
+
params: [],
|
|
18
|
+
locals: [],
|
|
19
|
+
returnType: name === "%init" ? VOID : F64,
|
|
20
|
+
body,
|
|
21
|
+
});
|
|
22
|
+
const global = (id, extra = {}) => ({
|
|
23
|
+
id,
|
|
24
|
+
name: id,
|
|
25
|
+
type: F64,
|
|
26
|
+
mutable: false,
|
|
27
|
+
...extra,
|
|
28
|
+
});
|
|
29
|
+
test("immutable globals stored once with a literal read as that literal", () => {
|
|
30
|
+
const mod = {
|
|
31
|
+
irVersion: 15,
|
|
32
|
+
sourceFile: "constant-globals.ts",
|
|
33
|
+
entry: "%init",
|
|
34
|
+
functions: [
|
|
35
|
+
fn("%init", [
|
|
36
|
+
assign("%g.DOT", num(46)),
|
|
37
|
+
assign("%g.LATE", num(7)),
|
|
38
|
+
assign("%g.TWICE", num(1)),
|
|
39
|
+
assign("%g.TWICE", num(2)),
|
|
40
|
+
assign("%g.MUT", num(3)),
|
|
41
|
+
]),
|
|
42
|
+
fn("read", [
|
|
43
|
+
ret({
|
|
44
|
+
loc,
|
|
45
|
+
kind: "bin",
|
|
46
|
+
op: "+",
|
|
47
|
+
left: ref("%g.DOT"),
|
|
48
|
+
right: {
|
|
49
|
+
loc,
|
|
50
|
+
kind: "bin",
|
|
51
|
+
op: "+",
|
|
52
|
+
left: ref("%g.LATE"),
|
|
53
|
+
right: {
|
|
54
|
+
loc,
|
|
55
|
+
kind: "bin",
|
|
56
|
+
op: "+",
|
|
57
|
+
left: ref("%g.TWICE"),
|
|
58
|
+
right: ref("%g.MUT"),
|
|
59
|
+
type: F64,
|
|
60
|
+
},
|
|
61
|
+
type: F64,
|
|
62
|
+
},
|
|
63
|
+
type: F64,
|
|
64
|
+
}),
|
|
65
|
+
]),
|
|
66
|
+
],
|
|
67
|
+
classes: [],
|
|
68
|
+
records: [],
|
|
69
|
+
unions: [],
|
|
70
|
+
globals: [
|
|
71
|
+
global("%g.DOT"),
|
|
72
|
+
global("%g.LATE", { initFlag: "%g.LATE.initialized" }),
|
|
73
|
+
global("%g.TWICE"),
|
|
74
|
+
global("%g.MUT", { mutable: true }),
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
const folded = foldConstantGlobals(mod);
|
|
78
|
+
const reads = [];
|
|
79
|
+
const walk = (e) => {
|
|
80
|
+
if (e.kind === "varRef")
|
|
81
|
+
reads.push(e.localId);
|
|
82
|
+
else if (e.kind === "numLit")
|
|
83
|
+
reads.push(String(e.value));
|
|
84
|
+
else if (e.kind === "bin") {
|
|
85
|
+
walk(e.left);
|
|
86
|
+
walk(e.right);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const body = folded.functions.find((f) => f.name === "read").body[0];
|
|
90
|
+
if (body.kind === "return" && body.value)
|
|
91
|
+
walk(body.value);
|
|
92
|
+
expect(reads).toEqual(["46", "%g.LATE", "%g.TWICE", "%g.MUT"]);
|
|
93
|
+
// The initializer keeps its store; the input module is not modified.
|
|
94
|
+
expect(folded.functions[0]).toBe(mod.functions[0]);
|
|
95
|
+
expect(mod.functions[1].body[0]).not.toBe(body);
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=constant-globals.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constant-globals.test.js","sourceRoot":"","sources":["../../src/ir/constant-globals.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type IrClassDef, type IrModule } from "./ir.js";
|
|
2
|
+
/** Whole-program final reference fields.
|
|
3
|
+
*
|
|
4
|
+
* A reference-counted class field is final when every write the program can
|
|
5
|
+
* make to it is a constructor of its family storing through that
|
|
6
|
+
* constructor's own `this`. Outside the constructors such a field never
|
|
7
|
+
* changes, so while its object is alive the field keeps its value alive: a
|
|
8
|
+
* read of `o.f` may be borrowed for as long as `o` itself is (`this.scanner`
|
|
9
|
+
* inside a method, across any call), without a retain and a release.
|
|
10
|
+
* Constructors are excluded from that use, because they are where the field
|
|
11
|
+
* changes; so are async functions and generators, whose suspensions let
|
|
12
|
+
* other code (a constructor that is still running) continue.
|
|
13
|
+
*
|
|
14
|
+
* Writes the IR does not show disqualify fields up front: library builds
|
|
15
|
+
* (instances cross a native boundary), live dynamic views whose stores can
|
|
16
|
+
* name the field (see dynamicFieldStores), and classes with runtime-provided
|
|
17
|
+
* or generic ancestors. Generated stores only initialize fresh objects or
|
|
18
|
+
* tear down dead ones. */
|
|
19
|
+
export declare class FinalFields {
|
|
20
|
+
private readonly classes;
|
|
21
|
+
private readonly finals;
|
|
22
|
+
private readonly familyOf;
|
|
23
|
+
/** Disqualified families and the first reason, for tests. */
|
|
24
|
+
readonly reasons: Map<string, string>;
|
|
25
|
+
constructor(classes?: ReadonlyMap<string, IrClassDef>);
|
|
26
|
+
/** The topmost class in the base chain declaring the field, and the field. */
|
|
27
|
+
family(className: string, field: string): string | null;
|
|
28
|
+
isFinal(className: string, field: string): boolean;
|
|
29
|
+
get size(): number;
|
|
30
|
+
add(family: string): void;
|
|
31
|
+
drop(family: string, why: string): void;
|
|
32
|
+
}
|
|
33
|
+
/** `%C.constructor`'s class name, or null for any other function. */
|
|
34
|
+
export declare function constructorClass(fnName: string): string | null;
|
|
35
|
+
export declare function analyzeFinalFields(mod: IrModule): FinalFields;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { isRefCounted } from "./ir.js";
|
|
2
|
+
import { dynamicFieldStores } from "./int32-slots.js";
|
|
3
|
+
import { everyExprChild, everyStmtChild } from "./traverse.js";
|
|
4
|
+
/** Whole-program final reference fields.
|
|
5
|
+
*
|
|
6
|
+
* A reference-counted class field is final when every write the program can
|
|
7
|
+
* make to it is a constructor of its family storing through that
|
|
8
|
+
* constructor's own `this`. Outside the constructors such a field never
|
|
9
|
+
* changes, so while its object is alive the field keeps its value alive: a
|
|
10
|
+
* read of `o.f` may be borrowed for as long as `o` itself is (`this.scanner`
|
|
11
|
+
* inside a method, across any call), without a retain and a release.
|
|
12
|
+
* Constructors are excluded from that use, because they are where the field
|
|
13
|
+
* changes; so are async functions and generators, whose suspensions let
|
|
14
|
+
* other code (a constructor that is still running) continue.
|
|
15
|
+
*
|
|
16
|
+
* Writes the IR does not show disqualify fields up front: library builds
|
|
17
|
+
* (instances cross a native boundary), live dynamic views whose stores can
|
|
18
|
+
* name the field (see dynamicFieldStores), and classes with runtime-provided
|
|
19
|
+
* or generic ancestors. Generated stores only initialize fresh objects or
|
|
20
|
+
* tear down dead ones. */
|
|
21
|
+
export class FinalFields {
|
|
22
|
+
classes;
|
|
23
|
+
finals = new Set();
|
|
24
|
+
familyOf = new Map();
|
|
25
|
+
/** Disqualified families and the first reason, for tests. */
|
|
26
|
+
reasons = new Map();
|
|
27
|
+
constructor(classes = new Map()) {
|
|
28
|
+
this.classes = classes;
|
|
29
|
+
}
|
|
30
|
+
/** The topmost class in the base chain declaring the field, and the field. */
|
|
31
|
+
family(className, field) {
|
|
32
|
+
const key = `${className}\0${field}`;
|
|
33
|
+
const cached = this.familyOf.get(key);
|
|
34
|
+
if (cached !== undefined)
|
|
35
|
+
return cached;
|
|
36
|
+
let owner = this.classes.get(className);
|
|
37
|
+
let result = null;
|
|
38
|
+
if (owner?.fields.some((f) => f.name === field)) {
|
|
39
|
+
for (;;) {
|
|
40
|
+
const base = owner.base ? this.classes.get(owner.base) : undefined;
|
|
41
|
+
if (!base?.fields.some((f) => f.name === field))
|
|
42
|
+
break;
|
|
43
|
+
owner = base;
|
|
44
|
+
}
|
|
45
|
+
result = `${owner.name}\0${field}`;
|
|
46
|
+
}
|
|
47
|
+
this.familyOf.set(key, result);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
isFinal(className, field) {
|
|
51
|
+
if (this.finals.size === 0)
|
|
52
|
+
return false;
|
|
53
|
+
const family = this.family(className, field);
|
|
54
|
+
return family !== null && this.finals.has(family);
|
|
55
|
+
}
|
|
56
|
+
get size() {
|
|
57
|
+
return this.finals.size;
|
|
58
|
+
}
|
|
59
|
+
/* ── construction (analyzeFinalFields only) ── */
|
|
60
|
+
add(family) {
|
|
61
|
+
this.finals.add(family);
|
|
62
|
+
}
|
|
63
|
+
drop(family, why) {
|
|
64
|
+
if (!this.reasons.has(family))
|
|
65
|
+
this.reasons.set(family, why);
|
|
66
|
+
this.finals.delete(family);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const CONSTRUCTOR_SUFFIX = ".constructor";
|
|
70
|
+
/** `%C.constructor`'s class name, or null for any other function. */
|
|
71
|
+
export function constructorClass(fnName) {
|
|
72
|
+
return fnName.startsWith("%") && fnName.endsWith(CONSTRUCTOR_SUFFIX)
|
|
73
|
+
? fnName.slice(1, -CONSTRUCTOR_SUFFIX.length)
|
|
74
|
+
: null;
|
|
75
|
+
}
|
|
76
|
+
export function analyzeFinalFields(mod) {
|
|
77
|
+
const classes = new Map((mod.classes ?? []).map((c) => [c.name, c]));
|
|
78
|
+
const finals = new FinalFields(classes);
|
|
79
|
+
if (mod.lib)
|
|
80
|
+
return finals;
|
|
81
|
+
const dynamic = dynamicFieldStores(mod);
|
|
82
|
+
if (dynamic.all)
|
|
83
|
+
return finals;
|
|
84
|
+
const genericFamilies = new Set();
|
|
85
|
+
for (const cls of classes.values())
|
|
86
|
+
if (cls.genericOf !== undefined) {
|
|
87
|
+
genericFamilies.add(cls.name);
|
|
88
|
+
genericFamilies.add(cls.genericOf);
|
|
89
|
+
}
|
|
90
|
+
const plainClass = (cls) => {
|
|
91
|
+
for (let c = cls; c; c = c.base ? classes.get(c.base) : undefined) {
|
|
92
|
+
if (c.runtime || genericFamilies.has(c.name))
|
|
93
|
+
return false;
|
|
94
|
+
if (c.base && !classes.has(c.base))
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
};
|
|
99
|
+
const inFamily = (className, family) => {
|
|
100
|
+
const owner = family.slice(0, family.indexOf("\0"));
|
|
101
|
+
for (let c = classes.get(className); c; c = c.base ? classes.get(c.base) : undefined)
|
|
102
|
+
if (c.name === owner)
|
|
103
|
+
return true;
|
|
104
|
+
return false;
|
|
105
|
+
};
|
|
106
|
+
for (const cls of classes.values())
|
|
107
|
+
for (const field of cls.fields) {
|
|
108
|
+
if (!isRefCounted(field.type) || field.name.startsWith("%"))
|
|
109
|
+
continue;
|
|
110
|
+
const family = finals.family(cls.name, field.name);
|
|
111
|
+
if (finals.reasons.has(family))
|
|
112
|
+
continue;
|
|
113
|
+
if (!plainClass(cls))
|
|
114
|
+
finals.drop(family, "runtime-provided or generic class");
|
|
115
|
+
else if (dynamic.names.has(field.name))
|
|
116
|
+
finals.drop(family, "dynamic stores can name the field");
|
|
117
|
+
else
|
|
118
|
+
finals.add(family);
|
|
119
|
+
}
|
|
120
|
+
if (finals.size === 0)
|
|
121
|
+
return finals;
|
|
122
|
+
for (const fn of mod.functions) {
|
|
123
|
+
const ctor = constructorClass(fn.name);
|
|
124
|
+
const self = ctor !== null ? fn.params[0]?.localId : undefined;
|
|
125
|
+
const selfLocal = self !== undefined ? fn.locals.find((l) => l.id === self) : undefined;
|
|
126
|
+
// `this` must name the object under construction for the whole body.
|
|
127
|
+
const constructing = selfLocal !== undefined && !selfLocal.boxed && !reassigns(fn.body, self);
|
|
128
|
+
const stmt = (s) => {
|
|
129
|
+
if (s.kind === "fieldSet") {
|
|
130
|
+
const family = finals.family(s.className, s.field);
|
|
131
|
+
if (family !== null && finals.isFinal(s.className, s.field)) {
|
|
132
|
+
const own = constructing && ctor !== null && inFamily(ctor, family) && isSelf(s.obj, self);
|
|
133
|
+
if (!own)
|
|
134
|
+
finals.drop(family, `written in ${fn.name}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return everyStmtChild(s, expr, stmt);
|
|
138
|
+
};
|
|
139
|
+
const expr = (e) => everyExprChild(e, expr, stmt);
|
|
140
|
+
for (const s of fn.body)
|
|
141
|
+
stmt(s);
|
|
142
|
+
}
|
|
143
|
+
return finals;
|
|
144
|
+
}
|
|
145
|
+
/** `this` itself, or behind the derived constructor's guards (`if (!super
|
|
146
|
+
* called) throw`), which read no reference and write nothing. */
|
|
147
|
+
function isSelf(e, self) {
|
|
148
|
+
if (e.kind === "varRef")
|
|
149
|
+
return e.localId === self;
|
|
150
|
+
if (e.kind !== "seqExpr")
|
|
151
|
+
return false;
|
|
152
|
+
for (const s of e.stmts) {
|
|
153
|
+
if (s.kind !== "if" || s.else_ !== null || s.then.length !== 1)
|
|
154
|
+
return false;
|
|
155
|
+
const only = s.then[0];
|
|
156
|
+
if (only.kind !== "exprStmt" ||
|
|
157
|
+
only.expr.kind !== "libCall" ||
|
|
158
|
+
only.expr.fn !== "error.nodeThrow" ||
|
|
159
|
+
!only.expr.args.every((arg) => arg.kind === "numLit" || arg.kind === "strLit") ||
|
|
160
|
+
!throwFreeCondition(s.cond))
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return isSelf(e.result, self);
|
|
164
|
+
}
|
|
165
|
+
function throwFreeCondition(e) {
|
|
166
|
+
if (e.kind === "varRef" || e.kind === "boolLit")
|
|
167
|
+
return e.type.kind === "bool";
|
|
168
|
+
return e.kind === "unary" && throwFreeCondition(e.operand);
|
|
169
|
+
}
|
|
170
|
+
function reassigns(body, localId) {
|
|
171
|
+
let found = false;
|
|
172
|
+
const expr = (e) => {
|
|
173
|
+
if ((e.kind === "assignExpr" || e.kind === "incDec") && e.localId === localId)
|
|
174
|
+
found = true;
|
|
175
|
+
return !found && everyExprChild(e, expr, stmt);
|
|
176
|
+
};
|
|
177
|
+
const stmt = (s) => {
|
|
178
|
+
if (s.kind === "assign" && s.localId === localId && s.initializes !== true)
|
|
179
|
+
found = true;
|
|
180
|
+
return !found && everyStmtChild(s, expr, stmt);
|
|
181
|
+
};
|
|
182
|
+
for (const s of body)
|
|
183
|
+
if (!stmt(s))
|
|
184
|
+
break;
|
|
185
|
+
return found;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=final-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"final-fields.js","sourceRoot":"","sources":["../../src/ir/final-fields.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
import { analyzeFinalFields, constructorClass } from "./final-fields.js";
|
|
3
|
+
import { BOOL, STRING, VOID, } from "./ir.js";
|
|
4
|
+
const loc = { file: "final-fields.ts", start: 0, end: 0 };
|
|
5
|
+
const obj = (className) => ({ kind: "object", className });
|
|
6
|
+
const ref = (localId, type) => ({ loc, kind: "varRef", localId, type });
|
|
7
|
+
const str = (value) => ({ loc, kind: "strLit", value, type: STRING });
|
|
8
|
+
const set = (target, className, field, value) => ({
|
|
9
|
+
loc,
|
|
10
|
+
kind: "fieldSet",
|
|
11
|
+
obj: target,
|
|
12
|
+
className,
|
|
13
|
+
field,
|
|
14
|
+
value,
|
|
15
|
+
});
|
|
16
|
+
const fn = (name, self, body) => ({
|
|
17
|
+
loc,
|
|
18
|
+
name,
|
|
19
|
+
params: self ? [{ localId: "this", name: "this", type: obj(self) }] : [],
|
|
20
|
+
locals: self ? [{ id: "this", name: "this", type: obj(self), mutable: false }] : [],
|
|
21
|
+
returnType: VOID,
|
|
22
|
+
body,
|
|
23
|
+
});
|
|
24
|
+
const cls = (name, fields, base) => ({
|
|
25
|
+
loc,
|
|
26
|
+
name,
|
|
27
|
+
...(base ? { base } : {}),
|
|
28
|
+
fields: fields.map((field) => ({ name: field, type: STRING })),
|
|
29
|
+
});
|
|
30
|
+
const mod = (classes, functions) => ({
|
|
31
|
+
irVersion: 15,
|
|
32
|
+
sourceFile: "final-fields.ts",
|
|
33
|
+
entry: "%main",
|
|
34
|
+
classes,
|
|
35
|
+
functions: [fn("%main", null, []), ...functions],
|
|
36
|
+
records: [],
|
|
37
|
+
unions: [],
|
|
38
|
+
globals: [],
|
|
39
|
+
});
|
|
40
|
+
const self = (className) => ref("this", obj(className));
|
|
41
|
+
test("constructor names map to their class", () => {
|
|
42
|
+
expect(constructorClass("%%m1.Parser.constructor")).toBe("%m1.Parser");
|
|
43
|
+
expect(constructorClass("%%m1.Parser.parse")).toBeNull();
|
|
44
|
+
});
|
|
45
|
+
test("fields written only through their constructors' this are final", () => {
|
|
46
|
+
const finals = analyzeFinalFields(mod([cls("A", ["kept", "moved"]), cls("B", ["kept", "moved", "own"], "A")], [
|
|
47
|
+
fn("%A.constructor", "A", [
|
|
48
|
+
set(self("A"), "A", "kept", str("a")),
|
|
49
|
+
set(self("A"), "A", "kept", str("twice")),
|
|
50
|
+
set(self("A"), "A", "moved", str("a")),
|
|
51
|
+
]),
|
|
52
|
+
// A subclass constructor initializes its base's field through a guard.
|
|
53
|
+
fn("%B.constructor", "B", [
|
|
54
|
+
set({
|
|
55
|
+
loc,
|
|
56
|
+
kind: "seqExpr",
|
|
57
|
+
stmts: [
|
|
58
|
+
{
|
|
59
|
+
loc,
|
|
60
|
+
kind: "if",
|
|
61
|
+
cond: {
|
|
62
|
+
loc,
|
|
63
|
+
kind: "unary",
|
|
64
|
+
op: "!",
|
|
65
|
+
operand: ref("superCalled", BOOL),
|
|
66
|
+
type: BOOL,
|
|
67
|
+
},
|
|
68
|
+
then: [
|
|
69
|
+
{
|
|
70
|
+
loc,
|
|
71
|
+
kind: "exprStmt",
|
|
72
|
+
expr: {
|
|
73
|
+
loc,
|
|
74
|
+
kind: "libCall",
|
|
75
|
+
fn: "error.nodeThrow",
|
|
76
|
+
args: [str("ReferenceError")],
|
|
77
|
+
type: VOID,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
else_: null,
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
result: self("B"),
|
|
85
|
+
type: obj("B"),
|
|
86
|
+
}, "B", "own", str("b")),
|
|
87
|
+
]),
|
|
88
|
+
// Any write elsewhere disqualifies the field family.
|
|
89
|
+
fn("%A.reset", "A", [set(self("A"), "A", "moved", str("later"))]),
|
|
90
|
+
]));
|
|
91
|
+
expect(finals.isFinal("A", "kept")).toBe(true);
|
|
92
|
+
expect(finals.isFinal("B", "kept")).toBe(true);
|
|
93
|
+
expect(finals.isFinal("B", "own")).toBe(true);
|
|
94
|
+
expect(finals.isFinal("A", "moved")).toBe(false);
|
|
95
|
+
expect(finals.isFinal("B", "moved")).toBe(false);
|
|
96
|
+
expect(finals.reasons.get("A\0moved")).toBe("written in %A.reset");
|
|
97
|
+
});
|
|
98
|
+
test("constructors writing another object, and library builds, are not final", () => {
|
|
99
|
+
const other = fn("%A.constructor", "A", [set(ref("peer", obj("A")), "A", "kept", str("a"))]);
|
|
100
|
+
other.locals.push({ id: "peer", name: "peer", type: obj("A"), mutable: false });
|
|
101
|
+
expect(analyzeFinalFields(mod([cls("A", ["kept"])], [other])).isFinal("A", "kept")).toBe(false);
|
|
102
|
+
const library = mod([cls("A", ["kept"])], []);
|
|
103
|
+
library.lib = { profile: "p" };
|
|
104
|
+
expect(analyzeFinalFields(library).size).toBe(0);
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=final-fields.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"final-fields.test.js","sourceRoot":"","sources":["../../src/ir/final-fields.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { IrClassDef, IrExpr, IrModule } from "./ir.js";
|
|
2
|
+
import { type IntegerSlotFacts } from "./integer-ranges.js";
|
|
3
|
+
/** Whole-program int32 specialization of numeric storage.
|
|
4
|
+
*
|
|
5
|
+
* A class field typed `number` whose every write provably stores an int32
|
|
6
|
+
* (never -0, never NaN, never a fraction or an out-of-range integer) can be
|
|
7
|
+
* stored as an i32: reading it back as a double is exact, so every program
|
|
8
|
+
* observation is unchanged. The same proof seeds parameters of functions
|
|
9
|
+
* that are only ever called directly (every call site passes an int32) and
|
|
10
|
+
* results of functions whose every return is an int32. Parameter and result
|
|
11
|
+
* ABIs stay double; only the facts reach the callee and the call sites.
|
|
12
|
+
*
|
|
13
|
+
* The analysis is optimistic: every candidate slot starts as int32, each
|
|
14
|
+
* function is analyzed by analyzeIntegerRanges under the current facts, and
|
|
15
|
+
* any write the analysis cannot prove disqualifies its slot. Functions that
|
|
16
|
+
* read a disqualified slot are analyzed again, until no write fails. At the
|
|
17
|
+
* fixpoint every assumption was proven against every write.
|
|
18
|
+
*
|
|
19
|
+
* Writes the IR does not show disqualify a slot up front. Instances that
|
|
20
|
+
* reach checked-dynamic code get live views whose runtime stores commit
|
|
21
|
+
* back into the fields; a field of such a class stays a double when any
|
|
22
|
+
* dynamic store in the program can name it (literal-keyed stores name one
|
|
23
|
+
* property, every other store any property, islands everything). Classes
|
|
24
|
+
* with runtime-provided ancestors, generic families, fields under
|
|
25
|
+
* `++`/`--`, and parameters of functions that escape as values, are
|
|
26
|
+
* constructed through class values, or are virtual-dispatch targets are
|
|
27
|
+
* excluded as well. Library builds keep ordinary storage: their instances
|
|
28
|
+
* cross a native boundary. Worker builds do not: instances reach another
|
|
29
|
+
* thread only through postMessage/workerData, whose dyn views read (and
|
|
30
|
+
* commit) fields like every other dynamic reader. Reads are never
|
|
31
|
+
* restricted: every reader (static code, dyn views, JSON, inspect) widens
|
|
32
|
+
* the i32 exactly. */
|
|
33
|
+
export declare class Int32Slots {
|
|
34
|
+
private readonly classes;
|
|
35
|
+
/** Field families (topmost declaring class and field) stored as i32. */
|
|
36
|
+
private readonly fields;
|
|
37
|
+
private readonly familyOf;
|
|
38
|
+
private readonly paramFacts;
|
|
39
|
+
private readonly returns;
|
|
40
|
+
/** Captured-binding groups (one shared box) that hold an int32, and the
|
|
41
|
+
* group of each `function\0local` member. */
|
|
42
|
+
private readonly boxes;
|
|
43
|
+
private readonly boxGroupOf;
|
|
44
|
+
/** Field write values proven int32 by the final analysis. */
|
|
45
|
+
readonly provenWrites: Set<IrExpr>;
|
|
46
|
+
/** Disqualified candidates and the first reason, for tests. */
|
|
47
|
+
readonly reasons: Map<string, string>;
|
|
48
|
+
constructor(classes?: ReadonlyMap<string, IrClassDef>);
|
|
49
|
+
/** The family key of a class field: the topmost class in the base chain
|
|
50
|
+
* that declares a field of that name (all subclasses share its slot). */
|
|
51
|
+
family(className: string, field: string): string | null;
|
|
52
|
+
isField(className: string, field: string): boolean;
|
|
53
|
+
/** The facts analyzeIntegerRanges may assume inside one function. */
|
|
54
|
+
facts(fnName: string): IntegerSlotFacts;
|
|
55
|
+
boxGroup(fnName: string, localId: string): string | null;
|
|
56
|
+
addBox(group: string, members: readonly string[]): void;
|
|
57
|
+
dropBox(group: string): boolean;
|
|
58
|
+
hasBox(group: string | null): boolean;
|
|
59
|
+
addField(family: string): void;
|
|
60
|
+
dropField(family: string): boolean;
|
|
61
|
+
hasFamily(family: string): boolean;
|
|
62
|
+
addParam(fnName: string, localId: string): void;
|
|
63
|
+
dropParam(fnName: string, localId: string): boolean;
|
|
64
|
+
hasParam(fnName: string, localId: string): boolean;
|
|
65
|
+
addReturn(fnName: string): void;
|
|
66
|
+
dropReturn(fnName: string): boolean;
|
|
67
|
+
hasReturn(fnName: string): boolean;
|
|
68
|
+
get fieldCount(): number;
|
|
69
|
+
get returnCount(): number;
|
|
70
|
+
get paramCount(): number;
|
|
71
|
+
}
|
|
72
|
+
/** The class field names that runtime stores through live dynamic views
|
|
73
|
+
* (typed-ref capsules) can write: every name when `all` (islands, jsval
|
|
74
|
+
* values, or a dynamic store whose key is not a literal), otherwise the
|
|
75
|
+
* literal keys of `dyn.keySet`/`dyn.keyDelete`. A view commits a store back
|
|
76
|
+
* into the instance's native field slots, which the IR does not show. */
|
|
77
|
+
export declare function dynamicFieldStores(mod: IrModule, records?: Map<string, import("./ir.js").IrRecordShape>, unions?: Map<string, import("./ir.js").IrUnionDef>): {
|
|
78
|
+
all: boolean;
|
|
79
|
+
names: Set<string>;
|
|
80
|
+
};
|
|
81
|
+
export declare function analyzeInt32Slots(mod: IrModule): Int32Slots;
|