@scriptc/compiler 0.4.5 → 0.4.6
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/assert-strict.d.ts +47 -0
- package/ambient/node-fallback/assert.d.ts +86 -0
- package/ambient/node-fallback/async_hooks.d.ts +41 -0
- package/ambient/node-fallback/buffer.d.ts +23 -0
- package/ambient/node-fallback/child_process.d.ts +242 -0
- package/ambient/node-fallback/cluster.d.ts +17 -0
- package/ambient/node-fallback/constants.d.ts +15 -0
- package/ambient/node-fallback/crypto.d.ts +837 -0
- package/ambient/node-fallback/dgram.d.ts +58 -0
- package/ambient/node-fallback/diagnostics_channel.d.ts +87 -0
- package/ambient/node-fallback/dns-promises.d.ts +27 -0
- package/ambient/node-fallback/dns.d.ts +65 -0
- package/ambient/node-fallback/events.d.ts +60 -0
- package/ambient/node-fallback/fs-promises.d.ts +225 -0
- package/ambient/node-fallback/fs.d.ts +641 -0
- package/ambient/node-fallback/graceful-fs.d.ts +9 -0
- package/ambient/node-fallback/http.d.ts +326 -0
- package/ambient/node-fallback/http2.d.ts +816 -0
- package/ambient/node-fallback/https.d.ts +59 -0
- package/ambient/node-fallback/module.d.ts +10 -0
- package/ambient/node-fallback/net.d.ts +374 -0
- package/ambient/node-fallback/os.d.ts +288 -0
- package/ambient/node-fallback/path-posix.d.ts +22 -0
- package/ambient/node-fallback/path-win32.d.ts +22 -0
- package/ambient/node-fallback/path.d.ts +55 -0
- package/ambient/node-fallback/process.d.ts +11 -0
- package/ambient/node-fallback/punycode.d.ts +18 -0
- package/ambient/node-fallback/querystring.d.ts +55 -0
- package/ambient/node-fallback/stream-consumers.d.ts +21 -0
- package/ambient/node-fallback/stream-promises.d.ts +28 -0
- package/ambient/node-fallback/stream-web.d.ts +36 -0
- package/ambient/node-fallback/stream.d.ts +644 -0
- package/ambient/node-fallback/string_decoder.d.ts +20 -0
- package/ambient/node-fallback/test.d.ts +236 -0
- package/ambient/node-fallback/timers-promises.d.ts +31 -0
- package/ambient/node-fallback/timers.d.ts +28 -0
- package/ambient/node-fallback/tls.d.ts +169 -0
- package/ambient/node-fallback/url.d.ts +95 -0
- package/ambient/node-fallback/util-types.d.ts +50 -0
- package/ambient/node-fallback/util.d.ts +416 -0
- package/ambient/node-fallback/v8.d.ts +43 -0
- package/ambient/node-fallback/worker_threads.d.ts +113 -0
- package/ambient/node-fallback/zlib.d.ts +422 -0
- package/ambient/scriptc-node-fallback.d.ts +224 -6688
- package/dist/backend/cycle-analysis.js +4 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/executable-features.d.ts +1 -1
- package/dist/backend/executable-features.js +15 -2
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/huge-text.d.ts +16 -0
- package/dist/backend/huge-text.js +103 -0
- package/dist/backend/huge-text.js.map +1 -0
- package/dist/backend/huge-text.test.d.ts +1 -0
- package/dist/backend/huge-text.test.js +73 -0
- package/dist/backend/huge-text.test.js.map +1 -0
- package/dist/backend/library-pack.js +1 -1
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/link-plan-core.d.ts +10 -0
- package/dist/backend/link-plan-core.js +14 -2
- package/dist/backend/link-plan-core.js.map +1 -1
- package/dist/backend/link-plan-core.test.d.ts +1 -0
- package/dist/backend/link-plan-core.test.js +20 -0
- package/dist/backend/link-plan-core.test.js.map +1 -0
- package/dist/backend/link-plan.d.ts +8 -0
- package/dist/backend/link-plan.js +7 -0
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/linker.js +37 -14
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/lld.d.ts +13 -0
- package/dist/backend/lld.js +18 -1
- package/dist/backend/lld.js.map +1 -1
- package/dist/backend/lld.test.js +7 -1
- package/dist/backend/lld.test.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +2 -0
- package/dist/backend/llvm/alloc.js +1 -1
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/arenas.d.ts +78 -0
- package/dist/backend/llvm/arenas.js +313 -0
- package/dist/backend/llvm/arenas.js.map +1 -0
- package/dist/backend/llvm/arenas.test.d.ts +1 -0
- package/dist/backend/llvm/arenas.test.js +140 -0
- package/dist/backend/llvm/arenas.test.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +11 -1
- package/dist/backend/llvm/blocks.js +23 -5
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/bytes-headers.d.ts +19 -0
- package/dist/backend/llvm/bytes-headers.js +55 -0
- package/dist/backend/llvm/bytes-headers.js.map +1 -0
- package/dist/backend/llvm/bytes-loop-versions.d.ts +4 -3
- package/dist/backend/llvm/bytes-loop-versions.js +42 -7
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.test.js +39 -4
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.d.ts +5 -0
- package/dist/backend/llvm/call-lifetimes.js +43 -8
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +26 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.d.ts +3 -0
- package/dist/backend/llvm/checked-narrows.js +8 -1
- package/dist/backend/llvm/checked-narrows.js.map +1 -1
- package/dist/backend/llvm/class-unions.d.ts +21 -0
- package/dist/backend/llvm/class-unions.js +141 -0
- package/dist/backend/llvm/class-unions.js.map +1 -0
- package/dist/backend/llvm/class-unions.test.d.ts +1 -0
- package/dist/backend/llvm/class-unions.test.js +137 -0
- package/dist/backend/llvm/class-unions.test.js.map +1 -0
- package/dist/backend/llvm/classes.d.ts +46 -8
- package/dist/backend/llvm/classes.js +259 -32
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +4 -0
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +23 -0
- package/dist/backend/llvm/common.js +34 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +39 -0
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/constant-choices.d.ts +32 -0
- package/dist/backend/llvm/constant-choices.js +209 -0
- package/dist/backend/llvm/constant-choices.js.map +1 -0
- package/dist/backend/llvm/constant-choices.test.d.ts +1 -0
- package/dist/backend/llvm/constant-choices.test.js +94 -0
- package/dist/backend/llvm/constant-choices.test.js.map +1 -0
- package/dist/backend/llvm/counted-loops.d.ts +14 -2
- package/dist/backend/llvm/counted-loops.js +60 -7
- package/dist/backend/llvm/counted-loops.js.map +1 -1
- package/dist/backend/llvm/counted-loops.test.d.ts +1 -0
- package/dist/backend/llvm/counted-loops.test.js +34 -0
- package/dist/backend/llvm/counted-loops.test.js.map +1 -0
- package/dist/backend/llvm/cpu-dispatch.d.ts +26 -0
- package/dist/backend/llvm/cpu-dispatch.js +279 -0
- package/dist/backend/llvm/cpu-dispatch.js.map +1 -0
- package/dist/backend/llvm/dense-array-access.d.ts +13 -2
- package/dist/backend/llvm/dense-array-access.js +60 -6
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dyn-handle-tags.test.js +40 -14
- package/dist/backend/llvm/dyn-handle-tags.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +28 -2
- package/dist/backend/llvm/dyn.js +176 -27
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +25 -3
- 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.d.ts +5 -3
- package/dist/backend/llvm/emit-module.js +362 -74
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emit-statements.js +327 -59
- package/dist/backend/llvm/emit-statements.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +223 -33
- package/dist/backend/llvm/emitter.js +713 -100
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +20 -1
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +32 -6
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +9 -1
- package/dist/backend/llvm/expr-bytes.js +105 -9
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +1 -1
- package/dist/backend/llvm/expr-callbacks.js +29 -22
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +0 -4
- package/dist/backend/llvm/expr-calls.js +116 -14
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +77 -12
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +22 -0
- package/dist/backend/llvm/expr-control.d.ts +4 -0
- package/dist/backend/llvm/expr-control.js +485 -426
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +4 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +3 -3
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +6 -0
- package/dist/backend/llvm/expr-primitives.js +119 -58
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +11 -2
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +36 -4
- package/dist/backend/llvm/expr-records.js +249 -37
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +124 -7
- 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.js +13 -14
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/frame-escapes.d.ts +11 -0
- package/dist/backend/llvm/frame-escapes.js +219 -0
- package/dist/backend/llvm/frame-escapes.js.map +1 -0
- package/dist/backend/llvm/function-layout.d.ts +15 -0
- package/dist/backend/llvm/function-layout.js +40 -0
- package/dist/backend/llvm/function-layout.js.map +1 -0
- package/dist/backend/llvm/heap-census.d.ts +34 -0
- package/dist/backend/llvm/heap-census.js +163 -0
- package/dist/backend/llvm/heap-census.js.map +1 -0
- package/dist/backend/llvm/inline-arrays.d.ts +41 -0
- package/dist/backend/llvm/inline-arrays.js +195 -0
- package/dist/backend/llvm/inline-arrays.js.map +1 -0
- package/dist/backend/llvm/int32-kind-loops.js +2 -0
- package/dist/backend/llvm/int32-kind-loops.js.map +1 -1
- package/dist/backend/llvm/integer-clones.d.ts +32 -5
- package/dist/backend/llvm/integer-clones.js +237 -44
- package/dist/backend/llvm/integer-clones.js.map +1 -1
- package/dist/backend/llvm/integer-clones.test.js +120 -0
- package/dist/backend/llvm/integer-clones.test.js.map +1 -1
- package/dist/backend/llvm/iterative-teardown.test.d.ts +1 -0
- package/dist/backend/llvm/iterative-teardown.test.js +62 -0
- package/dist/backend/llvm/iterative-teardown.test.js.map +1 -0
- package/dist/backend/llvm/js-ic.js +246 -62
- package/dist/backend/llvm/js-ic.js.map +1 -1
- package/dist/backend/llvm/lib-connect.js +1 -1
- package/dist/backend/llvm/lib-connect.js.map +1 -1
- package/dist/backend/llvm/lib-datagram.js +2 -2
- package/dist/backend/llvm/lib-datagram.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +153 -16
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.d.ts +8 -0
- package/dist/backend/llvm/lib-filesystem.js +48 -4
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-http2.js +4 -3
- package/dist/backend/llvm/lib-http2.js.map +1 -1
- package/dist/backend/llvm/lib-lookup.js +1 -1
- package/dist/backend/llvm/lib-lookup.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +15 -1
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +32 -8
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.d.ts +3 -0
- package/dist/backend/llvm/lib-shared.js +191 -28
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +1 -1
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +15 -1
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +1 -1
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-extents.d.ts +22 -0
- package/dist/backend/llvm/local-extents.js +102 -0
- package/dist/backend/llvm/local-extents.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.js +15 -2
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +1 -1
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
- package/dist/backend/llvm/loop-callees.d.ts +21 -0
- package/dist/backend/llvm/loop-callees.js +119 -0
- package/dist/backend/llvm/loop-callees.js.map +1 -0
- package/dist/backend/llvm/loop-callees.test.d.ts +1 -0
- package/dist/backend/llvm/loop-callees.test.js +65 -0
- package/dist/backend/llvm/loop-callees.test.js.map +1 -0
- package/dist/backend/llvm/loop-entry-versions.d.ts +17 -0
- package/dist/backend/llvm/loop-entry-versions.js +185 -0
- package/dist/backend/llvm/loop-entry-versions.js.map +1 -0
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +13 -4
- package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.d.ts +11 -0
- package/dist/backend/llvm/map-read-lifetimes.js +51 -1
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +6 -3
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.d.ts +67 -10
- package/dist/backend/llvm/nullable-unions.js +218 -22
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.js +124 -1
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -1
- package/dist/backend/llvm/periodic-guards.d.ts +16 -0
- package/dist/backend/llvm/periodic-guards.js +91 -0
- package/dist/backend/llvm/periodic-guards.js.map +1 -0
- package/dist/backend/llvm/periodic-guards.test.d.ts +1 -0
- package/dist/backend/llvm/periodic-guards.test.js +64 -0
- package/dist/backend/llvm/periodic-guards.test.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +12 -2
- package/dist/backend/llvm/publish.js +15 -8
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/rebound-parameters.d.ts +4 -1
- package/dist/backend/llvm/rebound-parameters.js +17 -1
- package/dist/backend/llvm/rebound-parameters.js.map +1 -1
- package/dist/backend/llvm/receivers.d.ts +7 -0
- package/dist/backend/llvm/receivers.js +77 -10
- package/dist/backend/llvm/receivers.js.map +1 -1
- package/dist/backend/llvm/record-union-keys.test.js +29 -0
- package/dist/backend/llvm/record-union-keys.test.js.map +1 -1
- package/dist/backend/llvm/record-views.d.ts +29 -0
- package/dist/backend/llvm/record-views.js +249 -0
- package/dist/backend/llvm/record-views.js.map +1 -0
- package/dist/backend/llvm/record-views.test.d.ts +1 -0
- package/dist/backend/llvm/record-views.test.js +118 -0
- package/dist/backend/llvm/record-views.test.js.map +1 -0
- package/dist/backend/llvm/reference-writes.js +21 -0
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/reference-writes.test.js +42 -0
- package/dist/backend/llvm/reference-writes.test.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.d.ts +5 -1
- package/dist/backend/llvm/regex-matchers.js +173 -21
- package/dist/backend/llvm/regex-matchers.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.test.js +39 -1
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -1
- package/dist/backend/llvm/region-groups.d.ts +67 -0
- package/dist/backend/llvm/region-groups.js +1719 -0
- package/dist/backend/llvm/region-groups.js.map +1 -0
- package/dist/backend/llvm/region-groups.test.d.ts +1 -0
- package/dist/backend/llvm/region-groups.test.js +197 -0
- package/dist/backend/llvm/region-groups.test.js.map +1 -0
- package/dist/backend/llvm/region-ir.d.ts +31 -0
- package/dist/backend/llvm/region-ir.js +256 -0
- package/dist/backend/llvm/region-ir.js.map +1 -0
- package/dist/backend/llvm/region-sites.d.ts +20 -0
- package/dist/backend/llvm/region-sites.js +327 -0
- package/dist/backend/llvm/region-sites.js.map +1 -0
- package/dist/backend/llvm/region-sites.test.d.ts +1 -0
- package/dist/backend/llvm/region-sites.test.js +216 -0
- package/dist/backend/llvm/region-sites.test.js.map +1 -0
- package/dist/backend/llvm/repr-report.d.ts +9 -0
- package/dist/backend/llvm/repr-report.js +143 -0
- package/dist/backend/llvm/repr-report.js.map +1 -0
- package/dist/backend/llvm/repr-report.test.d.ts +1 -0
- package/dist/backend/llvm/repr-report.test.js +62 -0
- package/dist/backend/llvm/repr-report.test.js.map +1 -0
- package/dist/backend/llvm/runtime-registries.test.d.ts +1 -0
- package/dist/backend/llvm/runtime-registries.test.js +88 -0
- package/dist/backend/llvm/runtime-registries.test.js.map +1 -0
- package/dist/backend/llvm/serialized-ir-emission.test.js +1 -0
- package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -1
- package/dist/backend/llvm/shape-union-tags.test.d.ts +1 -0
- package/dist/backend/llvm/shape-union-tags.test.js +75 -0
- package/dist/backend/llvm/shape-union-tags.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +60 -10
- package/dist/backend/llvm/shapes.js +233 -51
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +37 -18
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/speculative-integers.d.ts +3 -0
- package/dist/backend/llvm/speculative-integers.js +20 -8
- package/dist/backend/llvm/speculative-integers.js.map +1 -1
- package/dist/backend/llvm/split.js +6 -1
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/split.test.js +23 -0
- package/dist/backend/llvm/split.test.js.map +1 -1
- package/dist/backend/llvm/stack-callbacks.js +4 -2
- package/dist/backend/llvm/stack-callbacks.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +12 -3
- package/dist/backend/llvm/stack-objects.js +110 -22
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/stack-objects.test.js +144 -0
- package/dist/backend/llvm/stack-objects.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +24 -1
- package/dist/backend/llvm/stack-unions.test.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.js +2 -1
- package/dist/backend/llvm/string-lifetimes.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +4 -0
- package/dist/backend/llvm/string-reads.js +27 -0
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/test-boxed-unions.d.ts +10 -8
- package/dist/backend/llvm/test-boxed-unions.js +20 -25
- package/dist/backend/llvm/test-boxed-unions.js.map +1 -1
- package/dist/backend/llvm/union-repr.js +9 -8
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.js +45 -2
- package/dist/backend/llvm/union-retype.test.js.map +1 -1
- package/dist/backend/llvm/unwind-abi.d.ts +20 -8
- package/dist/backend/llvm/unwind-abi.js +177 -70
- package/dist/backend/llvm/unwind-abi.js.map +1 -1
- package/dist/backend/llvm/unwind-abi.test.js +90 -3
- package/dist/backend/llvm/unwind-abi.test.js.map +1 -1
- package/dist/backend/llvm/walk-borrows.d.ts +3 -2
- package/dist/backend/llvm/walk-borrows.js +2 -2
- package/dist/backend/llvm/walk-borrows.js.map +1 -1
- package/dist/backend/llvm/walk-borrows.test.js +18 -0
- package/dist/backend/llvm/walk-borrows.test.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +14 -1
- package/dist/backend/llvm/walkers.js +103 -11
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wrapping-sums.d.ts +26 -6
- package/dist/backend/llvm/wrapping-sums.js +64 -12
- package/dist/backend/llvm/wrapping-sums.js.map +1 -1
- package/dist/backend/loop-polls.d.ts +4 -2
- package/dist/backend/loop-polls.js +11 -2
- package/dist/backend/loop-polls.js.map +1 -1
- package/dist/backend/mangle.d.ts +0 -5
- package/dist/backend/mangle.js +0 -9
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.d.ts +10 -9
- package/dist/backend/may-throw.js +189 -27
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +44 -7
- package/dist/backend/may-throw.test.js.map +1 -1
- package/dist/backend/native/compiler-fingerprint.d.ts +5 -0
- package/dist/backend/native/compiler-fingerprint.js +62 -16
- package/dist/backend/native/compiler-fingerprint.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +31 -8
- package/dist/backend/native/executable.js +56 -32
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +3 -4
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/object-merge.d.ts +3 -1
- package/dist/backend/native/object-merge.js +24 -11
- package/dist/backend/native/object-merge.js.map +1 -1
- package/dist/backend/native/program-shards.js +6 -3
- package/dist/backend/native/program-shards.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +3 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native/vendor.d.ts +1 -1
- package/dist/backend/native-codegen-core.d.ts +15 -6
- package/dist/backend/native-codegen-core.js +20 -9
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.js +51 -5
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +82 -8
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +30 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-profile.d.ts +68 -4
- package/dist/backend/native-profile.js +86 -14
- package/dist/backend/native-profile.js.map +1 -1
- package/dist/backend/native-profile.test.js +127 -4
- package/dist/backend/native-profile.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 +58 -4
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/native-tools.d.ts +17 -3
- package/dist/backend/native-tools.js +12 -4
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/native-tools.test.d.ts +1 -0
- package/dist/backend/native-tools.test.js +76 -0
- package/dist/backend/native-tools.test.js.map +1 -0
- package/dist/backend/object-localize.js +69 -9
- package/dist/backend/object-localize.js.map +1 -1
- package/dist/backend/object-localize.test.js +99 -10
- package/dist/backend/object-localize.test.js.map +1 -1
- package/dist/backend/publication.d.ts +2 -0
- package/dist/backend/publication.js +4 -0
- package/dist/backend/publication.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +19 -0
- package/dist/backend/runtime-pack-core.js +23 -3
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.test.js +48 -2
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/target-cpu.d.ts +2 -0
- package/dist/backend/target-cpu.js +4 -0
- package/dist/backend/target-cpu.js.map +1 -1
- package/dist/backend/target-diagnostics.js +1 -19
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/target-diagnostics.test.js.map +1 -1
- package/dist/backend/targets.d.ts +28 -0
- package/dist/backend/targets.js +70 -0
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +75 -1
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/backend/vendor-archives.d.ts +1 -1
- package/dist/backend/vendor-archives.js +25 -12
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.d.ts +15 -2
- package/dist/backend/vendor-inputs.js +59 -3
- package/dist/backend/vendor-inputs.js.map +1 -1
- package/dist/backend/vendor-inputs.test.d.ts +1 -0
- package/dist/backend/vendor-inputs.test.js +74 -0
- package/dist/backend/vendor-inputs.test.js.map +1 -0
- package/dist/cli/command.js +95 -5
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +3 -0
- package/dist/cli/output-options.d.ts +3 -0
- package/dist/cli/output-options.js +8 -2
- package/dist/cli/output-options.js.map +1 -1
- package/dist/cli/usage.d.ts +28 -1
- package/dist/cli/usage.js +56 -6
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.d.ts +3 -0
- package/dist/compat/fetch-profile.js +23 -3
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +45 -0
- package/dist/contracts/check.js +70 -2
- package/dist/contracts/check.js.map +1 -1
- package/dist/contracts/int32-elements.d.ts +2 -1
- package/dist/contracts/int32-elements.js.map +1 -1
- package/dist/coverage/report.d.ts +5 -1
- package/dist/coverage/report.js +83 -2
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +2 -0
- package/dist/coverage/verdict-cache.js +5 -10
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/diagnostics/codes.d.ts +145 -0
- package/dist/diagnostics/codes.js +159 -0
- package/dist/diagnostics/codes.js.map +1 -0
- package/dist/diagnostics/codes.test.d.ts +1 -0
- package/dist/diagnostics/codes.test.js +78 -0
- package/dist/diagnostics/codes.test.js.map +1 -0
- package/dist/diagnostics/diagnostic.d.ts +101 -2
- package/dist/diagnostics/diagnostic.js +155 -0
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/dynamic-slots.d.ts +23 -0
- package/dist/diagnostics/dynamic-slots.js +29 -0
- package/dist/diagnostics/dynamic-slots.js.map +1 -0
- package/dist/diagnostics/dynamic-tier.d.ts +6 -0
- package/dist/diagnostics/dynamic-tier.js +8 -1
- package/dist/diagnostics/dynamic-tier.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +43 -1
- package/dist/diagnostics/envelope.js +19 -1
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/envelope.test.js.map +1 -1
- package/dist/diagnostics/render.d.ts +3 -1
- package/dist/diagnostics/render.js +27 -6
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +41 -0
- package/dist/executable/executable-cache.js +39 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +4 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.d.ts +2 -1
- package/dist/executable/prepare.js +421 -10
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +1 -0
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/canon-map.d.ts +17 -0
- package/dist/frontend/canon-map.js +177 -0
- package/dist/frontend/canon-map.js.map +1 -0
- package/dist/frontend/canon.d.ts +122 -0
- package/dist/frontend/canon.js +462 -0
- package/dist/frontend/canon.js.map +1 -0
- package/dist/frontend/contract-types.d.ts +9 -1
- package/dist/frontend/contract-types.js +46 -4
- package/dist/frontend/contract-types.js.map +1 -1
- package/dist/frontend/decl-projection.d.ts +3 -0
- package/dist/frontend/decl-projection.js +121 -3
- package/dist/frontend/decl-projection.js.map +1 -1
- package/dist/frontend/dts-paths.d.ts +17 -4
- package/dist/frontend/dts-paths.js +149 -5
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/fork-target.js +4 -4
- package/dist/frontend/fork-target.js.map +1 -1
- package/dist/frontend/fork-target.test.js +3 -3
- package/dist/frontend/fork-target.test.js.map +1 -1
- package/dist/frontend/heritage-elements.d.ts +15 -0
- package/dist/frontend/heritage-elements.js +18 -0
- package/dist/frontend/heritage-elements.js.map +1 -0
- package/dist/frontend/heritage-elements.test.d.ts +1 -0
- package/dist/frontend/heritage-elements.test.js +68 -0
- package/dist/frontend/heritage-elements.test.js.map +1 -0
- package/dist/frontend/input-tracker.d.ts +20 -0
- package/dist/frontend/input-tracker.js +74 -4
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +66 -0
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lowering/any-collection-residue.d.ts +9 -0
- package/dist/frontend/lowering/any-collection-residue.js +42 -0
- package/dist/frontend/lowering/any-collection-residue.js.map +1 -0
- package/dist/frontend/lowering/array-values.d.ts +44 -2
- package/dist/frontend/lowering/array-values.js +193 -3
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtin-namespaces.d.ts +6 -2
- package/dist/frontend/lowering/builtin-namespaces.js +28 -6
- package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
- package/dist/frontend/lowering/builtins/array-classes.d.ts +69 -0
- package/dist/frontend/lowering/builtins/array-classes.js +729 -0
- package/dist/frontend/lowering/builtins/array-classes.js.map +1 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js +4 -0
- package/dist/frontend/lowering/builtins/callable-aliases.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.js +34 -0
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/disposable-stack.js +1 -3
- package/dist/frontend/lowering/builtins/disposable-stack.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.d.ts +13 -9
- package/dist/frontend/lowering/builtins/errors.js +136 -56
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +1 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +85 -4
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem.d.ts +11 -6
- package/dist/frontend/lowering/builtins/filesystem.js +270 -24
- package/dist/frontend/lowering/builtins/filesystem.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +7 -1
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/mime.d.ts +25 -0
- package/dist/frontend/lowering/builtins/mime.js +167 -0
- package/dist/frontend/lowering/builtins/mime.js.map +1 -0
- package/dist/frontend/lowering/builtins/module-bindings.d.ts +3 -0
- package/dist/frontend/lowering/builtins/module-bindings.js +6 -0
- package/dist/frontend/lowering/builtins/module-bindings.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +79 -12
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +7 -4
- package/dist/frontend/lowering/builtins/module-resolution.js +115 -13
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/navigator.d.ts +3 -1
- package/dist/frontend/lowering/builtins/navigator.js +22 -8
- package/dist/frontend/lowering/builtins/navigator.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.js +49 -9
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.js +18 -3
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/promisify-callback.d.ts +6 -2
- package/dist/frontend/lowering/builtins/promisify-callback.js +19 -6
- package/dist/frontend/lowering/builtins/promisify-callback.js.map +1 -1
- package/dist/frontend/lowering/builtins/properties.js +23 -5
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/web-streams-dyn.d.ts +42 -0
- package/dist/frontend/lowering/builtins/web-streams-dyn.js +321 -0
- package/dist/frontend/lowering/builtins/web-streams-dyn.js.map +1 -0
- package/dist/frontend/lowering/builtins/x509.js +35 -5
- package/dist/frontend/lowering/builtins/x509.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.d.ts +14 -1
- package/dist/frontend/lowering/call-arguments.js +84 -70
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.js +108 -24
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/class-attributes.js +6 -5
- package/dist/frontend/lowering/class-attributes.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.js +40 -19
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-protocol-dispatch.js +4 -0
- package/dist/frontend/lowering/class-protocol-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +61 -1
- package/dist/frontend/lowering/class-protocols.js +297 -21
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/class-to-primitive.d.ts +3 -2
- package/dist/frontend/lowering/class-to-primitive.js +15 -5
- package/dist/frontend/lowering/class-to-primitive.js.map +1 -1
- package/dist/frontend/lowering/coercions/asserted.d.ts +16 -0
- package/dist/frontend/lowering/coercions/asserted.js +79 -0
- package/dist/frontend/lowering/coercions/asserted.js.map +1 -0
- package/dist/frontend/lowering/coercions/function-adapters.d.ts +13 -0
- package/dist/frontend/lowering/coercions/function-adapters.js +70 -3
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/state.d.ts +23 -0
- package/dist/frontend/lowering/coercions/state.js +9 -0
- package/dist/frontend/lowering/coercions/state.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +67 -1
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.d.ts +10 -0
- package/dist/frontend/lowering/coercions/structural.js +134 -4
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +11 -0
- package/dist/frontend/lowering/coercions/unions.js +83 -4
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/completion-callbacks.js +3 -2
- package/dist/frontend/lowering/completion-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +10 -0
- package/dist/frontend/lowering/containers/array-callbacks.js +224 -81
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.d.ts +5 -2
- package/dist/frontend/lowering/containers/array-concat.js +76 -7
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.d.ts +9 -4
- package/dist/frontend/lowering/containers/array-construction.js +112 -100
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +193 -45
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.d.ts +3 -0
- package/dist/frontend/lowering/containers/array-pipelines.js +81 -13
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +1 -0
- package/dist/frontend/lowering/containers/callback-arguments.js +28 -2
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +13 -3
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/filter-predicates.js +34 -3
- package/dist/frontend/lowering/containers/filter-predicates.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.d.ts +34 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +131 -72
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.js +43 -6
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/decl-origin.d.ts +49 -0
- package/dist/frontend/lowering/decl-origin.js +402 -0
- package/dist/frontend/lowering/decl-origin.js.map +1 -0
- package/dist/frontend/lowering/deferred-module-initializers.d.ts +2 -0
- package/dist/frontend/lowering/deferred-module-initializers.js +7 -0
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/divergences.js +5 -0
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/dynamic-tier.d.ts +8 -2
- package/dist/frontend/lowering/dynamic-tier.js +111 -3
- package/dist/frontend/lowering/dynamic-tier.js.map +1 -1
- package/dist/frontend/lowering/expressions/array-literals.d.ts +14 -1
- package/dist/frontend/lowering/expressions/array-literals.js +43 -5
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/asserted-receiver.d.ts +48 -0
- package/dist/frontend/lowering/expressions/asserted-receiver.js +233 -0
- package/dist/frontend/lowering/expressions/asserted-receiver.js.map +1 -0
- package/dist/frontend/lowering/expressions/binary.js +136 -1
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.d.ts +7 -0
- package/dist/frontend/lowering/expressions/element-access.js +363 -12
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.d.ts +3 -0
- package/dist/frontend/lowering/expressions/identifiers.js +78 -62
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/message-listeners.d.ts +3 -0
- package/dist/frontend/lowering/expressions/message-listeners.js +19 -0
- package/dist/frontend/lowering/expressions/message-listeners.js.map +1 -0
- package/dist/frontend/lowering/expressions/narrowing.js +224 -6
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +5 -2
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +282 -24
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +15 -3
- package/dist/frontend/lowering/expressions/property-access.js +397 -74
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/relational.js +202 -70
- package/dist/frontend/lowering/expressions/relational.js.map +1 -1
- package/dist/frontend/lowering/expressions/typeof.js +9 -1
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-fields.d.ts +28 -8
- package/dist/frontend/lowering/expressions/union-fields.js +168 -14
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/frozen-records.d.ts +8 -0
- package/dist/frontend/lowering/frozen-records.js +56 -9
- package/dist/frontend/lowering/frozen-records.js.map +1 -1
- package/dist/frontend/lowering/function-context.d.ts +3 -0
- package/dist/frontend/lowering/function-context.js +4 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/function-returns.d.ts +4 -0
- package/dist/frontend/lowering/function-returns.js +231 -2
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/generator-delegation.js +3 -2
- package/dist/frontend/lowering/generator-delegation.js.map +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +26 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +294 -2
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +10 -0
- package/dist/frontend/lowering/generic-functions.js +67 -7
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/global-values.d.ts +37 -0
- package/dist/frontend/lowering/global-values.js +395 -0
- package/dist/frontend/lowering/global-values.js.map +1 -0
- package/dist/frontend/lowering/handle-properties.js +3 -2
- package/dist/frontend/lowering/handle-properties.js.map +1 -1
- package/dist/frontend/lowering/handle-properties.test.d.ts +1 -0
- package/dist/frontend/lowering/handle-properties.test.js +25 -0
- package/dist/frontend/lowering/handle-properties.test.js.map +1 -0
- package/dist/frontend/lowering/import-meta.d.ts +3 -0
- package/dist/frontend/lowering/import-meta.js +8 -3
- package/dist/frontend/lowering/import-meta.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.js +3 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.d.ts +2 -0
- package/dist/frontend/lowering/key-order-witness.js +10 -0
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.d.ts +5 -1
- package/dist/frontend/lowering/lower-array-sort.js +16 -2
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +7 -0
- package/dist/frontend/lowering/lower-builtin-values.js +65 -16
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +222 -24
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +6 -0
- package/dist/frontend/lowering/lower-classes.js +154 -20
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-console.js +25 -2
- package/dist/frontend/lowering/lower-console.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +29 -0
- package/dist/frontend/lowering/lower-exprs.js +544 -24
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +93 -18
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.d.ts +4 -1
- package/dist/frontend/lowering/lower-global-value.js +10 -3
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +44 -4
- package/dist/frontend/lowering/lower-inspect.js +723 -26
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +3 -1
- package/dist/frontend/lowering/lower-modules.js +189 -24
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +7 -0
- package/dist/frontend/lowering/lower-namespaces.js +23 -0
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-island.d.ts +74 -0
- package/dist/frontend/lowering/lower-node-island.js +1931 -0
- package/dist/frontend/lowering/lower-node-island.js.map +1 -0
- package/dist/frontend/lowering/lower-server.js +44 -0
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-shared-modules.d.ts +27 -0
- package/dist/frontend/lowering/lower-shared-modules.js +611 -0
- package/dist/frontend/lowering/lower-shared-modules.js.map +1 -0
- package/dist/frontend/lowering/lower-stdlib.js +85 -9
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +2 -6
- package/dist/frontend/lowering/lower-stmts.js +781 -143
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +548 -36
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +9 -0
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +514 -10
- package/dist/frontend/lowering/lowerer.js +2667 -163
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +44 -1
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/maybe-promise.d.ts +6 -0
- package/dist/frontend/lowering/maybe-promise.js +13 -0
- package/dist/frontend/lowering/maybe-promise.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.d.ts +12 -0
- package/dist/frontend/lowering/module-namespace-elements.js +114 -18
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +11 -0
- package/dist/frontend/lowering/nan-coded-reads.js +45 -2
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.d.ts +4 -0
- package/dist/frontend/lowering/narrowing-stability.js +14 -6
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/receiver-returns.d.ts +3 -0
- package/dist/frontend/lowering/receiver-returns.js +134 -0
- package/dist/frontend/lowering/receiver-returns.js.map +1 -0
- package/dist/frontend/lowering/record-inherited.d.ts +26 -0
- package/dist/frontend/lowering/record-inherited.js +807 -0
- package/dist/frontend/lowering/record-inherited.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-elements.d.ts +31 -1
- package/dist/frontend/lowering/runtime-optional-elements.js +105 -13
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.d.ts +3 -0
- package/dist/frontend/lowering/runtime-optional-guards.js +35 -7
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js +59 -1
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -1
- package/dist/frontend/lowering/stable-names.d.ts +8 -0
- package/dist/frontend/lowering/stable-names.js +22 -0
- package/dist/frontend/lowering/stable-names.js.map +1 -1
- package/dist/frontend/lowering/stable-names.test.d.ts +1 -0
- package/dist/frontend/lowering/stable-names.test.js +16 -0
- package/dist/frontend/lowering/stable-names.test.js.map +1 -0
- package/dist/frontend/lowering/static-typeof.d.ts +5 -4
- package/dist/frontend/lowering/static-typeof.js +10 -4
- package/dist/frontend/lowering/static-typeof.js.map +1 -1
- package/dist/frontend/lowering/structural-instances.d.ts +22 -0
- package/dist/frontend/lowering/structural-instances.js +282 -0
- package/dist/frontend/lowering/structural-instances.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +3 -0
- package/dist/frontend/lowering/surfaces.js +108 -12
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/symbol-fields.d.ts +7 -0
- package/dist/frontend/lowering/symbol-fields.js +32 -0
- package/dist/frontend/lowering/symbol-fields.js.map +1 -1
- package/dist/frontend/lowering/type-failure.d.ts +17 -0
- package/dist/frontend/lowering/type-failure.js +163 -0
- package/dist/frontend/lowering/type-failure.js.map +1 -0
- package/dist/frontend/lowering/typed-arguments.d.ts +5 -6
- package/dist/frontend/lowering/typed-arguments.js +10 -2
- package/dist/frontend/lowering/typed-arguments.js.map +1 -1
- package/dist/frontend/lowering/union-narrow.d.ts +9 -1
- package/dist/frontend/lowering/union-narrow.js +31 -2
- package/dist/frontend/lowering/union-narrow.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +42 -2
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/unit-journal.d.ts +194 -0
- package/dist/frontend/lowering/unit-journal.js +556 -0
- package/dist/frontend/lowering/unit-journal.js.map +1 -0
- package/dist/frontend/lowering/unit-journal.test.d.ts +1 -0
- package/dist/frontend/lowering/unit-journal.test.js +335 -0
- package/dist/frontend/lowering/unit-journal.test.js.map +1 -0
- package/dist/frontend/lowering/width-lift.d.ts +19 -0
- package/dist/frontend/node-api-import.d.ts +21 -0
- package/dist/frontend/node-api-import.js +88 -0
- package/dist/frontend/node-api-import.js.map +1 -0
- package/dist/frontend/npm-static-type-exports-host.js +4 -3
- package/dist/frontend/npm-static-type-exports-host.js.map +1 -1
- package/dist/frontend/npm-static.js +9 -2
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/package-shims.d.ts +6 -2
- package/dist/frontend/package-shims.js +13 -2
- package/dist/frontend/package-shims.js.map +1 -1
- package/dist/frontend/pipeline.d.ts +11 -4
- package/dist/frontend/pipeline.js +249 -26
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/process-fork.d.ts +3 -0
- package/dist/frontend/process-fork.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +6 -0
- package/dist/frontend/program-analysis.js +4 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +12 -1
- package/dist/frontend/program.js +256 -36
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.js +8 -2
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/shape-inference/analyze.d.ts +23 -1
- package/dist/frontend/shape-inference/analyze.js +982 -97
- package/dist/frontend/shape-inference/analyze.js.map +1 -1
- package/dist/frontend/shape-inference/constant-graphs.d.ts +2 -0
- package/dist/frontend/shape-inference/constant-graphs.js +39 -4
- package/dist/frontend/shape-inference/constant-graphs.js.map +1 -1
- package/dist/frontend/shape-inference/domain.d.ts +2 -0
- package/dist/frontend/shape-inference/domain.js.map +1 -1
- package/dist/frontend/shape-inference/fallback.d.ts +17 -0
- package/dist/frontend/shape-inference/fallback.js +303 -0
- package/dist/frontend/shape-inference/fallback.js.map +1 -0
- package/dist/frontend/shape-inference/index.d.ts +75 -1
- package/dist/frontend/shape-inference/index.js +531 -2
- package/dist/frontend/shape-inference/index.js.map +1 -1
- package/dist/frontend/shape-inference/inferred-checks.d.ts +2 -0
- package/dist/frontend/shape-inference/inferred-checks.js +90 -0
- package/dist/frontend/shape-inference/inferred-checks.js.map +1 -0
- package/dist/frontend/shape-inference/memo.d.ts +30 -0
- package/dist/frontend/shape-inference/memo.js +99 -0
- package/dist/frontend/shape-inference/memo.js.map +1 -0
- package/dist/frontend/shape-inference/overlay.d.ts +81 -0
- package/dist/frontend/shape-inference/overlay.js +1160 -0
- package/dist/frontend/shape-inference/overlay.js.map +1 -0
- package/dist/frontend/shape-inference/registry.test.d.ts +1 -0
- package/dist/frontend/shape-inference/registry.test.js +34 -0
- package/dist/frontend/shape-inference/registry.test.js.map +1 -0
- package/dist/frontend/shape-inference/report.js +42 -8
- package/dist/frontend/shape-inference/report.js.map +1 -1
- package/dist/frontend/shape-inference/static-objects.d.ts +29 -0
- package/dist/frontend/shape-inference/static-objects.js +1951 -0
- package/dist/frontend/shape-inference/static-objects.js.map +1 -0
- package/dist/frontend/tier-analysis.d.ts +53 -1
- package/dist/frontend/tier-analysis.js +133 -0
- package/dist/frontend/tier-analysis.js.map +1 -1
- package/dist/frontend/ts7/api.js +4 -2
- package/dist/frontend/ts7/api.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +9 -0
- package/dist/frontend/ts7/ast-node.js +42 -10
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +23 -0
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/ts7/ast-wire-protocols.test.d.ts +1 -0
- package/dist/frontend/ts7/ast-wire-protocols.test.js +93 -0
- package/dist/frontend/ts7/ast-wire-protocols.test.js.map +1 -0
- package/dist/frontend/ts7/ast-wire.d.ts +18 -0
- package/dist/frontend/ts7/ast-wire.js +66 -4
- package/dist/frontend/ts7/ast-wire.js.map +1 -1
- package/dist/frontend/ts7/checker-server.d.ts +12 -11
- package/dist/frontend/ts7/checker-server.js +28 -12
- package/dist/frontend/ts7/checker-server.js.map +1 -1
- package/dist/frontend/ts7/checker-server.test.js +8 -3
- package/dist/frontend/ts7/checker-server.test.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +4 -0
- package/dist/frontend/ts7/checker.js +9 -0
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/checker.test.js +216 -205
- package/dist/frontend/ts7/checker.test.js.map +1 -1
- package/dist/frontend/ts7/lib-diagnostics.d.ts +71 -4
- package/dist/frontend/ts7/lib-diagnostics.js +337 -20
- package/dist/frontend/ts7/lib-diagnostics.js.map +1 -1
- package/dist/frontend/ts7/lib-diagnostics.test.js +268 -5
- package/dist/frontend/ts7/lib-diagnostics.test.js.map +1 -1
- package/dist/frontend/ts7/native-api.d.ts +4 -0
- package/dist/frontend/ts7/native-api.js +36 -1
- package/dist/frontend/ts7/native-api.js.map +1 -1
- package/dist/frontend/ts7/program-host.d.ts +19 -2
- package/dist/frontend/ts7/program-host.js +69 -9
- package/dist/frontend/ts7/program-host.js.map +1 -1
- package/dist/frontend/ts7/program-host.test.js +42 -1
- package/dist/frontend/ts7/program-host.test.js.map +1 -1
- package/dist/frontend/ts7/rpc-filesystem.d.ts +4 -2
- package/dist/frontend/ts7/rpc-filesystem.js +23 -2
- package/dist/frontend/ts7/rpc-filesystem.js.map +1 -1
- package/dist/frontend/ts7/rpc-filesystem.test.js +28 -2
- package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.js +73 -5
- package/dist/frontend/ts7/semantic-checker.js.map +1 -1
- package/dist/frontend/ts7/semantic-checker.test.js +106 -74
- package/dist/frontend/ts7/semantic-checker.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-json.d.ts +2 -6
- package/dist/frontend/ts7/semantic-model-71.test.d.ts +1 -0
- package/dist/frontend/ts7/semantic-model-71.test.js +131 -0
- package/dist/frontend/ts7/semantic-model-71.test.js.map +1 -0
- package/dist/frontend/ts7/semantic-model.d.ts +121 -3
- package/dist/frontend/ts7/semantic-model.js +245 -8
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/session.d.ts +19 -1
- package/dist/frontend/ts7/session.js +111 -11
- package/dist/frontend/ts7/session.js.map +1 -1
- package/dist/frontend/ts7/session.test.js +259 -239
- package/dist/frontend/ts7/session.test.js.map +1 -1
- package/dist/frontend/ts7/test-servers.d.ts +12 -0
- package/dist/frontend/ts7/test-servers.js +16 -0
- package/dist/frontend/ts7/test-servers.js.map +1 -0
- package/dist/frontend/tsc-codes.js +6 -3
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +61 -1
- package/dist/frontend/type-mapper.js +577 -28
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-patches/command.d.ts +19 -0
- package/dist/frontend/type-patches/command.js +352 -0
- package/dist/frontend/type-patches/command.js.map +1 -0
- package/dist/frontend/type-patches/layer.d.ts +45 -0
- package/dist/frontend/type-patches/layer.js +409 -0
- package/dist/frontend/type-patches/layer.js.map +1 -0
- package/dist/frontend/type-patches/locate.d.ts +41 -0
- package/dist/frontend/type-patches/locate.js +914 -0
- package/dist/frontend/type-patches/locate.js.map +1 -0
- package/dist/frontend/type-patches/locate.test.d.ts +1 -0
- package/dist/frontend/type-patches/locate.test.js +179 -0
- package/dist/frontend/type-patches/locate.test.js.map +1 -0
- package/dist/frontend/type-patches/selector.d.ts +43 -0
- package/dist/frontend/type-patches/selector.js +126 -0
- package/dist/frontend/type-patches/selector.js.map +1 -0
- package/dist/frontend/type-patches/selector.test.d.ts +1 -0
- package/dist/frontend/type-patches/selector.test.js +56 -0
- package/dist/frontend/type-patches/selector.test.js.map +1 -0
- package/dist/frontend/type-patches/semver.d.ts +19 -0
- package/dist/frontend/type-patches/semver.js +221 -0
- package/dist/frontend/type-patches/semver.js.map +1 -0
- package/dist/frontend/type-patches/semver.test.d.ts +1 -0
- package/dist/frontend/type-patches/semver.test.js +47 -0
- package/dist/frontend/type-patches/semver.test.js.map +1 -0
- package/dist/frontend/worker-target.test.js +2 -2
- package/dist/frontend/worker-target.test.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +292 -27
- package/dist/index.js.map +1 -1
- package/dist/ir/builtin-effects.js +51 -5
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +4 -3
- package/dist/ir/builtin-signatures.js +277 -12
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/callback-specialization.js +108 -67
- package/dist/ir/callback-specialization.js.map +1 -1
- package/dist/ir/capture-values.d.ts +7 -1
- package/dist/ir/capture-values.js +28 -5
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/char-unit-locals.js +38 -42
- package/dist/ir/char-unit-locals.js.map +1 -1
- package/dist/ir/expression-inlining.js +12 -6
- package/dist/ir/expression-inlining.js.map +1 -1
- package/dist/ir/fields.generated.d.ts +751 -0
- package/dist/ir/fields.generated.js +2071 -0
- package/dist/ir/fields.generated.js.map +1 -0
- package/dist/ir/fields.test.d.ts +1 -0
- package/dist/ir/fields.test.js +113 -0
- package/dist/ir/fields.test.js.map +1 -0
- package/dist/ir/function-references.js +4 -0
- package/dist/ir/function-references.js.map +1 -1
- package/dist/ir/function-references.test.js +25 -0
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/inline-array-sources.d.ts +15 -0
- package/dist/ir/inline-array-sources.js +1825 -0
- package/dist/ir/inline-array-sources.js.map +1 -0
- package/dist/ir/inline-arrays.d.ts +41 -0
- package/dist/ir/inline-arrays.js +533 -0
- package/dist/ir/inline-arrays.js.map +1 -0
- package/dist/ir/inline-arrays.test.d.ts +1 -0
- package/dist/ir/inline-arrays.test.js +225 -0
- package/dist/ir/inline-arrays.test.js.map +1 -0
- package/dist/ir/int32-slots.d.ts +6 -0
- package/dist/ir/int32-slots.js +154 -16
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +48 -0
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +12 -0
- package/dist/ir/integer-loops.js +23 -0
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +7 -1
- package/dist/ir/integer-ranges.js +29 -2
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +2 -1
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +103 -5
- package/dist/ir/ir.js +38 -4
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +134 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/jsval.js +211 -29
- package/dist/ir/jsval.js.map +1 -1
- package/dist/ir/jsval.test.js +120 -0
- package/dist/ir/jsval.test.js.map +1 -1
- package/dist/ir/loop-entry-ranges.d.ts +38 -0
- package/dist/ir/loop-entry-ranges.js +259 -0
- package/dist/ir/loop-entry-ranges.js.map +1 -0
- package/dist/ir/loop-entry-ranges.test.d.ts +1 -0
- package/dist/ir/loop-entry-ranges.test.js +191 -0
- package/dist/ir/loop-entry-ranges.test.js.map +1 -0
- package/dist/ir/node-index.d.ts +3 -0
- package/dist/ir/node-index.js +6 -0
- package/dist/ir/node-index.js.map +1 -1
- package/dist/ir/numeric-call-specialization.d.ts +9 -6
- package/dist/ir/numeric-call-specialization.js +164 -34
- package/dist/ir/numeric-call-specialization.js.map +1 -1
- package/dist/ir/paired-while-loops.js +23 -19
- package/dist/ir/paired-while-loops.js.map +1 -1
- package/dist/ir/parameter-versions.js +6 -3
- package/dist/ir/parameter-versions.js.map +1 -1
- package/dist/ir/receiver-readers.d.ts +10 -0
- package/dist/ir/receiver-readers.js +65 -28
- package/dist/ir/receiver-readers.js.map +1 -1
- package/dist/ir/row-pairs.d.ts +9 -1
- package/dist/ir/row-pairs.js +136 -43
- package/dist/ir/row-pairs.js.map +1 -1
- package/dist/ir/row-pairs.test.js +25 -5
- package/dist/ir/row-pairs.test.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +33 -1
- package/dist/ir/runtime-features.js +104 -6
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +13 -0
- package/dist/ir/runtime-features.test.js.map +1 -1
- package/dist/ir/saturating-loop-jams.d.ts +24 -0
- package/dist/ir/saturating-loop-jams.js +420 -0
- package/dist/ir/saturating-loop-jams.js.map +1 -0
- package/dist/ir/saturating-loop-jams.test.d.ts +1 -0
- package/dist/ir/saturating-loop-jams.test.js +196 -0
- package/dist/ir/saturating-loop-jams.test.js.map +1 -0
- package/dist/ir/scalar-records.js +9 -3
- package/dist/ir/scalar-records.js.map +1 -1
- package/dist/ir/self-captures.js +2 -1
- package/dist/ir/self-captures.js.map +1 -1
- package/dist/ir/serialize.d.ts +5 -1
- package/dist/ir/serialize.js +7 -1
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/traverse.js +3 -0
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +91 -9
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/ir-policy.js +1 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/native/cache.js +2 -0
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cli.js +54 -7
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.d.ts +3 -0
- package/dist/native/compiler.js +173 -36
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +86 -3
- package/dist/native/compiler.test.js.map +1 -1
- package/dist/native/executable-cache.d.ts +20 -2
- package/dist/native/executable-cache.js +17 -10
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/executable-cache.test.js +38 -1
- package/dist/native/executable-cache.test.js.map +1 -1
- package/dist/native/linker-job.d.ts +71 -0
- package/dist/native/linker-job.js +242 -0
- package/dist/native/linker-job.js.map +1 -0
- package/dist/native/linker-job.test.d.ts +1 -0
- package/dist/native/linker-job.test.js +349 -0
- package/dist/native/linker-job.test.js.map +1 -0
- package/dist/native/prepare.js +15 -2
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.js +10 -15
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/sanitizer.test.js +152 -66
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/native/toolchain.d.ts +11 -2
- package/dist/native/toolchain.js +43 -17
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +75 -0
- package/dist/native/toolchain.test.js.map +1 -1
- package/dist/node-islands/boundary.d.ts +37 -0
- package/dist/node-islands/boundary.js +135 -0
- package/dist/node-islands/boundary.js.map +1 -0
- package/dist/node-islands/classify.js +1 -1
- package/dist/node-islands/classify.js.map +1 -1
- package/dist/node-islands/effect-gate.d.ts +11 -0
- package/dist/node-islands/effect-gate.js +746 -0
- package/dist/node-islands/effect-gate.js.map +1 -0
- package/dist/node-islands/effect-gate.test.d.ts +1 -0
- package/dist/node-islands/effect-gate.test.js +152 -0
- package/dist/node-islands/effect-gate.test.js.map +1 -0
- package/dist/node-islands/libnode-pack.d.ts +68 -0
- package/dist/node-islands/libnode-pack.js +199 -0
- package/dist/node-islands/libnode-pack.js.map +1 -0
- package/dist/node-islands/libnode-pack.test.d.ts +1 -0
- package/dist/node-islands/libnode-pack.test.js +258 -0
- package/dist/node-islands/libnode-pack.test.js.map +1 -0
- package/dist/node-islands/libnode.d.ts +32 -0
- package/dist/node-islands/libnode.js +212 -0
- package/dist/node-islands/libnode.js.map +1 -0
- package/dist/node-islands/libnode.test.d.ts +1 -0
- package/dist/node-islands/libnode.test.js +170 -0
- package/dist/node-islands/libnode.test.js.map +1 -0
- package/dist/node-islands/modules.d.ts +96 -0
- package/dist/node-islands/modules.js +803 -0
- package/dist/node-islands/modules.js.map +1 -0
- package/dist/node-islands/modules.test.d.ts +1 -0
- package/dist/node-islands/modules.test.js +276 -0
- package/dist/node-islands/modules.test.js.map +1 -0
- package/dist/node-islands/resolve.d.ts +8 -0
- package/dist/node-islands/resolve.js +10 -0
- package/dist/node-islands/resolve.js.map +1 -0
- package/dist/node-islands/snapshot.d.ts +16 -0
- package/dist/node-islands/snapshot.js +486 -0
- package/dist/node-islands/snapshot.js.map +1 -0
- package/dist/node-islands/snapshot.test.d.ts +1 -0
- package/dist/node-islands/snapshot.test.js +56 -0
- package/dist/node-islands/snapshot.test.js.map +1 -0
- package/dist/project-config.d.ts +37 -1
- package/dist/project-config.js +159 -7
- package/dist/project-config.js.map +1 -1
- package/dist/project-config.test.js +153 -0
- package/dist/project-config.test.js.map +1 -1
- package/dist/startup-cache.d.ts +1 -0
- package/dist/startup-cache.js +1 -0
- package/dist/startup-cache.js.map +1 -1
- package/package.json +24 -21
- package/surface-manifest.json +47 -7
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import * as ts from "../ts7/adapter.js";
|
|
25
25
|
import { isJsSourceFile } from "../program.js";
|
|
26
26
|
import { npmStaticPackageOfPath } from "../npm-static.js";
|
|
27
|
-
import { AtomTable, MODELED_GLOBALS, STRING_METHOD_RESULTS } from "./domain.js";
|
|
27
|
+
import { AtomTable, MODELED_GLOBALS, OBJECT_PROTOTYPE_MEMBERS, STRING_METHOD_RESULTS, } from "./domain.js";
|
|
28
28
|
/** Array.prototype members: other names on an array are own properties. */
|
|
29
29
|
const ARRAY_METHODS = new Set([
|
|
30
30
|
"at",
|
|
@@ -67,6 +67,109 @@ const ARRAY_METHODS = new Set([
|
|
|
67
67
|
"with",
|
|
68
68
|
]);
|
|
69
69
|
const MAX_STEPS = 20_000_000;
|
|
70
|
+
/** The well-known symbols, static members of `Symbol` (Node 24). */
|
|
71
|
+
const WELL_KNOWN_SYMBOLS = new Set([
|
|
72
|
+
"asyncDispose",
|
|
73
|
+
"asyncIterator",
|
|
74
|
+
"dispose",
|
|
75
|
+
"hasInstance",
|
|
76
|
+
"isConcatSpreadable",
|
|
77
|
+
"iterator",
|
|
78
|
+
"match",
|
|
79
|
+
"matchAll",
|
|
80
|
+
"replace",
|
|
81
|
+
"search",
|
|
82
|
+
"species",
|
|
83
|
+
"split",
|
|
84
|
+
"toPrimitive",
|
|
85
|
+
"toStringTag",
|
|
86
|
+
"unscopables",
|
|
87
|
+
]);
|
|
88
|
+
/** The members String.prototype, Number.prototype and Boolean.prototype
|
|
89
|
+
* define (Node 24); Object.prototype's come from OBJECT_PROTOTYPE_MEMBERS. */
|
|
90
|
+
const PRIMITIVE_MEMBERS = {
|
|
91
|
+
string: new Set([
|
|
92
|
+
"at",
|
|
93
|
+
"charAt",
|
|
94
|
+
"charCodeAt",
|
|
95
|
+
"codePointAt",
|
|
96
|
+
"concat",
|
|
97
|
+
"endsWith",
|
|
98
|
+
"includes",
|
|
99
|
+
"indexOf",
|
|
100
|
+
"isWellFormed",
|
|
101
|
+
"lastIndexOf",
|
|
102
|
+
"localeCompare",
|
|
103
|
+
"match",
|
|
104
|
+
"matchAll",
|
|
105
|
+
"normalize",
|
|
106
|
+
"padEnd",
|
|
107
|
+
"padStart",
|
|
108
|
+
"repeat",
|
|
109
|
+
"replace",
|
|
110
|
+
"replaceAll",
|
|
111
|
+
"search",
|
|
112
|
+
"slice",
|
|
113
|
+
"split",
|
|
114
|
+
"startsWith",
|
|
115
|
+
"substr",
|
|
116
|
+
"substring",
|
|
117
|
+
"toLocaleLowerCase",
|
|
118
|
+
"toLocaleUpperCase",
|
|
119
|
+
"toLowerCase",
|
|
120
|
+
"toString",
|
|
121
|
+
"toUpperCase",
|
|
122
|
+
"toWellFormed",
|
|
123
|
+
"trim",
|
|
124
|
+
"trimEnd",
|
|
125
|
+
"trimStart",
|
|
126
|
+
"trimLeft",
|
|
127
|
+
"trimRight",
|
|
128
|
+
"valueOf",
|
|
129
|
+
"anchor",
|
|
130
|
+
"big",
|
|
131
|
+
"blink",
|
|
132
|
+
"bold",
|
|
133
|
+
"fixed",
|
|
134
|
+
"fontcolor",
|
|
135
|
+
"fontsize",
|
|
136
|
+
"italics",
|
|
137
|
+
"link",
|
|
138
|
+
"small",
|
|
139
|
+
"strike",
|
|
140
|
+
"sub",
|
|
141
|
+
"sup",
|
|
142
|
+
"length",
|
|
143
|
+
"constructor",
|
|
144
|
+
]),
|
|
145
|
+
number: new Set([
|
|
146
|
+
"toExponential",
|
|
147
|
+
"toFixed",
|
|
148
|
+
"toLocaleString",
|
|
149
|
+
"toPrecision",
|
|
150
|
+
"toString",
|
|
151
|
+
"valueOf",
|
|
152
|
+
"constructor",
|
|
153
|
+
]),
|
|
154
|
+
boolean: new Set(["toString", "valueOf", "constructor"]),
|
|
155
|
+
};
|
|
156
|
+
/** Per-call-site clones of an init factory, at most (SCRIPTC_SHAPE_SITE_CLONES;
|
|
157
|
+
* 0 turns them off), and the deepest chain of nested clones. */
|
|
158
|
+
const SITE_CLONES = Number(process.env["SCRIPTC_SHAPE_SITE_CLONES"] ?? 64);
|
|
159
|
+
const SITE_CLONE_DEPTH = 4;
|
|
160
|
+
/** The prototypes a string, number or boolean member read reaches. */
|
|
161
|
+
const PRIMITIVE_PROTOTYPES = new Set([
|
|
162
|
+
"String.prototype",
|
|
163
|
+
"Number.prototype",
|
|
164
|
+
"Boolean.prototype",
|
|
165
|
+
"Object.prototype",
|
|
166
|
+
]);
|
|
167
|
+
function isPrimitivePrototype(a) {
|
|
168
|
+
return a.kind === "builtin" && a.receiver === undefined && PRIMITIVE_PROTOTYPES.has(a.path ?? "");
|
|
169
|
+
}
|
|
170
|
+
/** The most atoms a value node tracks before it widens to ⊤
|
|
171
|
+
* (SCRIPTC_SHAPE_WIDEN overrides). */
|
|
172
|
+
const WIDEN_AT = Number(process.env["SCRIPTC_SHAPE_WIDEN"] ?? 32);
|
|
70
173
|
function list(arr) {
|
|
71
174
|
return arr?.nodes ?? [];
|
|
72
175
|
}
|
|
@@ -103,7 +206,14 @@ function propertyNameText(name) {
|
|
|
103
206
|
}
|
|
104
207
|
return null;
|
|
105
208
|
}
|
|
209
|
+
const shortFiles = new Map();
|
|
106
210
|
function shortFile(fileName) {
|
|
211
|
+
let short = shortFiles.get(fileName);
|
|
212
|
+
if (short === undefined)
|
|
213
|
+
shortFiles.set(fileName, (short = shortFileOf(fileName)));
|
|
214
|
+
return short;
|
|
215
|
+
}
|
|
216
|
+
function shortFileOf(fileName) {
|
|
107
217
|
const norm = fileName.split("\\").join("/");
|
|
108
218
|
const nm = norm.lastIndexOf("/node_modules/");
|
|
109
219
|
if (nm >= 0) {
|
|
@@ -130,6 +240,38 @@ function isLoop(node) {
|
|
|
130
240
|
ts.isWhileStatement(node) ||
|
|
131
241
|
ts.isDoStatement(node));
|
|
132
242
|
}
|
|
243
|
+
/** Whether control can reach the end of `stmts`. False only when every
|
|
244
|
+
* path ends in a return or throw, or in a `while (true)`, `do … while
|
|
245
|
+
* (true)` or `for (;;)` loop with no break inside; anything else is
|
|
246
|
+
* assumed to complete. */
|
|
247
|
+
function canComplete(stmts) {
|
|
248
|
+
return stmts.every(canCompleteStatement);
|
|
249
|
+
}
|
|
250
|
+
function canCompleteStatement(s) {
|
|
251
|
+
if (ts.isReturnStatement(s) || ts.isThrowStatement(s))
|
|
252
|
+
return false;
|
|
253
|
+
if (ts.isBlock(s))
|
|
254
|
+
return canComplete(list(s.statements));
|
|
255
|
+
if (ts.isIfStatement(s))
|
|
256
|
+
return (s.elseStatement === undefined ||
|
|
257
|
+
canCompleteStatement(s.thenStatement) ||
|
|
258
|
+
canCompleteStatement(s.elseStatement));
|
|
259
|
+
if (ts.isTryStatement(s)) {
|
|
260
|
+
if (s.finallyBlock !== undefined && !canCompleteStatement(s.finallyBlock))
|
|
261
|
+
return false;
|
|
262
|
+
return (canCompleteStatement(s.tryBlock) ||
|
|
263
|
+
(s.catchClause !== undefined && canCompleteStatement(s.catchClause.block)));
|
|
264
|
+
}
|
|
265
|
+
const endless = ((ts.isWhileStatement(s) || ts.isDoStatement(s)) &&
|
|
266
|
+
s.expression.kind === ts.SyntaxKind.TrueKeyword) ||
|
|
267
|
+
(ts.isForStatement(s) && s.condition === undefined);
|
|
268
|
+
return !endless || containsBreak(s);
|
|
269
|
+
}
|
|
270
|
+
/** Whether a break statement occurs in `node`'s body, outside nested
|
|
271
|
+
* functions. */
|
|
272
|
+
function containsBreak(node) {
|
|
273
|
+
return (ts.forEachChild(node, (c) => ts.isBreakStatement(c) || (!ts.isFunctionLike(c) && containsBreak(c)) ? true : undefined) === true);
|
|
274
|
+
}
|
|
133
275
|
const LOOP_CALLBACK_METHODS = new Set([
|
|
134
276
|
"map",
|
|
135
277
|
"forEach",
|
|
@@ -149,12 +291,22 @@ const LOOP_CALLBACK_METHODS = new Set([
|
|
|
149
291
|
"replace",
|
|
150
292
|
"replaceAll",
|
|
151
293
|
]);
|
|
152
|
-
export function analyzeShapes(program, checker) {
|
|
153
|
-
return new Analyzer(program, checker).run();
|
|
294
|
+
export function analyzeShapes(program, checker, options = {}) {
|
|
295
|
+
return new Analyzer(program, checker, options.siteClones ?? SITE_CLONES).run();
|
|
154
296
|
}
|
|
155
297
|
class Analyzer {
|
|
156
298
|
program;
|
|
157
299
|
checker;
|
|
300
|
+
siteCloneLimit;
|
|
301
|
+
/** locLabel per node: sink reasons and atom labels name the same sites
|
|
302
|
+
* over and over, and each label reads the file's text for its line. */
|
|
303
|
+
locLabels = new Map();
|
|
304
|
+
loc(node) {
|
|
305
|
+
let label = this.locLabels.get(node);
|
|
306
|
+
if (label === undefined)
|
|
307
|
+
this.locLabels.set(node, (label = locLabel(node)));
|
|
308
|
+
return label;
|
|
309
|
+
}
|
|
158
310
|
atoms = new AtomTable();
|
|
159
311
|
nodes = [];
|
|
160
312
|
functions = new Map();
|
|
@@ -165,6 +317,14 @@ class Analyzer {
|
|
|
165
317
|
escaped = new Map();
|
|
166
318
|
topWriteNames = new Map();
|
|
167
319
|
topComputedWrites = [];
|
|
320
|
+
/** Names a write may add to a primitive's prototype chain, or every name
|
|
321
|
+
* (`primitiveExtensionsAll`). A read of a name the chain lacks reads ⊤
|
|
322
|
+
* for them as well as undefined. */
|
|
323
|
+
primitiveExtensions = new Set();
|
|
324
|
+
primitiveExtensionsAll = false;
|
|
325
|
+
/** Reads of names a primitive's prototype chain lacks, by name; each
|
|
326
|
+
* takes ⊤ once a write may add the name. */
|
|
327
|
+
primitiveReads = new Map();
|
|
168
328
|
fields = new Map();
|
|
169
329
|
elements = new Map();
|
|
170
330
|
top;
|
|
@@ -196,8 +356,8 @@ class Analyzer {
|
|
|
196
356
|
* (JSON.parse revivers, JSON.stringify replacers and toJSON methods),
|
|
197
357
|
* which may run after the call's own handling. */
|
|
198
358
|
repeatingSites = new Set();
|
|
199
|
-
edgeFor(site, callee) {
|
|
200
|
-
const ctx = this.siteCtx.get(site);
|
|
359
|
+
edgeFor(site, callee, args) {
|
|
360
|
+
const ctx = (args !== undefined ? this.argsFrom.get(args) : undefined) ?? this.siteCtx.get(site);
|
|
201
361
|
this.calls.push({
|
|
202
362
|
caller: ctx?.caller ?? null,
|
|
203
363
|
callee,
|
|
@@ -205,11 +365,52 @@ class Analyzer {
|
|
|
205
365
|
site,
|
|
206
366
|
});
|
|
207
367
|
}
|
|
208
|
-
constructor(program, checker) {
|
|
368
|
+
constructor(program, checker, siteCloneLimit) {
|
|
209
369
|
this.program = program;
|
|
210
370
|
this.checker = checker;
|
|
371
|
+
this.siteCloneLimit = siteCloneLimit;
|
|
211
372
|
this.top = this.atoms.intern("top", () => ({ kind: "top", label: "⊤" }));
|
|
212
373
|
}
|
|
374
|
+
/** SCRIPTC_DEBUG_SHAPES_PROFILE: where the solver's steps go. */
|
|
375
|
+
profileReport() {
|
|
376
|
+
const byNodeLabel = new Map();
|
|
377
|
+
let atomsTotal = 0;
|
|
378
|
+
let maxAtoms = 0;
|
|
379
|
+
let onAtoms = 0;
|
|
380
|
+
let succ = 0;
|
|
381
|
+
for (const n of this.nodes) {
|
|
382
|
+
atomsTotal += n.atoms.size;
|
|
383
|
+
maxAtoms = Math.max(maxAtoms, n.atoms.size);
|
|
384
|
+
onAtoms += n.onAtom.length;
|
|
385
|
+
succ += n.succ.size;
|
|
386
|
+
}
|
|
387
|
+
const kinds = new Map();
|
|
388
|
+
for (const a of this.atoms.atoms)
|
|
389
|
+
kinds.set(a.kind, (kinds.get(a.kind) ?? 0) + 1);
|
|
390
|
+
const ctxPerFn = new Map();
|
|
391
|
+
for (const info of this.functions.values())
|
|
392
|
+
ctxPerFn.set(info.node, (ctxPerFn.get(info.node) ?? 0) + 1);
|
|
393
|
+
const topFns = [...ctxPerFn.entries()].sort((a, b) => b[1] - a[1]).slice(0, 15);
|
|
394
|
+
const lines = [
|
|
395
|
+
`nodes ${this.nodes.length} atoms ${this.atoms.atoms.length} (${[...kinds].map(([k, v]) => `${k} ${v}`).join(", ")})`,
|
|
396
|
+
`solve ${this.solveMs.toFixed(0)} ms (nested walks included) checker ${this.checkerMs.toFixed(0)} ms in ${this.checkerCalls} calls`,
|
|
397
|
+
`node-atom pairs ${atomsTotal} max ${maxAtoms} edges ${succ} listeners ${onAtoms} functions ${this.functions.size} steps ${this.steps}`,
|
|
398
|
+
...topFns.map(([n, c]) => ` ${c} contexts: ${locLabel(n)}`),
|
|
399
|
+
...[...this.popsByAtom.entries()]
|
|
400
|
+
.sort((a, b) => b[1] - a[1])
|
|
401
|
+
.slice(0, 15)
|
|
402
|
+
.map(([a, c]) => ` ${c} pops: atom ${a.kind} ${a.label}`),
|
|
403
|
+
...[...this.popsByNode.entries()]
|
|
404
|
+
.sort((a, b) => b[1] - a[1])
|
|
405
|
+
.slice(0, 10)
|
|
406
|
+
.map(([id, c]) => ` ${c} pops: node ${id} ${this.nodeLabel.get(id) ?? ""} atoms ${this.nodes[id].atoms.size} succ ${this.nodes[id].succ.size} listeners ${this.nodes[id].onAtom.length}`),
|
|
407
|
+
];
|
|
408
|
+
void byNodeLabel;
|
|
409
|
+
process.stderr.write(lines.map((l) => `[shapes-profile] ${l}\n`).join(""));
|
|
410
|
+
}
|
|
411
|
+
profiling = process.env["SCRIPTC_DEBUG_SHAPES_PROFILE"] !== undefined;
|
|
412
|
+
popsByAtom = new Map();
|
|
413
|
+
popsByNode = new Map();
|
|
213
414
|
run() {
|
|
214
415
|
for (const sf of this.program.getImplementationSourceFiles()) {
|
|
215
416
|
const name = sf.fileName.split("\\").join("/");
|
|
@@ -220,11 +421,15 @@ class Analyzer {
|
|
|
220
421
|
if (inPackage)
|
|
221
422
|
this.packageFiles++;
|
|
222
423
|
}
|
|
424
|
+
// Analysis resolves names and never asks for types: the program it
|
|
425
|
+
// runs on is usually replaced by the overlay's before lowering.
|
|
223
426
|
for (const sf of this.files)
|
|
224
|
-
this.checker.
|
|
427
|
+
this.checker.prefetchSourceFileSymbols(sf);
|
|
225
428
|
for (const sf of this.files)
|
|
226
429
|
this.moduleBody(sf);
|
|
227
430
|
this.finish();
|
|
431
|
+
if (this.profiling)
|
|
432
|
+
this.profileReport();
|
|
228
433
|
return {
|
|
229
434
|
atoms: this.atoms,
|
|
230
435
|
nodes: this.nodes,
|
|
@@ -247,6 +452,11 @@ class Analyzer {
|
|
|
247
452
|
nodeLabel: this.nodeLabel,
|
|
248
453
|
escapedFunctions: this.escapedFunctionCalls,
|
|
249
454
|
protoOf: this.protoOf,
|
|
455
|
+
fnOfInstance: this.fnOfInstance,
|
|
456
|
+
declValues: (decl) => this.declValues(decl),
|
|
457
|
+
classChain: (decl) => this.classChain(decl),
|
|
458
|
+
branchIfs: this.branchIfs,
|
|
459
|
+
walkedBranches: this.walkedBranches,
|
|
250
460
|
};
|
|
251
461
|
}
|
|
252
462
|
// ---- value nodes -------------------------------------------------------
|
|
@@ -264,7 +474,23 @@ class Analyzer {
|
|
|
264
474
|
const n = this.nodes[node];
|
|
265
475
|
if (n.atoms.has(atom))
|
|
266
476
|
return;
|
|
477
|
+
if (n.wide === true) {
|
|
478
|
+
this.escape(atom, "a value set too large to track");
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
267
481
|
n.atoms.add(atom);
|
|
482
|
+
// Widening: a value set this large is merged code (a utility every
|
|
483
|
+
// value flows through). It becomes ⊤: its values escape, so the facts
|
|
484
|
+
// stay sound, and the solver stops multiplying constraints per atom.
|
|
485
|
+
if (n.atoms.size > WIDEN_AT) {
|
|
486
|
+
n.wide = true;
|
|
487
|
+
for (const a of n.atoms)
|
|
488
|
+
this.escape(a, "a value set too large to track");
|
|
489
|
+
if (!n.atoms.has(this.top)) {
|
|
490
|
+
n.atoms.add(this.top);
|
|
491
|
+
this.worklist.push([node, this.top]);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
268
494
|
if (this.traceTop && atom === this.top && !this.topCause.has(node))
|
|
269
495
|
this.topCause.set(node, this.cause ??
|
|
270
496
|
(new Error().stack ?? "")
|
|
@@ -318,6 +544,27 @@ class Analyzer {
|
|
|
318
544
|
* and which function each `new F()` instance atom belongs to. */
|
|
319
545
|
protoOf = new Map();
|
|
320
546
|
fnOfInstance = new Map();
|
|
547
|
+
/** Per dictionary atom, the prototypes it was created with (Object.create). */
|
|
548
|
+
dictProtos = new Map();
|
|
549
|
+
/** Per object literal atom, the keys it has from its creation: another
|
|
550
|
+
* key may be absent when read (flow-insensitively, before its write). */
|
|
551
|
+
literalOwnKeys = new Map();
|
|
552
|
+
protoReads = new Set();
|
|
553
|
+
/** Arrays whose elements an index read inside its bounds may still miss:
|
|
554
|
+
* shrunk (pop, shift, splice, a length write), holey (`new Array(n)`, a
|
|
555
|
+
* delete, a store at an index that is not proven in bounds or the end). */
|
|
556
|
+
unsafeArrays = new Set();
|
|
557
|
+
/** Index reads proven in bounds by their loop (`for (let i = 0; i <
|
|
558
|
+
* a.length; i++) a[i]`): undefined joins them only if the array turns
|
|
559
|
+
* out unsafe (finish). */
|
|
560
|
+
guardedIndexReads = [];
|
|
561
|
+
boundsMemo = new Map();
|
|
562
|
+
dictProto(d) {
|
|
563
|
+
let id = this.dictProtos.get(d);
|
|
564
|
+
if (id === undefined)
|
|
565
|
+
this.dictProtos.set(d, (id = this.newNode()));
|
|
566
|
+
return id;
|
|
567
|
+
}
|
|
321
568
|
protoAtom(fn) {
|
|
322
569
|
let p = this.protoOf.get(fn);
|
|
323
570
|
if (p === undefined) {
|
|
@@ -333,11 +580,93 @@ class Analyzer {
|
|
|
333
580
|
}
|
|
334
581
|
return p;
|
|
335
582
|
}
|
|
583
|
+
/** A boolean literal: labeled `boolean` like any boolean, but its
|
|
584
|
+
* truthiness is known, so `if` statements on it walk one branch. */
|
|
585
|
+
boolLiteral(value) {
|
|
586
|
+
return this.atoms.intern(`prim:boolean:${value}`, () => ({
|
|
587
|
+
kind: "prim",
|
|
588
|
+
label: "boolean",
|
|
589
|
+
literal: value,
|
|
590
|
+
}));
|
|
591
|
+
}
|
|
592
|
+
/** The analysis environment a deferred walk restores. */
|
|
593
|
+
env() {
|
|
594
|
+
return {
|
|
595
|
+
ctx: this.ctx,
|
|
596
|
+
ctxRoot: this.ctxRoot,
|
|
597
|
+
currentFn: this.currentFn,
|
|
598
|
+
loopDepth: this.loopDepth,
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
inEnv(env, walk) {
|
|
602
|
+
const saved = this.env();
|
|
603
|
+
this.ctx = env.ctx;
|
|
604
|
+
this.ctxRoot = env.ctxRoot;
|
|
605
|
+
this.currentFn = env.currentFn;
|
|
606
|
+
this.loopDepth = env.loopDepth;
|
|
607
|
+
try {
|
|
608
|
+
walk();
|
|
609
|
+
}
|
|
610
|
+
finally {
|
|
611
|
+
this.ctx = saved.ctx;
|
|
612
|
+
this.ctxRoot = saved.ctxRoot;
|
|
613
|
+
this.currentFn = saved.currentFn;
|
|
614
|
+
this.loopDepth = saved.loopDepth;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
branchIfs = new Set();
|
|
618
|
+
walkedBranches = new Set();
|
|
619
|
+
/** Ifs whose branches wait for condition values; at the fixpoint, an
|
|
620
|
+
* `if` whose condition node stayed empty walks every waiting branch. */
|
|
621
|
+
pendingIfs = [];
|
|
622
|
+
/** An `if` walks a branch once a condition value allows it: the then
|
|
623
|
+
* branch on a value that may be truthy, the else branch on one that may
|
|
624
|
+
* be falsy. A branch no value allows is never walked, so its effects
|
|
625
|
+
* (returns, calls, writes) stay out of the facts; the overlay turns it
|
|
626
|
+
* into a checked internal error. */
|
|
627
|
+
ifStatement(s) {
|
|
628
|
+
const cond = this.expr(s.expression);
|
|
629
|
+
this.branchIfs.add(s);
|
|
630
|
+
const pending = {
|
|
631
|
+
s,
|
|
632
|
+
cond,
|
|
633
|
+
env: this.env(),
|
|
634
|
+
thenDone: false,
|
|
635
|
+
elseDone: s.elseStatement === undefined,
|
|
636
|
+
};
|
|
637
|
+
this.pendingIfs.push(pending);
|
|
638
|
+
this.on(cond, (a) => {
|
|
639
|
+
if (!pending.thenDone && mayBeTruthy(a))
|
|
640
|
+
this.walkBranch(pending, "then");
|
|
641
|
+
if (!pending.elseDone && mayBeFalsy(a))
|
|
642
|
+
this.walkBranch(pending, "else");
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
walkBranch(pending, which) {
|
|
646
|
+
const branch = which === "then" ? pending.s.thenStatement : pending.s.elseStatement;
|
|
647
|
+
if (which === "then")
|
|
648
|
+
pending.thenDone = true;
|
|
649
|
+
else
|
|
650
|
+
pending.elseDone = true;
|
|
651
|
+
this.walkedBranches.add(branch);
|
|
652
|
+
this.inEnv(pending.env, () => this.stmt(branch));
|
|
653
|
+
}
|
|
336
654
|
builtin(path, receiver) {
|
|
337
655
|
const key = receiver === undefined ? `builtin:${path}` : `builtin:${path}@${receiver.id}`;
|
|
338
656
|
return this.atoms.intern(key, () => ({ kind: "builtin", label: path, path, receiver }));
|
|
339
657
|
}
|
|
658
|
+
solveMs = 0;
|
|
340
659
|
solve() {
|
|
660
|
+
const started = this.profiling ? performance.now() : 0;
|
|
661
|
+
try {
|
|
662
|
+
this.solveLoop();
|
|
663
|
+
}
|
|
664
|
+
finally {
|
|
665
|
+
if (this.profiling)
|
|
666
|
+
this.solveMs += performance.now() - started;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
solveLoop() {
|
|
341
670
|
while (this.worklist.length > 0) {
|
|
342
671
|
if (++this.steps > MAX_STEPS) {
|
|
343
672
|
this.budgetExceeded = true;
|
|
@@ -345,6 +674,10 @@ class Analyzer {
|
|
|
345
674
|
}
|
|
346
675
|
const [id, atom] = this.worklist.pop();
|
|
347
676
|
const n = this.nodes[id];
|
|
677
|
+
if (this.profiling) {
|
|
678
|
+
this.popsByAtom.set(atom, (this.popsByAtom.get(atom) ?? 0) + 1);
|
|
679
|
+
this.popsByNode.set(id, (this.popsByNode.get(id) ?? 0) + 1);
|
|
680
|
+
}
|
|
348
681
|
this.cause = id;
|
|
349
682
|
for (const s of n.succ)
|
|
350
683
|
this.add(s, atom);
|
|
@@ -401,6 +734,9 @@ class Analyzer {
|
|
|
401
734
|
escape(atom, reason) {
|
|
402
735
|
if (atom.kind === "prim" || atom.kind === "top")
|
|
403
736
|
return;
|
|
737
|
+
// Unknown code may add any member to a primitive's prototype.
|
|
738
|
+
if (isPrimitivePrototype(atom))
|
|
739
|
+
this.extendPrimitives(null);
|
|
404
740
|
if (atom.kind === "builtin" && atom.receiver === undefined)
|
|
405
741
|
return;
|
|
406
742
|
if (this.escaped.has(atom))
|
|
@@ -459,6 +795,8 @@ class Analyzer {
|
|
|
459
795
|
}
|
|
460
796
|
/** Property names that untyped code writes on receivers that may be ⊤ (census). */
|
|
461
797
|
noteTopWrite(name, node) {
|
|
798
|
+
// ⊤ may be a primitive's prototype.
|
|
799
|
+
this.extendPrimitives(name);
|
|
462
800
|
if (name === null) {
|
|
463
801
|
const first = this.topComputedWrites.length === 0;
|
|
464
802
|
this.topComputedWrites.push(node);
|
|
@@ -482,6 +820,47 @@ class Analyzer {
|
|
|
482
820
|
this.add(id, this.top);
|
|
483
821
|
}
|
|
484
822
|
}
|
|
823
|
+
/** A read of a name a primitive's prototype chain lacks: ⊤ as well, now
|
|
824
|
+
* or once a write may add the name there. */
|
|
825
|
+
primitiveRead(name, dst) {
|
|
826
|
+
if (this.primitiveExtensionsAll || this.primitiveExtensions.has(name)) {
|
|
827
|
+
this.add(dst, this.top);
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
const reads = this.primitiveReads.get(name);
|
|
831
|
+
if (reads === undefined)
|
|
832
|
+
this.primitiveReads.set(name, [dst]);
|
|
833
|
+
else
|
|
834
|
+
reads.push(dst);
|
|
835
|
+
}
|
|
836
|
+
/** A write that may add `name` (any name when null) to String.prototype,
|
|
837
|
+
* Number.prototype, Boolean.prototype or Object.prototype. */
|
|
838
|
+
extendPrimitives(name) {
|
|
839
|
+
if (this.primitiveExtensionsAll)
|
|
840
|
+
return;
|
|
841
|
+
if (name === null || name === "__proto__") {
|
|
842
|
+
this.primitiveExtensionsAll = true;
|
|
843
|
+
for (const reads of this.primitiveReads.values())
|
|
844
|
+
for (const dst of reads)
|
|
845
|
+
this.add(dst, this.top);
|
|
846
|
+
this.primitiveReads.clear();
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
if (this.primitiveExtensions.has(name))
|
|
850
|
+
return;
|
|
851
|
+
this.primitiveExtensions.add(name);
|
|
852
|
+
for (const dst of this.primitiveReads.get(name) ?? [])
|
|
853
|
+
this.add(dst, this.top);
|
|
854
|
+
this.primitiveReads.delete(name);
|
|
855
|
+
}
|
|
856
|
+
/** An operation that may add, replace or remove `name` (any name when
|
|
857
|
+
* null) on its receiver: a primitive's prototype, or ⊤, which may be one. */
|
|
858
|
+
prototypeWrite(recv, name) {
|
|
859
|
+
this.on(recv, (t) => {
|
|
860
|
+
if (t.kind === "top" || isPrimitivePrototype(t))
|
|
861
|
+
this.extendPrimitives(name);
|
|
862
|
+
});
|
|
863
|
+
}
|
|
485
864
|
// ---- classes ---------------------------------------------------------------
|
|
486
865
|
/** The base class declaration of `decl`, via the checker; null at a
|
|
487
866
|
* builtin base or none; undefined when unresolved. */
|
|
@@ -563,7 +942,22 @@ class Analyzer {
|
|
|
563
942
|
return null;
|
|
564
943
|
}
|
|
565
944
|
// ---- symbols -----------------------------------------------------------------
|
|
945
|
+
checkerMs = 0;
|
|
946
|
+
checkerCalls = 0;
|
|
947
|
+
resolved = new Map();
|
|
566
948
|
resolve(id) {
|
|
949
|
+
if (this.resolved.has(id))
|
|
950
|
+
return this.resolved.get(id);
|
|
951
|
+
const started = this.profiling ? performance.now() : 0;
|
|
952
|
+
const out = this.resolveUncached(id);
|
|
953
|
+
if (this.profiling) {
|
|
954
|
+
this.checkerMs += performance.now() - started;
|
|
955
|
+
this.checkerCalls++;
|
|
956
|
+
}
|
|
957
|
+
this.resolved.set(id, out);
|
|
958
|
+
return out;
|
|
959
|
+
}
|
|
960
|
+
resolveUncached(id) {
|
|
567
961
|
let sym = this.checker.getSymbolAtLocation(id);
|
|
568
962
|
if (sym === undefined)
|
|
569
963
|
return undefined;
|
|
@@ -584,7 +978,7 @@ class Analyzer {
|
|
|
584
978
|
id = this.newNode();
|
|
585
979
|
this.bindings.set(key, id);
|
|
586
980
|
if (this.traceTop)
|
|
587
|
-
this.nodeLabel.set(id, `binding ${decl.name?.text ?? "?"}@${
|
|
981
|
+
this.nodeLabel.set(id, `binding ${decl.name?.text ?? "?"}@${this.loc(decl)}${this.ctx !== "" ? ` [${this.ctx}]` : ""}`);
|
|
588
982
|
}
|
|
589
983
|
return id;
|
|
590
984
|
}
|
|
@@ -598,6 +992,27 @@ class Analyzer {
|
|
|
598
992
|
node.end <= root.end;
|
|
599
993
|
return `${inside ? this.ctx : ""}|${this.nodeKey(node)}`;
|
|
600
994
|
}
|
|
995
|
+
declIndex = null;
|
|
996
|
+
declValues(decl) {
|
|
997
|
+
if (this.declIndex === null) {
|
|
998
|
+
this.declIndex = new Map();
|
|
999
|
+
for (const [key, id] of this.bindings) {
|
|
1000
|
+
const k = Number(key.slice(key.lastIndexOf("|") + 1));
|
|
1001
|
+
let l = this.declIndex.get(k);
|
|
1002
|
+
if (l === undefined)
|
|
1003
|
+
this.declIndex.set(k, (l = []));
|
|
1004
|
+
l.push(id);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
const out = new Set();
|
|
1008
|
+
const k = this.nodeKeys.get(decl);
|
|
1009
|
+
if (k === undefined)
|
|
1010
|
+
return out;
|
|
1011
|
+
for (const id of this.declIndex.get(k) ?? [])
|
|
1012
|
+
for (const a of this.nodes[id].atoms)
|
|
1013
|
+
out.add(a);
|
|
1014
|
+
return out;
|
|
1015
|
+
}
|
|
601
1016
|
receiverCtx(atom) {
|
|
602
1017
|
return atom.kind === "instance" || atom.kind === "class" ? `C${atom.id}` : "";
|
|
603
1018
|
}
|
|
@@ -607,7 +1022,9 @@ class Analyzer {
|
|
|
607
1022
|
return this.functions.get(`${atom.ctx ?? ""}|${this.nodeKey(atom.node)}`);
|
|
608
1023
|
}
|
|
609
1024
|
// ---- functions ---------------------------------------------------------------
|
|
610
|
-
|
|
1025
|
+
/** `lexicalThis`: an arrow's receiver node, for a clone walked away from
|
|
1026
|
+
* the function that encloses the arrow. */
|
|
1027
|
+
functionInfo(node, ownerClass, ctxArg = "", lexicalThis = null) {
|
|
611
1028
|
// A nested closure walked inside a clone shares the clone's context.
|
|
612
1029
|
const inherit = ctxArg === "" &&
|
|
613
1030
|
this.ctxRoot !== null &&
|
|
@@ -639,7 +1056,7 @@ class Analyzer {
|
|
|
639
1056
|
const nameNode = fn.name;
|
|
640
1057
|
const name = nameNode !== undefined ? (propertyNameText(nameNode) ?? "<computed>") : null;
|
|
641
1058
|
const owner = ownerClass !== null ? this.className(ownerClass) : null;
|
|
642
|
-
const label = `${owner !== null ? `${owner}.` : ""}${name ?? (ts.isConstructorDeclaration(node) ? "constructor" : "<fn>")}@${
|
|
1059
|
+
const label = `${owner !== null ? `${owner}.` : ""}${name ?? (ts.isConstructorDeclaration(node) ? "constructor" : "<fn>")}@${this.loc(node)}`;
|
|
643
1060
|
const info = {
|
|
644
1061
|
node,
|
|
645
1062
|
ctx,
|
|
@@ -648,7 +1065,11 @@ class Analyzer {
|
|
|
648
1065
|
label: ctx === "" ? label : `${label} [${this.ctxLabel(ctx)}]`,
|
|
649
1066
|
params,
|
|
650
1067
|
rest,
|
|
651
|
-
thisNode: isArrow &&
|
|
1068
|
+
thisNode: isArrow && lexicalThis !== null
|
|
1069
|
+
? lexicalThis
|
|
1070
|
+
: isArrow && this.currentFn !== null
|
|
1071
|
+
? this.currentFn.thisNode
|
|
1072
|
+
: this.newNode(),
|
|
652
1073
|
ret: this.newNode(),
|
|
653
1074
|
isArrow,
|
|
654
1075
|
isAsync: mods.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword),
|
|
@@ -685,7 +1106,7 @@ class Analyzer {
|
|
|
685
1106
|
if (p.dotDotDotToken !== undefined) {
|
|
686
1107
|
const arr = this.atoms.intern(`rest:${this.nodes.length}`, () => ({
|
|
687
1108
|
kind: "array",
|
|
688
|
-
label: `rest@${
|
|
1109
|
+
label: `rest@${this.loc(p)}`,
|
|
689
1110
|
node: p,
|
|
690
1111
|
}));
|
|
691
1112
|
this.add(this.binding(p), arr);
|
|
@@ -694,8 +1115,12 @@ class Analyzer {
|
|
|
694
1115
|
}
|
|
695
1116
|
const body = fn.body;
|
|
696
1117
|
if (body !== undefined) {
|
|
697
|
-
if (ts.isBlock(body))
|
|
1118
|
+
if (ts.isBlock(body)) {
|
|
698
1119
|
this.stmts(list(body.statements));
|
|
1120
|
+
// A call that runs off the end of the body returns undefined.
|
|
1121
|
+
if (canComplete(list(body.statements)))
|
|
1122
|
+
this.add(info.ret, this.prim("undefined"));
|
|
1123
|
+
}
|
|
699
1124
|
else
|
|
700
1125
|
this.edge(this.expr(body), info.ret);
|
|
701
1126
|
}
|
|
@@ -730,7 +1155,7 @@ class Analyzer {
|
|
|
730
1155
|
const p = decl.parent;
|
|
731
1156
|
if (p !== undefined && ts.isVariableDeclaration(p) && ts.isIdentifier(p.name))
|
|
732
1157
|
return p.name.text;
|
|
733
|
-
return `<class@${
|
|
1158
|
+
return `<class@${this.loc(decl)}>`;
|
|
734
1159
|
}
|
|
735
1160
|
classAtoms(decl) {
|
|
736
1161
|
const name = this.className(decl);
|
|
@@ -769,7 +1194,7 @@ class Analyzer {
|
|
|
769
1194
|
ctx: "",
|
|
770
1195
|
root: null,
|
|
771
1196
|
walked: true,
|
|
772
|
-
label: `${label}.${suffix}@${
|
|
1197
|
+
label: `${label}.${suffix}@${this.loc(decl)}`,
|
|
773
1198
|
params: [],
|
|
774
1199
|
rest: -1,
|
|
775
1200
|
thisNode: this.newNode(),
|
|
@@ -838,7 +1263,9 @@ class Analyzer {
|
|
|
838
1263
|
this.callConstructorChain(decl, instance, args, spread, site);
|
|
839
1264
|
}
|
|
840
1265
|
callConstructorChain(decl, instance, args, spread, site) {
|
|
841
|
-
|
|
1266
|
+
// The arguments' nodes too: one `new` site walked in several contexts
|
|
1267
|
+
// (receiver classes, per-site clones) passes each context's values.
|
|
1268
|
+
const key = `ctor:${this.nodeKey(decl)}:${instance.id}:${this.nodeKey(site)}:${args.join(",")}`;
|
|
842
1269
|
if (this.boundCalls.has(key))
|
|
843
1270
|
return;
|
|
844
1271
|
this.boundCalls.add(key);
|
|
@@ -850,7 +1277,7 @@ class Analyzer {
|
|
|
850
1277
|
this.activate(info);
|
|
851
1278
|
this.add(info.thisNode, instance);
|
|
852
1279
|
this.bindArgs(info, args, spread);
|
|
853
|
-
this.edgeFor(site, info);
|
|
1280
|
+
this.edgeFor(site, info, args);
|
|
854
1281
|
return;
|
|
855
1282
|
}
|
|
856
1283
|
const base = this.baseClass(decl);
|
|
@@ -894,18 +1321,19 @@ class Analyzer {
|
|
|
894
1321
|
}
|
|
895
1322
|
}
|
|
896
1323
|
/** Call of a function atom with a receiver node. */
|
|
897
|
-
callFunction(
|
|
1324
|
+
callFunction(callee, thisNode, args, spread, dst, site) {
|
|
898
1325
|
// `() => Object.create(null)` helpers: each call site gets its own
|
|
899
1326
|
// dictionary, as if the helper were inlined.
|
|
900
|
-
if (this.isFactory(
|
|
1327
|
+
if (this.isFactory(callee.node)) {
|
|
901
1328
|
const d = this.atoms.intern(`dict:${this.nodeKey(site)}`, () => ({
|
|
902
1329
|
kind: "dictionary",
|
|
903
|
-
label: `Object.create@${
|
|
1330
|
+
label: `Object.create@${this.loc(site)}`,
|
|
904
1331
|
node: site,
|
|
905
1332
|
}));
|
|
906
1333
|
this.add(dst, d);
|
|
907
1334
|
return;
|
|
908
1335
|
}
|
|
1336
|
+
const info = this.siteClone(callee, site, args) ?? callee;
|
|
909
1337
|
this.activate(info);
|
|
910
1338
|
const fnNode = info.node;
|
|
911
1339
|
const key = `call:${info.ctx}|${this.nodeKey(fnNode)}:${this.nodeKey(site)}:${thisNode ?? -1}:${dst}`;
|
|
@@ -925,7 +1353,88 @@ class Analyzer {
|
|
|
925
1353
|
}
|
|
926
1354
|
else
|
|
927
1355
|
this.edge(info.ret, dst);
|
|
928
|
-
this.edgeFor(site, info);
|
|
1356
|
+
this.edgeFor(site, info, args);
|
|
1357
|
+
}
|
|
1358
|
+
/** The prototype object of a class declaration (`C.prototype`). */
|
|
1359
|
+
classProto(decl) {
|
|
1360
|
+
return this.atoms.intern(`cproto:${this.nodeKey(decl)}`, () => ({
|
|
1361
|
+
kind: "object",
|
|
1362
|
+
label: `${this.className(decl)}.prototype`,
|
|
1363
|
+
node: decl,
|
|
1364
|
+
}));
|
|
1365
|
+
}
|
|
1366
|
+
/** Per-call-site clones of init factories: a function called from
|
|
1367
|
+
* module initialization (top-level code outside loops, or another such
|
|
1368
|
+
* clone) is analyzed once per call site, so the objects it creates are
|
|
1369
|
+
* one allocation per site (`z.string()` and `z.object(…)` schemas,
|
|
1370
|
+
* valibot's schema literals) instead of one per function. Clones run
|
|
1371
|
+
* at most once, which makes their objects singletons. */
|
|
1372
|
+
siteClones = new Map();
|
|
1373
|
+
/** The site-clone context a literal at `node` is allocated in, or "". */
|
|
1374
|
+
siteCloneCtx(node) {
|
|
1375
|
+
const root = this.ctxRoot;
|
|
1376
|
+
if (!this.ctx.includes("@S") || root === null)
|
|
1377
|
+
return "";
|
|
1378
|
+
const inside = node.getSourceFile() === root.getSourceFile() && node.pos >= root.pos && node.end <= root.end;
|
|
1379
|
+
return inside ? this.ctx : "";
|
|
1380
|
+
}
|
|
1381
|
+
siteClone(info, site, args) {
|
|
1382
|
+
if (this.siteCloneLimit === 0 || info.isGenerator || ts.isSourceFile(info.node))
|
|
1383
|
+
return null;
|
|
1384
|
+
if (ts.isClassLikeDeclaration(info.node))
|
|
1385
|
+
return null;
|
|
1386
|
+
// A function walked in an enclosing clone's or receiver's context reads
|
|
1387
|
+
// and writes that context's bindings of the variables it captures. A
|
|
1388
|
+
// clone is its own context root, so it would resolve them in the
|
|
1389
|
+
// default context instead, and their writes would be lost.
|
|
1390
|
+
if (info.root !== null && info.root !== info.node)
|
|
1391
|
+
return null;
|
|
1392
|
+
// A class's constructor and methods run in receiver contexts of their
|
|
1393
|
+
// own, rooted at each member: inside a clone they too would resolve the
|
|
1394
|
+
// function's bindings in the default context.
|
|
1395
|
+
if (this.declaresClass(info.node))
|
|
1396
|
+
return null;
|
|
1397
|
+
const sc = this.argsFrom.get(args);
|
|
1398
|
+
if (sc === undefined || sc.inLoop || this.forceLoop || this.repeatingSites.has(site))
|
|
1399
|
+
return null;
|
|
1400
|
+
const caller = sc.caller;
|
|
1401
|
+
if (caller === null)
|
|
1402
|
+
return null;
|
|
1403
|
+
// The clone itself, not a closure created inside it (which inherits
|
|
1404
|
+
// its context but may run any number of times).
|
|
1405
|
+
const callerInit = ts.isSourceFile(caller.node) || (caller.ctx.includes("@S") && caller.root === caller.node);
|
|
1406
|
+
if (!callerInit)
|
|
1407
|
+
return null;
|
|
1408
|
+
// A clone inside a clone keys on the whole chain of sites.
|
|
1409
|
+
const chain = caller.ctx.includes("@S") ? caller.ctx.slice(caller.ctx.indexOf("@S")) : "";
|
|
1410
|
+
if (chain.split("@S").length > SITE_CLONE_DEPTH)
|
|
1411
|
+
return null;
|
|
1412
|
+
const ctx = `${info.ctx}${chain}@S${this.nodeKey(site)}`;
|
|
1413
|
+
const existing = this.functions.get(`${ctx}|${this.nodeKey(info.node)}`);
|
|
1414
|
+
if (existing !== undefined)
|
|
1415
|
+
return existing;
|
|
1416
|
+
const count = this.siteClones.get(info.node) ?? 0;
|
|
1417
|
+
if (count >= this.siteCloneLimit)
|
|
1418
|
+
return null;
|
|
1419
|
+
this.siteClones.set(info.node, count + 1);
|
|
1420
|
+
// The clone keeps the function's receiver: an arrow's lexical `this`,
|
|
1421
|
+
// and whatever reaches a function's own `this`, such as the receiver
|
|
1422
|
+
// `bind` supplies.
|
|
1423
|
+
const clone = this.functionInfo(info.node, info.ownerClass, ctx, info.thisNode);
|
|
1424
|
+
if (!clone.isArrow)
|
|
1425
|
+
this.edge(info.thisNode, clone.thisNode);
|
|
1426
|
+
return clone;
|
|
1427
|
+
}
|
|
1428
|
+
classDeclarers = new Map();
|
|
1429
|
+
/** Whether a class declaration or expression is anywhere inside `node`. */
|
|
1430
|
+
declaresClass(node) {
|
|
1431
|
+
let r = this.classDeclarers.get(node);
|
|
1432
|
+
if (r === undefined) {
|
|
1433
|
+
const visit = (n) => ts.isClassLikeDeclaration(n) ? true : ts.forEachChild(n, visit);
|
|
1434
|
+
r = ts.forEachChild(node, visit) === true;
|
|
1435
|
+
this.classDeclarers.set(node, r);
|
|
1436
|
+
}
|
|
1437
|
+
return r;
|
|
929
1438
|
}
|
|
930
1439
|
factories = new Map();
|
|
931
1440
|
isFactory(node) {
|
|
@@ -969,7 +1478,7 @@ class Analyzer {
|
|
|
969
1478
|
syntheticArray(site, tag) {
|
|
970
1479
|
return this.atoms.intern(`arr:${tag}:${this.nodeKey(site)}`, () => ({
|
|
971
1480
|
kind: "array",
|
|
972
|
-
label: `${tag}[]@${
|
|
1481
|
+
label: `${tag}[]@${this.loc(site)}`,
|
|
973
1482
|
node: site,
|
|
974
1483
|
}));
|
|
975
1484
|
}
|
|
@@ -1013,8 +1522,12 @@ class Analyzer {
|
|
|
1013
1522
|
return;
|
|
1014
1523
|
}
|
|
1015
1524
|
if (ts.isReturnStatement(s)) {
|
|
1016
|
-
if (
|
|
1525
|
+
if (this.currentFn === null)
|
|
1526
|
+
return;
|
|
1527
|
+
if (s.expression !== undefined)
|
|
1017
1528
|
this.edge(this.expr(s.expression), this.currentFn.ret);
|
|
1529
|
+
else
|
|
1530
|
+
this.add(this.currentFn.ret, this.prim("undefined"));
|
|
1018
1531
|
return;
|
|
1019
1532
|
}
|
|
1020
1533
|
if (ts.isFunctionDeclaration(s)) {
|
|
@@ -1085,7 +1598,7 @@ class Analyzer {
|
|
|
1085
1598
|
return;
|
|
1086
1599
|
}
|
|
1087
1600
|
if (ts.isThrowStatement(s)) {
|
|
1088
|
-
this.sink(this.expr(s.expression), `thrown at ${
|
|
1601
|
+
this.sink(this.expr(s.expression), `thrown at ${this.loc(s)}`);
|
|
1089
1602
|
return;
|
|
1090
1603
|
}
|
|
1091
1604
|
if (ts.isImportDeclaration(s) ||
|
|
@@ -1097,6 +1610,10 @@ class Analyzer {
|
|
|
1097
1610
|
this.expr(s.expression);
|
|
1098
1611
|
return;
|
|
1099
1612
|
}
|
|
1613
|
+
if (ts.isIfStatement(s) && this.currentFn !== null) {
|
|
1614
|
+
this.ifStatement(s);
|
|
1615
|
+
return;
|
|
1616
|
+
}
|
|
1100
1617
|
// Blocks, ifs, switches, labels: walk children, evaluating expressions.
|
|
1101
1618
|
ts.forEachChild(s, (child) => {
|
|
1102
1619
|
if (ts.isExpression(child))
|
|
@@ -1110,6 +1627,13 @@ class Analyzer {
|
|
|
1110
1627
|
const b = this.binding(d);
|
|
1111
1628
|
if (d.initializer !== undefined)
|
|
1112
1629
|
this.edge(this.expr(d.initializer), b);
|
|
1630
|
+
else {
|
|
1631
|
+
// `let x;` holds undefined until it is assigned (a for-in/for-of
|
|
1632
|
+
// binding gets its values from the loop).
|
|
1633
|
+
const loop = d.parent?.parent;
|
|
1634
|
+
if (loop === undefined || !(ts.isForOfStatement(loop) || ts.isForInStatement(loop)))
|
|
1635
|
+
this.add(b, this.prim("undefined"));
|
|
1636
|
+
}
|
|
1113
1637
|
this.bindPattern(d.name, b);
|
|
1114
1638
|
}
|
|
1115
1639
|
/** Destructuring: binding elements read from the source node. */
|
|
@@ -1168,7 +1692,7 @@ class Analyzer {
|
|
|
1168
1692
|
else {
|
|
1169
1693
|
this.add(dst, this.top);
|
|
1170
1694
|
if (a.kind !== "top")
|
|
1171
|
-
this.escape(a, `iterated at ${
|
|
1695
|
+
this.escape(a, `iterated at ${this.loc(site)}`);
|
|
1172
1696
|
}
|
|
1173
1697
|
});
|
|
1174
1698
|
}
|
|
@@ -1178,10 +1702,18 @@ class Analyzer {
|
|
|
1178
1702
|
const memo = this.exprMemo.get(key);
|
|
1179
1703
|
if (memo !== undefined)
|
|
1180
1704
|
return memo;
|
|
1181
|
-
|
|
1705
|
+
let id = this.exprUncached(e);
|
|
1706
|
+
// A member of an optional chain (`a?.b.c`, `f?.()`) is undefined when
|
|
1707
|
+
// the chain short-circuits.
|
|
1708
|
+
if ((e.flags & ts.NodeFlags.OptionalChain) !== 0) {
|
|
1709
|
+
const out = this.newNode();
|
|
1710
|
+
this.edge(id, out);
|
|
1711
|
+
this.add(out, this.prim("undefined"));
|
|
1712
|
+
id = out;
|
|
1713
|
+
}
|
|
1182
1714
|
this.exprMemo.set(key, id);
|
|
1183
1715
|
if (this.traceTop && !this.nodeLabel.has(id))
|
|
1184
|
-
this.nodeLabel.set(id, `expr ${e.getText().slice(0, 40).replace(/\s+/g, " ")}@${
|
|
1716
|
+
this.nodeLabel.set(id, `expr ${e.getText().slice(0, 40).replace(/\s+/g, " ")}@${this.loc(e)}`);
|
|
1185
1717
|
return id;
|
|
1186
1718
|
}
|
|
1187
1719
|
exprUncached(e) {
|
|
@@ -1201,8 +1733,9 @@ class Analyzer {
|
|
|
1201
1733
|
case ts.SyntaxKind.BigIntLiteral:
|
|
1202
1734
|
return this.constNode(this.prim("bigint"));
|
|
1203
1735
|
case ts.SyntaxKind.TrueKeyword:
|
|
1736
|
+
return this.constNode(this.boolLiteral(true));
|
|
1204
1737
|
case ts.SyntaxKind.FalseKeyword:
|
|
1205
|
-
return this.constNode(this.
|
|
1738
|
+
return this.constNode(this.boolLiteral(false));
|
|
1206
1739
|
case ts.SyntaxKind.NullKeyword:
|
|
1207
1740
|
return this.constNode(this.prim("null"));
|
|
1208
1741
|
case ts.SyntaxKind.RegularExpressionLiteral:
|
|
@@ -1298,18 +1831,23 @@ class Analyzer {
|
|
|
1298
1831
|
const recv = this.expr(target.expression);
|
|
1299
1832
|
const name = ts.isPropertyAccessExpression(target) ? target.name.text : null;
|
|
1300
1833
|
this.ops.push({ kind: "delete", recv, name, node: e });
|
|
1834
|
+
this.prototypeWrite(recv, name);
|
|
1301
1835
|
}
|
|
1302
1836
|
return this.constNode(this.prim("boolean"));
|
|
1303
1837
|
}
|
|
1304
1838
|
if (ts.isPrefixUnaryExpression(e) || ts.isPostfixUnaryExpression(e)) {
|
|
1305
1839
|
const operand = e.operand;
|
|
1306
|
-
this.expr(operand);
|
|
1307
|
-
if (e.operator === ts.SyntaxKind.PlusPlusToken ||
|
|
1308
|
-
e.operator === ts.SyntaxKind.MinusMinusToken)
|
|
1309
|
-
this.assignTo(operand, this.constNode(this.prim("number")));
|
|
1840
|
+
const value = this.expr(operand);
|
|
1310
1841
|
if (ts.isPrefixUnaryExpression(e) && e.operator === ts.SyntaxKind.ExclamationToken)
|
|
1311
1842
|
return this.constNode(this.prim("boolean"));
|
|
1312
|
-
|
|
1843
|
+
// `+x` is a number (a bigint throws); `-x`, `~x`, `++`/`--` keep a bigint.
|
|
1844
|
+
if (ts.isPrefixUnaryExpression(e) && e.operator === ts.SyntaxKind.PlusToken)
|
|
1845
|
+
return this.constNode(this.prim("number"));
|
|
1846
|
+
const result = this.numericResult([value]);
|
|
1847
|
+
if (e.operator === ts.SyntaxKind.PlusPlusToken ||
|
|
1848
|
+
e.operator === ts.SyntaxKind.MinusMinusToken)
|
|
1849
|
+
this.assignTo(operand, result);
|
|
1850
|
+
return result;
|
|
1313
1851
|
}
|
|
1314
1852
|
if (ts.isSpreadElement(e))
|
|
1315
1853
|
return this.expr(e.expression);
|
|
@@ -1317,7 +1855,7 @@ class Analyzer {
|
|
|
1317
1855
|
return this.taggedTemplate(e);
|
|
1318
1856
|
if (ts.isYieldExpression(e)) {
|
|
1319
1857
|
if (e.expression !== undefined)
|
|
1320
|
-
this.sink(this.expr(e.expression), `yielded at ${
|
|
1858
|
+
this.sink(this.expr(e.expression), `yielded at ${this.loc(e)}`);
|
|
1321
1859
|
return this.constNode(this.top);
|
|
1322
1860
|
}
|
|
1323
1861
|
if (ts.isMetaProperty(e))
|
|
@@ -1343,6 +1881,8 @@ class Analyzer {
|
|
|
1343
1881
|
const arr = this.syntheticArray(id, "arguments");
|
|
1344
1882
|
for (const p of fn.params)
|
|
1345
1883
|
this.edge(p, this.element(arr));
|
|
1884
|
+
// Arguments past the declared parameters are not tracked.
|
|
1885
|
+
this.add(this.element(arr), this.top);
|
|
1346
1886
|
return this.constNode(arr);
|
|
1347
1887
|
}
|
|
1348
1888
|
}
|
|
@@ -1581,7 +2121,7 @@ class Analyzer {
|
|
|
1581
2121
|
let hasComputedKey = false;
|
|
1582
2122
|
const spreads = [];
|
|
1583
2123
|
const inPackage = isPackageJsFile(e.getSourceFile());
|
|
1584
|
-
const label = () => `{${keys.slice(0, 6).join(",")}${keys.length > 6 ? ",…" : ""}${keysKnown ? "" : ",…"}}@${
|
|
2124
|
+
const label = () => `{${keys.slice(0, 6).join(",")}${keys.length > 6 ? ",…" : ""}${keysKnown ? "" : ",…"}}@${this.loc(e)}`;
|
|
1585
2125
|
// keys first, so the label is complete
|
|
1586
2126
|
for (const p of list(e.properties)) {
|
|
1587
2127
|
if (ts.isSpreadAssignment(p)) {
|
|
@@ -1600,11 +2140,8 @@ class Analyzer {
|
|
|
1600
2140
|
if (!keys.includes(key))
|
|
1601
2141
|
keys.push(key);
|
|
1602
2142
|
}
|
|
1603
|
-
const
|
|
1604
|
-
|
|
1605
|
-
label: label(),
|
|
1606
|
-
node: e,
|
|
1607
|
-
}));
|
|
2143
|
+
const sctx = this.siteCloneCtx(e);
|
|
2144
|
+
const atom = this.atoms.intern(sctx === "" ? `obj:${this.nodeKey(e)}` : `obj:${sctx}|${this.nodeKey(e)}`, () => ({ kind: "object", label: label(), node: e, ...(sctx === "" ? {} : { ctx: sctx }) }));
|
|
1608
2145
|
const n = this.newNode();
|
|
1609
2146
|
this.add(n, atom);
|
|
1610
2147
|
for (const p of list(e.properties)) {
|
|
@@ -1649,17 +2186,21 @@ class Analyzer {
|
|
|
1649
2186
|
else
|
|
1650
2187
|
this.edge(value, this.anyField(atom));
|
|
1651
2188
|
}
|
|
2189
|
+
if (!this.literalOwnKeys.has(atom))
|
|
2190
|
+
this.literalOwnKeys.set(atom, new Set(keys));
|
|
1652
2191
|
if (!this.siteAtoms.has(atom) && this.siteAtoms.add(atom))
|
|
1653
2192
|
this.sites.push({
|
|
1654
2193
|
atom,
|
|
1655
2194
|
node: e,
|
|
1656
2195
|
kind: "object",
|
|
1657
2196
|
keys: keysKnown ? keys : null,
|
|
2197
|
+
ownKeys: keys,
|
|
1658
2198
|
hasAccessor,
|
|
1659
2199
|
hasProto,
|
|
1660
2200
|
hasComputedKey,
|
|
1661
2201
|
spreads,
|
|
1662
2202
|
inPackage,
|
|
2203
|
+
ctx: sctx,
|
|
1663
2204
|
});
|
|
1664
2205
|
return n;
|
|
1665
2206
|
}
|
|
@@ -1786,10 +2327,12 @@ class Analyzer {
|
|
|
1786
2327
|
this.lateCopies.push(call);
|
|
1787
2328
|
}
|
|
1788
2329
|
arrayLiteral(e) {
|
|
1789
|
-
const
|
|
2330
|
+
const sctx = this.siteCloneCtx(e);
|
|
2331
|
+
const atom = this.atoms.intern(sctx === "" ? `arr:${this.nodeKey(e)}` : `arr:${sctx}|${this.nodeKey(e)}`, () => ({
|
|
1790
2332
|
kind: "array",
|
|
1791
|
-
label: `[]@${
|
|
2333
|
+
label: `[]@${this.loc(e)}`,
|
|
1792
2334
|
node: e,
|
|
2335
|
+
...(sctx === "" ? {} : { ctx: sctx }),
|
|
1793
2336
|
}));
|
|
1794
2337
|
const n = this.newNode();
|
|
1795
2338
|
this.add(n, atom);
|
|
@@ -1811,11 +2354,13 @@ class Analyzer {
|
|
|
1811
2354
|
node: e,
|
|
1812
2355
|
kind: "array",
|
|
1813
2356
|
keys: null,
|
|
2357
|
+
ownKeys: [],
|
|
1814
2358
|
hasAccessor: false,
|
|
1815
2359
|
hasProto: hasHole,
|
|
1816
2360
|
hasComputedKey: false,
|
|
1817
2361
|
spreads: [],
|
|
1818
2362
|
inPackage: isPackageJsFile(e.getSourceFile()),
|
|
2363
|
+
ctx: sctx,
|
|
1819
2364
|
});
|
|
1820
2365
|
return n;
|
|
1821
2366
|
}
|
|
@@ -1837,14 +2382,12 @@ class Analyzer {
|
|
|
1837
2382
|
return n;
|
|
1838
2383
|
}
|
|
1839
2384
|
if (op >= ts.SyntaxKind.FirstCompoundAssignment && op <= ts.SyntaxKind.LastCompoundAssignment) {
|
|
1840
|
-
this.expr(e.left);
|
|
1841
|
-
this.expr(e.right);
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
2385
|
+
const lv = this.expr(e.left);
|
|
2386
|
+
const rv = this.expr(e.right);
|
|
2387
|
+
// Arithmetic on bigints answers bigints; `+=` may also concatenate.
|
|
2388
|
+
const result = this.numericResult([lv, rv]);
|
|
2389
|
+
if (op === ts.SyntaxKind.PlusEqualsToken)
|
|
1845
2390
|
this.add(result, this.prim("string"));
|
|
1846
|
-
this.add(result, this.prim("number"));
|
|
1847
|
-
}
|
|
1848
2391
|
this.assignTo(e.left, result);
|
|
1849
2392
|
return result;
|
|
1850
2393
|
}
|
|
@@ -1885,13 +2428,15 @@ class Analyzer {
|
|
|
1885
2428
|
this.add(n, this.prim("number"));
|
|
1886
2429
|
if (a.kind === "top")
|
|
1887
2430
|
this.add(n, this.prim("number"));
|
|
2431
|
+
if (a.kind === "top" || (a.kind === "prim" && a.label === "bigint"))
|
|
2432
|
+
this.add(n, this.prim("bigint"));
|
|
1888
2433
|
};
|
|
1889
2434
|
this.on(l, strOrNum);
|
|
1890
2435
|
this.on(r, strOrNum);
|
|
1891
2436
|
return n;
|
|
1892
2437
|
}
|
|
1893
2438
|
default:
|
|
1894
|
-
return this.
|
|
2439
|
+
return this.numericResult([l, r]);
|
|
1895
2440
|
}
|
|
1896
2441
|
}
|
|
1897
2442
|
assignTo(target, value) {
|
|
@@ -1899,7 +2444,7 @@ class Analyzer {
|
|
|
1899
2444
|
if (ts.isIdentifier(t)) {
|
|
1900
2445
|
const decl = this.resolve(t);
|
|
1901
2446
|
if (decl === undefined || decl.getSourceFile().isDeclarationFile) {
|
|
1902
|
-
this.sink(value, `global write at ${
|
|
2447
|
+
this.sink(value, `global write at ${this.loc(t)}`);
|
|
1903
2448
|
return;
|
|
1904
2449
|
}
|
|
1905
2450
|
this.edge(value, this.binding(decl));
|
|
@@ -1972,8 +2517,22 @@ class Analyzer {
|
|
|
1972
2517
|
case "prim":
|
|
1973
2518
|
if (name === "length" && a.label === "string")
|
|
1974
2519
|
this.add(dst, this.prim("number"));
|
|
1975
|
-
else if (a.label === "string"
|
|
1976
|
-
|
|
2520
|
+
else if (a.label === "string" && /^\d+$/.test(name)) {
|
|
2521
|
+
// An index past the end reads the prototype chain.
|
|
2522
|
+
this.add(dst, this.prim("string"));
|
|
2523
|
+
this.add(dst, this.prim("undefined"));
|
|
2524
|
+
this.primitiveRead(name, dst);
|
|
2525
|
+
}
|
|
2526
|
+
else if (a.label === "string" || a.label === "number" || a.label === "boolean") {
|
|
2527
|
+
// A name the primitive's prototype chain lacks reads undefined,
|
|
2528
|
+
// unless the program may add it there.
|
|
2529
|
+
if (PRIMITIVE_MEMBERS[a.label].has(name) || OBJECT_PROTOTYPE_MEMBERS.has(name))
|
|
2530
|
+
this.add(dst, this.builtin(`${a.label}.${name}`, a));
|
|
2531
|
+
else {
|
|
2532
|
+
this.add(dst, this.prim("undefined"));
|
|
2533
|
+
this.primitiveRead(name, dst);
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
1977
2536
|
return;
|
|
1978
2537
|
case "instance": {
|
|
1979
2538
|
const decl = a.node;
|
|
@@ -1984,6 +2543,9 @@ class Analyzer {
|
|
|
1984
2543
|
this.unknownKeysInto(a, dst);
|
|
1985
2544
|
return;
|
|
1986
2545
|
}
|
|
2546
|
+
// Members stored on a class's prototype object after the fact.
|
|
2547
|
+
for (const c of this.classChain(decl))
|
|
2548
|
+
this.edge(this.field(this.classProto(c), name), dst);
|
|
1987
2549
|
const member = this.lookupMember(decl, name, false);
|
|
1988
2550
|
if (member?.kind === "method")
|
|
1989
2551
|
this.add(dst, this.fnAtom(member.method, this.ownerOf(member.method), this.receiverCtx(a)));
|
|
@@ -2004,7 +2566,9 @@ class Analyzer {
|
|
|
2004
2566
|
case "class": {
|
|
2005
2567
|
const decl = a.node;
|
|
2006
2568
|
if (name === "prototype" || name === "name") {
|
|
2007
|
-
|
|
2569
|
+
// A class's prototype object: members stored on it later
|
|
2570
|
+
// (`C.prototype.isVector3 = true`) are members of its instances.
|
|
2571
|
+
this.add(dst, name === "prototype" ? this.classProto(decl) : this.prim("string"));
|
|
2008
2572
|
this.fieldInto(a, name, dst);
|
|
2009
2573
|
this.unknownKeysInto(a, dst);
|
|
2010
2574
|
return;
|
|
@@ -2051,8 +2615,10 @@ class Analyzer {
|
|
|
2051
2615
|
case "array":
|
|
2052
2616
|
if (name === "length")
|
|
2053
2617
|
this.add(dst, this.prim("number"));
|
|
2054
|
-
else if (/^\d+$/.test(name))
|
|
2618
|
+
else if (/^\d+$/.test(name)) {
|
|
2055
2619
|
this.edge(this.element(a), dst);
|
|
2620
|
+
this.add(dst, this.prim("undefined"));
|
|
2621
|
+
}
|
|
2056
2622
|
else {
|
|
2057
2623
|
// A named property, written by name or under an unknown key; an own field shadows a method.
|
|
2058
2624
|
if (ARRAY_METHODS.has(name)) {
|
|
@@ -2065,8 +2631,17 @@ class Analyzer {
|
|
|
2065
2631
|
}
|
|
2066
2632
|
return;
|
|
2067
2633
|
case "object": {
|
|
2634
|
+
// A read through a class's prototype object (`C.prototype.m`) may
|
|
2635
|
+
// be any member: unknown, as before prototype objects were tracked.
|
|
2636
|
+
if (a.label.endsWith(".prototype") &&
|
|
2637
|
+
a.node !== undefined &&
|
|
2638
|
+
ts.isClassLikeDeclaration(a.node))
|
|
2639
|
+
this.add(dst, this.top);
|
|
2068
2640
|
this.edge(this.field(a, name), dst);
|
|
2069
2641
|
this.edge(this.anyField(a), dst);
|
|
2642
|
+
const own = this.literalOwnKeys.get(a);
|
|
2643
|
+
if (own !== undefined && !own.has(name) && !OBJECT_PROTOTYPE_MEMBERS.has(name))
|
|
2644
|
+
this.add(dst, this.prim("undefined"));
|
|
2070
2645
|
if (this.namespaceAtoms.has(a) && name !== "exports") {
|
|
2071
2646
|
this.loadConstraint(this.field(a, "exports"), name, dst, site);
|
|
2072
2647
|
}
|
|
@@ -2092,10 +2667,24 @@ class Analyzer {
|
|
|
2092
2667
|
this.add(dst, this.builtin(`object.${name}`, a));
|
|
2093
2668
|
return;
|
|
2094
2669
|
}
|
|
2095
|
-
case "dictionary":
|
|
2670
|
+
case "dictionary": {
|
|
2096
2671
|
this.edge(this.anyField(a), dst);
|
|
2097
2672
|
this.edge(this.field(a, name), dst);
|
|
2673
|
+
// An absent key reads undefined, or what the prototype has.
|
|
2674
|
+
this.add(dst, this.prim("undefined"));
|
|
2675
|
+
const proto = this.dictProtos.get(a);
|
|
2676
|
+
// Once per dictionary, name and destination: prototype chains can
|
|
2677
|
+
// be cyclic in the analysis (`Object.create(this)`).
|
|
2678
|
+
const key = `${a.id}:${name}:${dst}`;
|
|
2679
|
+
if (proto !== undefined && !this.protoReads.has(key)) {
|
|
2680
|
+
this.protoReads.add(key);
|
|
2681
|
+
this.on(proto, (p) => {
|
|
2682
|
+
if (p.kind !== "prim")
|
|
2683
|
+
this.loadAtom(p, name, dst, site);
|
|
2684
|
+
});
|
|
2685
|
+
}
|
|
2098
2686
|
return;
|
|
2687
|
+
}
|
|
2099
2688
|
case "promise":
|
|
2100
2689
|
if (name === "then" || name === "catch" || name === "finally")
|
|
2101
2690
|
this.add(dst, this.builtin(`promise.${name}`, a));
|
|
@@ -2130,8 +2719,16 @@ class Analyzer {
|
|
|
2130
2719
|
this.add(dst, this.prim("number"));
|
|
2131
2720
|
else if (path === "Math" && /^[A-Z0-9_]+$/.test(name))
|
|
2132
2721
|
this.add(dst, this.prim("number"));
|
|
2133
|
-
else if (path === "Symbol")
|
|
2134
|
-
|
|
2722
|
+
else if (path === "Symbol") {
|
|
2723
|
+
// The well-known symbols are symbols; `Symbol.for` and `Symbol.keyFor`
|
|
2724
|
+
// are functions (a call of a symbol would answer nothing).
|
|
2725
|
+
if (WELL_KNOWN_SYMBOLS.has(name))
|
|
2726
|
+
this.add(dst, this.prim("symbol"));
|
|
2727
|
+
else if (name === "for" || name === "keyFor")
|
|
2728
|
+
this.add(dst, this.builtin(`Symbol.${name}`));
|
|
2729
|
+
else
|
|
2730
|
+
this.add(dst, this.top);
|
|
2731
|
+
}
|
|
2135
2732
|
else if (path === "Error.instance" || path === "error") {
|
|
2136
2733
|
if (name === "message" || name === "stack" || name === "name")
|
|
2137
2734
|
this.add(dst, this.prim("string"));
|
|
@@ -2140,6 +2737,7 @@ class Analyzer {
|
|
|
2140
2737
|
}
|
|
2141
2738
|
else if (a.receiver === undefined &&
|
|
2142
2739
|
MODELED_GLOBALS.has(path.split(".")[0]) &&
|
|
2740
|
+
!path.endsWith(".instance") &&
|
|
2143
2741
|
path.split(".").length < 4)
|
|
2144
2742
|
this.add(dst, this.builtin(`${path}.${name}`));
|
|
2145
2743
|
else if (path === "RegExp.instance")
|
|
@@ -2152,7 +2750,7 @@ class Analyzer {
|
|
|
2152
2750
|
switch (a.kind) {
|
|
2153
2751
|
case "top":
|
|
2154
2752
|
this.noteTopWrite(name, site);
|
|
2155
|
-
this.sink(value, `stored into ⊤.${name} at ${
|
|
2753
|
+
this.sink(value, `stored into ⊤.${name} at ${this.loc(site)}`);
|
|
2156
2754
|
return;
|
|
2157
2755
|
case "instance": {
|
|
2158
2756
|
const member = this.lookupMember(a.node, name, false);
|
|
@@ -2174,6 +2772,8 @@ class Analyzer {
|
|
|
2174
2772
|
this.edge(value, this.field(a, name));
|
|
2175
2773
|
return;
|
|
2176
2774
|
case "array":
|
|
2775
|
+
if (/^\d+$/.test(name) || name === "length")
|
|
2776
|
+
this.unsafeArrays.add(a);
|
|
2177
2777
|
if (/^\d+$/.test(name))
|
|
2178
2778
|
this.edge(value, this.element(a));
|
|
2179
2779
|
else if (name !== "length")
|
|
@@ -2182,7 +2782,9 @@ class Analyzer {
|
|
|
2182
2782
|
case "prim":
|
|
2183
2783
|
return;
|
|
2184
2784
|
default:
|
|
2185
|
-
|
|
2785
|
+
if (isPrimitivePrototype(a))
|
|
2786
|
+
this.extendPrimitives(name);
|
|
2787
|
+
this.sink(value, `stored into ${a.label} at ${this.loc(site)}`);
|
|
2186
2788
|
}
|
|
2187
2789
|
});
|
|
2188
2790
|
}
|
|
@@ -2193,12 +2795,23 @@ class Analyzer {
|
|
|
2193
2795
|
this.add(dst, this.top);
|
|
2194
2796
|
return;
|
|
2195
2797
|
case "array":
|
|
2798
|
+
// An index past the end (or a hole) reads undefined, unless the
|
|
2799
|
+
// loop proves the index in bounds of an array without holes.
|
|
2800
|
+
this.edge(this.element(a), dst);
|
|
2801
|
+
if (this.indexInBounds(site))
|
|
2802
|
+
this.guardedIndexReads.push({ recv: a, dst, done: false });
|
|
2803
|
+
else
|
|
2804
|
+
this.add(dst, this.prim("undefined"));
|
|
2805
|
+
return;
|
|
2196
2806
|
case "collection":
|
|
2197
2807
|
this.edge(this.element(a), dst);
|
|
2198
2808
|
return;
|
|
2199
2809
|
case "prim":
|
|
2200
|
-
if (a.label === "string")
|
|
2810
|
+
if (a.label === "string") {
|
|
2201
2811
|
this.add(dst, this.prim("string"));
|
|
2812
|
+
if (!this.indexInBounds(site))
|
|
2813
|
+
this.add(dst, this.prim("undefined"));
|
|
2814
|
+
}
|
|
2202
2815
|
return;
|
|
2203
2816
|
case "object":
|
|
2204
2817
|
case "dictionary":
|
|
@@ -2219,6 +2832,9 @@ class Analyzer {
|
|
|
2219
2832
|
this.lateCopies.push(copy);
|
|
2220
2833
|
if (a.kind === "instance" || a.kind === "class")
|
|
2221
2834
|
this.add(dst, this.top);
|
|
2835
|
+
// A key the object does not have reads undefined.
|
|
2836
|
+
else
|
|
2837
|
+
this.add(dst, this.prim("undefined"));
|
|
2222
2838
|
return;
|
|
2223
2839
|
}
|
|
2224
2840
|
default:
|
|
@@ -2232,12 +2848,14 @@ class Analyzer {
|
|
|
2232
2848
|
switch (a.kind) {
|
|
2233
2849
|
case "top":
|
|
2234
2850
|
this.noteTopWrite(null, site);
|
|
2235
|
-
this.sink(value, `stored into ⊤[k] at ${
|
|
2851
|
+
this.sink(value, `stored into ⊤[k] at ${this.loc(site)}`);
|
|
2236
2852
|
return;
|
|
2237
2853
|
case "array":
|
|
2238
2854
|
// An index, or a named property under an unknown key.
|
|
2239
2855
|
this.edge(value, this.element(a));
|
|
2240
2856
|
this.edge(value, this.anyField(a));
|
|
2857
|
+
if (!this.indexInBounds(site) && !isAppendIndex(site))
|
|
2858
|
+
this.unsafeArrays.add(a);
|
|
2241
2859
|
return;
|
|
2242
2860
|
case "prim":
|
|
2243
2861
|
return;
|
|
@@ -2250,7 +2868,9 @@ class Analyzer {
|
|
|
2250
2868
|
return;
|
|
2251
2869
|
default:
|
|
2252
2870
|
// As a store under a name: a builtin, promise or collection keeps it where it isn't tracked.
|
|
2253
|
-
|
|
2871
|
+
if (isPrimitivePrototype(a))
|
|
2872
|
+
this.extendPrimitives(null);
|
|
2873
|
+
this.sink(value, `stored into ${a.label}[k] at ${this.loc(site)}`);
|
|
2254
2874
|
}
|
|
2255
2875
|
});
|
|
2256
2876
|
}
|
|
@@ -2309,8 +2929,19 @@ class Analyzer {
|
|
|
2309
2929
|
}
|
|
2310
2930
|
out.push(this.expr(a));
|
|
2311
2931
|
}
|
|
2932
|
+
// The walk context of this call (one argument list per call site and
|
|
2933
|
+
// context): calls fire during solving, after the walk moved on.
|
|
2934
|
+
this.argsFrom.set(out, {
|
|
2935
|
+
caller: this.currentFn,
|
|
2936
|
+
inLoop: this.loopDepth > 0 || this.forceLoop,
|
|
2937
|
+
});
|
|
2312
2938
|
return { args: out, spread };
|
|
2313
2939
|
}
|
|
2940
|
+
/** Per argument list (args()), the calling function and whether the call
|
|
2941
|
+
* is in a loop, in the context the call was walked in. siteCtx keeps
|
|
2942
|
+
* the first context per syntax node, which a site walked in several
|
|
2943
|
+
* contexts (receiver classes, per-site clones) does not determine. */
|
|
2944
|
+
argsFrom = new Map();
|
|
2314
2945
|
call(e) {
|
|
2315
2946
|
this.noteSite(e);
|
|
2316
2947
|
const callee = unparen(e.expression);
|
|
@@ -2328,7 +2959,7 @@ class Analyzer {
|
|
|
2328
2959
|
}
|
|
2329
2960
|
else if (base === undefined)
|
|
2330
2961
|
for (const a of args)
|
|
2331
|
-
this.sink(a, `super(...) at ${
|
|
2962
|
+
this.sink(a, `super(...) at ${this.loc(e)}`);
|
|
2332
2963
|
return dst;
|
|
2333
2964
|
}
|
|
2334
2965
|
// CommonJS `require("<spec>")` of an analyzed module: its exports (the
|
|
@@ -2382,6 +3013,8 @@ class Analyzer {
|
|
|
2382
3013
|
}
|
|
2383
3014
|
if (name !== null)
|
|
2384
3015
|
this.ops.push({ kind: "read", recv, name, node: callee });
|
|
3016
|
+
else
|
|
3017
|
+
this.ops.push({ kind: "computedRead", recv, name: null, node: callee });
|
|
2385
3018
|
// Per receiver atom: the member it resolves to runs with that atom as `this`.
|
|
2386
3019
|
const member = name;
|
|
2387
3020
|
this.on(recv, (a) => {
|
|
@@ -2416,9 +3049,9 @@ class Analyzer {
|
|
|
2416
3049
|
return;
|
|
2417
3050
|
default:
|
|
2418
3051
|
for (const x of args)
|
|
2419
|
-
this.sink(x, `argument of ⊤ call at ${
|
|
3052
|
+
this.sink(x, `argument of ⊤ call at ${this.loc(site)}`);
|
|
2420
3053
|
if (recv !== null && a.kind === "top")
|
|
2421
|
-
this.sink(recv, `receiver of ⊤ call at ${
|
|
3054
|
+
this.sink(recv, `receiver of ⊤ call at ${this.loc(site)}`);
|
|
2422
3055
|
this.add(dst, this.top);
|
|
2423
3056
|
}
|
|
2424
3057
|
});
|
|
@@ -2447,17 +3080,24 @@ class Analyzer {
|
|
|
2447
3080
|
this.activate(info);
|
|
2448
3081
|
this.add(info.thisNode, inst);
|
|
2449
3082
|
this.bindArgs(info, args, spread);
|
|
2450
|
-
|
|
2451
|
-
|
|
3083
|
+
// `new` ignores a primitive result (and the undefined of a
|
|
3084
|
+
// body that runs off its end) and yields the instance.
|
|
3085
|
+
this.on(info.ret, (r) => {
|
|
3086
|
+
if (r.kind !== "prim")
|
|
3087
|
+
this.add(dst, r);
|
|
3088
|
+
});
|
|
3089
|
+
this.edgeFor(e, info, args);
|
|
2452
3090
|
}
|
|
2453
3091
|
return;
|
|
2454
3092
|
}
|
|
2455
3093
|
case "builtin":
|
|
2456
3094
|
this.constructBuiltin(a.path ?? "", args, dst, e);
|
|
2457
3095
|
return;
|
|
3096
|
+
case "prim":
|
|
3097
|
+
return; // `new` of a primitive throws
|
|
2458
3098
|
default:
|
|
2459
3099
|
for (const x of args)
|
|
2460
|
-
this.sink(x, `argument of ⊤ constructor at ${
|
|
3100
|
+
this.sink(x, `argument of ⊤ constructor at ${this.loc(e)}`);
|
|
2461
3101
|
this.add(dst, this.top);
|
|
2462
3102
|
}
|
|
2463
3103
|
});
|
|
@@ -2471,7 +3111,7 @@ class Analyzer {
|
|
|
2471
3111
|
case "WeakSet": {
|
|
2472
3112
|
const c = this.atoms.intern(`coll:${this.nodeKey(site)}`, () => ({
|
|
2473
3113
|
kind: "collection",
|
|
2474
|
-
label: `${path}@${
|
|
3114
|
+
label: `${path}@${this.loc(site)}`,
|
|
2475
3115
|
node: site,
|
|
2476
3116
|
}));
|
|
2477
3117
|
this.add(dst, c);
|
|
@@ -2486,7 +3126,7 @@ class Analyzer {
|
|
|
2486
3126
|
this.add(dst, this.builtin("Error.instance"));
|
|
2487
3127
|
return;
|
|
2488
3128
|
case "Promise": {
|
|
2489
|
-
const p = this.promiseAtom(site,
|
|
3129
|
+
const p = this.promiseAtom(site, this.loc(site));
|
|
2490
3130
|
this.add(this.field(p, "value"), this.top);
|
|
2491
3131
|
this.add(dst, p);
|
|
2492
3132
|
if (args[0] !== undefined) {
|
|
@@ -2505,7 +3145,10 @@ class Analyzer {
|
|
|
2505
3145
|
this.add(dst, this.builtin("RegExp.instance"));
|
|
2506
3146
|
return;
|
|
2507
3147
|
case "Array": {
|
|
2508
|
-
|
|
3148
|
+
const arr = this.syntheticArray(site, "Array");
|
|
3149
|
+
// `new Array(n)` has holes.
|
|
3150
|
+
this.unsafeArrays.add(arr);
|
|
3151
|
+
this.add(dst, arr);
|
|
2509
3152
|
return;
|
|
2510
3153
|
}
|
|
2511
3154
|
case "Proxy":
|
|
@@ -2513,12 +3156,12 @@ class Analyzer {
|
|
|
2513
3156
|
if (args[0] !== undefined)
|
|
2514
3157
|
this.ops.push({ kind: "proxy", recv: args[0], name: null, node: site });
|
|
2515
3158
|
for (const x of args)
|
|
2516
|
-
this.sink(x, `argument of new Proxy at ${
|
|
3159
|
+
this.sink(x, `argument of new Proxy at ${this.loc(site)}`);
|
|
2517
3160
|
this.add(dst, this.top);
|
|
2518
3161
|
return;
|
|
2519
3162
|
default:
|
|
2520
3163
|
for (const x of args)
|
|
2521
|
-
this.sink(x, `argument of new ${path} at ${
|
|
3164
|
+
this.sink(x, `argument of new ${path} at ${this.loc(site)}`);
|
|
2522
3165
|
this.add(dst, this.top);
|
|
2523
3166
|
}
|
|
2524
3167
|
}
|
|
@@ -2540,7 +3183,7 @@ class Analyzer {
|
|
|
2540
3183
|
}
|
|
2541
3184
|
else if (f.kind === "top" || f.kind === "builtin") {
|
|
2542
3185
|
for (const x of cbArgs)
|
|
2543
|
-
this.sink(x, `argument of ⊤ callback at ${
|
|
3186
|
+
this.sink(x, `argument of ⊤ callback at ${this.loc(site)}`);
|
|
2544
3187
|
if (ret !== null)
|
|
2545
3188
|
this.add(ret, this.top);
|
|
2546
3189
|
}
|
|
@@ -2548,7 +3191,7 @@ class Analyzer {
|
|
|
2548
3191
|
};
|
|
2549
3192
|
const escapeAll = () => {
|
|
2550
3193
|
for (const x of args)
|
|
2551
|
-
this.sink(x, `argument of ${path} at ${
|
|
3194
|
+
this.sink(x, `argument of ${path} at ${this.loc(site)}`);
|
|
2552
3195
|
this.add(dst, this.top);
|
|
2553
3196
|
};
|
|
2554
3197
|
// Methods of builtin receivers.
|
|
@@ -2572,6 +3215,8 @@ class Analyzer {
|
|
|
2572
3215
|
case "pop":
|
|
2573
3216
|
case "shift":
|
|
2574
3217
|
case "at":
|
|
3218
|
+
if (method !== "at")
|
|
3219
|
+
this.unsafeArrays.add(recv);
|
|
2575
3220
|
this.edge(el, dst);
|
|
2576
3221
|
this.add(dst, this.prim("undefined"));
|
|
2577
3222
|
return;
|
|
@@ -2625,6 +3270,8 @@ class Analyzer {
|
|
|
2625
3270
|
case "toSorted":
|
|
2626
3271
|
case "toReversed":
|
|
2627
3272
|
case "flat": {
|
|
3273
|
+
if (method === "splice")
|
|
3274
|
+
this.unsafeArrays.add(recv);
|
|
2628
3275
|
if (method === "filter")
|
|
2629
3276
|
callback(0, [el, num, recvN], null);
|
|
2630
3277
|
if (method === "sort" || method === "toSorted")
|
|
@@ -2679,7 +3326,7 @@ class Analyzer {
|
|
|
2679
3326
|
return;
|
|
2680
3327
|
}
|
|
2681
3328
|
escapeAll();
|
|
2682
|
-
this.escape(recv, `array.${method} at ${
|
|
3329
|
+
this.escape(recv, `array.${method} at ${this.loc(site)}`);
|
|
2683
3330
|
return;
|
|
2684
3331
|
}
|
|
2685
3332
|
if (path.startsWith("string.") || path.startsWith("number.") || path.startsWith("boolean.")) {
|
|
@@ -2705,8 +3352,10 @@ class Analyzer {
|
|
|
2705
3352
|
if (method === "test")
|
|
2706
3353
|
prim("boolean");
|
|
2707
3354
|
else if (method === "exec") {
|
|
3355
|
+
// The match and its capture groups; a group that did not take part is undefined.
|
|
2708
3356
|
const out = this.syntheticArray(site, "exec");
|
|
2709
3357
|
this.add(this.element(out), this.prim("string"));
|
|
3358
|
+
this.add(this.element(out), this.prim("undefined"));
|
|
2710
3359
|
this.add(dst, out);
|
|
2711
3360
|
prim("null");
|
|
2712
3361
|
}
|
|
@@ -2715,7 +3364,7 @@ class Analyzer {
|
|
|
2715
3364
|
return;
|
|
2716
3365
|
}
|
|
2717
3366
|
if (path.startsWith("promise.")) {
|
|
2718
|
-
const out = this.promiseAtom(site,
|
|
3367
|
+
const out = this.promiseAtom(site, this.loc(site));
|
|
2719
3368
|
const value = this.field(recv, "value");
|
|
2720
3369
|
const ret = this.newNode();
|
|
2721
3370
|
if (method === "then") {
|
|
@@ -2790,7 +3439,7 @@ class Analyzer {
|
|
|
2790
3439
|
for (const p of info.params)
|
|
2791
3440
|
this.add(p, this.top);
|
|
2792
3441
|
for (const x of args.slice(1))
|
|
2793
|
-
this.sink(x, `bound argument at ${
|
|
3442
|
+
this.sink(x, `bound argument at ${this.loc(site)}`);
|
|
2794
3443
|
}
|
|
2795
3444
|
this.add(dst, recv);
|
|
2796
3445
|
return;
|
|
@@ -2886,12 +3535,13 @@ class Analyzer {
|
|
|
2886
3535
|
return;
|
|
2887
3536
|
case "Object.assign": {
|
|
2888
3537
|
this.ops.push({ kind: "assign", recv: arg(0), name: null, node: site });
|
|
3538
|
+
this.prototypeWrite(arg(0), null);
|
|
2889
3539
|
this.on(arg(0), (t) => {
|
|
2890
3540
|
for (const s of args.slice(1))
|
|
2891
3541
|
this.copyFields(s, t, site);
|
|
2892
3542
|
if (t.kind === "top")
|
|
2893
3543
|
for (const s of args.slice(1))
|
|
2894
|
-
this.sink(s, `Object.assign into ⊤ at ${
|
|
3544
|
+
this.sink(s, `Object.assign into ⊤ at ${this.loc(site)}`);
|
|
2895
3545
|
});
|
|
2896
3546
|
this.edge(arg(0), dst);
|
|
2897
3547
|
return;
|
|
@@ -2900,29 +3550,35 @@ class Analyzer {
|
|
|
2900
3550
|
case "Object.defineProperties":
|
|
2901
3551
|
case "Reflect.defineProperty":
|
|
2902
3552
|
this.ops.push({ kind: "defineProperty", recv: arg(0), name: null, node: site });
|
|
2903
|
-
this.
|
|
2904
|
-
this.sink(arg(
|
|
3553
|
+
this.prototypeWrite(arg(0), path === "Object.defineProperties" ? null : literalKey(site, 1));
|
|
3554
|
+
this.sink(arg(2), `property descriptor at ${this.loc(site)}`);
|
|
3555
|
+
this.sink(arg(1), `property descriptor at ${this.loc(site)}`);
|
|
2905
3556
|
this.edge(arg(0), dst);
|
|
2906
3557
|
return;
|
|
2907
3558
|
case "Object.setPrototypeOf":
|
|
2908
3559
|
case "Reflect.setPrototypeOf":
|
|
2909
3560
|
this.ops.push({ kind: "setPrototypeOf", recv: arg(0), name: null, node: site });
|
|
2910
|
-
this.
|
|
3561
|
+
this.prototypeWrite(arg(0), null);
|
|
3562
|
+
this.sink(arg(1), `prototype at ${this.loc(site)}`);
|
|
2911
3563
|
this.edge(arg(0), dst);
|
|
2912
3564
|
return;
|
|
2913
3565
|
case "Object.create": {
|
|
2914
3566
|
const d = this.atoms.intern(`dict:${this.nodeKey(site)}`, () => ({
|
|
2915
3567
|
kind: "dictionary",
|
|
2916
|
-
label: `Object.create@${
|
|
3568
|
+
label: `Object.create@${this.loc(site)}`,
|
|
2917
3569
|
node: site,
|
|
2918
3570
|
}));
|
|
3571
|
+
// Its members are inherited from the prototype argument.
|
|
3572
|
+
this.edge(arg(0), this.dictProto(d));
|
|
3573
|
+
if (args[1] !== undefined)
|
|
3574
|
+
this.sink(args[1], `property descriptors at ${locLabel(site)}`);
|
|
2919
3575
|
this.add(dst, d);
|
|
2920
3576
|
return;
|
|
2921
3577
|
}
|
|
2922
3578
|
case "Object.fromEntries": {
|
|
2923
3579
|
const d = this.atoms.intern(`dict:${this.nodeKey(site)}`, () => ({
|
|
2924
3580
|
kind: "dictionary",
|
|
2925
|
-
label: `fromEntries@${
|
|
3581
|
+
label: `fromEntries@${this.loc(site)}`,
|
|
2926
3582
|
node: site,
|
|
2927
3583
|
}));
|
|
2928
3584
|
const pairs = this.newNode();
|
|
@@ -2970,7 +3626,7 @@ class Analyzer {
|
|
|
2970
3626
|
if (f.kind === "function")
|
|
2971
3627
|
this.callFunction(this.infoOfAtom(f), revived, [this.constNode(this.prim("string")), revived], false, revived, site);
|
|
2972
3628
|
else if (f.kind === "top")
|
|
2973
|
-
this.sink(revived, `JSON.parse reviver at ${
|
|
3629
|
+
this.sink(revived, `JSON.parse reviver at ${this.loc(site)}`);
|
|
2974
3630
|
});
|
|
2975
3631
|
this.edge(revived, dst);
|
|
2976
3632
|
return;
|
|
@@ -2990,18 +3646,16 @@ class Analyzer {
|
|
|
2990
3646
|
if (f.kind === "function")
|
|
2991
3647
|
this.callFunction(this.infoOfAtom(f), serialized, [key, serialized], false, serialized, site);
|
|
2992
3648
|
else if (f.kind === "top")
|
|
2993
|
-
this.sink(serialized, `JSON.stringify replacer at ${
|
|
3649
|
+
this.sink(serialized, `JSON.stringify replacer at ${this.loc(site)}`);
|
|
2994
3650
|
});
|
|
2995
3651
|
prim("string");
|
|
2996
3652
|
prim("undefined");
|
|
2997
3653
|
return;
|
|
2998
3654
|
}
|
|
2999
3655
|
case "Reflect.deleteProperty": {
|
|
3000
|
-
const
|
|
3001
|
-
const name = key !== undefined && (ts.isStringLiteral(key) || ts.isNoSubstitutionTemplateLiteral(key))
|
|
3002
|
-
? key.text
|
|
3003
|
-
: null;
|
|
3656
|
+
const name = literalKey(site, 1);
|
|
3004
3657
|
this.ops.push({ kind: "delete", recv: arg(0), name, node: site });
|
|
3658
|
+
this.prototypeWrite(arg(0), name);
|
|
3005
3659
|
prim("boolean");
|
|
3006
3660
|
return;
|
|
3007
3661
|
}
|
|
@@ -3019,7 +3673,7 @@ class Analyzer {
|
|
|
3019
3673
|
if (c.kind === "builtin" && c.path === "Proxy")
|
|
3020
3674
|
this.ops.push({ kind: "proxy", recv: listed, name: null, node: site });
|
|
3021
3675
|
});
|
|
3022
|
-
this.sink(listed, `argument of ${path} at ${
|
|
3676
|
+
this.sink(listed, `argument of ${path} at ${this.loc(site)}`);
|
|
3023
3677
|
escapeAll();
|
|
3024
3678
|
return;
|
|
3025
3679
|
}
|
|
@@ -3048,7 +3702,7 @@ class Analyzer {
|
|
|
3048
3702
|
prim("bigint");
|
|
3049
3703
|
return;
|
|
3050
3704
|
case "Promise.resolve": {
|
|
3051
|
-
const p = this.promiseAtom(site,
|
|
3705
|
+
const p = this.promiseAtom(site, this.loc(site));
|
|
3052
3706
|
if (args[0] !== undefined)
|
|
3053
3707
|
this.awaitInto(args[0], this.field(p, "value"));
|
|
3054
3708
|
else
|
|
@@ -3057,17 +3711,17 @@ class Analyzer {
|
|
|
3057
3711
|
return;
|
|
3058
3712
|
}
|
|
3059
3713
|
case "Promise.reject": {
|
|
3060
|
-
const p = this.promiseAtom(site,
|
|
3714
|
+
const p = this.promiseAtom(site, this.loc(site));
|
|
3061
3715
|
this.add(dst, p);
|
|
3062
3716
|
if (args[0] !== undefined)
|
|
3063
|
-
this.sink(args[0], `rejection at ${
|
|
3717
|
+
this.sink(args[0], `rejection at ${this.loc(site)}`);
|
|
3064
3718
|
return;
|
|
3065
3719
|
}
|
|
3066
3720
|
case "Promise.all":
|
|
3067
3721
|
case "Promise.allSettled":
|
|
3068
3722
|
case "Promise.race":
|
|
3069
3723
|
case "Promise.any": {
|
|
3070
|
-
const p = this.promiseAtom(site,
|
|
3724
|
+
const p = this.promiseAtom(site, this.loc(site));
|
|
3071
3725
|
const items = this.newNode();
|
|
3072
3726
|
if (args[0] !== undefined)
|
|
3073
3727
|
this.iterateInto(args[0], items, site);
|
|
@@ -3085,7 +3739,7 @@ class Analyzer {
|
|
|
3085
3739
|
}
|
|
3086
3740
|
case "promise.resolver":
|
|
3087
3741
|
for (const x of args)
|
|
3088
|
-
this.sink(x, `promise resolution at ${
|
|
3742
|
+
this.sink(x, `promise resolution at ${this.loc(site)}`);
|
|
3089
3743
|
return;
|
|
3090
3744
|
}
|
|
3091
3745
|
if (path.startsWith("console.")) {
|
|
@@ -3107,6 +3761,163 @@ class Analyzer {
|
|
|
3107
3761
|
void recvNode;
|
|
3108
3762
|
escapeAll();
|
|
3109
3763
|
}
|
|
3764
|
+
/** Whether an index access `x[i]` reads inside the bounds of `x` on
|
|
3765
|
+
* every evaluation: an enclosing `for (let i = <n ≥ 0>; i < x.length;
|
|
3766
|
+
* i++ | ++i | i += <n > 0>)` whose body assigns neither `i` nor `x`.
|
|
3767
|
+
* (The array's own length may still shrink or have holes: unsafeArrays.) */
|
|
3768
|
+
indexInBounds(site) {
|
|
3769
|
+
if (!ts.isElementAccessExpression(site) || site.questionDotToken !== undefined)
|
|
3770
|
+
return false;
|
|
3771
|
+
const memo = this.boundsMemo.get(site);
|
|
3772
|
+
if (memo !== undefined)
|
|
3773
|
+
return memo;
|
|
3774
|
+
const out = this.indexInBoundsUncached(site);
|
|
3775
|
+
this.boundsMemo.set(site, out);
|
|
3776
|
+
return out;
|
|
3777
|
+
}
|
|
3778
|
+
indexInBoundsUncached(site) {
|
|
3779
|
+
const obj = unparen(site.expression);
|
|
3780
|
+
const key = unparen(site.argumentExpression);
|
|
3781
|
+
if (!ts.isIdentifier(obj) || !ts.isIdentifier(key))
|
|
3782
|
+
return false;
|
|
3783
|
+
const objDecl = this.resolve(obj);
|
|
3784
|
+
const keyDecl = this.resolve(key);
|
|
3785
|
+
if (objDecl === undefined || keyDecl === undefined)
|
|
3786
|
+
return false;
|
|
3787
|
+
const names = (id, decl) => ts.isIdentifier(id) && this.resolve(id) === decl;
|
|
3788
|
+
for (let n = site.parent; n !== undefined; n = n.parent) {
|
|
3789
|
+
if (ts.isFunctionLike(n) || ts.isSourceFile(n))
|
|
3790
|
+
return false;
|
|
3791
|
+
if (!ts.isForStatement(n) || n.statement === undefined)
|
|
3792
|
+
continue;
|
|
3793
|
+
if (!(site.pos >= n.statement.pos && site.end <= n.statement.end))
|
|
3794
|
+
continue;
|
|
3795
|
+
const cond = n.condition !== undefined ? unparen(n.condition) : undefined;
|
|
3796
|
+
if (cond === undefined ||
|
|
3797
|
+
!ts.isBinaryExpression(cond) ||
|
|
3798
|
+
cond.operatorToken.kind !== ts.SyntaxKind.LessThanToken ||
|
|
3799
|
+
!names(unparen(cond.left), keyDecl))
|
|
3800
|
+
continue;
|
|
3801
|
+
const bound = unparen(cond.right);
|
|
3802
|
+
if (!ts.isPropertyAccessExpression(bound) ||
|
|
3803
|
+
bound.name.text !== "length" ||
|
|
3804
|
+
!names(unparen(bound.expression), objDecl))
|
|
3805
|
+
continue;
|
|
3806
|
+
// The index starts at a non-negative integer literal ...
|
|
3807
|
+
const init = n.initializer;
|
|
3808
|
+
let start;
|
|
3809
|
+
// (declared by the loop, so only the loop's own code can write it)
|
|
3810
|
+
if (init !== undefined &&
|
|
3811
|
+
ts.isVariableDeclarationList(init) &&
|
|
3812
|
+
(init.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0) {
|
|
3813
|
+
const d = init.declarations.nodes.find((x) => x === keyDecl);
|
|
3814
|
+
start = d !== undefined ? d.initializer : undefined;
|
|
3815
|
+
}
|
|
3816
|
+
if (start === undefined || !nonNegativeIntegerLiteral(start))
|
|
3817
|
+
continue;
|
|
3818
|
+
if (!this.neverReassigned(objDecl))
|
|
3819
|
+
continue;
|
|
3820
|
+
// ... and only grows by integers,
|
|
3821
|
+
const inc = n.incrementor !== undefined ? unparen(n.incrementor) : undefined;
|
|
3822
|
+
const grows = inc !== undefined &&
|
|
3823
|
+
(((ts.isPostfixUnaryExpression(inc) || ts.isPrefixUnaryExpression(inc)) &&
|
|
3824
|
+
inc.operator === ts.SyntaxKind.PlusPlusToken &&
|
|
3825
|
+
names(unparen(inc.operand), keyDecl)) ||
|
|
3826
|
+
(ts.isBinaryExpression(inc) &&
|
|
3827
|
+
inc.operatorToken.kind === ts.SyntaxKind.PlusEqualsToken &&
|
|
3828
|
+
names(unparen(inc.left), keyDecl) &&
|
|
3829
|
+
positiveIntegerLiteral(inc.right)));
|
|
3830
|
+
if (!grows)
|
|
3831
|
+
continue;
|
|
3832
|
+
// ... and the body writes neither the index nor the array binding.
|
|
3833
|
+
let written = false;
|
|
3834
|
+
const visit = (m) => {
|
|
3835
|
+
if (written)
|
|
3836
|
+
return;
|
|
3837
|
+
if (ts.isBinaryExpression(m) &&
|
|
3838
|
+
m.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
3839
|
+
m.operatorToken.kind <= ts.SyntaxKind.LastAssignment &&
|
|
3840
|
+
(names(unparen(m.left), keyDecl) || names(unparen(m.left), objDecl)))
|
|
3841
|
+
written = true;
|
|
3842
|
+
else if ((ts.isPostfixUnaryExpression(m) || ts.isPrefixUnaryExpression(m)) &&
|
|
3843
|
+
(m.operator === ts.SyntaxKind.PlusPlusToken ||
|
|
3844
|
+
m.operator === ts.SyntaxKind.MinusMinusToken) &&
|
|
3845
|
+
(names(unparen(m.operand), keyDecl) || names(unparen(m.operand), objDecl)))
|
|
3846
|
+
written = true;
|
|
3847
|
+
ts.forEachChild(m, (c) => {
|
|
3848
|
+
visit(c);
|
|
3849
|
+
return undefined;
|
|
3850
|
+
});
|
|
3851
|
+
};
|
|
3852
|
+
visit(n.statement);
|
|
3853
|
+
if (!written)
|
|
3854
|
+
return true;
|
|
3855
|
+
}
|
|
3856
|
+
return false;
|
|
3857
|
+
}
|
|
3858
|
+
reassignMemo = new Map();
|
|
3859
|
+
/** Whether a binding keeps the value it is declared with: a `const`, or a
|
|
3860
|
+
* parameter or variable that no code in its scope assigns. */
|
|
3861
|
+
neverReassigned(decl) {
|
|
3862
|
+
const memo = this.reassignMemo.get(decl);
|
|
3863
|
+
if (memo !== undefined)
|
|
3864
|
+
return memo;
|
|
3865
|
+
let out = false;
|
|
3866
|
+
if (ts.isVariableDeclaration(decl) || ts.isParameter(decl)) {
|
|
3867
|
+
const list = decl.parent;
|
|
3868
|
+
if (ts.isVariableDeclaration(decl) &&
|
|
3869
|
+
list !== undefined &&
|
|
3870
|
+
ts.isVariableDeclarationList(list) &&
|
|
3871
|
+
(list.flags & ts.NodeFlags.Const) !== 0)
|
|
3872
|
+
out = true;
|
|
3873
|
+
else {
|
|
3874
|
+
let scope = decl.parent;
|
|
3875
|
+
while (scope !== undefined && !ts.isFunctionLike(scope) && !ts.isSourceFile(scope))
|
|
3876
|
+
scope = scope.parent;
|
|
3877
|
+
if (scope !== undefined && ts.isIdentifier(decl.name)) {
|
|
3878
|
+
const text = decl.name.text;
|
|
3879
|
+
let written = false;
|
|
3880
|
+
const target = (e) => {
|
|
3881
|
+
const u = unparen(e);
|
|
3882
|
+
return ts.isIdentifier(u) && u.text === text && this.resolve(u) === decl;
|
|
3883
|
+
};
|
|
3884
|
+
const visit = (m) => {
|
|
3885
|
+
if (written)
|
|
3886
|
+
return;
|
|
3887
|
+
if ((ts.isBinaryExpression(m) &&
|
|
3888
|
+
m.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
3889
|
+
m.operatorToken.kind <= ts.SyntaxKind.LastAssignment &&
|
|
3890
|
+
target(m.left)) ||
|
|
3891
|
+
((ts.isPostfixUnaryExpression(m) || ts.isPrefixUnaryExpression(m)) &&
|
|
3892
|
+
(m.operator === ts.SyntaxKind.PlusPlusToken ||
|
|
3893
|
+
m.operator === ts.SyntaxKind.MinusMinusToken) &&
|
|
3894
|
+
target(m.operand)))
|
|
3895
|
+
written = true;
|
|
3896
|
+
ts.forEachChild(m, (c) => {
|
|
3897
|
+
visit(c);
|
|
3898
|
+
return undefined;
|
|
3899
|
+
});
|
|
3900
|
+
};
|
|
3901
|
+
visit(scope);
|
|
3902
|
+
out = !written;
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
this.reassignMemo.set(decl, out);
|
|
3907
|
+
return out;
|
|
3908
|
+
}
|
|
3909
|
+
/** The result of arithmetic over the operands: a number, or a bigint
|
|
3910
|
+
* where an operand may be one. */
|
|
3911
|
+
numericResult(operands) {
|
|
3912
|
+
const n = this.newNode();
|
|
3913
|
+
this.add(n, this.prim("number"));
|
|
3914
|
+
for (const o of operands)
|
|
3915
|
+
this.on(o, (a) => {
|
|
3916
|
+
if (a.kind === "top" || (a.kind === "prim" && a.label === "bigint"))
|
|
3917
|
+
this.add(n, this.prim("bigint"));
|
|
3918
|
+
});
|
|
3919
|
+
return n;
|
|
3920
|
+
}
|
|
3110
3921
|
/** Re-run deferred field copies until nothing new flows. */
|
|
3111
3922
|
finish() {
|
|
3112
3923
|
for (;;) {
|
|
@@ -3114,11 +3925,59 @@ class Analyzer {
|
|
|
3114
3925
|
for (const c of this.lateCopies)
|
|
3115
3926
|
c();
|
|
3116
3927
|
this.solve();
|
|
3928
|
+
for (const o of this.ops)
|
|
3929
|
+
if (o.kind === "delete" || o.kind === "lengthWrite")
|
|
3930
|
+
for (const a of this.nodes[o.recv].atoms)
|
|
3931
|
+
if (a.kind === "array")
|
|
3932
|
+
this.unsafeArrays.add(a);
|
|
3933
|
+
for (const g of this.guardedIndexReads)
|
|
3934
|
+
if (!g.done && this.unsafeArrays.has(g.recv)) {
|
|
3935
|
+
g.done = true;
|
|
3936
|
+
this.add(g.dst, this.prim("undefined"));
|
|
3937
|
+
}
|
|
3938
|
+
this.solve();
|
|
3939
|
+
// A condition with no values at the fixpoint is one the analysis
|
|
3940
|
+
// could not evaluate: walk both of its branches.
|
|
3941
|
+
let walked = false;
|
|
3942
|
+
for (const p of this.pendingIfs) {
|
|
3943
|
+
if (this.nodes[p.cond].atoms.size > 0)
|
|
3944
|
+
continue;
|
|
3945
|
+
if (!p.thenDone) {
|
|
3946
|
+
this.walkBranch(p, "then");
|
|
3947
|
+
walked = true;
|
|
3948
|
+
}
|
|
3949
|
+
if (!p.elseDone) {
|
|
3950
|
+
this.walkBranch(p, "else");
|
|
3951
|
+
walked = true;
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
if (walked)
|
|
3955
|
+
continue;
|
|
3117
3956
|
if (this.steps === before || this.budgetExceeded)
|
|
3118
3957
|
return;
|
|
3119
3958
|
}
|
|
3120
3959
|
}
|
|
3121
3960
|
}
|
|
3961
|
+
function nonNegativeIntegerLiteral(e) {
|
|
3962
|
+
const u = unparen(e);
|
|
3963
|
+
return ts.isNumericLiteral(u) && Number.isInteger(Number(u.text)) && Number(u.text) >= 0;
|
|
3964
|
+
}
|
|
3965
|
+
function positiveIntegerLiteral(e) {
|
|
3966
|
+
const u = unparen(e);
|
|
3967
|
+
return ts.isNumericLiteral(u) && Number.isInteger(Number(u.text)) && Number(u.text) > 0;
|
|
3968
|
+
}
|
|
3969
|
+
/** `x[x.length] = v`: a store at the end, which appends without a hole. */
|
|
3970
|
+
function isAppendIndex(site) {
|
|
3971
|
+
if (!ts.isElementAccessExpression(site))
|
|
3972
|
+
return false;
|
|
3973
|
+
const obj = unparen(site.expression);
|
|
3974
|
+
const key = unparen(site.argumentExpression);
|
|
3975
|
+
return (ts.isIdentifier(obj) &&
|
|
3976
|
+
ts.isPropertyAccessExpression(key) &&
|
|
3977
|
+
key.name.text === "length" &&
|
|
3978
|
+
ts.isIdentifier(unparen(key.expression)) &&
|
|
3979
|
+
unparen(key.expression).text === obj.text);
|
|
3980
|
+
}
|
|
3122
3981
|
/** The export name of a CommonJS export declaration the checker resolves
|
|
3123
3982
|
* bindings to: a member of the `module.exports` literal, or the target of
|
|
3124
3983
|
* `exports.name =` / `module.exports.name =`. */
|
|
@@ -3135,4 +3994,30 @@ function cjsExportName(decl) {
|
|
|
3135
3994
|
return decl.left.name.text;
|
|
3136
3995
|
return null;
|
|
3137
3996
|
}
|
|
3997
|
+
/** The string literal a call passes as argument `i`, or null. */
|
|
3998
|
+
function literalKey(site, i) {
|
|
3999
|
+
const key = ts.isCallExpression(site) ? list(site.arguments)[i] : undefined;
|
|
4000
|
+
if (key === undefined)
|
|
4001
|
+
return null;
|
|
4002
|
+
const k = unparen(key);
|
|
4003
|
+
return ts.isStringLiteral(k) || ts.isNoSubstitutionTemplateLiteral(k) ? k.text : null;
|
|
4004
|
+
}
|
|
4005
|
+
/** Whether a value of the atom may be truthy (only `null`, `undefined` and
|
|
4006
|
+
* the literal `false` never are; ⊤ may be anything). */
|
|
4007
|
+
function mayBeTruthy(a) {
|
|
4008
|
+
if (a.kind !== "prim")
|
|
4009
|
+
return true;
|
|
4010
|
+
if (a.label === "null" || a.label === "undefined")
|
|
4011
|
+
return false;
|
|
4012
|
+
return a.literal !== false;
|
|
4013
|
+
}
|
|
4014
|
+
/** Whether a value of the atom may be falsy (objects, arrays, functions,
|
|
4015
|
+
* classes, promises and collections never are). */
|
|
4016
|
+
function mayBeFalsy(a) {
|
|
4017
|
+
if (a.kind === "top")
|
|
4018
|
+
return true;
|
|
4019
|
+
if (a.kind !== "prim")
|
|
4020
|
+
return false;
|
|
4021
|
+
return a.literal !== true;
|
|
4022
|
+
}
|
|
3138
4023
|
//# sourceMappingURL=analyze.js.map
|