@geastack/compiler 1.0.15
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/LICENSE +202 -0
- package/README.md +149 -0
- package/dist/cli-analyze.d.ts +1 -0
- package/dist/cli-analyze.js +61 -0
- package/dist/cli-coverage.d.ts +1 -0
- package/dist/cli-coverage.js +329 -0
- package/dist/cli-emit.d.ts +10 -0
- package/dist/cli-emit.js +398 -0
- package/dist/cli-module-graph.d.ts +18 -0
- package/dist/cli-module-graph.js +123 -0
- package/dist/cli-package-source.d.ts +5 -0
- package/dist/cli-package-source.js +116 -0
- package/dist/cli-project.d.ts +2 -0
- package/dist/cli-project.js +60 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +199 -0
- package/dist/compiler.d.ts +228 -0
- package/dist/compiler.js +1029 -0
- package/dist/conversion/algebra.d.ts +218 -0
- package/dist/conversion/algebra.js +155 -0
- package/dist/conversion/build.d.ts +67 -0
- package/dist/conversion/build.js +1378 -0
- package/dist/conversion/derive.d.ts +37 -0
- package/dist/conversion/derive.js +260 -0
- package/dist/conversion/graph-validation.d.ts +8 -0
- package/dist/conversion/graph-validation.js +97 -0
- package/dist/conversion/native-callable-adapter.d.ts +13 -0
- package/dist/conversion/native-callable-adapter.js +53 -0
- package/dist/conversion/native-class-reference.d.ts +12 -0
- package/dist/conversion/native-class-reference.js +39 -0
- package/dist/conversion/native-payload-transport.d.ts +25 -0
- package/dist/conversion/native-payload-transport.js +33 -0
- package/dist/conversion/native-selection.d.ts +49 -0
- package/dist/conversion/native-selection.js +135 -0
- package/dist/conversion/native-sum.d.ts +42 -0
- package/dist/conversion/native-sum.js +115 -0
- package/dist/conversion/nodes.d.ts +55 -0
- package/dist/conversion/nodes.js +91 -0
- package/dist/conversion/operand-view.d.ts +14 -0
- package/dist/conversion/operand-view.js +20 -0
- package/dist/conversion/record-view.d.ts +157 -0
- package/dist/conversion/record-view.js +273 -0
- package/dist/conversion/registry.d.ts +217 -0
- package/dist/conversion/registry.js +1 -0
- package/dist/diagnostics/model.d.ts +76 -0
- package/dist/diagnostics/model.js +60 -0
- package/dist/diagnostics/sweep.d.ts +31 -0
- package/dist/diagnostics/sweep.js +112 -0
- package/dist/identity/ids.d.ts +179 -0
- package/dist/identity/ids.js +212 -0
- package/dist/ir/absent-class-arm.d.ts +48 -0
- package/dist/ir/absent-class-arm.js +157 -0
- package/dist/ir/borrow-effects.d.ts +23 -0
- package/dist/ir/borrow-effects.js +151 -0
- package/dist/ir/borrowed-call-arguments.d.ts +40 -0
- package/dist/ir/borrowed-call-arguments.js +117 -0
- package/dist/ir/build.d.ts +168 -0
- package/dist/ir/build.js +459 -0
- package/dist/ir/call-dispatch.d.ts +38 -0
- package/dist/ir/call-dispatch.js +502 -0
- package/dist/ir/call-entry.d.ts +142 -0
- package/dist/ir/call-entry.js +386 -0
- package/dist/ir/callable-class-flow.d.ts +27 -0
- package/dist/ir/callable-class-flow.js +1386 -0
- package/dist/ir/callable-field-slots.d.ts +22 -0
- package/dist/ir/callable-field-slots.js +166 -0
- package/dist/ir/callable-identity-demand.d.ts +52 -0
- package/dist/ir/callable-identity-demand.js +460 -0
- package/dist/ir/callable-member-candidates.d.ts +9 -0
- package/dist/ir/callable-member-candidates.js +39 -0
- package/dist/ir/callable-records.d.ts +21 -0
- package/dist/ir/callable-records.js +411 -0
- package/dist/ir/captures.d.ts +26 -0
- package/dist/ir/captures.js +335 -0
- package/dist/ir/certificate.d.ts +45 -0
- package/dist/ir/certificate.js +47 -0
- package/dist/ir/certify/carrier-keys.d.ts +73 -0
- package/dist/ir/certify/carrier-keys.js +221 -0
- package/dist/ir/certify/function-source.d.ts +4 -0
- package/dist/ir/certify/function-source.js +28 -0
- package/dist/ir/certify/has-property-key.d.ts +88 -0
- package/dist/ir/certify/has-property-key.js +116 -0
- package/dist/ir/certify/instanceof-key.d.ts +24 -0
- package/dist/ir/certify/instanceof-key.js +35 -0
- package/dist/ir/certify/property-access-keys.d.ts +172 -0
- package/dist/ir/certify/property-access-keys.js +291 -0
- package/dist/ir/certify/property-access.d.ts +3 -0
- package/dist/ir/certify/property-access.js +597 -0
- package/dist/ir/certify/runtime-helper.d.ts +3 -0
- package/dist/ir/certify/runtime-helper.js +326 -0
- package/dist/ir/certify/typeof-operand.d.ts +14 -0
- package/dist/ir/certify/typeof-operand.js +16 -0
- package/dist/ir/certify.d.ts +123 -0
- package/dist/ir/certify.js +481 -0
- package/dist/ir/class-evaluation.d.ts +26 -0
- package/dist/ir/class-evaluation.js +50 -0
- package/dist/ir/class-static-fields.d.ts +60 -0
- package/dist/ir/class-static-fields.js +108 -0
- package/dist/ir/construct-entry.d.ts +26 -0
- package/dist/ir/construct-entry.js +117 -0
- package/dist/ir/dead-values.d.ts +90 -0
- package/dist/ir/dead-values.js +184 -0
- package/dist/ir/deferral.d.ts +99 -0
- package/dist/ir/deferral.js +409 -0
- package/dist/ir/dense-loops.d.ts +230 -0
- package/dist/ir/dense-loops.js +697 -0
- package/dist/ir/dominance.d.ts +82 -0
- package/dist/ir/dominance.js +268 -0
- package/dist/ir/emission-representations.d.ts +71 -0
- package/dist/ir/emission-representations.js +350 -0
- package/dist/ir/facts.d.ts +218 -0
- package/dist/ir/facts.js +181 -0
- package/dist/ir/fixed-data-definition.d.ts +19 -0
- package/dist/ir/fixed-data-definition.js +49 -0
- package/dist/ir/generator-split.d.ts +38 -0
- package/dist/ir/generator-split.js +329 -0
- package/dist/ir/hoist.d.ts +55 -0
- package/dist/ir/hoist.js +375 -0
- package/dist/ir/instantiation.d.ts +61 -0
- package/dist/ir/instantiation.js +137 -0
- package/dist/ir/integer-storage.d.ts +170 -0
- package/dist/ir/integer-storage.js +822 -0
- package/dist/ir/integers.d.ts +161 -0
- package/dist/ir/integers.js +539 -0
- package/dist/ir/integrity-restrictions.d.ts +50 -0
- package/dist/ir/integrity-restrictions.js +118 -0
- package/dist/ir/local-iterators.d.ts +4 -0
- package/dist/ir/local-iterators.js +27 -0
- package/dist/ir/lower-allocation.d.ts +4 -0
- package/dist/ir/lower-allocation.js +325 -0
- package/dist/ir/lower-completion.d.ts +15 -0
- package/dist/ir/lower-completion.js +25 -0
- package/dist/ir/lower-destructuring.d.ts +5 -0
- package/dist/ir/lower-destructuring.js +693 -0
- package/dist/ir/lower-element.d.ts +29 -0
- package/dist/ir/lower-element.js +111 -0
- package/dist/ir/lower-exceptions.d.ts +47 -0
- package/dist/ir/lower-exceptions.js +92 -0
- package/dist/ir/lower-flow.d.ts +137 -0
- package/dist/ir/lower-flow.js +600 -0
- package/dist/ir/lower-graph.d.ts +218 -0
- package/dist/ir/lower-graph.js +687 -0
- package/dist/ir/lower-invocation.d.ts +4 -0
- package/dist/ir/lower-invocation.js +514 -0
- package/dist/ir/lower-narrow.d.ts +53 -0
- package/dist/ir/lower-narrow.js +320 -0
- package/dist/ir/lower-operands.d.ts +272 -0
- package/dist/ir/lower-operands.js +461 -0
- package/dist/ir/lower-property.d.ts +21 -0
- package/dist/ir/lower-property.js +132 -0
- package/dist/ir/lower-protocol.d.ts +11 -0
- package/dist/ir/lower-protocol.js +118 -0
- package/dist/ir/lower-short-circuit.d.ts +41 -0
- package/dist/ir/lower-short-circuit.js +63 -0
- package/dist/ir/lower.d.ts +82 -0
- package/dist/ir/lower.js +1346 -0
- package/dist/ir/model.d.ts +1474 -0
- package/dist/ir/model.js +6 -0
- package/dist/ir/native-absent-property.d.ts +3 -0
- package/dist/ir/native-absent-property.js +13 -0
- package/dist/ir/native-array-transport.d.ts +7 -0
- package/dist/ir/native-array-transport.js +46 -0
- package/dist/ir/native-callable-bind.d.ts +9 -0
- package/dist/ir/native-callable-bind.js +30 -0
- package/dist/ir/native-carrier-predicate.d.ts +34 -0
- package/dist/ir/native-carrier-predicate.js +49 -0
- package/dist/ir/native-class-accessor.d.ts +18 -0
- package/dist/ir/native-class-accessor.js +52 -0
- package/dist/ir/native-class-construction.d.ts +16 -0
- package/dist/ir/native-class-construction.js +71 -0
- package/dist/ir/native-class-initialization.d.ts +15 -0
- package/dist/ir/native-class-initialization.js +56 -0
- package/dist/ir/native-class-origins.d.ts +13 -0
- package/dist/ir/native-class-origins.js +237 -0
- package/dist/ir/native-dictionary-transport.d.ts +6 -0
- package/dist/ir/native-dictionary-transport.js +37 -0
- package/dist/ir/native-enumeration.d.ts +14 -0
- package/dist/ir/native-enumeration.js +26 -0
- package/dist/ir/native-equality.d.ts +10 -0
- package/dist/ir/native-equality.js +18 -0
- package/dist/ir/native-field-owner.d.ts +37 -0
- package/dist/ir/native-field-owner.js +183 -0
- package/dist/ir/native-fixed-layout.d.ts +41 -0
- package/dist/ir/native-fixed-layout.js +232 -0
- package/dist/ir/native-host-construction.d.ts +53 -0
- package/dist/ir/native-host-construction.js +62 -0
- package/dist/ir/native-key-query.d.ts +4 -0
- package/dist/ir/native-key-query.js +38 -0
- package/dist/ir/native-merge-transport.d.ts +25 -0
- package/dist/ir/native-merge-transport.js +71 -0
- package/dist/ir/native-record-index-transport.d.ts +11 -0
- package/dist/ir/native-record-index-transport.js +34 -0
- package/dist/ir/native-record-index.d.ts +12 -0
- package/dist/ir/native-record-index.js +27 -0
- package/dist/ir/native-reflect-field.d.ts +5 -0
- package/dist/ir/native-reflect-field.js +33 -0
- package/dist/ir/native-sequence-transport.d.ts +7 -0
- package/dist/ir/native-sequence-transport.js +53 -0
- package/dist/ir/numeric-intrinsics.d.ts +13 -0
- package/dist/ir/numeric-intrinsics.js +57 -0
- package/dist/ir/object-value-conversions.d.ts +20 -0
- package/dist/ir/object-value-conversions.js +50 -0
- package/dist/ir/physical-class-reflection.d.ts +9 -0
- package/dist/ir/physical-class-reflection.js +57 -0
- package/dist/ir/presence-proof.d.ts +42 -0
- package/dist/ir/presence-proof.js +490 -0
- package/dist/ir/program-facts.d.ts +106 -0
- package/dist/ir/program-facts.js +319 -0
- package/dist/ir/proven-branches.d.ts +16 -0
- package/dist/ir/proven-branches.js +219 -0
- package/dist/ir/queries.d.ts +41 -0
- package/dist/ir/queries.js +213 -0
- package/dist/ir/reflection-demand.d.ts +64 -0
- package/dist/ir/reflection-demand.js +1394 -0
- package/dist/ir/refusal.d.ts +43 -0
- package/dist/ir/refusal.js +28 -0
- package/dist/ir/shake.d.ts +37 -0
- package/dist/ir/shake.js +1078 -0
- package/dist/ir/static-callables.d.ts +11 -0
- package/dist/ir/static-callables.js +163 -0
- package/dist/ir/string-layout-reuse.d.ts +13 -0
- package/dist/ir/string-layout-reuse.js +39 -0
- package/dist/ir/string-length-reuse.d.ts +8 -0
- package/dist/ir/string-length-reuse.js +47 -0
- package/dist/ir/transfer.d.ts +78 -0
- package/dist/ir/transfer.js +270 -0
- package/dist/ir/type-query-results.d.ts +25 -0
- package/dist/ir/type-query-results.js +96 -0
- package/dist/ir/typed-property-access.d.ts +100 -0
- package/dist/ir/typed-property-access.js +161 -0
- package/dist/ir/verify.d.ts +19 -0
- package/dist/ir/verify.js +355 -0
- package/dist/plugins/apple/constructors.d.ts +112 -0
- package/dist/plugins/apple/constructors.js +217 -0
- package/dist/plugins/apple/host.d.ts +181 -0
- package/dist/plugins/apple/host.js +262 -0
- package/dist/plugins/apple/jsx.d.ts +2 -0
- package/dist/plugins/apple/jsx.js +293 -0
- package/dist/plugins/apple/members.d.ts +16 -0
- package/dist/plugins/apple/members.js +190 -0
- package/dist/plugins/apple/plugin.d.ts +2 -0
- package/dist/plugins/apple/plugin.js +156 -0
- package/dist/plugins/gea/component-classes.d.ts +25 -0
- package/dist/plugins/gea/component-classes.js +162 -0
- package/dist/plugins/gea/component-inline.d.ts +13 -0
- package/dist/plugins/gea/component-inline.js +532 -0
- package/dist/plugins/gea/constructors.d.ts +23 -0
- package/dist/plugins/gea/constructors.js +100 -0
- package/dist/plugins/gea/contract.d.ts +150 -0
- package/dist/plugins/gea/contract.js +195 -0
- package/dist/plugins/gea/element-ref.d.ts +31 -0
- package/dist/plugins/gea/element-ref.js +45 -0
- package/dist/plugins/gea/host.d.ts +520 -0
- package/dist/plugins/gea/host.js +762 -0
- package/dist/plugins/gea/lower.d.ts +6 -0
- package/dist/plugins/gea/lower.js +195 -0
- package/dist/plugins/gea/members.d.ts +22 -0
- package/dist/plugins/gea/members.js +221 -0
- package/dist/plugins/gea/plugin.d.ts +22 -0
- package/dist/plugins/gea/plugin.js +307 -0
- package/dist/plugins/gea/prelude.d.ts +78 -0
- package/dist/plugins/gea/prelude.js +153 -0
- package/dist/plugins/gea/producer.d.ts +5 -0
- package/dist/plugins/gea/producer.js +52 -0
- package/dist/plugins/gea/reactive-slots.d.ts +49 -0
- package/dist/plugins/gea/reactive-slots.js +578 -0
- package/dist/plugins/gea/render-bridge.d.ts +6 -0
- package/dist/plugins/gea/render-bridge.js +281 -0
- package/dist/plugins/gea/slots.d.ts +15 -0
- package/dist/plugins/gea/slots.js +36 -0
- package/dist/plugins/gea/template-analysis.d.ts +151 -0
- package/dist/plugins/gea/template-analysis.js +346 -0
- package/dist/plugins/gea/user-agent-styles.d.ts +9 -0
- package/dist/plugins/gea/user-agent-styles.js +94 -0
- package/dist/plugins/installed.d.ts +19 -0
- package/dist/plugins/installed.js +21 -0
- package/dist/plugins/load.d.ts +7 -0
- package/dist/plugins/load.js +207 -0
- package/dist/plugins/model.d.ts +735 -0
- package/dist/plugins/model.js +47 -0
- package/dist/plugins/webgl/host.d.ts +77 -0
- package/dist/plugins/webgl/host.js +162 -0
- package/dist/plugins/webgl/plugin.d.ts +40 -0
- package/dist/plugins/webgl/plugin.js +99 -0
- package/dist/preflight/obligations.d.ts +206 -0
- package/dist/preflight/obligations.js +36 -0
- package/dist/preflight/report.d.ts +20 -0
- package/dist/preflight/report.js +61 -0
- package/dist/preflight/run.d.ts +39 -0
- package/dist/preflight/run.js +403 -0
- package/dist/project-preparation.d.ts +33 -0
- package/dist/project-preparation.js +314 -0
- package/dist/projection/abi.d.ts +82 -0
- package/dist/projection/abi.js +349 -0
- package/dist/projection/apply-arguments.d.ts +12 -0
- package/dist/projection/apply-arguments.js +20 -0
- package/dist/projection/bindings.d.ts +250 -0
- package/dist/projection/bindings.js +340 -0
- package/dist/projection/callee.d.ts +196 -0
- package/dist/projection/callee.js +444 -0
- package/dist/projection/class-property-presence.d.ts +28 -0
- package/dist/projection/class-property-presence.js +58 -0
- package/dist/projection/class-prototype.d.ts +5 -0
- package/dist/projection/class-prototype.js +23 -0
- package/dist/projection/class-storage.d.ts +26 -0
- package/dist/projection/class-storage.js +236 -0
- package/dist/projection/classes.d.ts +283 -0
- package/dist/projection/classes.js +944 -0
- package/dist/projection/coercions.d.ts +20 -0
- package/dist/projection/coercions.js +33 -0
- package/dist/projection/dispatch.d.ts +167 -0
- package/dist/projection/dispatch.js +379 -0
- package/dist/projection/fields.d.ts +123 -0
- package/dist/projection/fields.js +383 -0
- package/dist/projection/instance-test.d.ts +78 -0
- package/dist/projection/instance-test.js +156 -0
- package/dist/projection/slots.d.ts +146 -0
- package/dist/projection/slots.js +663 -0
- package/dist/projection/synthesized-abi.d.ts +61 -0
- package/dist/projection/synthesized-abi.js +94 -0
- package/dist/representation/array-index.d.ts +14 -0
- package/dist/representation/array-index.js +17 -0
- package/dist/representation/callable-object.d.ts +3 -0
- package/dist/representation/callable-object.js +6 -0
- package/dist/representation/collections.d.ts +84 -0
- package/dist/representation/collections.js +139 -0
- package/dist/representation/derive.d.ts +159 -0
- package/dist/representation/derive.js +2546 -0
- package/dist/representation/difference.d.ts +30 -0
- package/dist/representation/difference.js +240 -0
- package/dist/representation/field-descriptor-policy.d.ts +19 -0
- package/dist/representation/field-descriptor-policy.js +39 -0
- package/dist/representation/function-constructor.d.ts +13 -0
- package/dist/representation/function-constructor.js +9 -0
- package/dist/representation/host-abi.d.ts +32 -0
- package/dist/representation/host-abi.js +97 -0
- package/dist/representation/host-templates.d.ts +67 -0
- package/dist/representation/host-templates.js +94 -0
- package/dist/representation/intersection.d.ts +84 -0
- package/dist/representation/intersection.js +149 -0
- package/dist/representation/literal-destination.d.ts +43 -0
- package/dist/representation/literal-destination.js +133 -0
- package/dist/representation/merge.d.ts +18 -0
- package/dist/representation/merge.js +83 -0
- package/dist/representation/model.d.ts +1160 -0
- package/dist/representation/model.js +1019 -0
- package/dist/representation/numeric-index.d.ts +13 -0
- package/dist/representation/numeric-index.js +29 -0
- package/dist/representation/object-shape.d.ts +109 -0
- package/dist/representation/object-shape.js +123 -0
- package/dist/representation/optional.d.ts +12 -0
- package/dist/representation/optional.js +87 -0
- package/dist/representation/plan.d.ts +60 -0
- package/dist/representation/plan.js +78 -0
- package/dist/representation/policies.d.ts +589 -0
- package/dist/representation/policies.js +107 -0
- package/dist/representation/primitive-domain.d.ts +1 -0
- package/dist/representation/primitive-domain.js +1 -0
- package/dist/representation/primitives.d.ts +44 -0
- package/dist/representation/primitives.js +78 -0
- package/dist/representation/publish.d.ts +49 -0
- package/dist/representation/publish.js +648 -0
- package/dist/representation/record-fields.d.ts +96 -0
- package/dist/representation/record-fields.js +116 -0
- package/dist/representation/template-object.d.ts +11 -0
- package/dist/representation/template-object.js +26 -0
- package/dist/representation/union.d.ts +30 -0
- package/dist/representation/union.js +324 -0
- package/dist/representation/value-records.d.ts +3 -0
- package/dist/representation/value-records.js +307 -0
- package/dist/representation/verify.d.ts +17 -0
- package/dist/representation/verify.js +221 -0
- package/dist/semantics/alias-this-field-declaration-transform.d.ts +4 -0
- package/dist/semantics/alias-this-field-declaration-transform.js +207 -0
- package/dist/semantics/ambient-type-realization-transform.d.ts +62 -0
- package/dist/semantics/ambient-type-realization-transform.js +168 -0
- package/dist/semantics/ambient.d.ts +24 -0
- package/dist/semantics/ambient.js +119 -0
- package/dist/semantics/borrowed-builtin-call-bind-source-transform.d.ts +4 -0
- package/dist/semantics/borrowed-builtin-call-bind-source-transform.js +341 -0
- package/dist/semantics/callable-origins.d.ts +46 -0
- package/dist/semantics/callable-origins.js +354 -0
- package/dist/semantics/class-alias.d.ts +7 -0
- package/dist/semantics/class-alias.js +37 -0
- package/dist/semantics/class-heritage.d.ts +34 -0
- package/dist/semantics/class-heritage.js +104 -0
- package/dist/semantics/commonjs-wrapper.d.ts +69 -0
- package/dist/semantics/commonjs-wrapper.js +231 -0
- package/dist/semantics/constructor-slot-subclasses.d.ts +28 -0
- package/dist/semantics/constructor-slot-subclasses.js +112 -0
- package/dist/semantics/declaration-overlay-transform.d.ts +35 -0
- package/dist/semantics/declaration-overlay-transform.js +2157 -0
- package/dist/semantics/define-property-source-transform.d.ts +4 -0
- package/dist/semantics/define-property-source-transform.js +437 -0
- package/dist/semantics/diagnostic-source-preparation.d.ts +24 -0
- package/dist/semantics/diagnostic-source-preparation.js +82 -0
- package/dist/semantics/documentation-ranges.d.ts +22 -0
- package/dist/semantics/documentation-ranges.js +36 -0
- package/dist/semantics/dynamic-fallback.d.ts +86 -0
- package/dist/semantics/dynamic-fallback.js +249 -0
- package/dist/semantics/frontend-timing.d.ts +6 -0
- package/dist/semantics/frontend-timing.js +35 -0
- package/dist/semantics/frontend.d.ts +504 -0
- package/dist/semantics/frontend.js +1157 -0
- package/dist/semantics/host-declaration-provenance.d.ts +11 -0
- package/dist/semantics/host-declaration-provenance.js +18 -0
- package/dist/semantics/host-methods.d.ts +24 -0
- package/dist/semantics/host-methods.js +74 -0
- package/dist/semantics/host-protocols.d.ts +429 -0
- package/dist/semantics/host-protocols.js +1501 -0
- package/dist/semantics/inherited-accessor.d.ts +7 -0
- package/dist/semantics/inherited-accessor.js +48 -0
- package/dist/semantics/interface-families.d.ts +70 -0
- package/dist/semantics/interface-families.js +180 -0
- package/dist/semantics/interface-implementors.d.ts +53 -0
- package/dist/semantics/interface-implementors.js +87 -0
- package/dist/semantics/jsdoc-namepath-transform.d.ts +4 -0
- package/dist/semantics/jsdoc-namepath-transform.js +85 -0
- package/dist/semantics/model/coverage.d.ts +68 -0
- package/dist/semantics/model/coverage.js +73 -0
- package/dist/semantics/model/edges.d.ts +103 -0
- package/dist/semantics/model/edges.js +20 -0
- package/dist/semantics/model/graph.d.ts +55 -0
- package/dist/semantics/model/graph.js +129 -0
- package/dist/semantics/model/operands.d.ts +159 -0
- package/dist/semantics/model/operands.js +26 -0
- package/dist/semantics/model/operations.d.ts +496 -0
- package/dist/semantics/model/operations.js +2 -0
- package/dist/semantics/model/primitive-domain.d.ts +26 -0
- package/dist/semantics/model/primitive-domain.js +38 -0
- package/dist/semantics/model/selected-signature.d.ts +261 -0
- package/dist/semantics/model/selected-signature.js +55 -0
- package/dist/semantics/model/structural-type-table.d.ts +93 -0
- package/dist/semantics/model/structural-type-table.js +237 -0
- package/dist/semantics/model/structural-types.d.ts +367 -0
- package/dist/semantics/model/structural-types.js +200 -0
- package/dist/semantics/module-resolution.d.ts +23 -0
- package/dist/semantics/module-resolution.js +227 -0
- package/dist/semantics/new-callee-class-tag-source-transform.d.ts +4 -0
- package/dist/semantics/new-callee-class-tag-source-transform.js +64 -0
- package/dist/semantics/node-project.d.ts +13 -0
- package/dist/semantics/node-project.js +107 -0
- package/dist/semantics/node-source-hooks.d.ts +1 -0
- package/dist/semantics/node-source-hooks.js +63 -0
- package/dist/semantics/normalize/absent-globals.d.ts +143 -0
- package/dist/semantics/normalize/absent-globals.js +191 -0
- package/dist/semantics/normalize/arguments-objects.d.ts +43 -0
- package/dist/semantics/normalize/arguments-objects.js +60 -0
- package/dist/semantics/normalize/asserted-arm-absence.d.ts +28 -0
- package/dist/semantics/normalize/asserted-arm-absence.js +61 -0
- package/dist/semantics/normalize/assignment-patterns.d.ts +70 -0
- package/dist/semantics/normalize/assignment-patterns.js +147 -0
- package/dist/semantics/normalize/bag-absence.d.ts +8 -0
- package/dist/semantics/normalize/bag-absence.js +42 -0
- package/dist/semantics/normalize/binding-fixpoint.d.ts +36 -0
- package/dist/semantics/normalize/binding-fixpoint.js +140 -0
- package/dist/semantics/normalize/callback-parameter-contracts.d.ts +16 -0
- package/dist/semantics/normalize/callback-parameter-contracts.js +91 -0
- package/dist/semantics/normalize/cells/agreement.d.ts +46 -0
- package/dist/semantics/normalize/cells/agreement.js +34 -0
- package/dist/semantics/normalize/cells/candidates.d.ts +17 -0
- package/dist/semantics/normalize/cells/candidates.js +35 -0
- package/dist/semantics/normalize/cells/facts.d.ts +19 -0
- package/dist/semantics/normalize/cells/facts.js +90 -0
- package/dist/semantics/normalize/cells/index.d.ts +10 -0
- package/dist/semantics/normalize/cells/index.js +6 -0
- package/dist/semantics/normalize/cells/model.d.ts +98 -0
- package/dist/semantics/normalize/cells/model.js +2 -0
- package/dist/semantics/normalize/cells/policies/bag.d.ts +44 -0
- package/dist/semantics/normalize/cells/policies/bag.js +114 -0
- package/dist/semantics/normalize/cells/policies/collection.d.ts +42 -0
- package/dist/semantics/normalize/cells/policies/collection.js +218 -0
- package/dist/semantics/normalize/cells/policies/field.d.ts +28 -0
- package/dist/semantics/normalize/cells/policies/field.js +40 -0
- package/dist/semantics/normalize/cells/policies/index.d.ts +49 -0
- package/dist/semantics/normalize/cells/policies/index.js +58 -0
- package/dist/semantics/normalize/cells/policies/local.d.ts +18 -0
- package/dist/semantics/normalize/cells/policies/local.js +37 -0
- package/dist/semantics/normalize/cells/policies/parameter.d.ts +28 -0
- package/dist/semantics/normalize/cells/policies/parameter.js +39 -0
- package/dist/semantics/normalize/cells/policies/return.d.ts +26 -0
- package/dist/semantics/normalize/cells/policies/return.js +45 -0
- package/dist/semantics/normalize/cells/policies/shared.d.ts +33 -0
- package/dist/semantics/normalize/cells/policies/shared.js +45 -0
- package/dist/semantics/normalize/cells/policy.d.ts +72 -0
- package/dist/semantics/normalize/cells/policy.js +18 -0
- package/dist/semantics/normalize/cells/registry.d.ts +14 -0
- package/dist/semantics/normalize/cells/registry.js +17 -0
- package/dist/semantics/normalize/census-refusal.d.ts +62 -0
- package/dist/semantics/normalize/census-refusal.js +27 -0
- package/dist/semantics/normalize/census.d.ts +109 -0
- package/dist/semantics/normalize/census.js +667 -0
- package/dist/semantics/normalize/collection-bindings.d.ts +278 -0
- package/dist/semantics/normalize/collection-bindings.js +677 -0
- package/dist/semantics/normalize/commonjs-module-record.d.ts +21 -0
- package/dist/semantics/normalize/commonjs-module-record.js +289 -0
- package/dist/semantics/normalize/commonjs-require.d.ts +13 -0
- package/dist/semantics/normalize/commonjs-require.js +1527 -0
- package/dist/semantics/normalize/contribution.d.ts +63 -0
- package/dist/semantics/normalize/contribution.js +172 -0
- package/dist/semantics/normalize/dead-typeof-guards.d.ts +64 -0
- package/dist/semantics/normalize/dead-typeof-guards.js +152 -0
- package/dist/semantics/normalize/deferred-intrinsic-protocols.d.ts +57 -0
- package/dist/semantics/normalize/deferred-intrinsic-protocols.js +109 -0
- package/dist/semantics/normalize/derived-expression-type.d.ts +1070 -0
- package/dist/semantics/normalize/derived-expression-type.js +3463 -0
- package/dist/semantics/normalize/evaluation-order.d.ts +16 -0
- package/dist/semantics/normalize/evaluation-order.js +37 -0
- package/dist/semantics/normalize/field-bindings.d.ts +167 -0
- package/dist/semantics/normalize/field-bindings.js +1125 -0
- package/dist/semantics/normalize/flow/array-element-continuation.d.ts +27 -0
- package/dist/semantics/normalize/flow/array-element-continuation.js +1452 -0
- package/dist/semantics/normalize/flow/callable-array-origins.d.ts +42 -0
- package/dist/semantics/normalize/flow/callable-array-origins.js +318 -0
- package/dist/semantics/normalize/flow/callable-completions.d.ts +45 -0
- package/dist/semantics/normalize/flow/callable-completions.js +82 -0
- package/dist/semantics/normalize/flow/callable-reach.d.ts +237 -0
- package/dist/semantics/normalize/flow/callable-reach.js +7174 -0
- package/dist/semantics/normalize/flow/class-family-member-read.d.ts +16 -0
- package/dist/semantics/normalize/flow/class-family-member-read.js +992 -0
- package/dist/semantics/normalize/flow/collection-value-continuation.d.ts +21 -0
- package/dist/semantics/normalize/flow/collection-value-continuation.js +192 -0
- package/dist/semantics/normalize/flow/component-solver.d.ts +199 -0
- package/dist/semantics/normalize/flow/component-solver.js +587 -0
- package/dist/semantics/normalize/flow/computed-key-set.d.ts +84 -0
- package/dist/semantics/normalize/flow/computed-key-set.js +660 -0
- package/dist/semantics/normalize/flow/export-importers.d.ts +24 -0
- package/dist/semantics/normalize/flow/export-importers.js +269 -0
- package/dist/semantics/normalize/flow/host-text-sink.d.ts +25 -0
- package/dist/semantics/normalize/flow/host-text-sink.js +87 -0
- package/dist/semantics/normalize/flow/intrinsic-array-callback-frames.d.ts +84 -0
- package/dist/semantics/normalize/flow/intrinsic-array-callback-frames.js +180 -0
- package/dist/semantics/normalize/flow/intrinsic-data-definition.d.ts +35 -0
- package/dist/semantics/normalize/flow/intrinsic-data-definition.js +140 -0
- package/dist/semantics/normalize/flow/invocation-facts.d.ts +98 -0
- package/dist/semantics/normalize/flow/invocation-facts.js +257 -0
- package/dist/semantics/normalize/flow/member-call-forwarding.d.ts +122 -0
- package/dist/semantics/normalize/flow/member-call-forwarding.js +835 -0
- package/dist/semantics/normalize/flow/model.d.ts +357 -0
- package/dist/semantics/normalize/flow/model.js +177 -0
- package/dist/semantics/normalize/flow/native-collection-protocol.d.ts +24 -0
- package/dist/semantics/normalize/flow/native-collection-protocol.js +252 -0
- package/dist/semantics/normalize/flow/node-path-token.d.ts +3 -0
- package/dist/semantics/normalize/flow/node-path-token.js +53 -0
- package/dist/semantics/normalize/flow/object-binding-continuation.d.ts +11 -0
- package/dist/semantics/normalize/flow/object-binding-continuation.js +42 -0
- package/dist/semantics/normalize/flow/origin-authority.d.ts +56 -0
- package/dist/semantics/normalize/flow/origin-authority.js +2 -0
- package/dist/semantics/normalize/flow/owned-class-receivers.d.ts +35 -0
- package/dist/semantics/normalize/flow/owned-class-receivers.js +191 -0
- package/dist/semantics/normalize/flow/parameter-values.d.ts +27 -0
- package/dist/semantics/normalize/flow/parameter-values.js +251 -0
- package/dist/semantics/normalize/flow/proof-hypotheses.d.ts +66 -0
- package/dist/semantics/normalize/flow/proof-hypotheses.js +162 -0
- package/dist/semantics/normalize/flow/record-alias-closure.d.ts +27 -0
- package/dist/semantics/normalize/flow/record-alias-closure.js +298 -0
- package/dist/semantics/normalize/flow/seeded-origins.d.ts +43 -0
- package/dist/semantics/normalize/flow/seeded-origins.js +54 -0
- package/dist/semantics/normalize/flow/source-class-data.d.ts +132 -0
- package/dist/semantics/normalize/flow/source-class-data.js +838 -0
- package/dist/semantics/normalize/flow/source-class-instanceof.d.ts +13 -0
- package/dist/semantics/normalize/flow/source-class-instanceof.js +37 -0
- package/dist/semantics/normalize/flow/source-class-static-data.d.ts +16 -0
- package/dist/semantics/normalize/flow/source-class-static-data.js +47 -0
- package/dist/semantics/normalize/flow/source-construction-frames.d.ts +12 -0
- package/dist/semantics/normalize/flow/source-construction-frames.js +118 -0
- package/dist/semantics/normalize/flow/source-invocation-frame-layout.d.ts +34 -0
- package/dist/semantics/normalize/flow/source-invocation-frame-layout.js +78 -0
- package/dist/semantics/normalize/flow/source-invocation-receiver.d.ts +37 -0
- package/dist/semantics/normalize/flow/source-invocation-receiver.js +95 -0
- package/dist/semantics/normalize/flow/source-prototype-method-identity.d.ts +23 -0
- package/dist/semantics/normalize/flow/source-prototype-method-identity.js +81 -0
- package/dist/semantics/normalize/flow/source-record-data.d.ts +29 -0
- package/dist/semantics/normalize/flow/source-record-data.js +626 -0
- package/dist/semantics/normalize/flow/source-value-session.d.ts +77 -0
- package/dist/semantics/normalize/flow/source-value-session.js +3089 -0
- package/dist/semantics/normalize/flow/targets.d.ts +118 -0
- package/dist/semantics/normalize/flow/targets.js +405 -0
- package/dist/semantics/normalize/flow/value-flow.d.ts +36 -0
- package/dist/semantics/normalize/flow/value-flow.js +823 -0
- package/dist/semantics/normalize/flow/value-provenance.d.ts +31 -0
- package/dist/semantics/normalize/flow/value-provenance.js +112 -0
- package/dist/semantics/normalize/gating.d.ts +51 -0
- package/dist/semantics/normalize/gating.js +560 -0
- package/dist/semantics/normalize/generic-function-choice.d.ts +31 -0
- package/dist/semantics/normalize/generic-function-choice.js +115 -0
- package/dist/semantics/normalize/global-host-mutations.d.ts +51 -0
- package/dist/semantics/normalize/global-host-mutations.js +5989 -0
- package/dist/semantics/normalize/host-effect-contracts.d.ts +77 -0
- package/dist/semantics/normalize/host-effect-contracts.js +143 -0
- package/dist/semantics/normalize/host-mutation-computed-keys.d.ts +38 -0
- package/dist/semantics/normalize/host-mutation-computed-keys.js +26 -0
- package/dist/semantics/normalize/host-mutation-key-reader.d.ts +66 -0
- package/dist/semantics/normalize/host-mutation-key-reader.js +192 -0
- package/dist/semantics/normalize/host-mutation-keys.d.ts +114 -0
- package/dist/semantics/normalize/host-mutation-keys.js +183 -0
- package/dist/semantics/normalize/identities.d.ts +172 -0
- package/dist/semantics/normalize/identities.js +426 -0
- package/dist/semantics/normalize/implicit-arguments-tuple.d.ts +97 -0
- package/dist/semantics/normalize/implicit-arguments-tuple.js +197 -0
- package/dist/semantics/normalize/implicit-arguments.d.ts +11 -0
- package/dist/semantics/normalize/implicit-arguments.js +39 -0
- package/dist/semantics/normalize/instantiation.d.ts +73 -0
- package/dist/semantics/normalize/instantiation.js +399 -0
- package/dist/semantics/normalize/intrinsic-property-call.d.ts +18 -0
- package/dist/semantics/normalize/intrinsic-property-call.js +69 -0
- package/dist/semantics/normalize/intrinsic-prototype.d.ts +41 -0
- package/dist/semantics/normalize/intrinsic-prototype.js +87 -0
- package/dist/semantics/normalize/intrinsic-static-member.d.ts +14 -0
- package/dist/semantics/normalize/intrinsic-static-member.js +23 -0
- package/dist/semantics/normalize/jsdoc-type-names.d.ts +32 -0
- package/dist/semantics/normalize/jsdoc-type-names.js +512 -0
- package/dist/semantics/normalize/keyof.d.ts +32 -0
- package/dist/semantics/normalize/keyof.js +110 -0
- package/dist/semantics/normalize/local-bindings.d.ts +176 -0
- package/dist/semantics/normalize/local-bindings.js +1826 -0
- package/dist/semantics/normalize/logical-result-type.d.ts +16 -0
- package/dist/semantics/normalize/logical-result-type.js +102 -0
- package/dist/semantics/normalize/namespace-paths.d.ts +57 -0
- package/dist/semantics/normalize/namespace-paths.js +108 -0
- package/dist/semantics/normalize/normalize.d.ts +57 -0
- package/dist/semantics/normalize/normalize.js +68 -0
- package/dist/semantics/normalize/object-bag-bindings.d.ts +305 -0
- package/dist/semantics/normalize/object-bag-bindings.js +1290 -0
- package/dist/semantics/normalize/omitted-stated-parameter.d.ts +53 -0
- package/dist/semantics/normalize/omitted-stated-parameter.js +59 -0
- package/dist/semantics/normalize/open-type-form.d.ts +10 -0
- package/dist/semantics/normalize/open-type-form.js +32 -0
- package/dist/semantics/normalize/parameter-bindings.d.ts +361 -0
- package/dist/semantics/normalize/parameter-bindings.js +3339 -0
- package/dist/semantics/normalize/parameter-slot.d.ts +264 -0
- package/dist/semantics/normalize/parameter-slot.js +491 -0
- package/dist/semantics/normalize/physical-overload-result.d.ts +77 -0
- package/dist/semantics/normalize/physical-overload-result.js +99 -0
- package/dist/semantics/normalize/primitive-property-absence.d.ts +12 -0
- package/dist/semantics/normalize/primitive-property-absence.js +60 -0
- package/dist/semantics/normalize/producer-context.d.ts +376 -0
- package/dist/semantics/normalize/producer-context.js +1 -0
- package/dist/semantics/normalize/producers/allocations.d.ts +3 -0
- package/dist/semantics/normalize/producers/allocations.js +863 -0
- package/dist/semantics/normalize/producers/binding-kind.d.ts +37 -0
- package/dist/semantics/normalize/producers/binding-kind.js +36 -0
- package/dist/semantics/normalize/producers/bindings.d.ts +85 -0
- package/dist/semantics/normalize/producers/bindings.js +710 -0
- package/dist/semantics/normalize/producers/boundary.d.ts +34 -0
- package/dist/semantics/normalize/producers/boundary.js +123 -0
- package/dist/semantics/normalize/producers/class-lifecycle.d.ts +3 -0
- package/dist/semantics/normalize/producers/class-lifecycle.js +902 -0
- package/dist/semantics/normalize/producers/computations.d.ts +3 -0
- package/dist/semantics/normalize/producers/computations.js +613 -0
- package/dist/semantics/normalize/producers/control-loops.d.ts +30 -0
- package/dist/semantics/normalize/producers/control-loops.js +91 -0
- package/dist/semantics/normalize/producers/control.d.ts +30 -0
- package/dist/semantics/normalize/producers/control.js +923 -0
- package/dist/semantics/normalize/producers/declaration-lifecycle.d.ts +3 -0
- package/dist/semantics/normalize/producers/declaration-lifecycle.js +390 -0
- package/dist/semantics/normalize/producers/destructuring.d.ts +45 -0
- package/dist/semantics/normalize/producers/destructuring.js +1180 -0
- package/dist/semantics/normalize/producers/dynamic-language.d.ts +3 -0
- package/dist/semantics/normalize/producers/dynamic-language.js +70 -0
- package/dist/semantics/normalize/producers/erasure.d.ts +51 -0
- package/dist/semantics/normalize/producers/erasure.js +90 -0
- package/dist/semantics/normalize/producers/installed.d.ts +3 -0
- package/dist/semantics/normalize/producers/installed.js +55 -0
- package/dist/semantics/normalize/producers/invocations.d.ts +35 -0
- package/dist/semantics/normalize/producers/invocations.js +1796 -0
- package/dist/semantics/normalize/producers/iteration-yield.d.ts +59 -0
- package/dist/semantics/normalize/producers/iteration-yield.js +235 -0
- package/dist/semantics/normalize/producers/jsx.d.ts +3 -0
- package/dist/semantics/normalize/producers/jsx.js +360 -0
- package/dist/semantics/normalize/producers/mint.d.ts +39 -0
- package/dist/semantics/normalize/producers/mint.js +44 -0
- package/dist/semantics/normalize/producers/nullish.d.ts +16 -0
- package/dist/semantics/normalize/producers/nullish.js +27 -0
- package/dist/semantics/normalize/producers/object-assignment.d.ts +8 -0
- package/dist/semantics/normalize/producers/object-assignment.js +204 -0
- package/dist/semantics/normalize/producers/object-tag.d.ts +9 -0
- package/dist/semantics/normalize/producers/object-tag.js +119 -0
- package/dist/semantics/normalize/producers/optional-chain.d.ts +44 -0
- package/dist/semantics/normalize/producers/optional-chain.js +75 -0
- package/dist/semantics/normalize/producers/properties.d.ts +21 -0
- package/dist/semantics/normalize/producers/properties.js +1053 -0
- package/dist/semantics/normalize/producers/protocol.d.ts +67 -0
- package/dist/semantics/normalize/producers/protocol.js +695 -0
- package/dist/semantics/normalize/producers/references.d.ts +53 -0
- package/dist/semantics/normalize/producers/references.js +1027 -0
- package/dist/semantics/normalize/producers/shared.d.ts +561 -0
- package/dist/semantics/normalize/producers/shared.js +1683 -0
- package/dist/semantics/normalize/producers/spread-arguments.d.ts +72 -0
- package/dist/semantics/normalize/producers/spread-arguments.js +375 -0
- package/dist/semantics/normalize/producers/tagged-template.d.ts +5 -0
- package/dist/semantics/normalize/producers/tagged-template.js +307 -0
- package/dist/semantics/normalize/producers/tuple-spread.d.ts +189 -0
- package/dist/semantics/normalize/producers/tuple-spread.js +279 -0
- package/dist/semantics/normalize/property-key-domain.d.ts +36 -0
- package/dist/semantics/normalize/property-key-domain.js +150 -0
- package/dist/semantics/normalize/reachability.d.ts +189 -0
- package/dist/semantics/normalize/reachability.js +1057 -0
- package/dist/semantics/normalize/reassigned-bindings.d.ts +13 -0
- package/dist/semantics/normalize/reassigned-bindings.js +41 -0
- package/dist/semantics/normalize/record-storage-families.d.ts +11 -0
- package/dist/semantics/normalize/record-storage-families.js +109 -0
- package/dist/semantics/normalize/return-bindings.d.ts +260 -0
- package/dist/semantics/normalize/return-bindings.js +1311 -0
- package/dist/semantics/normalize/return-paths.d.ts +2 -0
- package/dist/semantics/normalize/return-paths.js +28 -0
- package/dist/semantics/normalize/script-global-redefinition.d.ts +44 -0
- package/dist/semantics/normalize/script-global-redefinition.js +75 -0
- package/dist/semantics/normalize/specialization.d.ts +201 -0
- package/dist/semantics/normalize/specialization.js +1824 -0
- package/dist/semantics/normalize/structural-array-element.d.ts +176 -0
- package/dist/semantics/normalize/structural-array-element.js +700 -0
- package/dist/semantics/normalize/structural-array-read.d.ts +13 -0
- package/dist/semantics/normalize/structural-array-read.js +124 -0
- package/dist/semantics/normalize/structural-callable.d.ts +12 -0
- package/dist/semantics/normalize/structural-callable.js +82 -0
- package/dist/semantics/normalize/structural-creation-order.d.ts +32 -0
- package/dist/semantics/normalize/structural-creation-order.js +111 -0
- package/dist/semantics/normalize/structural-declarations.d.ts +395 -0
- package/dist/semantics/normalize/structural-declarations.js +968 -0
- package/dist/semantics/normalize/structural-declared-body.d.ts +25 -0
- package/dist/semantics/normalize/structural-declared-body.js +147 -0
- package/dist/semantics/normalize/structural-generics.d.ts +56 -0
- package/dist/semantics/normalize/structural-generics.js +120 -0
- package/dist/semantics/normalize/structural-indexed-access.d.ts +11 -0
- package/dist/semantics/normalize/structural-indexed-access.js +126 -0
- package/dist/semantics/normalize/structural-instantiated-member.d.ts +64 -0
- package/dist/semantics/normalize/structural-instantiated-member.js +407 -0
- package/dist/semantics/normalize/structural-joins.d.ts +44 -0
- package/dist/semantics/normalize/structural-joins.js +143 -0
- package/dist/semantics/normalize/structural-layout-relevance.d.ts +29 -0
- package/dist/semantics/normalize/structural-layout-relevance.js +391 -0
- package/dist/semantics/normalize/structural-layout-type.d.ts +11 -0
- package/dist/semantics/normalize/structural-layout-type.js +1468 -0
- package/dist/semantics/normalize/structural-leaves.d.ts +49 -0
- package/dist/semantics/normalize/structural-leaves.js +125 -0
- package/dist/semantics/normalize/structural-local-union.d.ts +13 -0
- package/dist/semantics/normalize/structural-local-union.js +133 -0
- package/dist/semantics/normalize/structural-members.d.ts +26 -0
- package/dist/semantics/normalize/structural-members.js +84 -0
- package/dist/semantics/normalize/structural-mutable-method.d.ts +15 -0
- package/dist/semantics/normalize/structural-mutable-method.js +109 -0
- package/dist/semantics/normalize/structural-parts.d.ts +131 -0
- package/dist/semantics/normalize/structural-parts.js +737 -0
- package/dist/semantics/normalize/structural-receiver.d.ts +66 -0
- package/dist/semantics/normalize/structural-receiver.js +551 -0
- package/dist/semantics/normalize/structural-rules.d.ts +112 -0
- package/dist/semantics/normalize/structural-rules.js +93 -0
- package/dist/semantics/normalize/structural-self-reference.d.ts +150 -0
- package/dist/semantics/normalize/structural-self-reference.js +494 -0
- package/dist/semantics/normalize/structural.d.ts +202 -0
- package/dist/semantics/normalize/structural.js +4218 -0
- package/dist/semantics/normalize/unreduced-type-form.d.ts +41 -0
- package/dist/semantics/normalize/unreduced-type-form.js +53 -0
- package/dist/semantics/normalize/unresolvable-names.d.ts +56 -0
- package/dist/semantics/normalize/unresolvable-names.js +140 -0
- package/dist/semantics/package-sources.d.ts +16 -0
- package/dist/semantics/package-sources.js +365 -0
- package/dist/semantics/program.d.ts +151 -0
- package/dist/semantics/program.js +667 -0
- package/dist/semantics/prototype-install-source-transform.d.ts +4 -0
- package/dist/semantics/prototype-install-source-transform.js +341 -0
- package/dist/semantics/prototype-object-class-source-transform.d.ts +4 -0
- package/dist/semantics/prototype-object-class-source-transform.js +525 -0
- package/dist/semantics/prototype-reparenting.d.ts +50 -0
- package/dist/semantics/prototype-reparenting.js +317 -0
- package/dist/semantics/stable-checker.d.ts +10 -0
- package/dist/semantics/stable-checker.js +148 -0
- package/dist/semantics/subclass-member-overlay-transform.d.ts +35 -0
- package/dist/semantics/subclass-member-overlay-transform.js +1418 -0
- package/dist/semantics/symbol-keyed-expando-source-transform.d.ts +4 -0
- package/dist/semantics/symbol-keyed-expando-source-transform.js +66 -0
- package/dist/semantics/this-constructor-source-transform.d.ts +4 -0
- package/dist/semantics/this-constructor-source-transform.js +122 -0
- package/dist/semantics/uninstantiable-classes.d.ts +22 -0
- package/dist/semantics/uninstantiable-classes.js +75 -0
- package/dist/targets/cpp/balanced-units.d.ts +3 -0
- package/dist/targets/cpp/balanced-units.js +58 -0
- package/dist/targets/cpp/borrowed-call-entry.d.ts +30 -0
- package/dist/targets/cpp/borrowed-call-entry.js +68 -0
- package/dist/targets/cpp/captures.d.ts +68 -0
- package/dist/targets/cpp/captures.js +269 -0
- package/dist/targets/cpp/class-layout.d.ts +313 -0
- package/dist/targets/cpp/class-layout.js +483 -0
- package/dist/targets/cpp/class-properties/computed-method-value.d.ts +25 -0
- package/dist/targets/cpp/class-properties/computed-method-value.js +22 -0
- package/dist/targets/cpp/class-properties/emit-class-properties.d.ts +216 -0
- package/dist/targets/cpp/class-properties/emit-class-properties.js +917 -0
- package/dist/targets/cpp/class-properties/native-prototype.d.ts +11 -0
- package/dist/targets/cpp/class-properties/native-prototype.js +101 -0
- package/dist/targets/cpp/class-ref-transport.d.ts +12 -0
- package/dist/targets/cpp/class-ref-transport.js +32 -0
- package/dist/targets/cpp/conversions.d.ts +3 -0
- package/dist/targets/cpp/conversions.js +2027 -0
- package/dist/targets/cpp/deferral-safety.d.ts +82 -0
- package/dist/targets/cpp/deferral-safety.js +86 -0
- package/dist/targets/cpp/direct-call-receivers.d.ts +37 -0
- package/dist/targets/cpp/direct-call-receivers.js +79 -0
- package/dist/targets/cpp/document.d.ts +74 -0
- package/dist/targets/cpp/document.js +106 -0
- package/dist/targets/cpp/emit-allocation.d.ts +60 -0
- package/dist/targets/cpp/emit-allocation.js +573 -0
- package/dist/targets/cpp/emit-arrays.d.ts +119 -0
- package/dist/targets/cpp/emit-arrays.js +1047 -0
- package/dist/targets/cpp/emit-binding-reference.d.ts +17 -0
- package/dist/targets/cpp/emit-binding-reference.js +120 -0
- package/dist/targets/cpp/emit-bindings.d.ts +158 -0
- package/dist/targets/cpp/emit-bindings.js +769 -0
- package/dist/targets/cpp/emit-buffers.d.ts +156 -0
- package/dist/targets/cpp/emit-buffers.js +573 -0
- package/dist/targets/cpp/emit-callable.d.ts +230 -0
- package/dist/targets/cpp/emit-callable.js +2154 -0
- package/dist/targets/cpp/emit-carrier-members.d.ts +406 -0
- package/dist/targets/cpp/emit-carrier-members.js +1224 -0
- package/dist/targets/cpp/emit-coercion.d.ts +26 -0
- package/dist/targets/cpp/emit-coercion.js +39 -0
- package/dist/targets/cpp/emit-context.d.ts +1882 -0
- package/dist/targets/cpp/emit-context.js +904 -0
- package/dist/targets/cpp/emit-dynamic-properties.d.ts +174 -0
- package/dist/targets/cpp/emit-dynamic-properties.js +1249 -0
- package/dist/targets/cpp/emit-equality.d.ts +39 -0
- package/dist/targets/cpp/emit-equality.js +472 -0
- package/dist/targets/cpp/emit-exceptions.d.ts +104 -0
- package/dist/targets/cpp/emit-exceptions.js +513 -0
- package/dist/targets/cpp/emit-field-owner.d.ts +4 -0
- package/dist/targets/cpp/emit-field-owner.js +27 -0
- package/dist/targets/cpp/emit-in.d.ts +31 -0
- package/dist/targets/cpp/emit-in.js +426 -0
- package/dist/targets/cpp/emit-instanceof.d.ts +19 -0
- package/dist/targets/cpp/emit-instanceof.js +601 -0
- package/dist/targets/cpp/emit-integers.d.ts +68 -0
- package/dist/targets/cpp/emit-integers.js +184 -0
- package/dist/targets/cpp/emit-iterator.d.ts +100 -0
- package/dist/targets/cpp/emit-iterator.js +1137 -0
- package/dist/targets/cpp/emit-json.d.ts +73 -0
- package/dist/targets/cpp/emit-json.js +823 -0
- package/dist/targets/cpp/emit-jsx.d.ts +74 -0
- package/dist/targets/cpp/emit-jsx.js +806 -0
- package/dist/targets/cpp/emit-mixed-binary.d.ts +51 -0
- package/dist/targets/cpp/emit-mixed-binary.js +60 -0
- package/dist/targets/cpp/emit-namespaces.d.ts +101 -0
- package/dist/targets/cpp/emit-namespaces.js +133 -0
- package/dist/targets/cpp/emit-narrowing.d.ts +738 -0
- package/dist/targets/cpp/emit-narrowing.js +3967 -0
- package/dist/targets/cpp/emit-native-equality.d.ts +3 -0
- package/dist/targets/cpp/emit-native-equality.js +14 -0
- package/dist/targets/cpp/emit-native-selection.d.ts +5 -0
- package/dist/targets/cpp/emit-native-selection.js +37 -0
- package/dist/targets/cpp/emit-object-tag.d.ts +4 -0
- package/dist/targets/cpp/emit-object-tag.js +108 -0
- package/dist/targets/cpp/emit-owned-record.d.ts +2 -0
- package/dist/targets/cpp/emit-owned-record.js +15 -0
- package/dist/targets/cpp/emit-presence.d.ts +78 -0
- package/dist/targets/cpp/emit-presence.js +376 -0
- package/dist/targets/cpp/emit-properties.d.ts +105 -0
- package/dist/targets/cpp/emit-properties.js +1640 -0
- package/dist/targets/cpp/emit-record-view.d.ts +20 -0
- package/dist/targets/cpp/emit-record-view.js +354 -0
- package/dist/targets/cpp/emit-return.d.ts +5 -0
- package/dist/targets/cpp/emit-return.js +237 -0
- package/dist/targets/cpp/emit-sum-widening.d.ts +10 -0
- package/dist/targets/cpp/emit-sum-widening.js +69 -0
- package/dist/targets/cpp/emit-tonumber.d.ts +38 -0
- package/dist/targets/cpp/emit-tonumber.js +177 -0
- package/dist/targets/cpp/emit-tostring.d.ts +92 -0
- package/dist/targets/cpp/emit-tostring.js +556 -0
- package/dist/targets/cpp/emit-typeof.d.ts +49 -0
- package/dist/targets/cpp/emit-typeof.js +317 -0
- package/dist/targets/cpp/emit-union-properties.d.ts +181 -0
- package/dist/targets/cpp/emit-union-properties.js +1281 -0
- package/dist/targets/cpp/emit.d.ts +45 -0
- package/dist/targets/cpp/emit.js +2225 -0
- package/dist/targets/cpp/error-types.d.ts +4 -0
- package/dist/targets/cpp/error-types.js +11 -0
- package/dist/targets/cpp/function-source-reads.d.ts +72 -0
- package/dist/targets/cpp/function-source-reads.js +148 -0
- package/dist/targets/cpp/host/atomics.d.ts +25 -0
- package/dist/targets/cpp/host/atomics.js +63 -0
- package/dist/targets/cpp/host/core-globals.d.ts +108 -0
- package/dist/targets/cpp/host/core-globals.js +158 -0
- package/dist/targets/cpp/host/dynamic-argument-members.d.ts +42 -0
- package/dist/targets/cpp/host/dynamic-argument-members.js +61 -0
- package/dist/targets/cpp/host/emit-host-arity.d.ts +139 -0
- package/dist/targets/cpp/host/emit-host-arity.js +232 -0
- package/dist/targets/cpp/host/emit-host-invoke.d.ts +91 -0
- package/dist/targets/cpp/host/emit-host-invoke.js +1105 -0
- package/dist/targets/cpp/host/emit-host-object.d.ts +55 -0
- package/dist/targets/cpp/host/emit-host-object.js +2206 -0
- package/dist/targets/cpp/host/emit-host-properties.d.ts +69 -0
- package/dist/targets/cpp/host/emit-host-properties.js +533 -0
- package/dist/targets/cpp/host/emit-host-reflect.d.ts +4 -0
- package/dist/targets/cpp/host/emit-host-reflect.js +180 -0
- package/dist/targets/cpp/host/emit-host-value.d.ts +120 -0
- package/dist/targets/cpp/host/emit-host-value.js +392 -0
- package/dist/targets/cpp/host/host-members.d.ts +505 -0
- package/dist/targets/cpp/host/host-members.js +819 -0
- package/dist/targets/cpp/host/host-method-aliases.d.ts +30 -0
- package/dist/targets/cpp/host/host-method-aliases.js +76 -0
- package/dist/targets/cpp/host/native-protocols.d.ts +47 -0
- package/dist/targets/cpp/host/native-protocols.js +183 -0
- package/dist/targets/cpp/host/object-protocol.d.ts +351 -0
- package/dist/targets/cpp/host/object-protocol.js +671 -0
- package/dist/targets/cpp/host-namespace-reads.d.ts +83 -0
- package/dist/targets/cpp/host-namespace-reads.js +113 -0
- package/dist/targets/cpp/manifest/capabilities.d.ts +39 -0
- package/dist/targets/cpp/manifest/capabilities.js +1484 -0
- package/dist/targets/cpp/manifest.d.ts +23 -0
- package/dist/targets/cpp/manifest.js +113 -0
- package/dist/targets/cpp/native-error-base.d.ts +38 -0
- package/dist/targets/cpp/native-error-base.js +74 -0
- package/dist/targets/cpp/native-narrowing-transport.d.ts +12 -0
- package/dist/targets/cpp/native-narrowing-transport.js +151 -0
- package/dist/targets/cpp/native-selection-helpers.d.ts +11 -0
- package/dist/targets/cpp/native-selection-helpers.js +46 -0
- package/dist/targets/cpp/native-symbol-keys.d.ts +8 -0
- package/dist/targets/cpp/native-symbol-keys.js +34 -0
- package/dist/targets/cpp/ownership.d.ts +43 -0
- package/dist/targets/cpp/ownership.js +38 -0
- package/dist/targets/cpp/owning-conversion-input.d.ts +14 -0
- package/dist/targets/cpp/owning-conversion-input.js +12 -0
- package/dist/targets/cpp/property-read-claims.d.ts +62 -0
- package/dist/targets/cpp/property-read-claims.js +23 -0
- package/dist/targets/cpp/property-store-claims.d.ts +62 -0
- package/dist/targets/cpp/property-store-claims.js +26 -0
- package/dist/targets/cpp/prototype/emit-prototype-array.d.ts +111 -0
- package/dist/targets/cpp/prototype/emit-prototype-array.js +602 -0
- package/dist/targets/cpp/prototype/emit-prototype-date.d.ts +133 -0
- package/dist/targets/cpp/prototype/emit-prototype-date.js +515 -0
- package/dist/targets/cpp/prototype/emit-prototype-error.d.ts +13 -0
- package/dist/targets/cpp/prototype/emit-prototype-error.js +54 -0
- package/dist/targets/cpp/prototype/emit-prototype-invoke.d.ts +34 -0
- package/dist/targets/cpp/prototype/emit-prototype-invoke.js +1003 -0
- package/dist/targets/cpp/prototype/emit-prototype-iterator.d.ts +47 -0
- package/dist/targets/cpp/prototype/emit-prototype-iterator.js +250 -0
- package/dist/targets/cpp/prototype/emit-prototype-promise.d.ts +46 -0
- package/dist/targets/cpp/prototype/emit-prototype-promise.js +143 -0
- package/dist/targets/cpp/prototype/emit-prototype-regexp.d.ts +335 -0
- package/dist/targets/cpp/prototype/emit-prototype-regexp.js +853 -0
- package/dist/targets/cpp/prototype/emit-prototype-string.d.ts +42 -0
- package/dist/targets/cpp/prototype/emit-prototype-string.js +252 -0
- package/dist/targets/cpp/prototype/prototype-method-reads.d.ts +25 -0
- package/dist/targets/cpp/prototype/prototype-method-reads.js +182 -0
- package/dist/targets/cpp/reactive-dependencies.d.ts +140 -0
- package/dist/targets/cpp/reactive-dependencies.js +432 -0
- package/dist/targets/cpp/reactive-origins.d.ts +44 -0
- package/dist/targets/cpp/reactive-origins.js +82 -0
- package/dist/targets/cpp/records.d.ts +277 -0
- package/dist/targets/cpp/records.js +2427 -0
- package/dist/targets/cpp/recursive-containers.d.ts +43 -0
- package/dist/targets/cpp/recursive-containers.js +144 -0
- package/dist/targets/cpp/regexp-types.d.ts +56 -0
- package/dist/targets/cpp/regexp-types.js +59 -0
- package/dist/targets/cpp/substrate.d.ts +125 -0
- package/dist/targets/cpp/substrate.js +12 -0
- package/dist/targets/cpp/translation-unit.d.ts +219 -0
- package/dist/targets/cpp/translation-unit.js +2063 -0
- package/dist/targets/cpp/types.d.ts +280 -0
- package/dist/targets/cpp/types.js +1135 -0
- package/dist/targets/cpp/virtual-methods.d.ts +95 -0
- package/dist/targets/cpp/virtual-methods.js +264 -0
- package/package.json +95 -0
- package/src/targets/cpp/runtime/gea_dynamic_proxy.h +824 -0
- package/src/targets/cpp/runtime/gea_eval.h +1376 -0
- package/src/targets/cpp/runtime/gea_native_class_prototype.h +44 -0
- package/src/targets/cpp/runtime/gea_runtime.h +29222 -0
- package/src/targets/cpp/runtime/gea_runtime_builtins.cpp +55 -0
package/dist/ir/shake.js
ADDED
|
@@ -0,0 +1,1078 @@
|
|
|
1
|
+
import { isRegionId } from '../identity/ids.js';
|
|
2
|
+
import { representationKey } from '../representation/model.js';
|
|
3
|
+
import { allOperationsOf } from './model.js';
|
|
4
|
+
import { arrayAllocationDrainsDynamicIterator, operandsOfIrOperation, resultOfIrOperation } from './queries.js';
|
|
5
|
+
import { verifyIrBody } from './verify.js';
|
|
6
|
+
/**
|
|
7
|
+
* Whether a carrier can put user code on the path of an otherwise arithmetic
|
|
8
|
+
* operation.
|
|
9
|
+
*
|
|
10
|
+
* `a + b` over two numbers is a machine instruction; over a boxed carrier it is
|
|
11
|
+
* `ToPrimitive`, which calls `valueOf`/`toString` and can run anything. So a
|
|
12
|
+
* `compute` is pure exactly when no carrier it touches is dynamic. The walk is
|
|
13
|
+
* total rather than top-level-only: a carrier that merely *contains* a box is
|
|
14
|
+
* rare here, and answering "no" for one would be the cheap kind of wrong.
|
|
15
|
+
*/
|
|
16
|
+
const carriesDynamic = (representation) => {
|
|
17
|
+
switch (representation.kind) {
|
|
18
|
+
case 'dynamic':
|
|
19
|
+
return true;
|
|
20
|
+
case 'record':
|
|
21
|
+
return representation.fields.some((field) => carriesDynamic(field.value));
|
|
22
|
+
case 'record-with-index':
|
|
23
|
+
return (representation.fields.some((field) => carriesDynamic(field.value)) ||
|
|
24
|
+
representation.indexes.some((index) => carriesDynamic(index.value)));
|
|
25
|
+
case 'proxy-object':
|
|
26
|
+
return true;
|
|
27
|
+
case 'borrowed-ref':
|
|
28
|
+
return carriesDynamic(representation.referent);
|
|
29
|
+
case 'array-object':
|
|
30
|
+
case 'dense-buffer':
|
|
31
|
+
case 'native-sequence':
|
|
32
|
+
case 'iterator':
|
|
33
|
+
return carriesDynamic(representation.element);
|
|
34
|
+
case 'promise':
|
|
35
|
+
return carriesDynamic(representation.value);
|
|
36
|
+
case 'keyed-collection':
|
|
37
|
+
return carriesDynamic(representation.key) || (representation.value !== null && carriesDynamic(representation.value));
|
|
38
|
+
case 'dictionary':
|
|
39
|
+
return carriesDynamic(representation.value);
|
|
40
|
+
case 'optional':
|
|
41
|
+
return carriesDynamic(representation.payload);
|
|
42
|
+
case 'tagged-union':
|
|
43
|
+
return representation.arms.some((arm) => carriesDynamic(arm.value));
|
|
44
|
+
default:
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* The effect class of one operation.
|
|
50
|
+
*
|
|
51
|
+
* Exhaustive over the operation union on purpose: a kind added later reaches
|
|
52
|
+
* the `always` default and is kept, which is the safe direction for a pass
|
|
53
|
+
* whose mistakes are silent.
|
|
54
|
+
*/
|
|
55
|
+
const effectOf = (operation) => {
|
|
56
|
+
switch (operation.kind) {
|
|
57
|
+
// A `gather` element drains a genuinely dynamic iterator -- see
|
|
58
|
+
// `queries.ts`'s `arrayAllocationDrainsDynamicIterator` -- so an
|
|
59
|
+
// allocation with one is not "a fresh object with no user code run" the
|
|
60
|
+
// way an ordinary literal or a native range-copy (`spread`) is.
|
|
61
|
+
case 'allocate-array-object':
|
|
62
|
+
return arrayAllocationDrainsDynamicIterator(operation) ? 'always' : 'pure';
|
|
63
|
+
// Allocation observes nothing and runs no user code: a fresh object, a
|
|
64
|
+
// callable carrier, a record, a compiled pattern. What is done to the
|
|
65
|
+
// object afterwards is separate operations, judged separately.
|
|
66
|
+
case 'allocate-ordinary-object':
|
|
67
|
+
case 'allocate-callable':
|
|
68
|
+
case 'allocate-constructor':
|
|
69
|
+
case 'allocate-proxy':
|
|
70
|
+
case 'allocate-record':
|
|
71
|
+
case 'allocate-template-object':
|
|
72
|
+
case 'allocate-regexp':
|
|
73
|
+
// Values that come from the frame, the environment, or a literal.
|
|
74
|
+
case 'constant':
|
|
75
|
+
case 'parameter':
|
|
76
|
+
case 'receiver':
|
|
77
|
+
case 'phi':
|
|
78
|
+
// A cell READ has no effect of its own; what it does is make the cell live,
|
|
79
|
+
// which the caller records separately.
|
|
80
|
+
case 'binding-read':
|
|
81
|
+
// Reading a wrapper parameter only exposes the current module record; it
|
|
82
|
+
// does not initialize, mutate, or invoke it. Keep it when its result is
|
|
83
|
+
// used, exactly like an ordinary binding read.
|
|
84
|
+
case 'commonjs-binding':
|
|
85
|
+
// Both predicates are total functions of a stated carrier: `ToBoolean` has
|
|
86
|
+
// no user-visible hook in the language (ECMA-262 7.1.2), and a nullish test
|
|
87
|
+
// reads a discriminant.
|
|
88
|
+
case 'test':
|
|
89
|
+
// A conversion-use application is a total function of its source under the
|
|
90
|
+
// conversion algebra: identity, an installed materializer, a field-wise
|
|
91
|
+
// product copy, an optional wrap, an element-wise collection map, or a
|
|
92
|
+
// tagged dispatch (`conversion/algebra.ts`). None of them invoke program
|
|
93
|
+
// code, so a conversion whose result nothing reads is not doing anything.
|
|
94
|
+
case 'convert':
|
|
95
|
+
// Same reasoning as `convert` immediately above, one arm narrower: this
|
|
96
|
+
// tests a proven-live subset of a tagged union's arms and applies the
|
|
97
|
+
// identical conversion algebra to whichever one holds, or reads the
|
|
98
|
+
// result's absent value when the source itself is absent. No arm of that
|
|
99
|
+
// is program code either.
|
|
100
|
+
case 'merge-live-arm-rebuild':
|
|
101
|
+
return 'pure';
|
|
102
|
+
case 'compute':
|
|
103
|
+
if (operation.form === 'require-object-coercible' ||
|
|
104
|
+
operation.form === 'require-iterable-present' ||
|
|
105
|
+
operation.form === 'require-tagged-union-arm')
|
|
106
|
+
return 'always';
|
|
107
|
+
return operation.operands.some((operand) => carriesDynamic(operand.representation)) || carriesDynamic(operation.result.representation)
|
|
108
|
+
? 'always'
|
|
109
|
+
: 'pure';
|
|
110
|
+
case 'set':
|
|
111
|
+
case 'delete':
|
|
112
|
+
case 'define-own-property':
|
|
113
|
+
case 'spread-copy':
|
|
114
|
+
return 'store';
|
|
115
|
+
case 'binding-write':
|
|
116
|
+
return 'cell-store';
|
|
117
|
+
// A require can synchronously initialize a target and throw; replacing
|
|
118
|
+
// `module.exports` mutates the record cell. Neither is removable even
|
|
119
|
+
// when its immediate result is unused.
|
|
120
|
+
case 'commonjs-require':
|
|
121
|
+
case 'commonjs-binding-set':
|
|
122
|
+
return 'always';
|
|
123
|
+
// Everything else is kept: a property read may run an accessor or reach a
|
|
124
|
+
// host, an iterator step runs the protocol, an element operation mutates a
|
|
125
|
+
// host tree, a call runs the program, and a catch binding is the shape of
|
|
126
|
+
// the clause the emitter renders rather than a value it may drop.
|
|
127
|
+
default:
|
|
128
|
+
return 'always';
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
/** An allocation whose result is a fresh object no one else can hold yet, so a store into it is observable only through it. */
|
|
132
|
+
const isPlainAllocation = (operation) => operation.kind === 'allocate-record' || operation.kind === 'allocate-ordinary-object' || operation.kind === 'allocate-array-object';
|
|
133
|
+
/** The receiver a store mutates, or `null` for an operation that is not one. */
|
|
134
|
+
const storeReceiverOf = (operation) => {
|
|
135
|
+
switch (operation.kind) {
|
|
136
|
+
case 'set':
|
|
137
|
+
case 'delete':
|
|
138
|
+
case 'define-own-property':
|
|
139
|
+
case 'spread-copy':
|
|
140
|
+
return operation.receiver.value;
|
|
141
|
+
default:
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* The backward slice of one body, given what the program already knows is
|
|
147
|
+
* live.
|
|
148
|
+
*
|
|
149
|
+
* Monotone in `liveCells`: a cell becoming live can only add operations, never
|
|
150
|
+
* remove one, which is what lets the caller re-run this as the program's own
|
|
151
|
+
* fixpoint widens without ever having to undo a conclusion.
|
|
152
|
+
*/
|
|
153
|
+
const sliceBody = (body, placements, liveCells, structuralViewScopes) => {
|
|
154
|
+
const definitions = new Map();
|
|
155
|
+
const blocks = [];
|
|
156
|
+
for (const blockId of body.blockOrder) {
|
|
157
|
+
const block = body.blocks.get(blockId);
|
|
158
|
+
if (!block)
|
|
159
|
+
continue;
|
|
160
|
+
blocks.push(block);
|
|
161
|
+
for (const operation of allOperationsOf(block)) {
|
|
162
|
+
const result = resultOfIrOperation(operation);
|
|
163
|
+
if (result)
|
|
164
|
+
definitions.set(result.id, operation);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const kept = new Set();
|
|
168
|
+
const keptValues = new Set();
|
|
169
|
+
const pending = [];
|
|
170
|
+
const keep = (operation) => {
|
|
171
|
+
if (kept.has(operation))
|
|
172
|
+
return;
|
|
173
|
+
kept.add(operation);
|
|
174
|
+
pending.push(operation);
|
|
175
|
+
};
|
|
176
|
+
const drain = () => {
|
|
177
|
+
for (let operation = pending.pop(); operation !== undefined; operation = pending.pop()) {
|
|
178
|
+
for (const operand of operandsOfIrOperation(operation)) {
|
|
179
|
+
keptValues.add(operand.value);
|
|
180
|
+
const definition = definitions.get(operand.value);
|
|
181
|
+
if (definition)
|
|
182
|
+
keep(definition);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
// A terminator is the block's control transfer; there is no such thing as a
|
|
187
|
+
// dead one in a body whose CFG this pass does not touch.
|
|
188
|
+
for (const block of blocks)
|
|
189
|
+
keep(block.terminator);
|
|
190
|
+
drain();
|
|
191
|
+
/** Whether an operation not yet kept has become one under what is now known. */
|
|
192
|
+
const activated = (operation) => {
|
|
193
|
+
const result = resultOfIrOperation(operation);
|
|
194
|
+
if (result && keptValues.has(result.id))
|
|
195
|
+
return true;
|
|
196
|
+
const effect = effectOf(operation);
|
|
197
|
+
if (effect === 'always')
|
|
198
|
+
return true;
|
|
199
|
+
if (effect === 'pure')
|
|
200
|
+
return false;
|
|
201
|
+
if (effect === 'cell-store') {
|
|
202
|
+
if (operation.kind !== 'binding-write')
|
|
203
|
+
return true;
|
|
204
|
+
const placement = placements.get(operation.declaration);
|
|
205
|
+
// A cell this projection does not place, or one that is not a run-once
|
|
206
|
+
// region's, is not this pass's to reason about: a local frame slot, a
|
|
207
|
+
// host-defined external, a name with no placement at all. Keep the write.
|
|
208
|
+
if (!placement || placement.storage.kind !== 'region')
|
|
209
|
+
return true;
|
|
210
|
+
return liveCells.has(operation.declaration);
|
|
211
|
+
}
|
|
212
|
+
const receiver = storeReceiverOf(operation);
|
|
213
|
+
if (receiver === null)
|
|
214
|
+
return true;
|
|
215
|
+
const allocation = definitions.get(receiver);
|
|
216
|
+
// A receiver this body did not freshly allocate may be reachable from
|
|
217
|
+
// anywhere -- a parameter, a global, a host object, a proxy whose traps run
|
|
218
|
+
// program code. The mutation stays.
|
|
219
|
+
if (!allocation || !isPlainAllocation(allocation))
|
|
220
|
+
return true;
|
|
221
|
+
return keptValues.has(receiver);
|
|
222
|
+
};
|
|
223
|
+
for (let changed = true; changed;) {
|
|
224
|
+
changed = false;
|
|
225
|
+
for (const block of blocks) {
|
|
226
|
+
for (const operation of block.operations) {
|
|
227
|
+
if (kept.has(operation) || !activated(operation))
|
|
228
|
+
continue;
|
|
229
|
+
keep(operation);
|
|
230
|
+
changed = true;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (changed)
|
|
234
|
+
drain();
|
|
235
|
+
}
|
|
236
|
+
const readCells = new Set();
|
|
237
|
+
const citedFunctions = new Set();
|
|
238
|
+
const carriers = [];
|
|
239
|
+
const spelledKeys = new Set();
|
|
240
|
+
const fieldHazardScopes = new Set();
|
|
241
|
+
const computedMemberHazards = [];
|
|
242
|
+
const constructors = new Set();
|
|
243
|
+
const constructedClasses = new Set();
|
|
244
|
+
const evaluatedClasses = new Set();
|
|
245
|
+
let openConstruction = false;
|
|
246
|
+
const constants = new Map();
|
|
247
|
+
for (const operation of kept)
|
|
248
|
+
if (operation.kind === 'constant')
|
|
249
|
+
constants.set(operation.result.id, operation.text);
|
|
250
|
+
for (const operation of kept) {
|
|
251
|
+
if (operation.kind === 'binding-read')
|
|
252
|
+
readCells.add(operation.declaration);
|
|
253
|
+
if (operation.kind === 'allocate-callable')
|
|
254
|
+
citedFunctions.add(operation.functionId);
|
|
255
|
+
if (operation.kind === 'allocate-constructor')
|
|
256
|
+
evaluatedClasses.add(operation.declaration);
|
|
257
|
+
if (operation.kind === 'construct') {
|
|
258
|
+
const targets = operation.target.kind === 'exact'
|
|
259
|
+
? [operation.target.target]
|
|
260
|
+
: operation.target.kind === 'closed-family'
|
|
261
|
+
? operation.target.targets
|
|
262
|
+
: null;
|
|
263
|
+
if (targets !== null)
|
|
264
|
+
for (const target of targets) {
|
|
265
|
+
if (target.kind === 'function')
|
|
266
|
+
constructors.add(target.functionId);
|
|
267
|
+
else
|
|
268
|
+
constructedClasses.add(target.classDeclaration);
|
|
269
|
+
}
|
|
270
|
+
// An open proof is a complete answer -- the callee is whatever the
|
|
271
|
+
// carrier holds -- and the carrier is what says what that can be. A
|
|
272
|
+
// `native-handle` holds a HOST constructor and nothing else: `new
|
|
273
|
+
// Error(...)`, `new Promise(...)`, `new Map()` all land here, and none of
|
|
274
|
+
// them can reach a class this program projects. They are the overwhelming
|
|
275
|
+
// majority of open constructions in a node-compat program (176 of them in
|
|
276
|
+
// `apps/raw-http-hello`), so reading the carrier here is the difference
|
|
277
|
+
// between this demand answering something and answering nothing at all.
|
|
278
|
+
// A `constructor-family` names its class objects exactly. Anything else
|
|
279
|
+
// -- a dynamic carrier, a callable dispatch -- really can be any of them.
|
|
280
|
+
else if (operation.callee.representation.kind === 'constructor-family')
|
|
281
|
+
for (const member of operation.callee.representation.members)
|
|
282
|
+
constructedClasses.add(member);
|
|
283
|
+
else if (operation.callee.representation.kind !== 'native-handle') {
|
|
284
|
+
if (process.env['GEA_SHAKE_DEBUG'])
|
|
285
|
+
console.log(`[SHAKE] open construction in ${String(body.sourceOwner)}: ${representationKey(operation.callee.representation)} -> ${representationKey(operation.result.representation)}`);
|
|
286
|
+
openConstruction = true;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (operation.kind === 'own-property-keys' || operation.kind === 'spread-copy') {
|
|
290
|
+
// An enumeration names no key, so every field of whatever it walks is
|
|
291
|
+
// reached without being spelled. Both operands: `spread-copy`'s
|
|
292
|
+
// `receiver` is the destination and its `source` is what gets read out,
|
|
293
|
+
// and a destination can be read back through the same walk.
|
|
294
|
+
for (const scope of receiverClassScopes(operation.receiver.representation, structuralViewScopes))
|
|
295
|
+
fieldHazardScopes.add(scope);
|
|
296
|
+
if (operation.kind === 'spread-copy')
|
|
297
|
+
for (const scope of receiverClassScopes(operation.source.representation, structuralViewScopes))
|
|
298
|
+
fieldHazardScopes.add(scope);
|
|
299
|
+
}
|
|
300
|
+
else if (operation.kind === 'get' ||
|
|
301
|
+
operation.kind === 'set' ||
|
|
302
|
+
operation.kind === 'delete' ||
|
|
303
|
+
operation.kind === 'has-property' ||
|
|
304
|
+
operation.kind === 'define-own-property') {
|
|
305
|
+
const text = constants.get(operation.key.value);
|
|
306
|
+
const scopes = receiverClassScopes(operation.receiver.representation, structuralViewScopes);
|
|
307
|
+
if (text !== undefined)
|
|
308
|
+
for (const scope of scopes)
|
|
309
|
+
spelledKeys.add(`${scope}#${text}`);
|
|
310
|
+
// A dynamic key is a hazard only where it READS. `fieldInitializerRuns`
|
|
311
|
+
// asks one question -- can anything observe the value this initializer
|
|
312
|
+
// would leave in the field -- and a store answers no: whatever key it
|
|
313
|
+
// lands on, it overwrites rather than reads. hono's `Hono` constructor
|
|
314
|
+
// does `allMethods.forEach((method) => { this[method] = ... })`, and
|
|
315
|
+
// treating that store as a read kept the initializer of every field the
|
|
316
|
+
// class declares, `fire = (event: FetchEventLike) => ...` among them.
|
|
317
|
+
//
|
|
318
|
+
// The field itself is untouched by this: pruning drops the initializer
|
|
319
|
+
// CALL, never the struct member, so the dispatcher a dynamic store goes
|
|
320
|
+
// through still has the slot to write.
|
|
321
|
+
else if (operation.kind !== 'set' && operation.kind !== 'define-own-property') {
|
|
322
|
+
for (const scope of scopes)
|
|
323
|
+
fieldHazardScopes.add(scope);
|
|
324
|
+
// A computed class `[[Get]]` can now select a generated prototype
|
|
325
|
+
// method (emit-dynamic-properties.ts). Keep every method in that
|
|
326
|
+
// receiver's inheritance scope: the string carrier intentionally
|
|
327
|
+
// erases a finite literal union, so pruning cannot recover a smaller
|
|
328
|
+
// key set here without inventing a second type analysis.
|
|
329
|
+
if (operation.kind === 'get') {
|
|
330
|
+
for (const scope of scopes)
|
|
331
|
+
computedMemberHazards.push({ scope, target: operation.result.representation });
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
else if (operation.kind === 'call' && operation.intrinsicReflection) {
|
|
336
|
+
// Reflect's authenticated native call still observes the same member as
|
|
337
|
+
// an ordinary property operation. Its native ABI does not make an
|
|
338
|
+
// otherwise-unreferenced field initializer dead.
|
|
339
|
+
const receiver = operation.arguments[0];
|
|
340
|
+
const key = operation.arguments[1];
|
|
341
|
+
if (operation.argumentsAreSpread || !receiver || !key) {
|
|
342
|
+
fieldHazardScopes.add(anyClassScope);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
const text = constants.get(key.value);
|
|
346
|
+
const scopes = receiverClassScopes(receiver.representation, structuralViewScopes);
|
|
347
|
+
if (text !== undefined)
|
|
348
|
+
for (const scope of scopes)
|
|
349
|
+
spelledKeys.add(`${scope}#${text}`);
|
|
350
|
+
else if (operation.intrinsicReflection !== 'set') {
|
|
351
|
+
for (const scope of scopes)
|
|
352
|
+
fieldHazardScopes.add(scope);
|
|
353
|
+
if (operation.intrinsicReflection === 'get' && operation.result)
|
|
354
|
+
for (const scope of scopes)
|
|
355
|
+
computedMemberHazards.push({ scope, target: operation.result.representation });
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
// OrdinaryToPrimitive invokes `toString`/`valueOf` without an explicit
|
|
360
|
+
// property operation. Root those protocol members on the carrier being
|
|
361
|
+
// coerced, rather than keeping same-named methods on every class in the
|
|
362
|
+
// compilation. A primitive computation is included conservatively because
|
|
363
|
+
// `+` and relational comparison may perform the same coercion.
|
|
364
|
+
if (operation.kind === 'convert' || operation.kind === 'compute') {
|
|
365
|
+
const operands = operation.kind === 'convert' ? [operation.source] : operation.operands;
|
|
366
|
+
for (const operand of operands) {
|
|
367
|
+
for (const scope of receiverClassScopes(operand.representation, structuralViewScopes)) {
|
|
368
|
+
spelledKeys.add(`${scope}#toString`);
|
|
369
|
+
spelledKeys.add(`${scope}#valueOf`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// `String(x)`, `Number(x)` and `Boolean(x)` run the same OrdinaryToPrimitive
|
|
374
|
+
// on their argument, and they are CALLS -- a `native-handle` callee named by
|
|
375
|
+
// the host -- not the `convert`/`compute` the clause above sees. Without
|
|
376
|
+
// this the method a class declares was shaken away while the printer's own
|
|
377
|
+
// ToString table still asked whether the class has one, and got "no": a
|
|
378
|
+
// `class Bag { toString() {...} }` whose only use was `String(bag)` printed
|
|
379
|
+
// the "[object Object]" tag, silently, with nothing refused anywhere.
|
|
380
|
+
// Three protocols by name rather than every native-handle call, so an
|
|
381
|
+
// unrelated host construction does not retain conversion members across
|
|
382
|
+
// the compilation -- the same narrowness the clause above is written for.
|
|
383
|
+
if (operation.kind === 'call' && operation.callee.representation.kind === 'native-handle') {
|
|
384
|
+
const protocol = operation.callee.representation.protocol;
|
|
385
|
+
if (protocol === 'StringConstructor' || protocol === 'NumberConstructor' || protocol === 'BooleanConstructor') {
|
|
386
|
+
for (const argument of operation.arguments) {
|
|
387
|
+
for (const scope of receiverClassScopes(argument.representation, structuralViewScopes)) {
|
|
388
|
+
spelledKeys.add(`${scope}#toString`);
|
|
389
|
+
spelledKeys.add(`${scope}#valueOf`);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
for (const operand of operandsOfIrOperation(operation))
|
|
395
|
+
carriers.push(operand.representation);
|
|
396
|
+
const result = resultOfIrOperation(operation);
|
|
397
|
+
if (result)
|
|
398
|
+
carriers.push(result.representation);
|
|
399
|
+
}
|
|
400
|
+
return {
|
|
401
|
+
kept,
|
|
402
|
+
readCells,
|
|
403
|
+
citedFunctions,
|
|
404
|
+
carriers,
|
|
405
|
+
spelledKeys,
|
|
406
|
+
fieldHazardScopes,
|
|
407
|
+
computedMemberHazards,
|
|
408
|
+
construction: { constructors, classes: constructedClasses, evaluated: evaluatedClasses, open: openConstruction }
|
|
409
|
+
};
|
|
410
|
+
};
|
|
411
|
+
/**
|
|
412
|
+
* Carriers a `[[Get]]` on which can never name a class-layout member.
|
|
413
|
+
*
|
|
414
|
+
* The point of the list is that a key spelled on one of these roots NOTHING:
|
|
415
|
+
* `text` read off a `string`, an `array-object`, a `dictionary` or a callable
|
|
416
|
+
* is a prototype member or an element, never a member some class declares. A
|
|
417
|
+
* kind NOT listed here is treated as possibly-a-class and roots the key
|
|
418
|
+
* globally. `constructor-family` is handled explicitly below: its member list
|
|
419
|
+
* names the exact class objects a static access can reach.
|
|
420
|
+
*
|
|
421
|
+
* The record kinds are neither: a class instance CAN be carried by value as a
|
|
422
|
+
* record (`representation/value-records.ts`), so a record receiver may well
|
|
423
|
+
* name a class member -- but only of the class whose instance carrier IS that
|
|
424
|
+
* record, which its `shapeId` identifies exactly. They get a shape scope
|
|
425
|
+
* instead, so a spread of a plain `Record<string, string>` stops rooting every
|
|
426
|
+
* field of every class in the program.
|
|
427
|
+
*
|
|
428
|
+
* The default is deliberately the conservative side: a kind added to the
|
|
429
|
+
* representation model later roots keys globally until someone states
|
|
430
|
+
* otherwise, which costs precision and never correctness.
|
|
431
|
+
*/
|
|
432
|
+
const nonClassReceiverKinds = new Set([
|
|
433
|
+
'array-buffer',
|
|
434
|
+
'array-object',
|
|
435
|
+
'data-view',
|
|
436
|
+
'dense-buffer',
|
|
437
|
+
'dictionary',
|
|
438
|
+
'function',
|
|
439
|
+
'function-family',
|
|
440
|
+
'function-value-dispatch',
|
|
441
|
+
'function-value-family',
|
|
442
|
+
'iterator',
|
|
443
|
+
'keyed-collection',
|
|
444
|
+
'native-sequence',
|
|
445
|
+
'null',
|
|
446
|
+
'promise',
|
|
447
|
+
'scalar',
|
|
448
|
+
'string',
|
|
449
|
+
'symbol',
|
|
450
|
+
'typed-array',
|
|
451
|
+
'undefined',
|
|
452
|
+
'void'
|
|
453
|
+
]);
|
|
454
|
+
/** The scope a globally-spelled key is filed under: one that could name a member of any class. */
|
|
455
|
+
const anyClassScope = '*';
|
|
456
|
+
/**
|
|
457
|
+
* The scope a key spelled on a record receiver is filed under.
|
|
458
|
+
*
|
|
459
|
+
* Namespaced away from `DeclarationId` so a shape can never collide with a
|
|
460
|
+
* declaration: the two are matched up in `inheritanceScopesOf`, which files a
|
|
461
|
+
* class under the shape of its own instance carrier as well as its declaration.
|
|
462
|
+
*/
|
|
463
|
+
const shapeScope = (shapeId) => `shape#${shapeId}`;
|
|
464
|
+
/**
|
|
465
|
+
* Which classes a key spelled on this receiver can name a member of.
|
|
466
|
+
*
|
|
467
|
+
* `c.text('hi')` and `response.text()` spell one key and mean two members of
|
|
468
|
+
* two unrelated classes, and filing the key without its receiver made either
|
|
469
|
+
* one keep the other. hono is where that stops being academic: `Response#text`
|
|
470
|
+
* is reached on the app's own reply path, and filing `text` globally kept
|
|
471
|
+
* `HonoRequest#text` -- and with it `#cachedBody`, `JSON.stringify` of a
|
|
472
|
+
* `BodyInit`, and a refusal in a body nothing runs.
|
|
473
|
+
*
|
|
474
|
+
* A `class-ref` names its class exactly, and a record names whichever class
|
|
475
|
+
* that shape is the instance carrier of. A wrapper is walked through. Anything
|
|
476
|
+
* else is `anyClassScope` unless `nonClassReceiverKinds` says it can name no
|
|
477
|
+
* class member at all -- see that set's own doc for why the default is the
|
|
478
|
+
* conservative one.
|
|
479
|
+
*/
|
|
480
|
+
const receiverClassScopes = (representation, structuralViewScopes) => {
|
|
481
|
+
switch (representation.kind) {
|
|
482
|
+
case 'class-ref':
|
|
483
|
+
return [representation.declaration, shapeScope(representation.shapeId)];
|
|
484
|
+
case 'constructor-family':
|
|
485
|
+
return representation.members;
|
|
486
|
+
case 'record':
|
|
487
|
+
case 'record-with-index':
|
|
488
|
+
case 'native-record-ref':
|
|
489
|
+
return [shapeScope(representation.shapeId), ...(structuralViewScopes.get(representation.shapeId) ?? [])];
|
|
490
|
+
case 'borrowed-ref':
|
|
491
|
+
return receiverClassScopes(representation.referent, structuralViewScopes);
|
|
492
|
+
case 'optional':
|
|
493
|
+
return receiverClassScopes(representation.payload, structuralViewScopes);
|
|
494
|
+
case 'tagged-union':
|
|
495
|
+
return representation.arms.flatMap((arm) => receiverClassScopes(arm.value, structuralViewScopes));
|
|
496
|
+
default:
|
|
497
|
+
return nonClassReceiverKinds.has(representation.kind) ? [] : [anyClassScope];
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
/**
|
|
501
|
+
* Class scopes whose methods can back each record-shaped interface carrier.
|
|
502
|
+
*
|
|
503
|
+
* A structural view stores receiver-bound class methods in a record. Calls
|
|
504
|
+
* through that record spell the INTERFACE shape, so ordinary receiver-scoped
|
|
505
|
+
* liveness cannot otherwise connect `Router#match` back to `SmartRouter`'s
|
|
506
|
+
* method body. Compute the connection from the same sealed class layouts and
|
|
507
|
+
* record carriers the pass already receives. Optional interface fields may be
|
|
508
|
+
* absent; every required data field or callable method must exist. This is a
|
|
509
|
+
* conservative reachability relation only: a false positive retains a body,
|
|
510
|
+
* while a missing relation would delete code the emitter is about to bind.
|
|
511
|
+
*/
|
|
512
|
+
const structuralViewScopesOf = (classes, deriver, bodies) => {
|
|
513
|
+
const targetShapes = new Set();
|
|
514
|
+
for (const body of bodies) {
|
|
515
|
+
for (const carrier of body.values.values()) {
|
|
516
|
+
if (carrier.kind === 'record' || carrier.kind === 'record-with-index' || carrier.kind === 'native-record-ref') {
|
|
517
|
+
targetShapes.add(carrier.shapeId);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
const inheritedKeys = (declaration) => {
|
|
522
|
+
const fields = new Set();
|
|
523
|
+
const methods = new Set();
|
|
524
|
+
const seen = new Set();
|
|
525
|
+
let current = declaration;
|
|
526
|
+
while (current !== null && !seen.has(current)) {
|
|
527
|
+
seen.add(current);
|
|
528
|
+
const layout = classes.get(current);
|
|
529
|
+
if (!layout)
|
|
530
|
+
break;
|
|
531
|
+
for (const field of layout.fields)
|
|
532
|
+
fields.add(field.key);
|
|
533
|
+
// An accessor satisfies a plain data field on the target exactly as
|
|
534
|
+
// storage does -- the view reads it by CALLING the getter
|
|
535
|
+
// (`conversion/record-view.ts`'s `class-accessor` read) -- so it belongs
|
|
536
|
+
// in the same set. Without it the only thing that reaches such a getter
|
|
537
|
+
// is a direct `obj.member` somewhere in the program, and a class whose
|
|
538
|
+
// members are read only through a structural view lost every one of
|
|
539
|
+
// them: `IncomingMessage.rawHeaders` is a getter, and pruning it left
|
|
540
|
+
// the view the emitter was about to build with no body to call.
|
|
541
|
+
for (const accessor of layout.accessors)
|
|
542
|
+
if (accessor.getter !== null)
|
|
543
|
+
fields.add(accessor.key);
|
|
544
|
+
for (const method of layout.methods)
|
|
545
|
+
if (method.callable !== null)
|
|
546
|
+
methods.add(method.key);
|
|
547
|
+
current = layout.base;
|
|
548
|
+
}
|
|
549
|
+
return { fields, methods };
|
|
550
|
+
};
|
|
551
|
+
const result = new Map();
|
|
552
|
+
for (const shapeId of targetShapes) {
|
|
553
|
+
const target = deriver.layoutOf(shapeId);
|
|
554
|
+
if (target.kind !== 'record' || target.accessors.length > 0)
|
|
555
|
+
continue;
|
|
556
|
+
const scopes = [];
|
|
557
|
+
for (const [declaration, layout] of classes) {
|
|
558
|
+
if (layout.instance?.kind !== 'class-ref' || layout.instance.ownership !== 'shared-refcount')
|
|
559
|
+
continue;
|
|
560
|
+
const keys = inheritedKeys(declaration);
|
|
561
|
+
const satisfied = target.fields.every((field) => !field.required ||
|
|
562
|
+
keys.fields.has(field.key) ||
|
|
563
|
+
(keys.methods.has(field.key) && 'abi' in field.value && field.value.abi.receiver === null && field.value.abi.restFrom === null));
|
|
564
|
+
if (satisfied)
|
|
565
|
+
scopes.push(declaration);
|
|
566
|
+
}
|
|
567
|
+
if (scopes.length > 0)
|
|
568
|
+
result.set(shapeId, scopes);
|
|
569
|
+
}
|
|
570
|
+
return result;
|
|
571
|
+
};
|
|
572
|
+
/**
|
|
573
|
+
* The member names the LANGUAGE can invoke without the program spelling one.
|
|
574
|
+
*
|
|
575
|
+
* `MemberReach` below decides a method is dead when nothing the program still
|
|
576
|
+
* runs names its key. That is only sound for keys a *program* has to write
|
|
577
|
+
* down, and the specification reserves a few it invokes itself:
|
|
578
|
+
*
|
|
579
|
+
* - `then`, which 27.2.5.4 makes the whole of what `await` and
|
|
580
|
+
* `PromiseResolve` do with a thenable.
|
|
581
|
+
* - `next`, `return` and `throw`, the iterator protocol's own methods
|
|
582
|
+
* (27.1.2), which `get-iterator`/`iterator-next`/`iterator-close` reach
|
|
583
|
+
* through a carrier rather than through a key operand.
|
|
584
|
+
*
|
|
585
|
+
* `toString` and `valueOf` are also language-invoked, but their receiver is
|
|
586
|
+
* present on the `convert`/`compute` operation that triggers coercion, so
|
|
587
|
+
* `sliceBody` roots them in that receiver's class scope. Keeping them here
|
|
588
|
+
* would retain those methods on every unrelated imported class.
|
|
589
|
+
*
|
|
590
|
+
* A SYMBOL-keyed member is not in this set and does not need to be: its
|
|
591
|
+
* layout key is `sym(<declaration>)` rather than a name, and
|
|
592
|
+
* `memberIsReachable` keeps every one of those unconditionally, because a
|
|
593
|
+
* well-known symbol member is reached through its protocol and never by a
|
|
594
|
+
* written name.
|
|
595
|
+
*/
|
|
596
|
+
const specificationInvokedKeys = new Set(['then', 'next', 'return', 'throw']);
|
|
597
|
+
/**
|
|
598
|
+
* Whether a member with this layout key survives.
|
|
599
|
+
*
|
|
600
|
+
* The key comes from the class projection, where a symbol-named member is
|
|
601
|
+
* spelled `sym(<declaration>)` (`semantics/model/structural-types.ts`'s
|
|
602
|
+
* `symbolPropertyKeyText`). Anything that is not a plain written name is kept:
|
|
603
|
+
* this pass compares against NAMES the program wrote, and a member with no
|
|
604
|
+
* name to compare is one it cannot rule out.
|
|
605
|
+
*/
|
|
606
|
+
const memberIsReachable = (reach, scopes, key) => specificationInvokedKeys.has(key) ||
|
|
607
|
+
key.startsWith('sym(') ||
|
|
608
|
+
reach.has(`${anyClassScope}#${key}`) ||
|
|
609
|
+
scopes.some((scope) => reach.has(`${scope}#${key}`));
|
|
610
|
+
/**
|
|
611
|
+
* The classes a member key has to be rooted across together.
|
|
612
|
+
*
|
|
613
|
+
* A key spelled on a receiver of class `D` cannot be answered by `D` alone.
|
|
614
|
+
* An INHERITED member is declared on a base, so the key has to reach upward;
|
|
615
|
+
* and a virtual dispatch through a base-typed receiver runs a DERIVED
|
|
616
|
+
* override, so it has to reach downward too. Those are two directed walks,
|
|
617
|
+
* not an undirected component: sibling classes cannot answer one another's
|
|
618
|
+
* dispatch. BSON has many siblings below `BSONValue`; treating the hierarchy
|
|
619
|
+
* as one component made using `ObjectId#toString` retain Decimal128's whole
|
|
620
|
+
* conversion implementation as though a runtime ObjectId could be one.
|
|
621
|
+
*/
|
|
622
|
+
const inheritanceScopesOf = (classes) => {
|
|
623
|
+
const children = new Map();
|
|
624
|
+
for (const [declaration, layout] of classes) {
|
|
625
|
+
if (layout.base === null)
|
|
626
|
+
continue;
|
|
627
|
+
children.set(layout.base, [...(children.get(layout.base) ?? []), declaration]);
|
|
628
|
+
}
|
|
629
|
+
const scopes = new Map();
|
|
630
|
+
for (const declaration of classes.keys()) {
|
|
631
|
+
const related = new Set([declaration]);
|
|
632
|
+
let base = classes.get(declaration)?.base ?? null;
|
|
633
|
+
while (base !== null && !related.has(base)) {
|
|
634
|
+
related.add(base);
|
|
635
|
+
base = classes.get(base)?.base ?? null;
|
|
636
|
+
}
|
|
637
|
+
const pending = [...(children.get(declaration) ?? [])];
|
|
638
|
+
for (let child = pending.pop(); child !== undefined; child = pending.pop()) {
|
|
639
|
+
if (related.has(child))
|
|
640
|
+
continue;
|
|
641
|
+
related.add(child);
|
|
642
|
+
pending.push(...(children.get(child) ?? []));
|
|
643
|
+
}
|
|
644
|
+
// A class is filed under its own instance shape too, so a key spelled on a
|
|
645
|
+
// by-value copy of it reaches the same layout the `class-ref` spelling does.
|
|
646
|
+
const members = [...related];
|
|
647
|
+
const shapes = members.flatMap((member) => {
|
|
648
|
+
const instance = classes.get(member)?.instance;
|
|
649
|
+
return instance !== null && instance !== undefined && 'shapeId' in instance ? [shapeScope(instance.shapeId)] : [];
|
|
650
|
+
});
|
|
651
|
+
scopes.set(declaration, [...members, ...shapes]);
|
|
652
|
+
}
|
|
653
|
+
return scopes;
|
|
654
|
+
};
|
|
655
|
+
/**
|
|
656
|
+
* Whether a FIELD's initializer still has to run.
|
|
657
|
+
*
|
|
658
|
+
* A field is harder to rule out than a method, because a method is only ever
|
|
659
|
+
* reached by a key and a field is not. The struct's own field dispatcher
|
|
660
|
+
* (`records.ts`'s `renderFieldDispatcher`) addresses `layout.fields` by
|
|
661
|
+
* RUNTIME key, and `gea_ownFieldKeys` hands the same list to a spread or a
|
|
662
|
+
* `for`-`in`, so a computed access or an enumeration reaches a field nothing
|
|
663
|
+
* ever spelled. Those are the two hazards, and they are recorded per receiver
|
|
664
|
+
* scope by `sliceBody` -- so an enumeration of one class does not pin the
|
|
665
|
+
* fields of an unrelated one.
|
|
666
|
+
*
|
|
667
|
+
* The other half is EFFECTS. Eliding a method body elides a call nothing
|
|
668
|
+
* makes; eliding a field initializer elides work a construction performs
|
|
669
|
+
* unconditionally, so it is only sound for an initializer that does nothing
|
|
670
|
+
* but produce a value. `effectFree` is that: every operation in its body is
|
|
671
|
+
* `pure` -- an allocation, a constant, a read, a conversion -- with no store,
|
|
672
|
+
* no call, and no cell write. hono's are exactly this shape: `#cachedBody =
|
|
673
|
+
* (key) => { ... }` and `html = (c, ...) => ...` allocate a closure and return
|
|
674
|
+
* it.
|
|
675
|
+
*
|
|
676
|
+
* What an elided initializer leaves behind is a member C++ default-constructs,
|
|
677
|
+
* because the struct member itself is rendered from the class's SHAPE and not
|
|
678
|
+
* from this layout (`records.ts`'s `recordLayoutOfShape`). That is the same
|
|
679
|
+
* state a field declared with no initializer at all is already in today, which
|
|
680
|
+
* is why it is acceptable here: nothing spells the key, and the two hazards
|
|
681
|
+
* that could reach it without spelling it are what this predicate rules out.
|
|
682
|
+
*/
|
|
683
|
+
const fieldInitializerRuns = (field, scopes, reach, hazards, effectFree) => {
|
|
684
|
+
if (field.initializer === null)
|
|
685
|
+
return false;
|
|
686
|
+
if (memberIsReachable(reach, scopes, field.key))
|
|
687
|
+
return true;
|
|
688
|
+
if (hazards.has(anyClassScope) || scopes.some((scope) => hazards.has(scope)))
|
|
689
|
+
return true;
|
|
690
|
+
return !effectFree.has(field.initializer);
|
|
691
|
+
};
|
|
692
|
+
/**
|
|
693
|
+
* Every body a class layout names that the program can still reach.
|
|
694
|
+
*
|
|
695
|
+
* The constructor and the INSTANCE field initializers are the construction's
|
|
696
|
+
* own work, so they are rooted exactly when something constructs this class --
|
|
697
|
+
* see `ConstructionDemand` for what counts as something. They used to be
|
|
698
|
+
* unconditional, on the reasoning that "a construction runs the constructor";
|
|
699
|
+
* that is true and was never checked, and a class the program only declares
|
|
700
|
+
* kept its whole constructor, its `super(...)` chain, and everything those
|
|
701
|
+
* reach. The STATIC field initializers are not construction work at all: they
|
|
702
|
+
* run at class evaluation, so they keep the older, observability-only rule.
|
|
703
|
+
*
|
|
704
|
+
* Methods and accessors are the members a dispatch has to name, and
|
|
705
|
+
* `MemberReach` is what says whether anything does. Fields are the third case
|
|
706
|
+
* and the hardest -- see `fieldInitializerRuns`.
|
|
707
|
+
*/
|
|
708
|
+
const bodiesOfClass = (layout, scopes, reach, hazards, computedMemberHazards, computedMethodCanFill, effectFree, constructed) => [
|
|
709
|
+
...(constructed && layout.constructor ? [layout.constructor] : []),
|
|
710
|
+
...layout.fields.flatMap((field) => constructed && field.initializer && fieldInitializerRuns(field, scopes, reach, hazards, effectFree) ? [field.initializer] : []),
|
|
711
|
+
...layout.staticFields.flatMap((field) => field.initializer && fieldInitializerRuns(field, scopes, reach, hazards, effectFree) ? [field.initializer] : []),
|
|
712
|
+
...layout.methods.flatMap((method) => method.callable &&
|
|
713
|
+
(memberIsReachable(reach, scopes, method.key) ||
|
|
714
|
+
[anyClassScope, ...scopes]
|
|
715
|
+
.flatMap((scope) => computedMemberHazards.get(scope) ?? [])
|
|
716
|
+
.some((target) => computedMethodCanFill(method.callable, target)))
|
|
717
|
+
? [method.callable]
|
|
718
|
+
: []),
|
|
719
|
+
// A computed `[[Get]]` on the constructor object (`C[String(k)]`) is a
|
|
720
|
+
// dispatch over every static member the class declares
|
|
721
|
+
// (`emit-dynamic-properties.ts`'s `constructorFamilyComputedGetText`), so
|
|
722
|
+
// the same hazard that keeps instance methods keeps the static ones -- and
|
|
723
|
+
// the static accessors, whose getter that dispatch calls by name.
|
|
724
|
+
...layout.staticMethods.flatMap((method) => method.callable &&
|
|
725
|
+
(memberIsReachable(reach, scopes, method.key) ||
|
|
726
|
+
[anyClassScope, ...scopes]
|
|
727
|
+
.flatMap((scope) => computedMemberHazards.get(scope) ?? [])
|
|
728
|
+
.some((target) => computedMethodCanFill(method.callable, target)))
|
|
729
|
+
? [method.callable]
|
|
730
|
+
: []),
|
|
731
|
+
...layout.accessors.flatMap((accessor) => memberIsReachable(reach, scopes, accessor.key)
|
|
732
|
+
? [...(accessor.getter ? [accessor.getter] : []), ...(accessor.setter ? [accessor.setter] : [])]
|
|
733
|
+
: []),
|
|
734
|
+
...layout.staticAccessors.flatMap((accessor) => memberIsReachable(reach, scopes, accessor.key) ||
|
|
735
|
+
[anyClassScope, ...scopes].some((scope) => (computedMemberHazards.get(scope) ?? []).length > 0)
|
|
736
|
+
? [...(accessor.getter ? [accessor.getter] : []), ...(accessor.setter ? [accessor.setter] : [])]
|
|
737
|
+
: [])
|
|
738
|
+
];
|
|
739
|
+
/**
|
|
740
|
+
* The layout with the members this pass dropped taken out of it.
|
|
741
|
+
*
|
|
742
|
+
* Emission renders a class's methods and accessors from its LAYOUT, not from
|
|
743
|
+
* the surviving body list (`targets/cpp/translation-unit.ts`,
|
|
744
|
+
* `virtual-methods.ts`, `emit-tostring.ts`), so a layout that still declares a
|
|
745
|
+
* member whose body is gone is a declaration with no definition -- the one
|
|
746
|
+
* failure mode this pass promises never to produce.
|
|
747
|
+
*
|
|
748
|
+
* So the layout is pruned against LIVENESS, not against the name set that
|
|
749
|
+
* roots it. `memberIsReachable` is one of several things that make a member's
|
|
750
|
+
* body live -- a bound-method reference reaches it as a cited callable, an
|
|
751
|
+
* accessor is reached through its carrier by `accessorBodiesOf` -- and a
|
|
752
|
+
* member kept by any of those has to stay declared. Asking `liveOwners` is
|
|
753
|
+
* asking the union of all of them, which is exactly the question "does this
|
|
754
|
+
* member still have a definition". A member with no callable at all is kept:
|
|
755
|
+
* there is no body to have dropped.
|
|
756
|
+
*/
|
|
757
|
+
const prunedClass = (layout, live, constructed) => {
|
|
758
|
+
const bodyLives = (callable) => callable === null || callable === undefined || live.has(callable);
|
|
759
|
+
const field = (entry) => (bodyLives(entry.initializer) ? entry : { ...entry, initializer: null });
|
|
760
|
+
return {
|
|
761
|
+
...layout,
|
|
762
|
+
// `layoutOnly` is the target's existing word for "this class is a type here,
|
|
763
|
+
// not a thing anything makes" (`projection/classes.ts`), and it is what
|
|
764
|
+
// `runtimeClassLayoutsOf` filters `[[Construct]]` rendering by. Saying it
|
|
765
|
+
// here is not a second mechanism: dropping the constructor body while the
|
|
766
|
+
// layout still named it would leave `translation-unit.ts`'s construct
|
|
767
|
+
// function calling a definition this pass deleted -- the one failure mode
|
|
768
|
+
// this pass promises never to produce -- and refusing that construction
|
|
769
|
+
// would report a diagnostic for a class nothing constructs. Both halves of
|
|
770
|
+
// the answer have to be the same fact, stated once.
|
|
771
|
+
...(constructed ? {} : { layoutOnly: true }),
|
|
772
|
+
fields: layout.fields.map(field),
|
|
773
|
+
staticFields: layout.staticFields.map(field),
|
|
774
|
+
methods: layout.methods.filter((method) => bodyLives(method.callable)),
|
|
775
|
+
accessors: layout.accessors.filter((accessor) => bodyLives(accessor.getter) && bodyLives(accessor.setter)),
|
|
776
|
+
staticMethods: layout.staticMethods.filter((method) => bodyLives(method.callable)),
|
|
777
|
+
staticAccessors: layout.staticAccessors.filter((accessor) => bodyLives(accessor.getter) && bodyLives(accessor.setter))
|
|
778
|
+
};
|
|
779
|
+
};
|
|
780
|
+
/**
|
|
781
|
+
* Every body an accessor-backed member of one carrier names.
|
|
782
|
+
*
|
|
783
|
+
* A `record` carries its accessors inline; a `native-record-ref` names a shape
|
|
784
|
+
* whose carrier the deriver resolves -- the same two answers `records.ts` asks
|
|
785
|
+
* for at the call site, asked here through the same deriver so the two cannot
|
|
786
|
+
* disagree about what a shape's members are.
|
|
787
|
+
*/
|
|
788
|
+
const accessorBodiesOf = (representation, deriver) => {
|
|
789
|
+
const resolved = representation.kind === 'native-record-ref' ? deriver.layoutOf(representation.shapeId) : representation;
|
|
790
|
+
if (resolved.kind !== 'record')
|
|
791
|
+
return [];
|
|
792
|
+
return resolved.accessors.flatMap((accessor) => [
|
|
793
|
+
...(accessor.getter ? [accessor.getter] : []),
|
|
794
|
+
...(accessor.setter ? [accessor.setter] : [])
|
|
795
|
+
]);
|
|
796
|
+
};
|
|
797
|
+
/** Rebuild one body from the operations its slice kept. Blocks and terminators are untouched; only the sequences shrink. */
|
|
798
|
+
const prunedBody = (body, slice) => {
|
|
799
|
+
const blocks = new Map();
|
|
800
|
+
const values = new Map();
|
|
801
|
+
for (const blockId of body.blockOrder) {
|
|
802
|
+
const block = body.blocks.get(blockId);
|
|
803
|
+
if (!block)
|
|
804
|
+
continue;
|
|
805
|
+
const operations = block.operations.filter((operation) => slice.kept.has(operation));
|
|
806
|
+
blocks.set(blockId, { id: block.id, operations, terminator: block.terminator });
|
|
807
|
+
for (const operation of [...operations, block.terminator]) {
|
|
808
|
+
const result = resultOfIrOperation(operation);
|
|
809
|
+
// The index is derived from the definitions that survive: an entry for a
|
|
810
|
+
// value nothing defines any more is exactly what `valuesIndexGuard`
|
|
811
|
+
// refuses, and rightly.
|
|
812
|
+
if (result)
|
|
813
|
+
values.set(result.id, result.representation);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
return { ...body, blocks, values };
|
|
817
|
+
};
|
|
818
|
+
export const shakeProgram = (input) => {
|
|
819
|
+
const structuralViewScopes = structuralViewScopesOf(input.classes, input.deriver, input.bodies.values());
|
|
820
|
+
const bodiesByOwner = new Map();
|
|
821
|
+
const writersOfCell = new Map();
|
|
822
|
+
for (const body of input.bodies.values()) {
|
|
823
|
+
const existing = bodiesByOwner.get(body.sourceOwner);
|
|
824
|
+
if (existing)
|
|
825
|
+
existing.push(body);
|
|
826
|
+
else
|
|
827
|
+
bodiesByOwner.set(body.sourceOwner, [body]);
|
|
828
|
+
for (const blockId of body.blockOrder) {
|
|
829
|
+
const block = body.blocks.get(blockId);
|
|
830
|
+
if (!block)
|
|
831
|
+
continue;
|
|
832
|
+
for (const operation of block.operations) {
|
|
833
|
+
if (operation.kind !== 'binding-write')
|
|
834
|
+
continue;
|
|
835
|
+
const writers = writersOfCell.get(operation.declaration);
|
|
836
|
+
if (writers)
|
|
837
|
+
writers.add(body.sourceOwner);
|
|
838
|
+
else
|
|
839
|
+
writersOfCell.set(operation.declaration, new Set([body.sourceOwner]));
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
const liveOwners = new Set();
|
|
844
|
+
const queue = [];
|
|
845
|
+
const reach = (owner) => {
|
|
846
|
+
if (liveOwners.has(owner))
|
|
847
|
+
return;
|
|
848
|
+
liveOwners.add(owner);
|
|
849
|
+
queue.push(owner);
|
|
850
|
+
};
|
|
851
|
+
// A region runs because something structural runs it -- the entry calls each
|
|
852
|
+
// module body in the frontend's order, a construction calls each field
|
|
853
|
+
// initializer -- and neither is an operation in any body. So every region is
|
|
854
|
+
// a root, and only functions are subject to reachability.
|
|
855
|
+
for (const body of input.bodies.values())
|
|
856
|
+
if (isRegionId(body.sourceOwner))
|
|
857
|
+
reach(body.sourceOwner);
|
|
858
|
+
// The member names the program still spells, grown by the walk below. A
|
|
859
|
+
// class member is rooted the moment its key enters this set, and never
|
|
860
|
+
// before -- see `MemberReach`.
|
|
861
|
+
const liveKeys = new Set();
|
|
862
|
+
// A construction runs a class's constructor and its field initializers
|
|
863
|
+
// whatever else the program does, so those are roots on the same footing as
|
|
864
|
+
// a region. The MEMBERS are not, and `rootReachableMembers` is what admits
|
|
865
|
+
// them as their keys become live.
|
|
866
|
+
const scopesOfClass = inheritanceScopesOf(input.classes);
|
|
867
|
+
// The scopes whose fields something reaches without naming them, grown by the
|
|
868
|
+
// walk below exactly as `liveKeys` is -- and read off KEPT operations for the
|
|
869
|
+
// same reason: an enumeration inside a body this pass goes on to drop is not
|
|
870
|
+
// a fact about the program that runs.
|
|
871
|
+
const fieldHazards = new Set();
|
|
872
|
+
const computedMemberHazards = new Map();
|
|
873
|
+
// Which bodies do nothing but produce a value. Computed once over every body
|
|
874
|
+
// rather than per lookup: it is a property of the body alone, not of what is
|
|
875
|
+
// live, so it cannot change as the fixpoint widens.
|
|
876
|
+
const effectFree = new Set();
|
|
877
|
+
for (const [owner, bodies] of bodiesByOwner) {
|
|
878
|
+
const pure = bodies.every((body) => body.blockOrder.every((blockId) => (body.blocks.get(blockId)?.operations ?? []).every((operation) => effectOf(operation) === 'pure')));
|
|
879
|
+
if (pure)
|
|
880
|
+
effectFree.add(owner);
|
|
881
|
+
}
|
|
882
|
+
// Which classes something can construct, grown by the walk below exactly as
|
|
883
|
+
// `liveKeys` is. `constructorOwners` inverts the layouts once so a target
|
|
884
|
+
// proof naming a written constructor's `FunctionId` lands on the class that
|
|
885
|
+
// owns it.
|
|
886
|
+
const constructorOwners = new Map();
|
|
887
|
+
for (const [declaration, layout] of input.classes)
|
|
888
|
+
if (layout.constructor !== null)
|
|
889
|
+
constructorOwners.set(layout.constructor, declaration);
|
|
890
|
+
const constructible = new Set();
|
|
891
|
+
let anyConstruction = false;
|
|
892
|
+
// `super(...)` runs the base's initialization, and so does the implicit
|
|
893
|
+
// constructor of a class that writes none, so constructing a class demands
|
|
894
|
+
// its whole base chain. Downward is NOT implied: a base being constructed
|
|
895
|
+
// says nothing about its subclasses.
|
|
896
|
+
const demandConstruction = (declaration) => {
|
|
897
|
+
let fresh = false;
|
|
898
|
+
for (let current = declaration; current !== null && !constructible.has(current);) {
|
|
899
|
+
constructible.add(current);
|
|
900
|
+
fresh = true;
|
|
901
|
+
current = input.classes.get(current)?.base ?? null;
|
|
902
|
+
}
|
|
903
|
+
return fresh;
|
|
904
|
+
};
|
|
905
|
+
const admitConstruction = (demand) => {
|
|
906
|
+
let fresh = false;
|
|
907
|
+
if (demand.open && !anyConstruction) {
|
|
908
|
+
anyConstruction = true;
|
|
909
|
+
fresh = true;
|
|
910
|
+
}
|
|
911
|
+
for (const constructorId of demand.constructors) {
|
|
912
|
+
const owner = constructorOwners.get(constructorId);
|
|
913
|
+
// A constructable target that owns no class layout is an ordinary
|
|
914
|
+
// function used with `new`, which this demand has no say over: its body
|
|
915
|
+
// is reached as a callee like any other.
|
|
916
|
+
if (owner !== undefined && demandConstruction(owner))
|
|
917
|
+
fresh = true;
|
|
918
|
+
}
|
|
919
|
+
for (const declaration of [...demand.classes, ...demand.evaluated])
|
|
920
|
+
if (demandConstruction(declaration))
|
|
921
|
+
fresh = true;
|
|
922
|
+
return fresh;
|
|
923
|
+
};
|
|
924
|
+
const isConstructible = (declaration) => anyConstruction || constructible.has(declaration);
|
|
925
|
+
const rootReachableMembers = () => {
|
|
926
|
+
for (const [declaration, layout] of input.classes) {
|
|
927
|
+
const scopes = scopesOfClass.get(declaration) ?? [declaration];
|
|
928
|
+
for (const owner of bodiesOfClass(layout, scopes, liveKeys, fieldHazards, computedMemberHazards, input.computedMethodCanFill, effectFree, isConstructible(declaration)))
|
|
929
|
+
reach(owner);
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
rootReachableMembers();
|
|
933
|
+
const liveCells = new Set();
|
|
934
|
+
const slices = new Map();
|
|
935
|
+
for (let owner = queue.pop(); owner !== undefined; owner = queue.pop()) {
|
|
936
|
+
const freshCells = [];
|
|
937
|
+
let freshKeys = false;
|
|
938
|
+
for (const body of bodiesByOwner.get(owner) ?? []) {
|
|
939
|
+
const slice = sliceBody(body, input.placements, liveCells, structuralViewScopes);
|
|
940
|
+
slices.set(body.owner, slice);
|
|
941
|
+
for (const cell of slice.readCells) {
|
|
942
|
+
if (liveCells.has(cell))
|
|
943
|
+
continue;
|
|
944
|
+
liveCells.add(cell);
|
|
945
|
+
freshCells.push(cell);
|
|
946
|
+
}
|
|
947
|
+
for (const key of slice.spelledKeys) {
|
|
948
|
+
if (liveKeys.has(key))
|
|
949
|
+
continue;
|
|
950
|
+
liveKeys.add(key);
|
|
951
|
+
freshKeys = true;
|
|
952
|
+
}
|
|
953
|
+
for (const scope of slice.fieldHazardScopes) {
|
|
954
|
+
if (fieldHazards.has(scope))
|
|
955
|
+
continue;
|
|
956
|
+
fieldHazards.add(scope);
|
|
957
|
+
freshKeys = true;
|
|
958
|
+
}
|
|
959
|
+
for (const hazard of slice.computedMemberHazards) {
|
|
960
|
+
const targets = computedMemberHazards.get(hazard.scope) ?? [];
|
|
961
|
+
if (targets.some((target) => representationKey(target) === representationKey(hazard.target)))
|
|
962
|
+
continue;
|
|
963
|
+
computedMemberHazards.set(hazard.scope, [...targets, hazard.target]);
|
|
964
|
+
freshKeys = true;
|
|
965
|
+
}
|
|
966
|
+
if (admitConstruction(slice.construction))
|
|
967
|
+
freshKeys = true;
|
|
968
|
+
for (const cited of slice.citedFunctions) {
|
|
969
|
+
reach(cited);
|
|
970
|
+
}
|
|
971
|
+
for (const carrier of slice.carriers)
|
|
972
|
+
for (const accessor of accessorBodiesOf(carrier, input.deriver))
|
|
973
|
+
reach(accessor);
|
|
974
|
+
}
|
|
975
|
+
// A cell that has just become live turns every kept write to it live too,
|
|
976
|
+
// so each body that writes one is sliced again. Each cell crosses this line
|
|
977
|
+
// once, so the re-slicing is bounded by the number of writes in the program.
|
|
978
|
+
for (const cell of freshCells)
|
|
979
|
+
for (const writer of writersOfCell.get(cell) ?? [])
|
|
980
|
+
if (liveOwners.has(writer))
|
|
981
|
+
queue.push(writer);
|
|
982
|
+
// And a member name that has just become live turns the member that
|
|
983
|
+
// answers it live -- as does a class that has just become constructible,
|
|
984
|
+
// which is why `admitConstruction` reports into the same flag. Bounded the
|
|
985
|
+
// same way: a key, and a class, crosses this line once.
|
|
986
|
+
if (freshKeys)
|
|
987
|
+
rootReachableMembers();
|
|
988
|
+
}
|
|
989
|
+
// A body already sliced before a later slice made another cell live has a
|
|
990
|
+
// stale answer: `sliceBody` reads `liveCells` to decide whether a write to a
|
|
991
|
+
// cell survives. The loop above re-queues a writer when its cell becomes
|
|
992
|
+
// live, so every such body is sliced again -- but only if it was already a
|
|
993
|
+
// live owner at that moment. A body that became live afterwards is sliced
|
|
994
|
+
// once, with the final cell set, so it needs nothing. The keys are not
|
|
995
|
+
// subject to this at all: `spelledKeys` is read off the kept set, and
|
|
996
|
+
// keeping more can only add keys, never remove one.
|
|
997
|
+
const shaken = new Map();
|
|
998
|
+
const violations = [];
|
|
999
|
+
let droppedBodies = 0;
|
|
1000
|
+
let droppedOperations = 0;
|
|
1001
|
+
for (const [id, body] of input.bodies) {
|
|
1002
|
+
if (!liveOwners.has(body.sourceOwner)) {
|
|
1003
|
+
droppedBodies += 1;
|
|
1004
|
+
for (const blockId of body.blockOrder)
|
|
1005
|
+
droppedOperations += body.blocks.get(blockId)?.operations.length ?? 0;
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
const slice = slices.get(id);
|
|
1009
|
+
// A live owner always has a slice: `reach` is the only thing that makes an
|
|
1010
|
+
// owner live, and the loop above slices every body of every owner it makes
|
|
1011
|
+
// live before it can finish. An absent one means this pass lost a body it
|
|
1012
|
+
// is about to prune around, so the whole shake is abandoned rather than
|
|
1013
|
+
// guessed at -- keeping this body whole would leave it citing callables the
|
|
1014
|
+
// rest of the pass has already decided to drop.
|
|
1015
|
+
if (!slice) {
|
|
1016
|
+
return {
|
|
1017
|
+
bodies: input.bodies,
|
|
1018
|
+
classes: input.classes,
|
|
1019
|
+
unreferencedCells: new Set(),
|
|
1020
|
+
droppedBodies: 0,
|
|
1021
|
+
droppedOperations: 0,
|
|
1022
|
+
refused: `body ${id} belongs to a reachable owner but was never sliced`
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
const pruned = prunedBody(body, slice);
|
|
1026
|
+
for (const blockId of body.blockOrder) {
|
|
1027
|
+
const before = body.blocks.get(blockId)?.operations.length ?? 0;
|
|
1028
|
+
droppedOperations += before - (pruned.blocks.get(blockId)?.operations.length ?? before);
|
|
1029
|
+
}
|
|
1030
|
+
violations.push(...verifyIrBody(pruned));
|
|
1031
|
+
shaken.set(id, pruned);
|
|
1032
|
+
}
|
|
1033
|
+
if (violations.length > 0) {
|
|
1034
|
+
const first = violations[0];
|
|
1035
|
+
return {
|
|
1036
|
+
bodies: input.bodies,
|
|
1037
|
+
classes: input.classes,
|
|
1038
|
+
unreferencedCells: new Set(),
|
|
1039
|
+
droppedBodies: 0,
|
|
1040
|
+
droppedOperations: 0,
|
|
1041
|
+
refused: `shaken IR failed verification (${violations.length} violation(s)); first: ${first ? `${first.guard}: ${first.message}` : 'unknown'}`
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
// A region cell the shaken program never names needs no file-scope variable.
|
|
1045
|
+
// Decided from the SURVIVING operations rather than from `liveCells`, so a
|
|
1046
|
+
// cell a kept write still targets keeps its storage whatever the liveness
|
|
1047
|
+
// fixpoint concluded about reads.
|
|
1048
|
+
const named = new Set();
|
|
1049
|
+
for (const body of shaken.values()) {
|
|
1050
|
+
for (const blockId of body.blockOrder) {
|
|
1051
|
+
const block = body.blocks.get(blockId);
|
|
1052
|
+
if (!block)
|
|
1053
|
+
continue;
|
|
1054
|
+
for (const operation of allOperationsOf(block)) {
|
|
1055
|
+
if (operation.kind === 'binding-read' || operation.kind === 'binding-write')
|
|
1056
|
+
named.add(operation.declaration);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
const unreferencedCells = new Set();
|
|
1061
|
+
for (const [declaration, placement] of input.placements) {
|
|
1062
|
+
if (placement.storage.kind !== 'region' || named.has(declaration))
|
|
1063
|
+
continue;
|
|
1064
|
+
unreferencedCells.add(declaration);
|
|
1065
|
+
}
|
|
1066
|
+
const prunedClasses = new Map();
|
|
1067
|
+
// Which classes survived as constructible, and how many did not. The answer
|
|
1068
|
+
// is one line per class and the question is only asked while sizing a binary,
|
|
1069
|
+
// so it is env-gated rather than carried in the result.
|
|
1070
|
+
if (process.env['GEA_SHAKE_DEBUG'])
|
|
1071
|
+
console.log(`[SHAKE] construction open=${anyConstruction} constructible=${constructible.size}/${input.classes.size}`);
|
|
1072
|
+
for (const [declaration, layout] of input.classes) {
|
|
1073
|
+
if (process.env['GEA_SHAKE_DEBUG'] && !isConstructible(declaration))
|
|
1074
|
+
console.log(`[SHAKE] not constructed: ${declaration}`);
|
|
1075
|
+
prunedClasses.set(declaration, prunedClass(layout, liveOwners, isConstructible(declaration)));
|
|
1076
|
+
}
|
|
1077
|
+
return { bodies: shaken, classes: prunedClasses, unreferencedCells, droppedBodies, droppedOperations, refused: null };
|
|
1078
|
+
};
|