@scriptc/compiler 0.4.8 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/node-fallback/buffer.d.ts +2 -0
- package/ambient/node-fallback/child_process.d.ts +9 -3
- package/ambient/node-fallback/dns-promises.d.ts +25 -0
- package/ambient/node-fallback/dns.d.ts +29 -0
- package/ambient/node-fallback/test.d.ts +7 -0
- package/ambient/scriptc-node-fallback.d.ts +145 -2
- package/ambient/scriptc-overrides.d.ts +22 -13
- package/dist/backend/build-cache.d.ts +1 -1
- package/dist/backend/build-cache.js +1 -1
- package/dist/backend/build-cache.js.map +1 -1
- package/dist/backend/cache-root.d.ts +7 -0
- package/dist/backend/cache-root.js +27 -0
- package/dist/backend/cache-root.js.map +1 -1
- package/dist/backend/executable-features.js +5 -1
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/link-plan.js +7 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.d.ts +12 -1
- package/dist/backend/llvm/bytes-loop-versions.js +107 -30
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.test.js +96 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +1 -0
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +16 -5
- package/dist/backend/llvm/classes.js +34 -6
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +21 -2
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +9 -0
- package/dist/backend/llvm/common.js +9 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/cpu-dispatch.d.ts +36 -2
- package/dist/backend/llvm/cpu-dispatch.js +96 -2
- package/dist/backend/llvm/cpu-dispatch.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +5 -2
- package/dist/backend/llvm/dense-array-access.js +16 -12
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +3 -1
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +24 -0
- package/dist/backend/llvm/dyn.js +117 -3
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +6 -0
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-journal.d.ts +1 -0
- package/dist/backend/llvm/emit-journal.js.map +1 -1
- package/dist/backend/llvm/emit-module.js +48 -5
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emit-module.test.js +41 -0
- package/dist/backend/llvm/emit-module.test.js.map +1 -1
- package/dist/backend/llvm/emit-statements.js +11 -0
- package/dist/backend/llvm/emit-statements.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +87 -7
- package/dist/backend/llvm/emitter.js +136 -15
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +28 -6
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +19 -5
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +29 -1
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +104 -6
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +15 -1
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +53 -5
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/inline-arrays.js +1 -1
- package/dist/backend/llvm/inline-arrays.js.map +1 -1
- package/dist/backend/llvm/js-ic.js +126 -2
- package/dist/backend/llvm/js-ic.js.map +1 -1
- package/dist/backend/llvm/lanes.d.ts +38 -0
- package/dist/backend/llvm/lanes.js +778 -0
- package/dist/backend/llvm/lanes.js.map +1 -0
- package/dist/backend/llvm/lanes.test.d.ts +1 -0
- package/dist/backend/llvm/lanes.test.js +402 -0
- package/dist/backend/llvm/lanes.test.js.map +1 -0
- package/dist/backend/llvm/lib-dispatch.js +9 -4
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +20 -0
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +27 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-test.js +11 -0
- package/dist/backend/llvm/lib-test.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +2 -2
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.js +8 -2
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.js +5 -2
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/publish.d.ts +3 -0
- package/dist/backend/llvm/publish.js +2 -2
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/reference-writes.js +1 -0
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/region-groups.js +43 -4
- package/dist/backend/llvm/region-groups.js.map +1 -1
- package/dist/backend/llvm/region-groups.test.js +79 -0
- package/dist/backend/llvm/region-groups.test.js.map +1 -1
- package/dist/backend/llvm/runtime-registries.test.js +32 -1
- package/dist/backend/llvm/runtime-registries.test.js.map +1 -1
- package/dist/backend/llvm/shapes.js +10 -1
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +1 -1
- package/dist/backend/llvm/string-reads.js +1 -1
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/unwind-abi.js +24 -2
- package/dist/backend/llvm/unwind-abi.js.map +1 -1
- package/dist/backend/llvm/unwind-abi.test.js +38 -0
- package/dist/backend/llvm/unwind-abi.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +3 -0
- package/dist/backend/llvm/walkers.js +20 -2
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +15 -3
- package/dist/backend/native/executable.js +19 -5
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +20 -0
- package/dist/backend/native-codegen-core.js +15 -0
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +5 -0
- package/dist/backend/native-codegen.js +62 -8
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +48 -8
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +27 -3
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-link-info.test.js +17 -1
- package/dist/backend/native-link-info.test.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +1 -1
- package/dist/backend/native-toolchain.js +1 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +14 -1
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/runtime-pack-core.d.ts +9 -3
- package/dist/backend/runtime-pack-core.js +6 -1
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +32 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/targets.d.ts +9 -1
- package/dist/backend/targets.js +11 -2
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +6 -0
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/cli/command.js +15 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +6 -0
- package/dist/cli/mcp.d.ts +72 -0
- package/dist/cli/mcp.js +601 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/mcp.test.d.ts +1 -0
- package/dist/cli/mcp.test.js +380 -0
- package/dist/cli/mcp.test.js.map +1 -0
- package/dist/cli/output-options.d.ts +1 -0
- package/dist/cli/output-options.js +3 -0
- package/dist/cli/output-options.js.map +1 -1
- package/dist/cli/usage.d.ts +51 -1
- package/dist/cli/usage.js +709 -186
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +9 -4
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +17 -0
- package/dist/coverage/report.d.ts +5 -9
- package/dist/coverage/report.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +17 -3
- package/dist/executable/executable-cache.js +17 -3
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/prepare.js +87 -10
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +3 -2
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/canon-map.js +13 -8
- package/dist/frontend/canon-map.js.map +1 -1
- package/dist/frontend/decl-projection.d.ts +18 -0
- package/dist/frontend/decl-projection.js +90 -22
- package/dist/frontend/decl-projection.js.map +1 -1
- package/dist/frontend/decl-projection.test.js +47 -1
- package/dist/frontend/decl-projection.test.js.map +1 -1
- package/dist/frontend/default-library.d.ts +10 -0
- package/dist/frontend/default-library.js +43 -0
- package/dist/frontend/default-library.js.map +1 -0
- package/dist/frontend/fork-target.js +54 -9
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +82 -0
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.test.js +73 -0
- package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
- package/dist/frontend/lowering/abstract-equality.d.ts +2 -1
- package/dist/frontend/lowering/abstract-equality.js +7 -1
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-values.js +2 -2
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/assertion-members.js +52 -2
- package/dist/frontend/lowering/assertion-members.js.map +1 -1
- package/dist/frontend/lowering/builtin-namespaces.d.ts +5 -0
- package/dist/frontend/lowering/builtin-namespaces.js +19 -12
- package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
- package/dist/frontend/lowering/builtins/callable-aliases.js +42 -6
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +12 -11
- package/dist/frontend/lowering/builtins/child-process.js +235 -38
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/compression.d.ts +6 -1
- package/dist/frontend/lowering/builtins/compression.js +3 -3
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.js +2 -2
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +3 -1
- package/dist/frontend/lowering/builtins/crypto.js +9 -1
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.js +26 -6
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/environment.d.ts +13 -1
- package/dist/frontend/lowering/builtins/environment.js +15 -4
- package/dist/frontend/lowering/builtins/environment.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +33 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +213 -11
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +9 -2
- package/dist/frontend/lowering/builtins/module-resolution.js +187 -19
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/performance.js +1 -1
- package/dist/frontend/lowering/builtins/performance.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.js +40 -2
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.js +33 -0
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +9 -5
- package/dist/frontend/lowering/builtins/readline.js +184 -75
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.d.ts +4 -0
- package/dist/frontend/lowering/builtins/url.js +6 -0
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.js +15 -0
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/callable-properties.d.ts +34 -0
- package/dist/frontend/lowering/callable-properties.js +210 -0
- package/dist/frontend/lowering/callable-properties.js.map +1 -0
- package/dist/frontend/lowering/cjs-inline-require.d.ts +16 -0
- package/dist/frontend/lowering/cjs-inline-require.js +105 -0
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
- package/dist/frontend/lowering/cjs-inline-require.test.d.ts +1 -0
- package/dist/frontend/lowering/cjs-inline-require.test.js +61 -0
- package/dist/frontend/lowering/cjs-inline-require.test.js.map +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +82 -2
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +57 -4
- package/dist/frontend/lowering/class-protocols.js +597 -30
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-unions.js +2 -2
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +12 -0
- package/dist/frontend/lowering/coercions/function-adapters.js +62 -0
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +56 -1
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +9 -4
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.d.ts +9 -0
- package/dist/frontend/lowering/collection-ingestion.js +115 -41
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +16 -0
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +66 -10
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +61 -5
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/filter-predicates.js +11 -0
- package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.d.ts +15 -0
- package/dist/frontend/lowering/containers/indexed-objects.js +213 -30
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/error-name-order.d.ts +16 -0
- package/dist/frontend/lowering/error-name-order.js +61 -0
- package/dist/frontend/lowering/error-name-order.js.map +1 -1
- package/dist/frontend/lowering/expressions/asserted-receiver.d.ts +17 -0
- package/dist/frontend/lowering/expressions/asserted-receiver.js +123 -1
- package/dist/frontend/lowering/expressions/asserted-receiver.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +147 -20
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +63 -14
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/erased-delete.d.ts +59 -0
- package/dist/frontend/lowering/expressions/erased-delete.js +247 -0
- package/dist/frontend/lowering/expressions/erased-delete.js.map +1 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +10 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +48 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +20 -0
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/narrowing.d.ts +7 -2
- package/dist/frontend/lowering/expressions/narrowing.js +77 -45
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +62 -19
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +19 -0
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +7 -7
- package/dist/frontend/lowering/expressions/property-access.js +247 -48
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/relational.d.ts +1 -0
- package/dist/frontend/lowering/expressions/relational.js +18 -8
- package/dist/frontend/lowering/expressions/relational.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js +11 -5
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +121 -11
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/function-context.d.ts +10 -0
- package/dist/frontend/lowering/function-context.js +36 -0
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +8 -8
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/handle-properties.d.ts +62 -3
- package/dist/frontend/lowering/handle-properties.js +674 -26
- package/dist/frontend/lowering/handle-properties.js.map +1 -1
- package/dist/frontend/lowering/handle-properties.test.js +95 -2
- package/dist/frontend/lowering/handle-properties.test.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +12 -0
- package/dist/frontend/lowering/lower-builtin-values.js +44 -0
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +328 -136
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +82 -17
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +113 -9
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.d.ts +13 -21
- package/dist/frontend/lowering/lower-expando.js +90 -126
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +2 -2
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +65 -0
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +471 -0
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +36 -10
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-node-island.js +28 -0
- package/dist/frontend/lowering/lower-node-island.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +53 -7
- package/dist/frontend/lowering/lower-server.js +213 -42
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.js +50 -7
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +24 -0
- package/dist/frontend/lowering/lower-stmts.js +463 -220
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +2 -2
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.js +71 -2
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +81 -10
- package/dist/frontend/lowering/lowerer.js +319 -72
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/new-target.js +10 -2
- package/dist/frontend/lowering/new-target.js.map +1 -1
- package/dist/frontend/lowering/nullish-empty-pattern.js +3 -3
- package/dist/frontend/lowering/nullish-empty-pattern.js.map +1 -1
- package/dist/frontend/lowering/partial-assertions.js +30 -5
- package/dist/frontend/lowering/partial-assertions.js.map +1 -1
- package/dist/frontend/lowering/primitive-throws.js +91 -1
- package/dist/frontend/lowering/primitive-throws.js.map +1 -1
- package/dist/frontend/lowering/primitive-wrappers.d.ts +9 -0
- package/dist/frontend/lowering/primitive-wrappers.js +2 -2
- package/dist/frontend/lowering/primitive-wrappers.js.map +1 -1
- package/dist/frontend/lowering/promise-executor-adapter.js +5 -2
- package/dist/frontend/lowering/promise-executor-adapter.js.map +1 -1
- package/dist/frontend/lowering/record-links.js +7 -2
- package/dist/frontend/lowering/record-links.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +4 -0
- package/dist/frontend/lowering/surfaces.js +118 -2
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/surfaces.test.d.ts +1 -0
- package/dist/frontend/lowering/surfaces.test.js +31 -0
- package/dist/frontend/lowering/surfaces.test.js.map +1 -0
- package/dist/frontend/mock-shapes.js +3 -3
- package/dist/frontend/mock-shapes.js.map +1 -1
- package/dist/frontend/npm-static-ladder.d.ts +21 -0
- package/dist/frontend/npm-static-ladder.js +2 -0
- package/dist/frontend/npm-static-ladder.js.map +1 -0
- package/dist/frontend/npm-static-ladder.test.d.ts +1 -0
- package/dist/frontend/npm-static-ladder.test.js +138 -0
- package/dist/frontend/npm-static-ladder.test.js.map +1 -0
- package/dist/frontend/npm-static-status.d.ts +15 -0
- package/dist/frontend/npm-static-status.js +2 -0
- package/dist/frontend/npm-static-status.js.map +1 -0
- package/dist/frontend/package-shims.js +1 -1
- package/dist/frontend/package-shims.js.map +1 -1
- package/dist/frontend/pipeline.d.ts +1 -1
- package/dist/frontend/pipeline.js +222 -25
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +4 -0
- package/dist/frontend/program-analysis.js +6 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.js +258 -32
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +30 -0
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.js +29 -5
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +40 -0
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/services.d.ts +8 -0
- package/dist/frontend/services.js +7 -0
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +7 -0
- package/dist/frontend/ts7/checker.js +12 -0
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +1 -0
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/program-host.d.ts +39 -2
- package/dist/frontend/ts7/program-host.js +62 -8
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/program-host.test.js +33 -0
- package/dist/frontend/ts7/program-host.test.js.map +1 -1
- package/dist/frontend/ts7/session-cache.d.ts +5 -1
- package/dist/frontend/ts7/session-cache.js +7 -1
- package/dist/frontend/ts7/session-cache.js.map +1 -1
- package/dist/frontend/ts7/session-cache.test.js +37 -0
- package/dist/frontend/ts7/session-cache.test.js.map +1 -1
- package/dist/frontend/ts7/session.js +19 -1
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/source-parser.d.ts +17 -2
- package/dist/frontend/ts7/source-parser.js +61 -2
- package/dist/frontend/ts7/source-parser.js.map +1 -1
- package/dist/frontend/ts7/source-parser.test.js +55 -2
- package/dist/frontend/ts7/source-parser.test.js.map +1 -1
- package/dist/frontend/tsc-codes.d.ts +3 -2
- package/dist/frontend/tsc-codes.js +129 -22
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +5 -11
- package/dist/frontend/type-mapper.js +380 -70
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +67 -7
- package/dist/index.js.map +1 -1
- package/dist/ir/builtin-effects.js +29 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +72 -6
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/codec.generated.d.ts +1 -1
- package/dist/ir/codec.generated.js +321 -263
- package/dist/ir/codec.generated.js.map +1 -1
- package/dist/ir/constant-length-clones.d.ts +26 -0
- package/dist/ir/constant-length-clones.js +589 -0
- package/dist/ir/constant-length-clones.js.map +1 -0
- package/dist/ir/constant-length-clones.test.d.ts +1 -0
- package/dist/ir/constant-length-clones.test.js +292 -0
- package/dist/ir/constant-length-clones.test.js.map +1 -0
- package/dist/ir/constant-tables.d.ts +10 -5
- package/dist/ir/constant-tables.js +83 -17
- package/dist/ir/constant-tables.js.map +1 -1
- package/dist/ir/constant-tables.test.js +58 -1
- package/dist/ir/constant-tables.test.js.map +1 -1
- package/dist/ir/fields.generated.js +5 -2
- package/dist/ir/fields.generated.js.map +1 -1
- package/dist/ir/function-references.js +2 -0
- package/dist/ir/function-references.js.map +1 -1
- package/dist/ir/function-references.test.js +13 -0
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/integer-loops.js +1 -0
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +16 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/ir.d.ts +50 -6
- package/dist/ir/ir.js +44 -2
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +83 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/js-groups.js +5 -1
- package/dist/ir/js-groups.js.map +1 -1
- package/dist/ir/js-ic.d.ts +20 -0
- package/dist/ir/js-ic.js +81 -4
- package/dist/ir/js-ic.js.map +1 -1
- package/dist/ir/js-ic.test.js +8 -1
- package/dist/ir/js-ic.test.js.map +1 -1
- package/dist/ir/lane-plans.d.ts +86 -0
- package/dist/ir/lane-plans.js +589 -0
- package/dist/ir/lane-plans.js.map +1 -0
- package/dist/ir/lane-plans.test.d.ts +1 -0
- package/dist/ir/lane-plans.test.js +549 -0
- package/dist/ir/lane-plans.test.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +68 -10
- package/dist/ir/runtime-features.js +285 -17
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +190 -1
- package/dist/ir/runtime-features.test.js.map +1 -1
- package/dist/ir/validate.js +61 -24
- package/dist/ir/validate.js.map +1 -1
- package/dist/native/cache.d.ts +5 -0
- package/dist/native/cache.js +23 -1
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cache.test.js +29 -1
- package/dist/native/cache.test.js.map +1 -1
- package/dist/native/cli.js +4 -2
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.d.ts +11 -3
- package/dist/native/compiler.js +102 -16
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +244 -2
- package/dist/native/compiler.test.js.map +1 -1
- package/dist/native/prepare.d.ts +14 -1
- package/dist/native/prepare.js +79 -29
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.test.js +3 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/unchanged.d.ts +80 -0
- package/dist/native/unchanged.js +301 -0
- package/dist/native/unchanged.js.map +1 -0
- package/dist/native/unchanged.test.d.ts +1 -0
- package/dist/native/unchanged.test.js +249 -0
- package/dist/native/unchanged.test.js.map +1 -0
- package/dist/node-islands/boundary.d.ts +16 -0
- package/dist/node-islands/boundary.js +70 -7
- package/dist/node-islands/boundary.js.map +1 -1
- package/dist/node-islands/boundary.test.js +59 -14
- package/dist/node-islands/boundary.test.js.map +1 -1
- package/dist/node-islands/detect.js +203 -47
- package/dist/node-islands/detect.js.map +1 -1
- package/dist/node-islands/detect.test.js +45 -0
- package/dist/node-islands/detect.test.js.map +1 -1
- package/dist/node-islands/growth.js +4 -16
- package/dist/node-islands/growth.js.map +1 -1
- package/dist/node-islands/modules.d.ts +3 -0
- package/dist/node-islands/modules.js +143 -12
- package/dist/node-islands/modules.js.map +1 -1
- package/dist/node-islands/modules.test.js +125 -0
- package/dist/node-islands/modules.test.js.map +1 -1
- package/dist/node-islands/report.d.ts +1 -1
- package/dist/node-islands/report.js +2 -1
- package/dist/node-islands/report.js.map +1 -1
- package/package.json +20 -20
- package/shims/undici/core/request.ts +7 -1
- package/surface-manifest.json +380 -2
|
@@ -1,20 +1,37 @@
|
|
|
1
|
-
/* Own properties that JavaScript adds to a native
|
|
2
|
-
* mixin assigns `spawned.kill = ...` and defines then/catch/finally
|
|
3
|
-
* Reflect.defineProperty, and its callers await the child as a
|
|
1
|
+
/* Own properties that JavaScript adds to a native handle: a ChildProcess
|
|
2
|
+
* (execa's mixin assigns `spawned.kill = ...` and defines then/catch/finally
|
|
3
|
+
* with Reflect.defineProperty, and its callers await the child as a
|
|
4
|
+
* thenable), a Date, RegExp, Map, Set, WeakMap, WeakSet, ArrayBuffer,
|
|
5
|
+
* SharedArrayBuffer or FinalizationRegistry (`d = new Date(); d.tag = 1`).
|
|
4
6
|
*
|
|
5
|
-
* The runtime keeps such properties in a side table per
|
|
7
|
+
* The runtime keeps such properties in a side table per handle
|
|
6
8
|
* (scr_dyn_handle_props.c). Only programs that can add one link it: a
|
|
7
|
-
* JavaScript write of a property onto a typed
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* JavaScript write of a property onto a typed handle, a type-visible
|
|
10
|
+
* definition or integrity call on one, or JavaScript that calls
|
|
11
|
+
* defineProperty in a program whose JavaScript loads child_process. Those
|
|
12
|
+
* programs install the table at start, and their defineProperty,
|
|
13
|
+
* getOwnPropertyDescriptor, thenable await and typed `child.on(event,
|
|
14
|
+
* listener)` calls take the entries that consult it. Every other program
|
|
15
|
+
* lowers exactly as before.
|
|
16
|
+
*
|
|
17
|
+
* A write or definition of a name the handle's class DECLARES is a grant:
|
|
18
|
+
* the compiler censuses the shadowed names per class (`d.getTime = f` on a
|
|
19
|
+
* Date) and hands them to the runtime at start, and the typed readers,
|
|
20
|
+
* calls and deletes of those names go through the checked-dynamic box so
|
|
21
|
+
* the own property wins. Names a builtin algorithm or an implicit
|
|
22
|
+
* conversion reads natively (exec, constructor, then, lastIndex, size, …)
|
|
23
|
+
* keep the refusal, and so does a typed implicit conversion
|
|
24
|
+
* (`String(d)`, `` `${d}` ``, `d == "x"`) of a class whose toString the
|
|
25
|
+
* program replaces. */
|
|
12
26
|
import * as ts from "../ts7/adapter.js";
|
|
27
|
+
import { constituentTypes } from "../ts7/checker.js";
|
|
13
28
|
import { isJsSourceFile, locOf } from "../program.js";
|
|
14
|
-
import { DYN, STRING, VOID } from "../../ir/ir.js";
|
|
15
|
-
import {
|
|
29
|
+
import { DYN, F64, STRING, VOID } from "../../ir/ir.js";
|
|
30
|
+
import { moduleUsesChildProcess } from "../../ir/runtime-features.js";
|
|
31
|
+
import { everyModuleNode, everyStmt, transformStmtList } from "../../ir/traverse.js";
|
|
16
32
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
17
33
|
import { ENTRY_NAME } from "./lowerer.js";
|
|
34
|
+
import { GUARDED_CONSUMERS, consumerName } from "./primitive-wrappers.js";
|
|
18
35
|
import { childStreamSetsEncoding, lowerWithCheckedParams, } from "./builtins/child-process-methods.js";
|
|
19
36
|
/** `child.name = value` in a JavaScript file over a typed child: the write
|
|
20
37
|
* lands in the child's property table through its checked-dynamic box. */
|
|
@@ -121,7 +138,9 @@ function childAdditions(lowerer) {
|
|
|
121
138
|
everyName = true;
|
|
122
139
|
};
|
|
123
140
|
for (const sf of spawns ? files : []) {
|
|
124
|
-
|
|
141
|
+
// Iterative: a whole-file walk must not recurse (a 7000-level
|
|
142
|
+
// expression is a named deferred fence, not a stack overflow).
|
|
143
|
+
walkFile(sf, (node) => {
|
|
125
144
|
if (ts.isBinaryExpression(node) &&
|
|
126
145
|
node.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
127
146
|
(ts.isPropertyAccessExpression(node.left) || ts.isElementAccessExpression(node.left)) &&
|
|
@@ -160,14 +179,479 @@ function childAdditions(lowerer) {
|
|
|
160
179
|
}
|
|
161
180
|
}
|
|
162
181
|
}
|
|
163
|
-
|
|
164
|
-
};
|
|
165
|
-
visit(sf);
|
|
182
|
+
return true;
|
|
183
|
+
});
|
|
166
184
|
}
|
|
167
185
|
known = { written, everyName, any: written.size > 0 || everyName || (spawns && defines) };
|
|
168
186
|
lowerer.childAdditions = known;
|
|
169
187
|
return known;
|
|
170
188
|
}
|
|
189
|
+
/** Stdlib classes whose instances are runtime handles with an own-property
|
|
190
|
+
* table (scr_dyn_handle_props.c's HP_TAGS). */
|
|
191
|
+
const HANDLE_CLASSES = new Set([
|
|
192
|
+
"Date",
|
|
193
|
+
"RegExp",
|
|
194
|
+
"Map",
|
|
195
|
+
"Set",
|
|
196
|
+
"WeakMap",
|
|
197
|
+
"WeakSet",
|
|
198
|
+
"ArrayBuffer",
|
|
199
|
+
"SharedArrayBuffer",
|
|
200
|
+
"FinalizationRegistry",
|
|
201
|
+
]);
|
|
202
|
+
/** Visits the file's nodes outermost first, iteratively: these censuses
|
|
203
|
+
* walk every body before reachability is known, and a recursively nested
|
|
204
|
+
* expression (a 7000-level chain is a named deferred fence at lowering,
|
|
205
|
+
* not a compiler stack overflow) must not overflow here either. */
|
|
206
|
+
function walkFile(sf, visit) {
|
|
207
|
+
const stack = [sf];
|
|
208
|
+
while (stack.length > 0) {
|
|
209
|
+
const node = stack.pop();
|
|
210
|
+
if (!visit(node))
|
|
211
|
+
return;
|
|
212
|
+
ts.forEachChild(node, (child) => {
|
|
213
|
+
stack.push(child);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** The handle class `node`'s checker type names (a union names one only
|
|
218
|
+
* when every constituent is that class), or null. */
|
|
219
|
+
export function handleClassOf(lowerer, node) {
|
|
220
|
+
const names = new Set();
|
|
221
|
+
const visit = (t) => {
|
|
222
|
+
if (t.flags & ts.TypeFlags.Union)
|
|
223
|
+
return constituentTypes(t).every(visit);
|
|
224
|
+
const sym = t.getAliasSymbol() ?? t.getSymbol();
|
|
225
|
+
if (!sym || !HANDLE_CLASSES.has(ts.symbolName(sym)))
|
|
226
|
+
return false;
|
|
227
|
+
if (!sym.declarations.some((d) => lowerer.isStdlibFile(ts.getSourceFileOfNode(d))))
|
|
228
|
+
return false;
|
|
229
|
+
names.add(ts.symbolName(sym));
|
|
230
|
+
return true;
|
|
231
|
+
};
|
|
232
|
+
return visit(lowerer.typeOf(node)) && names.size === 1 ? [...names][0] : null;
|
|
233
|
+
}
|
|
234
|
+
/** Member names a grant never opens (the runtime's deny list,
|
|
235
|
+
* scr_dyn_handle_props.c): a builtin algorithm reads them from the native
|
|
236
|
+
* object (RegExpExec, species, thenables, lastIndex, the RegExp flag
|
|
237
|
+
* getters, Map/Set iteration and size), JSON.stringify looks for toJSON,
|
|
238
|
+
* and the Object.prototype probes have lowerings of their own. The write
|
|
239
|
+
* keeps H1's refusal. */
|
|
240
|
+
const DENIED_HANDLE_MEMBERS = new Set([
|
|
241
|
+
"constructor",
|
|
242
|
+
"then",
|
|
243
|
+
"exec",
|
|
244
|
+
"lastIndex",
|
|
245
|
+
"flags",
|
|
246
|
+
"global",
|
|
247
|
+
"source",
|
|
248
|
+
"ignoreCase",
|
|
249
|
+
"multiline",
|
|
250
|
+
"dotAll",
|
|
251
|
+
"sticky",
|
|
252
|
+
"unicode",
|
|
253
|
+
"unicodeSets",
|
|
254
|
+
"hasIndices",
|
|
255
|
+
"size",
|
|
256
|
+
"toJSON",
|
|
257
|
+
"hasOwnProperty",
|
|
258
|
+
"propertyIsEnumerable",
|
|
259
|
+
"isPrototypeOf",
|
|
260
|
+
"__proto__",
|
|
261
|
+
"__defineGetter__",
|
|
262
|
+
"__defineSetter__",
|
|
263
|
+
"__lookupGetter__",
|
|
264
|
+
"__lookupSetter__",
|
|
265
|
+
]);
|
|
266
|
+
/** Member names a grant never opens for one class, because a builtin
|
|
267
|
+
* algorithm reads them from the native object in a way the wrapper cannot
|
|
268
|
+
* route: Set and Map composition methods read the argument's `has` and
|
|
269
|
+
* `keys` through GetSetRecord, and Date.prototype.toJSON reads
|
|
270
|
+
* `toISOString` from its receiver. A denied grant keeps the H1 refusal. */
|
|
271
|
+
const DENIED_HANDLE_MEMBERS_BY_CLASS = new Map([
|
|
272
|
+
["Date", new Set(["toISOString"])],
|
|
273
|
+
["Map", new Set(["has", "keys"])],
|
|
274
|
+
["Set", new Set(["has", "keys"])],
|
|
275
|
+
]);
|
|
276
|
+
/** Classes whose implicit conversions reach an own property: the runtime's
|
|
277
|
+
* ToPrimitive path calls the tag's ops, which the wrapper routes to the
|
|
278
|
+
* table. Anywhere else an implicit reader would still read the native
|
|
279
|
+
* object, so the grant is refused rather than diverging silently. */
|
|
280
|
+
const GRANTABLE_IMPLICIT_MEMBERS = new Map([
|
|
281
|
+
["Date", new Set(["toString", "toLocaleString", "valueOf"])],
|
|
282
|
+
["RegExp", new Set(["toString", "toLocaleString"])],
|
|
283
|
+
]);
|
|
284
|
+
/** Whether an own property may shadow member `name` of `cls`. */
|
|
285
|
+
function handleMemberGrantable(cls, name) {
|
|
286
|
+
if (DENIED_HANDLE_MEMBERS.has(name))
|
|
287
|
+
return false;
|
|
288
|
+
if (DENIED_HANDLE_MEMBERS_BY_CLASS.get(cls)?.has(name) === true)
|
|
289
|
+
return false;
|
|
290
|
+
if (name === "toString" || name === "valueOf" || name === "toLocaleString")
|
|
291
|
+
return GRANTABLE_IMPLICIT_MEMBERS.get(cls)?.has(name) ?? false;
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
/** A granted name has to survive the grant string's `<Class>:<name>,<name>`
|
|
295
|
+
* encoding, so a name holding one of its separators (or a non-printable
|
|
296
|
+
* character) grants nothing and keeps the refusal. */
|
|
297
|
+
function encodableGrantName(name) {
|
|
298
|
+
if (name.length === 0)
|
|
299
|
+
return false;
|
|
300
|
+
for (let i = 0; i < name.length; i++) {
|
|
301
|
+
const c = name.charCodeAt(i);
|
|
302
|
+
if (c < 0x20 || c > 0x7e || c === 0x2c || c === 0x3b || c === 0x3a)
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
/** The literal name a write or delete target names, or null when the key is
|
|
308
|
+
* computed (which can name any member, so it grants nothing). */
|
|
309
|
+
function literalKeyOf(access) {
|
|
310
|
+
if (ts.isPropertyAccessExpression(access))
|
|
311
|
+
return access.name.text;
|
|
312
|
+
const key = access.argumentExpression;
|
|
313
|
+
return ts.isStringLiteralLike(key) || ts.isNumericLiteral(key) ? key.text : null;
|
|
314
|
+
}
|
|
315
|
+
/** Whether the program's JavaScript adds own properties to handles: a
|
|
316
|
+
* write or delete of a name the handle class does not declare, a
|
|
317
|
+
* defineProperty/defineProperties/preventExtensions/seal/freeze call on a
|
|
318
|
+
* handle, or a write or definition of a member name the class's own
|
|
319
|
+
* properties may shadow (a grant). TypeScript files never count. */
|
|
320
|
+
function handleAdditions(lowerer) {
|
|
321
|
+
const known = lowerer.handleAdditions;
|
|
322
|
+
if (known)
|
|
323
|
+
return known;
|
|
324
|
+
const grants = new Map();
|
|
325
|
+
let any = false;
|
|
326
|
+
const files = lowerer.program
|
|
327
|
+
.getImplementationSourceFiles()
|
|
328
|
+
.filter((sf) => !sf.isDeclarationFile && isJsSourceFile(sf));
|
|
329
|
+
const integrity = new Set([
|
|
330
|
+
"defineProperty",
|
|
331
|
+
"defineProperties",
|
|
332
|
+
"preventExtensions",
|
|
333
|
+
"seal",
|
|
334
|
+
"freeze",
|
|
335
|
+
]);
|
|
336
|
+
// A grant for `name` of `cls`: a member name is granted when the class's
|
|
337
|
+
// own properties may shadow it; any other name is an ordinary table entry.
|
|
338
|
+
const grant = (cls, name) => {
|
|
339
|
+
if (!encodableGrantName(name))
|
|
340
|
+
return;
|
|
341
|
+
let names = grants.get(cls);
|
|
342
|
+
if (!names)
|
|
343
|
+
grants.set(cls, (names = new Set()));
|
|
344
|
+
names.add(name);
|
|
345
|
+
};
|
|
346
|
+
// A write or delete of `name` on a `cls` handle. A member name counts as
|
|
347
|
+
// an addition only when it may be granted: a denied one keeps H1's
|
|
348
|
+
// ordinary-member lowering and installs no table on its own.
|
|
349
|
+
const record = (cls, name, member) => {
|
|
350
|
+
if (name !== null && member && !handleMemberGrantable(cls, name))
|
|
351
|
+
return;
|
|
352
|
+
any = true;
|
|
353
|
+
if (name !== null && member)
|
|
354
|
+
grant(cls, name);
|
|
355
|
+
};
|
|
356
|
+
// `Object.defineProperty(handle, "name", …)`'s key: a literal names the
|
|
357
|
+
// entry, anything else can name any member and grants nothing. Any
|
|
358
|
+
// definition on a handle counts as an addition (H1), so the table answers
|
|
359
|
+
// a denied member with its refusal instead of the ordinary path.
|
|
360
|
+
const recordDefined = (cls, target, key, literal) => {
|
|
361
|
+
any = true;
|
|
362
|
+
const name = literal && (ts.isIdentifier(key) || ts.isStringLiteralLike(key) || ts.isNumericLiteral(key))
|
|
363
|
+
? key.text
|
|
364
|
+
: null;
|
|
365
|
+
if (name === null)
|
|
366
|
+
return;
|
|
367
|
+
const member = hasDeclaredProperty(lowerer, target, name);
|
|
368
|
+
if (member && !handleMemberGrantable(cls, name))
|
|
369
|
+
return;
|
|
370
|
+
if (member)
|
|
371
|
+
grant(cls, name);
|
|
372
|
+
};
|
|
373
|
+
// A whole-program census visits every body, reached or not, so no
|
|
374
|
+
// statement owns the local-class refusal a type query here may trigger
|
|
375
|
+
// (collectLocalClassForType leaves it reported instead of poisoning the
|
|
376
|
+
// compile).
|
|
377
|
+
lowerer.speculativeTypeQueries(() => {
|
|
378
|
+
for (const sf of files) {
|
|
379
|
+
walkFile(sf, (node) => {
|
|
380
|
+
if (ts.isBinaryExpression(node) &&
|
|
381
|
+
ts.isAssignmentOperator(node.operatorToken.kind) &&
|
|
382
|
+
(ts.isPropertyAccessExpression(node.left) || ts.isElementAccessExpression(node.left))) {
|
|
383
|
+
const cls = handleClassOf(lowerer, node.left.expression);
|
|
384
|
+
const name = literalKeyOf(node.left);
|
|
385
|
+
if (cls)
|
|
386
|
+
record(cls, name, name !== null && hasDeclaredProperty(lowerer, node.left.expression, name));
|
|
387
|
+
}
|
|
388
|
+
else if (ts.isDeleteExpression(node) &&
|
|
389
|
+
(ts.isPropertyAccessExpression(node.expression) ||
|
|
390
|
+
ts.isElementAccessExpression(node.expression))) {
|
|
391
|
+
const cls = handleClassOf(lowerer, node.expression.expression);
|
|
392
|
+
const name = literalKeyOf(node.expression);
|
|
393
|
+
// Deleting a name the class declares removes no own property of a
|
|
394
|
+
// handle that has none, and the ordinary delete keeps its answer.
|
|
395
|
+
if (cls &&
|
|
396
|
+
(name === null || !hasDeclaredProperty(lowerer, node.expression.expression, name)))
|
|
397
|
+
record(cls, name, false);
|
|
398
|
+
}
|
|
399
|
+
else if (ts.isCallExpression(node) &&
|
|
400
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
401
|
+
ts.isIdentifier(node.expression.expression) &&
|
|
402
|
+
(node.expression.expression.text === "Object" ||
|
|
403
|
+
node.expression.expression.text === "Reflect") &&
|
|
404
|
+
integrity.has(node.expression.name.text)) {
|
|
405
|
+
const [target, second] = node.arguments.nodes;
|
|
406
|
+
if (!target)
|
|
407
|
+
return true;
|
|
408
|
+
const cls = handleClassOf(lowerer, target);
|
|
409
|
+
if (!cls)
|
|
410
|
+
return true;
|
|
411
|
+
const method = node.expression.name.text;
|
|
412
|
+
if (method !== "defineProperty" && method !== "defineProperties") {
|
|
413
|
+
any = true;
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
if (!second)
|
|
417
|
+
return true;
|
|
418
|
+
if (method === "defineProperty" || !ts.isObjectLiteralExpression(second)) {
|
|
419
|
+
recordDefined(cls, target, second, method === "defineProperty");
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
for (const prop of second.properties.nodes) {
|
|
423
|
+
const nameNode = prop.name;
|
|
424
|
+
if (nameNode !== undefined)
|
|
425
|
+
recordDefined(cls, target, nameNode, true);
|
|
426
|
+
else
|
|
427
|
+
any = true;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return true;
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
const frozen = { grants, any };
|
|
436
|
+
lowerer.handleAdditions = frozen;
|
|
437
|
+
return frozen;
|
|
438
|
+
}
|
|
439
|
+
/** Whether the program's JavaScript adds own properties to handles. */
|
|
440
|
+
export function programAddsHandleProperties(lowerer) {
|
|
441
|
+
return handleAdditions(lowerer).any;
|
|
442
|
+
}
|
|
443
|
+
/** Whether the program's JavaScript writes or defines member `name` of the
|
|
444
|
+
* handle class `receiver` names, so its typed readers and calls reroute
|
|
445
|
+
* through the checked-dynamic box. */
|
|
446
|
+
function memberGranted(lowerer, receiver, name) {
|
|
447
|
+
const additions = handleAdditions(lowerer);
|
|
448
|
+
if (additions.grants.size === 0)
|
|
449
|
+
return false;
|
|
450
|
+
const cls = handleClassOf(lowerer, receiver);
|
|
451
|
+
return cls !== null && additions.grants.get(cls)?.has(name) === true;
|
|
452
|
+
}
|
|
453
|
+
/** The nodes the own-property census above reads the type of: every
|
|
454
|
+
* JavaScript write receiver, delete target and integrity-call target, plus
|
|
455
|
+
* the expression chain `Lowerer.typeOf` walks for a property-access
|
|
456
|
+
* receiver. `Lowerer.emitReachable` batches their types ahead of
|
|
457
|
+
* collection so the census makes no per-node checker request inside a
|
|
458
|
+
* deferred body. */
|
|
459
|
+
export function handlePropertyScanRoots(sourceFiles) {
|
|
460
|
+
const roots = [];
|
|
461
|
+
const receiver = (e) => {
|
|
462
|
+
for (let n = e;;) {
|
|
463
|
+
roots.push(n);
|
|
464
|
+
if (ts.isPropertyAccessExpression(n) ||
|
|
465
|
+
ts.isElementAccessExpression(n) ||
|
|
466
|
+
ts.isParenthesizedExpression(n) ||
|
|
467
|
+
ts.isNonNullExpression(n) ||
|
|
468
|
+
ts.isAsExpression(n))
|
|
469
|
+
n = n.expression;
|
|
470
|
+
else
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
for (const sf of sourceFiles) {
|
|
475
|
+
if (sf.isDeclarationFile || !isJsSourceFile(sf))
|
|
476
|
+
continue;
|
|
477
|
+
walkFile(sf, (node) => {
|
|
478
|
+
if (ts.isBinaryExpression(node) &&
|
|
479
|
+
ts.isAssignmentOperator(node.operatorToken.kind) &&
|
|
480
|
+
(ts.isPropertyAccessExpression(node.left) || ts.isElementAccessExpression(node.left)))
|
|
481
|
+
receiver(node.left.expression);
|
|
482
|
+
else if (ts.isDeleteExpression(node) &&
|
|
483
|
+
(ts.isPropertyAccessExpression(node.expression) ||
|
|
484
|
+
ts.isElementAccessExpression(node.expression)))
|
|
485
|
+
receiver(node.expression.expression);
|
|
486
|
+
else if (ts.isCallExpression(node) &&
|
|
487
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
488
|
+
ts.isIdentifier(node.expression.expression) &&
|
|
489
|
+
(node.expression.expression.text === "Object" ||
|
|
490
|
+
node.expression.expression.text === "Reflect") &&
|
|
491
|
+
(node.expression.name.text === "defineProperty" ||
|
|
492
|
+
node.expression.name.text === "defineProperties" ||
|
|
493
|
+
node.expression.name.text === "preventExtensions" ||
|
|
494
|
+
node.expression.name.text === "seal" ||
|
|
495
|
+
node.expression.name.text === "freeze") &&
|
|
496
|
+
node.arguments.nodes[0] !== undefined)
|
|
497
|
+
receiver(node.arguments.nodes[0]);
|
|
498
|
+
return true;
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
return roots;
|
|
502
|
+
}
|
|
503
|
+
/** The typed handle kinds a JavaScript program can hold (Date, ArrayBuffer,
|
|
504
|
+
* WeakMap, WeakSet and FinalizationRegistry are already checked-dynamic
|
|
505
|
+
* values there). */
|
|
506
|
+
export const TYPED_HANDLE_KINDS = new Set(["date", "regex", "map", "set"]);
|
|
507
|
+
/** Whether the program has a JavaScript implementation file: only such a
|
|
508
|
+
* program can add own properties to a handle, so every other program keeps
|
|
509
|
+
* its typed handle lowerings untouched. */
|
|
510
|
+
function programHasJsSource(lowerer) {
|
|
511
|
+
let known = lowerer.handleJsSources;
|
|
512
|
+
if (known === undefined) {
|
|
513
|
+
known = lowerer.program
|
|
514
|
+
.getImplementationSourceFiles()
|
|
515
|
+
.some((sf) => !sf.isDeclarationFile && isJsSourceFile(sf));
|
|
516
|
+
lowerer.handleJsSources = known;
|
|
517
|
+
}
|
|
518
|
+
return known;
|
|
519
|
+
}
|
|
520
|
+
/** A typed handle receiver of a program that adds properties to handles,
|
|
521
|
+
* boxed into its checked-dynamic value; null otherwise. A program without a
|
|
522
|
+
* JavaScript file never adds one, so its typed reads and writes stay typed. */
|
|
523
|
+
export function boxedHandleReceiver(lowerer, recv) {
|
|
524
|
+
if (!recv || !TYPED_HANDLE_KINDS.has(recv.type.kind))
|
|
525
|
+
return null;
|
|
526
|
+
if (!programHasJsSource(lowerer) || !programAddsHandleProperties(lowerer))
|
|
527
|
+
return null;
|
|
528
|
+
return lowerer.coerceToExpected(recv, DYN);
|
|
529
|
+
}
|
|
530
|
+
/** `m.label = 1` in a JavaScript file over a typed handle: the write lands
|
|
531
|
+
* in the handle's property table through its checked-dynamic box. */
|
|
532
|
+
export function lowerHandlePropertyWrite(lowerer, recv, key, value, loc) {
|
|
533
|
+
return {
|
|
534
|
+
kind: "exprStmt",
|
|
535
|
+
expr: {
|
|
536
|
+
kind: "libCall",
|
|
537
|
+
fn: key.type.kind === "string" ? "dyn.keySet" : "dyn.keySetComputed",
|
|
538
|
+
args: [recv, key, lowerer.lowerExprExpecting(value, DYN)],
|
|
539
|
+
type: VOID,
|
|
540
|
+
loc,
|
|
541
|
+
},
|
|
542
|
+
loc,
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
/** `m.label` as a value over a typed handle in a JavaScript file of a
|
|
546
|
+
* program that adds properties to handles, and `d.getTime` when the program
|
|
547
|
+
* shadows that member: the box answers its own property first. */
|
|
548
|
+
export function lowerHandlePropertyRead(lowerer, access, recv) {
|
|
549
|
+
if (access.questionDotToken)
|
|
550
|
+
return null;
|
|
551
|
+
// A typed handle receiver only: the grant query below is a whole-program
|
|
552
|
+
// census, and every other receiver reads its member statically.
|
|
553
|
+
if (!TYPED_HANDLE_KINDS.has(recv.type.kind))
|
|
554
|
+
return null;
|
|
555
|
+
const name = access.name.text;
|
|
556
|
+
const declared = hasDeclaredProperty(lowerer, access.expression, name);
|
|
557
|
+
// A member name keeps its typed read unless the program's JavaScript
|
|
558
|
+
// writes or defines it onto the handle.
|
|
559
|
+
if (declared && !memberGranted(lowerer, access.expression, name))
|
|
560
|
+
return null;
|
|
561
|
+
const boxed = boxedHandleReceiver(lowerer, recv);
|
|
562
|
+
if (!boxed)
|
|
563
|
+
return null;
|
|
564
|
+
const loc = locOf(access);
|
|
565
|
+
return {
|
|
566
|
+
kind: "dynKeyGet",
|
|
567
|
+
value: boxed,
|
|
568
|
+
key: { kind: "strLit", value: name, type: STRING, loc },
|
|
569
|
+
type: DYN,
|
|
570
|
+
loc,
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
/** `d.getTime()` (or `d["getTime"]()`) over a handle in a JavaScript file that
|
|
574
|
+
* shadows the member: the call of the handle's own property. A Date in
|
|
575
|
+
* JavaScript is already a checked-dynamic value, so its receiver is called as
|
|
576
|
+
* it is; a typed handle receiver calls through its box. */
|
|
577
|
+
export function lowerHandleMemberCall(lowerer, call, access, elementName) {
|
|
578
|
+
if (call.questionDotToken)
|
|
579
|
+
return null;
|
|
580
|
+
// `d?.getTime()`: the chain lowering re-dispatches a member call whose
|
|
581
|
+
// receiver it proved never nullish with the member marked handled, and
|
|
582
|
+
// then the guard cannot short-circuit: the step is the plain call.
|
|
583
|
+
if (access.questionDotToken && !lowerer.chainHandled.has(access))
|
|
584
|
+
return null;
|
|
585
|
+
if (call.arguments.nodes.some(ts.isSpreadElement))
|
|
586
|
+
return null;
|
|
587
|
+
// Only a program with a JavaScript file can shadow a member; every other
|
|
588
|
+
// program's call stays with its typed lowering.
|
|
589
|
+
if (!programHasJsSource(lowerer))
|
|
590
|
+
return null;
|
|
591
|
+
// A receiver whose checker type names a handle class: the cheap test that
|
|
592
|
+
// keeps the whole-program census below out of every other call. The typed
|
|
593
|
+
// Date call lowering would otherwise claim a shadowed member.
|
|
594
|
+
if (handleClassOf(lowerer, access.expression) === null)
|
|
595
|
+
return null;
|
|
596
|
+
const name = ts.isPropertyAccessExpression(access) ? access.name.text : elementName;
|
|
597
|
+
if (name === undefined)
|
|
598
|
+
return null;
|
|
599
|
+
if (!memberGranted(lowerer, access.expression, name))
|
|
600
|
+
return null;
|
|
601
|
+
const recv = tryLowerExpression(lowerer, access.expression);
|
|
602
|
+
if (!recv)
|
|
603
|
+
return null;
|
|
604
|
+
const boxed = boxedHandleReceiver(lowerer, recv) ??
|
|
605
|
+
(recv.type.kind === "dyn" && programAddsHandleProperties(lowerer) ? recv : null);
|
|
606
|
+
if (!boxed)
|
|
607
|
+
return null;
|
|
608
|
+
const loc = locOf(call);
|
|
609
|
+
return {
|
|
610
|
+
kind: "dynInvoke",
|
|
611
|
+
recv: boxed,
|
|
612
|
+
method: name,
|
|
613
|
+
calleeName: ts.getTextOfNode(access),
|
|
614
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
615
|
+
type: DYN,
|
|
616
|
+
loc,
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
/** Whether `access` names a member the program's JavaScript shadows on a
|
|
620
|
+
* handle (`d?.getTime` in `d?.getTime()`). The optional-chain lowering
|
|
621
|
+
* consults it before it guards a member call whose receiver it proved never
|
|
622
|
+
* nullish: the guarded step is then the plain shadowed call. */
|
|
623
|
+
export function shadowedHandleMember(lowerer, access) {
|
|
624
|
+
if (!programHasJsSource(lowerer))
|
|
625
|
+
return false;
|
|
626
|
+
if (handleClassOf(lowerer, access.expression) === null)
|
|
627
|
+
return false;
|
|
628
|
+
const name = ts.isPropertyAccessExpression(access) ? access.name.text : literalKeyOf(access);
|
|
629
|
+
return name !== null && memberGranted(lowerer, access.expression, name);
|
|
630
|
+
}
|
|
631
|
+
/** Whether the program's JavaScript writes or defines `name` onto a handle
|
|
632
|
+
* of the receiver's class: a typed read, write, call or delete of the member
|
|
633
|
+
* then goes through the checked-dynamic box. */
|
|
634
|
+
export function handleMemberGranted(lowerer, receiver, name) {
|
|
635
|
+
return programHasJsSource(lowerer) && memberGranted(lowerer, receiver, name);
|
|
636
|
+
}
|
|
637
|
+
/** Refuses a typed implicit conversion of a handle whose class the program's
|
|
638
|
+
* JavaScript granted the method the conversion would read: Node's
|
|
639
|
+
* ToPrimitive reads the own property, which the typed lowering cannot see. */
|
|
640
|
+
export function refuseShadowedImplicitReader(lowerer, node, type, name, operation) {
|
|
641
|
+
const cls = type.kind === "date" ? "Date" : type.kind === "regex" ? "RegExp" : null;
|
|
642
|
+
if (!cls || !programHasJsSource(lowerer))
|
|
643
|
+
return;
|
|
644
|
+
const additions = handleAdditions(lowerer);
|
|
645
|
+
if (additions.grants.get(cls)?.has(name) !== true)
|
|
646
|
+
return;
|
|
647
|
+
lowerer.unsupported("SC1090", node, `${operation} of a ${cls} whose ${name} the program replaces (read the property itself, or delete it first)`);
|
|
648
|
+
}
|
|
649
|
+
/** Whether the checker declares `name` as a property of `receiver`'s type.
|
|
650
|
+
* A member name (H2's territory) keeps its own lowering or fence; only an
|
|
651
|
+
* undeclared name can be a property table entry. */
|
|
652
|
+
function hasDeclaredProperty(lowerer, receiver, name) {
|
|
653
|
+
return !!lowerer.checker.getPropertyOfType(lowerer.typeOf(receiver), name);
|
|
654
|
+
}
|
|
171
655
|
/** The typed child a JavaScript member access reads from, when the member
|
|
172
656
|
* is one the program may have added to it. `untyped` is the last resort
|
|
173
657
|
* when no typed lowering claimed the access (a receiver the checker does
|
|
@@ -282,16 +766,37 @@ const RENAMES = new Map([
|
|
|
282
766
|
["dyn.promiseResolve", "child.propsResolve"],
|
|
283
767
|
["child.onDyn", "child.propsOnDyn"],
|
|
284
768
|
]);
|
|
285
|
-
/**
|
|
286
|
-
*
|
|
769
|
+
/** The member-name grants `<Class>:<name>,<name>;<Class>:…` the program's
|
|
770
|
+
* JavaScript produced, sorted for a deterministic IR; null without grants. */
|
|
771
|
+
function grantString(lowerer) {
|
|
772
|
+
const grants = handleAdditions(lowerer).grants;
|
|
773
|
+
const parts = [];
|
|
774
|
+
for (const cls of [...grants.keys()].sort()) {
|
|
775
|
+
const names = [...grants.get(cls)].sort();
|
|
776
|
+
if (names.length > 0)
|
|
777
|
+
parts.push(`${cls}:${names.join(",")}`);
|
|
778
|
+
}
|
|
779
|
+
return parts.length > 0 ? parts.join(";") : null;
|
|
780
|
+
}
|
|
781
|
+
/** Switches a program that can add properties to handles onto the
|
|
782
|
+
* property-table entries (in place), installs the table in %main, hands the
|
|
783
|
+
* runtime the member names the program shadows, and guards the graph
|
|
784
|
+
* walkers of a program that adds properties to handles. */
|
|
287
785
|
export function applyHandleProperties(lowerer, functions) {
|
|
288
|
-
|
|
786
|
+
const child = lowerer.writesOntoChildren || childAdditions(lowerer).any;
|
|
787
|
+
const handle = programAddsHandleProperties(lowerer);
|
|
788
|
+
if (!child && !handle)
|
|
289
789
|
return;
|
|
790
|
+
const renames = new Map(child ? RENAMES : []);
|
|
791
|
+
// Object.defineProperties reads every descriptor before defining any, a
|
|
792
|
+
// rule only the table-aware entry point keeps.
|
|
793
|
+
if (handle)
|
|
794
|
+
renames.set("dyn.defineProps", "handle.propsDefineProps");
|
|
290
795
|
// A node the IR shares at several places is renamed once.
|
|
291
796
|
const calls = new Set();
|
|
292
797
|
const visitor = {
|
|
293
798
|
expr: (e) => {
|
|
294
|
-
if (e.kind === "libCall" &&
|
|
799
|
+
if (e.kind === "libCall" && renames.has(e.fn))
|
|
295
800
|
calls.add(e);
|
|
296
801
|
return true;
|
|
297
802
|
},
|
|
@@ -301,15 +806,158 @@ export function applyHandleProperties(lowerer, functions) {
|
|
|
301
806
|
for (const s of fn.body)
|
|
302
807
|
everyStmt(s, visitor);
|
|
303
808
|
for (const call of calls)
|
|
304
|
-
call.fn =
|
|
809
|
+
call.fn = renames.get(call.fn);
|
|
305
810
|
const main = functions.find((fn) => fn.name === ENTRY_NAME);
|
|
306
|
-
if (
|
|
811
|
+
if (main) {
|
|
812
|
+
const loc = main.loc;
|
|
813
|
+
const grants = grantString(lowerer);
|
|
814
|
+
const prologue = [];
|
|
815
|
+
if (grants) {
|
|
816
|
+
prologue.push({
|
|
817
|
+
kind: "exprStmt",
|
|
818
|
+
expr: {
|
|
819
|
+
kind: "libCall",
|
|
820
|
+
fn: "handle.propsGrant",
|
|
821
|
+
args: [{ kind: "strLit", value: grants, type: STRING, loc }],
|
|
822
|
+
type: VOID,
|
|
823
|
+
loc,
|
|
824
|
+
},
|
|
825
|
+
loc,
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
prologue.push({
|
|
829
|
+
kind: "exprStmt",
|
|
830
|
+
expr: {
|
|
831
|
+
kind: "libCall",
|
|
832
|
+
fn: "handle.propsInstall",
|
|
833
|
+
args: [{ kind: "numLit", value: child ? 1 : 0, type: F64, loc }],
|
|
834
|
+
type: VOID,
|
|
835
|
+
loc,
|
|
836
|
+
},
|
|
837
|
+
loc,
|
|
838
|
+
});
|
|
839
|
+
main.body.unshift(...prologue);
|
|
840
|
+
}
|
|
841
|
+
if (handle)
|
|
842
|
+
guardHandleConsumers(lowerer, functions);
|
|
843
|
+
}
|
|
844
|
+
/** The child wrapper `handle.propsInstall(1)` asks the runtime for needs
|
|
845
|
+
* scr_child.c's ops. They are installed by scr_child_dyn_install, which the
|
|
846
|
+
* emitter emits from the childProcess runtime feature — the module fact
|
|
847
|
+
* that links scr_child.c. `childAdditions` counts every JavaScript file the
|
|
848
|
+
* type checker loaded, not just the ones the program reaches, so a
|
|
849
|
+
* program whose npm-static packages merely mention child_process (a
|
|
850
|
+
* comment or a string is enough) asks for a wrapper for handles it can
|
|
851
|
+
* never box: the install probes a tag nothing installed and traps at start.
|
|
852
|
+
* Align the request with the unit once the module is final; a program that
|
|
853
|
+
* cannot carry a child handle needs no wrapper, and one that can still asks
|
|
854
|
+
* for it. */
|
|
855
|
+
export function alignHandlePropertyChildFact(module) {
|
|
856
|
+
if (moduleUsesChildProcess(module))
|
|
307
857
|
return;
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
858
|
+
everyModuleNode(module, {
|
|
859
|
+
expr: (e) => {
|
|
860
|
+
if (e.kind !== "libCall" || e.fn !== "handle.propsInstall")
|
|
861
|
+
return true;
|
|
862
|
+
const arg = e.args[0];
|
|
863
|
+
if (arg?.kind === "numLit" && arg.value === 1)
|
|
864
|
+
arg.value = 0;
|
|
865
|
+
return true;
|
|
866
|
+
},
|
|
867
|
+
stmt: () => true,
|
|
868
|
+
type: () => true,
|
|
313
869
|
});
|
|
314
870
|
}
|
|
871
|
+
/** Whether a type holds a typed handle anywhere the dyn copy of the value
|
|
872
|
+
* walks: itself, an array element, a record field, a union arm, a promise
|
|
873
|
+
* payload or a collection element. */
|
|
874
|
+
function containsHandleKind(lowerer, type) {
|
|
875
|
+
const seen = new Set();
|
|
876
|
+
const visit = (t) => {
|
|
877
|
+
switch (t.kind) {
|
|
878
|
+
case "date":
|
|
879
|
+
case "regex":
|
|
880
|
+
case "map":
|
|
881
|
+
case "set":
|
|
882
|
+
return true;
|
|
883
|
+
case "array":
|
|
884
|
+
return visit(t.elem);
|
|
885
|
+
case "promise":
|
|
886
|
+
return visit(t.inner);
|
|
887
|
+
case "record":
|
|
888
|
+
return (lowerer.shapes.get(t.shapeId)?.fields ?? []).some((f) => visit(f.type));
|
|
889
|
+
case "union": {
|
|
890
|
+
if (seen.has(t.unionId))
|
|
891
|
+
return false;
|
|
892
|
+
seen.add(t.unionId);
|
|
893
|
+
return (lowerer.unions.get(t.unionId)?.arms ?? []).some(visit);
|
|
894
|
+
}
|
|
895
|
+
default:
|
|
896
|
+
return false;
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
return visit(type);
|
|
900
|
+
}
|
|
901
|
+
/** The graph walkers that cannot print or compare a handle's own properties
|
|
902
|
+
* refuse a value whose graph holds one: a dynamic argument passes through
|
|
903
|
+
* handle.propsGuard, and a typed argument keeps its typed lowering with a
|
|
904
|
+
* handle.propsCheck on a copy of the value first. */
|
|
905
|
+
function guardHandleConsumers(lowerer, functions) {
|
|
906
|
+
for (const fn of functions) {
|
|
907
|
+
const guarded = (arg, fnName) => {
|
|
908
|
+
if (arg.type.kind === "dyn" || (arg.type.kind === "array" && arg.type.elem.kind === "dyn")) {
|
|
909
|
+
return {
|
|
910
|
+
kind: "libCall",
|
|
911
|
+
fn: arg.type.kind === "dyn" ? "handle.propsGuard" : "handle.propsGuardList",
|
|
912
|
+
args: [arg, { kind: "strLit", value: consumerName(fnName), type: STRING, loc: arg.loc }],
|
|
913
|
+
type: arg.type,
|
|
914
|
+
loc: arg.loc,
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
if (!containsHandleKind(lowerer, arg.type))
|
|
918
|
+
return arg;
|
|
919
|
+
const id = `%handleCheck.${fn.locals.length}`;
|
|
920
|
+
fn.locals.push({ id, name: id, type: arg.type, mutable: false });
|
|
921
|
+
return {
|
|
922
|
+
kind: "seqExpr",
|
|
923
|
+
stmts: [
|
|
924
|
+
{ kind: "varDecl", localId: id, init: arg, loc: arg.loc },
|
|
925
|
+
{
|
|
926
|
+
kind: "exprStmt",
|
|
927
|
+
expr: {
|
|
928
|
+
kind: "libCall",
|
|
929
|
+
fn: "handle.propsCheck",
|
|
930
|
+
args: [
|
|
931
|
+
{
|
|
932
|
+
kind: "dynFrom",
|
|
933
|
+
value: { kind: "varRef", localId: id, type: arg.type, loc: arg.loc },
|
|
934
|
+
type: DYN,
|
|
935
|
+
loc: arg.loc,
|
|
936
|
+
},
|
|
937
|
+
{ kind: "strLit", value: consumerName(fnName), type: STRING, loc: arg.loc },
|
|
938
|
+
],
|
|
939
|
+
type: VOID,
|
|
940
|
+
loc: arg.loc,
|
|
941
|
+
},
|
|
942
|
+
loc: arg.loc,
|
|
943
|
+
},
|
|
944
|
+
],
|
|
945
|
+
result: { kind: "varRef", localId: id, type: arg.type, loc: arg.loc },
|
|
946
|
+
type: arg.type,
|
|
947
|
+
loc: arg.loc,
|
|
948
|
+
};
|
|
949
|
+
};
|
|
950
|
+
fn.body = transformStmtList(fn.body, {
|
|
951
|
+
expr: (expr) => {
|
|
952
|
+
if (expr.kind === "libCall" && GUARDED_CONSUMERS.has(expr.fn))
|
|
953
|
+
return { ...expr, args: expr.args.map((arg) => guarded(arg, expr.fn)) };
|
|
954
|
+
if (expr.kind === "intrinsic" &&
|
|
955
|
+
(expr.name === "console.log" || expr.name === "console.error"))
|
|
956
|
+
return { ...expr, args: expr.args.map((arg) => guarded(arg, expr.name)) };
|
|
957
|
+
return expr;
|
|
958
|
+
},
|
|
959
|
+
stmt: (stmt) => stmt,
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
}
|
|
315
963
|
//# sourceMappingURL=handle-properties.js.map
|