@scriptc/compiler 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +470 -66
- package/dist/backend/cycle-analysis.d.ts +4 -1
- package/dist/backend/cycle-analysis.js +6 -4
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +55 -0
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.d.ts +7 -0
- package/dist/backend/cycle-mutability.js +19 -1
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.js +2 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.d.ts +6 -3
- package/dist/backend/immutability.js +33 -29
- package/dist/backend/immutability.js.map +1 -1
- package/dist/backend/library-pack.js +1 -0
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +16 -1
- package/dist/backend/llvm/alloc.js +54 -4
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.d.ts +2 -1
- package/dist/backend/llvm/appended-array-literals.js +44 -36
- package/dist/backend/llvm/appended-array-literals.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.test.js +4 -3
- package/dist/backend/llvm/appended-array-literals.test.js.map +1 -1
- package/dist/backend/llvm/array-search.d.ts +4 -3
- package/dist/backend/llvm/array-search.js +21 -9
- package/dist/backend/llvm/array-search.js.map +1 -1
- package/dist/backend/llvm/blocks.d.ts +1 -1
- package/dist/backend/llvm/blocks.js +2 -2
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/byte-windows.js +2 -0
- package/dist/backend/llvm/byte-windows.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.d.ts +6 -1
- package/dist/backend/llvm/bytes-alias.js +8 -2
- package/dist/backend/llvm/bytes-alias.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.d.ts +47 -5
- package/dist/backend/llvm/bytes-loop-versions.js +479 -32
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.test.js +263 -2
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
- package/dist/backend/llvm/checked-value-lifetimes.js +2 -0
- package/dist/backend/llvm/checked-value-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +7 -5
- package/dist/backend/llvm/classes.js +44 -20
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +167 -7
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +9 -3
- package/dist/backend/llvm/common.js +9 -3
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +2 -1
- package/dist/backend/llvm/constant-callbacks.js +83 -52
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/counted-loops.d.ts +7 -0
- package/dist/backend/llvm/counted-loops.js +18 -0
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/debug-info.js +2 -5
- package/dist/backend/llvm/debug-info.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +39 -8
- package/dist/backend/llvm/dense-array-access.js +222 -52
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +36 -0
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.d.ts +17 -1
- package/dist/backend/llvm/dense-array-loops.js +194 -5
- package/dist/backend/llvm/dense-array-loops.js.map +1 -1
- package/dist/backend/llvm/dense-array-loops.test.js +90 -1
- package/dist/backend/llvm/dense-array-loops.test.js.map +1 -1
- package/dist/backend/llvm/dyn-handle-tags.test.js +6 -1
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +30 -0
- package/dist/backend/llvm/dyn.js +373 -70
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +13 -28
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-journal.d.ts +93 -0
- package/dist/backend/llvm/emit-journal.js +170 -0
- package/dist/backend/llvm/emit-journal.js.map +1 -0
- package/dist/backend/llvm/emit-module.js +211 -33
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emit-statements.d.ts +0 -4
- package/dist/backend/llvm/emit-statements.js +268 -84
- package/dist/backend/llvm/emit-statements.js.map +1 -1
- package/dist/backend/llvm/emitter-state.d.ts +7 -0
- package/dist/backend/llvm/emitter-state.js +14 -0
- package/dist/backend/llvm/emitter-state.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +186 -37
- package/dist/backend/llvm/emitter.js +733 -90
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +65 -7
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +11 -13
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +48 -20
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.js +47 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +28 -14
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +14 -2
- package/dist/backend/llvm/expr-containers.js +143 -37
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +14 -0
- package/dist/backend/llvm/expr-dynamic.js +18 -11
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +119 -38
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +11 -6
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +12 -0
- package/dist/backend/llvm/expr-records.js +106 -0
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +2 -2
- package/dist/backend/llvm/expr-stream-bridges.js +210 -69
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +74 -20
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/int32-kind-loops.d.ts +39 -0
- package/dist/backend/llvm/int32-kind-loops.js +106 -0
- package/dist/backend/llvm/int32-kind-loops.js.map +1 -0
- package/dist/backend/llvm/integer-or-nan-indexes.test.d.ts +1 -0
- package/dist/backend/llvm/integer-or-nan-indexes.test.js +118 -0
- package/dist/backend/llvm/integer-or-nan-indexes.test.js.map +1 -0
- package/dist/backend/llvm/integer-values.d.ts +25 -1
- package/dist/backend/llvm/integer-values.js +95 -0
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/js-ic.d.ts +1 -1
- package/dist/backend/llvm/js-ic.js +1 -1
- package/dist/backend/llvm/js-ic.js.map +1 -1
- package/dist/backend/llvm/key-orders.d.ts +7 -0
- package/dist/backend/llvm/key-orders.js +33 -0
- package/dist/backend/llvm/key-orders.js.map +1 -0
- package/dist/backend/llvm/lib-connect.js +4 -0
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +11 -0
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +213 -5
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +4 -4
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +4 -0
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +16 -6
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +37 -1
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +94 -2
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +35 -5
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +115 -19
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +14 -0
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/loop-state.d.ts +33 -0
- package/dist/backend/llvm/loop-state.js +42 -0
- package/dist/backend/llvm/loop-state.js.map +1 -0
- package/dist/backend/llvm/map-number-lookup.d.ts +26 -8
- package/dist/backend/llvm/map-number-lookup.js +91 -31
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +55 -0
- package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.js +4 -2
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.d.ts +2 -1
- package/dist/backend/llvm/nullable-unions.js +15 -3
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/publish.d.ts +10 -0
- package/dist/backend/llvm/publish.js +15 -3
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/receivers.js +6 -1
- package/dist/backend/llvm/receivers.js.map +1 -1
- package/dist/backend/llvm/record-results.d.ts +1 -9
- package/dist/backend/llvm/record-results.js +2 -11
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +3 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +7 -2
- package/dist/backend/llvm/reference-writes.js +89 -72
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/running-extrema.d.ts +11 -0
- package/dist/backend/llvm/running-extrema.js +115 -0
- package/dist/backend/llvm/running-extrema.js.map +1 -0
- package/dist/backend/llvm/running-extrema.test.d.ts +1 -0
- package/dist/backend/llvm/running-extrema.test.js +89 -0
- package/dist/backend/llvm/running-extrema.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +71 -15
- package/dist/backend/llvm/shapes.js +224 -40
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +53 -7
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +6 -0
- package/dist/backend/llvm/speculative-integers.js +2 -2
- package/dist/backend/llvm/speculative-integers.js.map +1 -1
- package/dist/backend/llvm/stack-captures.js +1 -5
- package/dist/backend/llvm/stack-captures.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +3 -2
- package/dist/backend/llvm/stack-objects.js +5 -2
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +12 -0
- package/dist/backend/llvm/string-reads.js +44 -0
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/union-repr.d.ts +4 -3
- package/dist/backend/llvm/union-repr.js +6 -5
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/walk-borrows.d.ts +3 -0
- package/dist/backend/llvm/walk-borrows.js +46 -41
- package/dist/backend/llvm/walk-borrows.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +3 -0
- package/dist/backend/llvm/walkers.js +101 -65
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wrapping-sums.d.ts +16 -1
- package/dist/backend/llvm/wrapping-sums.js +126 -0
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/may-throw.d.ts +8 -10
- package/dist/backend/may-throw.js +14 -10
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +5 -0
- package/dist/backend/native/executable.js +7 -0
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +5 -3
- package/dist/backend/native-codegen-core.js +13 -6
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.test.js +6 -4
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +4 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/publication.d.ts +12 -1
- package/dist/backend/publication.js +37 -14
- package/dist/backend/publication.js.map +1 -1
- package/dist/backend/publication.test.js +30 -0
- package/dist/backend/publication.test.js.map +1 -1
- package/dist/backend/result-slots.d.ts +16 -0
- package/dist/backend/result-slots.js +23 -0
- package/dist/backend/result-slots.js.map +1 -0
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +1 -0
- package/dist/backend/runtime-pack-core.js +1 -0
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +2 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +2 -1
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/stack-observations.d.ts +2 -1
- package/dist/backend/stack-observations.js +67 -42
- package/dist/backend/stack-observations.js.map +1 -1
- package/dist/backend/target-cpu.d.ts +26 -0
- package/dist/backend/target-cpu.js +98 -0
- package/dist/backend/target-cpu.js.map +1 -0
- package/dist/backend/target-cpu.test.d.ts +1 -0
- package/dist/backend/target-cpu.test.js +38 -0
- package/dist/backend/target-cpu.test.js.map +1 -0
- package/dist/backend/target-diagnostics.js +5 -3
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/warm-cache.js +1 -0
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/cli/command.js +20 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +4 -1
- package/dist/cli/usage.js +10 -3
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.js +1 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +7 -0
- package/dist/contracts/check.js +4 -3
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.js +10 -2
- package/dist/contracts/int32-elements.js.map +1 -1
- package/dist/coverage/report.js +12 -3
- package/dist/coverage/report.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +4 -0
- package/dist/diagnostics/diagnostic.js +1 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +3 -0
- package/dist/diagnostics/envelope.js +1 -0
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +5 -0
- package/dist/executable/executable-cache.js +5 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +3 -0
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/decl-projection.d.ts +41 -0
- package/dist/frontend/decl-projection.js +949 -0
- package/dist/frontend/decl-projection.js.map +1 -0
- package/dist/frontend/decl-projection.test.d.ts +1 -0
- package/dist/frontend/decl-projection.test.js +30 -0
- package/dist/frontend/decl-projection.test.js.map +1 -0
- package/dist/frontend/dts-paths.d.ts +15 -0
- package/dist/frontend/dts-paths.js +25 -0
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +6 -0
- package/dist/frontend/input-tracker.js +51 -28
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +19 -0
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lowering/array-values.js +100 -2
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.d.ts +8 -2
- package/dist/frontend/lowering/builtins/async-context.js +62 -3
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.js +46 -15
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.js +13 -2
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.js +87 -10
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.js +4 -1
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +3 -3
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +6 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-paths.d.ts +43 -5
- package/dist/frontend/lowering/builtins/fs-paths.js +245 -93
- package/dist/frontend/lowering/builtins/fs-paths.js.map +1 -1
- package/dist/frontend/lowering/builtins/global-namespace-keys.d.ts +3 -0
- package/dist/frontend/lowering/builtins/global-namespace-keys.js +122 -0
- package/dist/frontend/lowering/builtins/global-namespace-keys.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-calls.js +6 -3
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/numbers.js +9 -1
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +7 -1
- package/dist/frontend/lowering/builtins/promises.js +236 -139
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +5 -1
- package/dist/frontend/lowering/builtins/readline.js +35 -3
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.js +24 -1
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/webassembly.js +6 -3
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.js +0 -1
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
- package/dist/frontend/lowering/cjs-inline-require.d.ts +32 -0
- package/dist/frontend/lowering/cjs-inline-require.js +307 -4
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +5 -2
- package/dist/frontend/lowering/class-callbacks.js +82 -12
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +4 -1
- package/dist/frontend/lowering/class-construction.js +17 -3
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +49 -2
- package/dist/frontend/lowering/class-dynamic-dispatch.js +880 -108
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +47 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-iterables.d.ts +2 -1
- package/dist/frontend/lowering/class-iterables.js +9 -1
- package/dist/frontend/lowering/class-iterables.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +83 -24
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +25 -0
- package/dist/frontend/lowering/class-protocols.js +183 -1
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.js +31 -2
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +9 -3
- package/dist/frontend/lowering/class-runtime-statics.js +29 -4
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +48 -1
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +91 -1
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/completion-callbacks.d.ts +4 -0
- package/dist/frontend/lowering/completion-callbacks.js +146 -0
- package/dist/frontend/lowering/completion-callbacks.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +2 -2
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +5 -4
- package/dist/frontend/lowering/containers/array-callbacks.js +345 -24
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.js +10 -0
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +5 -0
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +26 -3
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.js +19 -8
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +25 -17
- package/dist/frontend/lowering/containers/bytes.js +455 -46
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +3 -0
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +7 -2
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/filter-predicates.d.ts +6 -0
- package/dist/frontend/lowering/containers/filter-predicates.js +205 -0
- package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -0
- package/dist/frontend/lowering/containers/indexed-objects.d.ts +0 -12
- package/dist/frontend/lowering/containers/indexed-objects.js +46 -7
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +55 -9
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.js +43 -19
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/date-values.d.ts +11 -0
- package/dist/frontend/lowering/date-values.js +207 -0
- package/dist/frontend/lowering/date-values.js.map +1 -0
- package/dist/frontend/lowering/dispatch-sites.js +15 -1
- package/dist/frontend/lowering/dispatch-sites.js.map +1 -1
- package/dist/frontend/lowering/divergences.js +9 -1
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/error-methods.js +47 -2
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/expressions/array-literals.js +53 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +100 -28
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +169 -13
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +64 -5
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/narrowing.js +95 -1
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +3 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/object-literals.js +138 -51
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +12 -0
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.js +168 -10
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/relational.js +212 -33
- package/dist/frontend/lowering/expressions/relational.js.map +1 -1
- package/dist/frontend/lowering/expressions/typeof.js +6 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-fields.js +4 -0
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +39 -3
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/frozen-records.d.ts +28 -0
- package/dist/frontend/lowering/frozen-records.js +322 -0
- package/dist/frontend/lowering/frozen-records.js.map +1 -0
- package/dist/frontend/lowering/function-returns.js +64 -0
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.js +7 -2
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/indexed-unions.d.ts +54 -0
- package/dist/frontend/lowering/indexed-unions.js +401 -0
- package/dist/frontend/lowering/indexed-unions.js.map +1 -0
- package/dist/frontend/lowering/iterable-values.d.ts +49 -0
- package/dist/frontend/lowering/iterable-values.js +297 -0
- package/dist/frontend/lowering/iterable-values.js.map +1 -0
- package/dist/frontend/lowering/iterator-adapters.js +186 -1
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/js-class-fields.d.ts +8 -0
- package/dist/frontend/lowering/js-class-fields.js +45 -10
- package/dist/frontend/lowering/js-class-fields.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.d.ts +18 -3
- package/dist/frontend/lowering/key-order-witness.js +974 -48
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.test.js +530 -10
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +15 -3
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js +4 -1
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +7 -0
- package/dist/frontend/lowering/lower-calls.js +462 -44
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +11 -2
- package/dist/frontend/lowering/lower-classes.js +324 -69
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +3 -1
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +215 -3
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.d.ts +11 -0
- package/dist/frontend/lowering/lower-functions.js +83 -0
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +42 -32
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.js +6 -3
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
- package/dist/frontend/lowering/lower-inspect.js +53 -17
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +53 -5
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +5 -1
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +2 -2
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +5 -0
- package/dist/frontend/lowering/lower-stdlib.js +30 -0
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +23 -0
- package/dist/frontend/lowering/lower-stmts.js +553 -81
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +20 -2
- package/dist/frontend/lowering/lower-stream.js +1483 -156
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +107 -8
- package/dist/frontend/lowering/lowerer.js +381 -36
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.d.ts +11 -1
- package/dist/frontend/lowering/module-namespace-elements.js +82 -5
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/new-target.d.ts +12 -0
- package/dist/frontend/lowering/new-target.js +280 -0
- package/dist/frontend/lowering/new-target.js.map +1 -0
- package/dist/frontend/lowering/object-factory-new.d.ts +5 -0
- package/dist/frontend/lowering/object-factory-new.js +20 -6
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/overload-choice.d.ts +33 -0
- package/dist/frontend/lowering/overload-choice.js +190 -0
- package/dist/frontend/lowering/overload-choice.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +3 -0
- package/dist/frontend/lowering/surfaces.js +73 -8
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/undefined-index.d.ts +27 -0
- package/dist/frontend/lowering/undefined-index.js +82 -0
- package/dist/frontend/lowering/undefined-index.js.map +1 -0
- package/dist/frontend/lowering/var-hoisting.js +29 -13
- package/dist/frontend/lowering/var-hoisting.js.map +1 -1
- package/dist/frontend/lowering/width-lift.d.ts +18 -0
- package/dist/frontend/npm-static-bundled-chunks.js +9 -11
- package/dist/frontend/npm-static-bundled-chunks.js.map +1 -1
- package/dist/frontend/npm-static-bundled-chunks.test.js +6 -5
- package/dist/frontend/npm-static-bundled-chunks.test.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.js +9 -1
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static.js +4 -20
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/package-shims.d.ts +3 -0
- package/dist/frontend/package-shims.js +71 -8
- package/dist/frontend/package-shims.js.map +1 -1
- package/dist/frontend/pipeline.js +19 -11
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/process-fork.d.ts +25 -0
- package/dist/frontend/process-fork.js +2 -0
- package/dist/frontend/process-fork.js.map +1 -0
- package/dist/frontend/program-analysis.d.ts +5 -1
- package/dist/frontend/program-analysis.js +5 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +21 -6
- package/dist/frontend/program.js +681 -83
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +43 -3
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/token-equivalence.d.ts +3 -0
- package/dist/frontend/token-equivalence.js +409 -0
- package/dist/frontend/token-equivalence.js.map +1 -0
- package/dist/frontend/token-equivalence.test.d.ts +1 -0
- package/dist/frontend/token-equivalence.test.js +67 -0
- package/dist/frontend/token-equivalence.test.js.map +1 -0
- package/dist/frontend/ts7/ast-node.d.ts +22 -0
- package/dist/frontend/ts7/ast-node.js +1048 -103
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +24 -0
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.d.ts +4 -3
- package/dist/frontend/ts7/ast-wire.js +34 -24
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/ast-wire.test.js +23 -0
- package/dist/frontend/ts7/ast-wire.test.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.d.ts +3 -4
- package/dist/frontend/ts7/checker-backend.js +2 -2
- package/dist/frontend/ts7/checker-backend.js.map +1 -1
- package/dist/frontend/ts7/checker-backend.test.js +5 -9
- package/dist/frontend/ts7/checker-backend.test.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +4 -0
- package/dist/frontend/ts7/checker.js +7 -0
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/lib-diagnostics.d.ts +24 -0
- package/dist/frontend/ts7/lib-diagnostics.js +307 -0
- package/dist/frontend/ts7/lib-diagnostics.js.map +1 -0
- package/dist/frontend/ts7/lib-diagnostics.test.d.ts +1 -0
- package/dist/frontend/ts7/lib-diagnostics.test.js +199 -0
- package/dist/frontend/ts7/lib-diagnostics.test.js.map +1 -0
- package/dist/frontend/ts7/program-host.d.ts +7 -0
- package/dist/frontend/ts7/program-host.js +25 -2
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +3 -0
- package/dist/frontend/ts7/semantic-model.js +5 -0
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +6 -1
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +1 -1
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +14 -1
- package/dist/frontend/ts7/session.js +22 -0
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +13 -1
- package/dist/frontend/type-mapper.js +229 -20
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.js +46 -4
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +5 -3
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/array-length-stability.d.ts +4 -0
- package/dist/ir/array-length-stability.js +19 -6
- package/dist/ir/array-length-stability.js.map +1 -1
- package/dist/ir/array-length-stability.test.js +24 -0
- package/dist/ir/array-length-stability.test.js.map +1 -1
- package/dist/ir/builtin-effects.d.ts +7 -0
- package/dist/ir/builtin-effects.js +60 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +6 -4
- package/dist/ir/builtin-signatures.js +222 -13
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +2 -1
- package/dist/ir/callback-specialization.js +23 -18
- package/dist/ir/callback-specialization.js.map +1 -1
- package/dist/ir/char-unit-locals.d.ts +19 -0
- package/dist/ir/char-unit-locals.js +185 -0
- package/dist/ir/char-unit-locals.js.map +1 -0
- package/dist/ir/char-unit-locals.test.d.ts +1 -0
- package/dist/ir/char-unit-locals.test.js +94 -0
- package/dist/ir/char-unit-locals.test.js.map +1 -0
- package/dist/ir/final-fields.d.ts +2 -1
- package/dist/ir/final-fields.js +14 -16
- package/dist/ir/final-fields.js.map +1 -1
- package/dist/ir/function-references.d.ts +2 -0
- package/dist/ir/function-references.js +2 -0
- package/dist/ir/function-references.js.map +1 -1
- package/dist/ir/function-references.test.js +3 -0
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/initializer-bindings.d.ts +2 -1
- package/dist/ir/initializer-bindings.js +27 -20
- package/dist/ir/initializer-bindings.js.map +1 -1
- package/dist/ir/int32-arrays.d.ts +108 -0
- package/dist/ir/int32-arrays.js +831 -0
- package/dist/ir/int32-arrays.js.map +1 -0
- package/dist/ir/int32-slots.d.ts +24 -2
- package/dist/ir/int32-slots.js +266 -57
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +33 -0
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +3 -3
- package/dist/ir/integer-loops.js +28 -10
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.js +10 -0
- package/dist/ir/integer-loops.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +5 -0
- package/dist/ir/integer-ranges.js +125 -12
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +30 -0
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/ir.d.ts +83 -10
- package/dist/ir/ir.js +77 -6
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +23 -2
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/js-ic.d.ts +4 -0
- package/dist/ir/js-ic.js +17 -1
- package/dist/ir/js-ic.js.map +1 -1
- package/dist/ir/js-ic.test.js +46 -0
- package/dist/ir/js-ic.test.js.map +1 -1
- package/dist/ir/node-index.d.ts +57 -0
- package/dist/ir/node-index.js +215 -0
- package/dist/ir/node-index.js.map +1 -0
- package/dist/ir/paired-while-loops.d.ts +25 -0
- package/dist/ir/paired-while-loops.js +335 -0
- package/dist/ir/paired-while-loops.js.map +1 -0
- package/dist/ir/paired-while-loops.test.d.ts +1 -0
- package/dist/ir/paired-while-loops.test.js +163 -0
- package/dist/ir/paired-while-loops.test.js.map +1 -0
- package/dist/ir/parameter-versions.d.ts +25 -0
- package/dist/ir/parameter-versions.js +300 -0
- package/dist/ir/parameter-versions.js.map +1 -0
- package/dist/ir/runtime-features.d.ts +34 -13
- package/dist/ir/runtime-features.js +177 -39
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/serialize.d.ts +12 -2
- package/dist/ir/serialize.js +16 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +17 -0
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/traverse.js +18 -6
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +167 -40
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/ir-policy.js +3 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/native/cache.d.ts +6 -1
- package/dist/native/cache.js +28 -5
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cache.test.js +16 -2
- package/dist/native/cache.test.js.map +1 -1
- package/dist/native/cli.js +21 -1
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +8 -6
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/executable-cache.d.ts +1 -1
- package/dist/native/executable-cache.js +2 -2
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/prepare.d.ts +4 -2
- package/dist/native/prepare.js +130 -32
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +96 -20
- package/dist/native/prepare.test.js.map +1 -1
- package/dist/native/sanitizer.test.js +2 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/text-file.d.ts +13 -3
- package/dist/native/text-file.js +63 -9
- package/dist/native/text-file.js.map +1 -1
- package/dist/native/text-file.test.d.ts +1 -0
- package/dist/native/text-file.test.js +49 -0
- package/dist/native/text-file.test.js.map +1 -0
- package/dist/native/toolchain.js +4 -4
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +3 -3
- package/dist/native/toolchain.test.js.map +1 -1
- package/package.json +21 -21
- package/shims/chalk/v5.ts +688 -0
- package/shims/hono-node-server/v2.ts +645 -0
- package/shims/hot-shots/client.ts +1126 -0
- package/shims/hot-shots/v8-unix-dgram.ts +8 -0
- package/shims/hot-shots/v8.ts +8 -0
- package/surface-manifest.json +27 -7
|
@@ -28,7 +28,7 @@ import { ClassConstructionDispatch } from "./class-construction.js";
|
|
|
28
28
|
import { DispatchSites } from "./dispatch-sites.js";
|
|
29
29
|
import { emitterRooted, lowerDynamicEmitterEmit, lowerDynamicEmitterOn, } from "./lower-event-emitter.js";
|
|
30
30
|
import { protocolArm, protocolFieldArm } from "./class-protocol-dispatch.js";
|
|
31
|
-
import { STREAM_OPERATORS } from "./lower-stream.js";
|
|
31
|
+
import { STREAM_OPERATORS, operatorSignalOptions, reduceSignalSetup } from "./lower-stream.js";
|
|
32
32
|
import { deletedPropertyNames, fixedFieldFamily } from "./js-class-fields.js";
|
|
33
33
|
const STREAM_METHODS = new Set([
|
|
34
34
|
"on",
|
|
@@ -252,7 +252,7 @@ export function classInstanceOf(lowerer, value, info, loc, classValue) {
|
|
|
252
252
|
localId: "candidate",
|
|
253
253
|
value: {
|
|
254
254
|
kind: "libCall",
|
|
255
|
-
fn: "dyn.
|
|
255
|
+
fn: "dyn.getPrototypeForIdentity",
|
|
256
256
|
args: [candidate],
|
|
257
257
|
type: DYN,
|
|
258
258
|
loc,
|
|
@@ -295,6 +295,37 @@ export function classInstanceOf(lowerer, value, info, loc, classValue) {
|
|
|
295
295
|
loc,
|
|
296
296
|
};
|
|
297
297
|
}
|
|
298
|
+
/** `value` is the parameter itself, possibly through js.fromDyn. */
|
|
299
|
+
function returnsParam(value, param) {
|
|
300
|
+
if (value.kind === "varRef")
|
|
301
|
+
return value.localId === param;
|
|
302
|
+
return (value.kind === "libCall" &&
|
|
303
|
+
value.fn === "js.fromDyn" &&
|
|
304
|
+
value.args.length === 1 &&
|
|
305
|
+
value.args[0].kind === "varRef" &&
|
|
306
|
+
value.args[0].localId === param);
|
|
307
|
+
}
|
|
308
|
+
/** The kind a class-table branch requires of `param`: a capsule-key test
|
|
309
|
+
* (alone or guarding a conjunction) needs a capsule, a class-key test a
|
|
310
|
+
* function value; null for any other condition. */
|
|
311
|
+
function branchKind(cond, param) {
|
|
312
|
+
if (cond.kind === "libCall" &&
|
|
313
|
+
(cond.fn === "dyn.typedRefIs" ||
|
|
314
|
+
cond.fn === "dyn.typedRefKeyIs" ||
|
|
315
|
+
cond.fn === "dyn.classIs") &&
|
|
316
|
+
cond.args[0]?.kind === "varRef" &&
|
|
317
|
+
cond.args[0].localId === param) {
|
|
318
|
+
if (cond.fn === "dyn.classIs")
|
|
319
|
+
return "funcKind";
|
|
320
|
+
const key = cond.args[1];
|
|
321
|
+
return key?.kind === "strLit" && key.value.startsWith("object:") ? "classCapsule" : null;
|
|
322
|
+
}
|
|
323
|
+
if (cond.kind === "ternary" && cond.else_.kind === "boolLit" && cond.else_.value === false)
|
|
324
|
+
return branchKind(cond.cond, param);
|
|
325
|
+
if (cond.kind === "logical" && cond.op === "&&")
|
|
326
|
+
return branchKind(cond.left, param);
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
298
329
|
const READ_PROPERTIES = "%dyn.class.readProperties";
|
|
299
330
|
const READ_PROPERTIES_OR_EMPTY = "%dyn.class.readPropertiesOrEmpty";
|
|
300
331
|
function isEmptyBag(value) {
|
|
@@ -549,6 +580,111 @@ export function classForInHasKey(lowerer, value, key, loc) {
|
|
|
549
580
|
}
|
|
550
581
|
return { kind: "call", callee: name, args: [value, key], type: BOOL, loc };
|
|
551
582
|
}
|
|
583
|
+
/** Box class instances at their exact class. `%dyn.class.normalize` turns a
|
|
584
|
+
* capsule of a class with subclasses into a capsule of the instance's own
|
|
585
|
+
* class before any member table reads it, so every such box was followed
|
|
586
|
+
* by a second capsule. Each conversion of a value whose static class has a
|
|
587
|
+
* normalization branch now selects the exact class at the conversion, with
|
|
588
|
+
* the same tests in the same order (%dyn.class.boxExact:C), and the
|
|
589
|
+
* normalization of the resulting capsule falls through. Only JavaScript
|
|
590
|
+
* class hierarchies, whose instances live in untyped code, take the exact
|
|
591
|
+
* box. */
|
|
592
|
+
export function boxClassInstancesExactly(lowerer, functions) {
|
|
593
|
+
const normalize = lowerer.liftedFnNamed("%dyn.class.normalize");
|
|
594
|
+
if (!normalize)
|
|
595
|
+
return;
|
|
596
|
+
// Static class → its constructible descendants in normalization order.
|
|
597
|
+
const branches = new Map();
|
|
598
|
+
for (const stmt of normalize.body) {
|
|
599
|
+
if (stmt.kind !== "if" || stmt.cond.kind !== "libCall" || stmt.cond.fn !== "dyn.typedRefIs")
|
|
600
|
+
continue;
|
|
601
|
+
const key = stmt.cond.args[1];
|
|
602
|
+
if (key?.kind !== "strLit" || !key.value.startsWith("object:"))
|
|
603
|
+
continue;
|
|
604
|
+
const children = [];
|
|
605
|
+
for (const inner of stmt.then) {
|
|
606
|
+
if (inner.kind !== "if" || inner.cond.kind !== "instanceOf")
|
|
607
|
+
continue;
|
|
608
|
+
children.push(inner.cond.className);
|
|
609
|
+
}
|
|
610
|
+
// TypeScript hierarchies keep their static-class capsules: their boxes
|
|
611
|
+
// are rarer, and an exact box would emit each subclass's checked view.
|
|
612
|
+
const className = key.value.slice("object:".length);
|
|
613
|
+
const decl = lowerer.classes.get(className)?.decl;
|
|
614
|
+
if (!decl || !isJsSourceFile(ts.getSourceFileOfNode(decl)))
|
|
615
|
+
continue;
|
|
616
|
+
if (children.length)
|
|
617
|
+
branches.set(className, children);
|
|
618
|
+
}
|
|
619
|
+
if (branches.size === 0)
|
|
620
|
+
return;
|
|
621
|
+
const loc = normalize.loc;
|
|
622
|
+
const helpers = new Map();
|
|
623
|
+
const helperFor = (className) => {
|
|
624
|
+
const known = helpers.get(className);
|
|
625
|
+
if (known !== undefined)
|
|
626
|
+
return known;
|
|
627
|
+
const name = `%dyn.class.boxExact:${className}`;
|
|
628
|
+
helpers.set(className, name);
|
|
629
|
+
const type = { kind: "object", className };
|
|
630
|
+
const value = varRef("value", type, loc);
|
|
631
|
+
functions.push({
|
|
632
|
+
name,
|
|
633
|
+
params: [{ localId: "value", name: "value", type }],
|
|
634
|
+
returnType: DYN,
|
|
635
|
+
locals: [{ id: "value", name: "value", type, mutable: false }],
|
|
636
|
+
body: [
|
|
637
|
+
...branches.get(className).map((child) => ({
|
|
638
|
+
kind: "if",
|
|
639
|
+
cond: { kind: "instanceOf", value, className: child, type: BOOL, loc },
|
|
640
|
+
then: [
|
|
641
|
+
{
|
|
642
|
+
kind: "return",
|
|
643
|
+
value: {
|
|
644
|
+
kind: "dynFrom",
|
|
645
|
+
value: {
|
|
646
|
+
kind: "downcast",
|
|
647
|
+
value,
|
|
648
|
+
type: { kind: "object", className: child },
|
|
649
|
+
loc,
|
|
650
|
+
},
|
|
651
|
+
type: DYN,
|
|
652
|
+
loc,
|
|
653
|
+
},
|
|
654
|
+
loc,
|
|
655
|
+
},
|
|
656
|
+
],
|
|
657
|
+
else_: null,
|
|
658
|
+
loc,
|
|
659
|
+
})),
|
|
660
|
+
{ kind: "return", value: { kind: "dynFrom", value, type: DYN, loc }, loc },
|
|
661
|
+
],
|
|
662
|
+
loc,
|
|
663
|
+
});
|
|
664
|
+
return name;
|
|
665
|
+
};
|
|
666
|
+
const rewrite = (fn) => {
|
|
667
|
+
fn.body = transformStmtList(fn.body, {
|
|
668
|
+
stmt: (statement) => statement,
|
|
669
|
+
expr: (expression) => expression.kind === "dynFrom" &&
|
|
670
|
+
expression.value.type.kind === "object" &&
|
|
671
|
+
branches.has(expression.value.type.className)
|
|
672
|
+
? {
|
|
673
|
+
kind: "call",
|
|
674
|
+
callee: helperFor(expression.value.type.className),
|
|
675
|
+
args: [expression.value],
|
|
676
|
+
type: DYN,
|
|
677
|
+
loc: expression.loc,
|
|
678
|
+
}
|
|
679
|
+
: expression,
|
|
680
|
+
});
|
|
681
|
+
};
|
|
682
|
+
for (const fn of [...functions]) {
|
|
683
|
+
if (fn === normalize || fn.name.startsWith("%dyn.class.boxExact:"))
|
|
684
|
+
continue;
|
|
685
|
+
rewrite(fn);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
552
688
|
/** Record field creation after the dispatch worklist closes, including writes
|
|
553
689
|
* in generated member tables. Native values stay in their slots; the bag
|
|
554
690
|
* owns only their property presence, attributes, and insertion position. */
|
|
@@ -557,15 +693,151 @@ export function trackClassFieldCreation(lowerer, functions) {
|
|
|
557
693
|
return;
|
|
558
694
|
const loc = functions[0].loc;
|
|
559
695
|
const name = "%dyn.class.fieldCreated";
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
|
|
696
|
+
const key = varRef("key", DYN, loc);
|
|
697
|
+
// One helper per class: the instance's bag is its own hidden field, so a
|
|
698
|
+
// creation reads it directly instead of boxing the instance and testing
|
|
699
|
+
// it against every class's capsule (%dyn.class.properties), which runs
|
|
700
|
+
// only to create the bag, once per instance.
|
|
701
|
+
const perClass = new Map();
|
|
702
|
+
const helperFor = (className) => {
|
|
703
|
+
const known = perClass.get(className);
|
|
704
|
+
if (known !== undefined)
|
|
705
|
+
return known;
|
|
706
|
+
const helperName = `${name}:${className}`;
|
|
707
|
+
perClass.set(className, helperName);
|
|
708
|
+
const self = varRef("this", { kind: "object", className }, loc);
|
|
709
|
+
const bagRef = varRef("bag", DYN, loc);
|
|
710
|
+
functions.push({
|
|
711
|
+
name: helperName,
|
|
712
|
+
params: [
|
|
713
|
+
{ localId: "this", name: "this", type: { kind: "object", className } },
|
|
714
|
+
{ localId: "key", name: "key", type: DYN },
|
|
715
|
+
],
|
|
716
|
+
returnType: VOID,
|
|
717
|
+
locals: [
|
|
718
|
+
{ id: "this", name: "this", type: { kind: "object", className }, mutable: false },
|
|
719
|
+
{ id: "key", name: "key", type: DYN, mutable: false },
|
|
720
|
+
{ id: "bag", name: "bag", type: DYN, mutable: true },
|
|
721
|
+
],
|
|
722
|
+
body: [
|
|
723
|
+
{
|
|
724
|
+
kind: "varDecl",
|
|
725
|
+
localId: "bag",
|
|
726
|
+
init: { kind: "fieldGet", obj: self, className, field: PROPERTY_BAG, type: DYN, loc },
|
|
727
|
+
loc,
|
|
728
|
+
},
|
|
729
|
+
{
|
|
730
|
+
kind: "if",
|
|
731
|
+
cond: { kind: "dynTest", test: "undefined", value: bagRef, type: BOOL, loc },
|
|
732
|
+
then: initializeBag(lowerer, className, self, loc),
|
|
733
|
+
else_: null,
|
|
734
|
+
loc,
|
|
735
|
+
},
|
|
736
|
+
...defineIfAbsent(lowerer, bagRef, key, loc),
|
|
737
|
+
],
|
|
738
|
+
loc,
|
|
739
|
+
});
|
|
740
|
+
return helperName;
|
|
741
|
+
};
|
|
742
|
+
// String-keyed fields take the runtime's direct insert for an ordinary
|
|
743
|
+
// bag; the general path stays for any other bag and for symbol keys.
|
|
744
|
+
const stringHelperFor = (className) => {
|
|
745
|
+
const known = perClass.get(`str:${className}`);
|
|
746
|
+
if (known !== undefined)
|
|
747
|
+
return known;
|
|
748
|
+
const general = helperFor(className);
|
|
749
|
+
const helperName = `${name}.string:${className}`;
|
|
750
|
+
perClass.set(`str:${className}`, helperName);
|
|
751
|
+
const type = { kind: "object", className };
|
|
752
|
+
const self = varRef("this", type, loc);
|
|
753
|
+
const bagRef = varRef("bag", DYN, loc);
|
|
754
|
+
const field = varRef("field", STRING, loc);
|
|
755
|
+
functions.push({
|
|
756
|
+
name: helperName,
|
|
757
|
+
params: [
|
|
758
|
+
{ localId: "this", name: "this", type },
|
|
759
|
+
{ localId: "field", name: "field", type: STRING },
|
|
760
|
+
],
|
|
761
|
+
returnType: VOID,
|
|
762
|
+
locals: [
|
|
763
|
+
{ id: "this", name: "this", type, mutable: false },
|
|
764
|
+
{ id: "field", name: "field", type: STRING, mutable: false },
|
|
765
|
+
{ id: "bag", name: "bag", type: DYN, mutable: true },
|
|
766
|
+
],
|
|
767
|
+
body: [
|
|
768
|
+
{
|
|
769
|
+
kind: "varDecl",
|
|
770
|
+
localId: "bag",
|
|
771
|
+
init: { kind: "fieldGet", obj: self, className, field: PROPERTY_BAG, type: DYN, loc },
|
|
772
|
+
loc,
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
kind: "if",
|
|
776
|
+
cond: { kind: "dynTest", test: "undefined", value: bagRef, type: BOOL, loc },
|
|
777
|
+
then: initializeBag(lowerer, className, self, loc),
|
|
778
|
+
else_: null,
|
|
779
|
+
loc,
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
kind: "if",
|
|
783
|
+
cond: {
|
|
784
|
+
kind: "libCall",
|
|
785
|
+
fn: "dyn.bagCreateField",
|
|
786
|
+
args: [bagRef, field],
|
|
787
|
+
type: BOOL,
|
|
788
|
+
loc,
|
|
789
|
+
},
|
|
790
|
+
then: [{ kind: "return", value: null, loc }],
|
|
791
|
+
else_: null,
|
|
792
|
+
loc,
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
kind: "exprStmt",
|
|
796
|
+
expr: {
|
|
797
|
+
kind: "call",
|
|
798
|
+
callee: general,
|
|
799
|
+
args: [self, lowerer.coerceToExpected(field, DYN)],
|
|
800
|
+
type: VOID,
|
|
801
|
+
loc,
|
|
802
|
+
},
|
|
803
|
+
loc,
|
|
804
|
+
},
|
|
805
|
+
],
|
|
806
|
+
loc,
|
|
807
|
+
});
|
|
808
|
+
return helperName;
|
|
809
|
+
};
|
|
810
|
+
const created = (receiver, className, field, loc) => {
|
|
811
|
+
const symbolKey = symbolMemberKey(lowerer, lowerer.classes.get(className), field, loc);
|
|
812
|
+
if (symbolKey === null) {
|
|
813
|
+
return {
|
|
814
|
+
kind: "exprStmt",
|
|
815
|
+
expr: {
|
|
816
|
+
kind: "call",
|
|
817
|
+
callee: stringHelperFor(className),
|
|
818
|
+
args: [
|
|
819
|
+
receiver.type.kind === "object" && receiver.type.className !== className
|
|
820
|
+
? { kind: "upcast", value: receiver, type: { kind: "object", className }, loc }
|
|
821
|
+
: receiver,
|
|
822
|
+
{ kind: "strLit", value: field, type: STRING, loc },
|
|
823
|
+
],
|
|
824
|
+
type: VOID,
|
|
825
|
+
loc,
|
|
826
|
+
},
|
|
827
|
+
loc,
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
return createdGeneral(receiver, className, field, loc);
|
|
831
|
+
};
|
|
832
|
+
const createdGeneral = (receiver, className, field, loc) => ({
|
|
563
833
|
kind: "exprStmt",
|
|
564
834
|
expr: {
|
|
565
835
|
kind: "call",
|
|
566
|
-
callee:
|
|
836
|
+
callee: helperFor(className),
|
|
567
837
|
args: [
|
|
568
|
-
|
|
838
|
+
receiver.type.kind === "object" && receiver.type.className !== className
|
|
839
|
+
? { kind: "upcast", value: receiver, type: { kind: "object", className }, loc }
|
|
840
|
+
: receiver,
|
|
569
841
|
symbolMemberKey(lowerer, lowerer.classes.get(className), field, loc) ??
|
|
570
842
|
lowerer.coerceToExpected({ kind: "strLit", value: field, type: STRING, loc }, DYN),
|
|
571
843
|
],
|
|
@@ -633,77 +905,101 @@ export function trackClassFieldCreation(lowerer, functions) {
|
|
|
633
905
|
},
|
|
634
906
|
});
|
|
635
907
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
{ id: "value", name: "value", type: DYN, mutable: false },
|
|
645
|
-
{ id: "key", name: "key", type: DYN, mutable: false },
|
|
646
|
-
{ id: "bag", name: "bag", type: DYN, mutable: false },
|
|
647
|
-
],
|
|
648
|
-
body: [
|
|
908
|
+
}
|
|
909
|
+
/** `bag = <the class's new bag>`, stored in the instance's hidden field:
|
|
910
|
+
* the class's own initializer when recorded, else the class-table
|
|
911
|
+
* dispatch, which creates it. */
|
|
912
|
+
function initializeBag(lowerer, className, self, loc) {
|
|
913
|
+
const init = lowerer.classBagInitializers?.get(className);
|
|
914
|
+
if (init === undefined) {
|
|
915
|
+
return [
|
|
649
916
|
{
|
|
650
|
-
kind: "
|
|
917
|
+
kind: "assign",
|
|
651
918
|
localId: "bag",
|
|
652
|
-
|
|
919
|
+
value: {
|
|
653
920
|
kind: "call",
|
|
654
921
|
callee: classPropertiesHelper(lowerer, loc).name,
|
|
655
|
-
args: [
|
|
922
|
+
args: [lowerer.coerceToExpected(self, DYN)],
|
|
656
923
|
type: DYN,
|
|
657
924
|
loc,
|
|
658
925
|
},
|
|
659
926
|
loc,
|
|
660
927
|
},
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
},
|
|
700
|
-
],
|
|
701
|
-
else_: null,
|
|
928
|
+
];
|
|
929
|
+
}
|
|
930
|
+
return [
|
|
931
|
+
{
|
|
932
|
+
kind: "fieldSet",
|
|
933
|
+
obj: self,
|
|
934
|
+
className,
|
|
935
|
+
field: PROPERTY_BAG,
|
|
936
|
+
value: structuredClone(init),
|
|
937
|
+
loc,
|
|
938
|
+
},
|
|
939
|
+
{
|
|
940
|
+
kind: "assign",
|
|
941
|
+
localId: "bag",
|
|
942
|
+
value: { kind: "fieldGet", obj: self, className, field: PROPERTY_BAG, type: DYN, loc },
|
|
943
|
+
loc,
|
|
944
|
+
},
|
|
945
|
+
];
|
|
946
|
+
}
|
|
947
|
+
/** `value` as JSON without its source locations. */
|
|
948
|
+
function withoutLocations(value) {
|
|
949
|
+
return JSON.stringify(value, (key, field) => (key === "loc" ? undefined : field));
|
|
950
|
+
}
|
|
951
|
+
/** Whether `value` reads local `id`. */
|
|
952
|
+
function mentionsLocal(value, id) {
|
|
953
|
+
return JSON.stringify(value).includes(`"localId":${JSON.stringify(id)}`);
|
|
954
|
+
}
|
|
955
|
+
/** `if (!hasOwn(bag, key)) defineProperty(bag, key, <undefined data field>)`:
|
|
956
|
+
* a field's creation in its instance's property bag. */
|
|
957
|
+
function defineIfAbsent(lowerer, bag, key, loc) {
|
|
958
|
+
return [
|
|
959
|
+
{
|
|
960
|
+
kind: "if",
|
|
961
|
+
cond: {
|
|
962
|
+
kind: "unary",
|
|
963
|
+
op: "!",
|
|
964
|
+
operand: { kind: "libCall", fn: "dyn.hasOwnComputed", args: [bag, key], type: BOOL, loc },
|
|
965
|
+
type: BOOL,
|
|
702
966
|
loc,
|
|
703
967
|
},
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
968
|
+
then: [
|
|
969
|
+
{
|
|
970
|
+
kind: "exprStmt",
|
|
971
|
+
expr: {
|
|
972
|
+
kind: "libCall",
|
|
973
|
+
fn: "dyn.defineProperty",
|
|
974
|
+
args: [
|
|
975
|
+
bag,
|
|
976
|
+
lowerer.coerceToExpected(key, DYN),
|
|
977
|
+
{
|
|
978
|
+
kind: "dynObjLit",
|
|
979
|
+
fields: [
|
|
980
|
+
{
|
|
981
|
+
key: { kind: "strLit", value: "value", type: STRING, loc },
|
|
982
|
+
value: dynUndefinedExpr(loc),
|
|
983
|
+
},
|
|
984
|
+
...["writable", "enumerable", "configurable"].map((key) => ({
|
|
985
|
+
key: { kind: "strLit", value: key, type: STRING, loc },
|
|
986
|
+
value: lowerer.coerceToExpected({ kind: "boolLit", value: true, type: BOOL, loc }, DYN),
|
|
987
|
+
})),
|
|
988
|
+
],
|
|
989
|
+
type: DYN,
|
|
990
|
+
loc,
|
|
991
|
+
},
|
|
992
|
+
],
|
|
993
|
+
type: DYN,
|
|
994
|
+
loc,
|
|
995
|
+
},
|
|
996
|
+
loc,
|
|
997
|
+
},
|
|
998
|
+
],
|
|
999
|
+
else_: null,
|
|
1000
|
+
loc,
|
|
1001
|
+
},
|
|
1002
|
+
];
|
|
707
1003
|
}
|
|
708
1004
|
/** Calls on native class capsules keep the instance's compiled methods. The
|
|
709
1005
|
* reachable-body fixed point discovers both the boxed classes and method
|
|
@@ -724,6 +1020,9 @@ export class ClassDynamicDispatch {
|
|
|
724
1020
|
deletedNames;
|
|
725
1021
|
boxed = new Set();
|
|
726
1022
|
boxedConstructors = new Set();
|
|
1023
|
+
/** Every class a boxed value was statically typed as, runtime error
|
|
1024
|
+
* classes included: the value's capsule can be any of its subclasses. */
|
|
1025
|
+
boxedStatic = new Set();
|
|
727
1026
|
dispatches = new Map();
|
|
728
1027
|
properties = new Map();
|
|
729
1028
|
computed = new Map();
|
|
@@ -755,8 +1054,17 @@ export class ClassDynamicDispatch {
|
|
|
755
1054
|
descriptorHelper = null;
|
|
756
1055
|
prototypeHelper = null;
|
|
757
1056
|
prototypeClasses = new Set();
|
|
758
|
-
|
|
759
|
-
|
|
1057
|
+
/** The stand-in prototype object of each class without prototype data
|
|
1058
|
+
* (prototypeStandIn), by class name. */
|
|
1059
|
+
prototypeStandIns = new Set();
|
|
1060
|
+
/** The prototype reads of identity walks, by libCall, and the classes
|
|
1061
|
+
* each one answers for boxed instances. */
|
|
1062
|
+
prototypeIdentityHelpers = new Map();
|
|
1063
|
+
/** `value instanceof Error` through Error.prototype: boxed instances of
|
|
1064
|
+
* classes with a heritage evaluated at run time test their prototype
|
|
1065
|
+
* data's chain. */
|
|
1066
|
+
errorPrototypeHelper = null;
|
|
1067
|
+
errorPrototypeClasses = new Set();
|
|
760
1068
|
instancePrototypes = new Map();
|
|
761
1069
|
checkedCasts = new Map();
|
|
762
1070
|
/** The for-in key helpers, by libCall (dyn and native string[] keys). */
|
|
@@ -797,6 +1105,7 @@ export class ClassDynamicDispatch {
|
|
|
797
1105
|
return;
|
|
798
1106
|
seenTypes.add(key);
|
|
799
1107
|
if (type.kind === "object") {
|
|
1108
|
+
this.boxedStatic.add(type.className);
|
|
800
1109
|
if (isDynTypedRefType(type))
|
|
801
1110
|
this.boxed.add(type.className);
|
|
802
1111
|
}
|
|
@@ -947,9 +1256,11 @@ export class ClassDynamicDispatch {
|
|
|
947
1256
|
});
|
|
948
1257
|
changed = true;
|
|
949
1258
|
}
|
|
950
|
-
if (this.
|
|
951
|
-
this.
|
|
952
|
-
|
|
1259
|
+
if (this.errorPrototypeHelper &&
|
|
1260
|
+
!this.errorPrototypeClasses.has(className) &&
|
|
1261
|
+
hasRuntimeHeritage(info)) {
|
|
1262
|
+
this.errorPrototypeClasses.add(className);
|
|
1263
|
+
const loc = this.errorPrototypeHelper.loc;
|
|
953
1264
|
const type = { kind: "object", className };
|
|
954
1265
|
const value = varRef("value", DYN, loc);
|
|
955
1266
|
const prototype = classPrototypeData(lowerer, info, loc, {
|
|
@@ -959,7 +1270,7 @@ export class ClassDynamicDispatch {
|
|
|
959
1270
|
loc,
|
|
960
1271
|
});
|
|
961
1272
|
if (prototype)
|
|
962
|
-
this.
|
|
1273
|
+
this.errorPrototypeHelper.body.unshift({
|
|
963
1274
|
kind: "if",
|
|
964
1275
|
cond: {
|
|
965
1276
|
kind: "libCall",
|
|
@@ -968,7 +1279,19 @@ export class ClassDynamicDispatch {
|
|
|
968
1279
|
type: BOOL,
|
|
969
1280
|
loc,
|
|
970
1281
|
},
|
|
971
|
-
then: [
|
|
1282
|
+
then: [
|
|
1283
|
+
{
|
|
1284
|
+
kind: "return",
|
|
1285
|
+
value: {
|
|
1286
|
+
kind: "libCall",
|
|
1287
|
+
fn: "dyn.inheritsErrorPrototype",
|
|
1288
|
+
args: [prototype],
|
|
1289
|
+
type: BOOL,
|
|
1290
|
+
loc,
|
|
1291
|
+
},
|
|
1292
|
+
loc,
|
|
1293
|
+
},
|
|
1294
|
+
],
|
|
972
1295
|
else_: null,
|
|
973
1296
|
loc,
|
|
974
1297
|
});
|
|
@@ -1033,6 +1356,101 @@ export class ClassDynamicDispatch {
|
|
|
1033
1356
|
}
|
|
1034
1357
|
}
|
|
1035
1358
|
}
|
|
1359
|
+
// The runtime boxes a class instance as its exact class, so a value
|
|
1360
|
+
// boxed at a base (or Error) static type reaches the identity views as
|
|
1361
|
+
// any subclass's capsule.
|
|
1362
|
+
for (const helper of this.prototypeIdentityHelpers.values())
|
|
1363
|
+
for (const [className, info] of lowerer.classes) {
|
|
1364
|
+
if (helper.classes.has(className))
|
|
1365
|
+
continue;
|
|
1366
|
+
if (info.builtinEmitter || info.builtinStream || info.builtinError)
|
|
1367
|
+
continue;
|
|
1368
|
+
if (!isDynTypedRefType({ kind: "object", className }))
|
|
1369
|
+
continue;
|
|
1370
|
+
if (!this.boxed.has(className) &&
|
|
1371
|
+
![...this.boxedStatic].some((base) => lowerer.isSubclassOf(className, base)))
|
|
1372
|
+
continue;
|
|
1373
|
+
helper.classes.add(className);
|
|
1374
|
+
const loc = helper.fn.loc;
|
|
1375
|
+
const type = { kind: "object", className };
|
|
1376
|
+
const value = varRef("value", DYN, loc);
|
|
1377
|
+
// A class with no prototype data in its chain (one extending
|
|
1378
|
+
// Error, or with no methods) has no prototype a program can name:
|
|
1379
|
+
// an object of the class's own stands in, so instances of one class
|
|
1380
|
+
// share it (`Object.getPrototypeOf(a) === Object.getPrototypeOf(b)`),
|
|
1381
|
+
// other prototypes differ from it, and an instanceof walk (through
|
|
1382
|
+
// Object.prototype to null) answers false instead of reaching the
|
|
1383
|
+
// reflection refusal. A function-local class is a new class at
|
|
1384
|
+
// each evaluation of its declaration, so its instances answer with
|
|
1385
|
+
// the prototype of their own class value instead.
|
|
1386
|
+
const answer = (name) => {
|
|
1387
|
+
const of = lowerer.classes.get(name);
|
|
1388
|
+
const prototype = hasClassPrototypeData(of) || of.localClass
|
|
1389
|
+
? classPrototypeData(lowerer, of, loc, {
|
|
1390
|
+
kind: "dynCheck",
|
|
1391
|
+
value,
|
|
1392
|
+
type: { kind: "object", className: name },
|
|
1393
|
+
loc,
|
|
1394
|
+
})
|
|
1395
|
+
: null;
|
|
1396
|
+
if (prototype)
|
|
1397
|
+
return [{ kind: "return", value: prototype, loc }];
|
|
1398
|
+
return hasClassPrototypeData(of) ? null : this.prototypeStandIn(lowerer, name, loc);
|
|
1399
|
+
};
|
|
1400
|
+
const own = answer(className);
|
|
1401
|
+
if (!own) {
|
|
1402
|
+
changed = true;
|
|
1403
|
+
continue;
|
|
1404
|
+
}
|
|
1405
|
+
// A capsule boxed at this class can hold a subclass instance: the
|
|
1406
|
+
// most derived subclass the instance belongs to answers.
|
|
1407
|
+
const depth = (name) => {
|
|
1408
|
+
let n = 0;
|
|
1409
|
+
for (let at = lowerer.classes.get(name)?.base; at; at = at.base)
|
|
1410
|
+
n++;
|
|
1411
|
+
return n;
|
|
1412
|
+
};
|
|
1413
|
+
const subclasses = [...lowerer.classes.keys()]
|
|
1414
|
+
.filter((name) => name !== className &&
|
|
1415
|
+
lowerer.isSubclassOf(name, className) &&
|
|
1416
|
+
isDynTypedRefType({ kind: "object", className: name }))
|
|
1417
|
+
.sort((a, b) => depth(b) - depth(a));
|
|
1418
|
+
const then = [];
|
|
1419
|
+
for (const name of subclasses) {
|
|
1420
|
+
const sub = answer(name);
|
|
1421
|
+
if (!sub)
|
|
1422
|
+
continue;
|
|
1423
|
+
then.push({
|
|
1424
|
+
kind: "if",
|
|
1425
|
+
cond: {
|
|
1426
|
+
kind: "instanceOf",
|
|
1427
|
+
value: { kind: "dynCheck", value, type, loc },
|
|
1428
|
+
className: name,
|
|
1429
|
+
type: BOOL,
|
|
1430
|
+
loc,
|
|
1431
|
+
},
|
|
1432
|
+
then: sub,
|
|
1433
|
+
else_: null,
|
|
1434
|
+
loc,
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
then.push(...own);
|
|
1438
|
+
helper.fn.body.unshift({
|
|
1439
|
+
kind: "if",
|
|
1440
|
+
cond: {
|
|
1441
|
+
kind: "libCall",
|
|
1442
|
+
fn: "dyn.typedRefIs",
|
|
1443
|
+
args: [value, { kind: "strLit", value: typeKey(type), type: STRING, loc }],
|
|
1444
|
+
type: BOOL,
|
|
1445
|
+
loc,
|
|
1446
|
+
},
|
|
1447
|
+
then,
|
|
1448
|
+
else_: null,
|
|
1449
|
+
loc,
|
|
1450
|
+
});
|
|
1451
|
+
changed = true;
|
|
1452
|
+
}
|
|
1453
|
+
let live = null;
|
|
1036
1454
|
for (const plan of this.propertyReceivers(lowerer, false, false)) {
|
|
1037
1455
|
const info = plan.info;
|
|
1038
1456
|
const className = info.def.name;
|
|
@@ -1102,7 +1520,11 @@ export class ClassDynamicDispatch {
|
|
|
1102
1520
|
const needsPrototype = (current) => hasClassPrototypeData(current) ||
|
|
1103
1521
|
current.subclasses.some((child) => lowerer.classCanBeConstructed(child) && needsPrototype(child));
|
|
1104
1522
|
const prototypeFor = (current, receiver, loc) => this.bagPrototype(lowerer, current, receiver, loc);
|
|
1105
|
-
|
|
1523
|
+
live ??= this.liveBagInitializers();
|
|
1524
|
+
for (const existingInit of [
|
|
1525
|
+
...(this.bagInitializers.get(className) ?? []),
|
|
1526
|
+
...(live.get(className) ?? []),
|
|
1527
|
+
]) {
|
|
1106
1528
|
if (existingInit.value.kind === "dynObjLit" && needsPrototype(info)) {
|
|
1107
1529
|
const prototype = prototypeFor(info, existingInit.obj, existingInit.loc);
|
|
1108
1530
|
if (prototype) {
|
|
@@ -1113,6 +1535,14 @@ export class ClassDynamicDispatch {
|
|
|
1113
1535
|
type: DYN,
|
|
1114
1536
|
loc: existingInit.loc,
|
|
1115
1537
|
};
|
|
1538
|
+
// The initializer is a statement of the property bag helpers;
|
|
1539
|
+
// their reused site summaries do not see an edit inside it.
|
|
1540
|
+
if (this.propertyBag)
|
|
1541
|
+
this.sites.forget(this.propertyBag);
|
|
1542
|
+
for (const fn of this.typedPropertyBags.values())
|
|
1543
|
+
this.sites.forget(fn);
|
|
1544
|
+
for (const fn of this.exactPropertyBags.values())
|
|
1545
|
+
this.sites.forget(fn);
|
|
1116
1546
|
changed = true;
|
|
1117
1547
|
}
|
|
1118
1548
|
}
|
|
@@ -1137,6 +1567,15 @@ export class ClassDynamicDispatch {
|
|
|
1137
1567
|
this.deletedNames = deletedPropertyNames(lowerer.moduleOrder);
|
|
1138
1568
|
if (!root.base?.def.runtime && !fixedFieldFamily(root, this.deletedNames))
|
|
1139
1569
|
track(root);
|
|
1570
|
+
// An Error family's bag records where `name` and `message` were
|
|
1571
|
+
// created, which the error slots do not.
|
|
1572
|
+
if (root.base?.def.name === "%Error") {
|
|
1573
|
+
const order = (current) => {
|
|
1574
|
+
current.def.errorBagOrder = true;
|
|
1575
|
+
current.subclasses.forEach(order);
|
|
1576
|
+
};
|
|
1577
|
+
order(info);
|
|
1578
|
+
}
|
|
1140
1579
|
}
|
|
1141
1580
|
const loc = this.propertyBag.loc;
|
|
1142
1581
|
const { receiver, condition } = this.propertyReceiver(plan, loc);
|
|
@@ -1358,29 +1797,65 @@ export class ClassDynamicDispatch {
|
|
|
1358
1797
|
}
|
|
1359
1798
|
return { kind: "call", callee: cast.fn.name, args: [expr.value], type, loc: expr.loc };
|
|
1360
1799
|
}
|
|
1800
|
+
if (expr.kind === "libCall" && expr.fn === "dyn.inheritsErrorPrototype") {
|
|
1801
|
+
if (!this.errorPrototypeHelper) {
|
|
1802
|
+
const loc = expr.loc;
|
|
1803
|
+
this.errorPrototypeHelper = {
|
|
1804
|
+
name: "%dyn.class.inheritsErrorPrototype",
|
|
1805
|
+
params: [{ localId: "value", name: "value", type: DYN }],
|
|
1806
|
+
locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
|
|
1807
|
+
returnType: BOOL,
|
|
1808
|
+
loc,
|
|
1809
|
+
body: [
|
|
1810
|
+
{ kind: "return", value: { ...expr, args: [varRef("value", DYN, loc)] }, loc },
|
|
1811
|
+
],
|
|
1812
|
+
};
|
|
1813
|
+
lowerer.liftedFns.push(this.errorPrototypeHelper);
|
|
1814
|
+
this.generated.add(this.errorPrototypeHelper);
|
|
1815
|
+
changed = true;
|
|
1816
|
+
}
|
|
1817
|
+
return {
|
|
1818
|
+
kind: "call",
|
|
1819
|
+
callee: this.errorPrototypeHelper.name,
|
|
1820
|
+
args: expr.args,
|
|
1821
|
+
type: BOOL,
|
|
1822
|
+
loc: expr.loc,
|
|
1823
|
+
};
|
|
1824
|
+
}
|
|
1361
1825
|
if (expr.kind === "libCall" &&
|
|
1362
|
-
expr.fn === "dyn.getPrototype" &&
|
|
1826
|
+
(expr.fn === "dyn.getPrototype" || expr.fn === "dyn.getPrototypeForIdentity") &&
|
|
1363
1827
|
expr.args[0]?.kind !== "dynObjLit") {
|
|
1364
1828
|
if (expr.prototypeIdentityOnly) {
|
|
1365
|
-
|
|
1829
|
+
let helper = this.prototypeIdentityHelpers.get(expr.fn);
|
|
1830
|
+
if (!helper) {
|
|
1366
1831
|
const loc = expr.loc;
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1832
|
+
helper = {
|
|
1833
|
+
fn: {
|
|
1834
|
+
name: expr.fn === "dyn.getPrototype"
|
|
1835
|
+
? "%dyn.class.prototypeIdentity"
|
|
1836
|
+
: "%dyn.class.prototypeChainIdentity",
|
|
1837
|
+
params: [{ localId: "value", name: "value", type: DYN }],
|
|
1838
|
+
locals: [{ id: "value", name: "value", type: DYN, mutable: false }],
|
|
1839
|
+
returnType: DYN,
|
|
1840
|
+
loc,
|
|
1841
|
+
body: [
|
|
1842
|
+
{
|
|
1843
|
+
kind: "return",
|
|
1844
|
+
value: { ...expr, args: [varRef("value", DYN, loc)] },
|
|
1845
|
+
loc,
|
|
1846
|
+
},
|
|
1847
|
+
],
|
|
1848
|
+
},
|
|
1849
|
+
classes: new Set(),
|
|
1376
1850
|
};
|
|
1377
|
-
|
|
1378
|
-
|
|
1851
|
+
this.prototypeIdentityHelpers.set(expr.fn, helper);
|
|
1852
|
+
lowerer.liftedFns.push(helper.fn);
|
|
1853
|
+
this.generated.add(helper.fn);
|
|
1379
1854
|
changed = true;
|
|
1380
1855
|
}
|
|
1381
1856
|
return {
|
|
1382
1857
|
kind: "call",
|
|
1383
|
-
callee:
|
|
1858
|
+
callee: helper.fn.name,
|
|
1384
1859
|
args: expr.args,
|
|
1385
1860
|
type: DYN,
|
|
1386
1861
|
loc: expr.loc,
|
|
@@ -2152,7 +2627,28 @@ export class ClassDynamicDispatch {
|
|
|
2152
2627
|
loc,
|
|
2153
2628
|
});
|
|
2154
2629
|
}
|
|
2155
|
-
|
|
2630
|
+
const receiverAccess = read
|
|
2631
|
+
? [{ kind: "return", value: { ...read, value: varRef("p.0", DYN, loc) }, loc }]
|
|
2632
|
+
: [
|
|
2633
|
+
{
|
|
2634
|
+
kind: "exprStmt",
|
|
2635
|
+
expr: {
|
|
2636
|
+
...write,
|
|
2637
|
+
args: [varRef("p.0", DYN, loc), write.args[1], varRef("p.1", DYN, loc)],
|
|
2638
|
+
},
|
|
2639
|
+
loc,
|
|
2640
|
+
},
|
|
2641
|
+
{ kind: "return", value: null, loc },
|
|
2642
|
+
];
|
|
2643
|
+
dispatch = {
|
|
2644
|
+
name,
|
|
2645
|
+
write: !!write,
|
|
2646
|
+
fn: helper,
|
|
2647
|
+
classes: new Set(),
|
|
2648
|
+
...(name !== "constructor" && name !== "toString"
|
|
2649
|
+
? { plain: { tail: [...helper.body], access: receiverAccess } }
|
|
2650
|
+
: {}),
|
|
2651
|
+
};
|
|
2156
2652
|
this.properties.set(key, dispatch);
|
|
2157
2653
|
this.generated.add(helper);
|
|
2158
2654
|
lowerer.liftedFns.push(helper);
|
|
@@ -3273,6 +3769,39 @@ export class ClassDynamicDispatch {
|
|
|
3273
3769
|
}
|
|
3274
3770
|
/** The receiver's own dynamic properties for a read: undefined while it has
|
|
3275
3771
|
* none, and never stored, so reads stay valid on published objects. */
|
|
3772
|
+
/** Statements that return `className`'s stand-in prototype: one empty
|
|
3773
|
+
* object per class, created on first use and kept in a module global. */
|
|
3774
|
+
prototypeStandIn(lowerer, className, loc) {
|
|
3775
|
+
const globalId = `%g.%prototype.standIn.${className}`;
|
|
3776
|
+
const readyId = `${globalId}.ready`;
|
|
3777
|
+
if (!this.prototypeStandIns.has(className)) {
|
|
3778
|
+
this.prototypeStandIns.add(className);
|
|
3779
|
+
lowerer.globalsList.push({ id: globalId, name: `${className}.prototype`, type: DYN, mutable: true }, { id: readyId, name: `${className}.prototype.ready`, type: BOOL, mutable: true });
|
|
3780
|
+
}
|
|
3781
|
+
return [
|
|
3782
|
+
{
|
|
3783
|
+
kind: "if",
|
|
3784
|
+
cond: { kind: "unary", op: "!", operand: varRef(readyId, BOOL, loc), type: BOOL, loc },
|
|
3785
|
+
then: [
|
|
3786
|
+
{
|
|
3787
|
+
kind: "assign",
|
|
3788
|
+
localId: globalId,
|
|
3789
|
+
value: { kind: "dynObjLit", fields: [], type: DYN, loc },
|
|
3790
|
+
loc,
|
|
3791
|
+
},
|
|
3792
|
+
{
|
|
3793
|
+
kind: "assign",
|
|
3794
|
+
localId: readyId,
|
|
3795
|
+
value: { kind: "boolLit", value: true, type: BOOL, loc },
|
|
3796
|
+
loc,
|
|
3797
|
+
},
|
|
3798
|
+
],
|
|
3799
|
+
else_: null,
|
|
3800
|
+
loc,
|
|
3801
|
+
},
|
|
3802
|
+
{ kind: "return", value: varRef(globalId, DYN, loc), loc },
|
|
3803
|
+
];
|
|
3804
|
+
}
|
|
3276
3805
|
readPropertyBag(lowerer, receiver, loc) {
|
|
3277
3806
|
const helper = classPropertiesHelper(lowerer, loc, true);
|
|
3278
3807
|
this.generated.add(helper);
|
|
@@ -4086,6 +4615,34 @@ export class ClassDynamicDispatch {
|
|
|
4086
4615
|
* A class with constructible subclasses that have prototype data selects
|
|
4087
4616
|
* it through its `%class.bagPrototype` helper; any other class reads its
|
|
4088
4617
|
* own prototype data. */
|
|
4618
|
+
/** The lazy bag stores as they stand in the generated bodies, by class.
|
|
4619
|
+
* Worklist passes that transform every function rebuild statement
|
|
4620
|
+
* objects, so a recorded initializer can be a detached copy; a store that
|
|
4621
|
+
* gains its prototype must be updated where it runs. */
|
|
4622
|
+
liveBagInitializers() {
|
|
4623
|
+
const live = new Map();
|
|
4624
|
+
const add = (stmt) => {
|
|
4625
|
+
if (stmt?.kind !== "if")
|
|
4626
|
+
return;
|
|
4627
|
+
const store = stmt.then[0];
|
|
4628
|
+
if (store?.kind !== "fieldSet" || store.field !== PROPERTY_BAG)
|
|
4629
|
+
return;
|
|
4630
|
+
const list = live.get(store.className);
|
|
4631
|
+
if (list)
|
|
4632
|
+
list.push(store);
|
|
4633
|
+
else
|
|
4634
|
+
live.set(store.className, [store]);
|
|
4635
|
+
};
|
|
4636
|
+
// The complete dispatch guards each class's lazy store by its receiver.
|
|
4637
|
+
for (const stmt of this.propertyBag?.body ?? [])
|
|
4638
|
+
if (stmt.kind === "if")
|
|
4639
|
+
add(stmt.then[0]);
|
|
4640
|
+
for (const helper of this.typedPropertyBags.values())
|
|
4641
|
+
add(helper.body[0]);
|
|
4642
|
+
for (const helper of this.exactPropertyBags.values())
|
|
4643
|
+
add(helper.body[0]);
|
|
4644
|
+
return live;
|
|
4645
|
+
}
|
|
4089
4646
|
bagPrototype(lowerer, current, receiver, loc) {
|
|
4090
4647
|
const arg = receiver.type.kind === "object" && receiver.type.className !== current.def.name
|
|
4091
4648
|
? {
|
|
@@ -4159,6 +4716,8 @@ export class ClassDynamicDispatch {
|
|
|
4159
4716
|
if (lowerer)
|
|
4160
4717
|
for (const fn of this.generated)
|
|
4161
4718
|
lowerer.shareHelper(fn);
|
|
4719
|
+
if (lowerer)
|
|
4720
|
+
this.recordBagInitializers(lowerer);
|
|
4162
4721
|
for (const { helper, initialize, orEmpty } of this.readPropertyBags) {
|
|
4163
4722
|
const absent = helper.body[0];
|
|
4164
4723
|
if (isEmptyBag(initialize.value) && !orEmpty)
|
|
@@ -4175,6 +4734,170 @@ export class ClassDynamicDispatch {
|
|
|
4175
4734
|
fn.locals = structuredClone(this.propertyBag.locals);
|
|
4176
4735
|
fn.body = readOnlyBagBody(structuredClone(this.propertyBag.body), fn.name === READ_PROPERTIES_OR_EMPTY);
|
|
4177
4736
|
}
|
|
4737
|
+
if (lowerer)
|
|
4738
|
+
this.guardClassTables(lowerer);
|
|
4739
|
+
if (lowerer)
|
|
4740
|
+
this.guardPropertyHelpers(lowerer);
|
|
4741
|
+
}
|
|
4742
|
+
/** Each tracked class's bag initializer over a typed receiver (`this`),
|
|
4743
|
+
* for the per-class field-creation helpers (trackClassFieldCreation),
|
|
4744
|
+
* which create an instance's bag without the class-table dispatch. */
|
|
4745
|
+
recordBagInitializers(lowerer) {
|
|
4746
|
+
for (const [className, initializers] of this.bagInitializers) {
|
|
4747
|
+
const init = initializers[0];
|
|
4748
|
+
if (!init || !lowerer.classes.get(className)?.def.tracksOwnFields)
|
|
4749
|
+
continue;
|
|
4750
|
+
const self = varRef("this", { kind: "object", className }, init.loc);
|
|
4751
|
+
const value = withTypedReceiver(structuredClone(init.value), self);
|
|
4752
|
+
if (mentionsLocal(value, "p.0"))
|
|
4753
|
+
continue;
|
|
4754
|
+
// The class-table branches can give the class's instances different
|
|
4755
|
+
// bags (a base class's own prototype for its instances, the
|
|
4756
|
+
// instance's class prototype for subclass instances); only a class
|
|
4757
|
+
// whose branches all agree has one initializer for every instance.
|
|
4758
|
+
const shape = withoutLocations(value);
|
|
4759
|
+
if (initializers.some((other) => withoutLocations(withTypedReceiver(structuredClone(other.value), self)) !== shape))
|
|
4760
|
+
continue;
|
|
4761
|
+
// Lowerer stand-ins in unit tests may not carry the table.
|
|
4762
|
+
lowerer.classBagInitializers?.set(className, value);
|
|
4763
|
+
}
|
|
4764
|
+
}
|
|
4765
|
+
/** Fast exits for the generated class tables: every class branch of
|
|
4766
|
+
* the property-bag, normalization and static-bag helpers tests the
|
|
4767
|
+
* value's capsule key (or class key), so a value of another kind (a
|
|
4768
|
+
* plain object, the common case in untyped code) skips straight to the
|
|
4769
|
+
* table's fallthrough instead of testing every class in the program. */
|
|
4770
|
+
guardClassTables(lowerer) {
|
|
4771
|
+
const names = new Set([
|
|
4772
|
+
"%dyn.class.properties",
|
|
4773
|
+
READ_PROPERTIES,
|
|
4774
|
+
READ_PROPERTIES_OR_EMPTY,
|
|
4775
|
+
"%dyn.class.normalize",
|
|
4776
|
+
"%dyn.class.staticProperties",
|
|
4777
|
+
]);
|
|
4778
|
+
for (const fn of lowerer.liftedFns) {
|
|
4779
|
+
if (!names.has(fn.name) || fn.body.length < 2)
|
|
4780
|
+
continue;
|
|
4781
|
+
const param = fn.params[0]?.localId;
|
|
4782
|
+
if (param === undefined)
|
|
4783
|
+
continue;
|
|
4784
|
+
const last = fn.body[fn.body.length - 1];
|
|
4785
|
+
if (last.kind !== "return" || last.value === null || !returnsParam(last.value, param))
|
|
4786
|
+
continue;
|
|
4787
|
+
let test = null;
|
|
4788
|
+
let ok = true;
|
|
4789
|
+
for (const stmt of fn.body.slice(0, -1)) {
|
|
4790
|
+
if (stmt.kind === "assign" &&
|
|
4791
|
+
stmt.localId === param &&
|
|
4792
|
+
stmt.value.kind === "call" &&
|
|
4793
|
+
stmt.value.callee === "%dyn.class.normalize")
|
|
4794
|
+
continue;
|
|
4795
|
+
const kind = stmt.kind === "if" && stmt.else_ === null ? branchKind(stmt.cond, param) : null;
|
|
4796
|
+
if (kind === null || (test !== null && kind !== test)) {
|
|
4797
|
+
ok = false;
|
|
4798
|
+
break;
|
|
4799
|
+
}
|
|
4800
|
+
test = kind;
|
|
4801
|
+
}
|
|
4802
|
+
if (!ok || test === null)
|
|
4803
|
+
continue;
|
|
4804
|
+
const first = fn.body[0];
|
|
4805
|
+
if (first.kind === "if" && first.cond.kind === "dynTest" && first.cond.test === test)
|
|
4806
|
+
continue;
|
|
4807
|
+
const loc = fn.loc;
|
|
4808
|
+
fn.body.unshift({
|
|
4809
|
+
kind: "if",
|
|
4810
|
+
cond: {
|
|
4811
|
+
kind: "dynTest",
|
|
4812
|
+
test,
|
|
4813
|
+
negated: true,
|
|
4814
|
+
value: varRef(param, DYN, loc),
|
|
4815
|
+
type: BOOL,
|
|
4816
|
+
loc,
|
|
4817
|
+
},
|
|
4818
|
+
then: [structuredClone(last)],
|
|
4819
|
+
else_: null,
|
|
4820
|
+
loc,
|
|
4821
|
+
});
|
|
4822
|
+
}
|
|
4823
|
+
}
|
|
4824
|
+
/** Fast exits for the generated property helpers: when every class
|
|
4825
|
+
* branch tests a capsule key or a class key and the fallthrough is still
|
|
4826
|
+
* the bag access the helper was created with, a value of another kind
|
|
4827
|
+
* (a plain object, array or primitive) normalizes to itself, has itself
|
|
4828
|
+
* as its bag, and so gets the plain access directly, without the
|
|
4829
|
+
* normalization, bag and static-bag calls. */
|
|
4830
|
+
guardPropertyHelpers(lowerer) {
|
|
4831
|
+
// Every class table the fallthrough or normalization calls must answer
|
|
4832
|
+
// a plain value with the value itself: its kind exit is in place.
|
|
4833
|
+
const exits = (name) => {
|
|
4834
|
+
const helper = lowerer.liftedFnNamed(name);
|
|
4835
|
+
const first = helper?.body[0];
|
|
4836
|
+
const param = helper?.params[0]?.localId;
|
|
4837
|
+
return (param !== undefined &&
|
|
4838
|
+
first?.kind === "if" &&
|
|
4839
|
+
first.cond.kind === "dynTest" &&
|
|
4840
|
+
first.cond.negated === true &&
|
|
4841
|
+
first.then.length === 1 &&
|
|
4842
|
+
first.then[0].kind === "return" &&
|
|
4843
|
+
first.then[0].value !== null &&
|
|
4844
|
+
returnsParam(first.then[0].value, param));
|
|
4845
|
+
};
|
|
4846
|
+
const tables = new Set([
|
|
4847
|
+
"%dyn.class.properties",
|
|
4848
|
+
READ_PROPERTIES,
|
|
4849
|
+
READ_PROPERTIES_OR_EMPTY,
|
|
4850
|
+
"%dyn.class.normalize",
|
|
4851
|
+
"%dyn.class.staticProperties",
|
|
4852
|
+
]);
|
|
4853
|
+
const callsOnlyGuardedTables = (statements) => everyStmtList(statements, {
|
|
4854
|
+
stmt: () => true,
|
|
4855
|
+
expr: (expression) => expression.kind !== "call" || (tables.has(expression.callee) && exits(expression.callee)),
|
|
4856
|
+
});
|
|
4857
|
+
for (const dispatch of this.properties.values()) {
|
|
4858
|
+
const plain = dispatch.plain;
|
|
4859
|
+
if (!plain)
|
|
4860
|
+
continue;
|
|
4861
|
+
const fn = dispatch.fn;
|
|
4862
|
+
const param = fn.params[0]?.localId;
|
|
4863
|
+
if (param === undefined)
|
|
4864
|
+
continue;
|
|
4865
|
+
const head = fn.body.length - plain.tail.length;
|
|
4866
|
+
if (head < 0 || plain.tail.some((stmt, i) => fn.body[head + i] !== stmt))
|
|
4867
|
+
continue;
|
|
4868
|
+
let ok = true;
|
|
4869
|
+
for (const stmt of fn.body.slice(0, head)) {
|
|
4870
|
+
if (stmt.kind === "assign" &&
|
|
4871
|
+
stmt.localId === param &&
|
|
4872
|
+
stmt.value.kind === "call" &&
|
|
4873
|
+
stmt.value.callee === "%dyn.class.normalize")
|
|
4874
|
+
continue;
|
|
4875
|
+
if (stmt.kind === "if" && stmt.else_ === null && branchKind(stmt.cond, param) !== null)
|
|
4876
|
+
continue;
|
|
4877
|
+
ok = false;
|
|
4878
|
+
break;
|
|
4879
|
+
}
|
|
4880
|
+
// Class branches never run for a plain value; the rest always does.
|
|
4881
|
+
if (!ok || !callsOnlyGuardedTables(fn.body.filter((stmt) => stmt.kind !== "if")))
|
|
4882
|
+
continue;
|
|
4883
|
+
const loc = fn.loc;
|
|
4884
|
+
const not = (test) => ({
|
|
4885
|
+
kind: "dynTest",
|
|
4886
|
+
test,
|
|
4887
|
+
negated: true,
|
|
4888
|
+
value: varRef(param, DYN, loc),
|
|
4889
|
+
type: BOOL,
|
|
4890
|
+
loc,
|
|
4891
|
+
});
|
|
4892
|
+
fn.body.unshift({
|
|
4893
|
+
kind: "if",
|
|
4894
|
+
cond: not("classCapsule"),
|
|
4895
|
+
then: [{ kind: "if", cond: not("funcKind"), then: plain.access, else_: null, loc }],
|
|
4896
|
+
else_: null,
|
|
4897
|
+
loc,
|
|
4898
|
+
});
|
|
4899
|
+
delete dispatch.plain;
|
|
4900
|
+
}
|
|
4178
4901
|
}
|
|
4179
4902
|
normalizedDispatches() {
|
|
4180
4903
|
return [
|
|
@@ -4246,10 +4969,15 @@ export class ClassDynamicDispatch {
|
|
|
4246
4969
|
this.normalizationKey = key;
|
|
4247
4970
|
const loc = this.normalization.loc;
|
|
4248
4971
|
const value = varRef("value", DYN, loc);
|
|
4249
|
-
|
|
4972
|
+
// The checked receiver is unboxed once per capsule branch, not once
|
|
4973
|
+
// per subclass test.
|
|
4974
|
+
this.normalization.locals = this.normalization.locals.filter((local) => !local.id.startsWith("%normalized."));
|
|
4975
|
+
this.normalization.body = entries.map(({ capsule, children }, index) => {
|
|
4250
4976
|
const type = { kind: "object", className: capsule.def.name };
|
|
4251
|
-
const
|
|
4252
|
-
|
|
4977
|
+
const id = `%normalized.${index}`;
|
|
4978
|
+
this.normalization.locals.push({ id, name: id, type, mutable: false });
|
|
4979
|
+
const receiver = varRef(id, type, loc);
|
|
4980
|
+
const branch = {
|
|
4253
4981
|
kind: "if",
|
|
4254
4982
|
cond: {
|
|
4255
4983
|
kind: "libCall",
|
|
@@ -4290,6 +5018,15 @@ export class ClassDynamicDispatch {
|
|
|
4290
5018
|
else_: null,
|
|
4291
5019
|
loc,
|
|
4292
5020
|
};
|
|
5021
|
+
// The capsule test stays the branch condition; its body unboxes.
|
|
5022
|
+
if (branch.kind === "if")
|
|
5023
|
+
branch.then.unshift({
|
|
5024
|
+
kind: "varDecl",
|
|
5025
|
+
localId: id,
|
|
5026
|
+
init: { kind: "dynCheck", value, type, loc },
|
|
5027
|
+
loc,
|
|
5028
|
+
});
|
|
5029
|
+
return branch;
|
|
4293
5030
|
});
|
|
4294
5031
|
this.normalization.body.push({ kind: "return", value, loc });
|
|
4295
5032
|
}
|
|
@@ -5254,13 +5991,16 @@ export class ClassDynamicDispatch {
|
|
|
5254
5991
|
const arg = (i) => incoming[i] ?? dynUndefinedExpr(loc);
|
|
5255
5992
|
const readableT = { kind: "object", className: "%Readable" };
|
|
5256
5993
|
const op = (fn, args, type) => ret({ kind: "libCall", fn: fn, args: [receiver, ...args], type, loc });
|
|
5994
|
+
// Node passes every callback its { signal }; the callback's
|
|
5995
|
+
// declared parameters are not known here.
|
|
5996
|
+
const sig = () => operatorSignalOptions(lowerer, arg(1), loc);
|
|
5257
5997
|
switch (method) {
|
|
5258
5998
|
case "map":
|
|
5259
|
-
return op("readable.opMap", [arg(0), arg(1)], readableT);
|
|
5999
|
+
return op("readable.opMap", [arg(0), arg(1), sig()], readableT);
|
|
5260
6000
|
case "filter":
|
|
5261
|
-
return op("readable.opFilter", [arg(0), arg(1)], readableT);
|
|
6001
|
+
return op("readable.opFilter", [arg(0), arg(1), sig()], readableT);
|
|
5262
6002
|
case "flatMap":
|
|
5263
|
-
return op("readable.opFlatMap", [arg(0), arg(1)], readableT);
|
|
6003
|
+
return op("readable.opFlatMap", [arg(0), arg(1), sig()], readableT);
|
|
5264
6004
|
case "drop":
|
|
5265
6005
|
return op("readable.opDrop", [arg(0), arg(1)], readableT);
|
|
5266
6006
|
case "take":
|
|
@@ -5268,21 +6008,45 @@ export class ClassDynamicDispatch {
|
|
|
5268
6008
|
case "toArray":
|
|
5269
6009
|
return op("readable.opToArray", [arg(0)], { kind: "promise", inner: DYN });
|
|
5270
6010
|
case "forEach":
|
|
5271
|
-
return op("readable.opForEach", [arg(0), arg(1)], {
|
|
6011
|
+
return op("readable.opForEach", [arg(0), arg(1), sig()], {
|
|
6012
|
+
kind: "promise",
|
|
6013
|
+
inner: VOID,
|
|
6014
|
+
});
|
|
5272
6015
|
case "some":
|
|
5273
|
-
return op("readable.opSome", [arg(0), arg(1)], { kind: "promise", inner: BOOL });
|
|
6016
|
+
return op("readable.opSome", [arg(0), arg(1), sig()], { kind: "promise", inner: BOOL });
|
|
5274
6017
|
case "every":
|
|
5275
|
-
return op("readable.opEvery", [arg(0), arg(1)], {
|
|
6018
|
+
return op("readable.opEvery", [arg(0), arg(1), sig()], {
|
|
6019
|
+
kind: "promise",
|
|
6020
|
+
inner: BOOL,
|
|
6021
|
+
});
|
|
5276
6022
|
case "find":
|
|
5277
|
-
return op("readable.opFind", [arg(0), arg(1)], { kind: "promise", inner: DYN });
|
|
5278
|
-
case "reduce":
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
6023
|
+
return op("readable.opFind", [arg(0), arg(1), sig()], { kind: "promise", inner: DYN });
|
|
6024
|
+
case "reduce": {
|
|
6025
|
+
// the dispatch function's locals: there is no function
|
|
6026
|
+
// context while dispatch bodies are built
|
|
6027
|
+
const setup = reduceSignalSetup(lowerer, arg(2), loc, (name, type) => {
|
|
6028
|
+
const local = {
|
|
6029
|
+
id: `${name}.${dispatch.fn.locals.length}`,
|
|
6030
|
+
name,
|
|
6031
|
+
type,
|
|
6032
|
+
mutable: false,
|
|
6033
|
+
};
|
|
6034
|
+
dispatch.fn.locals.push(local);
|
|
6035
|
+
return local;
|
|
6036
|
+
});
|
|
6037
|
+
return [
|
|
6038
|
+
...setup.stmts,
|
|
6039
|
+
...op("readable.opReduceSignal", [
|
|
6040
|
+
arg(0),
|
|
6041
|
+
arg(1),
|
|
6042
|
+
{ kind: "boolLit", value: dispatch.source.args.length >= 2, type: BOOL, loc },
|
|
6043
|
+
arg(2),
|
|
6044
|
+
{ kind: "numLit", value: 0, type: F64, loc },
|
|
6045
|
+
setup.abort,
|
|
6046
|
+
setup.cbOpts,
|
|
6047
|
+
], { kind: "promise", inner: DYN }),
|
|
6048
|
+
];
|
|
6049
|
+
}
|
|
5286
6050
|
}
|
|
5287
6051
|
}
|
|
5288
6052
|
if (method === "destroy" && (!incoming.length || incoming[0]?.kind === "unitLit"))
|
|
@@ -5530,4 +6294,12 @@ const INHERITED_OBJECT_METHODS = new Set([
|
|
|
5530
6294
|
"hasOwnProperty",
|
|
5531
6295
|
"propertyIsEnumerable",
|
|
5532
6296
|
]);
|
|
6297
|
+
/** Whether a class or one of its bases has a heritage evaluated at run
|
|
6298
|
+
* time, whose prototype chain may reach Error.prototype. */
|
|
6299
|
+
function hasRuntimeHeritage(info) {
|
|
6300
|
+
for (let current = info; current; current = current.base)
|
|
6301
|
+
if (current.callableBase)
|
|
6302
|
+
return true;
|
|
6303
|
+
return false;
|
|
6304
|
+
}
|
|
5533
6305
|
//# sourceMappingURL=class-dynamic-dispatch.js.map
|