@scriptc/compiler 0.4.2 → 0.4.3
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 +397 -37
- package/dist/backend/cycle-analysis.d.ts +4 -1
- package/dist/backend/cycle-analysis.js +6 -4
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +55 -0
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.d.ts +7 -0
- package/dist/backend/cycle-mutability.js +19 -1
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +2 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.d.ts +6 -3
- package/dist/backend/immutability.js +33 -29
- package/dist/backend/immutability.js.map +1 -1
- package/dist/backend/library-pack.js +1 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +16 -1
- package/dist/backend/llvm/alloc.js +54 -4
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.d.ts +2 -1
- package/dist/backend/llvm/appended-array-literals.js +44 -36
- package/dist/backend/llvm/appended-array-literals.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +4 -3
- package/dist/backend/llvm/appended-array-literals.test.js.map +1 -1
- package/dist/backend/llvm/array-search.d.ts +4 -3
- package/dist/backend/llvm/array-search.js +21 -9
- package/dist/backend/llvm/array-search.js.map +1 -1
- package/dist/backend/llvm/blocks.d.ts +1 -1
- package/dist/backend/llvm/blocks.js +2 -2
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/byte-windows.js +2 -0
- package/dist/backend/llvm/byte-windows.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +6 -1
- package/dist/backend/llvm/bytes-alias.js +8 -2
- package/dist/backend/llvm/bytes-alias.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.d.ts +47 -5
- package/dist/backend/llvm/bytes-loop-versions.js +473 -32
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.test.js +258 -2
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +2 -0
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +7 -5
- package/dist/backend/llvm/classes.js +44 -20
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +167 -7
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +9 -3
- package/dist/backend/llvm/common.js +9 -3
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +2 -1
- package/dist/backend/llvm/constant-callbacks.js +83 -52
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +7 -0
- package/dist/backend/llvm/counted-loops.js +18 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +39 -8
- package/dist/backend/llvm/dense-array-access.js +222 -52
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +36 -0
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +17 -1
- package/dist/backend/llvm/dense-array-loops.js +194 -5
- package/dist/backend/llvm/dense-array-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.test.js +90 -1
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -1
- package/dist/backend/llvm/dyn-handle-tags.test.js +6 -1
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +26 -0
- package/dist/backend/llvm/dyn.js +352 -61
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +11 -20
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-journal.d.ts +93 -0
- package/dist/backend/llvm/emit-journal.js +170 -0
- package/dist/backend/llvm/emit-journal.js.map +1 -0
- package/dist/backend/llvm/emit-module.js +195 -27
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emit-statements.d.ts +0 -4
- package/dist/backend/llvm/emit-statements.js +268 -84
- package/dist/backend/llvm/emit-statements.js.map +1 -1
- package/dist/backend/llvm/emitter-state.d.ts +7 -0
- package/dist/backend/llvm/emitter-state.js +14 -0
- package/dist/backend/llvm/emitter-state.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +176 -37
- package/dist/backend/llvm/emitter.js +724 -85
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +54 -5
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +34 -12
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.js +47 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +28 -14
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +14 -2
- package/dist/backend/llvm/expr-containers.js +129 -37
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +14 -0
- package/dist/backend/llvm/expr-dynamic.js +18 -11
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +100 -28
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +11 -6
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +12 -0
- package/dist/backend/llvm/expr-records.js +106 -0
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +2 -2
- package/dist/backend/llvm/expr-stream-bridges.js +194 -65
- 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-bridges.test.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +74 -20
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-kind-loops.d.ts +39 -0
- package/dist/backend/llvm/int32-kind-loops.js +106 -0
- package/dist/backend/llvm/int32-kind-loops.js.map +1 -0
- package/dist/backend/llvm/integer-or-nan-indexes.test.d.ts +1 -0
- package/dist/backend/llvm/integer-or-nan-indexes.test.js +118 -0
- package/dist/backend/llvm/integer-or-nan-indexes.test.js.map +1 -0
- package/dist/backend/llvm/integer-values.d.ts +20 -1
- package/dist/backend/llvm/integer-values.js +71 -0
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/js-ic.d.ts +1 -1
- package/dist/backend/llvm/js-ic.js +1 -1
- package/dist/backend/llvm/js-ic.js.map +1 -1
- package/dist/backend/llvm/key-orders.d.ts +7 -0
- package/dist/backend/llvm/key-orders.js +33 -0
- package/dist/backend/llvm/key-orders.js.map +1 -0
- package/dist/backend/llvm/lib-connect.js +4 -0
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +11 -0
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +80 -2
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +4 -4
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +4 -0
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +16 -6
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +73 -2
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +35 -5
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +115 -19
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +14 -0
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/loop-state.d.ts +33 -0
- package/dist/backend/llvm/loop-state.js +42 -0
- package/dist/backend/llvm/loop-state.js.map +1 -0
- package/dist/backend/llvm/map-number-lookup.d.ts +26 -8
- package/dist/backend/llvm/map-number-lookup.js +91 -31
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +55 -0
- package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.js +4 -2
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.d.ts +2 -1
- package/dist/backend/llvm/nullable-unions.js +15 -3
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/publish.d.ts +10 -0
- package/dist/backend/llvm/publish.js +12 -0
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/receivers.js +6 -1
- package/dist/backend/llvm/receivers.js.map +1 -1
- package/dist/backend/llvm/record-results.d.ts +1 -9
- package/dist/backend/llvm/record-results.js +2 -11
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +7 -2
- package/dist/backend/llvm/reference-writes.js +89 -72
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/running-extrema.d.ts +11 -0
- package/dist/backend/llvm/running-extrema.js +115 -0
- package/dist/backend/llvm/running-extrema.js.map +1 -0
- package/dist/backend/llvm/running-extrema.test.d.ts +1 -0
- package/dist/backend/llvm/running-extrema.test.js +89 -0
- package/dist/backend/llvm/running-extrema.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +71 -15
- package/dist/backend/llvm/shapes.js +222 -33
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +53 -7
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +6 -0
- package/dist/backend/llvm/speculative-integers.js +2 -2
- package/dist/backend/llvm/speculative-integers.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +3 -2
- package/dist/backend/llvm/stack-objects.js +5 -2
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +12 -0
- package/dist/backend/llvm/string-reads.js +44 -0
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/walk-borrows.d.ts +3 -0
- package/dist/backend/llvm/walk-borrows.js +46 -41
- package/dist/backend/llvm/walk-borrows.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +3 -0
- package/dist/backend/llvm/walkers.js +88 -65
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wrapping-sums.d.ts +16 -1
- package/dist/backend/llvm/wrapping-sums.js +126 -0
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/may-throw.d.ts +8 -10
- package/dist/backend/may-throw.js +14 -10
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +5 -0
- package/dist/backend/native/executable.js +7 -0
- package/dist/backend/native/executable.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-link-info-core.d.ts +4 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.d.ts +12 -1
- package/dist/backend/publication.js +37 -14
- package/dist/backend/publication.js.map +1 -1
- package/dist/backend/publication.test.js +30 -0
- package/dist/backend/publication.test.js.map +1 -1
- package/dist/backend/result-slots.d.ts +16 -0
- package/dist/backend/result-slots.js +23 -0
- package/dist/backend/result-slots.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 +1 -0
- package/dist/backend/runtime-pack-core.js +1 -0
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +2 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +2 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +2 -1
- package/dist/backend/stack-observations.js +67 -42
- package/dist/backend/stack-observations.js.map +1 -1
- package/dist/backend/target-diagnostics.js +5 -3
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/warm-cache.js +1 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/cli/usage.d.ts +1 -1
- package/dist/cli/usage.js +3 -3
- package/dist/compat/fetch-profile.js +1 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/contracts/check.js +4 -3
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.js +10 -2
- package/dist/contracts/int32-elements.js.map +1 -1
- package/dist/coverage/report.js +12 -3
- package/dist/coverage/report.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +4 -0
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +3 -0
- package/dist/diagnostics/envelope.js +1 -0
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +2 -0
- package/dist/executable/executable-cache.js +1 -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/frontend/decl-projection.d.ts +41 -0
- package/dist/frontend/decl-projection.js +854 -0
- package/dist/frontend/decl-projection.js.map +1 -0
- package/dist/frontend/decl-projection.test.d.ts +1 -0
- package/dist/frontend/decl-projection.test.js +30 -0
- package/dist/frontend/decl-projection.test.js.map +1 -0
- package/dist/frontend/dts-paths.d.ts +15 -0
- package/dist/frontend/dts-paths.js +25 -0
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +6 -0
- package/dist/frontend/input-tracker.js +51 -28
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +19 -0
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lowering/array-values.js +100 -2
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.js +46 -15
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.js +13 -2
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.js +84 -9
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/global-namespace-keys.d.ts +3 -0
- package/dist/frontend/lowering/builtins/global-namespace-keys.js +122 -0
- package/dist/frontend/lowering/builtins/global-namespace-keys.js.map +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +9 -1
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +6 -0
- package/dist/frontend/lowering/builtins/promises.js +88 -2
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +5 -1
- package/dist/frontend/lowering/builtins/readline.js +35 -3
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.js +24 -1
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/webassembly.js +6 -3
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +5 -2
- package/dist/frontend/lowering/class-callbacks.js +82 -12
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +4 -1
- package/dist/frontend/lowering/class-construction.js +17 -3
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +39 -2
- package/dist/frontend/lowering/class-dynamic-dispatch.js +766 -108
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +47 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +2 -1
- package/dist/frontend/lowering/class-iterables.js +9 -1
- package/dist/frontend/lowering/class-iterables.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +32 -9
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.js +31 -2
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +9 -3
- package/dist/frontend/lowering/class-runtime-statics.js +29 -4
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +48 -1
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +91 -1
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callback-call.js +2 -2
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +338 -18
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +10 -0
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +15 -0
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +19 -8
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +2 -1
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +3 -0
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +7 -2
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/filter-predicates.d.ts +6 -0
- package/dist/frontend/lowering/containers/filter-predicates.js +205 -0
- package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -0
- package/dist/frontend/lowering/containers/indexed-objects.d.ts +0 -12
- package/dist/frontend/lowering/containers/indexed-objects.js +46 -7
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +55 -9
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +43 -19
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/dispatch-sites.js +15 -1
- package/dist/frontend/lowering/dispatch-sites.js.map +1 -1
- package/dist/frontend/lowering/divergences.js +9 -1
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/error-methods.js +47 -2
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/expressions/array-literals.js +47 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +36 -2
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +90 -13
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +33 -4
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/narrowing.js +95 -1
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +3 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +138 -51
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +12 -0
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.js +113 -11
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/relational.js +212 -33
- package/dist/frontend/lowering/expressions/relational.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js +4 -0
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +22 -3
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/frozen-records.d.ts +28 -0
- package/dist/frontend/lowering/frozen-records.js +322 -0
- package/dist/frontend/lowering/frozen-records.js.map +1 -0
- package/dist/frontend/lowering/function-returns.js +49 -0
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.js +7 -2
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/iterable-values.d.ts +49 -0
- package/dist/frontend/lowering/iterable-values.js +297 -0
- package/dist/frontend/lowering/iterable-values.js.map +1 -0
- package/dist/frontend/lowering/iterator-adapters.js +186 -1
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +8 -0
- package/dist/frontend/lowering/js-class-fields.js +45 -10
- package/dist/frontend/lowering/js-class-fields.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.d.ts +18 -3
- package/dist/frontend/lowering/key-order-witness.js +770 -22
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.test.js +428 -8
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js +4 -1
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +7 -0
- package/dist/frontend/lowering/lower-calls.js +443 -41
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +11 -2
- package/dist/frontend/lowering/lower-classes.js +302 -22
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +3 -1
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +10 -2
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.d.ts +11 -0
- package/dist/frontend/lowering/lower-functions.js +83 -0
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +41 -31
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +6 -3
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +18 -6
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +32 -0
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +5 -1
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +2 -2
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +5 -0
- package/dist/frontend/lowering/lower-stdlib.js +30 -0
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +23 -0
- package/dist/frontend/lowering/lower-stmts.js +454 -48
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +20 -2
- package/dist/frontend/lowering/lower-stream.js +1483 -156
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +77 -6
- package/dist/frontend/lowering/lowerer.js +313 -29
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.d.ts +11 -1
- package/dist/frontend/lowering/module-namespace-elements.js +82 -5
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/new-target.d.ts +12 -0
- package/dist/frontend/lowering/new-target.js +280 -0
- package/dist/frontend/lowering/new-target.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +3 -0
- package/dist/frontend/lowering/surfaces.js +18 -6
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/undefined-index.d.ts +27 -0
- package/dist/frontend/lowering/undefined-index.js +82 -0
- package/dist/frontend/lowering/undefined-index.js.map +1 -0
- package/dist/frontend/lowering/var-hoisting.js +29 -13
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +18 -0
- package/dist/frontend/npm-static-bundled-chunks.js +9 -11
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.test.js +6 -5
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.js +9 -1
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static.js +4 -20
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/package-shims.d.ts +3 -0
- package/dist/frontend/package-shims.js +71 -8
- package/dist/frontend/package-shims.js.map +1 -1
- package/dist/frontend/pipeline.js +18 -10
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/process-fork.d.ts +25 -0
- package/dist/frontend/process-fork.js +2 -0
- package/dist/frontend/process-fork.js.map +1 -0
- package/dist/frontend/program.d.ts +8 -1
- package/dist/frontend/program.js +484 -69
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +43 -3
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/token-equivalence.d.ts +3 -0
- package/dist/frontend/token-equivalence.js +409 -0
- package/dist/frontend/token-equivalence.js.map +1 -0
- package/dist/frontend/token-equivalence.test.d.ts +1 -0
- package/dist/frontend/token-equivalence.test.js +67 -0
- package/dist/frontend/token-equivalence.test.js.map +1 -0
- package/dist/frontend/ts7/ast-node.d.ts +22 -0
- package/dist/frontend/ts7/ast-node.js +1048 -103
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +24 -0
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.d.ts +4 -3
- package/dist/frontend/ts7/ast-wire.js +34 -24
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.test.js +23 -0
- package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +3 -4
- package/dist/frontend/ts7/checker-backend.js +2 -2
- package/dist/frontend/ts7/checker-backend.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.test.js +5 -9
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +4 -0
- package/dist/frontend/ts7/checker.js +7 -0
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/lib-diagnostics.d.ts +24 -0
- package/dist/frontend/ts7/lib-diagnostics.js +307 -0
- package/dist/frontend/ts7/lib-diagnostics.js.map +1 -0
- package/dist/frontend/ts7/lib-diagnostics.test.d.ts +1 -0
- package/dist/frontend/ts7/lib-diagnostics.test.js +199 -0
- package/dist/frontend/ts7/lib-diagnostics.test.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +7 -0
- package/dist/frontend/ts7/program-host.js +25 -2
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +14 -1
- package/dist/frontend/ts7/session.js +22 -0
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +13 -1
- package/dist/frontend/type-mapper.js +191 -11
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.js +34 -4
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +5 -3
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +4 -0
- package/dist/ir/array-length-stability.js +19 -6
- package/dist/ir/array-length-stability.js.map +1 -1
- package/dist/ir/array-length-stability.test.js +24 -0
- package/dist/ir/array-length-stability.test.js.map +1 -1
- package/dist/ir/builtin-effects.d.ts +7 -0
- package/dist/ir/builtin-effects.js +52 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +6 -4
- package/dist/ir/builtin-signatures.js +166 -13
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +2 -1
- package/dist/ir/callback-specialization.js +23 -18
- package/dist/ir/callback-specialization.js.map +1 -1
- package/dist/ir/char-unit-locals.d.ts +19 -0
- package/dist/ir/char-unit-locals.js +185 -0
- package/dist/ir/char-unit-locals.js.map +1 -0
- package/dist/ir/char-unit-locals.test.d.ts +1 -0
- package/dist/ir/char-unit-locals.test.js +94 -0
- package/dist/ir/char-unit-locals.test.js.map +1 -0
- package/dist/ir/final-fields.d.ts +2 -1
- package/dist/ir/final-fields.js +14 -16
- package/dist/ir/final-fields.js.map +1 -1
- package/dist/ir/function-references.d.ts +2 -0
- package/dist/ir/function-references.js +2 -0
- package/dist/ir/function-references.js.map +1 -1
- package/dist/ir/function-references.test.js +3 -0
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/initializer-bindings.d.ts +2 -1
- package/dist/ir/initializer-bindings.js +27 -20
- package/dist/ir/initializer-bindings.js.map +1 -1
- package/dist/ir/int32-arrays.d.ts +108 -0
- package/dist/ir/int32-arrays.js +831 -0
- package/dist/ir/int32-arrays.js.map +1 -0
- package/dist/ir/int32-slots.d.ts +24 -2
- package/dist/ir/int32-slots.js +259 -57
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +3 -3
- package/dist/ir/integer-loops.js +14 -6
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +10 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +5 -0
- package/dist/ir/integer-ranges.js +125 -12
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +30 -0
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/ir.d.ts +70 -7
- package/dist/ir/ir.js +58 -1
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +21 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/js-ic.d.ts +19 -2
- package/dist/ir/js-ic.js +95 -11
- package/dist/ir/js-ic.js.map +1 -1
- package/dist/ir/js-ic.test.js +188 -0
- package/dist/ir/js-ic.test.js.map +1 -1
- package/dist/ir/node-index.d.ts +57 -0
- package/dist/ir/node-index.js +215 -0
- package/dist/ir/node-index.js.map +1 -0
- package/dist/ir/paired-while-loops.d.ts +25 -0
- package/dist/ir/paired-while-loops.js +335 -0
- package/dist/ir/paired-while-loops.js.map +1 -0
- package/dist/ir/paired-while-loops.test.d.ts +1 -0
- package/dist/ir/paired-while-loops.test.js +163 -0
- package/dist/ir/paired-while-loops.test.js.map +1 -0
- package/dist/ir/parameter-versions.d.ts +25 -0
- package/dist/ir/parameter-versions.js +300 -0
- package/dist/ir/parameter-versions.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +34 -13
- package/dist/ir/runtime-features.js +152 -38
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/serialize.d.ts +12 -2
- package/dist/ir/serialize.js +16 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +17 -0
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/traverse.js +18 -6
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +122 -36
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/ir-policy.js +2 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/native/cache.d.ts +6 -1
- package/dist/native/cache.js +28 -5
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cache.test.js +16 -2
- package/dist/native/cache.test.js.map +1 -1
- package/dist/native/cli.js +21 -1
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +8 -6
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/executable-cache.d.ts +1 -1
- package/dist/native/executable-cache.js +2 -2
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/prepare.d.ts +3 -1
- package/dist/native/prepare.js +119 -31
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +78 -18
- package/dist/native/prepare.test.js.map +1 -1
- package/dist/native/sanitizer.test.js +2 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/text-file.d.ts +13 -3
- package/dist/native/text-file.js +63 -9
- package/dist/native/text-file.js.map +1 -1
- package/dist/native/text-file.test.d.ts +1 -0
- package/dist/native/text-file.test.js +49 -0
- package/dist/native/text-file.test.js.map +1 -0
- package/dist/native/toolchain.js +4 -4
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +3 -3
- package/dist/native/toolchain.test.js.map +1 -1
- package/package.json +21 -21
- package/shims/chalk/v5.ts +688 -0
- package/shims/hono-node-server/v2.ts +645 -0
- package/shims/hot-shots/client.ts +1126 -0
- package/shims/hot-shots/v8-unix-dgram.ts +8 -0
- package/shims/hot-shots/v8.ts +8 -0
- package/surface-manifest.json +26 -4
|
@@ -1,5 +1,34 @@
|
|
|
1
|
-
import { shapeHasAccessorSlots, typeEquals, UNDEFINED_T } from "../../ir/ir.js";
|
|
2
|
-
import { everyExprChild, everyStmtChild, everyTypeChild } from "../../ir/traverse.js";
|
|
1
|
+
import { BOOL, F64, KEY_ORDER_FIELD, shapeHasAccessorSlots, typeEquals, UNDEFINED_T, } from "../../ir/ir.js";
|
|
2
|
+
import { everyExprChild, everyStmtChild, everyTypeChild, transformStmtList, } from "../../ir/traverse.js";
|
|
3
|
+
import * as ts from "../ts7/adapter.js";
|
|
4
|
+
import { ALWAYS_THROW_LIB_FNS } from "../../ir/builtin-effects.js";
|
|
5
|
+
/** The statements a key-order helper runs for record `ref`: `walks[0]`,
|
|
6
|
+
* its walk over the shape's table, or, for a shape with orderVariants, a
|
|
7
|
+
* branch per order (walks[i] for order i) on the value's KEY_ORDER_FIELD.
|
|
8
|
+
* `walks` follows shapeKeyOrders. */
|
|
9
|
+
export function perKeyOrder(shape, ref, walks, loc) {
|
|
10
|
+
let tail = walks[0];
|
|
11
|
+
for (let i = walks.length - 1; i >= 1; i--) {
|
|
12
|
+
const index = {
|
|
13
|
+
kind: "recordGet",
|
|
14
|
+
obj: ref,
|
|
15
|
+
shapeId: shape.id,
|
|
16
|
+
field: KEY_ORDER_FIELD,
|
|
17
|
+
type: F64,
|
|
18
|
+
loc,
|
|
19
|
+
};
|
|
20
|
+
const cond = {
|
|
21
|
+
kind: "bin",
|
|
22
|
+
op: "===",
|
|
23
|
+
left: index,
|
|
24
|
+
right: { kind: "numLit", value: i, type: F64, loc },
|
|
25
|
+
type: BOOL,
|
|
26
|
+
loc,
|
|
27
|
+
};
|
|
28
|
+
tail = [{ kind: "if", cond, then: walks[i], else_: tail, loc }];
|
|
29
|
+
}
|
|
30
|
+
return tail;
|
|
31
|
+
}
|
|
3
32
|
/** Witness notes the lowering attaches to the IR nodes it builds. Keyed by
|
|
4
33
|
* node identity, so nodes a speculative lowering discards are never walked.
|
|
5
34
|
* Literals the IR rewriters rebuild (traverse.ts mapExprChildren) carry
|
|
@@ -8,6 +37,7 @@ import { everyExprChild, everyStmtChild, everyTypeChild } from "../../ir/travers
|
|
|
8
37
|
export class KeyOrderNotes {
|
|
9
38
|
literals = new Map();
|
|
10
39
|
copies = new Map();
|
|
40
|
+
methodResults = new Map();
|
|
11
41
|
/** Shapes a frontend order surface (keys, values/entries, inspect,
|
|
12
42
|
* index-signature merges) walks. */
|
|
13
43
|
observed = new Set();
|
|
@@ -21,8 +51,14 @@ export class KeyOrderNotes {
|
|
|
21
51
|
this.copies.set(node, sourceShapeId);
|
|
22
52
|
return node;
|
|
23
53
|
}
|
|
54
|
+
/** The checked result of a typed call of method `name`, which the program
|
|
55
|
+
* may replace on its instance (class-callbacks.ts classCallbackCall). */
|
|
56
|
+
methodResult(node, name) {
|
|
57
|
+
this.methodResults.set(node, name);
|
|
58
|
+
return node;
|
|
59
|
+
}
|
|
24
60
|
/** A pass rebuilt `from` as `to` (traverse.ts mapExprChildren): the
|
|
25
|
-
* rebuilt
|
|
61
|
+
* rebuilt node is the same construction, so it keeps the witness. */
|
|
26
62
|
follow(from, to) {
|
|
27
63
|
const segments = this.literals.get(from);
|
|
28
64
|
if (segments !== undefined)
|
|
@@ -30,6 +66,9 @@ export class KeyOrderNotes {
|
|
|
30
66
|
const source = this.copies.get(from);
|
|
31
67
|
if (source !== undefined)
|
|
32
68
|
this.copies.set(to, source);
|
|
69
|
+
const method = this.methodResults.get(from);
|
|
70
|
+
if (method !== undefined)
|
|
71
|
+
this.methodResults.set(to, method);
|
|
33
72
|
}
|
|
34
73
|
observe(type) {
|
|
35
74
|
if (type.kind === "record")
|
|
@@ -41,6 +80,10 @@ export class KeyOrderNotes {
|
|
|
41
80
|
copyOf(node) {
|
|
42
81
|
return this.copies.get(node);
|
|
43
82
|
}
|
|
83
|
+
/** The method whose checked result `node` is, if it is one. */
|
|
84
|
+
methodResultOf(node) {
|
|
85
|
+
return this.methodResults.get(node);
|
|
86
|
+
}
|
|
44
87
|
}
|
|
45
88
|
const isArrayIndex = (name) => {
|
|
46
89
|
const n = Number(name);
|
|
@@ -55,6 +98,62 @@ function orderPreservingClone(node) {
|
|
|
55
98
|
const source = value.args[0];
|
|
56
99
|
return (source !== undefined && source.kind === "dynFrom" && typeEquals(source.value.type, node.type));
|
|
57
100
|
}
|
|
101
|
+
const PRIMITIVE_KINDS = new Set([
|
|
102
|
+
"f64",
|
|
103
|
+
"bigint",
|
|
104
|
+
"string",
|
|
105
|
+
"bool",
|
|
106
|
+
"undefinedT",
|
|
107
|
+
"nullT",
|
|
108
|
+
"symbol",
|
|
109
|
+
]);
|
|
110
|
+
/** A checked conversion of a boxed primitive (the `undefined` a dynamic
|
|
111
|
+
* construction passes for a missing argument) answers that primitive or
|
|
112
|
+
* throws: it builds no record. */
|
|
113
|
+
function primitiveSource(node) {
|
|
114
|
+
return node.value.kind === "dynFrom" && PRIMITIVE_KINDS.has(node.value.value.type.kind);
|
|
115
|
+
}
|
|
116
|
+
/** Whether a census site for a method name can only read the method or
|
|
117
|
+
* install a replacement whose result holds no object: a read
|
|
118
|
+
* (`C.prototype.m`, `obj.m`) outside an assignment target, or an assignment
|
|
119
|
+
* of a function expression whose return type is primitive. Other sites (a
|
|
120
|
+
* computed write of another value, a reflection call, a property bag) may
|
|
121
|
+
* install a replacement that returns a record. */
|
|
122
|
+
function replacesWithoutRecords(lowerer, site) {
|
|
123
|
+
const parent = site.parent;
|
|
124
|
+
if (ts.isPropertyAccessExpression(site) || ts.isElementAccessExpression(site))
|
|
125
|
+
return !(parent !== undefined &&
|
|
126
|
+
ts.isBinaryExpression(parent) &&
|
|
127
|
+
parent.left === site &&
|
|
128
|
+
parent.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
129
|
+
parent.operatorToken.kind <= ts.SyntaxKind.LastAssignment);
|
|
130
|
+
if (!ts.isBinaryExpression(site) || site.operatorToken.kind !== ts.SyntaxKind.EqualsToken)
|
|
131
|
+
return false;
|
|
132
|
+
let value = site.right;
|
|
133
|
+
while (ts.isParenthesizedExpression(value))
|
|
134
|
+
value = value.expression;
|
|
135
|
+
if (!ts.isArrowFunction(value) && !ts.isFunctionExpression(value))
|
|
136
|
+
return false;
|
|
137
|
+
const signatures = lowerer.checker.getCallSignatures(lowerer.typeOf(value));
|
|
138
|
+
return (signatures.length > 0 &&
|
|
139
|
+
signatures.every((signature) => primitiveOnly(lowerer.checker.getReturnTypeOfSignature(signature))));
|
|
140
|
+
}
|
|
141
|
+
/** A type whose values are primitives (or void): it holds no record. */
|
|
142
|
+
function primitiveOnly(type) {
|
|
143
|
+
if (type.isUnionType())
|
|
144
|
+
return ts.constituentTypes(type).every(primitiveOnly);
|
|
145
|
+
return ((type.flags &
|
|
146
|
+
(ts.TypeFlags.StringLike |
|
|
147
|
+
ts.TypeFlags.NumberLike |
|
|
148
|
+
ts.TypeFlags.BooleanLike |
|
|
149
|
+
ts.TypeFlags.BigIntLike |
|
|
150
|
+
ts.TypeFlags.ESSymbolLike |
|
|
151
|
+
ts.TypeFlags.Null |
|
|
152
|
+
ts.TypeFlags.Undefined |
|
|
153
|
+
ts.TypeFlags.Void |
|
|
154
|
+
ts.TypeFlags.Never)) !==
|
|
155
|
+
0);
|
|
156
|
+
}
|
|
58
157
|
/** Chooses each in-scope record shape's enumeration table from its
|
|
59
158
|
* witnesses. Runs once retained reachability has settled the historical
|
|
60
159
|
* tables and derived metadata, before the order-snapshotting helper bodies
|
|
@@ -90,52 +189,95 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
90
189
|
/** Every record shape a type can hold, through fields, arms, elements,
|
|
91
190
|
* callables, promises and class fields. */
|
|
92
191
|
/** Each walk shares one `seen` set per result set, so every type graph
|
|
93
|
-
* is walked once however many roots reach it.
|
|
94
|
-
|
|
95
|
-
|
|
192
|
+
* is walked once however many roots reach it.
|
|
193
|
+
*
|
|
194
|
+
* `produced` walks only what a checked conversion into the type can
|
|
195
|
+
* build. It answers an existing native instance for a class type (a plain
|
|
196
|
+
* object cannot acquire a class brand; only %Error rebuilds), so the
|
|
197
|
+
* records the instance's fields hold come from the class's own writes and
|
|
198
|
+
* its checked field setters, each a witness of its own. A checked
|
|
199
|
+
* function's parameters receive native values: a record parameter is
|
|
200
|
+
* passed out, never built, though a callback among them receives values
|
|
201
|
+
* built from JavaScript again. */
|
|
202
|
+
const shapesIn = (type, out, seen, produced = false) => {
|
|
203
|
+
const visit = (t, built) => {
|
|
204
|
+
const mark = built ? "" : "-";
|
|
205
|
+
// A container JavaScript builds converts into fresh native storage, so
|
|
206
|
+
// its children are built too. One passed out stays shared: JavaScript
|
|
207
|
+
// writes into it (built children) and reads native values out of it,
|
|
208
|
+
// such as callbacks whose parameters it then builds (children passed
|
|
209
|
+
// out). Those children count in both directions.
|
|
210
|
+
const child = (type) => {
|
|
211
|
+
visit(type, true);
|
|
212
|
+
if (!built)
|
|
213
|
+
visit(type, false);
|
|
214
|
+
return true;
|
|
215
|
+
};
|
|
96
216
|
if (t.kind === "record") {
|
|
97
|
-
if (seen.has("r:" + t.shapeId))
|
|
217
|
+
if (seen.has(mark + "r:" + t.shapeId))
|
|
98
218
|
return true;
|
|
99
|
-
seen.add("r:" + t.shapeId);
|
|
100
|
-
|
|
219
|
+
seen.add(mark + "r:" + t.shapeId);
|
|
220
|
+
if (built)
|
|
221
|
+
out.add(t.shapeId);
|
|
101
222
|
const shape = shapes.get(t.shapeId);
|
|
102
223
|
if (shape) {
|
|
103
224
|
for (const f of shape.fields)
|
|
104
|
-
|
|
225
|
+
child(f.type);
|
|
105
226
|
if (shape.indexValue)
|
|
106
|
-
|
|
227
|
+
child(shape.indexValue);
|
|
107
228
|
}
|
|
108
229
|
return true;
|
|
109
230
|
}
|
|
110
231
|
if (t.kind === "union") {
|
|
111
|
-
if (seen.has("u:" + t.unionId))
|
|
232
|
+
if (seen.has(mark + "u:" + t.unionId))
|
|
112
233
|
return true;
|
|
113
|
-
seen.add("u:" + t.unionId);
|
|
234
|
+
seen.add(mark + "u:" + t.unionId);
|
|
114
235
|
for (const arm of lowerer.unions.get(t.unionId)?.arms ?? [])
|
|
115
|
-
visit(arm);
|
|
236
|
+
visit(arm, built);
|
|
116
237
|
return true;
|
|
117
238
|
}
|
|
118
239
|
if (t.kind === "object") {
|
|
119
|
-
if (
|
|
240
|
+
if (produced && t.className !== "%Error")
|
|
120
241
|
return true;
|
|
121
|
-
seen.
|
|
242
|
+
if (seen.has(mark + "c:" + t.className))
|
|
243
|
+
return true;
|
|
244
|
+
seen.add(mark + "c:" + t.className);
|
|
122
245
|
for (const f of lowerer.classes.get(t.className)?.def.fields ?? [])
|
|
123
|
-
|
|
246
|
+
child(f.type);
|
|
124
247
|
return true;
|
|
125
248
|
}
|
|
126
|
-
|
|
249
|
+
if (produced && t.kind === "func") {
|
|
250
|
+
for (const param of t.params)
|
|
251
|
+
visit(param, !built);
|
|
252
|
+
return visit(t.ret, built);
|
|
253
|
+
}
|
|
254
|
+
return everyTypeChild(t, child);
|
|
127
255
|
};
|
|
128
|
-
visit(type);
|
|
256
|
+
visit(type, true);
|
|
129
257
|
};
|
|
130
258
|
const opaqueShapes = new Set();
|
|
131
259
|
const opaqueSeen = new Set();
|
|
132
260
|
const runtimeShapes = new Set();
|
|
133
261
|
const runtimeSeen = new Set();
|
|
262
|
+
/** Shapes the declaration-typed boundary converts into (adopting casts):
|
|
263
|
+
* their values come from package code that builds them in the
|
|
264
|
+
* declaration's order, the order their table holds. */
|
|
265
|
+
const declaredShapes = new Set();
|
|
266
|
+
const declaredSeen = new Set();
|
|
267
|
+
/** The checked result of a replaceable method call while every site that
|
|
268
|
+
* can replace the method installs functions that return no record. */
|
|
269
|
+
const unchangedMethodResult = (node) => {
|
|
270
|
+
const name = notes.methodResultOf(node);
|
|
271
|
+
if (name === undefined)
|
|
272
|
+
return false;
|
|
273
|
+
const sites = lowerer.methodAccessSites.get(name) ?? [];
|
|
274
|
+
return sites.every((site) => replacesWithoutRecords(lowerer, site));
|
|
275
|
+
};
|
|
134
276
|
const producedBy = (type, opaque) => {
|
|
135
277
|
if (opaque)
|
|
136
278
|
shapesIn(type, opaqueShapes, opaqueSeen);
|
|
137
279
|
else
|
|
138
|
-
shapesIn(type, runtimeShapes, runtimeSeen);
|
|
280
|
+
shapesIn(type, runtimeShapes, runtimeSeen, true);
|
|
139
281
|
};
|
|
140
282
|
// ── collection ──────────────────────────────────────────────────────
|
|
141
283
|
let pos = 0;
|
|
@@ -229,7 +371,12 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
229
371
|
// record may walk its keys; runtime builders make new records.
|
|
230
372
|
for (const arg of e.args)
|
|
231
373
|
observedRoots.push(arg.type);
|
|
232
|
-
|
|
374
|
+
// An always-throwing call stands in for a value (`error.nodeThrow`
|
|
375
|
+
// in a narrowing ternary) and never produces one. Other calls
|
|
376
|
+
// whose signature result is VOID are typed by their use site and
|
|
377
|
+
// build the record at run time (`server.address()`).
|
|
378
|
+
if (!ALWAYS_THROW_LIB_FNS.has(e.fn))
|
|
379
|
+
producedBy(e.type, true);
|
|
233
380
|
return;
|
|
234
381
|
case "intrinsic":
|
|
235
382
|
// Intrinsics hand back values built elsewhere, except allSettled's
|
|
@@ -242,10 +389,33 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
242
389
|
case "strIntrinsic":
|
|
243
390
|
case "regexIntrinsic":
|
|
244
391
|
case "bytesIntrinsic":
|
|
392
|
+
// Promise.withResolvers records are built by the backend in a fixed
|
|
393
|
+
// layout.
|
|
394
|
+
case "promiseWithResolvers":
|
|
245
395
|
producedBy(e.type, true);
|
|
246
396
|
return;
|
|
397
|
+
case "genResume": {
|
|
398
|
+
// A resume builds at most its IteratorResult record ({ done, value }
|
|
399
|
+
// in a fixed layout; an async generator's settles a promise of it).
|
|
400
|
+
// The value it carries is the generator's own yielded or returned
|
|
401
|
+
// value, which the generator's body constructs. The record-free
|
|
402
|
+
// drives build nothing: `value` moves that value out, and step,
|
|
403
|
+
// close and a record-free delegate answer a boolean or nothing.
|
|
404
|
+
if (e.mode === "step" || e.mode === "value" || e.mode === "close")
|
|
405
|
+
return;
|
|
406
|
+
const result = e.type.kind === "promise" ? e.type.inner : e.type;
|
|
407
|
+
if (result.kind === "record")
|
|
408
|
+
opaqueShapes.add(result.shapeId);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
247
411
|
case "dynCheck":
|
|
248
|
-
if (
|
|
412
|
+
if (e.adopt === true)
|
|
413
|
+
shapesIn(e.type, declaredShapes, declaredSeen);
|
|
414
|
+
// Conversions that build no record: a boxed primitive, and a
|
|
415
|
+
// replaceable method's result while no replacement the program can
|
|
416
|
+
// install returns a record: then it is the method's own value,
|
|
417
|
+
// boxed and checked back unchanged.
|
|
418
|
+
else if (!orderPreservingClone(e) && !primitiveSource(e) && !unchangedMethodResult(e))
|
|
249
419
|
producedBy(e.type, false);
|
|
250
420
|
return;
|
|
251
421
|
case "dynDestrCheck":
|
|
@@ -310,6 +480,9 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
310
480
|
}
|
|
311
481
|
for (const id of runtimeShapes)
|
|
312
482
|
factsOf(id).runtime = true;
|
|
483
|
+
for (const id of declaredShapes)
|
|
484
|
+
if (!runtimeShapes.has(id))
|
|
485
|
+
factsOf(id).pinned = true;
|
|
313
486
|
// ── scope ───────────────────────────────────────────────────────────
|
|
314
487
|
// Only plain declared-field shapes with a table take part.
|
|
315
488
|
const inScope = (shape) => shape !== undefined &&
|
|
@@ -524,6 +697,22 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
524
697
|
deps.add(c.source);
|
|
525
698
|
return [...deps];
|
|
526
699
|
};
|
|
700
|
+
/** `{ ...value, ...rest }` that starts with a spread of a value of the
|
|
701
|
+
* literal's own shape holding every key: it creates its keys in the
|
|
702
|
+
* value's order, and the later segments only overwrite them. With no
|
|
703
|
+
* checked conversion building the shape, every value enumerates in the
|
|
704
|
+
* one table this pass chooses, so the copy agrees with any choice and
|
|
705
|
+
* adds no edge. */
|
|
706
|
+
const copiesItself = (id, f, table, segments) => {
|
|
707
|
+
const first = segments[0];
|
|
708
|
+
return (first !== undefined &&
|
|
709
|
+
first.kind === "spread" &&
|
|
710
|
+
first.shapeId === id &&
|
|
711
|
+
!first.maybeAbsent &&
|
|
712
|
+
!f.runtime &&
|
|
713
|
+
segments.every((s) => s.kind !== "opaque") &&
|
|
714
|
+
table.every((k) => !maybeAbsent(id, k)));
|
|
715
|
+
};
|
|
527
716
|
/** One shape's order given its sources' current orders. */
|
|
528
717
|
const resolveOne = (id, current) => {
|
|
529
718
|
const shape = shapes.get(id);
|
|
@@ -544,6 +733,8 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
544
733
|
if (f.pinned)
|
|
545
734
|
chain(table, edges);
|
|
546
735
|
for (const segments of f.literals) {
|
|
736
|
+
if (copiesItself(id, f, table, segments))
|
|
737
|
+
continue;
|
|
547
738
|
const sequences = literalSequences(segments, keySet, current);
|
|
548
739
|
if (sequences === null)
|
|
549
740
|
return "unknown";
|
|
@@ -654,5 +845,562 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
654
845
|
shape.declaredOrder = [...shape.declaredOrder.filter(isArrayIndex), ...resolved.order];
|
|
655
846
|
notes.changed.add(id);
|
|
656
847
|
}
|
|
848
|
+
// ── per-instance orders ─────────────────────────────────────────────
|
|
849
|
+
// A shape whose literals write its keys in more than one order has no
|
|
850
|
+
// one table. Each value then records which of the orders it was written
|
|
851
|
+
// in (KEY_ORDER_FIELD), when every construction's order is known
|
|
852
|
+
// statically or copied from a value that records its own:
|
|
853
|
+
// - a literal of explicit keys writes its order;
|
|
854
|
+
// - a copy from a shape with one resolved order writes that order;
|
|
855
|
+
// - a copy from a value of a shape with orders writes the source's
|
|
856
|
+
// order, filtered to the copy's keys (rest bindings, width copies);
|
|
857
|
+
// - clones copy the field, and every other construction (synthesized
|
|
858
|
+
// literals, checked conversions, runtime producers) leaves 0, today's
|
|
859
|
+
// table, as before.
|
|
860
|
+
// A write of an optional key a value lacks moves the key to the end of
|
|
861
|
+
// the value's order, as in Node: the orders include every order such
|
|
862
|
+
// writes reach, and each write site updates the index after it evaluates
|
|
863
|
+
// the value and before it writes the key.
|
|
864
|
+
const MAX_ORDERS = 16;
|
|
865
|
+
const unresolved = (id) => result.get(id) === "unknown";
|
|
866
|
+
/** `order` over every key of `table`: keys the order lacks follow it. */
|
|
867
|
+
const complete = (order, table) => {
|
|
868
|
+
const keys = new Set(table);
|
|
869
|
+
const out = order.filter((k) => keys.has(k));
|
|
870
|
+
const seen = new Set(out);
|
|
871
|
+
return [...out, ...table.filter((k) => !seen.has(k))];
|
|
872
|
+
};
|
|
873
|
+
const literalOrder = (segments) => {
|
|
874
|
+
const out = [];
|
|
875
|
+
for (const segment of segments) {
|
|
876
|
+
if (segment.kind !== "key" || !segment.definite)
|
|
877
|
+
return null;
|
|
878
|
+
if (!isArrayIndex(segment.name))
|
|
879
|
+
out.push(segment.name);
|
|
880
|
+
}
|
|
881
|
+
return out;
|
|
882
|
+
};
|
|
883
|
+
/** `{ ...value }` of a value of the literal's own shape: a copy of the
|
|
884
|
+
* value's order. */
|
|
885
|
+
const selfSpread = (segments, id) => segments.length === 1 &&
|
|
886
|
+
segments[0].kind === "spread" &&
|
|
887
|
+
segments[0].shapeId === id &&
|
|
888
|
+
!segments[0].maybeAbsent;
|
|
889
|
+
const sameOrder = (a, b) => a.join("\0") === b.join("\0");
|
|
890
|
+
const indexOfOrder = (orders, order) => orders.findIndex((o) => sameOrder(o, order));
|
|
891
|
+
/** The keys writes can add to a value of the shape, or null when a
|
|
892
|
+
* clone override can (the clone's order is its source's). */
|
|
893
|
+
const movingKeys = (id, f, table) => {
|
|
894
|
+
const keys = new Set(table);
|
|
895
|
+
const moving = new Set();
|
|
896
|
+
for (const w of f.writes) {
|
|
897
|
+
if (w.kind === "delete" || !keys.has(w.field) || !maybeAbsent(id, w.field))
|
|
898
|
+
continue;
|
|
899
|
+
if (w.kind === "clone")
|
|
900
|
+
return null;
|
|
901
|
+
moving.add(w.field);
|
|
902
|
+
}
|
|
903
|
+
return [...moving];
|
|
904
|
+
};
|
|
905
|
+
/** `values[i]` for the order index `current` holds, as a chain of
|
|
906
|
+
* tests. */
|
|
907
|
+
const indexChain = (current, values, loc) => {
|
|
908
|
+
let out = { kind: "numLit", value: values[values.length - 1], type: F64, loc };
|
|
909
|
+
for (let i = values.length - 2; i >= 0; i--) {
|
|
910
|
+
if (out.kind === "numLit" && out.value === values[i])
|
|
911
|
+
continue;
|
|
912
|
+
out = {
|
|
913
|
+
kind: "ternary",
|
|
914
|
+
cond: {
|
|
915
|
+
kind: "bin",
|
|
916
|
+
op: "===",
|
|
917
|
+
left: current,
|
|
918
|
+
right: { kind: "numLit", value: i, type: F64, loc },
|
|
919
|
+
type: BOOL,
|
|
920
|
+
loc,
|
|
921
|
+
},
|
|
922
|
+
then: { kind: "numLit", value: values[i], type: F64, loc },
|
|
923
|
+
else_: out,
|
|
924
|
+
type: F64,
|
|
925
|
+
loc,
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
return out;
|
|
929
|
+
};
|
|
930
|
+
const moves = new Map();
|
|
931
|
+
/** Adds to `orders` every order writes of `moving` keys reach from them
|
|
932
|
+
* and records each key's transitions; false past MAX_ORDERS. */
|
|
933
|
+
const closeUnderMoves = (id, orders, moving) => {
|
|
934
|
+
const transitions = new Map(moving.map((k) => [k, []]));
|
|
935
|
+
for (let i = 0; i < orders.length; i++) {
|
|
936
|
+
for (const key of moving) {
|
|
937
|
+
const moved = [...orders[i].filter((k) => k !== key), key];
|
|
938
|
+
let index = indexOfOrder(orders, moved);
|
|
939
|
+
if (index < 0) {
|
|
940
|
+
if (orders.length === MAX_ORDERS)
|
|
941
|
+
return false;
|
|
942
|
+
index = orders.push(moved) - 1;
|
|
943
|
+
}
|
|
944
|
+
transitions.get(key)[i] = index;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
if (moving.length > 0)
|
|
948
|
+
moves.set(id, transitions);
|
|
949
|
+
return true;
|
|
950
|
+
};
|
|
951
|
+
// Observed shapes, and the shapes their values copy their orders from.
|
|
952
|
+
const wanted = new Set(observed);
|
|
953
|
+
const pending = [...observed];
|
|
954
|
+
while (pending.length > 0) {
|
|
955
|
+
const f = facts.get(pending.pop());
|
|
956
|
+
if (f === undefined)
|
|
957
|
+
continue;
|
|
958
|
+
const sources = [
|
|
959
|
+
...f.copies.map((c) => c.source),
|
|
960
|
+
...f.literals.flatMap((segments) => segments.flatMap((s) => (s.kind === "spread" ? [s.shapeId] : []))),
|
|
961
|
+
];
|
|
962
|
+
for (const source of sources) {
|
|
963
|
+
if (wanted.has(source))
|
|
964
|
+
continue;
|
|
965
|
+
wanted.add(source);
|
|
966
|
+
pending.push(source);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
const orderable = (id, f) => {
|
|
970
|
+
const shape = shapes.get(id);
|
|
971
|
+
if (!wanted.has(id) || !unresolved(id) || !inScope(shape))
|
|
972
|
+
return null;
|
|
973
|
+
const moving = movingKeys(id, f, tableOf(shape));
|
|
974
|
+
return moving === null ? null : { shape, moving };
|
|
975
|
+
};
|
|
976
|
+
const variants = new Map();
|
|
977
|
+
for (const [id, f] of facts) {
|
|
978
|
+
const candidate = orderable(id, f);
|
|
979
|
+
// A runtime producer builds the shape's values in its fixed layout,
|
|
980
|
+
// which has no KEY_ORDER_FIELD.
|
|
981
|
+
if (candidate === null || f.literals.length === 0 || f.opaque)
|
|
982
|
+
continue;
|
|
983
|
+
const table = tableOf(candidate.shape);
|
|
984
|
+
const orders = [table];
|
|
985
|
+
let ok = true;
|
|
986
|
+
const add = (order) => {
|
|
987
|
+
const full = complete(order, table);
|
|
988
|
+
if (indexOfOrder(orders, full) < 0)
|
|
989
|
+
orders.push(full);
|
|
990
|
+
};
|
|
991
|
+
for (const segments of f.literals) {
|
|
992
|
+
if (selfSpread(segments, id))
|
|
993
|
+
continue;
|
|
994
|
+
const order = literalOrder(segments);
|
|
995
|
+
if (order === null)
|
|
996
|
+
ok = false;
|
|
997
|
+
else
|
|
998
|
+
add(order);
|
|
999
|
+
}
|
|
1000
|
+
for (const c of f.copies) {
|
|
1001
|
+
if (c.source === id)
|
|
1002
|
+
continue;
|
|
1003
|
+
const source = result.get(c.source);
|
|
1004
|
+
if (source === undefined || source === "unknown")
|
|
1005
|
+
ok = false;
|
|
1006
|
+
else
|
|
1007
|
+
add(source.order.filter((k) => c.keys.has(k)));
|
|
1008
|
+
}
|
|
1009
|
+
if (!ok || orders.length > MAX_ORDERS || !closeUnderMoves(id, orders, candidate.moving))
|
|
1010
|
+
continue;
|
|
1011
|
+
if (orders.length > 1)
|
|
1012
|
+
variants.set(id, orders);
|
|
1013
|
+
else
|
|
1014
|
+
moves.delete(id);
|
|
1015
|
+
}
|
|
1016
|
+
const templateOf = (segments, id) => {
|
|
1017
|
+
const prefix = [];
|
|
1018
|
+
const suffix = [];
|
|
1019
|
+
let source = null;
|
|
1020
|
+
for (const segment of segments) {
|
|
1021
|
+
if (segment.kind === "opaque")
|
|
1022
|
+
return null;
|
|
1023
|
+
if (segment.kind === "spread") {
|
|
1024
|
+
if (source !== null || segment.maybeAbsent || segment.shapeId === id)
|
|
1025
|
+
return null;
|
|
1026
|
+
source = segment.shapeId;
|
|
1027
|
+
continue;
|
|
1028
|
+
}
|
|
1029
|
+
if (!segment.definite)
|
|
1030
|
+
return null;
|
|
1031
|
+
(source === null ? prefix : suffix).push(segment.name);
|
|
1032
|
+
}
|
|
1033
|
+
return source === null ? null : { source, prefix, suffix };
|
|
1034
|
+
};
|
|
1035
|
+
const templateKey = (t) => JSON.stringify([t.source, t.prefix, t.suffix]);
|
|
1036
|
+
const copyTemplate = (source) => ({ source, prefix: [], suffix: [] });
|
|
1037
|
+
const mirrors = new Map();
|
|
1038
|
+
for (const [id, f] of facts) {
|
|
1039
|
+
if (variants.has(id) || f.pinned || f.runtime || f.opaque)
|
|
1040
|
+
continue;
|
|
1041
|
+
const candidate = orderable(id, f);
|
|
1042
|
+
if (candidate === null || f.literals.length + f.copies.length === 0)
|
|
1043
|
+
continue;
|
|
1044
|
+
const templates = f.literals.map((segments) => templateOf(segments, id));
|
|
1045
|
+
for (const c of f.copies)
|
|
1046
|
+
templates.push(copyTemplate(c.source));
|
|
1047
|
+
const first = templates[0];
|
|
1048
|
+
if (first === null ||
|
|
1049
|
+
first === undefined ||
|
|
1050
|
+
templates.some((t) => t === null || templateKey(t) !== templateKey(first)))
|
|
1051
|
+
continue;
|
|
1052
|
+
const orders = variants.get(first.source);
|
|
1053
|
+
if (orders === undefined || mirrors.has(first.source))
|
|
1054
|
+
continue;
|
|
1055
|
+
const table = tableOf(candidate.shape);
|
|
1056
|
+
const tested = first.suffix.filter((k) => maybeAbsent(first.source, k));
|
|
1057
|
+
if (tested.length > 4)
|
|
1058
|
+
continue;
|
|
1059
|
+
const mirrorOf = (o, lacks) => {
|
|
1060
|
+
const order = [...first.prefix];
|
|
1061
|
+
for (const k of o)
|
|
1062
|
+
if (!lacks.has(k) && !order.includes(k))
|
|
1063
|
+
order.push(k);
|
|
1064
|
+
for (const k of first.suffix)
|
|
1065
|
+
if (!order.includes(k))
|
|
1066
|
+
order.push(k);
|
|
1067
|
+
return complete(order, table);
|
|
1068
|
+
};
|
|
1069
|
+
let mirrored;
|
|
1070
|
+
let template = first;
|
|
1071
|
+
if (tested.length === 0)
|
|
1072
|
+
mirrored = orders.map((o) => mirrorOf(o, new Set()));
|
|
1073
|
+
else {
|
|
1074
|
+
mirrored = [];
|
|
1075
|
+
const index = [];
|
|
1076
|
+
for (let present = 0; present < 1 << tested.length; present++) {
|
|
1077
|
+
const lacks = new Set(tested.filter((_, j) => (present & (1 << j)) === 0));
|
|
1078
|
+
const row = [];
|
|
1079
|
+
for (const o of orders) {
|
|
1080
|
+
const order = mirrorOf(o, lacks);
|
|
1081
|
+
let i = indexOfOrder(mirrored, order);
|
|
1082
|
+
if (i < 0)
|
|
1083
|
+
i = mirrored.push(order) - 1;
|
|
1084
|
+
row.push(i);
|
|
1085
|
+
}
|
|
1086
|
+
index.push(row);
|
|
1087
|
+
}
|
|
1088
|
+
if (mirrored.length > MAX_ORDERS)
|
|
1089
|
+
continue;
|
|
1090
|
+
template = {
|
|
1091
|
+
source: first.source,
|
|
1092
|
+
prefix: first.prefix,
|
|
1093
|
+
suffix: first.suffix,
|
|
1094
|
+
select: { keys: tested, index },
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
if (!closeUnderMoves(id, mirrored, candidate.moving))
|
|
1098
|
+
continue;
|
|
1099
|
+
if (mirrored.every((o) => sameOrder(o, mirrored[0]))) {
|
|
1100
|
+
// Every order of the source agrees over these keys: one table.
|
|
1101
|
+
moves.delete(id);
|
|
1102
|
+
const shape = candidate.shape;
|
|
1103
|
+
const only = mirrored[0] ?? table;
|
|
1104
|
+
if (!sameOrder(only, table))
|
|
1105
|
+
shape.declaredOrder = [...shape.declaredOrder.filter(isArrayIndex), ...only];
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
variants.set(id, mirrored);
|
|
1109
|
+
mirrors.set(id, template);
|
|
1110
|
+
}
|
|
1111
|
+
if (variants.size === 0)
|
|
1112
|
+
return;
|
|
1113
|
+
// Every construction of those shapes, to give each its order index. A
|
|
1114
|
+
// copy reads its source's index, so its source must be a plain binding.
|
|
1115
|
+
const sites = new Map();
|
|
1116
|
+
/** The statements a spread literal's sequence evaluates first: the
|
|
1117
|
+
* spread value's binding, then its fields. */
|
|
1118
|
+
const prologues = new Map();
|
|
1119
|
+
const siteOf = (e) => {
|
|
1120
|
+
if (e.kind === "seqExpr" && e.result.kind === "recordLit")
|
|
1121
|
+
prologues.set(e.result, e.stmts);
|
|
1122
|
+
if (e.kind === "recordLit" && e.type.kind === "record" && variants.has(e.type.shapeId)) {
|
|
1123
|
+
const list = sites.get(e.type.shapeId) ?? [];
|
|
1124
|
+
list.push(e);
|
|
1125
|
+
sites.set(e.type.shapeId, list);
|
|
1126
|
+
}
|
|
1127
|
+
return everyExprChild(e, siteOf, siteStmt);
|
|
1128
|
+
};
|
|
1129
|
+
const siteStmt = (st) => everyStmtChild(st, siteOf, siteStmt);
|
|
1130
|
+
/** The function each literal with a prologue is built in. */
|
|
1131
|
+
const owners = new Map();
|
|
1132
|
+
for (const fn of fns) {
|
|
1133
|
+
const before = new Set(prologues.keys());
|
|
1134
|
+
for (const st of fn.body)
|
|
1135
|
+
siteStmt(st);
|
|
1136
|
+
for (const lit of prologues.keys())
|
|
1137
|
+
if (!before.has(lit))
|
|
1138
|
+
owners.set(lit, fn);
|
|
1139
|
+
}
|
|
1140
|
+
/** Where a literal evaluated its spread of `source`: the declaration the
|
|
1141
|
+
* spread segment names, in the literal's own prologue. */
|
|
1142
|
+
const spreadBinding = (lit, source) => {
|
|
1143
|
+
const stmts = prologues.get(lit);
|
|
1144
|
+
if (stmts === undefined)
|
|
1145
|
+
return null;
|
|
1146
|
+
for (const segment of notes.literalOf(lit) ?? []) {
|
|
1147
|
+
if (segment.kind !== "spread" || segment.shapeId !== source || !segment.value)
|
|
1148
|
+
continue;
|
|
1149
|
+
const localId = segment.value.localId;
|
|
1150
|
+
const at = stmts.findIndex((st) => st.kind === "varDecl" && st.localId === localId);
|
|
1151
|
+
const decl = stmts[at];
|
|
1152
|
+
if (decl?.kind !== "varDecl" || decl.init === null)
|
|
1153
|
+
return null;
|
|
1154
|
+
return { stmts, at, value: { kind: "varRef", localId, type: decl.init.type, loc: lit.loc } };
|
|
1155
|
+
}
|
|
1156
|
+
return null;
|
|
1157
|
+
};
|
|
1158
|
+
/** The binding a copy or spread reads its fields from. A literal's spread
|
|
1159
|
+
* names it; every field of a copy reads it. */
|
|
1160
|
+
const copySource = (lit, source) => {
|
|
1161
|
+
if (notes.literalOf(lit) !== undefined)
|
|
1162
|
+
return spreadBinding(lit, source)?.value ?? null;
|
|
1163
|
+
for (const field of lit.fields) {
|
|
1164
|
+
const value = field.value;
|
|
1165
|
+
if (value.kind === "recordGet" && value.shapeId === source && value.obj.kind === "varRef")
|
|
1166
|
+
return value.obj;
|
|
1167
|
+
}
|
|
1168
|
+
for (const st of prologues.get(lit) ?? []) {
|
|
1169
|
+
if (st.kind !== "varDecl" || st.init === null)
|
|
1170
|
+
continue;
|
|
1171
|
+
const t = st.init.type;
|
|
1172
|
+
if (t.kind === "record" && t.shapeId === source)
|
|
1173
|
+
return { kind: "varRef", localId: st.localId, type: t, loc: lit.loc };
|
|
1174
|
+
}
|
|
1175
|
+
return null;
|
|
1176
|
+
};
|
|
1177
|
+
const orderIndex = (id, lit) => {
|
|
1178
|
+
const orders = variants.get(id);
|
|
1179
|
+
const segments = notes.literalOf(lit);
|
|
1180
|
+
if (segments !== undefined && selfSpread(segments, id)) {
|
|
1181
|
+
const obj = copySource(lit, id);
|
|
1182
|
+
if (obj === null)
|
|
1183
|
+
return null;
|
|
1184
|
+
return {
|
|
1185
|
+
kind: "recordGet",
|
|
1186
|
+
obj,
|
|
1187
|
+
shapeId: id,
|
|
1188
|
+
field: KEY_ORDER_FIELD,
|
|
1189
|
+
type: F64,
|
|
1190
|
+
loc: lit.loc,
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
const mirror = mirrors.get(id);
|
|
1194
|
+
if (segments !== undefined && mirror !== undefined) {
|
|
1195
|
+
const obj = copySource(lit, mirror.source);
|
|
1196
|
+
if (obj === null)
|
|
1197
|
+
return null;
|
|
1198
|
+
const sourceIndex = {
|
|
1199
|
+
kind: "recordGet",
|
|
1200
|
+
obj,
|
|
1201
|
+
shapeId: mirror.source,
|
|
1202
|
+
field: KEY_ORDER_FIELD,
|
|
1203
|
+
type: F64,
|
|
1204
|
+
loc: lit.loc,
|
|
1205
|
+
};
|
|
1206
|
+
const select = mirror.select;
|
|
1207
|
+
if (select === undefined)
|
|
1208
|
+
return sourceIndex;
|
|
1209
|
+
// Tests the source for each key in turn, then picks by its index.
|
|
1210
|
+
const pick = (j, present) => {
|
|
1211
|
+
if (j === select.keys.length)
|
|
1212
|
+
return indexChain(sourceIndex, select.index[present], lit.loc);
|
|
1213
|
+
return {
|
|
1214
|
+
kind: "ternary",
|
|
1215
|
+
cond: lowerer.recordFieldPresent(obj, mirror.source, select.keys[j], lit.loc),
|
|
1216
|
+
then: pick(j + 1, present | (1 << j)),
|
|
1217
|
+
else_: pick(j + 1, present),
|
|
1218
|
+
type: F64,
|
|
1219
|
+
loc: lit.loc,
|
|
1220
|
+
};
|
|
1221
|
+
};
|
|
1222
|
+
return pick(0, 0);
|
|
1223
|
+
}
|
|
1224
|
+
if (segments !== undefined) {
|
|
1225
|
+
const order = literalOrder(segments);
|
|
1226
|
+
return order === null ? null : indexOfOrder(orders, complete(order, orders[0]));
|
|
1227
|
+
}
|
|
1228
|
+
const source = notes.copyOf(lit);
|
|
1229
|
+
if (source === undefined)
|
|
1230
|
+
return 0;
|
|
1231
|
+
if (variants.has(source) && (source === id || mirrors.get(id)?.source === source)) {
|
|
1232
|
+
const obj = copySource(lit, source);
|
|
1233
|
+
if (obj === null)
|
|
1234
|
+
return null;
|
|
1235
|
+
return {
|
|
1236
|
+
kind: "recordGet",
|
|
1237
|
+
obj,
|
|
1238
|
+
shapeId: source,
|
|
1239
|
+
field: KEY_ORDER_FIELD,
|
|
1240
|
+
type: F64,
|
|
1241
|
+
loc: lit.loc,
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1244
|
+
const resolved = result.get(source);
|
|
1245
|
+
if (resolved === undefined || resolved === "unknown")
|
|
1246
|
+
return null;
|
|
1247
|
+
const keys = new Set(lit.fields.filter((x) => x.value.kind !== "fieldAbsent").map((x) => x.name));
|
|
1248
|
+
return indexOfOrder(orders, complete(resolved.order.filter((k) => keys.has(k)), orders[0]));
|
|
1249
|
+
};
|
|
1250
|
+
const plan = new Map();
|
|
1251
|
+
const dropped = new Set();
|
|
1252
|
+
for (const [id, list] of sites) {
|
|
1253
|
+
for (const lit of list) {
|
|
1254
|
+
const index = orderIndex(id, lit);
|
|
1255
|
+
if (index === null || (typeof index === "number" && index < 0))
|
|
1256
|
+
dropped.add(id);
|
|
1257
|
+
else
|
|
1258
|
+
plan.set(lit, index);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
// Write sites of keys that move: each reads and updates the value's
|
|
1262
|
+
// index before the write.
|
|
1263
|
+
const writeSites = [];
|
|
1264
|
+
let writeFn = null;
|
|
1265
|
+
const writeExpr = (e) => everyExprChild(e, writeExpr, writeOf);
|
|
1266
|
+
const writeOf = (st) => {
|
|
1267
|
+
if (st.kind === "recordSet" &&
|
|
1268
|
+
st.value.kind !== "fieldAbsent" &&
|
|
1269
|
+
moves.get(st.shapeId)?.has(st.field))
|
|
1270
|
+
writeSites.push({ st, fn: writeFn });
|
|
1271
|
+
return everyStmtChild(st, writeExpr, writeOf);
|
|
1272
|
+
};
|
|
1273
|
+
for (const fn of fns) {
|
|
1274
|
+
writeFn = fn;
|
|
1275
|
+
for (const st of fn.body)
|
|
1276
|
+
writeOf(st);
|
|
1277
|
+
}
|
|
1278
|
+
// A shape whose copies cannot read their source keeps today's table, and
|
|
1279
|
+
// so do the shapes that mirror it.
|
|
1280
|
+
for (const [id, mirror] of mirrors)
|
|
1281
|
+
if (dropped.has(mirror.source))
|
|
1282
|
+
dropped.add(id);
|
|
1283
|
+
let temporaries = 0;
|
|
1284
|
+
for (const [lit, index] of plan) {
|
|
1285
|
+
const id = lit.type.shapeId;
|
|
1286
|
+
if (dropped.has(id))
|
|
1287
|
+
continue;
|
|
1288
|
+
let value = typeof index === "number" ? { kind: "numLit", value: index, type: F64, loc: lit.loc } : index;
|
|
1289
|
+
// A spread's order is the source's order at the spread: a later
|
|
1290
|
+
// property may move the source's keys. Read it right after the literal
|
|
1291
|
+
// evaluates the source.
|
|
1292
|
+
const source = mirrors.get(id)?.source;
|
|
1293
|
+
const binding = typeof index === "number" || !source ? null : spreadBinding(lit, source);
|
|
1294
|
+
const fn = owners.get(lit);
|
|
1295
|
+
if (binding && fn) {
|
|
1296
|
+
const localId = `%keyOrderSource.${temporaries++}`;
|
|
1297
|
+
fn.locals.push({ id: localId, name: "%keyOrderSource", type: F64, mutable: false });
|
|
1298
|
+
binding.stmts.splice(binding.at + 1, 0, {
|
|
1299
|
+
kind: "varDecl",
|
|
1300
|
+
localId,
|
|
1301
|
+
init: value,
|
|
1302
|
+
loc: lit.loc,
|
|
1303
|
+
});
|
|
1304
|
+
value = { kind: "varRef", localId, type: F64, loc: lit.loc };
|
|
1305
|
+
}
|
|
1306
|
+
lit.fields.push({ name: KEY_ORDER_FIELD, value });
|
|
1307
|
+
}
|
|
1308
|
+
const replacements = new Map();
|
|
1309
|
+
for (const { st, fn } of writeSites) {
|
|
1310
|
+
if (dropped.has(st.shapeId))
|
|
1311
|
+
continue;
|
|
1312
|
+
const transitions = moves.get(st.shapeId).get(st.field);
|
|
1313
|
+
const loc = st.loc;
|
|
1314
|
+
// A receiver other than a binding evaluates once, into a local. So does
|
|
1315
|
+
// a binding when the value evaluates first (below): the value may
|
|
1316
|
+
// assign the binding, and the write still goes to the object the
|
|
1317
|
+
// binding held before.
|
|
1318
|
+
const pure = st.value.kind === "numLit" ||
|
|
1319
|
+
st.value.kind === "strLit" ||
|
|
1320
|
+
st.value.kind === "boolLit" ||
|
|
1321
|
+
st.value.kind === "varRef";
|
|
1322
|
+
let plain = st.obj;
|
|
1323
|
+
while (plain.kind === "unionNarrow" || plain.kind === "downcast")
|
|
1324
|
+
plain = plain.value;
|
|
1325
|
+
const prologue = [];
|
|
1326
|
+
let obj = st.obj;
|
|
1327
|
+
if (plain.kind !== "varRef" || !pure) {
|
|
1328
|
+
const localId = `%keyOrderReceiver.${temporaries++}`;
|
|
1329
|
+
fn.locals.push({ id: localId, name: "%keyOrderReceiver", type: st.obj.type, mutable: false });
|
|
1330
|
+
prologue.push({ kind: "varDecl", localId, init: st.obj, loc });
|
|
1331
|
+
obj = { kind: "varRef", localId, type: st.obj.type, loc };
|
|
1332
|
+
}
|
|
1333
|
+
const current = {
|
|
1334
|
+
kind: "recordGet",
|
|
1335
|
+
obj,
|
|
1336
|
+
shapeId: st.shapeId,
|
|
1337
|
+
field: KEY_ORDER_FIELD,
|
|
1338
|
+
type: F64,
|
|
1339
|
+
loc,
|
|
1340
|
+
};
|
|
1341
|
+
const next = indexChain(current, transitions, loc);
|
|
1342
|
+
// The value evaluates before the key is tested and moved: it may add
|
|
1343
|
+
// other keys to the same value, which then come first.
|
|
1344
|
+
let value = st.value;
|
|
1345
|
+
if (!pure) {
|
|
1346
|
+
const localId = `%keyOrderValue.${temporaries++}`;
|
|
1347
|
+
fn.locals.push({ id: localId, name: "%keyOrderValue", type: value.type, mutable: false });
|
|
1348
|
+
prologue.push({ kind: "varDecl", localId, init: value, loc });
|
|
1349
|
+
value = { kind: "varRef", localId, type: value.type, loc };
|
|
1350
|
+
}
|
|
1351
|
+
const absent = {
|
|
1352
|
+
kind: "unary",
|
|
1353
|
+
op: "!",
|
|
1354
|
+
operand: lowerer.recordFieldPresent(obj, st.shapeId, st.field, loc),
|
|
1355
|
+
type: BOOL,
|
|
1356
|
+
loc,
|
|
1357
|
+
};
|
|
1358
|
+
const update = {
|
|
1359
|
+
kind: "recordSet",
|
|
1360
|
+
obj,
|
|
1361
|
+
shapeId: st.shapeId,
|
|
1362
|
+
field: KEY_ORDER_FIELD,
|
|
1363
|
+
value: next,
|
|
1364
|
+
loc,
|
|
1365
|
+
};
|
|
1366
|
+
// The write becomes a block that moves the key first.
|
|
1367
|
+
const write = {
|
|
1368
|
+
kind: "recordSet",
|
|
1369
|
+
obj,
|
|
1370
|
+
shapeId: st.shapeId,
|
|
1371
|
+
field: st.field,
|
|
1372
|
+
value,
|
|
1373
|
+
loc,
|
|
1374
|
+
};
|
|
1375
|
+
const guard = { kind: "if", cond: absent, then: [update], else_: null, loc };
|
|
1376
|
+
const block = { kind: "block", body: [...prologue, guard, write], loc };
|
|
1377
|
+
let replaced = replacements.get(fn);
|
|
1378
|
+
if (replaced === undefined) {
|
|
1379
|
+
replaced = new Map();
|
|
1380
|
+
replacements.set(fn, replaced);
|
|
1381
|
+
}
|
|
1382
|
+
replaced.set(st, block);
|
|
1383
|
+
}
|
|
1384
|
+
for (const [fn, replaced] of replacements) {
|
|
1385
|
+
fn.body = transformStmtList(fn.body, {
|
|
1386
|
+
expr: (e) => e,
|
|
1387
|
+
stmt: (st) => replaced.get(st) ?? st,
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
for (const [id, orders] of variants) {
|
|
1391
|
+
if (dropped.has(id))
|
|
1392
|
+
continue;
|
|
1393
|
+
const shape = shapes.get(id);
|
|
1394
|
+
const indexKeys = (shape.declaredOrder ?? []).filter(isArrayIndex);
|
|
1395
|
+
shapes.addKeyOrderField(id);
|
|
1396
|
+
const tables = [];
|
|
1397
|
+
for (const order of orders) {
|
|
1398
|
+
const table = [...indexKeys];
|
|
1399
|
+
for (const key of order)
|
|
1400
|
+
table.push(key);
|
|
1401
|
+
tables.push(table);
|
|
1402
|
+
}
|
|
1403
|
+
shape.orderVariants = tables;
|
|
1404
|
+
}
|
|
657
1405
|
}
|
|
658
1406
|
//# sourceMappingURL=key-order-witness.js.map
|