@scriptc/compiler 0.4.7 → 0.4.8
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/child_process.d.ts +71 -22
- package/ambient/node-fallback/crypto.d.ts +15 -7
- package/ambient/node-fallback/events.d.ts +23 -5
- package/ambient/node-fallback/fs.d.ts +3 -2
- package/ambient/node-fallback/http.d.ts +23 -17
- package/ambient/node-fallback/https.d.ts +5 -2
- package/ambient/node-fallback/net.d.ts +6 -0
- package/ambient/node-fallback/os.d.ts +11 -1
- package/ambient/node-fallback/path-posix.d.ts +6 -0
- package/ambient/node-fallback/path-win32.d.ts +5 -0
- package/ambient/node-fallback/path.d.ts +2 -0
- package/ambient/node-fallback/zlib.d.ts +31 -2
- package/ambient/scriptc-node-fallback.d.ts +37 -7
- package/ambient/scriptc.d.ts +7 -2
- package/dist/backend/executable-features.js +11 -3
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/library-pack.d.ts +6 -0
- package/dist/backend/library-pack.js +17 -6
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/library-pack.test.d.ts +1 -0
- package/dist/backend/library-pack.test.js +28 -0
- package/dist/backend/library-pack.test.js.map +1 -0
- package/dist/backend/linker.d.ts +9 -2
- package/dist/backend/linker.js +190 -32
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/lld.d.ts +8 -4
- package/dist/backend/lld.js +19 -13
- package/dist/backend/lld.js.map +1 -1
- package/dist/backend/lld.test.js +3 -1
- package/dist/backend/lld.test.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +15 -2
- package/dist/backend/llvm/alloc.js +172 -36
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +69 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/arenas.d.ts +17 -4
- package/dist/backend/llvm/arenas.js +105 -10
- package/dist/backend/llvm/arenas.js.map +1 -1
- package/dist/backend/llvm/arenas.test.js +229 -0
- package/dist/backend/llvm/arenas.test.js.map +1 -1
- package/dist/backend/llvm/bytes-alias.js +10 -1
- package/dist/backend/llvm/bytes-alias.js.map +1 -1
- package/dist/backend/llvm/bytes-headers.js +6 -0
- package/dist/backend/llvm/bytes-headers.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.test.js +25 -0
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.js +10 -0
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +16 -9
- package/dist/backend/llvm/classes.js +142 -37
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +42 -0
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/cpu-dispatch.d.ts +15 -5
- package/dist/backend/llvm/cpu-dispatch.js +31 -7
- package/dist/backend/llvm/cpu-dispatch.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +12 -3
- package/dist/backend/llvm/dyn.js +31 -7
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +67 -4
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-module.js +90 -39
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emit-module.test.d.ts +1 -0
- package/dist/backend/llvm/emit-module.test.js +52 -0
- package/dist/backend/llvm/emit-module.test.js.map +1 -0
- package/dist/backend/llvm/emit-statements.js +99 -15
- package/dist/backend/llvm/emit-statements.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +113 -8
- package/dist/backend/llvm/emitter.js +438 -67
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +31 -3
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +19 -1
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +16 -1
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +18 -2
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +31 -10
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +31 -3
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +1 -1
- package/dist/backend/llvm/expr-records.js +124 -56
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +17 -0
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/js-groups.d.ts +21 -0
- package/dist/backend/llvm/js-groups.js +277 -0
- package/dist/backend/llvm/js-groups.js.map +1 -0
- package/dist/backend/llvm/js-ic.d.ts +19 -1
- package/dist/backend/llvm/js-ic.js +96 -23
- package/dist/backend/llvm/js-ic.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +132 -1
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +33 -6
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +44 -3
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +69 -2
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +32 -0
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
- package/dist/backend/llvm/loop-state.js +7 -2
- package/dist/backend/llvm/loop-state.js.map +1 -1
- package/dist/backend/llvm/map-entry-fusion.d.ts +8 -0
- package/dist/backend/llvm/map-entry-fusion.js +3 -3
- package/dist/backend/llvm/map-entry-fusion.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.test.js +6 -6
- package/dist/backend/llvm/map-number-lookup.test.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.js +7 -6
- package/dist/backend/llvm/nullable-unions.js.map +1 -1
- package/dist/backend/llvm/nullable-unions.test.js +4 -1
- package/dist/backend/llvm/nullable-unions.test.js.map +1 -1
- package/dist/backend/llvm/receivers.js +3 -0
- package/dist/backend/llvm/receivers.js.map +1 -1
- package/dist/backend/llvm/record-entry-fusion.d.ts +32 -0
- package/dist/backend/llvm/record-entry-fusion.js +217 -0
- package/dist/backend/llvm/record-entry-fusion.js.map +1 -0
- package/dist/backend/llvm/record-results.d.ts +5 -2
- package/dist/backend/llvm/record-results.js +13 -12
- package/dist/backend/llvm/record-results.js.map +1 -1
- package/dist/backend/llvm/record-views.js +12 -6
- package/dist/backend/llvm/record-views.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +1 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.js +3 -0
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/region-ir.js +1 -0
- package/dist/backend/llvm/region-ir.js.map +1 -1
- package/dist/backend/llvm/region-sites.d.ts +18 -0
- package/dist/backend/llvm/region-sites.js +79 -1
- package/dist/backend/llvm/region-sites.js.map +1 -1
- package/dist/backend/llvm/runtime-registries.test.js +53 -6
- package/dist/backend/llvm/runtime-registries.test.js.map +1 -1
- package/dist/backend/llvm/serialized-ir-emission.test.js +3 -1
- package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +33 -3
- package/dist/backend/llvm/shapes.js +183 -13
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +1 -2
- package/dist/backend/llvm/stack-objects.js +8 -5
- package/dist/backend/llvm/stack-objects.js.map +1 -1
- package/dist/backend/llvm/walkers.d.ts +12 -0
- package/dist/backend/llvm/walkers.js +46 -2
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/may-throw.js +12 -2
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +13 -0
- package/dist/backend/may-throw.test.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +48 -8
- package/dist/backend/native/executable.js +55 -13
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/helper-identity-record.d.ts +11 -0
- package/dist/backend/native/helper-identity-record.js +76 -0
- package/dist/backend/native/helper-identity-record.js.map +1 -0
- package/dist/backend/native/helper-identity-record.test.d.ts +1 -0
- package/dist/backend/native/helper-identity-record.test.js +101 -0
- package/dist/backend/native/helper-identity-record.test.js.map +1 -0
- package/dist/backend/native/library.js +9 -1
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.js +4 -1
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native/vendor.d.ts +1 -1
- package/dist/backend/native/vendor.js +1 -1
- package/dist/backend/native/vendor.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +13 -10
- package/dist/backend/native-codegen-core.js +26 -13
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.js +27 -8
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +110 -14
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +37 -8
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/runtime-pack-core.d.ts +17 -2
- package/dist/backend/runtime-pack-core.js +18 -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-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +211 -2
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/tree-classes.d.ts +42 -0
- package/dist/backend/tree-classes.js +723 -0
- package/dist/backend/tree-classes.js.map +1 -0
- package/dist/backend/tree-classes.test.d.ts +1 -0
- package/dist/backend/tree-classes.test.js +338 -0
- package/dist/backend/tree-classes.test.js.map +1 -0
- package/dist/backend/vendor-archives.d.ts +5 -1
- package/dist/backend/vendor-archives.js +51 -7
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.d.ts +25 -4
- package/dist/backend/vendor-inputs.js +68 -4
- package/dist/backend/vendor-inputs.js.map +1 -1
- package/dist/backend/vendor-inputs.test.js +35 -1
- package/dist/backend/vendor-inputs.test.js.map +1 -1
- package/dist/backend/warm-cache.js +1 -1
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/compat/fetch-profile.js +2 -2
- package/dist/coverage/report.js +47 -0
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +1 -1
- package/dist/diagnostics/codes.d.ts +8 -0
- package/dist/diagnostics/codes.js +8 -0
- package/dist/diagnostics/codes.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +27 -9
- package/dist/diagnostics/diagnostic.js +60 -19
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +18 -0
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +21 -2
- package/dist/executable/executable-cache.js +21 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +123 -1
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +199 -248
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +200 -18
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +4 -0
- package/dist/frontend/builtin-modules.js +10 -0
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/early-errors.d.ts +12 -2
- package/dist/frontend/early-errors.js +535 -4
- package/dist/frontend/early-errors.js.map +1 -1
- package/dist/frontend/early-errors.test.js +165 -0
- package/dist/frontend/early-errors.test.js.map +1 -1
- package/dist/frontend/inferred-js-diagnostics.test.js +65 -0
- package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -1
- package/dist/frontend/jsx-opinion-sites.test.d.ts +1 -0
- package/dist/frontend/jsx-opinion-sites.test.js +86 -0
- package/dist/frontend/jsx-opinion-sites.test.js.map +1 -0
- package/dist/frontend/lib-exports.d.ts +23 -4
- package/dist/frontend/lib-exports.js +98 -26
- package/dist/frontend/lib-exports.js.map +1 -1
- package/dist/frontend/lowering/binding-analysis.js +21 -3
- package/dist/frontend/lowering/binding-analysis.js.map +1 -1
- package/dist/frontend/lowering/buffers.d.ts +8 -0
- package/dist/frontend/lowering/buffers.js +43 -0
- package/dist/frontend/lowering/buffers.js.map +1 -0
- package/dist/frontend/lowering/builtin-calls.js +4 -0
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtin-namespaces.d.ts +3 -2
- package/dist/frontend/lowering/builtin-namespaces.js +24 -3
- package/dist/frontend/lowering/builtin-namespaces.js.map +1 -1
- package/dist/frontend/lowering/builtin-statics.d.ts +24 -0
- package/dist/frontend/lowering/builtin-statics.js +407 -0
- package/dist/frontend/lowering/builtin-statics.js.map +1 -0
- package/dist/frontend/lowering/builtins/arguments.d.ts +4 -0
- package/dist/frontend/lowering/builtins/arguments.js +12 -0
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/atomics.d.ts +6 -1
- package/dist/frontend/lowering/builtins/atomics.js +87 -1
- package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-methods.js +2 -2
- package/dist/frontend/lowering/builtins/child-process-methods.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process-sync.d.ts +13 -0
- package/dist/frontend/lowering/builtins/child-process-sync.js +1 -13
- package/dist/frontend/lowering/builtins/child-process-sync.js.map +1 -1
- package/dist/frontend/lowering/builtins/child-process.d.ts +10 -4
- package/dist/frontend/lowering/builtins/child-process.js +560 -27
- package/dist/frontend/lowering/builtins/child-process.js.map +1 -1
- package/dist/frontend/lowering/builtins/compression.d.ts +2 -2
- package/dist/frontend/lowering/builtins/compression.js +41 -21
- package/dist/frontend/lowering/builtins/compression.js.map +1 -1
- package/dist/frontend/lowering/builtins/constants.js +7 -2
- package/dist/frontend/lowering/builtins/constants.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +1 -0
- package/dist/frontend/lowering/builtins/filesystem-calls.js +28 -2
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +4 -0
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +3 -1
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/numbers.d.ts +4 -1
- package/dist/frontend/lowering/builtins/numbers.js +10 -2
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +6 -3
- package/dist/frontend/lowering/builtins/operating-system.js +96 -16
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +2 -2
- package/dist/frontend/lowering/builtins/process.js +103 -8
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.js +169 -8
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/properties.js +6 -2
- package/dist/frontend/lowering/builtins/properties.js.map +1 -1
- package/dist/frontend/lowering/builtins/readline.d.ts +6 -4
- package/dist/frontend/lowering/builtins/readline.js +180 -36
- package/dist/frontend/lowering/builtins/readline.js.map +1 -1
- package/dist/frontend/lowering/builtins/url.js +35 -12
- package/dist/frontend/lowering/builtins/url.js.map +1 -1
- package/dist/frontend/lowering/builtins/webassembly.js +2 -0
- package/dist/frontend/lowering/builtins/webassembly.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.d.ts +10 -0
- package/dist/frontend/lowering/call-arguments.js +37 -2
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +10 -0
- package/dist/frontend/lowering/call-signatures.js +103 -0
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +14 -2
- package/dist/frontend/lowering/class-construction.js +99 -5
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +9 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +1283 -1030
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +158 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.js +20 -15
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
- package/dist/frontend/lowering/class-runtime-statics.js +20 -1
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-unions.js +21 -4
- package/dist/frontend/lowering/class-unions.js.map +1 -1
- package/dist/frontend/lowering/coercions/function-adapters.js +9 -0
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/state.d.ts +8 -0
- package/dist/frontend/lowering/coercions/state.js +17 -0
- package/dist/frontend/lowering/coercions/state.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +20 -5
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +10 -1
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +2 -1
- package/dist/frontend/lowering/coercions/unions.js +54 -10
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/constructor-returns.d.ts +23 -2
- package/dist/frontend/lowering/constructor-returns.js +284 -58
- package/dist/frontend/lowering/constructor-returns.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +156 -62
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +21 -3
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-from-async.js +139 -3
- package/dist/frontend/lowering/containers/array-from-async.js.map +1 -1
- package/dist/frontend/lowering/containers/array-iteration.d.ts +14 -4
- package/dist/frontend/lowering/containers/array-iteration.js +24 -7
- package/dist/frontend/lowering/containers/array-iteration.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +14 -11
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +6 -0
- package/dist/frontend/lowering/containers/bytes.js +446 -86
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.d.ts +5 -0
- package/dist/frontend/lowering/containers/callback-arguments.js +21 -12
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-grouping.js +421 -2
- package/dist/frontend/lowering/containers/collection-grouping.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +52 -17
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/iterator-helpers.d.ts +23 -0
- package/dist/frontend/lowering/containers/iterator-helpers.js +176 -10
- package/dist/frontend/lowering/containers/iterator-helpers.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +5 -2
- package/dist/frontend/lowering/containers/string-and-regexp.js +45 -11
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/crypto-tables.d.ts +3 -3
- package/dist/frontend/lowering/crypto-tables.js +5 -5
- package/dist/frontend/lowering/dispatch-sites.js +3 -0
- package/dist/frontend/lowering/dispatch-sites.js.map +1 -1
- package/dist/frontend/lowering/divergences.d.ts +40 -0
- package/dist/frontend/lowering/divergences.js +239 -20
- package/dist/frontend/lowering/divergences.js.map +1 -1
- package/dist/frontend/lowering/effect-free.d.ts +12 -0
- package/dist/frontend/lowering/effect-free.js +44 -0
- package/dist/frontend/lowering/effect-free.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.d.ts +10 -0
- package/dist/frontend/lowering/expressions/array-literals.js +62 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +115 -5
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +151 -7
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.d.ts +15 -0
- package/dist/frontend/lowering/expressions/hosted-narrowing.js +54 -1
- package/dist/frontend/lowering/expressions/hosted-narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +31 -2
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/narrowing.d.ts +3 -0
- package/dist/frontend/lowering/expressions/narrowing.js +175 -22
- package/dist/frontend/lowering/expressions/narrowing.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +173 -11
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +5 -1
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.d.ts +8 -0
- package/dist/frontend/lowering/expressions/property-access.js +379 -109
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/relational.js +237 -7
- package/dist/frontend/lowering/expressions/relational.js.map +1 -1
- package/dist/frontend/lowering/expressions/typeof.js +8 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-fields.d.ts +20 -1
- package/dist/frontend/lowering/expressions/union-fields.js +103 -13
- package/dist/frontend/lowering/expressions/union-fields.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +74 -55
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +37 -10
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/general-streams.js +5 -0
- package/dist/frontend/lowering/general-streams.js.map +1 -1
- package/dist/frontend/lowering/generator-delegation.d.ts +15 -7
- package/dist/frontend/lowering/generator-delegation.js +301 -118
- package/dist/frontend/lowering/generator-delegation.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.d.ts +27 -1
- package/dist/frontend/lowering/generic-functions.js +432 -18
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/global-function-values.d.ts +25 -0
- package/dist/frontend/lowering/global-function-values.js +193 -0
- package/dist/frontend/lowering/global-function-values.js.map +1 -0
- package/dist/frontend/lowering/global-values.d.ts +6 -4
- package/dist/frontend/lowering/global-values.js +24 -10
- package/dist/frontend/lowering/global-values.js.map +1 -1
- package/dist/frontend/lowering/host-global-values.d.ts +31 -0
- package/dist/frontend/lowering/host-global-values.js +121 -0
- package/dist/frontend/lowering/host-global-values.js.map +1 -0
- package/dist/frontend/lowering/host-globals.d.ts +74 -0
- package/dist/frontend/lowering/host-globals.js +344 -0
- package/dist/frontend/lowering/host-globals.js.map +1 -0
- package/dist/frontend/lowering/http2-constants.js +1 -1
- package/dist/frontend/lowering/iterator-adapters.js +46 -17
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/iterator-prototype.d.ts +30 -0
- package/dist/frontend/lowering/iterator-prototype.js +160 -0
- package/dist/frontend/lowering/iterator-prototype.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.js +43 -22
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.test.js +1 -0
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +11 -3
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +30 -15
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +11 -0
- package/dist/frontend/lowering/lower-async-iteration.js +15 -0
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.js +11 -1
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +25 -0
- package/dist/frontend/lowering/lower-calls.js +929 -227
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.test.js +59 -16
- package/dist/frontend/lowering/lower-calls.test.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +20 -0
- package/dist/frontend/lowering/lower-classes.js +468 -44
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.d.ts +6 -2
- package/dist/frontend/lowering/lower-event-emitter.js +253 -83
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +1 -1
- package/dist/frontend/lowering/lower-exprs.js +71 -20
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +25 -6
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +57 -10
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-global-value.d.ts +6 -0
- package/dist/frontend/lowering/lower-global-value.js +14 -5
- package/dist/frontend/lowering/lower-global-value.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
- package/dist/frontend/lowering/lower-inspect.js +638 -64
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +48 -2
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +18 -0
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-node-island.js +16 -6
- package/dist/frontend/lowering/lower-node-island.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +303 -87
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.js +45 -0
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +14 -11
- package/dist/frontend/lowering/lower-stmts.js +270 -52
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-timers.js +110 -27
- package/dist/frontend/lowering/lower-timers.js.map +1 -1
- package/dist/frontend/lowering/lower-url.js +6 -3
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +227 -21
- package/dist/frontend/lowering/lowerer.js +651 -92
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +18 -0
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/lowering-facts.d.ts +110 -0
- package/dist/frontend/lowering/lowering-facts.js +323 -0
- package/dist/frontend/lowering/lowering-facts.js.map +1 -0
- package/dist/frontend/lowering/lowering-facts.test.d.ts +1 -0
- package/dist/frontend/lowering/lowering-facts.test.js +100 -0
- package/dist/frontend/lowering/lowering-facts.test.js.map +1 -0
- package/dist/frontend/lowering/nan-coded-reads.d.ts +27 -4
- package/dist/frontend/lowering/nan-coded-reads.js +112 -9
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.d.ts +4 -0
- package/dist/frontend/lowering/optional-arguments.js +26 -2
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/partial-assertions.d.ts +0 -3
- package/dist/frontend/lowering/partial-assertions.js +9 -15
- package/dist/frontend/lowering/partial-assertions.js.map +1 -1
- package/dist/frontend/lowering/primitive-throws.d.ts +100 -0
- package/dist/frontend/lowering/primitive-throws.js +241 -0
- package/dist/frontend/lowering/primitive-throws.js.map +1 -0
- package/dist/frontend/lowering/primitive-wrappers.js +1 -0
- package/dist/frontend/lowering/primitive-wrappers.js.map +1 -1
- package/dist/frontend/lowering/record-inherited.d.ts +17 -1
- package/dist/frontend/lowering/record-inherited.js +16 -2
- package/dist/frontend/lowering/record-inherited.js.map +1 -1
- package/dist/frontend/lowering/record-links.d.ts +73 -0
- package/dist/frontend/lowering/record-links.js +797 -0
- package/dist/frontend/lowering/record-links.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-provenance.d.ts +27 -7
- package/dist/frontend/lowering/runtime-optional-provenance.js +25 -11
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-report.d.ts +40 -0
- package/dist/frontend/lowering/runtime-optional-report.js +300 -0
- package/dist/frontend/lowering/runtime-optional-report.js.map +1 -0
- package/dist/frontend/lowering/scoped-type-memo.test.d.ts +1 -0
- package/dist/frontend/lowering/scoped-type-memo.test.js +86 -0
- package/dist/frontend/lowering/scoped-type-memo.test.js.map +1 -0
- package/dist/frontend/lowering/static-typeof.d.ts +3 -1
- package/dist/frontend/lowering/static-typeof.js +6 -1
- package/dist/frontend/lowering/static-typeof.js.map +1 -1
- package/dist/frontend/lowering/strict-mode.d.ts +1 -5
- package/dist/frontend/lowering/strict-mode.js +4 -30
- package/dist/frontend/lowering/strict-mode.js.map +1 -1
- package/dist/frontend/lowering/structural-instances.d.ts +7 -0
- package/dist/frontend/lowering/structural-instances.js +23 -0
- package/dist/frontend/lowering/structural-instances.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +15 -1
- package/dist/frontend/lowering/surfaces.js +78 -10
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/union-retag.d.ts +13 -1
- package/dist/frontend/lowering/union-retag.js +55 -1
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +51 -0
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/unit-journal.d.ts +8 -0
- package/dist/frontend/lowering/unit-journal.js +14 -0
- package/dist/frontend/lowering/unit-journal.js.map +1 -1
- package/dist/frontend/lowering/unit-journal.test.js +36 -1
- package/dist/frontend/lowering/unit-journal.test.js.map +1 -1
- package/dist/frontend/lowering/zlib-constants.js +3 -2
- package/dist/frontend/lowering/zlib-constants.js.map +1 -1
- package/dist/frontend/npm-static.js +78 -9
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.js +95 -2
- package/dist/frontend/npm-static.test.js.map +1 -1
- package/dist/frontend/pipeline.d.ts +5 -4
- package/dist/frontend/pipeline.js +94 -31
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +68 -11
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program.d.ts +62 -2
- package/dist/frontend/program.js +695 -422
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +37 -1
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/services-node.d.ts +7 -0
- package/dist/frontend/services-node.js +32 -1
- package/dist/frontend/services-node.js.map +1 -1
- package/dist/frontend/services-node.test.js +51 -0
- package/dist/frontend/services-node.test.js.map +1 -1
- package/dist/frontend/shape-inference/overlay.js +68 -2
- package/dist/frontend/shape-inference/overlay.js.map +1 -1
- package/dist/frontend/tier-analysis.d.ts +9 -0
- package/dist/frontend/tier-analysis.js +1 -0
- package/dist/frontend/tier-analysis.js.map +1 -1
- package/dist/frontend/tsc-codes.d.ts +57 -3
- package/dist/frontend/tsc-codes.js +935 -150
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/tsc-codes.test.js +221 -12
- package/dist/frontend/tsc-codes.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +91 -9
- package/dist/frontend/type-mapper.js +622 -181
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +80 -15
- package/dist/index.js.map +1 -1
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +60 -0
- package/dist/index.test.js.map +1 -0
- package/dist/ir/builtin-effects.js +43 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +242 -16
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/callback-specialization.d.ts +3 -2
- package/dist/ir/callback-specialization.js +35 -25
- package/dist/ir/callback-specialization.js.map +1 -1
- package/dist/ir/capture-values.d.ts +8 -4
- package/dist/ir/capture-values.js +9 -6
- package/dist/ir/capture-values.js.map +1 -1
- package/dist/ir/char-unit-locals.d.ts +6 -2
- package/dist/ir/char-unit-locals.js +11 -2
- package/dist/ir/char-unit-locals.js.map +1 -1
- package/dist/ir/class-key-index.d.ts +18 -0
- package/dist/ir/class-key-index.js +29 -0
- package/dist/ir/class-key-index.js.map +1 -0
- package/dist/ir/class-key-index.test.d.ts +1 -0
- package/dist/ir/class-key-index.test.js +25 -0
- package/dist/ir/class-key-index.test.js.map +1 -0
- package/dist/ir/codec.generated.d.ts +1 -1
- package/dist/ir/codec.generated.js +724 -648
- package/dist/ir/codec.generated.js.map +1 -1
- package/dist/ir/constant-globals.d.ts +5 -2
- package/dist/ir/constant-globals.js +25 -27
- package/dist/ir/constant-globals.js.map +1 -1
- package/dist/ir/expression-inlining.d.ts +4 -2
- package/dist/ir/expression-inlining.js +8 -2
- package/dist/ir/expression-inlining.js.map +1 -1
- package/dist/ir/field-values.d.ts +5 -2
- package/dist/ir/field-values.js +32 -21
- package/dist/ir/field-values.js.map +1 -1
- package/dist/ir/fields.generated.d.ts +11 -2
- package/dist/ir/fields.generated.js +8 -0
- package/dist/ir/fields.generated.js.map +1 -1
- package/dist/ir/final-fields.js +1 -1
- package/dist/ir/final-fields.js.map +1 -1
- package/dist/ir/function-references.d.ts +5 -4
- package/dist/ir/function-references.js +7 -4
- package/dist/ir/function-references.js.map +1 -1
- package/dist/ir/function-references.test.js +7 -0
- package/dist/ir/function-references.test.js.map +1 -1
- package/dist/ir/init-only-globals.d.ts +4 -2
- package/dist/ir/init-only-globals.js +17 -18
- package/dist/ir/init-only-globals.js.map +1 -1
- package/dist/ir/inline-array-views.js +1 -0
- package/dist/ir/inline-array-views.js.map +1 -1
- package/dist/ir/int32-slots.js +7 -0
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/ir.d.ts +59 -4
- package/dist/ir/ir.js +7 -0
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/js-groups.d.ts +51 -0
- package/dist/ir/js-groups.js +394 -0
- package/dist/ir/js-groups.js.map +1 -0
- package/dist/ir/js-groups.test.d.ts +1 -0
- package/dist/ir/js-groups.test.js +555 -0
- package/dist/ir/js-groups.test.js.map +1 -0
- package/dist/ir/js-ic.js +30 -5
- package/dist/ir/js-ic.js.map +1 -1
- package/dist/ir/js-ic.test.js +27 -1
- package/dist/ir/js-ic.test.js.map +1 -1
- package/dist/ir/node-index.d.ts +23 -6
- package/dist/ir/node-index.js +126 -49
- package/dist/ir/node-index.js.map +1 -1
- package/dist/ir/numeric-call-specialization.d.ts +4 -2
- package/dist/ir/numeric-call-specialization.js +40 -26
- package/dist/ir/numeric-call-specialization.js.map +1 -1
- package/dist/ir/paired-while-loops.d.ts +4 -2
- package/dist/ir/paired-while-loops.js +8 -2
- package/dist/ir/paired-while-loops.js.map +1 -1
- package/dist/ir/parameter-versions.d.ts +13 -4
- package/dist/ir/parameter-versions.js +63 -42
- package/dist/ir/parameter-versions.js.map +1 -1
- package/dist/ir/property-bags.d.ts +4 -2
- package/dist/ir/property-bags.js +22 -17
- package/dist/ir/property-bags.js.map +1 -1
- package/dist/ir/row-pairs.d.ts +4 -2
- package/dist/ir/row-pairs.js +12 -11
- package/dist/ir/row-pairs.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +87 -12
- package/dist/ir/runtime-features.js +263 -160
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/runtime-features.test.js +109 -139
- package/dist/ir/runtime-features.test.js.map +1 -1
- package/dist/ir/runtime-jam-loops.d.ts +35 -0
- package/dist/ir/runtime-jam-loops.js +604 -0
- package/dist/ir/runtime-jam-loops.js.map +1 -0
- package/dist/ir/runtime-jam-loops.test.d.ts +1 -0
- package/dist/ir/runtime-jam-loops.test.js +565 -0
- package/dist/ir/runtime-jam-loops.test.js.map +1 -0
- package/dist/ir/saturating-loop-jams.d.ts +4 -2
- package/dist/ir/saturating-loop-jams.js +11 -10
- package/dist/ir/saturating-loop-jams.js.map +1 -1
- package/dist/ir/scalar-records.d.ts +5 -2
- package/dist/ir/scalar-records.js +12 -2
- package/dist/ir/scalar-records.js.map +1 -1
- package/dist/ir/self-captures.d.ts +4 -2
- package/dist/ir/self-captures.js +32 -27
- package/dist/ir/self-captures.js.map +1 -1
- package/dist/ir/serialize.d.ts +6 -1
- package/dist/ir/serialize.js +87 -23
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +26 -0
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/tiers.js +1 -0
- package/dist/ir/tiers.js.map +1 -1
- package/dist/ir/traverse.js +4 -0
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/typed-argument-clones.d.ts +30 -0
- package/dist/ir/typed-argument-clones.js +789 -0
- package/dist/ir/typed-argument-clones.js.map +1 -0
- package/dist/ir/union-arm-loops.d.ts +3 -0
- package/dist/ir/union-arm-loops.js +373 -0
- package/dist/ir/union-arm-loops.js.map +1 -0
- package/dist/ir/union-arm-loops.test.d.ts +1 -0
- package/dist/ir/union-arm-loops.test.js +230 -0
- package/dist/ir/union-arm-loops.test.js.map +1 -0
- package/dist/ir/validate.js +88 -18
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/compiler-self-identity.d.ts +8 -2
- package/dist/library/compiler-self-identity.js +92 -18
- package/dist/library/compiler-self-identity.js.map +1 -1
- package/dist/library/compiler-self-identity.test.js +150 -3
- package/dist/library/compiler-self-identity.test.js.map +1 -1
- package/dist/library/int-infer.d.ts +5 -0
- package/dist/library/int-infer.js +15 -3
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/ir-policy.js +1 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/library/library-cache.d.ts +4 -0
- package/dist/library/library-cache.js +2 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +26 -0
- package/dist/library/library-cache.test.js.map +1 -1
- package/dist/library/prepare.js +99 -31
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cache.d.ts +7 -0
- package/dist/native/cache.js +47 -0
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cache.test.js +13 -1
- package/dist/native/cache.test.js.map +1 -1
- package/dist/native/cli.js +1 -1
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.js +18 -3
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/executable-cache-open.test.js +31 -5
- package/dist/native/executable-cache-open.test.js.map +1 -1
- package/dist/native/executable-cache.d.ts +6 -1
- package/dist/native/executable-cache.js +7 -1
- package/dist/native/executable-cache.js.map +1 -1
- package/dist/native/prepare.d.ts +3 -0
- package/dist/native/prepare.js +43 -26
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +25 -3
- package/dist/native/prepare.test.js.map +1 -1
- package/dist/native/sanitizer.js +10 -1
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/sanitizer.test.js +7 -2
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/node-islands/boundary.d.ts +12 -0
- package/dist/node-islands/boundary.js +38 -6
- package/dist/node-islands/boundary.js.map +1 -1
- package/dist/node-islands/boundary.test.d.ts +1 -0
- package/dist/node-islands/boundary.test.js +76 -0
- package/dist/node-islands/boundary.test.js.map +1 -0
- package/dist/node-islands/detect.d.ts +9 -0
- package/dist/node-islands/detect.js +110 -0
- package/dist/node-islands/detect.js.map +1 -1
- package/dist/node-islands/detect.test.js +24 -0
- package/dist/node-islands/detect.test.js.map +1 -1
- package/dist/node-islands/graph-islands.d.ts +40 -0
- package/dist/node-islands/graph-islands.js +128 -0
- package/dist/node-islands/graph-islands.js.map +1 -0
- package/dist/node-islands/growth.d.ts +57 -0
- package/dist/node-islands/growth.js +205 -0
- package/dist/node-islands/growth.js.map +1 -0
- package/dist/node-islands/report.d.ts +12 -0
- package/dist/node-islands/report.js +28 -0
- package/dist/node-islands/report.js.map +1 -1
- package/dist/node-islands/report.test.js +2 -0
- package/dist/node-islands/report.test.js.map +1 -1
- package/dist/node-islands/rules.js +5 -0
- package/dist/node-islands/rules.js.map +1 -1
- package/dist/node-islands/scan.d.ts +11 -2
- package/dist/node-islands/scan.js +61 -9
- package/dist/node-islands/scan.js.map +1 -1
- package/dist/wasm/translate.js +11 -5
- package/dist/wasm/translate.js.map +1 -1
- package/dist/wasm/translate.test.js +35 -0
- package/dist/wasm/translate.test.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +184 -117
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { lowerIteratorFromDyn } from "./iterator-prototype.js";
|
|
1
2
|
import { programCreatesWrappers } from "./primitive-wrappers.js";
|
|
2
3
|
import { arrayClassMemberOwner, arrayClassReceiver, lowerArrayClassStaticCall, } from "./builtins/array-classes.js";
|
|
3
4
|
import { structuralCallInstance } from "./structural-instances.js";
|
|
@@ -11,7 +12,8 @@ import { lowerDateToPrimitiveCall } from "./builtins/dates.js";
|
|
|
11
12
|
import { isForwardedTupleSpread, lowerForwardingApply } from "./typed-arguments.js";
|
|
12
13
|
import { guardNullProto, nullProtoRecordShape } from "./null-prototype.js";
|
|
13
14
|
import { lowerDynStreamMemberCall } from "./dyn-streams.js";
|
|
14
|
-
import {
|
|
15
|
+
import { isPureReference } from "./effect-free.js";
|
|
16
|
+
import { builtinClassKind, builtinClassKindOf, builtinClassValue, lowerBuiltinClassCall, } from "./builtins/builtin-class-dyn.js";
|
|
15
17
|
import { refuseModuleMemberThis } from "./module-member-this.js";
|
|
16
18
|
import { lowerUnionEquality, tagEqualityMayMissAlias } from "./strict-equality.js";
|
|
17
19
|
import { lowerHashStreamCall } from "./builtins/hash-stream.js";
|
|
@@ -43,11 +45,12 @@ import { errorToStringCall } from "./error-methods.js";
|
|
|
43
45
|
import { lowerClassPrototypeAssign, lowerClassPrototypeDescriptors } from "./class-prototypes.js";
|
|
44
46
|
import { BYTES_ELEMENT_NAME, BYTES_U8, BIGINT_T, BOOL, CAUGHT, DYN, DYN_HANDLE_KINDS, F64, NULL_T, STRING, SYMBOL_T, UNDEFINED_T, VOID, arrayOf, canBoxFuncIntoDyn, canConvertToDyn, canDynCheckTo, funcOf, isDynTypedRefType, isUnitType, recordTextCodecClass, shapeHasAccessorSlots, shapeKeyOrders, typeEquals, RUNTIME_EMITTER_CLASS, } from "../../ir/ir.js";
|
|
45
47
|
import { lowerProtocolMethodCall } from "./class-protocol-dispatch.js";
|
|
48
|
+
import { MUTABLE_BUFFER_MEMBERS } from "./buffers.js";
|
|
46
49
|
import { isJsSourceFile, locOf, requireSpecOf } from "../program.js";
|
|
47
50
|
import { isPackageShimFile, isShimIntrinsicName } from "../package-shims.js";
|
|
48
51
|
import { lowerJsonRequireCall } from "./json-require.js";
|
|
49
52
|
import { lowerAssertInstanceCall } from "./assert-instances.js";
|
|
50
|
-
import { isGenericCallableMemberType, isOverloadedCallableMemberType, typeKey, } from "../type-mapper.js";
|
|
53
|
+
import { erasedOverloadMemberType, isGenericCallableMemberType, isOverloadedCallableMemberType, typeKey, } from "../type-mapper.js";
|
|
51
54
|
import { dynFallbackType, jsFuncNameOf, newFnCtx, staticImportNamespaceType } from "./lowerer.js";
|
|
52
55
|
import { NARROW_FIRST, STRING_INDEX_METHODS, STR_METHODS, UTIL_TYPES_KEYS, stdlibGlobalNameOf, } from "./surfaces.js";
|
|
53
56
|
import { dynStringReceiver } from "./containers/dynamic-receivers.js";
|
|
@@ -55,13 +58,13 @@ import { lowerArrayConstructor, lowerArrayFromCall, lowerArrayOfCall, } from "./
|
|
|
55
58
|
import { lowerArrayFromAsyncCall } from "./containers/array-from-async.js";
|
|
56
59
|
import { lowerDynArrayFilterCall, lowerDynArrayFlatMapCall } from "./containers/array-callbacks.js";
|
|
57
60
|
import { lowerGroupByStaticCall } from "./containers/collection-grouping.js";
|
|
58
|
-
import { lowerGeneratorHelperCall, lowerHelperReturnCall, lowerIteratorFromCall, lowerIteratorHelperCall, } from "./containers/iterator-helpers.js";
|
|
61
|
+
import { lowerGeneratorHelperCall, lowerHelperReturnCall, lowerIteratorFromCall, lowerIteratorHelperCall, lowerWidenedIteratorHelperCall, } from "./containers/iterator-helpers.js";
|
|
59
62
|
import { lowerObjectAssignIndexShape, lowerObjectConstructor, lowerObjectFromEntriesCall, lowerObjectIterOverIndexShape, } from "./containers/indexed-objects.js";
|
|
60
63
|
import { lowerTupleReadMethodCall } from "./containers/array-methods.js";
|
|
61
64
|
import { tryFuseIndexRead } from "./array-values.js";
|
|
62
|
-
import { isPrimitivePrototypeRead } from "./expressions/property-access.js";
|
|
65
|
+
import { builtinGlobalValue, isPrimitivePrototypeRead } from "./expressions/property-access.js";
|
|
63
66
|
import { lowerBufferConstruct, lowerBytesPrototypeSetCall, lowerBytesStaticCall, } from "./containers/bytes.js";
|
|
64
|
-
import { lowerRegexMethodCall, lowerStringIndexCall, lowerStringMethodCall, lowerStringPaddingCall, lowerStringSplitCall, isDynPrimitiveKindMethod, lowerDynPrimitiveMethodCall, lowerExtraNumberMethodCall, } from "./containers/string-and-regexp.js";
|
|
67
|
+
import { EXTRA_STRING_METHODS, lowerRegexMethodCall, lowerStringIndexCall, lowerStringMethodCall, lowerStringPaddingCall, lowerStringSplitCall, isDynPrimitiveKindMethod, lowerDynPrimitiveMethodCall, lowerExtraNumberMethodCall, lowerExtraStringMethodCall, } from "./containers/string-and-regexp.js";
|
|
65
68
|
import { createRequireSpecOf } from "./builtins/module-bindings.js";
|
|
66
69
|
import { lowerChildStreamMethodCall, lowerChildWriterMethodCall, } from "./builtins/child-process-methods.js";
|
|
67
70
|
import { lowerCreateRequireCall, lowerImportMetaResolveCall, lowerRequireResolveCall, } from "./builtins/module-resolution.js";
|
|
@@ -74,9 +77,11 @@ import { fencePerfEntryKeyWalk, isPerfEntryType, lowerHistogramMethodCall, lower
|
|
|
74
77
|
import { fenceX509KeyWalk } from "./builtins/x509.js";
|
|
75
78
|
import { lowerProcStreamMethodCall, lowerProcessBuiltinModuleNamespace, } from "./builtins/process.js";
|
|
76
79
|
import { recordMayKeepSource, recordSourceTest, throughRecordSource } from "./record-sources.js";
|
|
80
|
+
import { answerLinkedCopies, linkedCopyBranches, recordStringCall, registerLinkedHelper, } from "./record-links.js";
|
|
77
81
|
import { lowerReflectCall } from "./builtins/reflection.js";
|
|
78
82
|
import { lowerAbsenceProbe, v8CalleeText, lowerPromiseAllTupleCall, lowerPromiseRejectCall, lowerToNumberArgument, stringWrapperToString, symbolFieldInfo, templateRawTextOf, primitiveCtorClosure, } from "./lower-exprs.js";
|
|
79
83
|
import { isSafeToDiscard } from "./expressions/evaluation-safety.js";
|
|
84
|
+
import { nullishLiteral, nullishReadTypeError, throwAfterEach } from "./primitive-throws.js";
|
|
80
85
|
import { tryLowerExpression } from "./expressions/try-lower-expression.js";
|
|
81
86
|
import { lowerChildMethodValue, lowerChildPropertyCall } from "./handle-properties.js";
|
|
82
87
|
import { classObjectTag, classToNumberConversion } from "./class-to-primitive.js";
|
|
@@ -85,12 +90,13 @@ import { structuralReadType } from "./class-unions.js";
|
|
|
85
90
|
import { httpClientFnBindingOf, lowerCompatReqStreamOptionalCall, lowerHttpClientFnCall, } from "./lower-server.js";
|
|
86
91
|
import { EMITTER_API_MEMBERS, exactClassOfReceiver, exactInstanceClassOf, findGenericMethodOn, lowerClassGenericMethodCall, lowerStaticMethodCall, lowerStaticFieldRead, returnsOnlyThis, storedClassValueType, } from "./lower-classes.js";
|
|
87
92
|
import { classCallbackCall, isClassCallback } from "./class-callbacks.js";
|
|
88
|
-
import { emitterRooted, lowerEmitterMethodCall } from "./lower-event-emitter.js";
|
|
93
|
+
import { emitOverrideAtOrAbove, emitterRooted, lowerEmitterMethodCall, } from "./lower-event-emitter.js";
|
|
89
94
|
import { eventTargetApiMethod, lowerEventTargetMethodCall } from "./lower-event-target.js";
|
|
90
95
|
import { dateRootOf, isDatePrototypeMethod, lowerInheritedDateMethodCall, } from "./builtins/date-classes.js";
|
|
91
96
|
import { lowerConsoleInstanceCall, lowerConsoleMethodCall, lowerConsoleOutput, } from "./lower-console.js";
|
|
92
97
|
import { STREAM_API_MEMBERS, STREAM_OPERATORS, lowerStreamMethodCall, lowerStreamStaticCall, streamSidesOf, } from "./lower-stream.js";
|
|
93
98
|
import { ambientNsRootOf, ambientUndefReadType, ambientUndefVarRootOf, ambientUndefinedFnSymbolOf, contextualUndefReadType, fenceEarlyAliasUse, fenceEarlyNsMemberRef, nsMemberIdentOf, nsUndefRead, } from "./lower-namespaces.js";
|
|
99
|
+
import { hostGlobalNameOfRead, hostGlobalPrototypeMemberOf } from "./host-globals.js";
|
|
94
100
|
import { expandoMemberRead } from "./lower-expando.js";
|
|
95
101
|
import { fenceNodeModuleMutationCall, isCjsRequireGlobal, lowerRequireCacheKeys, } from "./lower-node-module.js";
|
|
96
102
|
import { pathModuleValue } from "./lower-builtin-values.js";
|
|
@@ -102,10 +108,11 @@ import { freezableRecordType, lowerNativeFreeze, noteUntypedIntegrity } from "./
|
|
|
102
108
|
import { classStaticDataFor } from "./class-static-data.js";
|
|
103
109
|
import { lowerUrlFactory } from "./lower-url.js";
|
|
104
110
|
import { nullishValueUnitOf } from "./binding-analysis.js";
|
|
105
|
-
import { spreadNeedsRuntimeArity, completeFuncValueArgs, lowerSpreadArgsCall, completeArgs, } from "./call-arguments.js";
|
|
111
|
+
import { spreadNeedsRuntimeArity, completeFuncValueArgs, checkedRestCallArgs, lowerSpreadArgsCall, completeArgs, } from "./call-arguments.js";
|
|
106
112
|
import { isThisParameter } from "./call-signatures.js";
|
|
107
113
|
import { dynamicOverloadChoice } from "./overload-choice.js";
|
|
108
114
|
import { lowerStringIteratorValue } from "./iterator-adapters.js";
|
|
115
|
+
import { iterableGenerator, iterableUnionOf } from "./iterable-values.js";
|
|
109
116
|
import { checkedArmExtraction } from "./coercions/unions.js";
|
|
110
117
|
import { maybePromiseReturnStmt, promiseArmedUnionOf, promiseOrUnitUnionOf, } from "./maybe-promise.js";
|
|
111
118
|
import { requireObjLitGenericReceiver, objLitGenericFnNodeOf, objLitGenericFnInfoOf, genericCallInstance, } from "./generic-functions.js";
|
|
@@ -181,8 +188,60 @@ function receiverlessCalleeOf(callee) {
|
|
|
181
188
|
}
|
|
182
189
|
export function lowerCall(lowerer, expr) {
|
|
183
190
|
const loc = locOf(expr);
|
|
191
|
+
// A JavaScript source calling a member that resizes, grows or detaches a
|
|
192
|
+
// buffer is the mutableBuffers fact (buffers.ts, t262-dc §2.4). The
|
|
193
|
+
// receiver may be a checked-dynamic value, so the callee's name decides;
|
|
194
|
+
// the member read never reaches lowerPropertyAccessExpr when the call
|
|
195
|
+
// lowers straight through its receiver.
|
|
196
|
+
if (isJsSourceFile(ts.getSourceFileOfNode(expr))) {
|
|
197
|
+
const callee = expr.expression;
|
|
198
|
+
const name = ts.isPropertyAccessExpression(callee)
|
|
199
|
+
? callee.name.text
|
|
200
|
+
: ts.isElementAccessExpression(callee)
|
|
201
|
+
? lowerer.foldedStringKeyOf(callee.argumentExpression)
|
|
202
|
+
: null;
|
|
203
|
+
if (name !== null && MUTABLE_BUFFER_MEMBERS.has(name))
|
|
204
|
+
lowerer.buffersMutable = true;
|
|
205
|
+
}
|
|
206
|
+
// `(null).foo()` / `(undefined)["foo"]()`: the MEMBER READ throws Node's
|
|
207
|
+
// TypeError before the arguments evaluate, exactly as a plain read does.
|
|
208
|
+
// Only a nullish LITERAL qualifies — every other receiver, a binding or a
|
|
209
|
+
// property included, has a value the runtime reads and refuses itself,
|
|
210
|
+
// with the same message and the same order.
|
|
211
|
+
{
|
|
212
|
+
const callee = expr.expression;
|
|
213
|
+
const member = ts.isPropertyAccessExpression(callee) && !callee.questionDotToken
|
|
214
|
+
? { base: callee.expression, name: callee.name.text }
|
|
215
|
+
: ts.isElementAccessExpression(callee) && !callee.questionDotToken
|
|
216
|
+
? { base: callee.expression, name: lowerer.foldedStringKeyOf(callee.argumentExpression) }
|
|
217
|
+
: null;
|
|
218
|
+
const unit = !expr.questionDotToken && member !== null ? nullishLiteral(lowerer, member.base) : null;
|
|
219
|
+
if (member !== null && member.name !== null && unit !== null) {
|
|
220
|
+
const recv = lowerer.lowerExpr(member.base);
|
|
221
|
+
const t = lowerer.mapTypeOf(lowerer.typeOf(expr)) ?? F64;
|
|
222
|
+
return throwAfterEach([recv], nullishReadTypeError(unit, member.name, t, loc), loc);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
184
225
|
if (lowerer.errorAccessorReflection === null)
|
|
185
226
|
noteErrorAccessorReflection(lowerer, expr);
|
|
227
|
+
// Calling a Node 24 global the native runtime does not provide (WebSocket,
|
|
228
|
+
// FormData, …): the value a read answers refuses the call
|
|
229
|
+
// (host-global-values.ts), so the call is that refusal — SC2020, which a
|
|
230
|
+
// JavaScript source defers to the throw at this statement.
|
|
231
|
+
{
|
|
232
|
+
const hostGlobal = hostGlobalNameOfRead(lowerer, expr.expression);
|
|
233
|
+
if (hostGlobal !== null)
|
|
234
|
+
lowerer.hostGlobalFence(hostGlobal, expr.expression);
|
|
235
|
+
}
|
|
236
|
+
// A method on the value's prototype (`FormData.prototype.append(...)`):
|
|
237
|
+
// the prototype carries the constructor link only, so the method is
|
|
238
|
+
// surface native code does not have (SC2020, host-global). A call reads
|
|
239
|
+
// its callee without going through the member-read hook.
|
|
240
|
+
{
|
|
241
|
+
const prototypeOf = hostGlobalPrototypeMemberOf(lowerer, expr.expression);
|
|
242
|
+
if (prototypeOf !== null)
|
|
243
|
+
lowerer.hostGlobalFence(prototypeOf, expr.expression);
|
|
244
|
+
}
|
|
186
245
|
// Object's checker return type is `any`. Claim known object inputs
|
|
187
246
|
// before generic checked-dynamic dispatch tries to load the constructor.
|
|
188
247
|
if (ts.isIdentifier(expr.expression) &&
|
|
@@ -197,6 +256,14 @@ export function lowerCall(lowerer, expr) {
|
|
|
197
256
|
const builtinClassCall = lowerBuiltinClassCall(lowerer, expr);
|
|
198
257
|
if (builtinClassCall)
|
|
199
258
|
return builtinClassCall;
|
|
259
|
+
// `R.<method>.call(thisArg, ...)` over EventEmitter.prototype's methods.
|
|
260
|
+
if (ts.isPropertyAccessExpression(expr.expression) &&
|
|
261
|
+
!expr.expression.questionDotToken &&
|
|
262
|
+
expr.expression.name.text === "call") {
|
|
263
|
+
const emitterMethod = lowerEmitterMethodValueCall(lowerer, expr, expr.expression);
|
|
264
|
+
if (emitterMethod)
|
|
265
|
+
return emitterMethod;
|
|
266
|
+
}
|
|
200
267
|
// require() of a JSON document: the shared parsed object.
|
|
201
268
|
const json = lowerJsonRequireCall(lowerer, expr);
|
|
202
269
|
if (json)
|
|
@@ -711,7 +778,12 @@ export function lowerCall(lowerer, expr) {
|
|
|
711
778
|
const converted = lowerBigIntConstructorValue(lowerer, arg, loc);
|
|
712
779
|
if (converted)
|
|
713
780
|
return converted;
|
|
714
|
-
|
|
781
|
+
// Report the type the program wrote, which is the type the checker has
|
|
782
|
+
// narrowed to here. The stored union only shows up when it is what
|
|
783
|
+
// actually blocks the conversion.
|
|
784
|
+
const narrowed = lowerer.mapTypeOf(lowerer.typeOf(argNode));
|
|
785
|
+
const shown = narrowed && !typeEquals(narrowed, arg.type) ? narrowed : arg.type;
|
|
786
|
+
lowerer.noLowering(`BigInt of ${lowerer.fmt(shown)} values`, argNode, bigintRefusalHint(lowerer, arg, narrowed));
|
|
715
787
|
}
|
|
716
788
|
if (lowerer.isStdlibGlobal(expr.expression, "String") ||
|
|
717
789
|
lowerer.isStdlibGlobal(expr.expression, "Boolean") ||
|
|
@@ -991,32 +1063,7 @@ export function lowerCall(lowerer, expr) {
|
|
|
991
1063
|
// different, non-stdlib symbol.
|
|
992
1064
|
if ((expr.expression.text === "atob" || expr.expression.text === "btoa") &&
|
|
993
1065
|
lowerer.isStdlibSymbol(lowerer.resolveValueSymbol(expr.expression) ?? undefined)) {
|
|
994
|
-
|
|
995
|
-
if (expr.arguments.nodes.length === 0) {
|
|
996
|
-
return { kind: "libCall", fn: "str.b64Missing", args: [], type: STRING, loc };
|
|
997
|
-
}
|
|
998
|
-
if (expr.arguments.nodes.length > 1) {
|
|
999
|
-
lowerer.noLowering(`${name} with ${expr.arguments.nodes.length} arguments`, expr);
|
|
1000
|
-
}
|
|
1001
|
-
const argNode = expr.arguments.nodes[0];
|
|
1002
|
-
const v = lowerer.lowerExpr(argNode);
|
|
1003
|
-
let data;
|
|
1004
|
-
if (v.type.kind === "dyn") {
|
|
1005
|
-
data = v;
|
|
1006
|
-
}
|
|
1007
|
-
else if (v.kind === "unitLit" || lowerer.dynConvertible(v.type)) {
|
|
1008
|
-
data = { kind: "dynFrom", value: v, type: DYN, loc };
|
|
1009
|
-
}
|
|
1010
|
-
else {
|
|
1011
|
-
lowerer.noLowering(`${name} with a '${lowerer.fmt(v.type)}' argument`, argNode, "string-convertible arguments lower (Node ToStrings the value — convert it explicitly)");
|
|
1012
|
-
}
|
|
1013
|
-
return {
|
|
1014
|
-
kind: "libCall",
|
|
1015
|
-
fn: name === "atob" ? "str.atob" : "str.btoa",
|
|
1016
|
-
args: [data],
|
|
1017
|
-
type: STRING,
|
|
1018
|
-
loc,
|
|
1019
|
-
};
|
|
1066
|
+
return lowerBase64Call(lowerer, expr, expr.expression.text, loc);
|
|
1020
1067
|
}
|
|
1021
1068
|
// global function executes — callFn(globalGet(name)) — and the
|
|
1022
1069
|
// result exits to the declared static type. A user function
|
|
@@ -1438,6 +1485,11 @@ export function lowerCall(lowerer, expr) {
|
|
|
1438
1485
|
// (untyped in fallback builds, so before the dyn receiver path) or
|
|
1439
1486
|
// webcrypto.
|
|
1440
1487
|
lowerWebCryptoMethodCall(lowerer, expr, expr.expression) ??
|
|
1488
|
+
// A helper call on a JavaScript binding reassigned with a helper
|
|
1489
|
+
// stage (`let it = g(); it = it.filter(...)`): the binding holds the
|
|
1490
|
+
// checked value, and the dyn receiver path would read `filter` as
|
|
1491
|
+
// Array.prototype's. Before it, so the runtime's helper answers.
|
|
1492
|
+
lowerWidenedIteratorHelperCall(lowerer, expr) ??
|
|
1441
1493
|
// Dyn receivers (JSON.parse-derived `unknown`/`any` values) —
|
|
1442
1494
|
lowerDynReceiverMethodCall(lowerer, expr, expr.expression) ??
|
|
1443
1495
|
// Narrowing filters (inferred predicates, filter(Boolean)) claim
|
|
@@ -1779,9 +1831,156 @@ function callableInstanceStringCall(lowerer, expr, callee, loc) {
|
|
|
1779
1831
|
loc,
|
|
1780
1832
|
};
|
|
1781
1833
|
}
|
|
1834
|
+
/** Refuses a copying conversion at a call through a value whose checker
|
|
1835
|
+
* signature keeps its own type parameters — the erased instance
|
|
1836
|
+
* lowerGenericFnValue / erasedGenericInstance produce. The call itself
|
|
1837
|
+
* needs no new rule: such a value's IR type is already the erased func
|
|
1838
|
+
* type, so the ordinary func-value lane completes its arguments into the
|
|
1839
|
+
* erased signature's `unknown` slots (records, arrays and collections box
|
|
1840
|
+
* as live capsules, primitives as themselves) and leaves the result dyn
|
|
1841
|
+
* for each use to convert, where a lie throws (dynCheck) instead of
|
|
1842
|
+
* answering a value the program never had. Keeping the lane unchanged is
|
|
1843
|
+
* what keeps every program that compiles today byte-identical. */
|
|
1844
|
+
function refuseCopyingErasureInstanceCall(lowerer, call, callee) {
|
|
1845
|
+
if (callee.type.kind !== "func")
|
|
1846
|
+
return;
|
|
1847
|
+
const sigs = lowerer.checker.getCallSignatures(lowerer.typeOf(call.expression));
|
|
1848
|
+
if (!sigs.some((sig) => sig.getTypeParameters().length > 0))
|
|
1849
|
+
return;
|
|
1850
|
+
refuseCopyingErasureBoundary(lowerer, call, callee.type);
|
|
1851
|
+
}
|
|
1852
|
+
/** Refuse an erased instantiation whose boundary conversion would COPY the
|
|
1853
|
+
* value instead of carrying it by reference.
|
|
1854
|
+
*
|
|
1855
|
+
* Most conversions across the erased boundary are exact: records and arrays
|
|
1856
|
+
* box into `unknown` as live capsules of themselves, and the checked unbox
|
|
1857
|
+
* back answers the same object (object-model S1). Two conversions are not,
|
|
1858
|
+
* and compiling them would silently hand the program a different object
|
|
1859
|
+
* than Node's:
|
|
1860
|
+
*
|
|
1861
|
+
* - a promise payload crossing the boundary. The dynamic promise conversion
|
|
1862
|
+
* re-materializes the settled record rather than boxing it live, so a
|
|
1863
|
+
* `Promise<{ id: number }>` that crosses into `unknown` (or into a wider
|
|
1864
|
+
* promise) settles to a copy. This is a pre-existing dynamic-tier
|
|
1865
|
+
* behaviour — it is what `const u: unknown = await p` does today for a
|
|
1866
|
+
* `Promise<Record>` with no generics in sight — so the erased form must
|
|
1867
|
+
* not promise otherwise. A closure counts by its RESULT: calling a boxed
|
|
1868
|
+
* closure converts its result into `unknown`, so a callback returning a
|
|
1869
|
+
* promise of a record loses that record's identity (the createLimiter
|
|
1870
|
+
* shape: `async () => shared` over the boundary).
|
|
1871
|
+
* - a record (or array) converting to a different record (or array) type: a
|
|
1872
|
+
* width conversion copies.
|
|
1873
|
+
*
|
|
1874
|
+
* Everything the rule names is a shape the compiler refuses today, so no
|
|
1875
|
+
* program that compiles changes: these fences only replace a silent
|
|
1876
|
+
* divergence with a diagnostic. */
|
|
1877
|
+
function refuseCopyingErasureBoundary(lowerer, call, funcType) {
|
|
1878
|
+
const argNodes = call.arguments.nodes;
|
|
1879
|
+
for (let i = 0; i < argNodes.length && i < funcType.params.length; i++) {
|
|
1880
|
+
const arg = argNodes[i];
|
|
1881
|
+
if (ts.isSpreadElement(arg))
|
|
1882
|
+
continue;
|
|
1883
|
+
const reason = erasureCopyReason(lowerer, lowerer.irTypeOf(arg), funcType.params[i]);
|
|
1884
|
+
if (reason !== null) {
|
|
1885
|
+
lowerer.unsupported("SC1090", arg, `passing this argument across the erased generic boundary (${reason}; JavaScript hands the same object over)`);
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
const reason = erasureCopyReason(lowerer, funcType.ret, lowerer.irTypeOf(call));
|
|
1889
|
+
if (reason !== null) {
|
|
1890
|
+
lowerer.unsupported("SC1090", call, `returning this call's result across the erased generic boundary (${reason}; JavaScript hands the same object back)`);
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
/** Why converting a value of type `src` at the erased boundary (`dst`)
|
|
1894
|
+
* copies it, or null when the conversion is exact. */
|
|
1895
|
+
function erasureCopyReason(lowerer, src, dst) {
|
|
1896
|
+
if (typeEquals(src, dst))
|
|
1897
|
+
return null;
|
|
1898
|
+
// An unboxed capsule answers the same object, and a promise payload
|
|
1899
|
+
// boxes by reference as well (object-model S1), so no dynamic-side
|
|
1900
|
+
// crossing copies.
|
|
1901
|
+
if (src.kind === "dyn")
|
|
1902
|
+
return null;
|
|
1903
|
+
if (dst.kind === "dyn")
|
|
1904
|
+
return dynCrossingCopyReason(lowerer, src);
|
|
1905
|
+
if (src.kind === "record" && dst.kind === "record")
|
|
1906
|
+
return `a '${lowerer.fmt(src)}' becomes the narrower '${lowerer.fmt(dst)}' by copying it`;
|
|
1907
|
+
if (src.kind === "array" && dst.kind === "array")
|
|
1908
|
+
return `a '${lowerer.fmt(src)}' becomes '${lowerer.fmt(dst)}' by copying it`;
|
|
1909
|
+
if (src.kind === "promise" && dst.kind === "promise")
|
|
1910
|
+
return erasureCopyReason(lowerer, src.inner, dst.inner);
|
|
1911
|
+
if (src.kind === "func" && dst.kind === "func")
|
|
1912
|
+
return erasureCopyReason(lowerer, src.ret, dst.ret);
|
|
1913
|
+
return null;
|
|
1914
|
+
}
|
|
1915
|
+
/** Why a value of type `t` crossing INTO `unknown` copies, or null. A
|
|
1916
|
+
* record, array or promise boxes as a live capsule of itself (a promise's
|
|
1917
|
+
* payload boxes by reference too, object-model S1); a function boxes as a
|
|
1918
|
+
* callable whose RESULT converts through the dynamic call, so a record or
|
|
1919
|
+
* array result comes back as a fresh value. */
|
|
1920
|
+
function dynCrossingCopyReason(lowerer, t) {
|
|
1921
|
+
if (t.kind === "func") {
|
|
1922
|
+
const inner = dynCrossingCopyReason(lowerer, t.ret);
|
|
1923
|
+
if (inner !== null)
|
|
1924
|
+
return inner;
|
|
1925
|
+
if (structuredResultHoldsCopy(lowerer, t.ret))
|
|
1926
|
+
return `a '${lowerer.fmt(t.ret)}' result is re-materialized when the boxed function returns it`;
|
|
1927
|
+
return null;
|
|
1928
|
+
}
|
|
1929
|
+
if (t.kind === "union") {
|
|
1930
|
+
const def = lowerer.unions.get(t.unionId);
|
|
1931
|
+
for (const arm of def?.arms ?? []) {
|
|
1932
|
+
const reason = dynCrossingCopyReason(lowerer, arm);
|
|
1933
|
+
if (reason !== null)
|
|
1934
|
+
return reason;
|
|
1935
|
+
}
|
|
1936
|
+
return null;
|
|
1937
|
+
}
|
|
1938
|
+
return null;
|
|
1939
|
+
}
|
|
1940
|
+
/** True when a boxed function's RESULT is a record or array, or a union with
|
|
1941
|
+
* such an arm. The boxed callable converts that result through the dynamic
|
|
1942
|
+
* call, which answers a fresh value, so the caller does not get the object
|
|
1943
|
+
* the function returned. */
|
|
1944
|
+
function structuredResultHoldsCopy(lowerer, t) {
|
|
1945
|
+
if (t.kind === "record" || t.kind === "array")
|
|
1946
|
+
return true;
|
|
1947
|
+
if (t.kind !== "union")
|
|
1948
|
+
return false;
|
|
1949
|
+
const def = lowerer.unions.get(t.unionId);
|
|
1950
|
+
return def !== undefined && def.arms.some((arm) => structuredResultHoldsCopy(lowerer, arm));
|
|
1951
|
+
}
|
|
1782
1952
|
/** A call through an evaluated callee value: checked-dynamic callees,
|
|
1783
1953
|
* function unions, typed-rest and runtime-arity closures. */
|
|
1784
1954
|
export function lowerCallThroughValue(lowerer, expr, callee, loc) {
|
|
1955
|
+
return overloadValueResult(lowerer, expr, callee, lowerCallThroughValueRaw(lowerer, expr, callee, loc));
|
|
1956
|
+
}
|
|
1957
|
+
/** A call through a VALUE of an OVERLOADED type: the value holds the set's
|
|
1958
|
+
* erased function (mapType's overload-value rule), so its result converts to
|
|
1959
|
+
* the resolved overload's type, as a call through an overloaded record
|
|
1960
|
+
* member does. Only a callee whose IR type IS that erased function converts,
|
|
1961
|
+
* so a class method or a declared function called through its own
|
|
1962
|
+
* implementation is unchanged. Shared with the optional chain's own call
|
|
1963
|
+
* step (`f?.(x)`, `a.m?.(x)`), which builds its callValue directly. */
|
|
1964
|
+
export function overloadValueResult(lowerer, expr, callee, result) {
|
|
1965
|
+
if (result.kind !== "callValue" || callee.type.kind !== "func")
|
|
1966
|
+
return result;
|
|
1967
|
+
const calleeTs = lowerer.checker.getNonNullableType(lowerer.typeOf(expr.expression));
|
|
1968
|
+
if (!isOverloadedCallableMemberType(calleeTs, lowerer.checker))
|
|
1969
|
+
return result;
|
|
1970
|
+
const erased = erasedOverloadMemberType(calleeTs, lowerer.typeCtx);
|
|
1971
|
+
if (erased === undefined || !typeEquals(erased, callee.type))
|
|
1972
|
+
return result;
|
|
1973
|
+
return lowerer.coerceInto(expr, result, resolvedOverloadResultType(lowerer, expr));
|
|
1974
|
+
}
|
|
1975
|
+
function lowerCallThroughValueRaw(lowerer, expr, callee, loc) {
|
|
1976
|
+
// A callee value that keeps its call signature's OWN type parameters
|
|
1977
|
+
// (`f(3)` where `f: <T>(x: T) => T`, a generic method's record slot, a
|
|
1978
|
+
// generic result read back) is the ERASED instance — one function whose
|
|
1979
|
+
// parameters and result are `unknown`, exactly the function JavaScript
|
|
1980
|
+
// runs for every type argument. Its IR type is that erased func type, so
|
|
1981
|
+
// the ordinary lanes below serve the call; only a boundary conversion
|
|
1982
|
+
// that would COPY is refused instead of compiled.
|
|
1983
|
+
refuseCopyingErasureInstanceCall(lowerer, expr, callee);
|
|
1785
1984
|
// A CHECKED-DYNAMIC callee — `fn(a, b)` where fn is an implicit-any
|
|
1786
1985
|
// JS binding (the mustCall body's `fn(...args)`), a dyn capture, or a
|
|
1787
1986
|
// keyed read off a dyn value: the dynCall boundary. Arguments convert
|
|
@@ -2166,6 +2365,32 @@ function lowerNumberConstructorValue(lowerer, argNode, loc) {
|
|
|
2166
2365
|
? "unions of numbers, booleans, strings, null, and undefined lower — narrow other arms first"
|
|
2167
2366
|
: undefined);
|
|
2168
2367
|
}
|
|
2368
|
+
/** Whether a stored union arm converts on its own. A whole dynamic
|
|
2369
|
+
* argument takes dyn.bigintConstructor instead, so dyn is never a
|
|
2370
|
+
* dispatched arm. */
|
|
2371
|
+
function bigintArmLowers(arm) {
|
|
2372
|
+
return (arm.kind === "bigint" ||
|
|
2373
|
+
arm.kind === "string" ||
|
|
2374
|
+
arm.kind === "f64" ||
|
|
2375
|
+
arm.kind === "bool" ||
|
|
2376
|
+
arm.kind === "bytes" ||
|
|
2377
|
+
arm.kind === "array" ||
|
|
2378
|
+
isUnitType(arm));
|
|
2379
|
+
}
|
|
2380
|
+
/** The hint for a BigInt argument no conversion covers. Lowering dispatches
|
|
2381
|
+
* on the STORED union, which a call-site guard need not narrow; when the
|
|
2382
|
+
* checker sees a different type, name both and point at the arms that stand
|
|
2383
|
+
* in the way, rather than pasting the whole tagged storage at the reader. */
|
|
2384
|
+
function bigintRefusalHint(lowerer, arg, narrowed) {
|
|
2385
|
+
const supported = "string, number, boolean, bigint, byte views, and array arguments are supported";
|
|
2386
|
+
if (!narrowed || arg.type.kind !== "union" || typeEquals(narrowed, arg.type))
|
|
2387
|
+
return supported;
|
|
2388
|
+
const arms = lowerer.unions.get(arg.type.unionId)?.arms ?? [];
|
|
2389
|
+
const blocking = arms.filter((arm) => !bigintArmLowers(arm)).map((arm) => lowerer.fmt(arm));
|
|
2390
|
+
if (blocking.length === 0)
|
|
2391
|
+
return supported;
|
|
2392
|
+
return `the checker narrows the argument to ${lowerer.fmt(narrowed)}, but the stored value can also hold ${blocking.join(" | ")} at run time; ${supported}`;
|
|
2393
|
+
}
|
|
2169
2394
|
/** A runtime-optional local retains its full tagged storage even after a
|
|
2170
2395
|
* checker guard. Dispatch BigInt by the actual value, including nullish
|
|
2171
2396
|
* TypeErrors, rather than interpreting that storage as the narrowed arm. */
|
|
@@ -2183,7 +2408,10 @@ function lowerBigIntConstructorValue(lowerer, arg, loc) {
|
|
|
2183
2408
|
// as that element, none as 0n, several throw the SyntaxError for the
|
|
2184
2409
|
// joined text), a Buffer's is its UTF-8 decoding and a DataView's is
|
|
2185
2410
|
// "[object DataView]". The runtime value tells them apart, as for String.
|
|
2186
|
-
|
|
2411
|
+
// An array reaches the same ToPrimitive: its text is the elements joined
|
|
2412
|
+
// with "," (`[5]` reads "5", `[]` reads ""), whichever element types it
|
|
2413
|
+
// holds, and BigInt parses that.
|
|
2414
|
+
if (arg.type.kind === "bytes" || arg.type.kind === "array") {
|
|
2187
2415
|
const text = {
|
|
2188
2416
|
kind: "toString",
|
|
2189
2417
|
operand: { kind: "dynFrom", value: arg, type: DYN, loc },
|
|
@@ -2222,13 +2450,7 @@ function lowerBigIntConstructorValue(lowerer, arg, loc) {
|
|
|
2222
2450
|
return null;
|
|
2223
2451
|
const unionId = arg.type.unionId;
|
|
2224
2452
|
const arms = lowerer.unions.get(unionId)?.arms;
|
|
2225
|
-
if (!arms ||
|
|
2226
|
-
!arms.every((arm) => arm.kind === "bigint" ||
|
|
2227
|
-
arm.kind === "string" ||
|
|
2228
|
-
arm.kind === "f64" ||
|
|
2229
|
-
arm.kind === "bool" ||
|
|
2230
|
-
arm.kind === "bytes" ||
|
|
2231
|
-
isUnitType(arm)))
|
|
2453
|
+
if (!arms || !arms.every(bigintArmLowers))
|
|
2232
2454
|
return null;
|
|
2233
2455
|
const key = `bigint.scalar:${unionId}`;
|
|
2234
2456
|
let helper = lowerer.valueHelpers.get(key);
|
|
@@ -2860,11 +3082,16 @@ function lowerStringPrototypeCall(lowerer, call, access) {
|
|
|
2860
3082
|
return null;
|
|
2861
3083
|
const methodAccess = access.expression;
|
|
2862
3084
|
const prototypeAccess = methodAccess.expression;
|
|
3085
|
+
// The Annex B CreateHTML methods, substr, concat and the locale-cased pair
|
|
3086
|
+
// lower only as EXTRA_STRING_METHODS; a `.call` reaches the same lowering
|
|
3087
|
+
// with the receiver as its first argument.
|
|
3088
|
+
const extraMethod = EXTRA_STRING_METHODS.has(methodAccess.name.text);
|
|
2863
3089
|
if (!ts.isPropertyAccessExpression(prototypeAccess) ||
|
|
2864
3090
|
prototypeAccess.name.text !== "prototype" ||
|
|
2865
3091
|
!ts.isIdentifier(prototypeAccess.expression) ||
|
|
2866
3092
|
prototypeAccess.expression.text !== "String" ||
|
|
2867
|
-
(!
|
|
3093
|
+
(!extraMethod &&
|
|
3094
|
+
!Object.hasOwn(STR_METHODS, methodAccess.name.text) &&
|
|
2868
3095
|
!STRING_INDEX_METHODS.has(methodAccess.name.text)) ||
|
|
2869
3096
|
!lowerer.isStdlibMember(methodAccess))
|
|
2870
3097
|
return null;
|
|
@@ -2874,9 +3101,11 @@ function lowerStringPrototypeCall(lowerer, call, access) {
|
|
|
2874
3101
|
const indexMethod = STRING_INDEX_METHODS.has(methodAccess.name.text)
|
|
2875
3102
|
? methodAccess.name.text
|
|
2876
3103
|
: null;
|
|
2877
|
-
const resultType =
|
|
2878
|
-
?
|
|
2879
|
-
:
|
|
3104
|
+
const resultType = extraMethod
|
|
3105
|
+
? STRING
|
|
3106
|
+
: indexMethod
|
|
3107
|
+
? lowerer.withUndefinedArmOf(indexMethod === "at" ? STRING : F64)
|
|
3108
|
+
: entry?.result;
|
|
2880
3109
|
if (!resultType)
|
|
2881
3110
|
return null;
|
|
2882
3111
|
const method = methodAccess.name.text === "trimStart"
|
|
@@ -2936,6 +3165,17 @@ function lowerStringPrototypeCall(lowerer, call, access) {
|
|
|
2936
3165
|
false));
|
|
2937
3166
|
// Other methods convert object receivers before lowering their arguments;
|
|
2938
3167
|
// padding uses a helper that delays conversion until every argument is ready.
|
|
3168
|
+
if (extraMethod) {
|
|
3169
|
+
// Only the receivers the typed extra-method lowering already accepts: a
|
|
3170
|
+
// scalar converts without running code, and the checked-dynamic receiver
|
|
3171
|
+
// took the branch above. An object receiver's ToString can run user code,
|
|
3172
|
+
// which `Function.call` orders after every argument, so it keeps its fence.
|
|
3173
|
+
if (!scalar) {
|
|
3174
|
+
lowerer.noLowering(`String.prototype.${methodAccess.name.text}.call with ${lowerer.fmt(receiverType)} receivers`, call);
|
|
3175
|
+
}
|
|
3176
|
+
const receiver = lowerer.ensureString(receiverValue, receiverNode);
|
|
3177
|
+
return lowerExtraStringMethodCall(lowerer, call, methodAccess.name.text, receiver, receiverNode, call.arguments.nodes.slice(1));
|
|
3178
|
+
}
|
|
2939
3179
|
const objectWithoutMethodArgs = entry?.maxArgs === 0 &&
|
|
2940
3180
|
call.arguments.nodes.length === 1 &&
|
|
2941
3181
|
(receiverType.kind === "record" ||
|
|
@@ -3080,7 +3320,11 @@ function lowerOptionalStringNumber(lowerer, arg, loc, fn = "num.fromString", lab
|
|
|
3080
3320
|
return { kind: "call", callee: helper, args: [arg], type: F64, loc };
|
|
3081
3321
|
}
|
|
3082
3322
|
/** `s[Symbol.iterator]()` on a string-typed receiver: the generator over
|
|
3083
|
-
* its code points.
|
|
3323
|
+
* its code points. On an `Iterable<T>` value (`Iterable<SegmentData>` in a
|
|
3324
|
+
* union with another iterable, an option's segment function): GetIterator
|
|
3325
|
+
* over the current arm, the same interned helper for-of and spread open —
|
|
3326
|
+
* the answer is the canonical iterator, so `.next()` reads like any other.
|
|
3327
|
+
* Null for other element calls. */
|
|
3084
3328
|
function lowerStringIteratorCall(lowerer, call, access) {
|
|
3085
3329
|
let key = access.argumentExpression;
|
|
3086
3330
|
while (ts.isParenthesizedExpression(key))
|
|
@@ -3088,7 +3332,11 @@ function lowerStringIteratorCall(lowerer, call, access) {
|
|
|
3088
3332
|
if (!ts.isPropertyAccessExpression(key) ||
|
|
3089
3333
|
lowerer.stdlibGlobalMember(key, "Symbol") !== "iterator")
|
|
3090
3334
|
return null;
|
|
3091
|
-
|
|
3335
|
+
const receiverT = lowerer.mapTypeOf(lowerer.typeOf(access.expression));
|
|
3336
|
+
const iterable = receiverT ? iterableUnionOf(lowerer, receiverT) : null;
|
|
3337
|
+
if (iterable)
|
|
3338
|
+
return iterableGenerator(lowerer, lowerer.lowerExpr(access.expression), iterable);
|
|
3339
|
+
if (receiverT?.kind !== "string")
|
|
3092
3340
|
return null;
|
|
3093
3341
|
const type = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
3094
3342
|
if (type?.kind !== "generator")
|
|
@@ -4446,7 +4694,10 @@ function lowerArrayIsArrayCall(lowerer, call, access) {
|
|
|
4446
4694
|
return folded;
|
|
4447
4695
|
// A computed argument (`Array.isArray(make())`, `Array.isArray([1, 2])`)
|
|
4448
4696
|
// still answers from its static type, so evaluate the argument for its
|
|
4449
|
-
// effects and discard the value.
|
|
4697
|
+
// effects and discard the value. `undefined`/`null` lower to a bare unitLit,
|
|
4698
|
+
// which carries no effect and is not a valid IR expression statement.
|
|
4699
|
+
if (arg.kind === "unitLit")
|
|
4700
|
+
return folded;
|
|
4450
4701
|
return {
|
|
4451
4702
|
kind: "seqExpr",
|
|
4452
4703
|
stmts: [{ kind: "exprStmt", expr: arg, loc }],
|
|
@@ -4679,8 +4930,13 @@ function lowerDefaultToStringCall(lowerer, call, access) {
|
|
|
4679
4930
|
// throws "<callee> is not a function".
|
|
4680
4931
|
const nullProtoT = nullProtoRecordShape(lowerer, recvT);
|
|
4681
4932
|
const missing = nullProtoT ? `${ts.getTextOfNode(access)} is not a function` : null;
|
|
4933
|
+
// A linked copy or a record with a kept source answers as its source
|
|
4934
|
+
// does (record-links.ts).
|
|
4935
|
+
const linked = !missing && recvT.kind === "record" && recordMayKeepSource(lowerer, recvT);
|
|
4682
4936
|
if (!missing && pureObjectToStringReceiver(access.expression))
|
|
4683
|
-
return
|
|
4937
|
+
return linked
|
|
4938
|
+
? recordStringCall(lowerer, lowerer.lowerExpr(access.expression), "string", loc, "constant")
|
|
4939
|
+
: constant;
|
|
4684
4940
|
const recv = lowerer.lowerExpr(access.expression);
|
|
4685
4941
|
const key = `objToStr:${typeKey(recv.type)}${missing ? `:${missing}` : ""}`;
|
|
4686
4942
|
let helper = lowerer.valueHelpers.get(key);
|
|
@@ -4688,7 +4944,7 @@ function lowerDefaultToStringCall(lowerer, call, access) {
|
|
|
4688
4944
|
helper = keyedHelperName(lowerer, "%obj.tostr", key);
|
|
4689
4945
|
lowerer.valueHelpers.set(key, helper);
|
|
4690
4946
|
const o = varRef("o.0", recv.type, loc);
|
|
4691
|
-
|
|
4947
|
+
const fn = {
|
|
4692
4948
|
name: helper,
|
|
4693
4949
|
params: [{ localId: "o.0", name: "o", type: recv.type }],
|
|
4694
4950
|
returnType: STRING,
|
|
@@ -4703,7 +4959,10 @@ function lowerDefaultToStringCall(lowerer, call, access) {
|
|
|
4703
4959
|
},
|
|
4704
4960
|
],
|
|
4705
4961
|
loc,
|
|
4706
|
-
}
|
|
4962
|
+
};
|
|
4963
|
+
lowerer.liftedFns.push(fn);
|
|
4964
|
+
if (linked)
|
|
4965
|
+
registerLinkedHelper(lowerer, fn, recvT.shapeId, "string");
|
|
4707
4966
|
}
|
|
4708
4967
|
return { kind: "call", callee: helper, args: [recv], type: STRING, loc };
|
|
4709
4968
|
}
|
|
@@ -6781,6 +7040,7 @@ export function recordKeysArrayCall(lowerer, receiver, argIr, shape, loc) {
|
|
|
6781
7040
|
finalize();
|
|
6782
7041
|
lowerer.shapeOrderHelperFinalizers.push(finalize);
|
|
6783
7042
|
lowerer.liftedFns.push(fn);
|
|
7043
|
+
registerLinkedHelper(lowerer, fn, argIr.shapeId, "keys");
|
|
6784
7044
|
}
|
|
6785
7045
|
return { kind: "call", callee: helper, args: [receiver], type: resultT, loc };
|
|
6786
7046
|
}
|
|
@@ -6823,7 +7083,7 @@ export function recordHasOwnHelper(lowerer, shapeId, loc) {
|
|
|
6823
7083
|
? { kind: "recordOvfHas", obj: rRef, shapeId, key: kRef, type: BOOL, loc }
|
|
6824
7084
|
: { kind: "boolLit", value: false, type: BOOL, loc };
|
|
6825
7085
|
body.push({ kind: "return", value: fallback, loc });
|
|
6826
|
-
|
|
7086
|
+
const fn = {
|
|
6827
7087
|
name: helper,
|
|
6828
7088
|
params: [
|
|
6829
7089
|
{ localId: "r.0", name: "r", type: recT },
|
|
@@ -6836,14 +7096,15 @@ export function recordHasOwnHelper(lowerer, shapeId, loc) {
|
|
|
6836
7096
|
],
|
|
6837
7097
|
body,
|
|
6838
7098
|
loc,
|
|
6839
|
-
}
|
|
7099
|
+
};
|
|
7100
|
+
lowerer.liftedFns.push(fn);
|
|
7101
|
+
registerLinkedHelper(lowerer, fn, shapeId, "hasOwn");
|
|
6840
7102
|
// A record that kept undeclared keys answers an undeclared key through
|
|
6841
7103
|
// its kept view: the declared branches above stay exact (the table's
|
|
6842
7104
|
// placeholders only fill declared names the record owns), and the
|
|
6843
7105
|
// closed-shape `false` fallback becomes the view's own-key test when a
|
|
6844
7106
|
// kept width spread builds this shape.
|
|
6845
7107
|
if (!shape.indexValue && recordMayKeepSource(lowerer, recT)) {
|
|
6846
|
-
const fn = lowerer.liftedFns[lowerer.liftedFns.length - 1];
|
|
6847
7108
|
lowerer.shapeOrderHelperFinalizers.push(() => {
|
|
6848
7109
|
if (!lowerer.keyOrder.keptSourceShapes.has(shapeId))
|
|
6849
7110
|
return;
|
|
@@ -7024,6 +7285,12 @@ function lowerIteratorStaticFence(lowerer, call, access) {
|
|
|
7024
7285
|
const from = lowerIteratorFromCall(lowerer, call, access);
|
|
7025
7286
|
if (from)
|
|
7026
7287
|
return from;
|
|
7288
|
+
// Any other argument in JavaScript: the runtime's Iterator.from.
|
|
7289
|
+
if (access.name.text === "from" && !call.questionDotToken && !access.questionDotToken) {
|
|
7290
|
+
const dynamic = lowerIteratorFromDyn(lowerer, call);
|
|
7291
|
+
if (dynamic)
|
|
7292
|
+
return dynamic;
|
|
7293
|
+
}
|
|
7027
7294
|
lowerer.noLowering(`Iterator.${access.name.text}`, call, access.name.text === "from"
|
|
7028
7295
|
? "Iterator.from accepts arrays, strings, typed arrays, Sets, Maps and iterator objects such as generators"
|
|
7029
7296
|
: "iterator helpers apply directly to generators and to array, Map and Set iterators: " +
|
|
@@ -7138,6 +7405,29 @@ function isDynEntryPairsType(lowerer, t) {
|
|
|
7138
7405
|
const field = (name) => shape.fields.find((f) => f.name === name)?.type;
|
|
7139
7406
|
return field("0")?.kind === "string" && field("1")?.kind === "dyn";
|
|
7140
7407
|
}
|
|
7408
|
+
/** Object.seal, Object.freeze, Object.preventExtensions and their queries
|
|
7409
|
+
* over a byte view (a typed array or a DataView) in JavaScript code. A view
|
|
7410
|
+
* boxes BY REFERENCE and carries its integrity state on itself
|
|
7411
|
+
* (ScrBytes.properties), so the checked-dynamic operations model it exactly:
|
|
7412
|
+
* seal and freeze of a view with elements throw after making it
|
|
7413
|
+
* non-extensible, as in V8. seal, freeze and preventExtensions answer the
|
|
7414
|
+
* view itself, so the result converts back to the same view (a checked cast,
|
|
7415
|
+
* which preserves its identity) wherever the element type admits the
|
|
7416
|
+
* conversion — bytes<u8>, the DataView and Uint8Array case. A view of wider
|
|
7417
|
+
* elements stays checked-dynamic, which the discarded statement form and a
|
|
7418
|
+
* later comparison against the view both handle exactly. The queries answer
|
|
7419
|
+
* a boolean. */
|
|
7420
|
+
export function lowerBytesIntegrity(lowerer, fn, view, loc) {
|
|
7421
|
+
const query = fn.startsWith("dyn.is");
|
|
7422
|
+
const result = {
|
|
7423
|
+
kind: "libCall",
|
|
7424
|
+
fn,
|
|
7425
|
+
args: [lowerer.coerceToExpected(view, DYN)],
|
|
7426
|
+
type: query ? BOOL : DYN,
|
|
7427
|
+
loc,
|
|
7428
|
+
};
|
|
7429
|
+
return query ? result : lowerer.coerceToExpected(result, view.type);
|
|
7430
|
+
}
|
|
7141
7431
|
/** True when the expression is statically a PLAIN OBJECT at runtime: a dyn
|
|
7142
7432
|
* object literal, or a record (a literal, a clone, or any expression of a
|
|
7143
7433
|
* record type, which dynFrom boxes field by field). Both build an ordinary
|
|
@@ -7615,9 +7905,30 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
7615
7905
|
}
|
|
7616
7906
|
}
|
|
7617
7907
|
}
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7908
|
+
// An operand the CHECKER narrowed to one record ARM of its declared
|
|
7909
|
+
// union (`content?.type === "toolCall"` narrows the array element to
|
|
7910
|
+
// ToolCall, whose lowered value still carries the element's
|
|
7911
|
+
// `ToolCall | ToolResult`): the plan runs over the arm, and the
|
|
7912
|
+
// operand lowers through the CHECKED extraction — the same
|
|
7913
|
+
// `%union.narrow` every other arm-typed site uses, so a value that
|
|
7914
|
+
// is not that arm throws the catchable TypeError instead of being
|
|
7915
|
+
// copied through the wrong layout. The extraction yields the arm's
|
|
7916
|
+
// own record, so the write still mutates the value the program holds.
|
|
7917
|
+
const assignOperand = (node, probe) => {
|
|
7918
|
+
if (probe?.type.kind === "record")
|
|
7919
|
+
return probe.type;
|
|
7920
|
+
if (probe?.type.kind !== "union")
|
|
7921
|
+
return null;
|
|
7922
|
+
const site = lowerer.mapTypeOf(lowerer.typeOf(node));
|
|
7923
|
+
return site?.kind === "record" && lowerer.armTag(probe.type.unionId, site) >= 0
|
|
7924
|
+
? site
|
|
7925
|
+
: null;
|
|
7926
|
+
};
|
|
7927
|
+
const tOperand = assignOperand(call.arguments.nodes[0], tProbe);
|
|
7928
|
+
const sOperand = assignOperand(call.arguments.nodes[1], sProbe);
|
|
7929
|
+
if (tOperand?.kind === "record" && sOperand?.kind === "record") {
|
|
7930
|
+
const tShape = lowerer.shapes.get(tOperand.shapeId);
|
|
7931
|
+
const sShape = lowerer.shapes.get(sOperand.shapeId);
|
|
7621
7932
|
const ok = tShape &&
|
|
7622
7933
|
sShape &&
|
|
7623
7934
|
!tShape.tuple &&
|
|
@@ -7635,8 +7946,12 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
7635
7946
|
});
|
|
7636
7947
|
if (ok) {
|
|
7637
7948
|
const loc = locOf(call);
|
|
7638
|
-
const
|
|
7639
|
-
|
|
7949
|
+
const operand = (node, arm) => {
|
|
7950
|
+
const value = lowerer.lowerExpr(node);
|
|
7951
|
+
return value.type.kind === "record" ? value : lowerer.coerceToExpected(value, arm);
|
|
7952
|
+
};
|
|
7953
|
+
const target = operand(call.arguments.nodes[0], tOperand);
|
|
7954
|
+
const source = operand(call.arguments.nodes[1], sOperand);
|
|
7640
7955
|
if (target.type.kind === "record" && source.type.kind === "record") {
|
|
7641
7956
|
const helper = recordAssignHelper(lowerer, target.type.shapeId, source.type.shapeId, loc);
|
|
7642
7957
|
return { kind: "call", callee: helper, args: [target, source], type: target.type, loc };
|
|
@@ -8004,6 +8319,17 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
8004
8319
|
? extensible
|
|
8005
8320
|
: { kind: "unary", op: "!", operand: extensible, type: BOOL, loc: locOf(call) };
|
|
8006
8321
|
}
|
|
8322
|
+
// A byte view carries its integrity state on itself and boxes by
|
|
8323
|
+
// reference, so the checked-dynamic operations model these exactly.
|
|
8324
|
+
if (value.type.kind === "bytes" && isJsSourceFile(ts.getSourceFileOfNode(call))) {
|
|
8325
|
+
const operation = {
|
|
8326
|
+
preventExtensions: "dyn.preventExtensions",
|
|
8327
|
+
isExtensible: "dyn.isExtensible",
|
|
8328
|
+
seal: "dyn.seal",
|
|
8329
|
+
isSealed: "dyn.isSealed",
|
|
8330
|
+
};
|
|
8331
|
+
return lowerBytesIntegrity(lowerer, operation[member], value, locOf(call));
|
|
8332
|
+
}
|
|
8007
8333
|
if (member === "preventExtensions" || member === "seal") {
|
|
8008
8334
|
const integrity = lowerClassIntegrity(lowerer, call, member, value);
|
|
8009
8335
|
if (integrity)
|
|
@@ -8020,11 +8346,16 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
8020
8346
|
};
|
|
8021
8347
|
}
|
|
8022
8348
|
if (value.type.kind === "dyn") {
|
|
8349
|
+
// The kind is only known at runtime: the queries refuse a native
|
|
8350
|
+
// handle or a promise, whose integrity state scriptc does not track
|
|
8351
|
+
// (Object.preventExtensions and Object.seal do not change it, so any
|
|
8352
|
+
// answer would be invented). The static arms above keep the plain
|
|
8353
|
+
// queries for the kinds whose state is modeled.
|
|
8023
8354
|
const operation = {
|
|
8024
8355
|
preventExtensions: "dyn.preventExtensions",
|
|
8025
|
-
isExtensible: "dyn.
|
|
8356
|
+
isExtensible: "dyn.isExtensibleQuery",
|
|
8026
8357
|
seal: "dyn.seal",
|
|
8027
|
-
isSealed: "dyn.
|
|
8358
|
+
isSealed: "dyn.isSealedQuery",
|
|
8028
8359
|
};
|
|
8029
8360
|
const fn = operation[member];
|
|
8030
8361
|
if (!member.startsWith("is"))
|
|
@@ -8077,6 +8408,8 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
8077
8408
|
loc,
|
|
8078
8409
|
};
|
|
8079
8410
|
}
|
|
8411
|
+
if (probedKind === "bytes" && isJsSourceFile(ts.getSourceFileOfNode(call)))
|
|
8412
|
+
return lowerBytesIntegrity(lowerer, "dyn.isFrozen", lowerer.lowerExpr(argNode), locOf(call));
|
|
8080
8413
|
const value = lowerer.lowerExprExpecting(argNode, DYN);
|
|
8081
8414
|
return { kind: "libCall", fn: "dyn.isFrozen", args: [value], type: BOOL, loc: locOf(call) };
|
|
8082
8415
|
}
|
|
@@ -8135,6 +8468,8 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
8135
8468
|
return lowerNativeFreeze(lowerer, "array.freeze", value, locOf(call));
|
|
8136
8469
|
if (value.type.kind === "map" || value.type.kind === "set")
|
|
8137
8470
|
return lowerNativeFreeze(lowerer, "collection.preventExtensions", value, locOf(call));
|
|
8471
|
+
if (value.type.kind === "bytes" && isJsSourceFile(ts.getSourceFileOfNode(call)))
|
|
8472
|
+
return lowerBytesIntegrity(lowerer, "dyn.freeze", value, locOf(call));
|
|
8138
8473
|
lowerer.noLowering("Object.freeze of a possibly-aliased value", call, "freeze of a FRESH object/array literal (and of primitives) compiles — frozen-ness is unobservable there; an aliased target's later writes would need the runtime frozen bit");
|
|
8139
8474
|
}
|
|
8140
8475
|
// `Object.hasOwn(r, k)` over a RECORD receiver: a record's own-key set
|
|
@@ -8520,7 +8855,6 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
8520
8855
|
helper = keyedHelperName(lowerer, `%obj.${member}`, key);
|
|
8521
8856
|
const recT = argIr;
|
|
8522
8857
|
const ref = { kind: "varRef", localId: "r.0", type: recT, loc };
|
|
8523
|
-
const outRef = { kind: "varRef", localId: "out.0", type: resultT, loc };
|
|
8524
8858
|
const fn = {
|
|
8525
8859
|
name: helper,
|
|
8526
8860
|
params: [{ localId: "r.0", name: "r", type: recT }],
|
|
@@ -8532,189 +8866,290 @@ function lowerObjectStaticCall(lowerer, call, access) {
|
|
|
8532
8866
|
body: [],
|
|
8533
8867
|
loc,
|
|
8534
8868
|
};
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
const
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
//
|
|
8547
|
-
|
|
8548
|
-
const
|
|
8549
|
-
|
|
8550
|
-
const f = current.fields.find((x) => x.name === name);
|
|
8551
|
-
const raw = {
|
|
8552
|
-
kind: "recordGet",
|
|
8553
|
-
obj: ref,
|
|
8554
|
-
shapeId: argIr.shapeId,
|
|
8555
|
-
field: f.name,
|
|
8556
|
-
type: f.type,
|
|
8557
|
-
loc,
|
|
8558
|
-
};
|
|
8559
|
-
// The pushed element per member; null when the field's value
|
|
8560
|
-
// cannot flow into the result element type.
|
|
8561
|
-
const elemOf = (value, vt) => {
|
|
8562
|
-
if (!valueT)
|
|
8563
|
-
return null;
|
|
8564
|
-
if (typeEquals(vt, valueT))
|
|
8565
|
-
return value;
|
|
8566
|
-
if (valueT.kind === "dyn" && lowerer.dynConvertible(vt))
|
|
8567
|
-
return lowerer.coerceToExpected(value, DYN);
|
|
8568
|
-
if (valueT.kind === "union" && vt.kind !== "union") {
|
|
8569
|
-
const tag = lowerer.armTag(valueT.unionId, vt);
|
|
8570
|
-
if (tag >= 0) {
|
|
8571
|
-
return { kind: "unionWrap", unionId: valueT.unionId, tag, value, type: valueT, loc };
|
|
8572
|
-
}
|
|
8573
|
-
}
|
|
8869
|
+
// The statement that pushes field `f` of the record `obj` (of shape
|
|
8870
|
+
// `shapeId`), or the reason its value cannot flow into the result.
|
|
8871
|
+
const fieldPush = (obj, shapeId, f, out) => {
|
|
8872
|
+
const raw = {
|
|
8873
|
+
kind: "recordGet",
|
|
8874
|
+
obj,
|
|
8875
|
+
shapeId,
|
|
8876
|
+
field: f.name,
|
|
8877
|
+
type: f.type,
|
|
8878
|
+
loc,
|
|
8879
|
+
};
|
|
8880
|
+
// The pushed element per member; null when the field's value
|
|
8881
|
+
// cannot flow into the result element type.
|
|
8882
|
+
const elemOf = (value, vt) => {
|
|
8883
|
+
if (!valueT)
|
|
8574
8884
|
return null;
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
|
|
8579
|
-
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8585
|
-
|
|
8586
|
-
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
|
|
8592
|
-
|
|
8593
|
-
}
|
|
8594
|
-
else if (others.length === 1) {
|
|
8595
|
-
vt = others[0];
|
|
8596
|
-
// A UNIT other arm (`null | undefined` fields — the mixed-
|
|
8597
|
-
// defaults spread idiom; undefined was filtered above, so
|
|
8598
|
-
// the unit is null): units carry no payload, so the guarded
|
|
8599
|
-
// push writes the unit LITERAL — unionNarrow to a unit arm
|
|
8600
|
-
// (and unionWrap of a narrowed unit) is malformed IR; the
|
|
8601
|
-
// literal is the one legal unit spelling.
|
|
8602
|
-
value = isUnitType(vt)
|
|
8603
|
-
? { kind: "unitLit", unit: "null", type: vt, loc }
|
|
8604
|
-
: {
|
|
8605
|
-
kind: "unionNarrow",
|
|
8606
|
-
unionId: f.type.unionId,
|
|
8607
|
-
tag: lowerer.armTag(f.type.unionId, vt),
|
|
8608
|
-
value: raw,
|
|
8609
|
-
type: vt,
|
|
8610
|
-
loc,
|
|
8611
|
-
};
|
|
8612
|
-
}
|
|
8613
|
-
else {
|
|
8614
|
-
lowerer.unsupported("SC1090", call, `Object.${member} over '${lowerer.fmt(argIr)}' (field '${f.name}' is a multi-arm union that ` +
|
|
8615
|
-
"cannot re-tag into the result element type — read the fields directly)");
|
|
8616
|
-
}
|
|
8885
|
+
if (typeEquals(vt, valueT))
|
|
8886
|
+
return value;
|
|
8887
|
+
if (valueT.kind === "dyn" && lowerer.dynConvertible(vt))
|
|
8888
|
+
return lowerer.coerceToExpected(value, DYN);
|
|
8889
|
+
if (valueT.kind === "union" && vt.kind === "union") {
|
|
8890
|
+
// A field union that is a PROPER SUBSET of the element union
|
|
8891
|
+
// (`{ accent: number | string; scrollbarThumb: number | string
|
|
8892
|
+
// | undefined }` enumerates as `[string, number | string |
|
|
8893
|
+
// undefined][]`): every arm the field can hold is an arm of the
|
|
8894
|
+
// element union, so the box re-tags onto it — the same runtime
|
|
8895
|
+
// value under the element union's tag numbering.
|
|
8896
|
+
return lowerer.unionRetagMappable(vt.unionId, valueT.unionId)
|
|
8897
|
+
? lowerer.coerceToExpected(value, valueT)
|
|
8898
|
+
: null;
|
|
8899
|
+
}
|
|
8900
|
+
if (valueT.kind === "union" && vt.kind !== "union") {
|
|
8901
|
+
const tag = lowerer.armTag(valueT.unionId, vt);
|
|
8902
|
+
if (tag >= 0) {
|
|
8903
|
+
return { kind: "unionWrap", unionId: valueT.unionId, tag, value, type: valueT, loc };
|
|
8617
8904
|
}
|
|
8618
|
-
|
|
8619
|
-
|
|
8620
|
-
|
|
8905
|
+
}
|
|
8906
|
+
return null;
|
|
8907
|
+
};
|
|
8908
|
+
// Undefined-armed fields: the push is guarded by the field's
|
|
8909
|
+
// presence; a narrowed push re-tags the non-undefined arm.
|
|
8910
|
+
let guardUndefTag = null;
|
|
8911
|
+
let value = raw;
|
|
8912
|
+
let vt = f.type;
|
|
8913
|
+
if (f.type.kind === "union") {
|
|
8914
|
+
const undefTag = lowerer.armTag(f.type.unionId, UNDEFINED_T);
|
|
8915
|
+
if (undefTag >= 0) {
|
|
8916
|
+
guardUndefTag = undefTag;
|
|
8917
|
+
const arms = lowerer.unions.get(f.type.unionId)?.arms ?? [];
|
|
8918
|
+
const others = arms.filter((a) => a.kind !== "undefinedT");
|
|
8919
|
+
if (valueT?.kind === "dyn" || typeEquals(f.type, valueT ?? f.type)) {
|
|
8920
|
+
// The field union IS the result union (single-field shapes):
|
|
8921
|
+
// push the raw box — but then the undefined skip must NOT
|
|
8922
|
+
// narrow. Handled below via vt === valueT.
|
|
8923
|
+
value = raw;
|
|
8924
|
+
vt = f.type;
|
|
8925
|
+
}
|
|
8926
|
+
else if (others.length === 1) {
|
|
8927
|
+
vt = others[0];
|
|
8928
|
+
// A UNIT other arm (`null | undefined` fields — the mixed-
|
|
8929
|
+
// defaults spread idiom; undefined was filtered above, so
|
|
8930
|
+
// the unit is null): units carry no payload, so the guarded
|
|
8931
|
+
// push writes the unit LITERAL — unionNarrow to a unit arm
|
|
8932
|
+
// (and unionWrap of a narrowed unit) is malformed IR; the
|
|
8933
|
+
// literal is the one legal unit spelling.
|
|
8934
|
+
value = isUnitType(vt)
|
|
8935
|
+
? { kind: "unitLit", unit: "null", type: vt, loc }
|
|
8936
|
+
: {
|
|
8937
|
+
kind: "unionNarrow",
|
|
8938
|
+
unionId: f.type.unionId,
|
|
8939
|
+
tag: lowerer.armTag(f.type.unionId, vt),
|
|
8940
|
+
value: raw,
|
|
8941
|
+
type: vt,
|
|
8942
|
+
loc,
|
|
8943
|
+
};
|
|
8944
|
+
}
|
|
8945
|
+
else {
|
|
8946
|
+
return `field '${f.name}' is a multi-arm union that cannot re-tag into the result element type`;
|
|
8621
8947
|
}
|
|
8622
8948
|
}
|
|
8623
|
-
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8949
|
+
else if (valueT?.kind !== "dyn" &&
|
|
8950
|
+
!typeEquals(f.type, valueT ?? f.type) &&
|
|
8951
|
+
!(valueT?.kind === "union" && lowerer.unionRetagMappable(f.type.unionId, valueT.unionId))) {
|
|
8952
|
+
return `field '${f.name}' is a union that cannot re-tag into the result element type`;
|
|
8627
8953
|
}
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8954
|
+
}
|
|
8955
|
+
const coerced = elemOf(value, vt);
|
|
8956
|
+
if (!coerced) {
|
|
8957
|
+
return (`field '${f.name}' of type '${lowerer.fmt(f.type)}' ` +
|
|
8958
|
+
`cannot flow into the '${lowerer.fmt(valueT)}' result element`);
|
|
8959
|
+
}
|
|
8960
|
+
const pushOf = (element) => ({
|
|
8961
|
+
kind: "exprStmt",
|
|
8962
|
+
expr: {
|
|
8963
|
+
kind: "arrIntrinsic",
|
|
8964
|
+
method: "push",
|
|
8965
|
+
receiver: out,
|
|
8966
|
+
args: [
|
|
8967
|
+
member === "values"
|
|
8968
|
+
? element
|
|
8969
|
+
: {
|
|
8970
|
+
kind: "recordLit",
|
|
8971
|
+
fields: [
|
|
8972
|
+
{ name: "0", value: { kind: "strLit", value: f.name, type: STRING, loc } },
|
|
8973
|
+
{ name: "1", value: element },
|
|
8974
|
+
],
|
|
8975
|
+
type: tupleT,
|
|
8976
|
+
loc,
|
|
8977
|
+
},
|
|
8978
|
+
],
|
|
8979
|
+
type: F64,
|
|
8650
8980
|
loc,
|
|
8651
|
-
}
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8666
|
-
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8981
|
+
},
|
|
8982
|
+
loc,
|
|
8983
|
+
});
|
|
8984
|
+
let stmt = pushOf(coerced);
|
|
8985
|
+
if (guardUndefTag !== null && f.type.kind === "union") {
|
|
8986
|
+
if (value !== raw) {
|
|
8987
|
+
// A narrowed push: a present field holding undefined pushes
|
|
8988
|
+
// the result element's own undefined when it has one; a values
|
|
8989
|
+
// array without one stores a present undefined element (a
|
|
8990
|
+
// runtime-optional field the checker typed as required). An
|
|
8991
|
+
// entries tuple slot has no spelling for it.
|
|
8992
|
+
const undefinedElement = valueT ? lowerer.wrappedUndefined(valueT, loc) : null;
|
|
8993
|
+
const undefinedPush = undefinedElement
|
|
8994
|
+
? pushOf(undefinedElement)
|
|
8995
|
+
: member === "values"
|
|
8996
|
+
? {
|
|
8997
|
+
kind: "arraySetUndefined",
|
|
8998
|
+
arr: out,
|
|
8999
|
+
index: {
|
|
9000
|
+
kind: "arrIntrinsic",
|
|
9001
|
+
method: "length",
|
|
9002
|
+
receiver: out,
|
|
9003
|
+
args: [],
|
|
9004
|
+
type: F64,
|
|
8675
9005
|
loc,
|
|
8676
|
-
}
|
|
8677
|
-
: null;
|
|
8678
|
-
stmt = {
|
|
8679
|
-
kind: "if",
|
|
8680
|
-
cond: {
|
|
8681
|
-
kind: "unionIsTag",
|
|
8682
|
-
unionId: f.type.unionId,
|
|
8683
|
-
tag: guardUndefTag,
|
|
8684
|
-
negated: true,
|
|
8685
|
-
value: raw,
|
|
8686
|
-
type: BOOL,
|
|
9006
|
+
},
|
|
8687
9007
|
loc,
|
|
8688
|
-
}
|
|
8689
|
-
|
|
8690
|
-
else_: undefinedPush ? [undefinedPush] : null,
|
|
8691
|
-
loc,
|
|
8692
|
-
};
|
|
8693
|
-
}
|
|
8694
|
-
// Absent fields contribute nothing; present ones push their
|
|
8695
|
-
// value, undefined included.
|
|
9008
|
+
}
|
|
9009
|
+
: null;
|
|
8696
9010
|
stmt = {
|
|
8697
9011
|
kind: "if",
|
|
8698
|
-
cond:
|
|
9012
|
+
cond: {
|
|
9013
|
+
kind: "unionIsTag",
|
|
9014
|
+
unionId: f.type.unionId,
|
|
9015
|
+
tag: guardUndefTag,
|
|
9016
|
+
negated: true,
|
|
9017
|
+
value: raw,
|
|
9018
|
+
type: BOOL,
|
|
9019
|
+
loc,
|
|
9020
|
+
},
|
|
8699
9021
|
then: [stmt],
|
|
8700
|
-
else_: null,
|
|
9022
|
+
else_: undefinedPush ? [undefinedPush] : null,
|
|
8701
9023
|
loc,
|
|
8702
9024
|
};
|
|
8703
9025
|
}
|
|
8704
|
-
|
|
9026
|
+
// Absent fields contribute nothing; present ones push their
|
|
9027
|
+
// value, undefined included.
|
|
9028
|
+
stmt = {
|
|
9029
|
+
kind: "if",
|
|
9030
|
+
cond: lowerer.recordFieldPresent(obj, shapeId, f.name, loc),
|
|
9031
|
+
then: [stmt],
|
|
9032
|
+
else_: null,
|
|
9033
|
+
loc,
|
|
9034
|
+
};
|
|
8705
9035
|
}
|
|
8706
|
-
|
|
8707
|
-
|
|
8708
|
-
|
|
9036
|
+
return stmt;
|
|
9037
|
+
};
|
|
9038
|
+
// The walk that pushes the fields of `obj` (of `current`) into out.0,
|
|
9039
|
+
// one walk per key order (see perKeyOrder). `refused` answers a field
|
|
9040
|
+
// whose value cannot flow into the result.
|
|
9041
|
+
// The walk that pushes the fields of `obj` (of `current`) into the
|
|
9042
|
+
// local `outId` and returns it, one walk per key order (see
|
|
9043
|
+
// perKeyOrder). `refused` answers a field whose value cannot flow into
|
|
9044
|
+
// the result.
|
|
9045
|
+
const fieldWalk = (obj, current, outId, refused) => {
|
|
9046
|
+
const out = { kind: "varRef", localId: outId, type: resultT, loc };
|
|
9047
|
+
const orders = shapeKeyOrders(current);
|
|
9048
|
+
const walks = orders.map(() => []);
|
|
9049
|
+
for (const [k, name] of orders.flatMap((order, k) => order.map((name) => [k, name]))) {
|
|
9050
|
+
const f = current.fields.find((x) => x.name === name);
|
|
9051
|
+
const stmt = fieldPush(obj, current.id, f, out);
|
|
9052
|
+
walks[k].push(typeof stmt === "string" ? refused(stmt) : stmt);
|
|
9053
|
+
}
|
|
9054
|
+
return [
|
|
9055
|
+
{
|
|
9056
|
+
kind: "varDecl",
|
|
9057
|
+
localId: outId,
|
|
9058
|
+
init: { kind: "arrayLit", elems: [], type: resultT, loc },
|
|
9059
|
+
loc,
|
|
9060
|
+
},
|
|
9061
|
+
...perKeyOrder(current, obj, walks, loc),
|
|
9062
|
+
{ kind: "return", value: out, loc },
|
|
9063
|
+
];
|
|
9064
|
+
};
|
|
9065
|
+
const finalize = () => {
|
|
9066
|
+
const latest = lowerer.shapes.get(argIr.shapeId);
|
|
9067
|
+
const current = latest !== undefined ? latest : shape;
|
|
9068
|
+
fn.body = fieldWalk(ref, current, "out.0", (reason) => lowerer.unsupported("SC1090", call, `Object.${member} over '${lowerer.fmt(argIr)}' (${reason} — read the fields directly)`));
|
|
8709
9069
|
};
|
|
8710
9070
|
finalize();
|
|
8711
9071
|
lowerer.arrHofHelpers.set(key, helper);
|
|
8712
9072
|
lowerer.shapeOrderHelperFinalizers.push(finalize);
|
|
8713
9073
|
lowerer.liftedFns.push(fn);
|
|
9074
|
+
// A linked copy lists its source's fields. When one of them cannot
|
|
9075
|
+
// flow into the result, the copy answers as a kept source does: its
|
|
9076
|
+
// checked view's values, checked into the result (which throws).
|
|
9077
|
+
registerLinkedHelper(lowerer, fn, argIr.shapeId, "custom");
|
|
9078
|
+
lowerer.linkedHelperFinalizers.push(() => {
|
|
9079
|
+
// The answer for the composed record of a link, which can itself be
|
|
9080
|
+
// a linked copy or keep a checked source: their properties come first.
|
|
9081
|
+
// `path` holds the record types the links followed so far. Two types
|
|
9082
|
+
// can link both ways (each lacks an optional field of the other): a
|
|
9083
|
+
// composed record of this helper's own type calls the helper, and one
|
|
9084
|
+
// of another type on the path answers from its checked view.
|
|
9085
|
+
const answerAt = (path) => (composed) => {
|
|
9086
|
+
const composedT = composed.type;
|
|
9087
|
+
const sourceShape = lowerer.shapes.get(composedT.shapeId);
|
|
9088
|
+
const view = { kind: "dynFrom", value: composed, liveRef: true, type: DYN, loc };
|
|
9089
|
+
const viewAnswer = {
|
|
9090
|
+
kind: "return",
|
|
9091
|
+
value: {
|
|
9092
|
+
kind: "dynCheck",
|
|
9093
|
+
value: {
|
|
9094
|
+
kind: "libCall",
|
|
9095
|
+
fn: member === "values" ? "dyn.objValues" : "dyn.objEntries",
|
|
9096
|
+
args: [view],
|
|
9097
|
+
type: DYN,
|
|
9098
|
+
loc,
|
|
9099
|
+
},
|
|
9100
|
+
type: resultT,
|
|
9101
|
+
loc,
|
|
9102
|
+
},
|
|
9103
|
+
loc,
|
|
9104
|
+
};
|
|
9105
|
+
if (composedT.shapeId === argIr.shapeId)
|
|
9106
|
+
return [
|
|
9107
|
+
{
|
|
9108
|
+
kind: "return",
|
|
9109
|
+
value: { kind: "call", callee: fn.name, args: [composed], type: resultT, loc },
|
|
9110
|
+
loc,
|
|
9111
|
+
},
|
|
9112
|
+
];
|
|
9113
|
+
if (path.has(composedT.shapeId))
|
|
9114
|
+
return [viewAnswer];
|
|
9115
|
+
let fits = true;
|
|
9116
|
+
const walk = fieldWalk(composed, sourceShape, linkedOut(fn, resultT), () => {
|
|
9117
|
+
fits = false;
|
|
9118
|
+
return {
|
|
9119
|
+
kind: "exprStmt",
|
|
9120
|
+
expr: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc },
|
|
9121
|
+
loc,
|
|
9122
|
+
};
|
|
9123
|
+
});
|
|
9124
|
+
const further = linkedCopyBranches(lowerer, fn, composed, composedT.shapeId, answerAt(new Set([...path, composedT.shapeId])));
|
|
9125
|
+
if (!fits)
|
|
9126
|
+
return [...further, viewAnswer];
|
|
9127
|
+
if (!recordMayKeepSource(lowerer, composedT))
|
|
9128
|
+
return [...further, ...walk];
|
|
9129
|
+
return [
|
|
9130
|
+
...further,
|
|
9131
|
+
{
|
|
9132
|
+
kind: "if",
|
|
9133
|
+
cond: recordSourceTest(composed, loc),
|
|
9134
|
+
then: [viewAnswer],
|
|
9135
|
+
else_: null,
|
|
9136
|
+
loc,
|
|
9137
|
+
},
|
|
9138
|
+
...walk,
|
|
9139
|
+
];
|
|
9140
|
+
};
|
|
9141
|
+
answerLinkedCopies(lowerer, fn, argIr.shapeId, answerAt(new Set([argIr.shapeId])));
|
|
9142
|
+
});
|
|
8714
9143
|
}
|
|
8715
9144
|
const callee = helper;
|
|
8716
9145
|
return sourced((receiver) => ({ kind: "call", callee, args: [receiver], type: resultT, loc }));
|
|
8717
9146
|
}
|
|
9147
|
+
/** A fresh hidden local of `fn` for a linked copy's values or entries. */
|
|
9148
|
+
function linkedOut(fn, type) {
|
|
9149
|
+
const id = `linkedOut.${fn.locals.length}`;
|
|
9150
|
+
fn.locals.push({ id, name: "linkedOut", type, mutable: false });
|
|
9151
|
+
return id;
|
|
9152
|
+
}
|
|
8718
9153
|
/** An entries array consumed pair by pair right where it is built: a
|
|
8719
9154
|
* for-of loop or an array callback method. These consumers bind each pair
|
|
8720
9155
|
* from the array's own layout, so the pair's value slot can keep a
|
|
@@ -8996,6 +9431,60 @@ export function lowerRecordFieldCall(lowerer, call, access) {
|
|
|
8996
9431
|
lowerer.unsupported("SC1090", call, `calling a function field of a '${lowerer.fmt(target.obj.type)}' record (the record has no dynamic form to pass as 'this')`);
|
|
8997
9432
|
}
|
|
8998
9433
|
}
|
|
9434
|
+
// A generic member's field holds its erased instance, and the call
|
|
9435
|
+
// through the field crosses the same boundary as one through the
|
|
9436
|
+
// instance value itself: the conversions that would copy are refused
|
|
9437
|
+
// here too.
|
|
9438
|
+
refuseCopyingErasureInstanceCall(lowerer, call, callee);
|
|
9439
|
+
// A rest-marked field value hides one synthetic trailing dyn array in
|
|
9440
|
+
// its lifted signature — the checked variadic ABI a JS rest closure
|
|
9441
|
+
// has, and the one a generic member's erased instance keeps when its
|
|
9442
|
+
// erased signature cannot pin the tail (`...args: EventArguments<…>`, a
|
|
9443
|
+
// conditional tuple over the member's own type parameters). The call
|
|
9444
|
+
// passes that slot natively, so a record or array the callee returns
|
|
9445
|
+
// comes back as the object it returned, exactly as JavaScript hands it
|
|
9446
|
+
// back; the boxed thunk would copy it and break identity and mutation
|
|
9447
|
+
// sharing. A call that leaves an omitted parameter without an absent
|
|
9448
|
+
// spelling still rides the thunk (JavaScript's own arity).
|
|
9449
|
+
if (init === null &&
|
|
9450
|
+
receiver === undefined &&
|
|
9451
|
+
callee.type.rest === true &&
|
|
9452
|
+
callee.type.restAbi === undefined &&
|
|
9453
|
+
!call.arguments.nodes.some(ts.isSpreadElement) &&
|
|
9454
|
+
canBoxFuncIntoDyn(callee.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
9455
|
+
const nativeArgs = checkedRestCallArgs(lowerer, call, callee.type, loc);
|
|
9456
|
+
if (nativeArgs) {
|
|
9457
|
+
// The resolved result converts exactly like the fixed-arity lane
|
|
9458
|
+
// below; a void result needs no conversion (the call's own value is
|
|
9459
|
+
// discarded, as an `unknown` has no void spelling).
|
|
9460
|
+
let nativeResult = {
|
|
9461
|
+
kind: "callValue",
|
|
9462
|
+
callee,
|
|
9463
|
+
args: nativeArgs,
|
|
9464
|
+
type: callee.type.ret,
|
|
9465
|
+
loc,
|
|
9466
|
+
};
|
|
9467
|
+
const resolved = lowerer.irTypeOf(call);
|
|
9468
|
+
if (resolved.kind !== "void" &&
|
|
9469
|
+
isGenericCallableMemberType(lowerer.typeOf(access), lowerer.checker))
|
|
9470
|
+
nativeResult = lowerer.coerceInto(call, nativeResult, resolved);
|
|
9471
|
+
return nativeResult;
|
|
9472
|
+
}
|
|
9473
|
+
const boxed = { kind: "dynFrom", value: callee, type: DYN, loc };
|
|
9474
|
+
let boxedResult = {
|
|
9475
|
+
kind: "dynCall",
|
|
9476
|
+
callee: boxed,
|
|
9477
|
+
calleeName: v8CalleeText(call.expression),
|
|
9478
|
+
args: call.arguments.nodes.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
9479
|
+
type: DYN,
|
|
9480
|
+
loc,
|
|
9481
|
+
};
|
|
9482
|
+
const resolved = lowerer.irTypeOf(call);
|
|
9483
|
+
if (resolved.kind !== "void" &&
|
|
9484
|
+
isGenericCallableMemberType(lowerer.typeOf(access), lowerer.checker))
|
|
9485
|
+
boxedResult = lowerer.coerceInto(call, boxedResult, resolved);
|
|
9486
|
+
return boxedResult;
|
|
9487
|
+
}
|
|
8999
9488
|
const args = completeFuncValueArgs(lowerer, call, callee.type, locOf(call));
|
|
9000
9489
|
let result = {
|
|
9001
9490
|
kind: "callValue",
|
|
@@ -9029,9 +9518,11 @@ export function lowerRecordFieldCall(lowerer, call, access) {
|
|
|
9029
9518
|
/** The URL factories use the constructor's conversion order and parser.
|
|
9030
9519
|
* URL.revokeObjectURL() with NO argument: Node's ERR_MISSING_ARGS
|
|
9031
9520
|
* throws before the registry lookup, so the zero-argument contract is
|
|
9032
|
-
* exact without any blob machinery. The one-argument form
|
|
9033
|
-
*
|
|
9034
|
-
*
|
|
9521
|
+
* exact without any blob machinery. The one-argument form coerces the
|
|
9522
|
+
* id to a string (a Symbol throws) and finds nothing registered — a
|
|
9523
|
+
* compiled program cannot create a blob URL, so the lookup always
|
|
9524
|
+
* misses and the call is its own coercion. createObjectURL keeps its
|
|
9525
|
+
* fence: there is no blob registry to register into. */
|
|
9035
9526
|
function lowerUrlStaticCall(lowerer, call, callee) {
|
|
9036
9527
|
if (!ts.isPropertyAccessExpression(callee) || callee.questionDotToken !== undefined)
|
|
9037
9528
|
return null;
|
|
@@ -9043,9 +9534,20 @@ function lowerUrlStaticCall(lowerer, call, callee) {
|
|
|
9043
9534
|
if (callee.name.text === "canParse" || callee.name.text === "parse") {
|
|
9044
9535
|
return lowerUrlFactory(lowerer, call, callee.name.text);
|
|
9045
9536
|
}
|
|
9046
|
-
if (callee.name.text !== "revokeObjectURL"
|
|
9537
|
+
if (callee.name.text !== "revokeObjectURL")
|
|
9047
9538
|
return null;
|
|
9048
|
-
|
|
9539
|
+
const args = call.arguments.nodes;
|
|
9540
|
+
if (args.length === 0) {
|
|
9541
|
+
return nodeThrowExpr(1, "ERR_MISSING_ARGS", 'The "url" argument must be specified', VOID, locOf(call));
|
|
9542
|
+
}
|
|
9543
|
+
if (args.length !== 1)
|
|
9544
|
+
return null;
|
|
9545
|
+
const arg = args[0];
|
|
9546
|
+
const id = lowerer.lowerExpr(arg);
|
|
9547
|
+
const text = id.type.kind === "url"
|
|
9548
|
+
? { kind: "libCall", fn: "url.href", args: [id], type: STRING, loc: locOf(arg) }
|
|
9549
|
+
: lowerer.ensureString(id, arg);
|
|
9550
|
+
return { kind: "libCall", fn: "url.revokeObjectURL", args: [text], type: VOID, loc: locOf(call) };
|
|
9049
9551
|
}
|
|
9050
9552
|
const SP_BRAND_METHODS = new Set([
|
|
9051
9553
|
"append",
|
|
@@ -9250,10 +9752,84 @@ function lowerArrowFunctionApply(lowerer, call, access) {
|
|
|
9250
9752
|
}
|
|
9251
9753
|
return { kind: "seqExpr", stmts, result, type: DYN, loc };
|
|
9252
9754
|
}
|
|
9755
|
+
/** The Promise statics whose generic algorithms depend only on the `this`
|
|
9756
|
+
* constructor: NewPromiseCapability(C), GetPromiseResolve(C) and the
|
|
9757
|
+
* iterator protocol. scr_js_promise_generic.c runs them for a `this` that
|
|
9758
|
+
* is not %Promise%. `withResolvers` and `try` take no iterable and stay
|
|
9759
|
+
* refused (their capability shapes have no dynamic representation yet). */
|
|
9760
|
+
const PROMISE_GENERIC_STATICS = new Set([
|
|
9761
|
+
"all",
|
|
9762
|
+
"allSettled",
|
|
9763
|
+
"any",
|
|
9764
|
+
"race",
|
|
9765
|
+
"resolve",
|
|
9766
|
+
"reject",
|
|
9767
|
+
]);
|
|
9253
9768
|
function lowerObjLitGenericMethodCall(lowerer, call, access) {
|
|
9254
9769
|
if (lowerer.chainBlocked(access, call))
|
|
9255
9770
|
return null;
|
|
9256
9771
|
const name = access.name.text;
|
|
9772
|
+
// The Promise statics through Function.prototype.call with ANY `this`
|
|
9773
|
+
// (`Promise.all.call(NotPromise, iterable)`): the specification's
|
|
9774
|
+
// algorithms over NewPromiseCapability(C), where %Promise% answers the
|
|
9775
|
+
// ordinary implementation. A `.js` source only — the arm replaces the
|
|
9776
|
+
// checked-value fence below, so no typed program changes shape. The
|
|
9777
|
+
// runtime unit scr_js_promise_generic.c runs the generic steps; the
|
|
9778
|
+
// builtin function's own thunk (dyn_builtin_fn_call) does not grow.
|
|
9779
|
+
if (name === "call" && !call.questionDotToken && isJsSourceFile(ts.getSourceFileOfNode(call))) {
|
|
9780
|
+
const stat = ts.isPropertyAccessExpression(access.expression)
|
|
9781
|
+
? lowerer.stdlibGlobalMember(access.expression, "Promise")
|
|
9782
|
+
: null;
|
|
9783
|
+
if (stat !== null &&
|
|
9784
|
+
PROMISE_GENERIC_STATICS.has(stat) &&
|
|
9785
|
+
!call.arguments.nodes.some(ts.isSpreadElement)) {
|
|
9786
|
+
const loc = locOf(call);
|
|
9787
|
+
const thisArg = call.arguments.nodes[0];
|
|
9788
|
+
const value = call.arguments.nodes[1];
|
|
9789
|
+
// `Promise.all.call(Promise, …)` is the ordinary call: the runtime
|
|
9790
|
+
// recognizes %Promise% by identity and forwards to the native
|
|
9791
|
+
// implementation. The global read yields the interned constructor
|
|
9792
|
+
// value (`dyn.globalConstructor`) — exactly the identity compared —
|
|
9793
|
+
// rather than the reflected-value fence a stdlib global read as a
|
|
9794
|
+
// `.call` receiver otherwise reports.
|
|
9795
|
+
let thisIr = !thisArg
|
|
9796
|
+
? dynUndefinedExpr(loc)
|
|
9797
|
+
: stdlibGlobalNameOf(lowerer, thisArg) === "Promise"
|
|
9798
|
+
? (builtinGlobalValue("Promise", loc, true) ?? lowerer.lowerExprExpecting(thisArg, DYN))
|
|
9799
|
+
: lowerer.lowerExprExpecting(thisArg, DYN);
|
|
9800
|
+
let valueIr = value ? lowerer.lowerExprExpecting(value, DYN) : dynUndefinedExpr(loc);
|
|
9801
|
+
const callOf = (receiver, iterable) => ({
|
|
9802
|
+
kind: "libCall",
|
|
9803
|
+
fn: "promise.genericStatic",
|
|
9804
|
+
args: [{ kind: "strLit", value: stat, type: STRING, loc }, receiver, iterable],
|
|
9805
|
+
type: DYN,
|
|
9806
|
+
loc,
|
|
9807
|
+
});
|
|
9808
|
+
// The algorithm reads only the first two arguments, but Node evaluates
|
|
9809
|
+
// every argument of the call before it runs: the receiver and the
|
|
9810
|
+
// iterable first, then each surplus argument, in source order. Hold the
|
|
9811
|
+
// two the unit reads in hidden locals so the surplus arguments'
|
|
9812
|
+
// effects and exceptions happen after them, and drop their values.
|
|
9813
|
+
const surplus = call.arguments.nodes.slice(2);
|
|
9814
|
+
if (surplus.length === 0)
|
|
9815
|
+
return callOf(thisIr, valueIr);
|
|
9816
|
+
const holds = [];
|
|
9817
|
+
// Both are lowered into the checked-dynamic slot, so each is a dyn value
|
|
9818
|
+
// a hidden local can hold.
|
|
9819
|
+
const hold = (expr, name) => {
|
|
9820
|
+
const local = lowerer.declareHiddenLocal(name, expr.type);
|
|
9821
|
+
holds.push({ kind: "varDecl", localId: local.id, init: expr, loc });
|
|
9822
|
+
return varRef(local.id, expr.type, loc);
|
|
9823
|
+
};
|
|
9824
|
+
thisIr = hold(thisIr, "%promiseStaticThis");
|
|
9825
|
+
valueIr = hold(valueIr, "%promiseStaticIterable");
|
|
9826
|
+
for (const arg of surplus) {
|
|
9827
|
+
const argIr = lowerer.lowerExprExpecting(arg, DYN);
|
|
9828
|
+
holds.push({ kind: "exprStmt", expr: argIr, loc: locOf(arg) });
|
|
9829
|
+
}
|
|
9830
|
+
return { kind: "seqExpr", stmts: holds, result: callOf(thisIr, valueIr), type: DYN, loc };
|
|
9831
|
+
}
|
|
9832
|
+
}
|
|
9257
9833
|
// URLSearchParams method values through Function.prototype.call/apply
|
|
9258
9834
|
// with a receiver that is provably NOT a URLSearchParams (the suite's
|
|
9259
9835
|
// `params.append.call(undefined)` probes): the WHATWG brand check
|
|
@@ -10626,4 +11202,130 @@ function checkedDynamicOperand(expr) {
|
|
|
10626
11202
|
return expr;
|
|
10627
11203
|
return expr.kind === "dynCheck" && expr.value.type.kind === "dyn" ? expr.value : null;
|
|
10628
11204
|
}
|
|
11205
|
+
/** The class of the object `node` is statically, or null. */
|
|
11206
|
+
function objectClassOf(lowerer, node) {
|
|
11207
|
+
let t;
|
|
11208
|
+
try {
|
|
11209
|
+
t = lowerer.mapTypeOf(lowerer.typeOf(node));
|
|
11210
|
+
}
|
|
11211
|
+
catch {
|
|
11212
|
+
return null;
|
|
11213
|
+
}
|
|
11214
|
+
if (t?.kind !== "object")
|
|
11215
|
+
return null;
|
|
11216
|
+
return lowerer.classes.get(t.className) ?? null;
|
|
11217
|
+
}
|
|
11218
|
+
/** The class of an EventEmitter instance (not a stream) that `node` is
|
|
11219
|
+
* statically, or null. */
|
|
11220
|
+
function plainEmitterInfoOf(lowerer, node) {
|
|
11221
|
+
const info = objectClassOf(lowerer, node);
|
|
11222
|
+
return info && emitterRooted(lowerer, info) && streamSidesOf(lowerer, info) === null
|
|
11223
|
+
? info
|
|
11224
|
+
: null;
|
|
11225
|
+
}
|
|
11226
|
+
/** `R.<method>.call(thisArg, ...args)` where `R.<method>` is
|
|
11227
|
+
* EventEmitter.prototype's method: R is `EventEmitter.prototype` or an
|
|
11228
|
+
* EventEmitter instance (not a stream) whose class does not override
|
|
11229
|
+
* `emit`, read without effects. Node runs the method with thisArg as
|
|
11230
|
+
* `this`. A thisArg that is statically such an emitter takes the method's
|
|
11231
|
+
* typed lowering with thisArg as the receiver and static dispatch (the
|
|
11232
|
+
* super spelling); any other thisArg calls the untyped
|
|
11233
|
+
* EventEmitter.prototype method, which works on the object's `_events`.
|
|
11234
|
+
* Null for every other shape. */
|
|
11235
|
+
function lowerEmitterMethodValueCall(lowerer, call, access) {
|
|
11236
|
+
const target = access.expression;
|
|
11237
|
+
if (!ts.isPropertyAccessExpression(target) || target.questionDotToken)
|
|
11238
|
+
return null;
|
|
11239
|
+
const member = target.name.text;
|
|
11240
|
+
if (!EMITTER_API_MEMBERS.has(member))
|
|
11241
|
+
return null;
|
|
11242
|
+
const holderNode = target.expression;
|
|
11243
|
+
const emitterKind = builtinClassKind(RUNTIME_EMITTER_CLASS);
|
|
11244
|
+
const isPrototype = ts.isPropertyAccessExpression(holderNode) &&
|
|
11245
|
+
holderNode.name.text === "prototype" &&
|
|
11246
|
+
builtinClassKindOf(lowerer, holderNode.expression) === emitterKind;
|
|
11247
|
+
// `EventEmitter.prototype` is a builtin read; any other holder must be
|
|
11248
|
+
// effect-free, or its getter (and its exceptions) would be skipped.
|
|
11249
|
+
if (!isPrototype && !isPureReference(lowerer, holderNode))
|
|
11250
|
+
return null;
|
|
11251
|
+
const holder = isPrototype ? null : plainEmitterInfoOf(lowerer, holderNode);
|
|
11252
|
+
if (!isPrototype && (!holder || (member === "emit" && emitOverrideAtOrAbove(holder))))
|
|
11253
|
+
return null;
|
|
11254
|
+
const args = call.arguments.nodes;
|
|
11255
|
+
if (args.length === 0 || args.some(ts.isSpreadElement))
|
|
11256
|
+
return null;
|
|
11257
|
+
const thisArg = args[0];
|
|
11258
|
+
const thisInfo = plainEmitterInfoOf(lowerer, thisArg);
|
|
11259
|
+
const thisClass = objectClassOf(lowerer, thisArg);
|
|
11260
|
+
if (!thisInfo &&
|
|
11261
|
+
thisClass !== null &&
|
|
11262
|
+
emitterRooted(lowerer, thisClass) &&
|
|
11263
|
+
streamSidesOf(lowerer, thisClass) !== null) {
|
|
11264
|
+
// A stream keeps its own event table: the untyped method would read
|
|
11265
|
+
// fields the compiled stream does not have.
|
|
11266
|
+
lowerer.noLowering(`EventEmitter.prototype.${member}.call on a stream`, call, "call the method on the stream directly");
|
|
11267
|
+
}
|
|
11268
|
+
if (thisInfo && member === "emit" && emitOverrideAtOrAbove(thisInfo)) {
|
|
11269
|
+
lowerer.noLowering("EventEmitter.prototype.emit called on an instance whose class overrides emit", call, "call the override, or emit from a class that does not override emit");
|
|
11270
|
+
}
|
|
11271
|
+
if (thisInfo) {
|
|
11272
|
+
const thisRef = lowerer.lowerExpr(thisArg);
|
|
11273
|
+
if (thisRef.type.kind !== "object")
|
|
11274
|
+
return null;
|
|
11275
|
+
return lowerEmitterMethodCall(lowerer, call, target, thisInfo, { thisRef, cls: thisInfo }, args.slice(1));
|
|
11276
|
+
}
|
|
11277
|
+
const loc = locOf(call);
|
|
11278
|
+
const prototype = {
|
|
11279
|
+
kind: "dynKeyGet",
|
|
11280
|
+
value: builtinClassValue(emitterKind, loc),
|
|
11281
|
+
key: { kind: "strLit", value: "prototype", type: STRING, loc },
|
|
11282
|
+
type: DYN,
|
|
11283
|
+
loc,
|
|
11284
|
+
};
|
|
11285
|
+
return {
|
|
11286
|
+
kind: "dynInvoke",
|
|
11287
|
+
recv: {
|
|
11288
|
+
kind: "dynKeyGet",
|
|
11289
|
+
value: prototype,
|
|
11290
|
+
key: { kind: "strLit", value: member, type: STRING, loc },
|
|
11291
|
+
type: DYN,
|
|
11292
|
+
loc,
|
|
11293
|
+
},
|
|
11294
|
+
method: "call",
|
|
11295
|
+
calleeName: ts.getTextOfNode(access),
|
|
11296
|
+
args: args.map((arg) => lowerer.lowerExprExpecting(arg, DYN)),
|
|
11297
|
+
type: DYN,
|
|
11298
|
+
loc,
|
|
11299
|
+
};
|
|
11300
|
+
}
|
|
11301
|
+
/** atob(data) / btoa(data), the globals and node:buffer's members (the same
|
|
11302
|
+
* functions in Node): str.atob / str.btoa over the argument as a dyn value,
|
|
11303
|
+
* str.b64Missing for the zero-argument call. */
|
|
11304
|
+
export function lowerBase64Call(lowerer, expr, name, loc) {
|
|
11305
|
+
if (expr.arguments.nodes.length === 0) {
|
|
11306
|
+
return { kind: "libCall", fn: "str.b64Missing", args: [], type: STRING, loc };
|
|
11307
|
+
}
|
|
11308
|
+
if (expr.arguments.nodes.length > 1) {
|
|
11309
|
+
lowerer.noLowering(`${name} with ${expr.arguments.nodes.length} arguments`, expr);
|
|
11310
|
+
}
|
|
11311
|
+
const argNode = expr.arguments.nodes[0];
|
|
11312
|
+
const v = lowerer.lowerExpr(argNode);
|
|
11313
|
+
let data;
|
|
11314
|
+
if (v.type.kind === "dyn") {
|
|
11315
|
+
data = v;
|
|
11316
|
+
}
|
|
11317
|
+
else if (v.kind === "unitLit" || lowerer.dynConvertible(v.type)) {
|
|
11318
|
+
data = { kind: "dynFrom", value: v, type: DYN, loc };
|
|
11319
|
+
}
|
|
11320
|
+
else {
|
|
11321
|
+
lowerer.noLowering(`${name} with a '${lowerer.fmt(v.type)}' argument`, argNode, "string-convertible arguments lower (Node ToStrings the value — convert it explicitly)");
|
|
11322
|
+
}
|
|
11323
|
+
return {
|
|
11324
|
+
kind: "libCall",
|
|
11325
|
+
fn: name === "atob" ? "str.atob" : "str.btoa",
|
|
11326
|
+
args: [data],
|
|
11327
|
+
type: STRING,
|
|
11328
|
+
loc,
|
|
11329
|
+
};
|
|
11330
|
+
}
|
|
10629
11331
|
//# sourceMappingURL=lower-calls.js.map
|