@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
|
@@ -0,0 +1,1249 @@
|
|
|
1
|
+
import { representationKey } from '../../representation/model.js';
|
|
2
|
+
import { isNativeCallableCarrier } from '../../representation/callable-object.js';
|
|
3
|
+
import { createCppEmitBlockedError, defineValue, operandText } from './emit-context.js';
|
|
4
|
+
import { cppAbiParameterType, cppRecordFieldName, cppResultTypeOf, cppStringLiteral, cppTypeOf } from './types.js';
|
|
5
|
+
import { intrinsicMemberValueOf } from './host/emit-host-object.js';
|
|
6
|
+
import { toStringText } from './emit-tostring.js';
|
|
7
|
+
import { alignedValueText, dynamicCarrierBoxText, dynamicTagFor, recipeText, unboxedLoadText, widenedStoreText } from './emit-narrowing.js';
|
|
8
|
+
import { dictionaryTableOf } from './emit-properties.js';
|
|
9
|
+
import { keyedTableKeyText, memberAccessOperator, recordIndexSidecarTableOf, recordIndexAttributeKeyText } from './emit-carrier-members.js';
|
|
10
|
+
import { declaredRecordFieldOf, recordFieldsOfShape, recordIndexesOfShape } from './records.js';
|
|
11
|
+
import { classStaticFieldStorageKeysOf, classMemberOf } from './class-layout.js';
|
|
12
|
+
import { classConstructorStaticMemberTextFor, computedClassPrototypeMethodText } from './class-properties/emit-class-properties.js';
|
|
13
|
+
import { hostMemberOf } from './host/host-members.js';
|
|
14
|
+
import { objectShapePrototypeMethods } from '../../projection/callee.js';
|
|
15
|
+
import { cppRegExpNativeTypes } from './regexp-types.js';
|
|
16
|
+
import { arrayPrototypeMethods } from './prototype/emit-prototype-array.js';
|
|
17
|
+
import { nativeAbsentPropertyReadOf } from '../../ir/native-absent-property.js';
|
|
18
|
+
/**
|
|
19
|
+
* Property access over a genuinely dynamic receiver, and over the dynamic
|
|
20
|
+
* half of a receiver that is otherwise native.
|
|
21
|
+
*
|
|
22
|
+
* Two situations, one machine. A value the program itself declared `any` or
|
|
23
|
+
* `unknown` and never narrowed is carried as `gea::Value`, and its properties
|
|
24
|
+
* live in the `gea::DynamicObject` that box owns -- that is a real dynamic
|
|
25
|
+
* boundary, one of the four `representation/model.ts` admits, and the honest
|
|
26
|
+
* answer for it is a real property table rather than a refusal. A value that
|
|
27
|
+
* DOES have a static type but is used dynamically (`(store as any)[key] = v`
|
|
28
|
+
* on a class instance) is the opposite case: its storage stays exactly the
|
|
29
|
+
* native struct it was, and the dynamic key goes into a `gea::DynamicObject`
|
|
30
|
+
* SIDECAR beside the declared fields. Boxing the receiver to make the write
|
|
31
|
+
* compile is the forbidden shortcut, and the sidecar is what makes refusing it
|
|
32
|
+
* cost nothing.
|
|
33
|
+
*
|
|
34
|
+
* The two share this file because they share every hard part: turning a key
|
|
35
|
+
* operand into a `gea::PropertyKey`, deciding what a read of an absent
|
|
36
|
+
* property produces, and reconciling a statically-typed value into a boxed
|
|
37
|
+
* slot on the way in. Splitting them would be two copies of one rule.
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* A key operand as a `gea::PropertyKey`.
|
|
41
|
+
*
|
|
42
|
+
* A key is a String or a Symbol and nothing else (ECMA-262 6.1.7), so this is
|
|
43
|
+
* a two-way decision plus the ToPropertyKey conversions that feed it. A
|
|
44
|
+
* constant key is already the canonical text the language's own
|
|
45
|
+
* ToPropertyKey would produce -- `producers/properties.ts` spells `o[0]` and
|
|
46
|
+
* `o["0"]` identically for exactly that reason -- so it renders as a literal
|
|
47
|
+
* with no runtime conversion at all.
|
|
48
|
+
*
|
|
49
|
+
* A numeric key converts through the same `toStringText` every other ToString
|
|
50
|
+
* in this backend goes through, because ToPropertyKey of a Number *is*
|
|
51
|
+
* ToString of it. A carrier that is neither string, symbol nor number is
|
|
52
|
+
* refused by name: `ToPropertyKey` on an arbitrary object runs `ToPrimitive`,
|
|
53
|
+
* which can call user code, and no such dispatch is installed.
|
|
54
|
+
*/
|
|
55
|
+
const propertyKeyCarrierText = (ctx, carrier, text, contextDescription) => {
|
|
56
|
+
if (carrier.kind === 'null' || carrier.kind === 'undefined') {
|
|
57
|
+
return `gea::PropertyKey::string(${cppStringLiteral(carrier.kind)})`;
|
|
58
|
+
}
|
|
59
|
+
if (carrier.kind === 'string')
|
|
60
|
+
return `gea::PropertyKey::string(${text})`;
|
|
61
|
+
if (carrier.kind === 'symbol')
|
|
62
|
+
return `gea::PropertyKey::symbol(${text})`;
|
|
63
|
+
if (carrier.kind === 'scalar') {
|
|
64
|
+
if (carrier.domain !== 'boolean' && carrier.domain !== 'bigint')
|
|
65
|
+
return `gea::PropertyKey::number(static_cast<double>(${text}))`;
|
|
66
|
+
const converted = toStringText(text, carrier, ctx.classes, ctx.deriver);
|
|
67
|
+
if (converted !== null)
|
|
68
|
+
return `gea::PropertyKey::string(${converted})`;
|
|
69
|
+
}
|
|
70
|
+
if (carrier.kind === 'optional') {
|
|
71
|
+
const present = propertyKeyCarrierText(ctx, carrier.payload, `(*${text})`, contextDescription);
|
|
72
|
+
return `(${text}.has_value() ? ${present} : ` + `gea::PropertyKey::string(${cppStringLiteral(carrier.absence)}))`;
|
|
73
|
+
}
|
|
74
|
+
if (carrier.kind === 'tagged-union') {
|
|
75
|
+
const arms = carrier.arms.map((arm, index) => propertyKeyCarrierText(ctx, arm.value, `${text}.get<${index}>()`, contextDescription));
|
|
76
|
+
const dispatched = arms.reduceRight((rest, arm, index) => (index === arms.length - 1 ? arm : `${text}.is<${index}>() ? ${arm} : (${rest})`), '');
|
|
77
|
+
if (dispatched !== '')
|
|
78
|
+
return arms.length > 1 ? `(${dispatched})` : dispatched;
|
|
79
|
+
}
|
|
80
|
+
// A BOXED key. ToPropertyKey's ToPrimitive step is the identity for every
|
|
81
|
+
// primitive a box can hold, and the box's own tag says which one it holds --
|
|
82
|
+
// so `gea::host::toPropertyKey` (gea_runtime.h) renders 7.1.19 exactly for
|
|
83
|
+
// those, and aborts by name for the one payload that genuinely needs the
|
|
84
|
+
// dispatch this backend has none of (an Object or Function, whose
|
|
85
|
+
// ToPrimitive calls user code). three's `uuid in _materialCache` and
|
|
86
|
+
// `u.id in values` are the shape: both operands are values the JS source
|
|
87
|
+
// never typed, and refusing the KEY refused the whole operator.
|
|
88
|
+
if (carrier.kind === 'dynamic')
|
|
89
|
+
return `gea::host::toPropertyKey(${text})`;
|
|
90
|
+
throw createCppEmitBlockedError(`runtime-helper:computation:to-property-key:${carrier.kind}`, `${contextDescription} is keyed by a "${carrier.kind}" carrier; ToPropertyKey over one runs ToPrimitive, which can call ` +
|
|
91
|
+
'user code, and no such dispatch is installed -- only string, symbol and numeric keys are rendered');
|
|
92
|
+
};
|
|
93
|
+
export const propertyKeyText = (ctx, key, contextDescription) => {
|
|
94
|
+
const staticKey = ctx.constantTexts.get(key.value);
|
|
95
|
+
if (staticKey !== undefined)
|
|
96
|
+
return `gea::PropertyKey::string(${cppStringLiteral(staticKey)})`;
|
|
97
|
+
return propertyKeyCarrierText(ctx, key.representation, operandText(ctx, key), contextDescription);
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* The head of a name-comparison chain over a RUNTIME key: declares the
|
|
101
|
+
* `std::string` the chain's `__gea_key == "..."` arms compare.
|
|
102
|
+
*
|
|
103
|
+
* A `string` carrier is that string outright. A `symbol`, a `string | symbol`
|
|
104
|
+
* union (test262's `verifyProperty(obj, name, ...)` carries `name` so, because
|
|
105
|
+
* it spells a symbol's description into its messages) or an optional of either
|
|
106
|
+
* goes through `gea::PropertyKey` first -- the one renderer that already
|
|
107
|
+
* dispatches every key carrier, so a carrier it refuses is refused here by the
|
|
108
|
+
* same name -- and a symbol answers `symbolAnswer` before the chain runs. That
|
|
109
|
+
* is the honest answer for every chain this heads: a record layout's fields,
|
|
110
|
+
* an intrinsic's classified member table and a builtin function's own
|
|
111
|
+
* `name`/`length` are string-keyed without exception, so no arm could ever
|
|
112
|
+
* match a symbol. (`Math[Symbol.toStringTag]` is real but the intrinsic table
|
|
113
|
+
* deliberately holds no symbol-keyed member -- see `hostIntrinsicMembersOf`.)
|
|
114
|
+
*/
|
|
115
|
+
export const stringKeyPreludeText = (ctx, key, contextDescription, symbolAnswer) => {
|
|
116
|
+
if (key.representation.kind === 'string')
|
|
117
|
+
return `const std::string& __gea_key = ${operandText(ctx, key)};`;
|
|
118
|
+
return (`const gea::PropertyKey __gea_property_key = ${propertyKeyText(ctx, key, contextDescription)}; ` +
|
|
119
|
+
`if (__gea_property_key.isSymbol()) return ${symbolAnswer}; const std::string& __gea_key = __gea_property_key.text();`);
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* The receiver expression a property table is reached through, or `null` when
|
|
123
|
+
* this receiver has no table at all.
|
|
124
|
+
*
|
|
125
|
+
* A `dynamic` receiver IS the table's owner: `gea::Value` carries the
|
|
126
|
+
* `DynamicObject` and answers the four internal methods directly. Every other
|
|
127
|
+
* carrier answers `null` here and is picked up by `nativeSidecarGetText` /
|
|
128
|
+
* `emitNativeSidecarSet` below instead, which reach the object's declared
|
|
129
|
+
* members through the field dispatcher `records.ts` renders and its
|
|
130
|
+
* undeclared ones through `gea::detail::expandoFor`. The split is the point:
|
|
131
|
+
* only a value the program itself declared dynamic is CARRIED as one.
|
|
132
|
+
*/
|
|
133
|
+
const dynamicReceiverText = (ctx, receiver) => receiver.representation.kind === 'dynamic' ? operandText(ctx, receiver) : null;
|
|
134
|
+
/**
|
|
135
|
+
* Reading a property of a genuinely dynamic receiver.
|
|
136
|
+
*
|
|
137
|
+
* The result of `[[Get]]` on a value whose type the program never stated is
|
|
138
|
+
* usually a value whose type the program never stated, and the box comes back
|
|
139
|
+
* as it is. But a narrowing can state one: `Array.isArray(v)` proves `v` is
|
|
140
|
+
* `any[]`, and `v.length` inside that branch is a `number` the checker really
|
|
141
|
+
* did settle. That result reads through the tag-checked unboxing load
|
|
142
|
+
* `convertedValueText` installs -- which ABORTS BY NAME on a box holding
|
|
143
|
+
* something else, rather than reinterpreting its bytes -- so the narrowing's
|
|
144
|
+
* claim is enforced at the read instead of assumed.
|
|
145
|
+
*
|
|
146
|
+
* A carrier that load has no answer for is still refused here rather than
|
|
147
|
+
* `static_cast`-ed into a plausible wrong answer.
|
|
148
|
+
*/
|
|
149
|
+
export const dynamicGetText = (ctx, operation) => {
|
|
150
|
+
const receiver = dynamicReceiverText(ctx, operation.receiver);
|
|
151
|
+
if (receiver === null)
|
|
152
|
+
return null;
|
|
153
|
+
const read = `${receiver}.getProperty(${propertyKeyText(ctx, operation.key, 'a "get" on a dynamic receiver')})`;
|
|
154
|
+
const produced = operation.result.representation;
|
|
155
|
+
if (produced.kind === 'dynamic')
|
|
156
|
+
return read;
|
|
157
|
+
// `read` is a call, not an already-materialized SSA name: on a Proxy
|
|
158
|
+
// receiver it invokes the trap, which is user code with its own
|
|
159
|
+
// observable effects (`log.push(...)` in the measured case). Every
|
|
160
|
+
// rendering path below this point -- `unboxedLoadText`'s `optional` case
|
|
161
|
+
// is the one that fired here -- assumes exactly the opposite, the same
|
|
162
|
+
// invariant `widenedStoreText` states in its own `dynamic` branch
|
|
163
|
+
// ("`text` is read once per arm ... `operandText` answers an
|
|
164
|
+
// already-materialized SSA name, never an expression with effects"), and
|
|
165
|
+
// freely substitutes its `text` argument more than once when a carrier
|
|
166
|
+
// needs both a presence test and a payload load (`tag() == Undefined ?
|
|
167
|
+
// ... : ...(unboxValue(text, ...))`). Handed the raw call, that duplicates
|
|
168
|
+
// the `[[Get]]` itself: one JS property read became two -- four for two
|
|
169
|
+
// reads -- invoking a Proxy `get` trap twice per access.
|
|
170
|
+
// Binding the call to a lambda PARAMETER evaluates it exactly once no
|
|
171
|
+
// matter how many times the converted text below repeats the parameter's
|
|
172
|
+
// name, the same fix `unboxedLoadText`'s own callable-ABI branch already
|
|
173
|
+
// uses for an unrelated case of this identical hazard.
|
|
174
|
+
const materialized = 'gea_get_result';
|
|
175
|
+
const converted = alignedValueText(ctx, 'emit-dynamic-properties.ts:170', { kind: 'dynamic', reason: 'declared-any-never-narrowed' }, produced, materialized);
|
|
176
|
+
if (converted !== null)
|
|
177
|
+
return `[](const gea::Value& ${materialized}) -> ${cppTypeOf(produced)} { return ${converted}; }(${read})`;
|
|
178
|
+
throw createCppEmitBlockedError(`conversion:${representationKey({ kind: 'dynamic', reason: 'declared-any-never-narrowed' })}->${representationKey(produced)}`, `a "get" on a dynamic receiver publishes a "${produced.kind}" carrier; unboxing a dynamic property read into a concrete ` +
|
|
179
|
+
'carrier needs a tag-checked conversion, which is not installed');
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* The value a store writes, reconciled against the boxed slot it lands in.
|
|
183
|
+
*
|
|
184
|
+
* This is the one direction the no-boxing rule permits, and it permits it
|
|
185
|
+
* because the DESTINATION is the dynamic thing: a property of an object the
|
|
186
|
+
* program declared `any` really does hold anything, so writing a `double` into
|
|
187
|
+
* one is a widening the language itself performs. `widenedStoreText` is the
|
|
188
|
+
* same reconciliation a binding cell and a struct member already use
|
|
189
|
+
* (`emit-narrowing.ts`), asked here for a slot rather than for a field, so
|
|
190
|
+
* there is one table of "which carrier boxes under which tag" and not two.
|
|
191
|
+
*
|
|
192
|
+
* A carrier `dynamicTagFor` has no tag for is refused by name -- an iterator,
|
|
193
|
+
* a promise, a proxy. Those are real gaps in the box, not values to guess a
|
|
194
|
+
* tag for.
|
|
195
|
+
*/
|
|
196
|
+
export const boxedValueText = (ctx, value, contextDescription) => {
|
|
197
|
+
const text = operandText(ctx, value);
|
|
198
|
+
if (value.representation.kind === 'dynamic')
|
|
199
|
+
return text;
|
|
200
|
+
const boxed = { kind: 'dynamic', reason: 'declared-any-never-narrowed' };
|
|
201
|
+
const widened = widenedStoreText(boxed, value.representation, text);
|
|
202
|
+
if (widened !== null)
|
|
203
|
+
return widened;
|
|
204
|
+
throw createCppEmitBlockedError(`conversion:${representationKey(value.representation)}->${representationKey(boxed)}`, `${contextDescription} writes a "${value.representation.kind}" carrier into a dynamic property, and this backend has no ` +
|
|
205
|
+
'box tag for that carrier');
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Writing a property of a genuinely dynamic receiver.
|
|
209
|
+
*
|
|
210
|
+
* The store's own result -- when the program reads one -- is the receiver
|
|
211
|
+
* threaded onward, exactly as a struct field store publishes the object it
|
|
212
|
+
* wrote into (`emit-properties.ts`'s `emitFieldStore`). A `[[Set]]` nominally
|
|
213
|
+
* returns a success boolean, but that boolean is only observable under strict
|
|
214
|
+
* mode's false-to-throw rule. `Value::reflectSet` is the existing runtime
|
|
215
|
+
* spelling that preserves that boolean; `Value::setProperty` deliberately
|
|
216
|
+
* discards it and is therefore only suitable for callers that have already
|
|
217
|
+
* chosen sloppy behavior. What a consumer of an assignment expression reads
|
|
218
|
+
* is still the assigned object.
|
|
219
|
+
*/
|
|
220
|
+
export const emitDynamicSet = (ctx, lines, operation) => {
|
|
221
|
+
const receiver = dynamicReceiverText(ctx, operation.receiver);
|
|
222
|
+
if (receiver === null)
|
|
223
|
+
return false;
|
|
224
|
+
const key = propertyKeyText(ctx, operation.key, 'a "set" on a dynamic receiver');
|
|
225
|
+
const set = `${receiver}.reflectSet(${key}, ${boxedValueText(ctx, operation.value, 'a "set" on a dynamic receiver')}, ${receiver})`;
|
|
226
|
+
if (operation.kind === 'set' && operation.strict) {
|
|
227
|
+
lines.push(`if (!${set}) gea::host::throwRuntimeError("TypeError", "Cannot assign to read-only property");`);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
lines.push(`(void)${set};`);
|
|
231
|
+
}
|
|
232
|
+
if (operation.result && operation.result.representation.kind !== 'void') {
|
|
233
|
+
lines.push(`${defineValue(ctx, operation.result)} = ${receiver};`);
|
|
234
|
+
}
|
|
235
|
+
return true;
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* `delete obj[k]` over a dynamic receiver.
|
|
239
|
+
*
|
|
240
|
+
* The operator's own result is the boolean `[[Delete]]` returns -- "the
|
|
241
|
+
* property is gone", which includes "was never there" -- so unlike `[[Set]]`
|
|
242
|
+
* this one really is published when the program reads it.
|
|
243
|
+
*/
|
|
244
|
+
/** Render the one [[Delete]] outcome, preserving strict-mode's false-to-throw rule. */
|
|
245
|
+
const emitDeleteOutcome = (ctx, lines, operation, outcome) => {
|
|
246
|
+
if (operation.result) {
|
|
247
|
+
const produced = operation.result.representation;
|
|
248
|
+
if (produced.kind !== 'scalar' || produced.domain !== 'boolean') {
|
|
249
|
+
throw createCppEmitBlockedError(`runtime-helper:computation:delete-result:${representationKey(produced)}`, `a "delete" publishes a "${produced.kind}" carrier; the operator's result is the boolean [[Delete]] returns and nothing else`);
|
|
250
|
+
}
|
|
251
|
+
const checked = operation.strict
|
|
252
|
+
? `([&]() -> bool { if (!(${outcome})) gea::host::throwRuntimeError("TypeError", "Cannot delete non-configurable property"); return true; })()`
|
|
253
|
+
: outcome;
|
|
254
|
+
lines.push(`${defineValue(ctx, operation.result)} = ${checked};`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (operation.strict) {
|
|
258
|
+
lines.push(`if (!(${outcome})) gea::host::throwRuntimeError("TypeError", "Cannot delete non-configurable property");`);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
lines.push(`${outcome};`);
|
|
262
|
+
};
|
|
263
|
+
export const emitDynamicDelete = (ctx, lines, operation) => {
|
|
264
|
+
const receiver = dynamicReceiverText(ctx, operation.receiver);
|
|
265
|
+
if (receiver === null)
|
|
266
|
+
return false;
|
|
267
|
+
const key = propertyKeyText(ctx, operation.key, 'a "delete" on a dynamic receiver');
|
|
268
|
+
const call = `${receiver}.deleteProperty(${key})`;
|
|
269
|
+
emitDeleteOutcome(ctx, lines, operation, call);
|
|
270
|
+
return true;
|
|
271
|
+
};
|
|
272
|
+
/** `k in obj` over a dynamic receiver -- ECMA-262 13.10.2, which is `[[HasProperty]]` including the prototype chain. */
|
|
273
|
+
export const emitDynamicHasProperty = (ctx, lines, operation) => {
|
|
274
|
+
const receiver = dynamicReceiverText(ctx, operation.receiver);
|
|
275
|
+
if (receiver === null)
|
|
276
|
+
return false;
|
|
277
|
+
const key = propertyKeyText(ctx, operation.key, 'an "in" test on a dynamic receiver');
|
|
278
|
+
lines.push(`${defineValue(ctx, operation.result)} = ${receiver}.hasProperty(${key});`);
|
|
279
|
+
return true;
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* `delete o.p` as an EXPRESSION.
|
|
283
|
+
*
|
|
284
|
+
* The removal itself is the `[[Delete]]` the property operation already
|
|
285
|
+
* performed; this computation is only the report of its outcome (ECMA-262
|
|
286
|
+
* 13.5.1.2 step 5), whose value is that operation's boolean result. So
|
|
287
|
+
* forwarding the operand is the whole semantics, exactly as unary `void`'s
|
|
288
|
+
* result is settled without consulting a carrier.
|
|
289
|
+
*
|
|
290
|
+
* The operand is CHECKED to be that boolean rather than assumed. An operand of
|
|
291
|
+
* any other carrier means the `[[Delete]]`'s own result was published with the
|
|
292
|
+
* wrong type -- a defect in the producer, which is where it gets fixed -- and
|
|
293
|
+
* coercing it here would hide exactly that.
|
|
294
|
+
*/
|
|
295
|
+
export const emitUnaryDelete = (ctx, lines, result, operand) => {
|
|
296
|
+
const produced = operand.representation;
|
|
297
|
+
if (produced.kind !== 'scalar' || produced.domain !== 'boolean') {
|
|
298
|
+
throw createCppEmitBlockedError(`runtime-helper:computation:delete-result:${representationKey(produced)}`, `unary "delete" received a "${produced.kind}" operand; the operator's value is the boolean its [[Delete]] published`);
|
|
299
|
+
}
|
|
300
|
+
lines.push(`${result} = ${operandText(ctx, operand)};`);
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* The receiver of a native sidecar access, or `null` when this is not one.
|
|
304
|
+
*
|
|
305
|
+
* A statically typed object reached through a key only known at runtime --
|
|
306
|
+
* `(this as any)[key]`, `(raw as any)[prop]` -- keeps its own C++ type. The
|
|
307
|
+
* receiver text is the `std::shared_ptr<T>` it already was; nothing about this
|
|
308
|
+
* path widens it, which is the whole point. `owned` ownership is refused
|
|
309
|
+
* rather than copied into a box: a by-value struct has no stable identity for
|
|
310
|
+
* the sidecar table to key on, and giving one a private sidecar per copy would
|
|
311
|
+
* be a plausible-looking wrong answer.
|
|
312
|
+
*/
|
|
313
|
+
const nativeSidecarReceiver = (ctx, receiver, contextDescription) => {
|
|
314
|
+
const representation = receiver.representation;
|
|
315
|
+
const addressable = representation.kind === 'class-ref' ||
|
|
316
|
+
representation.kind === 'record' ||
|
|
317
|
+
representation.kind === 'record-with-index' ||
|
|
318
|
+
representation.kind === 'native-record-ref' ||
|
|
319
|
+
// An Array exotic object's ORDINARY own properties -- everything that is
|
|
320
|
+
// not an index, `length`, or a field its extended interface declares --
|
|
321
|
+
// live in the same identity-keyed expando table, and the runtime already
|
|
322
|
+
// writes into it: `finalizeTemplateObject` installs GetTemplateObject's
|
|
323
|
+
// `raw` there. See `arrayAccessText`'s own comment for why that function
|
|
324
|
+
// defers here rather than stating a table exists or does not.
|
|
325
|
+
representation.kind === 'array-object';
|
|
326
|
+
if (!addressable)
|
|
327
|
+
return null;
|
|
328
|
+
if (representation.ownership !== 'shared-refcount') {
|
|
329
|
+
throw createCppEmitBlockedError(`native-boundary:dynamic-property-sidecar:${representation.ownership}`, `${contextDescription} has a "${representation.ownership}" receiver; a dynamic-property sidecar needs the object's own ` +
|
|
330
|
+
'shared identity to key on, which a by-value struct does not have');
|
|
331
|
+
}
|
|
332
|
+
return operandText(ctx, receiver);
|
|
333
|
+
};
|
|
334
|
+
/** A generated record has complete fixed-field and index hooks; host records deliberately do not impersonate that protocol. */
|
|
335
|
+
const generatedNativeSidecarReceiver = (ctx, receiver, contextDescription) => {
|
|
336
|
+
const representation = receiver.representation;
|
|
337
|
+
const generated = representation.kind === 'record' ||
|
|
338
|
+
representation.kind === 'record-with-index' ||
|
|
339
|
+
representation.kind === 'class-ref' ||
|
|
340
|
+
(representation.kind === 'native-record-ref' && representation.native === null);
|
|
341
|
+
return generated ? nativeSidecarReceiver(ctx, receiver, contextDescription) : null;
|
|
342
|
+
};
|
|
343
|
+
/**
|
|
344
|
+
* Whether a constant key names no declared field on a GENERATED record/class
|
|
345
|
+
* shape -- the one question `nativeSidecarGetText`'s get arm and
|
|
346
|
+
* `emitNativeSidecarSet`'s set arm both ask before falling through to their
|
|
347
|
+
* expando-sidecar branch. A host-native record (`representation.native !==
|
|
348
|
+
* null`) answers `false` here on purpose: its declared fields stay with its
|
|
349
|
+
* own protocol-specific interceptor, and treating an undeclared name on one as
|
|
350
|
+
* sidecar-only is what let `(error as any).code = value` fall through to a C++
|
|
351
|
+
* member named `code` that the native Error layout never declared -- see
|
|
352
|
+
* `nativeSidecarGetText`'s own comment for the incident. Stated once so a
|
|
353
|
+
* change to which kinds count as "generated", or to `declaredRecordFieldOf`'s
|
|
354
|
+
* own notion of a declared field, updates both the read and the write arm
|
|
355
|
+
* together instead of one of them silently asking a stale question.
|
|
356
|
+
*/
|
|
357
|
+
const staticKeyIsSidecarOnly = (ctx, representation, key) => {
|
|
358
|
+
const generated = representation.kind === 'record' ||
|
|
359
|
+
representation.kind === 'record-with-index' ||
|
|
360
|
+
representation.kind === 'class-ref' ||
|
|
361
|
+
representation.kind === 'native-record-ref';
|
|
362
|
+
// An Array's own layout answers `length`, a canonical index and the fields
|
|
363
|
+
// its extended interface declares; `arrayAccessText` renders all three and
|
|
364
|
+
// only defers a key that is none of them, so by the time one arrives here it
|
|
365
|
+
// is sidecar-only by construction. Restating that test would be a second
|
|
366
|
+
// opinion that can only ever agree.
|
|
367
|
+
if (representation.kind === 'array-object')
|
|
368
|
+
return true;
|
|
369
|
+
return generated && declaredRecordFieldOf(ctx.deriver, representation, key, ctx.classes) === null;
|
|
370
|
+
};
|
|
371
|
+
/** A Pattern keeps prototype-sensitive dynamic access in its exact native protocol. */
|
|
372
|
+
const isPatternSidecarReceiver = (receiver) => receiver.representation.kind === 'native-record-ref' && receiver.representation.native === cppRegExpNativeTypes.pattern;
|
|
373
|
+
/**
|
|
374
|
+
* OrdinarySet / OrdinaryDelete on a GENERATED object (a record, a class
|
|
375
|
+
* instance) go through the runtime's `nativeDynamicSet` / `nativeDynamicDelete`
|
|
376
|
+
* exactly like a host object's do -- there is deliberately no emitter-side
|
|
377
|
+
* spelling of the declared-field routing (`gea_matchesOwnField` ->
|
|
378
|
+
* `gea_writeOwnField` / `gea_deleteOwnField`, then the index sidecar, then
|
|
379
|
+
* the expando table). The runtime states that routing once, behind
|
|
380
|
+
* `if constexpr` on the struct's protocol, and `records.ts` declares that
|
|
381
|
+
* protocol only when the reflection census saw a dynamic operation EXECUTE on
|
|
382
|
+
* the struct. A body the callable flow proved never entered is still emitted
|
|
383
|
+
* (see `reflection-demand.ts`: layout and ABI retain every body, only
|
|
384
|
+
* impossible execution contributes no demand), so a set or delete inside it
|
|
385
|
+
* must compile against a struct whose protocol is off. An inline spelling of
|
|
386
|
+
* the same routing did not: @hono/node-server's lightweight `Response`, once
|
|
387
|
+
* nothing constructed it, named `gea_matchesOwnField` on a struct that had
|
|
388
|
+
* never been asked to declare it, and the unit failed to compile on a line
|
|
389
|
+
* the census had correctly proved dead.
|
|
390
|
+
*/
|
|
391
|
+
const generatedNativeWriteText = (receiver, key, value) => `gea::nativeDynamicSet(${receiver}, ${key}, ${value})`;
|
|
392
|
+
const generatedNativeDeleteText = (receiver, key) => `gea::nativeDynamicDelete(${receiver}, ${key})`;
|
|
393
|
+
/**
|
|
394
|
+
* Whether a carrier is one of the five native callable representations that
|
|
395
|
+
* share a `gea::CallableObject`-style identity-owned property table --
|
|
396
|
+
* `callableSidecarReceiver`, `deferredCallableShapeMethodClaim` and
|
|
397
|
+
* `callableSidecarGetText` all gate on exactly this set, and used to spell it
|
|
398
|
+
* three times. A kind added to (or dropped from) the callable family only
|
|
399
|
+
* needs to change here now; before this, a site that missed the update would
|
|
400
|
+
* silently keep treating that kind as non-callable while its siblings moved
|
|
401
|
+
* on -- which is the "two authorities" shape this file's own header warns
|
|
402
|
+
* about, spelled as three copies rather than two.
|
|
403
|
+
*/
|
|
404
|
+
export { isNativeCallableCarrier } from '../../representation/callable-object.js';
|
|
405
|
+
/**
|
|
406
|
+
* A native callable's own-property sidecar.
|
|
407
|
+
*
|
|
408
|
+
* A `CallableObject` is copied by value for its fixed ABI, but every copy of
|
|
409
|
+
* one JavaScript function preserves the same identity-owned property table.
|
|
410
|
+
* The receiver therefore stays callable here; boxing it solely to reach a
|
|
411
|
+
* property table would lose the static call convention the representation
|
|
412
|
+
* proved.
|
|
413
|
+
*/
|
|
414
|
+
const callableSidecarReceiver = (ctx, receiver) => isNativeCallableCarrier(receiver.representation.kind) ? operandText(ctx, receiver) : null;
|
|
415
|
+
/** Function.prototype names that this compiler either defers or still refuses, never treats as an expando. */
|
|
416
|
+
const nonExpandoFunctionMemberNames = new Set(['call', 'apply', 'bind', 'toString', 'constructor', 'caller', 'arguments', 'prototype']);
|
|
417
|
+
/**
|
|
418
|
+
* A fixed own Function property or a statically named callable expando.
|
|
419
|
+
*
|
|
420
|
+
* Computed symbol keys are the one dynamic-keyed subset this native carrier
|
|
421
|
+
* can state: the modeled Function.prototype surface is string-keyed, so a
|
|
422
|
+
* symbol read reaches only the callable's own sidecar. Other computed keys
|
|
423
|
+
* remain refused rather than guessing whether they name `bind`, `call`, or an
|
|
424
|
+
* unimplemented inherited member.
|
|
425
|
+
*/
|
|
426
|
+
/**
|
|
427
|
+
* Whether a callable's `hasOwnProperty`/`propertyIsEnumerable` is a deferred
|
|
428
|
+
* `Object.prototype` read answered from the shared function-object table.
|
|
429
|
+
*
|
|
430
|
+
* Stated once; `callableSidecarGetText` and the prototype-read walk both ask
|
|
431
|
+
* it. A symbol key reaches the sidecar instead and a computed key cannot know
|
|
432
|
+
* the name, so both are excluded here exactly as they are there.
|
|
433
|
+
*/
|
|
434
|
+
export const deferredCallableShapeMethodClaim = (staticKeyTexts, receiver, key) => {
|
|
435
|
+
const representation = receiver.representation;
|
|
436
|
+
if (!isNativeCallableCarrier(representation.kind))
|
|
437
|
+
return null;
|
|
438
|
+
if (key.representation.kind === 'symbol')
|
|
439
|
+
return null;
|
|
440
|
+
const staticKey = staticKeyTexts.get(key.value);
|
|
441
|
+
if (staticKey === undefined || !objectShapePrototypeMethods.has(staticKey))
|
|
442
|
+
return null;
|
|
443
|
+
return { receiverKind: 'callable-shape', member: staticKey, receiver: { kind: 'operand', operand: receiver }, receiverElement: null };
|
|
444
|
+
};
|
|
445
|
+
export const callableSidecarGetText = (ctx, operation) => {
|
|
446
|
+
const representation = operation.receiver.representation;
|
|
447
|
+
// A function object with no calling convention (`Array.from`, whose four
|
|
448
|
+
// overloads disagree at parameter 0) owns the same identity table as every
|
|
449
|
+
// callable below, and `name`/`length` are the two facts a program can read
|
|
450
|
+
// off it without a frame. Nothing else is spelled: there is no thunk to bind
|
|
451
|
+
// `.call` to, no expando the backend put there, and a computed key would
|
|
452
|
+
// need the `Function.prototype` walk the arms below only reach through a
|
|
453
|
+
// callable -- all of which stay refused, by the manifest and by here.
|
|
454
|
+
if (representation.kind === 'callable-identity') {
|
|
455
|
+
const fact = ctx.staticKeyTexts.get(operation.key.value);
|
|
456
|
+
if (fact !== 'name' && fact !== 'length')
|
|
457
|
+
return null;
|
|
458
|
+
const site = `a Function own-property read of "${fact}"`;
|
|
459
|
+
return unboxedReadText(operation.result.representation, `gea::functionIdentityDynamicGet(${operandText(ctx, operation.receiver)}, ${propertyKeyText(ctx, operation.key, site)})`, site);
|
|
460
|
+
}
|
|
461
|
+
if (!isNativeCallableCarrier(representation.kind))
|
|
462
|
+
return null;
|
|
463
|
+
if (operation.key.representation.kind === 'symbol') {
|
|
464
|
+
const site = 'a computed symbol own-property read on a callable';
|
|
465
|
+
return unboxedReadText(operation.result.representation, `gea::callableDynamicGet(${operandText(ctx, operation.receiver)}, ${propertyKeyText(ctx, operation.key, site)})`, site);
|
|
466
|
+
}
|
|
467
|
+
// This picks the whole branch below (fixed name/length/prototype vs. the
|
|
468
|
+
// computed-key runtime dispatch), so it must ask `staticKeyTexts` -- a key
|
|
469
|
+
// `constantTexts` only later folds (a render-time `typeof` result) is not a
|
|
470
|
+
// member name the program wrote, and treating it as one would misroute a
|
|
471
|
+
// genuinely computed key into the fixed-member arm.
|
|
472
|
+
const key = ctx.staticKeyTexts.get(operation.key.value);
|
|
473
|
+
if (key === undefined) {
|
|
474
|
+
if (representation.kind !== 'function-value-dispatch' && representation.kind !== 'function-and-constructor')
|
|
475
|
+
return null;
|
|
476
|
+
// A runtime string key reaches the one shared function-object table, the
|
|
477
|
+
// way a constant `name`/`length`/expando key does below. What this arm
|
|
478
|
+
// cannot know statically is whether the key names a `Function.prototype`
|
|
479
|
+
// member the backend does not model -- so it asks at runtime and throws
|
|
480
|
+
// rather than answering `undefined` for `fn[k]` with `k === "call"`.
|
|
481
|
+
const site = 'a computed own-property read on a callable';
|
|
482
|
+
const guarded = [...nonExpandoFunctionMemberNames].map((name) => `__gea_name == ${cppStringLiteral(name)}`).join(' || ');
|
|
483
|
+
const read = `([&]() -> gea::Value { const gea::PropertyKey __gea_key = ${propertyKeyText(ctx, operation.key, site)}; ` +
|
|
484
|
+
`if (!__gea_key.isSymbol()) { const std::string& __gea_name = __gea_key.text(); if (${guarded}) ` +
|
|
485
|
+
`gea::host::throwRuntimeError("TypeError", "a computed read of Function.prototype's own \"" + __gea_name + "\" on a callable is not rendered by this backend"); } ` +
|
|
486
|
+
`return gea::callableDynamicGet(${operandText(ctx, operation.receiver)}, __gea_key); })()`;
|
|
487
|
+
return unboxedReadText(operation.result.representation, read, site);
|
|
488
|
+
}
|
|
489
|
+
if (deferredCallableShapeMethodClaim(ctx.staticKeyTexts, operation.receiver, operation.key) !== null) {
|
|
490
|
+
// `fn.hasOwnProperty(k)` / `fn.propertyIsEnumerable(k)`: Object.prototype
|
|
491
|
+
// reached through the callable, answered at the call from the one shared
|
|
492
|
+
// function-object table (`callableShapeCallText`) -- never read as an
|
|
493
|
+
// expando, which the table does not hold and would unbox as undefined.
|
|
494
|
+
return '';
|
|
495
|
+
}
|
|
496
|
+
// `prototype` is a fixed own Function property for a `function-and-constructor`
|
|
497
|
+
// by its carrier, and for a `function-value-dispatch` only where the read
|
|
498
|
+
// carries the census's proof that the declaration ran `MakeConstructor`
|
|
499
|
+
// (`GetOperation.callableOwnPrototype`). The printer does not re-derive that
|
|
500
|
+
// proof and cannot: by here only the carrier is left, and the carrier
|
|
501
|
+
// answering this was the defect.
|
|
502
|
+
// The census's `prototype` verdict, carried on the read itself
|
|
503
|
+
// (`GetOperation.callableOwnPrototype`) and present at `false` as well as at
|
|
504
|
+
// `true` -- a declaration that provably owns no `prototype` is the same read
|
|
505
|
+
// with the other answer. Only ABSENCE means unproven, and an unproven read
|
|
506
|
+
// never reaches emission: certification refused it. The printer does not
|
|
507
|
+
// re-derive the verdict and cannot -- by here only the carrier is left, and
|
|
508
|
+
// the carrier answering this was the defect.
|
|
509
|
+
if (representation.kind === 'function-value-dispatch' && key === 'prototype' && operation.callableOwnPrototype !== undefined) {
|
|
510
|
+
return unboxedReadText(operation.result.representation, `gea::callableOwnPrototypeGet(${operandText(ctx, operation.receiver)}, ${operation.callableOwnPrototype ? 'true' : 'false'})`, 'a Function own-property read of "prototype"');
|
|
511
|
+
}
|
|
512
|
+
const fixed = key === 'name' || key === 'length' || (representation.kind === 'function-and-constructor' && key === 'prototype');
|
|
513
|
+
if (!fixed && nonExpandoFunctionMemberNames.has(key) && key !== 'call' && key !== 'apply' && key !== 'bind')
|
|
514
|
+
return null;
|
|
515
|
+
const site = fixed ? `a Function own-property read of "${key}"` : 'a static callable expando read';
|
|
516
|
+
// Unless the program shadowed it, `fn.apply` is Function.prototype's own
|
|
517
|
+
// builtin, which no typed payload matches. It is called through its box,
|
|
518
|
+
// with `fn` -- the receiver the typed convention passes first -- boxed by
|
|
519
|
+
// its own ABI so a rest or receiver-bearing callable stays one.
|
|
520
|
+
const builtin = builtinCallableMethodText(operation.result.representation, key, () => `gea::callableDynamicGet(${operandText(ctx, operation.receiver)}, ${propertyKeyText(ctx, operation.key, site)})`);
|
|
521
|
+
if (builtin !== null)
|
|
522
|
+
return builtin;
|
|
523
|
+
return unboxedReadText(operation.result.representation, `gea::callableDynamicGet(${operandText(ctx, operation.receiver)}, ${propertyKeyText(ctx, operation.key, site)})`, site);
|
|
524
|
+
};
|
|
525
|
+
const builtinCallableMethodText = (produced, key, read) => {
|
|
526
|
+
if (key !== 'call' && key !== 'apply' && key !== 'bind')
|
|
527
|
+
return null;
|
|
528
|
+
if (produced.kind !== 'function-value-dispatch')
|
|
529
|
+
return null;
|
|
530
|
+
const abi = produced.abi;
|
|
531
|
+
const receiver = abi.receiver;
|
|
532
|
+
if (receiver === null)
|
|
533
|
+
return null;
|
|
534
|
+
// `CallableFunction.call`'s receiver is the function itself, already adapted
|
|
535
|
+
// to `(thisArg, ...args)` -- the very parameters `call` takes -- so the
|
|
536
|
+
// method is a plain forward, with nothing to box. `apply` is the same
|
|
537
|
+
// forward when the function's own frame is `(this, rest array)`: the array
|
|
538
|
+
// `apply` spreads is exactly the rest array the body binds.
|
|
539
|
+
const parameterTypes = abi.parameters.map(cppAbiParameterType);
|
|
540
|
+
const sameFrame = cppTypeOf(receiver) === `gea::CallableObject<${cppResultTypeOf(abi.result)}(${parameterTypes.join(', ')})>`;
|
|
541
|
+
const restFrame = key === 'apply' &&
|
|
542
|
+
receiver.kind === 'function-value-dispatch' &&
|
|
543
|
+
receiver.abi.receiver !== null &&
|
|
544
|
+
receiver.abi.restFrom === 0 &&
|
|
545
|
+
receiver.abi.parameters.length === 1 &&
|
|
546
|
+
abi.parameters.length === 2;
|
|
547
|
+
if ((key === 'call' || restFrame) && sameFrame) {
|
|
548
|
+
const formals = [cppTypeOf(receiver), ...parameterTypes].map((type, index) => `${type} gea_argument_${index}`);
|
|
549
|
+
const actuals = parameterTypes.map((_, index) => `gea_argument_${index + 1}`);
|
|
550
|
+
return (`${cppTypeOf(produced)}(+[](void*, ${formals.join(', ')}) -> ${cppResultTypeOf(abi.result)} { ` +
|
|
551
|
+
`return gea_argument_0.call(${actuals.join(', ')}); }, static_cast<void*>(nullptr))`);
|
|
552
|
+
}
|
|
553
|
+
if (abi.restFrom !== null)
|
|
554
|
+
return null;
|
|
555
|
+
const boxes = [receiver, ...abi.parameters.map((parameter) => parameter.value)].map((carrier, index) => carrier.kind === 'dynamic' ? `gea_argument_${index}` : dynamicCarrierBoxText(carrier, `gea_argument_${index}`));
|
|
556
|
+
if (boxes.some((box) => box === null))
|
|
557
|
+
return null;
|
|
558
|
+
const called = `gea_source->callWithReceiver(${boxes[0]}, {${boxes.slice(1).join(', ')}})`;
|
|
559
|
+
const result = cppResultTypeOf(abi.result);
|
|
560
|
+
let body;
|
|
561
|
+
if (abi.result.kind === 'void')
|
|
562
|
+
body = `${called};`;
|
|
563
|
+
else if (abi.result.kind === 'dynamic')
|
|
564
|
+
body = `return ${called};`;
|
|
565
|
+
else {
|
|
566
|
+
const loaded = unboxedLoadText(abi.result, called);
|
|
567
|
+
if (loaded === null)
|
|
568
|
+
return null;
|
|
569
|
+
body = `return ${loaded};`;
|
|
570
|
+
}
|
|
571
|
+
const formals = [cppTypeOf(receiver), ...abi.parameters.map(cppAbiParameterType)].map((type, index) => `${type} gea_argument_${index}`);
|
|
572
|
+
const type = cppTypeOf(produced);
|
|
573
|
+
return (`[&]() { const gea::Value gea_builtin = ${read()}; ` +
|
|
574
|
+
`return ${type}(+[](void* gea_environment${formals.map((formal) => `, ${formal}`).join('')}) -> ${result} { ` +
|
|
575
|
+
`alignas(void*) unsigned char gea_slot[sizeof(void*)]; const gea::Value* gea_source = gea::unpackEnvironment<gea::Value>(gea_environment, gea_slot); ${body} }, ` +
|
|
576
|
+
`gea::packEnvironment<gea::Value>(gea_builtin)); }()`);
|
|
577
|
+
};
|
|
578
|
+
/**
|
|
579
|
+
* A dynamic property read landing in a carrier the checker already fixed.
|
|
580
|
+
*
|
|
581
|
+
* `(this as unknown as Record<symbol, StoreState<S>>)[_PRIV]` reads a property
|
|
582
|
+
* dynamically and the expression's type is a record, not `any`. The value came
|
|
583
|
+
* out of the sidecar as a `gea::Value`, so it has to come back -- and the
|
|
584
|
+
* unbox is TAG- AND TYPE-CHECKED (`detail::unboxAs`), because the write that
|
|
585
|
+
* filled the property is a different expression entirely and nothing at this
|
|
586
|
+
* site proves the two agreed. A mismatch aborts by name; it does not silently
|
|
587
|
+
* reinterpret one struct as another.
|
|
588
|
+
*
|
|
589
|
+
* Exported (with `boxedValueText` above) for one other caller:
|
|
590
|
+
* `emit-prototype-regexp.ts`'s `stringObjectMemberText`/
|
|
591
|
+
* `emitStringObjectSet`. A String OBJECT is the one native-record-ref type
|
|
592
|
+
* whose whole point is arbitrary, program-chosen CONSTANT keys as dynamic
|
|
593
|
+
* properties (`escapedString.isEscaped = true`, hono's `utils/html.ts`) --
|
|
594
|
+
* every other native-record-ref type's constant keys are enumerable ahead of
|
|
595
|
+
* time and handled by a per-protocol interceptor that names each one
|
|
596
|
+
* (`regexpMemberText`, `emitDateConstruct`), so `nativeSidecarGetText`/
|
|
597
|
+
* `emitNativeSidecarSet` below have always been free to skip a constant key
|
|
598
|
+
* outright. String's own interceptor cannot rely on that skip -- it has to
|
|
599
|
+
* route ITS constant, non-`length` keys through the identical
|
|
600
|
+
* box/unbox machinery this pair already implements, rather than duplicate it.
|
|
601
|
+
*/
|
|
602
|
+
export const unboxedReadText = (produced, text, site) => {
|
|
603
|
+
if (produced.kind === 'dynamic')
|
|
604
|
+
return text;
|
|
605
|
+
// Undefined and null have no payload type. `unboxAs<T>` is intentionally
|
|
606
|
+
// stricter for payload-bearing values, but applying it to these two tags
|
|
607
|
+
// rejects the legitimate default `gea::Value()` absence produced by a
|
|
608
|
+
// missing dynamic property. Reuse the canonical tag-only loaders from
|
|
609
|
+
// `unboxedLoadText`, preserving refusal for every wrong tag.
|
|
610
|
+
if (produced.kind === 'undefined')
|
|
611
|
+
return `gea::detail::unboxUndefinedValue(${text}, ${cppStringLiteral(site)})`;
|
|
612
|
+
if (produced.kind === 'null')
|
|
613
|
+
return `gea::detail::unboxNullValue(${text}, ${cppStringLiteral(site)})`;
|
|
614
|
+
// A sidecar holds one live JavaScript value, while a tagged union is only
|
|
615
|
+
// the native carrier that records which exact arm it is. This is the AJV
|
|
616
|
+
// `errors?: readonly Error[] | null` path: undefined/null/array are
|
|
617
|
+
// distinct live results, not an optional approximation of one another. Do
|
|
618
|
+
// not use `DynamicCarrier<TaggedUnion>::in` here: that helper is for a CALL
|
|
619
|
+
// argument, where `undefined` means a missing parameter. A property read
|
|
620
|
+
// legitimately returns an `undefined` union arm. `unboxedLoadText` performs
|
|
621
|
+
// an arm-by-arm tag *and payload* decode and builds the matching native arm,
|
|
622
|
+
// with no coercion or reboxing.
|
|
623
|
+
if (produced.kind === 'tagged-union') {
|
|
624
|
+
// The decoder tests and loads the Value in separate expressions. Retain
|
|
625
|
+
// one sidecar result first so an accessor-backed callable property is read
|
|
626
|
+
// once, just as [[Get]] requires.
|
|
627
|
+
const value = '__gea_sidecar_value';
|
|
628
|
+
const decoded = unboxedLoadText(produced, value);
|
|
629
|
+
if (decoded !== null) {
|
|
630
|
+
return `([&]() -> ${cppTypeOf(produced)} { const gea::Value ${value} = ${text}; return ${decoded}; })()`;
|
|
631
|
+
}
|
|
632
|
+
throw createCppEmitBlockedError(`conversion:${representationKey({ kind: 'dynamic', reason: 'declared-any-never-narrowed' })}->${representationKey(produced)}`, `${site} publishes a tagged-union carrier with no exact Value-to-arm decoder`);
|
|
633
|
+
}
|
|
634
|
+
// An `optional` result is the property's own absence, not a second carrier
|
|
635
|
+
// to unbox: `Record<string, T>` read under `noUncheckedIndexedAccess` is
|
|
636
|
+
// `T | undefined`, and the missing key is exactly the empty optional.
|
|
637
|
+
if (produced.kind === 'optional') {
|
|
638
|
+
// A record payload is REBUILT, not reinterpreted. `unboxOptional<Ref<R>>`
|
|
639
|
+
// asks the box to already carry that exact C++ struct, which is true only
|
|
640
|
+
// when the value came from this program; a descriptor object the RUNTIME
|
|
641
|
+
// built (`Reflect.getOwnPropertyDescriptor`) is an ordinary dynamic object
|
|
642
|
+
// with the right fields and the wrong payload type, and the assertion
|
|
643
|
+
// aborted at run time. `unboxedLoadText` already renders the field-by-field
|
|
644
|
+
// materialization -- including a fast path that preserves identity when the
|
|
645
|
+
// box does carry the struct -- so the absence stays this branch's question
|
|
646
|
+
// and the payload becomes that function's.
|
|
647
|
+
// A TAGGED-UNION payload is rebuilt for the same reason and by the same
|
|
648
|
+
// decoder. The absence stays this branch's question -- `undefined`/`null`
|
|
649
|
+
// is the optional's own empty state, not an arm -- and what remains is an
|
|
650
|
+
// ordinary union decode, arm by arm, on tag AND payload type. Without
|
|
651
|
+
// this the pair fell through to `dynamicTagFor`, which has no single box
|
|
652
|
+
// tag to name for a union and refused: `@hono/node-server`'s
|
|
653
|
+
// `readBodyBufferedBeforeDisconnect` caches `Buffer | Error` under a
|
|
654
|
+
// symbol key on the incoming message and reads it back as
|
|
655
|
+
// `Buffer | Error | undefined`, which is exactly this shape.
|
|
656
|
+
if (produced.payload.kind === 'record' || produced.payload.kind === 'tagged-union') {
|
|
657
|
+
const value = '__gea_optional_value';
|
|
658
|
+
const load = unboxedLoadText(produced.payload, value);
|
|
659
|
+
if (load !== null) {
|
|
660
|
+
return (`([&]() -> ${cppTypeOf(produced)} { const gea::Value ${value} = ${text}; ` +
|
|
661
|
+
`if (${value}.tag() == gea::Value::Tag::Undefined || ${value}.tag() == gea::Value::Tag::Null) return ${cppTypeOf(produced)}(); ` +
|
|
662
|
+
`return ${cppTypeOf(produced)}(${load}); })()`);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
const payloadTag = dynamicTagFor(produced.payload);
|
|
666
|
+
if (payloadTag === null) {
|
|
667
|
+
throw createCppEmitBlockedError(`conversion:${representationKey({ kind: 'dynamic', reason: 'declared-any-never-narrowed' })}->${representationKey(produced)}`, `${site} publishes an optional over a "${produced.payload.kind}" carrier, which this backend has no box tag for`);
|
|
668
|
+
}
|
|
669
|
+
return `gea::detail::unboxOptional<${cppTypeOf(produced.payload)}>(${text}, gea::Value::Tag::${payloadTag}, ${cppStringLiteral(site)})`;
|
|
670
|
+
}
|
|
671
|
+
const tag = dynamicTagFor(produced);
|
|
672
|
+
if (tag === null) {
|
|
673
|
+
throw createCppEmitBlockedError(`conversion:${representationKey({ kind: 'dynamic', reason: 'declared-any-never-narrowed' })}->${representationKey(produced)}`, `${site} publishes a "${produced.kind}" carrier, and this backend has no box tag to read one back out of a property`);
|
|
674
|
+
}
|
|
675
|
+
return `gea::detail::unboxAs<${cppTypeOf(produced)}>(${text}, gea::Value::Tag::${tag}, ${cppStringLiteral(site)})`;
|
|
676
|
+
};
|
|
677
|
+
/**
|
|
678
|
+
* The ownership of a generated record/record-with-index/native-record-ref/
|
|
679
|
+
* class-ref carrier, or `owned` for anything else -- the same question
|
|
680
|
+
* `host/object-protocol.ts` asks of a KNOWN view's own representation, stated
|
|
681
|
+
* once here because that file already imports from this one
|
|
682
|
+
* (`propertyKeyText`) and a second copy on that side of the boundary would be
|
|
683
|
+
* free to answer this differently the next time a "generated shared object"
|
|
684
|
+
* kind is added and only one side is updated for it. `finiteRecordUnionGetText`
|
|
685
|
+
* below is this file's own asker.
|
|
686
|
+
*/
|
|
687
|
+
export const ownershipOfGeneratedCarrier = (representation) => representation.kind === 'record' ||
|
|
688
|
+
representation.kind === 'record-with-index' ||
|
|
689
|
+
representation.kind === 'class-ref' ||
|
|
690
|
+
representation.kind === 'native-record-ref'
|
|
691
|
+
? representation.ownership
|
|
692
|
+
: 'owned';
|
|
693
|
+
/**
|
|
694
|
+
* A computed read whose lowering published a finite fixed-field recipe. The
|
|
695
|
+
* recipe owns the key domain and conversion nodes; this function only renders
|
|
696
|
+
* the already-sealed switch and the field spelling for the native carrier.
|
|
697
|
+
*
|
|
698
|
+
* The old tagged-union path remains below as a migration fallback for reads
|
|
699
|
+
* produced by lowerings that have not published this recipe yet. It keeps the
|
|
700
|
+
* existing unknown-key behavior while the recipe authority is adopted by all
|
|
701
|
+
* property-read producers.
|
|
702
|
+
*/
|
|
703
|
+
const finiteRecordUnionGetText = (ctx, operation, receiver) => {
|
|
704
|
+
const recipe = operation.typedComputedRead;
|
|
705
|
+
if (recipe !== undefined && (operation.key.representation.kind === 'string' || recipe.receiverBounded !== undefined)) {
|
|
706
|
+
const produced = operation.result.representation;
|
|
707
|
+
if (operation.receiver.representation.kind !== 'record')
|
|
708
|
+
return null;
|
|
709
|
+
if (recipe.receiver !== representationKey(operation.receiver.representation) ||
|
|
710
|
+
recipe.result !== representationKey(produced) ||
|
|
711
|
+
(recipe.receiverBounded !== undefined && recipe.receiverBounded.carrier !== representationKey(operation.key.representation))) {
|
|
712
|
+
throw createCppEmitBlockedError('property-access:record:get:typed-computed-read', 'the sealed computed-read recipe does not match the operation carriers');
|
|
713
|
+
}
|
|
714
|
+
const accessor = memberAccessOperator(operation.receiver.representation.ownership);
|
|
715
|
+
const arms = [];
|
|
716
|
+
for (const arm of recipe.arms) {
|
|
717
|
+
const node = ctx.conversions.nodeById(arm.conversion);
|
|
718
|
+
if (node === null ||
|
|
719
|
+
representationKey(node.source) !== representationKey(arm.source) ||
|
|
720
|
+
representationKey(node.target) !== representationKey(produced)) {
|
|
721
|
+
throw createCppEmitBlockedError('property-access:record:get:typed-computed-read', `the sealed conversion for field "${arm.key}" no longer matches the read result`);
|
|
722
|
+
}
|
|
723
|
+
const read = `${receiver}${accessor}${cppRecordFieldName(arm.key)}`;
|
|
724
|
+
const converted = recipeText(ctx, node, read);
|
|
725
|
+
if (converted === null) {
|
|
726
|
+
throw createCppEmitBlockedError('property-access:record:get:typed-computed-read', `the sealed conversion for field "${arm.key}" has no renderer`);
|
|
727
|
+
}
|
|
728
|
+
arms.push(`if (__gea_key == ${cppStringLiteral(arm.key)}) return ${converted};`);
|
|
729
|
+
}
|
|
730
|
+
if (arms.length > 0) {
|
|
731
|
+
const resultType = cppTypeOf(produced);
|
|
732
|
+
let missing = `gea::host::unreachableValue<${resultType}>()`;
|
|
733
|
+
if (recipe.receiverBounded !== undefined) {
|
|
734
|
+
const node = ctx.conversions.nodeById(recipe.receiverBounded.missing);
|
|
735
|
+
if (node === null || node.source.kind !== 'undefined' || representationKey(node.target) !== recipe.result)
|
|
736
|
+
throw createCppEmitBlockedError('property-access:record:get:typed-computed-read', 'the receiver-bounded read has no matching absence conversion');
|
|
737
|
+
const converted = recipeText(ctx, node, 'gea::Undefined{}');
|
|
738
|
+
if (converted === null)
|
|
739
|
+
throw createCppEmitBlockedError('property-access:record:get:typed-computed-read', 'the receiver-bounded read absence has no renderer');
|
|
740
|
+
missing = converted;
|
|
741
|
+
}
|
|
742
|
+
const key = recipe.receiverBounded === undefined ? operandText(ctx, operation.key) : keyedTableKeyText(ctx, operation.key, 'string');
|
|
743
|
+
return `([&]() -> ${resultType} { const std::string& __gea_key = ${key}; ` + `${arms.join(' ')} return ${missing}; })()`;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
// Compatibility route for IR reads lowered before the sealed recipe was
|
|
747
|
+
// introduced (including destructuring and protocol-generated reads). Keep
|
|
748
|
+
// its prior tagged-union condition and conversion behavior intact.
|
|
749
|
+
const produced = operation.result.representation;
|
|
750
|
+
if (produced.kind !== 'tagged-union' || operation.key.representation.kind !== 'string')
|
|
751
|
+
return null;
|
|
752
|
+
const representation = operation.receiver.representation;
|
|
753
|
+
const fields = representation.kind === 'record' || representation.kind === 'record-with-index'
|
|
754
|
+
? representation.fields
|
|
755
|
+
: representation.kind === 'class-ref' || (representation.kind === 'native-record-ref' && representation.native === null)
|
|
756
|
+
? recordFieldsOfShape(ctx.deriver, representation.shapeId)
|
|
757
|
+
: null;
|
|
758
|
+
if (fields === null || fields.length === 0)
|
|
759
|
+
return null;
|
|
760
|
+
const accessor = memberAccessOperator(ownershipOfGeneratedCarrier(representation));
|
|
761
|
+
const arms = [];
|
|
762
|
+
for (const field of fields) {
|
|
763
|
+
const read = `${receiver}${accessor}${cppRecordFieldName(field.key)}`;
|
|
764
|
+
const converted = alignedValueText(ctx, 'emit-dynamic-properties.ts:582', field.value, produced, read);
|
|
765
|
+
if (converted === null)
|
|
766
|
+
return null;
|
|
767
|
+
arms.push(`if (__gea_key == ${cppStringLiteral(field.key)}) return ${converted};`);
|
|
768
|
+
}
|
|
769
|
+
const resultType = cppTypeOf(produced);
|
|
770
|
+
return (`([&]() -> ${resultType} { const std::string& __gea_key = ${operandText(ctx, operation.key)}; ` +
|
|
771
|
+
`${arms.join(' ')} return gea::host::unreachableValue<${resultType}>(); })()`);
|
|
772
|
+
};
|
|
773
|
+
/** `[[Get]]` with a runtime key on a receiver that keeps its native type. */
|
|
774
|
+
/**
|
|
775
|
+
* `C[key]` with a key only known at runtime, read off the class constructor
|
|
776
|
+
* object itself: the cpn (computed property name) family's
|
|
777
|
+
* `C[String(1)]` after `static [1] = 2`.
|
|
778
|
+
*
|
|
779
|
+
* A constructor object has no expando sidecar to consult -- every property it
|
|
780
|
+
* carries is a static member the layout declares, an assignment-only static
|
|
781
|
+
* the whole-program census gave storage to, or its own `name`/`length` --
|
|
782
|
+
* and all of those are spelled at compile time. So the runtime read is a
|
|
783
|
+
* dispatch over that finite key set, each arm rendered by the SAME per-key
|
|
784
|
+
* renderer a constant-key read uses (`classConstructorStaticMemberTextFor`),
|
|
785
|
+
* with the result boxed: the checker types a computed read of a class
|
|
786
|
+
* constructor as `any`, and an arm that publishes anything narrower is
|
|
787
|
+
* converted through the ordinary tag-checked path at the site. The set is
|
|
788
|
+
* collected along the base chain because `Derived[k]` resolves through
|
|
789
|
+
* `Derived`'s `[[Prototype]]`, the base constructor, exactly as
|
|
790
|
+
* `classStaticMemberOf` walks it for a constant key. A key nothing declares
|
|
791
|
+
* is the language's `undefined`.
|
|
792
|
+
*/
|
|
793
|
+
const constructorFamilyComputedGetText = (ctx, operation) => {
|
|
794
|
+
const receiver = operation.receiver.representation;
|
|
795
|
+
// Deciding whether THIS function even applies (a constant key defers to
|
|
796
|
+
// `classConstructorStaticMemberText`'s own per-key renderer instead), so the
|
|
797
|
+
// claim is `staticKeyTexts` -- a key `constantTexts` only later folds must
|
|
798
|
+
// never be admitted here as if the program had named a static member.
|
|
799
|
+
if (receiver.kind !== 'constructor-family' || ctx.staticKeyTexts.has(operation.key.value))
|
|
800
|
+
return null;
|
|
801
|
+
const site = 'a computed "get" on a class constructor';
|
|
802
|
+
const keys = new Set();
|
|
803
|
+
const walked = new Set();
|
|
804
|
+
for (const member of receiver.members) {
|
|
805
|
+
let current = member;
|
|
806
|
+
while (current !== null && !walked.has(current)) {
|
|
807
|
+
walked.add(current);
|
|
808
|
+
const layout = ctx.classes.get(current);
|
|
809
|
+
if (!layout)
|
|
810
|
+
break;
|
|
811
|
+
for (const field of layout.staticFields)
|
|
812
|
+
keys.add(field.key);
|
|
813
|
+
for (const method of layout.staticMethods)
|
|
814
|
+
keys.add(method.key);
|
|
815
|
+
for (const accessor of layout.staticAccessors)
|
|
816
|
+
keys.add(accessor.key);
|
|
817
|
+
for (const key of classStaticFieldStorageKeysOf(ctx.classes, current))
|
|
818
|
+
keys.add(key);
|
|
819
|
+
if (layout.name !== null) {
|
|
820
|
+
keys.add('name');
|
|
821
|
+
keys.add('length');
|
|
822
|
+
}
|
|
823
|
+
current = layout.base;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
const boxed = { kind: 'dynamic', reason: 'declared-any-never-narrowed' };
|
|
827
|
+
const receiverText = operandText(ctx, operation.receiver);
|
|
828
|
+
const arms = [...keys].map((key) => {
|
|
829
|
+
const text = classConstructorStaticMemberTextFor(ctx, receiver, key, boxed, () => receiverText);
|
|
830
|
+
if (text === null)
|
|
831
|
+
throw createCppEmitBlockedError('property-access:constructor-family:get:true', `${site} cannot render its static member "${key}"`);
|
|
832
|
+
return `if (gea_key == gea::PropertyKey::string(${cppStringLiteral(key)})) return ${text}; `;
|
|
833
|
+
});
|
|
834
|
+
const read = `([&](const gea::PropertyKey& gea_key) -> gea::Value { ${arms.join('')}return gea::Value(); })(${propertyKeyText(ctx, operation.key, site)})`;
|
|
835
|
+
return unboxedReadText(operation.result.representation, read, site);
|
|
836
|
+
};
|
|
837
|
+
export const nativeSidecarGetText = (ctx, operation) => {
|
|
838
|
+
const constructorRead = constructorFamilyComputedGetText(ctx, operation);
|
|
839
|
+
if (constructorRead !== null)
|
|
840
|
+
return { text: constructorRead, spelling: null };
|
|
841
|
+
// Whether this key names a DECLARED field (below) or the Array.prototype
|
|
842
|
+
// refusal applies is a claim, not a fold: ask `staticKeyTexts` so a value
|
|
843
|
+
// `constantTexts` only later accumulates (a render-time `typeof` fold)
|
|
844
|
+
// can never make a computed key look like a name the program wrote.
|
|
845
|
+
const staticKey = ctx.staticKeyTexts.get(operation.key.value);
|
|
846
|
+
// This is a normal-completion certificate. A native reference still owes
|
|
847
|
+
// the null receiver check, even though no successful lookup can find a key.
|
|
848
|
+
const absent = nativeAbsentPropertyReadOf(operation);
|
|
849
|
+
if (absent === 'checked-reference')
|
|
850
|
+
return {
|
|
851
|
+
text: `gea::nativeAbsentPropertyGet(${operandText(ctx, operation.receiver)}, ${propertyKeyText(ctx, operation.key, 'a proven absent numeric read')})`,
|
|
852
|
+
spelling: null
|
|
853
|
+
};
|
|
854
|
+
if (absent === 'primitive')
|
|
855
|
+
return { text: 'gea::Undefined{}', spelling: null };
|
|
856
|
+
if (staticKey !== undefined) {
|
|
857
|
+
const representation = operation.receiver.representation;
|
|
858
|
+
// A key the generated layout declares is reached by the ordinary member
|
|
859
|
+
// path below. A key it does not declare can still be an own property when
|
|
860
|
+
// source reached the object through `any`; that property lives in this
|
|
861
|
+
// object's expando table even though its spelling happened to be static.
|
|
862
|
+
// A host-native record's declared fields stay with its protocol-specific
|
|
863
|
+
// interceptor, which runs before this fallback. An undeclared key reached
|
|
864
|
+
// through a dynamic view is still an ordinary expando on that same native
|
|
865
|
+
// object, so it belongs in the generic sidecar just as it does for a
|
|
866
|
+
// generated record. Excluding host-native records here made
|
|
867
|
+
// `(error as any).code = value` fall through to a C++ member named `code`
|
|
868
|
+
// that the native Error layout never declared.
|
|
869
|
+
if (!staticKeyIsSidecarOnly(ctx, representation, staticKey))
|
|
870
|
+
return null;
|
|
871
|
+
// A key naming one of `Array.prototype`'s own members, undeclared on a
|
|
872
|
+
// receiver whose static type is not an array, is the one shape this
|
|
873
|
+
// fallback must NOT answer generically. `borrowed-builtin-call-bind-
|
|
874
|
+
// source-transform.ts` rewrites `Array.prototype.<member>.call(receiver,
|
|
875
|
+
// ...)` to `receiver.<member>(...)` syntactically, before the checker
|
|
876
|
+
// runs, on the documented assumption that a receiver the borrowed member
|
|
877
|
+
// cannot natively serve is refused "by the ordinary member-call machinery,
|
|
878
|
+
// under its own name" -- i.e. that this very fallback would fail closed.
|
|
879
|
+
// It does not: an expando sidecar exists precisely to answer a program's
|
|
880
|
+
// OWN dynamically-assigned property of this name (`o.join = fn; o.join()`
|
|
881
|
+
// is sound, ordinary JS), so `gea::nativeDynamicGet` renders unconditionally
|
|
882
|
+
// and, finding nothing, throws a `gea::Value` `TypeError` this program
|
|
883
|
+
// never asked for and, unless the borrowed call happens to sit inside a
|
|
884
|
+
// `try`, never catches -- an unrelated pass (real JS: `Array.prototype.join
|
|
885
|
+
// .call(o, sep)` never does a `[[Get]]` of "join" on `o` at all; it invokes
|
|
886
|
+
// the method directly) that certifies clean and aborts at runtime instead.
|
|
887
|
+
// So this refuses BY NAME, the same way `arrayAccessText`'s own
|
|
888
|
+
// `arrayMemberRefusals` refuses a member the array carrier itself cannot
|
|
889
|
+
// render: a program that reaches here is not turned into a silent
|
|
890
|
+
// TypeError or a SIGABRT, it is told at compile time which method and why.
|
|
891
|
+
if (arrayPrototypeMethods.has(staticKey)) {
|
|
892
|
+
throw createCppEmitBlockedError(`property-access:${representation.kind}:get:false`, `"Array.prototype.${staticKey}" has no rendering off a "${representationKey(representation)}" receiver -- only a genuine array carrier ` +
|
|
893
|
+
`dispatches an Array.prototype method natively (emit-prototype-array.ts's arrayMethods); an undeclared "${staticKey}" here would fall through ` +
|
|
894
|
+
`to this receiver's dynamic-property sidecar, which states no generic non-native Array.prototype method and, finding none assigned, would ` +
|
|
895
|
+
`resolve to a non-callable value at the call that follows`);
|
|
896
|
+
}
|
|
897
|
+
// A read the census typed as the ABSENCE itself -- a constant key a closed
|
|
898
|
+
// record declares no field for, `const { fn = function () {} } = {}` --
|
|
899
|
+
// is the language's `undefined`, and there is nothing to consult for it:
|
|
900
|
+
// the layout has no such field by construction, and the census only
|
|
901
|
+
// answers `undefined` for a holder whose static type is closed. Reading
|
|
902
|
+
// the sidecar and demanding an `Undefined` tag back aborted at runtime on
|
|
903
|
+
// exactly the absent key it was meant to spell.
|
|
904
|
+
if (representation.kind === 'record' && operation.result.representation.kind === 'undefined')
|
|
905
|
+
return { text: 'gea::Undefined{}', spelling: null };
|
|
906
|
+
}
|
|
907
|
+
const site = staticKey === undefined ? 'a computed "get" on a native receiver' : 'a dynamic-view "get" on a native receiver';
|
|
908
|
+
const finiteUnion = finiteRecordUnionGetText(ctx, operation, operandText(ctx, operation.receiver));
|
|
909
|
+
if (finiteUnion !== null)
|
|
910
|
+
return { text: finiteUnion, spelling: null };
|
|
911
|
+
const receiver = nativeSidecarReceiver(ctx, operation.receiver, site);
|
|
912
|
+
if (receiver === null)
|
|
913
|
+
return null;
|
|
914
|
+
const key = propertyKeyText(ctx, operation.key, site);
|
|
915
|
+
const read = isPatternSidecarReceiver(operation.receiver)
|
|
916
|
+
? `gea::runtime::regex::dynamicGet(${receiver}, ${key})`
|
|
917
|
+
: `gea::nativeDynamicGet(${receiver}, ${key})`;
|
|
918
|
+
const prototypeMethod = computedClassPrototypeMethodText(ctx, operation);
|
|
919
|
+
// ONE carrier for the whole read, and it is the prototype arm's when there
|
|
920
|
+
// is a prototype arm. A `?:` has a single type, and the two arms are the two
|
|
921
|
+
// halves of one `[[Get]]`: whatever this read yields, it yields at one
|
|
922
|
+
// convention. `boundMethodValueRepresentation` is the authority that decides
|
|
923
|
+
// it for a method value -- receiver first, because that is what the thunk the
|
|
924
|
+
// value points at really takes -- and the sidecar arm's `unboxAs` tag check
|
|
925
|
+
// is equally exact at either spelling, since the expando holds a boxed
|
|
926
|
+
// callable that the same `receivesThis` convention hands the instance back
|
|
927
|
+
// through. Spelling the sidecar arm from the UNCORRECTED result carrier made
|
|
928
|
+
// hono's `raw[key]()` (`HonoRequest.#cachedBody`, five monomorphs) emit a
|
|
929
|
+
// ternary whose arms were `CallableObject<Promise<std::string>()>` and
|
|
930
|
+
// `CallableObject<Promise<std::string>(Ref<Request>)>` and a slot declared as
|
|
931
|
+
// the first while the call passed the receiver the second wants.
|
|
932
|
+
const result = prototypeMethod === null ? operation.result.representation : prototypeMethod.carrier;
|
|
933
|
+
const decoded = unboxedReadText(result, read, site);
|
|
934
|
+
const own = result.kind === 'dynamic' || isPatternSidecarReceiver(operation.receiver)
|
|
935
|
+
? decoded
|
|
936
|
+
: `gea::nativeFieldGet<${cppTypeOf(result)}>(${receiver}, ${key}, [&]() { return ${decoded}; })`;
|
|
937
|
+
if (prototypeMethod === null)
|
|
938
|
+
return { text: own, spelling: null };
|
|
939
|
+
// OrdinaryGetOwnProperty runs before the prototype walk. The native field
|
|
940
|
+
// table and the identity-keyed expando are precisely this object's own
|
|
941
|
+
// properties, so preserve their shadowing before selecting a generated
|
|
942
|
+
// prototype method by name.
|
|
943
|
+
return {
|
|
944
|
+
text: `(gea::nativeDynamicHas(${receiver}, ${key}) ? ${own} : ${prototypeMethod.text})`,
|
|
945
|
+
// Only where the correction actually moved the carrier. Where it did not,
|
|
946
|
+
// the ordinary declaration is already right, and overriding it with the
|
|
947
|
+
// identical spelling would drop the slot out of `ownedValues` for no
|
|
948
|
+
// reason -- a different program, not a different spelling of this one.
|
|
949
|
+
spelling: representationKey(result) === representationKey(operation.result.representation) ? null : (prototypeMethod.spelling ?? null)
|
|
950
|
+
};
|
|
951
|
+
};
|
|
952
|
+
/** `[[Set]]` with a runtime key on a receiver that keeps its native type. */
|
|
953
|
+
export const emitNativeSidecarSet = (ctx, lines, operation) => {
|
|
954
|
+
const callable = callableSidecarReceiver(ctx, operation.receiver);
|
|
955
|
+
if (callable !== null && operation.kind === 'set') {
|
|
956
|
+
// The "own" vs "computed" wording names whether the KEY is one the
|
|
957
|
+
// program wrote, so it asks `staticKeyTexts` -- a value `constantTexts`
|
|
958
|
+
// only later folds would otherwise mislabel a genuinely computed key as
|
|
959
|
+
// an own, statically-named one in this description.
|
|
960
|
+
const site = ctx.staticKeyTexts.has(operation.key.value)
|
|
961
|
+
? 'an own "set" on a callable receiver'
|
|
962
|
+
: 'a computed "set" on a callable receiver';
|
|
963
|
+
const key = propertyKeyText(ctx, operation.key, site);
|
|
964
|
+
const value = boxedValueText(ctx, operation.value, site);
|
|
965
|
+
// CallableConstructorObject has the same identity-owned Function table as
|
|
966
|
+
// CallableObject, but must first materialize its non-configurable own
|
|
967
|
+
// `prototype` before an ordinary Set/Delete can observe it. Keep this as
|
|
968
|
+
// a native table operation; widening the constructor itself would erase
|
|
969
|
+
// its independently typed [[Call]] and [[Construct]] entries.
|
|
970
|
+
const write = operation.receiver.representation.kind === 'function-and-constructor'
|
|
971
|
+
? `([&]() -> bool { const auto& __gea_callable = ${callable}; gea::installCallableOwnFacts(__gea_callable.functionObjectIdentity(), __gea_callable.name(), __gea_callable.length()); ` +
|
|
972
|
+
`const gea::PropertyKey __gea_key = ${key}; ` +
|
|
973
|
+
`if (!__gea_key.isSymbol() && __gea_key.text() == "prototype") gea::installCallableConstructorPrototype(__gea_callable); ` +
|
|
974
|
+
`return __gea_callable.functionObjectIdentity()->properties->set(__gea_key, ${value}, gea::Value::box(gea::Value::Tag::Function, __gea_callable)); })()`
|
|
975
|
+
: `gea::callableDynamicSet(${callable}, ${key}, ${value})`;
|
|
976
|
+
if (operation.strict) {
|
|
977
|
+
lines.push(`if (!${write}) gea::host::throwRuntimeError("TypeError", "Cannot assign to read-only Function own property");`);
|
|
978
|
+
}
|
|
979
|
+
else
|
|
980
|
+
lines.push(`${write};`);
|
|
981
|
+
if (!operation.result || operation.result.representation.kind === 'void')
|
|
982
|
+
return true;
|
|
983
|
+
const threaded = alignedValueText(ctx, 'emit-dynamic-properties.ts:752', operation.receiver.representation, operation.result.representation, callable);
|
|
984
|
+
if (threaded === null) {
|
|
985
|
+
throw createCppEmitBlockedError(`conversion:${representationKey(operation.receiver.representation)}->${representationKey(operation.result.representation)}`, `${site} publishes a "${operation.result.representation.kind}" carrier as the assignment's own value, and this backend cannot spell a ` +
|
|
986
|
+
`"${operation.receiver.representation.kind}" receiver as one`);
|
|
987
|
+
}
|
|
988
|
+
lines.push(`${defineValue(ctx, operation.result)} = ${threaded};`);
|
|
989
|
+
return true;
|
|
990
|
+
}
|
|
991
|
+
// Whether this write lands on a declared field/accessor (deferred to
|
|
992
|
+
// another branch) or the expando sidecar is a claim, not a fold: ask
|
|
993
|
+
// `staticKeyTexts` so a value `constantTexts` only later accumulates (a
|
|
994
|
+
// render-time `typeof` fold) can never be mistaken for a declared name.
|
|
995
|
+
const staticKey = ctx.staticKeyTexts.get(operation.key.value);
|
|
996
|
+
if (staticKey !== undefined) {
|
|
997
|
+
const representation = operation.receiver.representation;
|
|
998
|
+
if (!staticKeyIsSidecarOnly(ctx, representation, staticKey))
|
|
999
|
+
return false;
|
|
1000
|
+
// An accessor is installed on the class prototype rather than in instance
|
|
1001
|
+
// storage, so `declaredRecordFieldOf` correctly finds no struct field for
|
|
1002
|
+
// it. That absence does not make the write an expando: OrdinarySet must
|
|
1003
|
+
// call the inherited setter. Leave this constant key for emit-properties'
|
|
1004
|
+
// class accessor branch. Methods remain sidecar writes because assigning
|
|
1005
|
+
// one creates an own property that shadows the writable prototype method.
|
|
1006
|
+
if (representation.kind === 'class-ref' && classMemberOf(ctx.classes, representation.declaration, staticKey)?.kind === 'accessor') {
|
|
1007
|
+
return false;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
const site = staticKey === undefined ? 'a computed "set" on a native receiver' : 'a dynamic-view "set" on a native receiver';
|
|
1011
|
+
const receiver = nativeSidecarReceiver(ctx, operation.receiver, site);
|
|
1012
|
+
if (receiver === null)
|
|
1013
|
+
return false;
|
|
1014
|
+
const key = propertyKeyText(ctx, operation.key, site);
|
|
1015
|
+
const value = boxedValueText(ctx, operation.value, site);
|
|
1016
|
+
const generated = generatedNativeSidecarReceiver(ctx, operation.receiver, site);
|
|
1017
|
+
const write = isPatternSidecarReceiver(operation.receiver)
|
|
1018
|
+
? `gea::runtime::regex::dynamicSet(${receiver}, ${key}, ${value})`
|
|
1019
|
+
: generated === null
|
|
1020
|
+
? `gea::nativeDynamicSet(${receiver}, ${key}, ${value})`
|
|
1021
|
+
: generatedNativeWriteText(generated, key, value);
|
|
1022
|
+
if (operation.kind === 'set' && operation.strict) {
|
|
1023
|
+
lines.push(`if (!${write}) gea::host::throwRuntimeError("TypeError", "Cannot assign to read-only property");`);
|
|
1024
|
+
}
|
|
1025
|
+
else {
|
|
1026
|
+
lines.push(`${write};`);
|
|
1027
|
+
}
|
|
1028
|
+
// The store's own result is the receiver threaded onward, exactly as a
|
|
1029
|
+
// struct field store publishes the object it wrote into. It is RECONCILED
|
|
1030
|
+
// rather than assigned as it stands: the receiver of a sidecar write reached
|
|
1031
|
+
// its native carrier through a cast, so the expression's own published
|
|
1032
|
+
// carrier is what the cast said (`dynamic` for `(this as any)[k] = v`) and
|
|
1033
|
+
// not what the receiver physically is. A pair the conversion table cannot
|
|
1034
|
+
// spell is refused by name -- writing a `class-ref` into a slot declared as
|
|
1035
|
+
// something else would be a wrong answer, not a spelling gap.
|
|
1036
|
+
if (!operation.result || operation.result.representation.kind === 'void')
|
|
1037
|
+
return true;
|
|
1038
|
+
const produced = operation.result.representation;
|
|
1039
|
+
const threaded = alignedValueText(ctx, 'emit-dynamic-properties.ts:808', operation.receiver.representation, produced, receiver);
|
|
1040
|
+
if (threaded === null) {
|
|
1041
|
+
throw createCppEmitBlockedError(`conversion:${representationKey(operation.receiver.representation)}->${representationKey(produced)}`, `${site} publishes a "${produced.kind}" carrier as the assignment's own value, and this backend cannot spell a ` +
|
|
1042
|
+
`"${operation.receiver.representation.kind}" receiver as one`);
|
|
1043
|
+
}
|
|
1044
|
+
lines.push(`${defineValue(ctx, operation.result)} = ${threaded};`);
|
|
1045
|
+
return true;
|
|
1046
|
+
};
|
|
1047
|
+
/**
|
|
1048
|
+
* `delete` over a `dictionary` receiver's own `std::map`-backed table --
|
|
1049
|
+
* `Dictionary::erase`/`NumericDictionary::erase` (gea_runtime.h), the same
|
|
1050
|
+
* table `dictionaryTableOf` (emit-properties.ts) already builds the
|
|
1051
|
+
* read/subscript spellings for. Reused rather than re-derived so a delete and
|
|
1052
|
+
* a read of the identical receiver can never disagree about which member
|
|
1053
|
+
* expression reaches the table.
|
|
1054
|
+
*
|
|
1055
|
+
* `deleteProperty` and not `erase`: since `Object.defineProperty` on a
|
|
1056
|
+
* dictionary retains attributes, an entry CAN be non-configurable, and
|
|
1057
|
+
* `[[Delete]]` (ECMA-262 10.1.10) answers false for one rather than removing
|
|
1058
|
+
* it. This used to be `erase` plus a literal `true` -- correct while every
|
|
1059
|
+
* entry was configurable, and the honest comment for it said so. `erase`
|
|
1060
|
+
* stays the unconditional removal the container's internal rewrites need.
|
|
1061
|
+
*/
|
|
1062
|
+
const emitDictionaryDelete = (ctx, lines, operation) => {
|
|
1063
|
+
const table = dictionaryTableOf(ctx, operation.receiver, operation.key);
|
|
1064
|
+
if (table === null)
|
|
1065
|
+
return false;
|
|
1066
|
+
emitDeleteOutcome(ctx, lines, operation, `${table.member}deleteProperty(${table.key})`);
|
|
1067
|
+
return true;
|
|
1068
|
+
};
|
|
1069
|
+
/**
|
|
1070
|
+
* `delete` over the native-sidecar receiver: a statically typed object's own
|
|
1071
|
+
* expando table, the same one `nativeSidecarGetText`/`emitNativeSidecarSet`
|
|
1072
|
+
* above read and write. `gea::nativeDynamicDelete` (gea_runtime.h) is the
|
|
1073
|
+
* runtime's own answer for BOTH halves of what a dynamic key on a native
|
|
1074
|
+
* receiver can name: a currently-present declared struct field, which it
|
|
1075
|
+
* refuses to remove because a runtime-only key carries no field-specific
|
|
1076
|
+
* reset recipe, and an expando key, which it actually erases. That runtime check
|
|
1077
|
+
* is exactly what makes a COMPUTED key safe to route here even though it
|
|
1078
|
+
* might, at runtime, turn out to name a field: the answer is still correct,
|
|
1079
|
+
* never a silent no-op reported as success.
|
|
1080
|
+
*
|
|
1081
|
+
* A constant key naming an optional generated field has more information: the
|
|
1082
|
+
* emitter can clear its typed value and independent presence bit, which is the
|
|
1083
|
+
* ordinary configurable-property delete. A plain record's REQUIRED field never
|
|
1084
|
+
* reaches here: `ir/certify/property-access.ts` leaves its `record:delete`
|
|
1085
|
+
* row unclaimed (`deleteNamesRecordExpandoKey`), because no direct read of a
|
|
1086
|
+
* required field consults its presence bit, and claiming the field disappeared
|
|
1087
|
+
* would make direct reads and reflective key queries disagree. A class
|
|
1088
|
+
* instance's constructor-assigned field is the one exception this emitter
|
|
1089
|
+
* keeps: `grouped-field-read.runtime.js` deletes one and reads it back only
|
|
1090
|
+
* through the computed chain, which does consult presence.
|
|
1091
|
+
*/
|
|
1092
|
+
const emitNativeSidecarDelete = (ctx, lines, operation) => {
|
|
1093
|
+
const table = recordIndexSidecarTableOf(ctx, operation.receiver, operation.key);
|
|
1094
|
+
if (table?.disjoint) {
|
|
1095
|
+
const attributeKey = recordIndexAttributeKeyText(table.index, operation.key.representation, '__gea_key');
|
|
1096
|
+
const answer = `([&]() -> bool { const auto __gea_key = ${table.key}; const auto __gea_attribute_key = ${attributeKey}; ` +
|
|
1097
|
+
`if (${table.member}has(__gea_key) && !${table.attributes}.deleteAllowed(__gea_attribute_key)) return false; ` +
|
|
1098
|
+
`${table.member}erase(__gea_key); ${table.attributes}.erase(__gea_attribute_key); return true; })()`;
|
|
1099
|
+
emitDeleteOutcome(ctx, lines, operation, answer);
|
|
1100
|
+
return true;
|
|
1101
|
+
}
|
|
1102
|
+
const site = 'a "delete" on a native receiver';
|
|
1103
|
+
const representation = operation.receiver.representation;
|
|
1104
|
+
const ownedIndexed = (representation.kind === 'record-with-index' && representation.ownership !== 'shared-refcount') ||
|
|
1105
|
+
(representation.kind === 'native-record-ref' &&
|
|
1106
|
+
representation.ownership !== 'shared-refcount' &&
|
|
1107
|
+
representation.native === null &&
|
|
1108
|
+
recordIndexesOfShape(ctx.deriver, representation.shapeId).length > 0);
|
|
1109
|
+
if (ownedIndexed) {
|
|
1110
|
+
const receiver = operandText(ctx, operation.receiver);
|
|
1111
|
+
const ownership = representation.kind === 'record-with-index' || representation.kind === 'native-record-ref' ? representation.ownership : 'owned';
|
|
1112
|
+
const accessor = memberAccessOperator(ownership);
|
|
1113
|
+
const key = propertyKeyText(ctx, operation.key, site);
|
|
1114
|
+
const call = `([&]() -> bool { const gea::PropertyKey __gea_key = ${key}; ` +
|
|
1115
|
+
`if (${receiver}${accessor}gea_matchesOwnField(__gea_key)) return ${receiver}${accessor}gea_deleteOwnField(__gea_key); ` +
|
|
1116
|
+
`if (${receiver}${accessor}gea_matchesOwnIndex(__gea_key)) return ${receiver}${accessor}gea_deleteOwnIndex(__gea_key); return true; })()`;
|
|
1117
|
+
emitDeleteOutcome(ctx, lines, operation, call);
|
|
1118
|
+
return true;
|
|
1119
|
+
}
|
|
1120
|
+
const receiver = nativeSidecarReceiver(ctx, operation.receiver, site);
|
|
1121
|
+
if (receiver === null)
|
|
1122
|
+
return false;
|
|
1123
|
+
const key = propertyKeyText(ctx, operation.key, site);
|
|
1124
|
+
const generated = generatedNativeSidecarReceiver(ctx, operation.receiver, site);
|
|
1125
|
+
const call = generated === null ? `gea::nativeDynamicDelete(${receiver}, ${key})` : generatedNativeDeleteText(generated, key);
|
|
1126
|
+
emitDeleteOutcome(ctx, lines, operation, call);
|
|
1127
|
+
return true;
|
|
1128
|
+
};
|
|
1129
|
+
/**
|
|
1130
|
+
* `delete` over a `native-handle` receiver (`Math`, `Array.prototype`, ...),
|
|
1131
|
+
* for a compile-time-constant key.
|
|
1132
|
+
*
|
|
1133
|
+
* A `native-handle` is a zero-size compile-time tag, not a runtime object
|
|
1134
|
+
* with a table to erase a slot from -- so what this answers is ECMA-262
|
|
1135
|
+
* 10.1.10.1 `OrdinaryDelete`'s OWN outcome, not a real removal:
|
|
1136
|
+
*
|
|
1137
|
+
* - A key the host member table does not claim at all names no own property
|
|
1138
|
+
* (`hostMemberOf` returns `undefined`), so `[[GetOwnProperty]]` would answer
|
|
1139
|
+
* `undefined` and step 2 of `OrdinaryDelete` returns `true` immediately --
|
|
1140
|
+
* there was never anything to delete, so nothing needs to happen.
|
|
1141
|
+
* - A `'property'` row is a data constant: every one of these (21.3.1's Math
|
|
1142
|
+
* values; a builtin function's own restricted `name`/`length`, 10.2.4) is
|
|
1143
|
+
* specified non-configurable, so `OrdinaryDelete` returns `false` without
|
|
1144
|
+
* removing anything, and that is exactly what deleting one of these
|
|
1145
|
+
* observably does -- nothing, forever.
|
|
1146
|
+
* - A `'method'` row (`Math.pow`, ...) IS specified configurable, so a
|
|
1147
|
+
* faithful answer would actually remove it -- and this compiler has no
|
|
1148
|
+
* per-instance storage a `native-handle` could lose a member from (every
|
|
1149
|
+
* handle of one protocol is the same zero-size tag), so refusing by name is
|
|
1150
|
+
* the honest answer rather than reporting a `true` that changes nothing.
|
|
1151
|
+
*
|
|
1152
|
+
* A computed (runtime) key refuses for the same reason `nativeHandleMemberText`
|
|
1153
|
+
* does for a get: there is no runtime member table to search a non-constant
|
|
1154
|
+
* key against.
|
|
1155
|
+
*/
|
|
1156
|
+
const emitNativeHandleDelete = (ctx, lines, operation) => {
|
|
1157
|
+
const representation = operation.receiver.representation;
|
|
1158
|
+
if (representation.kind !== 'native-handle')
|
|
1159
|
+
return false;
|
|
1160
|
+
const site = 'a "delete" on a native-handle receiver';
|
|
1161
|
+
// Which branch fires (a per-protocol member lookup vs. the runtime search
|
|
1162
|
+
// over the intrinsic table) is a claim, not a fold: ask `staticKeyTexts` so
|
|
1163
|
+
// a value `constantTexts` only later accumulates (a render-time `typeof`
|
|
1164
|
+
// fold) can never be treated as a name the program wrote.
|
|
1165
|
+
const staticKey = ctx.staticKeyTexts.get(operation.key.value);
|
|
1166
|
+
const memberProtocol = representation.native ?? representation.protocol;
|
|
1167
|
+
if (staticKey === undefined) {
|
|
1168
|
+
// The computed-key half, over the same per-protocol sidecar the computed
|
|
1169
|
+
// get and set use (`emit-host-properties.ts`'s
|
|
1170
|
+
// `computedNativeHandleGetText` states the design): a non-configurable
|
|
1171
|
+
// member answers false and changes nothing, anything else is marked
|
|
1172
|
+
// removed there and answers true.
|
|
1173
|
+
const members = representation.native === null ? ctx.hosts.intrinsicMembers.get(memberProtocol) : undefined;
|
|
1174
|
+
if (members === undefined) {
|
|
1175
|
+
throw createCppEmitBlockedError('property-access:native-handle:delete:true', `${site} has no compile-time-constant key, and a "${representation.protocol}" host handle has no runtime member table for a computed key to search`);
|
|
1176
|
+
}
|
|
1177
|
+
const computedSite = `a computed "delete" on a "${representation.protocol}" host handle`;
|
|
1178
|
+
const fixed = members
|
|
1179
|
+
.filter((member) => !intrinsicMemberValueOf(ctx, memberProtocol, member, computedSite).configurable)
|
|
1180
|
+
.map((member) => `__gea_key.text() == ${cppStringLiteral(member.name)}`);
|
|
1181
|
+
const keep = fixed.length === 0 ? 'false' : `(!__gea_key.isSymbol() && (${fixed.join(' || ')}))`;
|
|
1182
|
+
const answer = `([&]() -> bool { const gea::PropertyKey __gea_key = ${propertyKeyText(ctx, operation.key, computedSite)}; if (${keep}) return false; ` +
|
|
1183
|
+
`gea::detail::hostIntrinsicSidecar(${cppStringLiteral(memberProtocol)}).remove(__gea_key); return true; })()`;
|
|
1184
|
+
emitDeleteOutcome(ctx, lines, operation, answer);
|
|
1185
|
+
return true;
|
|
1186
|
+
}
|
|
1187
|
+
const host = hostMemberOf(ctx.hosts.members, memberProtocol, staticKey);
|
|
1188
|
+
const answer = host === undefined ? 'true' : host.kind === 'property' ? 'false' : null;
|
|
1189
|
+
if (answer === null) {
|
|
1190
|
+
throw createCppEmitBlockedError('property-access:native-handle:delete:false', `${site} names "${representation.protocol}.${staticKey}", a host METHOD -- ECMA-262 specifies it configurable, so a faithful ` +
|
|
1191
|
+
'[[Delete]] would actually remove it, and this backend has no per-instance storage a zero-size native handle could lose a member from');
|
|
1192
|
+
}
|
|
1193
|
+
emitDeleteOutcome(ctx, lines, operation, answer);
|
|
1194
|
+
return true;
|
|
1195
|
+
};
|
|
1196
|
+
/**
|
|
1197
|
+
* `[[Delete]]` and `[[HasProperty]]` as IR operations, with their refusals.
|
|
1198
|
+
*
|
|
1199
|
+
* Four receivers have an answer for a key to remove: a `gea::Value`, whether
|
|
1200
|
+
* it owns a `DynamicObject` outright or boxes a native struct whose field
|
|
1201
|
+
* dispatcher and expando together describe it (`emitDynamicDelete`); a
|
|
1202
|
+
* `dictionary`'s own `std::map`-backed storage (`emitDictionaryDelete`); a
|
|
1203
|
+
* statically typed object's own expando sidecar, reached through a computed
|
|
1204
|
+
* key (`emitNativeSidecarDelete`); and a `native-handle`, which has no table
|
|
1205
|
+
* at all but whose ANSWER (never its effect) is still knowable from the same
|
|
1206
|
+
* static attribute table its property reads already consult
|
|
1207
|
+
* (`emitNativeHandleDelete`). Every other carrier is a fixed struct with no
|
|
1208
|
+
* sidecar or an Array's slots -- none of which has a key to remove at all --
|
|
1209
|
+
* so it is refused by name rather than given a plausible `true`.
|
|
1210
|
+
*/
|
|
1211
|
+
/**
|
|
1212
|
+
* `delete fn[k]` on a callable: the shared function-object table's own
|
|
1213
|
+
* [[Delete]], with the `name`/`length` facts installed first so deleting one
|
|
1214
|
+
* of them answers the way ECMA-262 says (both configurable, 10.2.10) and a
|
|
1215
|
+
* later `hasOwnProperty` sees it gone.
|
|
1216
|
+
*/
|
|
1217
|
+
const emitCallableSidecarDelete = (ctx, lines, operation) => {
|
|
1218
|
+
const callable = callableSidecarReceiver(ctx, operation.receiver);
|
|
1219
|
+
if (callable === null)
|
|
1220
|
+
return false;
|
|
1221
|
+
const site = 'a "delete" on a callable receiver';
|
|
1222
|
+
const key = propertyKeyText(ctx, operation.key, site);
|
|
1223
|
+
const constructorSetup = operation.receiver.representation.kind === 'function-and-constructor'
|
|
1224
|
+
? `if (!__gea_key.isSymbol() && __gea_key.text() == "prototype") gea::installCallableConstructorPrototype(__gea_callable); `
|
|
1225
|
+
: '';
|
|
1226
|
+
const answer = `([&]() -> bool { const auto& __gea_callable = ${callable}; ` +
|
|
1227
|
+
'gea::installCallableOwnFacts(__gea_callable.functionObjectIdentity(), __gea_callable.name(), __gea_callable.length()); ' +
|
|
1228
|
+
`const gea::PropertyKey __gea_key = ${key}; ${constructorSetup}` +
|
|
1229
|
+
'return __gea_callable.functionObjectIdentity()->properties->deleteOwnProperty(__gea_key); })()';
|
|
1230
|
+
emitDeleteOutcome(ctx, lines, operation, answer);
|
|
1231
|
+
return true;
|
|
1232
|
+
};
|
|
1233
|
+
export const emitDeleteOperation = (ctx, lines, operation) => {
|
|
1234
|
+
if (emitDynamicDelete(ctx, lines, operation))
|
|
1235
|
+
return;
|
|
1236
|
+
if (emitCallableSidecarDelete(ctx, lines, operation))
|
|
1237
|
+
return;
|
|
1238
|
+
if (emitDictionaryDelete(ctx, lines, operation))
|
|
1239
|
+
return;
|
|
1240
|
+
if (emitNativeSidecarDelete(ctx, lines, operation))
|
|
1241
|
+
return;
|
|
1242
|
+
if (emitNativeHandleDelete(ctx, lines, operation))
|
|
1243
|
+
return;
|
|
1244
|
+
// The refusal's key-form suffix names whether the key is one the program
|
|
1245
|
+
// wrote, matching the claim every branch above just asked -- `staticKeyTexts`,
|
|
1246
|
+
// not `constantTexts`, or a render-time `typeof` fold could make this code
|
|
1247
|
+
// report "static" for a key none of those branches actually treated as one.
|
|
1248
|
+
throw createCppEmitBlockedError(`property-access:${operation.receiver.representation.kind}:delete:${String(ctx.staticKeyTexts.get(operation.key.value) === undefined)}`, `a "delete" on a "${operation.receiver.representation.kind}" receiver has no property table to remove a key from`);
|
|
1249
|
+
};
|