@scriptc/compiler 0.4.6 → 0.4.7
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/node-fallback/events.d.ts +6 -1
- package/ambient/node-fallback/fs-promises.d.ts +1 -1
- package/ambient/node-fallback/fs.d.ts +54 -10
- package/ambient/node-fallback/http.d.ts +3 -1
- package/ambient/node-fallback/net.d.ts +19 -0
- package/ambient/node-fallback/querystring.d.ts +3 -3
- package/ambient/scriptc-node-fallback.d.ts +58 -13
- package/dist/backend/executable-features.js +13 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.d.ts +12 -1
- package/dist/backend/immutability.js +50 -4
- package/dist/backend/immutability.js.map +1 -1
- package/dist/backend/immutability.test.js +95 -1
- package/dist/backend/immutability.test.js.map +1 -1
- package/dist/backend/library-pack.js +2 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/linker.d.ts +11 -0
- package/dist/backend/linker.js +31 -3
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/lld.d.ts +7 -2
- package/dist/backend/lld.js +5 -3
- package/dist/backend/lld.js.map +1 -1
- package/dist/backend/lld.test.js +10 -4
- package/dist/backend/lld.test.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +50 -1
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/cpu-dispatch.js +6 -5
- package/dist/backend/llvm/cpu-dispatch.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +53 -1
- package/dist/backend/llvm/dyn.js +221 -9
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +1 -1
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-module.js +148 -50
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emit-statements.js +39 -19
- package/dist/backend/llvm/emit-statements.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +29 -2
- package/dist/backend/llvm/emitter.js +86 -7
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +4 -1
- package/dist/backend/llvm/expr-calls.js +20 -4
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +209 -16
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +94 -11
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +8 -0
- package/dist/backend/llvm/expr-stream-bridges.js +42 -2
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +16 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +206 -20
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/integer-values.d.ts +2 -0
- package/dist/backend/llvm/integer-values.js +6 -0
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/js-ic.d.ts +38 -0
- package/dist/backend/llvm/js-ic.js +295 -1
- package/dist/backend/llvm/js-ic.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +20 -0
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +116 -11
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +136 -24
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +70 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +67 -0
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/loop-entry-versions.d.ts +2 -2
- package/dist/backend/llvm/loop-entry-versions.js +43 -21
- package/dist/backend/llvm/loop-entry-versions.js.map +1 -1
- package/dist/backend/llvm/loop-state.d.ts +7 -1
- package/dist/backend/llvm/loop-state.js +20 -2
- package/dist/backend/llvm/loop-state.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.d.ts +3 -1
- package/dist/backend/llvm/map-number-lookup.js +7 -3
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +52 -11
- package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
- package/dist/backend/llvm/receiver-brackets.test.d.ts +1 -0
- package/dist/backend/llvm/receiver-brackets.test.js +68 -0
- package/dist/backend/llvm/receiver-brackets.test.js.map +1 -0
- package/dist/backend/llvm/record-views.d.ts +22 -2
- package/dist/backend/llvm/record-views.js +139 -10
- package/dist/backend/llvm/record-views.js.map +1 -1
- package/dist/backend/llvm/record-views.test.js +76 -0
- package/dist/backend/llvm/record-views.test.js.map +1 -1
- package/dist/backend/llvm/reference-writes.js +1 -0
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +3 -0
- package/dist/backend/llvm/shapes.js +18 -3
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +4 -0
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +10 -1
- package/dist/backend/llvm/speculative-integers.js +59 -8
- package/dist/backend/llvm/speculative-integers.js.map +1 -1
- package/dist/backend/llvm/unwind-abi.d.ts +3 -3
- package/dist/backend/llvm/unwind-abi.js +8 -3
- package/dist/backend/llvm/unwind-abi.js.map +1 -1
- package/dist/backend/llvm/walkers.js +1 -1
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +54 -0
- package/dist/backend/native/executable.js +87 -5
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -1
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.js +5 -1
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native/vendor.d.ts +1 -1
- package/dist/backend/native/vendor.js +1 -1
- package/dist/backend/native/vendor.js.map +1 -1
- package/dist/backend/native-codegen.js +3 -0
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +43 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-link-info.js +1 -0
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-profile.d.ts +4 -1
- package/dist/backend/native-profile.js +12 -1
- package/dist/backend/native-profile.js.map +1 -1
- package/dist/backend/native-profile.test.js +10 -0
- package/dist/backend/native-profile.test.js.map +1 -1
- package/dist/backend/publication.d.ts +4 -1
- package/dist/backend/publication.js +4 -2
- package/dist/backend/publication.js.map +1 -1
- 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 +31 -7
- package/dist/backend/runtime-pack-core.js +21 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.d.ts +18 -1
- package/dist/backend/runtime-pack-native.js +138 -29
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-native.test.js +166 -4
- package/dist/backend/runtime-pack-native.test.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +3 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.d.ts +7 -0
- package/dist/backend/runtime-pack.js +25 -3
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +3 -11
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/vendor-archives.d.ts +4 -1
- package/dist/backend/vendor-archives.js +264 -3
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.d.ts +36 -0
- package/dist/backend/vendor-inputs.js +42 -0
- package/dist/backend/vendor-inputs.js.map +1 -1
- package/dist/backend/vendor-inputs.test.js +28 -1
- package/dist/backend/vendor-inputs.test.js.map +1 -1
- package/dist/backend/warm-cache.js +2 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/compat/fetch-profile.d.ts +7 -1
- package/dist/compat/fetch-profile.js +23 -10
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +7 -0
- package/dist/contracts/check.d.ts +3 -0
- package/dist/contracts/check.js +18 -5
- package/dist/contracts/check.js.map +1 -1
- package/dist/coverage/surface-manifest.js +1 -1
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/codes.d.ts +6 -0
- package/dist/diagnostics/codes.js +6 -0
- package/dist/diagnostics/codes.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +50 -0
- package/dist/diagnostics/diagnostic.js +142 -3
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/dynamic-tier.js +3 -1
- package/dist/diagnostics/dynamic-tier.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +29 -0
- package/dist/executable/executable-cache.js +18 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +5 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.d.ts +13 -3
- package/dist/executable/prepare.js +271 -18
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/early-errors.d.ts +14 -0
- package/dist/frontend/early-errors.js +305 -0
- package/dist/frontend/early-errors.js.map +1 -0
- package/dist/frontend/early-errors.test.d.ts +1 -0
- package/dist/frontend/early-errors.test.js +42 -0
- package/dist/frontend/early-errors.test.js.map +1 -0
- package/dist/frontend/inferred-js-diagnostics.test.js +23 -0
- package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +47 -0
- package/dist/frontend/input-tracker.js +173 -36
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +86 -2
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/js-inference.d.ts +2 -0
- package/dist/frontend/js-inference.js +18 -0
- package/dist/frontend/js-inference.js.map +1 -0
- package/dist/frontend/lowering/binding-analysis.d.ts +2 -1
- package/dist/frontend/lowering/binding-analysis.js +65 -1
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.js +9 -0
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-namespaces.d.ts +1 -1
- package/dist/frontend/lowering/builtin-namespaces.js +19 -2
- package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.d.ts +7 -0
- package/dist/frontend/lowering/builtins/child-process-methods.js +50 -10
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.js +5 -1
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.d.ts +1 -1
- package/dist/frontend/lowering/builtins/dates.js +23 -1
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/environment.d.ts +55 -0
- package/dist/frontend/lowering/builtins/environment.js +213 -2
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +47 -16
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.d.ts +25 -7
- package/dist/frontend/lowering/builtins/filesystem.js +185 -16
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +39 -2
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +8 -0
- package/dist/frontend/lowering/builtins/module-resolution.js +31 -5
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +3 -2
- package/dist/frontend/lowering/builtins/operating-system.js +5 -4
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +17 -1
- package/dist/frontend/lowering/builtins/process.js +285 -19
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/querystring.d.ts +8 -0
- package/dist/frontend/lowering/builtins/querystring.js +202 -18
- package/dist/frontend/lowering/builtins/querystring.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.js +21 -3
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/reflection.js +60 -1
- package/dist/frontend/lowering/builtins/reflection.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.js +208 -59
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.js +20 -1
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/v8.d.ts +5 -5
- package/dist/frontend/lowering/builtins/v8.js +7 -5
- package/dist/frontend/lowering/builtins/v8.js.map +1 -1
- package/dist/frontend/lowering/builtins/web-streams-dyn.d.ts +17 -2
- package/dist/frontend/lowering/builtins/web-streams-dyn.js +97 -9
- package/dist/frontend/lowering/builtins/web-streams-dyn.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.js +77 -0
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.d.ts +3 -0
- package/dist/frontend/lowering/cjs-exports-object.js +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
- package/dist/frontend/lowering/cjs-inline-require.js +5 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +5 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +114 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +59 -10
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.js +15 -0
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-views.d.ts +13 -0
- package/dist/frontend/lowering/class-views.js +51 -0
- package/dist/frontend/lowering/class-views.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +15 -1
- package/dist/frontend/lowering/coercions/function-adapters.js +54 -10
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/state.d.ts +7 -0
- package/dist/frontend/lowering/coercions/state.js +7 -0
- package/dist/frontend/lowering/coercions/state.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +60 -3
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +29 -1
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +8 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +132 -28
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +16 -5
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +16 -0
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +4 -0
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +11 -0
- package/dist/frontend/lowering/containers/callback-arguments.js +53 -0
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/filter-predicates.d.ts +10 -0
- package/dist/frontend/lowering/containers/filter-predicates.js +69 -3
- package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +46 -2
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/expressions/array-literals.d.ts +14 -0
- package/dist/frontend/lowering/expressions/array-literals.js +26 -10
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +104 -12
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +121 -4
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +143 -3
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/keyed-field-targets.d.ts +11 -1
- package/dist/frontend/lowering/expressions/keyed-field-targets.js +22 -1
- package/dist/frontend/lowering/expressions/keyed-field-targets.js.map +1 -1
- package/dist/frontend/lowering/expressions/narrowing.js +25 -1
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +5 -1
- package/dist/frontend/lowering/expressions/object-literals.js +778 -229
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +66 -20
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +31 -0
- package/dist/frontend/lowering/expressions/property-access.js +796 -12
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/relational.js +29 -1
- package/dist/frontend/lowering/expressions/relational.js.map +1 -1
- package/dist/frontend/lowering/expressions/typeof.js +17 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +132 -17
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/frozen-records.d.ts +6 -0
- package/dist/frontend/lowering/frozen-records.js +10 -4
- package/dist/frontend/lowering/frozen-records.js.map +1 -1
- package/dist/frontend/lowering/frozen-records.test.d.ts +1 -0
- package/dist/frontend/lowering/frozen-records.test.js +44 -0
- package/dist/frontend/lowering/frozen-records.test.js.map +1 -0
- package/dist/frontend/lowering/function-names.d.ts +9 -0
- package/dist/frontend/lowering/function-names.js +95 -0
- package/dist/frontend/lowering/function-names.js.map +1 -0
- package/dist/frontend/lowering/function-returns.js +5 -3
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +49 -0
- package/dist/frontend/lowering/generic-functions.js +365 -7
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/global-values.d.ts +9 -0
- package/dist/frontend/lowering/global-values.js +44 -0
- package/dist/frontend/lowering/global-values.js.map +1 -1
- package/dist/frontend/lowering/handle-properties.js +34 -1
- package/dist/frontend/lowering/handle-properties.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.d.ts +54 -0
- package/dist/frontend/lowering/key-order-witness.js +546 -5
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +14 -0
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +110 -1
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +36 -6
- package/dist/frontend/lowering/lower-builtin-values.js +332 -58
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +22 -1
- package/dist/frontend/lowering/lower-calls.js +427 -48
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-calls.test.js +78 -0
- package/dist/frontend/lowering/lower-calls.test.js.map +1 -0
- package/dist/frontend/lowering/lower-classes.d.ts +16 -5
- package/dist/frontend/lowering/lower-classes.js +168 -51
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +9 -0
- package/dist/frontend/lowering/lower-event-emitter.js +383 -41
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +14 -0
- package/dist/frontend/lowering/lower-exprs.js +25 -0
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +2 -0
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +80 -33
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +87 -25
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-node-island.d.ts +35 -4
- package/dist/frontend/lowering/lower-node-island.js +456 -61
- package/dist/frontend/lowering/lower-node-island.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +160 -9
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-shared-modules.js +13 -1
- package/dist/frontend/lowering/lower-shared-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +3 -2
- package/dist/frontend/lowering/lower-stdlib.js +32 -18
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +21 -4
- package/dist/frontend/lowering/lower-stmts.js +580 -103
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +126 -8
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +133 -21
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +139 -3
- package/dist/frontend/lowering/lowerer.js +579 -43
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +1 -1
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.js +15 -0
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/new-target.js +2 -2
- package/dist/frontend/lowering/nullish-empty-pattern.d.ts +17 -0
- package/dist/frontend/lowering/nullish-empty-pattern.js +118 -0
- package/dist/frontend/lowering/nullish-empty-pattern.js.map +1 -0
- package/dist/frontend/lowering/partial-assertions.d.ts +39 -0
- package/dist/frontend/lowering/partial-assertions.js +195 -0
- package/dist/frontend/lowering/partial-assertions.js.map +1 -0
- package/dist/frontend/lowering/primitive-wrappers.d.ts +34 -0
- package/dist/frontend/lowering/primitive-wrappers.js +220 -0
- package/dist/frontend/lowering/primitive-wrappers.js.map +1 -0
- package/dist/frontend/lowering/private-statics.d.ts +46 -0
- package/dist/frontend/lowering/private-statics.js +322 -0
- package/dist/frontend/lowering/private-statics.js.map +1 -0
- package/dist/frontend/lowering/record-sources.d.ts +12 -1
- package/dist/frontend/lowering/record-sources.js +60 -0
- package/dist/frontend/lowering/record-sources.js.map +1 -1
- package/dist/frontend/lowering/strict-equality.d.ts +4 -0
- package/dist/frontend/lowering/strict-equality.js +14 -0
- package/dist/frontend/lowering/strict-equality.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +27 -0
- package/dist/frontend/lowering/surfaces.js +135 -62
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/unit-journal.d.ts +128 -17
- package/dist/frontend/lowering/unit-journal.js +310 -53
- package/dist/frontend/lowering/unit-journal.js.map +1 -1
- package/dist/frontend/lowering/unit-journal.test.js +91 -3
- package/dist/frontend/lowering/unit-journal.test.js.map +1 -1
- package/dist/frontend/lowering/unit-reuse.d.ts +92 -0
- package/dist/frontend/lowering/unit-reuse.js +1008 -0
- package/dist/frontend/lowering/unit-reuse.js.map +1 -0
- package/dist/frontend/lowering/width-lift.d.ts +12 -0
- package/dist/frontend/npm-file-import.test.d.ts +1 -0
- package/dist/frontend/npm-file-import.test.js +76 -0
- package/dist/frontend/npm-file-import.test.js.map +1 -0
- package/dist/frontend/npm-static.js +17 -2
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +9 -0
- package/dist/frontend/npm.js +82 -0
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/pipeline-native.js +2 -1
- package/dist/frontend/pipeline-native.js.map +1 -1
- package/dist/frontend/pipeline.d.ts +4 -0
- package/dist/frontend/pipeline.js +68 -7
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/program-node.d.ts +3 -0
- package/dist/frontend/program-node.js +13 -6
- package/dist/frontend/program-node.js.map +1 -1
- package/dist/frontend/program.d.ts +9 -0
- package/dist/frontend/program.js +159 -7
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance-core.js +4 -0
- package/dist/frontend/provenance-core.js.map +1 -1
- package/dist/frontend/services.d.ts +14 -0
- package/dist/frontend/services.js +52 -2
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +61 -1
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/shape-inference/analyze.d.ts +5 -0
- package/dist/frontend/shape-inference/analyze.js +104 -4
- package/dist/frontend/shape-inference/analyze.js.map +1 -1
- package/dist/frontend/shape-inference/domain.js +0 -1
- package/dist/frontend/shape-inference/domain.js.map +1 -1
- package/dist/frontend/shape-inference/index.js +5 -1
- package/dist/frontend/shape-inference/index.js.map +1 -1
- package/dist/frontend/shape-inference/memo.d.ts +2 -1
- package/dist/frontend/shape-inference/memo.js +6 -2
- package/dist/frontend/shape-inference/memo.js.map +1 -1
- package/dist/frontend/shape-inference/overlay.d.ts +1 -1
- package/dist/frontend/shape-inference/overlay.js +116 -2
- package/dist/frontend/shape-inference/overlay.js.map +1 -1
- package/dist/frontend/shape-inference/static-objects.js +11 -6
- package/dist/frontend/shape-inference/static-objects.js.map +1 -1
- package/dist/frontend/source-phase-imports.test.d.ts +1 -0
- package/dist/frontend/source-phase-imports.test.js +37 -0
- package/dist/frontend/source-phase-imports.test.js.map +1 -0
- package/dist/frontend/ts7/ast-node.d.ts +6 -1
- package/dist/frontend/ts7/ast-node.js +12 -0
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-wire-protocols.test.js +11 -3
- package/dist/frontend/ts7/ast-wire-protocols.test.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.js +3 -5
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +13 -0
- package/dist/frontend/ts7/checker-backend.js +84 -2
- package/dist/frontend/ts7/checker-backend.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.test.js +126 -2
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
- package/dist/frontend/ts7/program-host.d.ts +22 -1
- package/dist/frontend/ts7/program-host.js +49 -4
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/program-host.test.js +83 -0
- package/dist/frontend/ts7/program-host.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-process.d.ts +16 -1
- package/dist/frontend/ts7/rpc-process.js +170 -92
- package/dist/frontend/ts7/rpc-process.js.map +1 -1
- package/dist/frontend/ts7/rpc-process.test.js +49 -21
- package/dist/frontend/ts7/rpc-process.test.js.map +1 -1
- package/dist/frontend/tsc-codes.js +70 -0
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +7 -2
- package/dist/frontend/type-mapper.js +148 -1
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +152 -8
- package/dist/index.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/build.d.ts +3 -2
- package/dist/ir/build.js +4 -2
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-effects.js +53 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +211 -10
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/codec.d.ts +82 -0
- package/dist/ir/codec.generated.d.ts +13 -0
- package/dist/ir/codec.generated.js +5274 -0
- package/dist/ir/codec.generated.js.map +1 -0
- package/dist/ir/codec.js +325 -0
- package/dist/ir/codec.js.map +1 -0
- package/dist/ir/codec.test.d.ts +1 -0
- package/dist/ir/codec.test.js +225 -0
- package/dist/ir/codec.test.js.map +1 -0
- package/dist/ir/fields.generated.d.ts +20 -10
- package/dist/ir/fields.generated.js +1031 -11
- package/dist/ir/fields.generated.js.map +1 -1
- package/dist/ir/fields.test.js +46 -2
- package/dist/ir/fields.test.js.map +1 -1
- package/dist/ir/function-references.d.ts +5 -4
- package/dist/ir/function-references.js +8 -4
- package/dist/ir/function-references.js.map +1 -1
- package/dist/ir/function-references.test.js +7 -0
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/inline-array-sources.js +4 -1
- package/dist/ir/inline-array-sources.js.map +1 -1
- package/dist/ir/inline-array-views.d.ts +13 -0
- package/dist/ir/inline-array-views.js +944 -0
- package/dist/ir/inline-array-views.js.map +1 -0
- package/dist/ir/inline-arrays.d.ts +7 -0
- package/dist/ir/inline-arrays.js +190 -55
- package/dist/ir/inline-arrays.js.map +1 -1
- package/dist/ir/inline-arrays.test.js +140 -2
- package/dist/ir/inline-arrays.test.js.map +1 -1
- package/dist/ir/integer-ranges.js +16 -6
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/ir.d.ts +75 -44
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/js-ic.d.ts +10 -9
- package/dist/ir/js-ic.js +28 -20
- package/dist/ir/js-ic.js.map +1 -1
- package/dist/ir/js-ic.test.js +10 -2
- package/dist/ir/js-ic.test.js.map +1 -1
- package/dist/ir/jsval.js +374 -63
- package/dist/ir/jsval.js.map +1 -1
- package/dist/ir/jsval.test.js +96 -2
- package/dist/ir/jsval.test.js.map +1 -1
- package/dist/ir/loop-entry-ranges.js +112 -9
- package/dist/ir/loop-entry-ranges.js.map +1 -1
- package/dist/ir/loop-entry-ranges.test.js +40 -0
- package/dist/ir/loop-entry-ranges.test.js.map +1 -1
- package/dist/ir/parameter-versions.d.ts +2 -1
- package/dist/ir/parameter-versions.js +3 -1
- package/dist/ir/parameter-versions.js.map +1 -1
- package/dist/ir/receiver-readers.js +58 -2
- package/dist/ir/receiver-readers.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +60 -1
- package/dist/ir/runtime-features.js +277 -2
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +165 -1
- package/dist/ir/runtime-features.test.js.map +1 -1
- package/dist/ir/saturating-loop-jams.d.ts +8 -1
- package/dist/ir/saturating-loop-jams.js +46 -7
- package/dist/ir/saturating-loop-jams.js.map +1 -1
- package/dist/ir/saturating-loop-jams.test.js +39 -1
- package/dist/ir/saturating-loop-jams.test.js.map +1 -1
- package/dist/ir/self-captures.js +8 -1
- package/dist/ir/self-captures.js.map +1 -1
- package/dist/ir/self-captures.test.js +15 -0
- package/dist/ir/self-captures.test.js.map +1 -1
- package/dist/ir/serialize.d.ts +3 -2
- package/dist/ir/serialize.js +6 -2
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.js +82 -4
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +46 -0
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/ir-policy.js +3 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/native/cache.js +2 -0
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cli.js +2 -0
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +8 -2
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/prepare.js +32 -3
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.js +53 -3
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/sanitizer.test.js +88 -2
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.js +9 -2
- package/dist/native/toolchain.js.map +1 -1
- package/dist/node-islands/boundary.d.ts +25 -1
- package/dist/node-islands/boundary.js +28 -2
- package/dist/node-islands/boundary.js.map +1 -1
- package/dist/node-islands/detect.d.ts +18 -1
- package/dist/node-islands/detect.js +365 -40
- package/dist/node-islands/detect.js.map +1 -1
- package/dist/node-islands/detect.test.js +151 -4
- package/dist/node-islands/detect.test.js.map +1 -1
- package/dist/node-islands/effect-gate.js +30 -20
- package/dist/node-islands/effect-gate.js.map +1 -1
- package/dist/node-islands/effect-gate.test.js +4 -1
- package/dist/node-islands/effect-gate.test.js.map +1 -1
- package/dist/node-islands/libnode.d.ts +1 -1
- package/dist/node-islands/libnode.js +1 -1
- package/dist/node-islands/libnode.js.map +1 -1
- package/dist/node-islands/modules.d.ts +28 -0
- package/dist/node-islands/modules.js +156 -0
- package/dist/node-islands/modules.js.map +1 -1
- package/dist/node-islands/modules.test.js +105 -1
- package/dist/node-islands/modules.test.js.map +1 -1
- package/dist/node-islands/policy.js +2 -3
- package/dist/node-islands/policy.js.map +1 -1
- package/dist/node-islands/probe-recorder.d.ts +1 -0
- package/dist/node-islands/probe-recorder.js +596 -0
- package/dist/node-islands/probe-recorder.js.map +1 -0
- package/dist/node-islands/probe-recorder.test.d.ts +1 -0
- package/dist/node-islands/probe-recorder.test.js +80 -0
- package/dist/node-islands/probe-recorder.test.js.map +1 -0
- package/dist/node-islands/report.test.js +2 -0
- package/dist/node-islands/report.test.js.map +1 -1
- package/dist/node-islands/rules.js +4 -0
- package/dist/node-islands/rules.js.map +1 -1
- package/dist/node-islands/scan.d.ts +7 -1
- package/dist/node-islands/scan.js +51 -2
- package/dist/node-islands/scan.js.map +1 -1
- package/dist/node-islands/snapshot.d.ts +38 -1
- package/dist/node-islands/snapshot.js +165 -161
- package/dist/node-islands/snapshot.js.map +1 -1
- package/dist/node-islands/snapshot.test.js +63 -2
- package/dist/node-islands/snapshot.test.js.map +1 -1
- package/dist/node-islands/summary.js +8 -0
- package/dist/node-islands/summary.js.map +1 -1
- package/dist/node-islands/type-strip.d.ts +11 -0
- package/dist/node-islands/type-strip.js +157 -0
- package/dist/node-islands/type-strip.js.map +1 -0
- package/dist/node-islands/type-strip.test.d.ts +1 -0
- package/dist/node-islands/type-strip.test.js +31 -0
- package/dist/node-islands/type-strip.test.js.map +1 -0
- package/dist/project-config.d.ts +4 -0
- package/dist/project-config.js +19 -0
- package/dist/project-config.js.map +1 -1
- package/dist/project-config.test.js +10 -0
- package/dist/project-config.test.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +43 -11
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { dynUndefinedExpr, strLit } from "../../ir/build.js";
|
|
2
|
+
import { BOOL, DYN, F64, KEY_ORDER_FIELD, shapeHasAccessorSlots, typeEquals, UNDEFINED_T, VOID, } from "../../ir/ir.js";
|
|
3
|
+
import { everyExprChild, everyStmtChild, everyStmtList, everyTypeChild, transformStmtList, } from "../../ir/traverse.js";
|
|
3
4
|
import * as ts from "../ts7/adapter.js";
|
|
4
5
|
import { ALWAYS_THROW_LIB_FNS } from "../../ir/builtin-effects.js";
|
|
5
|
-
import {
|
|
6
|
+
import { replaceChildExpr } from "../../ir/fields.generated.js";
|
|
7
|
+
import { InternalCompilerError } from "../../errors.js";
|
|
8
|
+
import { recordMayKeepSource, recordSourceTest } from "./record-sources.js";
|
|
6
9
|
/** The statements a key-order helper runs for record `ref`: `walks[0]`,
|
|
7
10
|
* its walk over the shape's table, or, for a shape with orderVariants, a
|
|
8
11
|
* branch per order (walks[i] for order i) on the value's KEY_ORDER_FIELD.
|
|
@@ -39,25 +42,77 @@ export class KeyOrderNotes {
|
|
|
39
42
|
literals = new Map();
|
|
40
43
|
copies = new Map();
|
|
41
44
|
methodResults = new Map();
|
|
45
|
+
/** Literals whose spreads copy source keys the target does not declare
|
|
46
|
+
* (a width spread), with their contributors (keepWidthSpreads), and
|
|
47
|
+
* every spread literal over a shape that can keep a source (same-shape
|
|
48
|
+
* copies, which keep the source's undeclared keys when it has any). */
|
|
49
|
+
widths = new Map();
|
|
50
|
+
/** `"k" in r` answers over a closed record whose literal key the shape
|
|
51
|
+
* does not declare, with the receiver the static form evaluated
|
|
52
|
+
* (keepSourceProbes). */
|
|
53
|
+
sourceProbes = new Map();
|
|
54
|
+
/** Same-shape `{ ...r, k: v }` clones (lowerObjectLiteral's recordClone
|
|
55
|
+
* fast path), which copy the source's own keys too (keepRecordClones). */
|
|
56
|
+
clones = new Set();
|
|
42
57
|
/** Shapes a frontend order surface (keys, values/entries, inspect,
|
|
43
58
|
* index-signature merges) walks. */
|
|
44
59
|
observed = new Set();
|
|
45
60
|
/** Shapes whose table this pass replaced. */
|
|
46
61
|
changed = new Set();
|
|
62
|
+
/** Width-spread literals this pass kept as a record's source
|
|
63
|
+
* (keepWidthSpreads). A kept copy holds undeclared keys, so the
|
|
64
|
+
* index-signature capture must consult it (lowerer.ts). */
|
|
65
|
+
keptWidthSpreads = 0;
|
|
66
|
+
/** The shapes those kept copies build. A width spread or clone only
|
|
67
|
+
* keeps a source on a shape in here, so the reflective helpers
|
|
68
|
+
* (lower-calls.ts) stay static for every other shape, and the pass reads
|
|
69
|
+
* it back as a spread source that can already hold one. */
|
|
70
|
+
keptSourceShapes = new Set();
|
|
47
71
|
/** The sizes of the notes' tables (unit-journal.ts). */
|
|
48
72
|
journalSizes() {
|
|
49
73
|
return [
|
|
50
74
|
this.literals.size,
|
|
51
75
|
this.copies.size,
|
|
52
76
|
this.methodResults.size,
|
|
77
|
+
this.widths.size,
|
|
78
|
+
this.sourceProbes.size,
|
|
79
|
+
this.clones.size,
|
|
53
80
|
this.observed.size,
|
|
54
81
|
this.changed.size,
|
|
82
|
+
this.keptSourceShapes.size,
|
|
55
83
|
];
|
|
56
84
|
}
|
|
57
85
|
literal(node, segments) {
|
|
58
86
|
this.literals.set(node, segments);
|
|
59
87
|
return node;
|
|
60
88
|
}
|
|
89
|
+
/** A record literal whose spreads copy source keys the target does not
|
|
90
|
+
* declare (`drops`), with its contributors. */
|
|
91
|
+
width(node, segments, drops) {
|
|
92
|
+
this.widths.set(node, { segments, drops });
|
|
93
|
+
return node;
|
|
94
|
+
}
|
|
95
|
+
widthOf(node) {
|
|
96
|
+
return this.widths.get(node);
|
|
97
|
+
}
|
|
98
|
+
/** A statically-false `"k" in r` over a closed record, which a kept
|
|
99
|
+
* source can make true. */
|
|
100
|
+
sourceProbe(node, receiver, key) {
|
|
101
|
+
this.sourceProbes.set(node, { receiver, key });
|
|
102
|
+
return node;
|
|
103
|
+
}
|
|
104
|
+
sourceProbeOf(node) {
|
|
105
|
+
return this.sourceProbes.get(node);
|
|
106
|
+
}
|
|
107
|
+
/** A same-shape `{ ...r, k: v }` clone, which copies the source's own
|
|
108
|
+
* keys as Node does. */
|
|
109
|
+
clone(node) {
|
|
110
|
+
this.clones.add(node);
|
|
111
|
+
return node;
|
|
112
|
+
}
|
|
113
|
+
isClone(node) {
|
|
114
|
+
return this.clones.has(node);
|
|
115
|
+
}
|
|
61
116
|
copy(node, sourceShapeId) {
|
|
62
117
|
this.copies.set(node, sourceShapeId);
|
|
63
118
|
return node;
|
|
@@ -80,6 +135,14 @@ export class KeyOrderNotes {
|
|
|
80
135
|
const method = this.methodResults.get(from);
|
|
81
136
|
if (method !== undefined)
|
|
82
137
|
this.methodResults.set(to, method);
|
|
138
|
+
const width = this.widths.get(from);
|
|
139
|
+
if (width !== undefined)
|
|
140
|
+
this.widths.set(to, width);
|
|
141
|
+
const probe = this.sourceProbes.get(from);
|
|
142
|
+
if (probe !== undefined)
|
|
143
|
+
this.sourceProbes.set(to, probe);
|
|
144
|
+
if (this.clones.has(from))
|
|
145
|
+
this.clones.add(to);
|
|
83
146
|
}
|
|
84
147
|
observe(type) {
|
|
85
148
|
if (type.kind === "record")
|
|
@@ -201,6 +264,8 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
201
264
|
return f;
|
|
202
265
|
};
|
|
203
266
|
const observedRoots = [];
|
|
267
|
+
/** The receivers of the program's own-key presence tests. */
|
|
268
|
+
const presenceRoots = [];
|
|
204
269
|
const inits = new Map();
|
|
205
270
|
const undefinedArmed = (t) => t.kind === "union" && lowerer.armTag(t.unionId, UNDEFINED_T) >= 0;
|
|
206
271
|
const containsAbsent = (value) => value.kind === "fieldAbsent" ||
|
|
@@ -311,6 +376,13 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
311
376
|
* each one is built. A literal's notes are shared by its rebuilt copies,
|
|
312
377
|
* so `literalSites` counts every literal of each witness. */
|
|
313
378
|
const leadingSpreads = new Map();
|
|
379
|
+
/** Width literals (KeyOrderNotes.width), where each is built. */
|
|
380
|
+
const widthSites = [];
|
|
381
|
+
/** `"k" in r` sites a kept source can answer true (keepSourceProbes). */
|
|
382
|
+
const probeSites = [];
|
|
383
|
+
/** Same-shape `{ ...r, k: v }` clones that copy the source's own keys
|
|
384
|
+
* (keepRecordClones). */
|
|
385
|
+
const cloneSites = [];
|
|
314
386
|
const literalSites = new Map();
|
|
315
387
|
const loops = [];
|
|
316
388
|
let loopIds = 0;
|
|
@@ -349,6 +421,13 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
349
421
|
inits.set(id, { count: 1, fn: fnName, loop: loopKey(), pos, fresh });
|
|
350
422
|
};
|
|
351
423
|
const visitExpr = (e) => {
|
|
424
|
+
const probe = notes.sourceProbeOf(e);
|
|
425
|
+
if (probe !== undefined && currentFn !== null) {
|
|
426
|
+
probeSites.push({ node: e, fn: currentFn });
|
|
427
|
+
presenceRoots.push(probe.receiver.type);
|
|
428
|
+
}
|
|
429
|
+
if (e.kind === "call" && e.callee.startsWith("%obj.hasOwn") && e.args[0] !== undefined)
|
|
430
|
+
presenceRoots.push(e.args[0].type);
|
|
352
431
|
switch (e.kind) {
|
|
353
432
|
case "recordLit": {
|
|
354
433
|
if (e.type.kind !== "record")
|
|
@@ -382,6 +461,8 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
382
461
|
case "recordClone": {
|
|
383
462
|
if (e.type.kind !== "record")
|
|
384
463
|
return;
|
|
464
|
+
if (notes.isClone(e) && currentFn !== null)
|
|
465
|
+
cloneSites.push({ node: e, fn: currentFn });
|
|
385
466
|
const f = factsOf(e.type.shapeId);
|
|
386
467
|
f.clones = true;
|
|
387
468
|
for (const o of e.overrides)
|
|
@@ -396,6 +477,9 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
396
477
|
const literal = e.result;
|
|
397
478
|
if (literal.kind !== "recordLit" || currentFn === null)
|
|
398
479
|
return;
|
|
480
|
+
const width = notes.widthOf(literal);
|
|
481
|
+
if (width !== undefined)
|
|
482
|
+
widthSites.push({ wrapper: e, literal, fn: currentFn, note: width });
|
|
399
483
|
const segments = notes.literalOf(literal);
|
|
400
484
|
const first = segments?.[0];
|
|
401
485
|
if (segments === undefined || first?.kind !== "spread" || first.value === undefined)
|
|
@@ -540,6 +624,157 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
540
624
|
for (const id of declaredShapes)
|
|
541
625
|
if (!runtimeShapes.has(id))
|
|
542
626
|
factsOf(id).pinned = true;
|
|
627
|
+
// ── width spreads ───────────────────────────────────────────────────
|
|
628
|
+
// A width spread keeps the copy's own keys when an order surface can
|
|
629
|
+
// observe its target (keepWidthSpreads). The observation is the one the
|
|
630
|
+
// tables use below, before ordered spreads join it. A source can be
|
|
631
|
+
// another width spread's target, so this runs until no site joins.
|
|
632
|
+
const keptWidths = new Set();
|
|
633
|
+
const keptClones = new Set();
|
|
634
|
+
/** The shapes a checked conversion in this program builds, which are the
|
|
635
|
+
* only values that already hold a source when this pass runs (the ones
|
|
636
|
+
* this pass keeps join keptSourceShapes as it decides). */
|
|
637
|
+
const convertedShapes = new Set();
|
|
638
|
+
{
|
|
639
|
+
const seen = new Set();
|
|
640
|
+
for (const fn of fns)
|
|
641
|
+
everyStmtList(fn.body, {
|
|
642
|
+
expr: (expr) => {
|
|
643
|
+
if (expr.kind === "dynCheck")
|
|
644
|
+
conversionShapes(lowerer, expr.type, convertedShapes, seen);
|
|
645
|
+
return true;
|
|
646
|
+
},
|
|
647
|
+
stmt: () => true,
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
/** The statements each kept site's literal evaluates in (the wrapper's
|
|
651
|
+
* prologue), which the per-instance order plan reads a spread's source
|
|
652
|
+
* binding from after keepWidthSpreads moved the literal into a
|
|
653
|
+
* declaration of its own. */
|
|
654
|
+
const keptLiteralStmts = new Map();
|
|
655
|
+
/** Shapes a kept dropping copy builds: the copy holds keys the shape has
|
|
656
|
+
* no slot for, so its order is its kept source's, and the shape keeps
|
|
657
|
+
* today's table (as a literal with a dropped field does without the
|
|
658
|
+
* kept source). */
|
|
659
|
+
const keptDropShapes = new Set();
|
|
660
|
+
{
|
|
661
|
+
const early = new Set();
|
|
662
|
+
const earlySeen = new Set();
|
|
663
|
+
for (const id of notes.observed)
|
|
664
|
+
shapesIn({ kind: "record", shapeId: id }, early, earlySeen);
|
|
665
|
+
for (const root of observedRoots)
|
|
666
|
+
shapesIn(root, early, earlySeen);
|
|
667
|
+
// A presence test (`"k" in r`, Object.hasOwn) observes a record's own
|
|
668
|
+
// keys as an order surface does.
|
|
669
|
+
for (const root of presenceRoots)
|
|
670
|
+
shapesIn(root, early, earlySeen);
|
|
671
|
+
// An observed copy shows the own keys of each record it spreads, so a
|
|
672
|
+
// spread source is observed through it, transitively.
|
|
673
|
+
for (let grew = true; grew;) {
|
|
674
|
+
grew = false;
|
|
675
|
+
for (const { literal, note } of widthSites) {
|
|
676
|
+
if (literal.type.kind !== "record" || !early.has(literal.type.shapeId))
|
|
677
|
+
continue;
|
|
678
|
+
for (const segment of note.segments) {
|
|
679
|
+
if (segment.kind !== "spread")
|
|
680
|
+
continue;
|
|
681
|
+
const before = early.size;
|
|
682
|
+
shapesIn(segment.value.type, early, earlySeen);
|
|
683
|
+
if (early.size !== before)
|
|
684
|
+
grew = true;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
for (let grew = true; grew;) {
|
|
689
|
+
grew = false;
|
|
690
|
+
for (const { wrapper, literal, note } of widthSites) {
|
|
691
|
+
if (!note.drops || keptWidths.has(wrapper) || literal.type.kind !== "record")
|
|
692
|
+
continue;
|
|
693
|
+
if (!early.has(literal.type.shapeId) || !widthKeepable(lowerer, wrapper, note.segments))
|
|
694
|
+
continue;
|
|
695
|
+
keptWidths.add(wrapper);
|
|
696
|
+
notes.keptSourceShapes.add(literal.type.shapeId);
|
|
697
|
+
grew = true;
|
|
698
|
+
for (const segment of note.segments)
|
|
699
|
+
if (segment.kind === "spread")
|
|
700
|
+
shapesIn(segment.value.type, early, earlySeen);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
// A same-shape copy (`{ ...r }`, `{ ...r, ...s }`) of a record that
|
|
704
|
+
// kept undeclared keys copies them too. A copy keeps its source's own
|
|
705
|
+
// keys, so a source can itself be such a copy; admit a non-dropping
|
|
706
|
+
// site only when a spread source of it can actually hold a source (a
|
|
707
|
+
// shape a checked conversion builds or an earlier kept copy's), so a
|
|
708
|
+
// program — or a copy of a shape no conversion ever produces — stays
|
|
709
|
+
// byte-identical.
|
|
710
|
+
if (lowerer.recordSourcesPossible || keptWidths.size > 0) {
|
|
711
|
+
for (let grew = true; grew;) {
|
|
712
|
+
grew = false;
|
|
713
|
+
for (const { wrapper, literal, note } of widthSites) {
|
|
714
|
+
if (note.drops || keptWidths.has(wrapper) || literal.type.kind !== "record")
|
|
715
|
+
continue;
|
|
716
|
+
if (!early.has(literal.type.shapeId) || !widthKeepable(lowerer, wrapper, note.segments))
|
|
717
|
+
continue;
|
|
718
|
+
if (!note.segments.some((segment) => segment.kind === "spread" &&
|
|
719
|
+
reachesKeptSource(lowerer, segment.value.type, convertedShapes)))
|
|
720
|
+
continue;
|
|
721
|
+
keptWidths.add(wrapper);
|
|
722
|
+
notes.keptSourceShapes.add(literal.type.shapeId);
|
|
723
|
+
grew = true;
|
|
724
|
+
for (const segment of note.segments)
|
|
725
|
+
if (segment.kind === "spread")
|
|
726
|
+
shapesIn(segment.value.type, early, earlySeen);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
for (const { wrapper, literal, note } of widthSites) {
|
|
731
|
+
if (!keptWidths.has(wrapper) || literal.type.kind !== "record")
|
|
732
|
+
continue;
|
|
733
|
+
const shapeId = literal.type.shapeId;
|
|
734
|
+
notes.keptSourceShapes.add(shapeId);
|
|
735
|
+
if (!note.drops) {
|
|
736
|
+
// A same-shape copy keeps its own order (a spread of the literal's
|
|
737
|
+
// own shape reads its source's index): its witness stays, and the
|
|
738
|
+
// plan finds the source binding through the wrapper's prologue.
|
|
739
|
+
keptLiteralStmts.set(literal, wrapper.stmts);
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
// A kept copy that drops keys enumerates through its own kept source,
|
|
743
|
+
// so like a checked conversion it contributes no order to its shape's
|
|
744
|
+
// table, and the shape keeps today's table.
|
|
745
|
+
const segments = notes.literalOf(literal);
|
|
746
|
+
const literals = facts.get(shapeId)?.literals;
|
|
747
|
+
const at = segments === undefined || literals === undefined ? -1 : literals.indexOf(segments);
|
|
748
|
+
if (at >= 0)
|
|
749
|
+
literals.splice(at, 1);
|
|
750
|
+
keptDropShapes.add(shapeId);
|
|
751
|
+
}
|
|
752
|
+
// Same-shape clones of a record that can keep keys copy them too, when
|
|
753
|
+
// the program converts checked values or keeps a width spread and the
|
|
754
|
+
// shape is observed. The source, not the clone, decides: a clone of a
|
|
755
|
+
// shape no conversion produces finds no keys to keep.
|
|
756
|
+
if (lowerer.recordSourcesPossible || keptWidths.size > 0) {
|
|
757
|
+
for (const { node } of cloneSites) {
|
|
758
|
+
if (node.kind !== "recordClone")
|
|
759
|
+
continue;
|
|
760
|
+
const cloneT = node.type;
|
|
761
|
+
if (cloneT.kind !== "record" || !early.has(cloneT.shapeId))
|
|
762
|
+
continue;
|
|
763
|
+
if (!recordMayKeepSource(lowerer, cloneT))
|
|
764
|
+
continue;
|
|
765
|
+
if (!reachesKeptSource(lowerer, node.source.type, convertedShapes))
|
|
766
|
+
continue;
|
|
767
|
+
keptClones.add(node);
|
|
768
|
+
notes.keptSourceShapes.add(cloneT.shapeId);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
// A program that keeps no width spread is byte-identical to main: the
|
|
773
|
+
// reflective surfaces below (and the two helper finalizers in
|
|
774
|
+
// lower-calls.ts, which consult keptSourceShapes) stay static there, as
|
|
775
|
+
// they did before this pass.
|
|
776
|
+
keepSourceProbes(lowerer, notes, probeSites, keptWidths.size > 0 || keptClones.size > 0);
|
|
777
|
+
keepRecordClones(lowerer, cloneSites, keptClones);
|
|
543
778
|
// ── scope ───────────────────────────────────────────────────────────
|
|
544
779
|
// Only plain declared-field shapes with a table take part.
|
|
545
780
|
const inScope = (shape) => shape !== undefined &&
|
|
@@ -580,8 +815,10 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
580
815
|
return keys.join("\0") !== table;
|
|
581
816
|
});
|
|
582
817
|
});
|
|
583
|
-
if (!interesting)
|
|
818
|
+
if (!interesting) {
|
|
819
|
+
keepWidthSpreads(notes, widthSites, keptWidths, new Set());
|
|
584
820
|
return;
|
|
821
|
+
}
|
|
585
822
|
// ── presence classes and late-write constraints ─────────────────────
|
|
586
823
|
const maybeAbsent = (id, key) => {
|
|
587
824
|
const shape = shapes.get(id);
|
|
@@ -969,6 +1206,15 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
969
1206
|
shapesIn({ kind: "record", shapeId: id }, observed, observedSeen);
|
|
970
1207
|
for (const root of observedRoots)
|
|
971
1208
|
shapesIn(root, observed, observedSeen);
|
|
1209
|
+
// A kept width spread snapshots its sources' own keys, an order surface
|
|
1210
|
+
// over each source.
|
|
1211
|
+
for (const { wrapper, note } of widthSites) {
|
|
1212
|
+
if (!keptWidths.has(wrapper))
|
|
1213
|
+
continue;
|
|
1214
|
+
for (const segment of note.segments)
|
|
1215
|
+
if (segment.kind === "spread")
|
|
1216
|
+
shapesIn(segment.value.type, observed, observedSeen);
|
|
1217
|
+
}
|
|
972
1218
|
// An ordered spread's copies of values without a source take the source's
|
|
973
1219
|
// order from its table, which must then hold the resolved order.
|
|
974
1220
|
const orderedTarget = (sites) => {
|
|
@@ -998,6 +1244,7 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
998
1244
|
// Ordered spreads carry their source's order over (see above).
|
|
999
1245
|
let orderedResults = 0;
|
|
1000
1246
|
const rewritten = new Set();
|
|
1247
|
+
keepWidthSpreads(notes, widthSites, keptWidths, rewritten);
|
|
1001
1248
|
for (const [segments, sites] of leadingSpreads) {
|
|
1002
1249
|
const first = segments[0];
|
|
1003
1250
|
if (!orderedSpreads.has(segments) || first?.kind !== "spread" || first.value === undefined)
|
|
@@ -1307,6 +1554,12 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
1307
1554
|
const siteOf = (e) => {
|
|
1308
1555
|
if (e.kind === "seqExpr" && e.result.kind === "recordLit")
|
|
1309
1556
|
prologues.set(e.result, e.stmts);
|
|
1557
|
+
// A kept width spread's literal now initializes its own declaration, but
|
|
1558
|
+
// it still evaluates the spread's source binding in the wrapper's
|
|
1559
|
+
// prologue (keepWidthSpreads).
|
|
1560
|
+
const host = keptLiteralStmts.get(e);
|
|
1561
|
+
if (host !== undefined && e.kind === "recordLit")
|
|
1562
|
+
prologues.set(e, host);
|
|
1310
1563
|
if (e.kind === "recordLit" && e.type.kind === "record" && variants.has(e.type.shapeId)) {
|
|
1311
1564
|
const list = sites.get(e.type.shapeId) ?? [];
|
|
1312
1565
|
list.push(e);
|
|
@@ -1436,7 +1689,7 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
1436
1689
|
return indexOfOrder(orders, complete(resolved.order.filter((k) => keys.has(k)), orders[0]));
|
|
1437
1690
|
};
|
|
1438
1691
|
const plan = new Map();
|
|
1439
|
-
const dropped = new Set();
|
|
1692
|
+
const dropped = new Set(keptDropShapes);
|
|
1440
1693
|
for (const [id, list] of sites) {
|
|
1441
1694
|
for (const lit of list) {
|
|
1442
1695
|
const index = orderIndex(id, lit);
|
|
@@ -1591,4 +1844,292 @@ export function applyKeyOrderWitnesses(lowerer, fns) {
|
|
|
1591
1844
|
shape.orderVariants = tables;
|
|
1592
1845
|
}
|
|
1593
1846
|
}
|
|
1847
|
+
/** The replacements recorded for `fn`. */
|
|
1848
|
+
function replacementsIn(byFn, fn) {
|
|
1849
|
+
let replacements = byFn.get(fn);
|
|
1850
|
+
if (replacements === undefined)
|
|
1851
|
+
byFn.set(fn, (replacements = new Map()));
|
|
1852
|
+
return replacements;
|
|
1853
|
+
}
|
|
1854
|
+
/** Replaces each node of `replacements` in `fn` through the node that holds
|
|
1855
|
+
* it (replaceChildExpr), and the nodes under a replacement in turn. A node
|
|
1856
|
+
* is never rewritten into another kind in place: the compiler compiles this
|
|
1857
|
+
* file too, and a node it builds keeps its kind's fields. */
|
|
1858
|
+
function replaceThroughParents(fn, replacements) {
|
|
1859
|
+
if (replacements.size === 0)
|
|
1860
|
+
return;
|
|
1861
|
+
let replaced = 0;
|
|
1862
|
+
const children = (parent) => ({
|
|
1863
|
+
expr: (child) => {
|
|
1864
|
+
const to = replacements.get(child);
|
|
1865
|
+
if (to !== undefined && replaceChildExpr(parent, child, to))
|
|
1866
|
+
replaced++;
|
|
1867
|
+
visitExpr(to ?? child);
|
|
1868
|
+
return true;
|
|
1869
|
+
},
|
|
1870
|
+
stmt: (child) => {
|
|
1871
|
+
visitStmt(child);
|
|
1872
|
+
return true;
|
|
1873
|
+
},
|
|
1874
|
+
});
|
|
1875
|
+
function visitExpr(node) {
|
|
1876
|
+
const { expr, stmt } = children(node);
|
|
1877
|
+
everyExprChild(node, expr, stmt);
|
|
1878
|
+
}
|
|
1879
|
+
function visitStmt(node) {
|
|
1880
|
+
const { expr, stmt } = children(node);
|
|
1881
|
+
everyStmtChild(node, expr, stmt);
|
|
1882
|
+
}
|
|
1883
|
+
for (const stmt of fn.body)
|
|
1884
|
+
visitStmt(stmt);
|
|
1885
|
+
if (replaced !== replacements.size)
|
|
1886
|
+
throw new InternalCompilerError(`key-order-witness: ${replacements.size - replaced} kept site(s) not found in ${fn.name}`);
|
|
1887
|
+
}
|
|
1888
|
+
/** Width spreads: `{ ...wide }` into a narrower declared record. Node's copy
|
|
1889
|
+
* holds every own key of the source; the static copy holds the declared
|
|
1890
|
+
* ones. When an order surface can observe the target shape (the same
|
|
1891
|
+
* observation the order tables use), the literal keeps the copy's whole
|
|
1892
|
+
* own-key list as the record's kept source (scr_record_source_note): each
|
|
1893
|
+
* spread source's own keys are snapshot as the spread runs, explicit keys
|
|
1894
|
+
* hold placeholders at their position, and the record stays the source of
|
|
1895
|
+
* truth for every declared key. Programs no surface observes keep the
|
|
1896
|
+
* static copy byte for byte. */
|
|
1897
|
+
function widthKeepable(lowerer, wrapper, width) {
|
|
1898
|
+
return width.every((segment) => segment.kind === "key" ||
|
|
1899
|
+
((segment.value.type.kind === "dyn" || lowerer.dynConvertible(segment.value.type)) &&
|
|
1900
|
+
wrapper.stmts.some((stmt) => stmt.kind === "varDecl" && stmt.localId === segment.value.localId)));
|
|
1901
|
+
}
|
|
1902
|
+
function keepWidthSpreads(notes, sites, kept, rewritten) {
|
|
1903
|
+
let index = 0;
|
|
1904
|
+
for (const { wrapper, literal, fn, note } of sites) {
|
|
1905
|
+
if (!kept.has(wrapper) || rewritten.has(wrapper))
|
|
1906
|
+
continue;
|
|
1907
|
+
rewritten.add(wrapper);
|
|
1908
|
+
notes.keptWidthSpreads++;
|
|
1909
|
+
const width = note.segments;
|
|
1910
|
+
const loc = literal.loc;
|
|
1911
|
+
const site = index++;
|
|
1912
|
+
const empty = () => ({ kind: "dynObjLit", fields: [], type: DYN, loc });
|
|
1913
|
+
const assign = (target, from) => ({
|
|
1914
|
+
kind: "libCall",
|
|
1915
|
+
fn: "dyn.assign",
|
|
1916
|
+
args: [target, from],
|
|
1917
|
+
type: DYN,
|
|
1918
|
+
loc,
|
|
1919
|
+
});
|
|
1920
|
+
let mirror = empty();
|
|
1921
|
+
let spreadIndex = 0;
|
|
1922
|
+
for (const segment of width) {
|
|
1923
|
+
if (segment.kind === "key") {
|
|
1924
|
+
mirror = assign(mirror, {
|
|
1925
|
+
kind: "dynObjLit",
|
|
1926
|
+
fields: [{ key: strLit(segment.name, loc), value: dynUndefinedExpr(loc) }],
|
|
1927
|
+
type: DYN,
|
|
1928
|
+
loc,
|
|
1929
|
+
});
|
|
1930
|
+
continue;
|
|
1931
|
+
}
|
|
1932
|
+
// The spread copies the source's own keys when it runs: snapshot them
|
|
1933
|
+
// right after the literal evaluated the source.
|
|
1934
|
+
const localId = `%widthKeys.${site}.${spreadIndex++}`;
|
|
1935
|
+
fn.locals.push({ id: localId, name: "%widthKeys", type: DYN, mutable: false });
|
|
1936
|
+
const boxed = segment.value.type.kind === "dyn"
|
|
1937
|
+
? segment.value
|
|
1938
|
+
: { kind: "dynFrom", value: segment.value, liveRef: true, type: DYN, loc };
|
|
1939
|
+
const at = wrapper.stmts.findIndex((stmt) => stmt.kind === "varDecl" && stmt.localId === segment.value.localId);
|
|
1940
|
+
wrapper.stmts.splice(at + 1, 0, {
|
|
1941
|
+
kind: "varDecl",
|
|
1942
|
+
localId,
|
|
1943
|
+
init: assign(empty(), boxed),
|
|
1944
|
+
loc,
|
|
1945
|
+
});
|
|
1946
|
+
mirror = assign(mirror, { kind: "varRef", localId, type: DYN, loc });
|
|
1947
|
+
}
|
|
1948
|
+
const builtId = `%widthKept.${site}`;
|
|
1949
|
+
fn.locals.push({ id: builtId, name: "%widthKept", type: literal.type, mutable: false });
|
|
1950
|
+
const built = { kind: "varRef", localId: builtId, type: literal.type, loc };
|
|
1951
|
+
wrapper.stmts.push({ kind: "varDecl", localId: builtId, init: literal, loc }, {
|
|
1952
|
+
kind: "exprStmt",
|
|
1953
|
+
expr: { kind: "libCall", fn: "record.sourceNote", args: [built, mirror], type: VOID, loc },
|
|
1954
|
+
loc,
|
|
1955
|
+
});
|
|
1956
|
+
wrapper.result = built;
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
/** Whether a value of this type reaches a record layout that holds a kept
|
|
1960
|
+
* source: a plain record a checked conversion builds or an earlier kept
|
|
1961
|
+
* copy's shape, or a union with such an arm. */
|
|
1962
|
+
function reachesKeptSource(lowerer, type, converted) {
|
|
1963
|
+
if (type.kind === "record")
|
|
1964
|
+
return (recordMayKeepSource(lowerer, type) &&
|
|
1965
|
+
(converted.has(type.shapeId) || lowerer.keyOrder.keptSourceShapes.has(type.shapeId)));
|
|
1966
|
+
if (type.kind === "union")
|
|
1967
|
+
return (lowerer.unions.get(type.unionId)?.arms ?? []).some((arm) => reachesKeptSource(lowerer, arm, converted));
|
|
1968
|
+
return false;
|
|
1969
|
+
}
|
|
1970
|
+
/** Add the record shapes a checked conversion's target can hold a source
|
|
1971
|
+
* in: the target itself when it is a plain record, or the records nested in
|
|
1972
|
+
* a union arm, an array element, a promise or an index signature's values
|
|
1973
|
+
* (the layouts the checked builder notes sources for). */
|
|
1974
|
+
function conversionShapes(lowerer, target, out, seen) {
|
|
1975
|
+
if (target.kind === "promise")
|
|
1976
|
+
return conversionShapes(lowerer, target.inner, out, seen);
|
|
1977
|
+
if (target.kind === "array")
|
|
1978
|
+
return conversionShapes(lowerer, target.elem, out, seen);
|
|
1979
|
+
if (target.kind === "record") {
|
|
1980
|
+
if (seen.has(target.shapeId))
|
|
1981
|
+
return;
|
|
1982
|
+
seen.add(target.shapeId);
|
|
1983
|
+
// A conversion builds the records of its nested fields too, each with
|
|
1984
|
+
// its own kept source.
|
|
1985
|
+
if (recordMayKeepSource(lowerer, target))
|
|
1986
|
+
out.add(target.shapeId);
|
|
1987
|
+
const shape = lowerer.shapes.get(target.shapeId);
|
|
1988
|
+
for (const field of shape?.fields ?? [])
|
|
1989
|
+
conversionShapes(lowerer, field.type, out, seen);
|
|
1990
|
+
if (shape?.indexValue !== undefined)
|
|
1991
|
+
conversionShapes(lowerer, shape.indexValue, out, seen);
|
|
1992
|
+
return;
|
|
1993
|
+
}
|
|
1994
|
+
if (target.kind !== "union" || seen.has(target.unionId))
|
|
1995
|
+
return;
|
|
1996
|
+
seen.add(target.unionId);
|
|
1997
|
+
for (const arm of lowerer.unions.get(target.unionId)?.arms ?? [])
|
|
1998
|
+
conversionShapes(lowerer, arm, out, seen);
|
|
1999
|
+
}
|
|
2000
|
+
/** `"k" in r` over a closed record answers statically false for a literal
|
|
2001
|
+
* key the shape does not declare. A kept source can hold it (a checked
|
|
2002
|
+
* conversion's undeclared keys, a width spread's extras), so when the
|
|
2003
|
+
* program keeps record sources the site answers through the record's own
|
|
2004
|
+
* kept view instead. The receiver evaluates exactly once, as the static
|
|
2005
|
+
* form evaluated it. */
|
|
2006
|
+
function keepSourceProbes(lowerer, notes, sites, possible) {
|
|
2007
|
+
if (!possible)
|
|
2008
|
+
return;
|
|
2009
|
+
let index = 0;
|
|
2010
|
+
const byFn = new Map();
|
|
2011
|
+
for (const { node, fn } of sites) {
|
|
2012
|
+
const probe = notes.sourceProbeOf(node);
|
|
2013
|
+
if (probe === undefined)
|
|
2014
|
+
continue;
|
|
2015
|
+
const recT = probe.receiver.type;
|
|
2016
|
+
if (recT.kind !== "record")
|
|
2017
|
+
continue;
|
|
2018
|
+
if (!recordMayKeepSource(lowerer, recT))
|
|
2019
|
+
continue;
|
|
2020
|
+
const loc = node.loc;
|
|
2021
|
+
const id = `%inSource.${index++}`;
|
|
2022
|
+
fn.locals.push({ id, name: "%inSource", type: recT, mutable: false });
|
|
2023
|
+
const ref = { kind: "varRef", localId: id, type: recT, loc };
|
|
2024
|
+
const replacement = {
|
|
2025
|
+
kind: "seqExpr",
|
|
2026
|
+
stmts: [{ kind: "varDecl", localId: id, init: probe.receiver, loc }],
|
|
2027
|
+
result: {
|
|
2028
|
+
kind: "logical",
|
|
2029
|
+
op: "&&",
|
|
2030
|
+
left: recordSourceTest(ref, loc),
|
|
2031
|
+
right: {
|
|
2032
|
+
kind: "dynHasKey",
|
|
2033
|
+
key: probe.key,
|
|
2034
|
+
value: { kind: "dynFrom", value: ref, liveRef: true, type: DYN, loc },
|
|
2035
|
+
type: BOOL,
|
|
2036
|
+
loc,
|
|
2037
|
+
},
|
|
2038
|
+
type: BOOL,
|
|
2039
|
+
loc,
|
|
2040
|
+
},
|
|
2041
|
+
type: BOOL,
|
|
2042
|
+
loc,
|
|
2043
|
+
};
|
|
2044
|
+
replacementsIn(byFn, fn).set(node, replacement);
|
|
2045
|
+
}
|
|
2046
|
+
for (const [fn, replacements] of byFn)
|
|
2047
|
+
replaceThroughParents(fn, replacements);
|
|
2048
|
+
}
|
|
2049
|
+
/** Same-shape `{ ...r, k: v }` clones: Node's copy holds every own key of
|
|
2050
|
+
* the source, and the recordClone fast path copies the declared fields
|
|
2051
|
+
* only. A clone over a shape that can keep a source, in a program that
|
|
2052
|
+
* keeps one, snapshots the source's own keys and notes them on the built
|
|
2053
|
+
* record; the overrides keep their source position (a placeholder for an
|
|
2054
|
+
* existing key keeps its place, a new one follows the source's keys). The
|
|
2055
|
+
* override values still evaluate after the source, as before. */
|
|
2056
|
+
function keepRecordClones(lowerer, sites, kept) {
|
|
2057
|
+
let index = 0;
|
|
2058
|
+
const byFn = new Map();
|
|
2059
|
+
for (const { node, fn } of sites) {
|
|
2060
|
+
if (!kept.has(node) || node.kind !== "recordClone")
|
|
2061
|
+
continue;
|
|
2062
|
+
const cloneT = node.type;
|
|
2063
|
+
if (cloneT.kind !== "record" || !recordMayKeepSource(lowerer, cloneT))
|
|
2064
|
+
continue;
|
|
2065
|
+
const loc = node.loc;
|
|
2066
|
+
const n = index++;
|
|
2067
|
+
const srcId = `%cloneSrc.${n}`;
|
|
2068
|
+
const keysId = `%cloneKeys.${n}`;
|
|
2069
|
+
const builtId = `%cloneKept.${n}`;
|
|
2070
|
+
fn.locals.push({ id: srcId, name: "%cloneSrc", type: node.source.type, mutable: false });
|
|
2071
|
+
fn.locals.push({ id: keysId, name: "%cloneKeys", type: DYN, mutable: false });
|
|
2072
|
+
fn.locals.push({ id: builtId, name: "%cloneKept", type: cloneT, mutable: false });
|
|
2073
|
+
const srcRef = { kind: "varRef", localId: srcId, type: node.source.type, loc };
|
|
2074
|
+
const assign = (target, from) => ({
|
|
2075
|
+
kind: "libCall",
|
|
2076
|
+
fn: "dyn.assign",
|
|
2077
|
+
args: [target, from],
|
|
2078
|
+
type: DYN,
|
|
2079
|
+
loc,
|
|
2080
|
+
});
|
|
2081
|
+
const placeholder = (name) => ({
|
|
2082
|
+
kind: "dynObjLit",
|
|
2083
|
+
fields: [{ key: strLit(name, loc), value: dynUndefinedExpr(loc) }],
|
|
2084
|
+
type: DYN,
|
|
2085
|
+
loc,
|
|
2086
|
+
});
|
|
2087
|
+
let mirror = { kind: "varRef", localId: keysId, type: DYN, loc };
|
|
2088
|
+
for (const override of node.overrides)
|
|
2089
|
+
mirror = assign(mirror, placeholder(override.name));
|
|
2090
|
+
const built = { kind: "varRef", localId: builtId, type: cloneT, loc };
|
|
2091
|
+
const overrides = node.overrides;
|
|
2092
|
+
const replacement = {
|
|
2093
|
+
kind: "seqExpr",
|
|
2094
|
+
stmts: [
|
|
2095
|
+
{ kind: "varDecl", localId: srcId, init: node.source, loc },
|
|
2096
|
+
{
|
|
2097
|
+
kind: "varDecl",
|
|
2098
|
+
localId: keysId,
|
|
2099
|
+
init: assign({ kind: "dynObjLit", fields: [], type: DYN, loc }, {
|
|
2100
|
+
kind: "dynFrom",
|
|
2101
|
+
value: srcRef,
|
|
2102
|
+
liveRef: true,
|
|
2103
|
+
type: DYN,
|
|
2104
|
+
loc,
|
|
2105
|
+
}),
|
|
2106
|
+
loc,
|
|
2107
|
+
},
|
|
2108
|
+
{
|
|
2109
|
+
kind: "varDecl",
|
|
2110
|
+
localId: builtId,
|
|
2111
|
+
init: { kind: "recordClone", source: srcRef, overrides, type: cloneT, loc },
|
|
2112
|
+
loc,
|
|
2113
|
+
},
|
|
2114
|
+
{
|
|
2115
|
+
kind: "exprStmt",
|
|
2116
|
+
expr: {
|
|
2117
|
+
kind: "libCall",
|
|
2118
|
+
fn: "record.sourceNote",
|
|
2119
|
+
args: [built, mirror],
|
|
2120
|
+
type: VOID,
|
|
2121
|
+
loc,
|
|
2122
|
+
},
|
|
2123
|
+
loc,
|
|
2124
|
+
},
|
|
2125
|
+
],
|
|
2126
|
+
result: built,
|
|
2127
|
+
type: cloneT,
|
|
2128
|
+
loc,
|
|
2129
|
+
};
|
|
2130
|
+
replacementsIn(byFn, fn).set(node, replacement);
|
|
2131
|
+
}
|
|
2132
|
+
for (const [fn, replacements] of byFn)
|
|
2133
|
+
replaceThroughParents(fn, replacements);
|
|
2134
|
+
}
|
|
1594
2135
|
//# sourceMappingURL=key-order-witness.js.map
|