@scriptc/compiler 0.2.10 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +7 -38
- package/ambient/scriptc-overrides.d.ts +1 -25
- package/ambient/scriptc.d.ts +1 -9
- package/dist/backend/cycle-analysis.test.js +1 -1
- package/dist/backend/cycle-mutability.d.ts +1 -1
- package/dist/backend/cycle-mutability.js +1 -18
- package/dist/backend/cycle-mutability.js.map +1 -1
- package/dist/backend/executable-features.d.ts +1 -1
- package/dist/backend/executable-features.js +3 -8
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/immutability.d.ts +1 -1
- package/dist/backend/immutability.js +1 -1
- package/dist/backend/immutability.test.js +1 -1
- package/dist/backend/library-pack.js +0 -2
- package/dist/backend/library-pack.js.map +1 -1
- package/dist/backend/linker.js +1 -1
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/llvm/bigint-wrap.d.ts +4 -0
- package/dist/backend/llvm/bigint-wrap.js +590 -0
- package/dist/backend/llvm/bigint-wrap.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +2 -0
- package/dist/backend/llvm/blocks.js +4 -0
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.js +15 -4
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +14 -3
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +2 -2
- package/dist/backend/llvm/checked-narrows.test.js.map +1 -1
- package/dist/backend/llvm/classes.js +60 -21
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +11 -11
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +7 -5
- package/dist/backend/llvm/common.js +7 -5
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +1 -1
- package/dist/backend/llvm/constant-callbacks.js +13 -31
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +1 -1
- package/dist/backend/llvm/dense-array-access.js +133 -45
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +54 -2
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +2 -1
- package/dist/backend/llvm/dyn.js +4 -73
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +123 -23
- package/dist/backend/llvm/emitter.js +729 -258
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +17 -10
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +120 -43
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +2 -2
- package/dist/backend/llvm/expr-async.test.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +51 -36
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.js +72 -3
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +1 -1
- package/dist/backend/llvm/expr-calls.js +159 -30
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.js +132 -0
- package/dist/backend/llvm/expr-calls.test.js.map +1 -0
- package/dist/backend/llvm/expr-containers.js +25 -8
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +2 -0
- package/dist/backend/llvm/expr-control.js +4 -107
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.d.ts +1 -2
- package/dist/backend/llvm/expr-dispatch.js +3 -41
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.d.ts +1 -1
- package/dist/backend/llvm/expr-dynamic.js +39 -31
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +7 -0
- package/dist/backend/llvm/expr-primitives.js +80 -22
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +97 -7
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +9 -0
- package/dist/backend/llvm/expr-records.js +134 -16
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +80 -1
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +51 -2
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
- package/dist/backend/llvm/int32-abi.d.ts +31 -0
- package/dist/backend/llvm/int32-abi.js +62 -0
- package/dist/backend/llvm/int32-abi.js.map +1 -0
- package/dist/backend/llvm/int32-abi.test.js +107 -0
- package/dist/backend/llvm/int32-abi.test.js.map +1 -0
- package/dist/backend/llvm/int32-locals.d.ts +30 -0
- package/dist/backend/llvm/int32-locals.js +95 -0
- package/dist/backend/llvm/int32-locals.js.map +1 -0
- package/dist/backend/llvm/integer-values.d.ts +4 -0
- package/dist/backend/llvm/integer-values.js +30 -1
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/integer-views.d.ts +8 -1
- package/dist/backend/llvm/integer-views.js +47 -2
- package/dist/backend/llvm/integer-views.js.map +1 -1
- package/dist/backend/llvm/lazy-captures.d.ts +16 -0
- package/dist/backend/llvm/lazy-captures.js +88 -2
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lazy-captures.test.js +48 -0
- package/dist/backend/llvm/lazy-captures.test.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +14 -1
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +3 -13
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +7 -8
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +21 -2
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +4 -3
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +3 -3
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.d.ts +7 -0
- package/dist/backend/llvm/map-number-lookup.js +16 -2
- package/dist/backend/llvm/map-number-lookup.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.js +7 -1
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +25 -8
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +2 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +3 -0
- package/dist/backend/llvm/reference-writes.js +10 -2
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.d.ts +39 -0
- package/dist/backend/llvm/regex-matchers.js +1649 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.test.js +96 -0
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +36 -1
- package/dist/backend/llvm/shapes.js +128 -16
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +3 -3
- package/dist/backend/llvm/stack-unions.test.js +2 -2
- package/dist/backend/llvm/stack-unions.test.js.map +1 -1
- package/dist/backend/llvm/string-construction.test.js +3 -3
- package/dist/backend/llvm/string-construction.test.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +6 -6
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-literal-equality.d.ts +22 -0
- package/dist/backend/llvm/string-literal-equality.js +78 -0
- package/dist/backend/llvm/string-literal-equality.js.map +1 -0
- package/dist/backend/llvm/switch-dispatch.js +59 -13
- package/dist/backend/llvm/switch-dispatch.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +72 -7
- package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.d.ts +1 -0
- package/dist/backend/llvm/union-retype.test.js +229 -0
- package/dist/backend/llvm/union-retype.test.js.map +1 -0
- package/dist/backend/llvm/wrapping-sums.d.ts +17 -0
- package/dist/backend/llvm/wrapping-sums.js +113 -0
- package/dist/backend/llvm/wrapping-sums.js.map +1 -0
- package/dist/backend/loop-polls.js +1 -0
- package/dist/backend/loop-polls.js.map +1 -1
- package/dist/backend/mangle.d.ts +9 -0
- package/dist/backend/mangle.js +15 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.js +6 -12
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +1 -1
- package/dist/backend/native/artifact-stamps.js +0 -2
- package/dist/backend/native/artifact-stamps.js.map +1 -1
- package/dist/backend/native/cache-warm.d.ts +1 -1
- package/dist/backend/native/cache-warm.js +2 -3
- package/dist/backend/native/cache-warm.js.map +1 -1
- package/dist/backend/native/compiler-fingerprint.d.ts +1 -1
- package/dist/backend/native/compiler-fingerprint.js +4 -7
- package/dist/backend/native/compiler-fingerprint.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +3 -28
- package/dist/backend/native/driver.js +1 -3
- package/dist/backend/native/driver.js.map +1 -1
- package/dist/backend/native/executable.d.ts +0 -15
- package/dist/backend/native/executable.js +17 -172
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/tool-identity.js +0 -1
- package/dist/backend/native/tool-identity.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-link-info-core.d.ts +0 -2
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +23 -33
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/publication.test.js +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +1 -2
- package/dist/backend/runtime-pack-core.js +5 -14
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +3 -8
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +22 -19
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/target-diagnostics.d.ts +0 -5
- package/dist/backend/target-diagnostics.js +1 -11
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/vendor-archives.d.ts +1 -7
- package/dist/backend/vendor-archives.js +9 -189
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/backend/vendor-inputs.d.ts +0 -1
- package/dist/backend/vendor-inputs.js +0 -1
- package/dist/backend/vendor-inputs.js.map +1 -1
- package/dist/backend/warm-cache.js +3 -5
- package/dist/backend/warm-cache.js.map +1 -1
- package/dist/cli/command.js +4 -8
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +1 -1
- package/dist/cli/usage.d.ts +1 -5
- package/dist/cli/usage.js +4 -9
- package/dist/cli/usage.js.map +1 -1
- package/dist/compat/fetch-profile.d.ts +2 -2
- package/dist/compat/fetch-profile.js +16 -25
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/compile-types.d.ts +2 -17
- package/dist/contracts/check.js +6 -6
- package/dist/contracts/check.js.map +1 -1
- package/dist/coverage/report.d.ts +5 -22
- package/dist/coverage/report.js +12 -76
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.d.ts +3 -3
- package/dist/coverage/surface-manifest.js +22 -27
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +1 -3
- package/dist/coverage/verdict-cache.js +2 -7
- package/dist/coverage/verdict-cache.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +11 -60
- package/dist/diagnostics/diagnostic.js +39 -118
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +3 -4
- package/dist/diagnostics/envelope.js +0 -9
- package/dist/diagnostics/envelope.js.map +1 -1
- package/dist/diagnostics/envelope.test.js +1 -1
- package/dist/diagnostics/envelope.test.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +0 -3
- package/dist/executable/executable-cache.js +2 -4
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +0 -4
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +5 -2
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +10 -10
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/cjs-syntax.js +0 -88
- package/dist/frontend/cjs-syntax.js.map +1 -1
- package/dist/frontend/dts-paths.d.ts +1 -1
- package/dist/frontend/dts-paths.js +1 -1
- package/dist/frontend/lowering/abstract-equality.js +1 -4
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +14 -0
- package/dist/frontend/lowering/array-values.js +33 -11
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtins/arguments.js +0 -13
- package/dist/frontend/lowering/builtins/arguments.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.d.ts +0 -4
- package/dist/frontend/lowering/builtins/crypto.js +0 -4
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.js +1 -39
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-resolution.d.ts +0 -15
- package/dist/frontend/lowering/builtins/module-resolution.js +5 -44
- package/dist/frontend/lowering/builtins/module-resolution.js.map +1 -1
- package/dist/frontend/lowering/builtins/numbers.d.ts +0 -6
- package/dist/frontend/lowering/builtins/numbers.js +6 -57
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.js +4 -67
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/workers.js +1 -1
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/call-arguments.d.ts +1 -37
- package/dist/frontend/lowering/call-arguments.js +11 -94
- package/dist/frontend/lowering/call-arguments.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.d.ts +1 -6
- package/dist/frontend/lowering/call-signatures.js +16 -68
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +19 -4
- package/dist/frontend/lowering/class-dynamic-dispatch.js +168 -98
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +44 -4
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +0 -2
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.js +1 -1
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/coercions/function-adapters.js +5 -35
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/state.d.ts +0 -1
- package/dist/frontend/lowering/coercions/state.js +0 -1
- package/dist/frontend/lowering/coercions/state.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural-plans.js +2 -4
- package/dist/frontend/lowering/coercions/structural-plans.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +2 -12
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.js +0 -1
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +49 -28
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +2 -3
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +10 -54
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.d.ts +54 -0
- package/dist/frontend/lowering/containers/array-pipelines.js +1827 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.js +0 -1
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +2 -10
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +1 -6
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/exec-result-uses.d.ts +10 -0
- package/dist/frontend/lowering/containers/exec-result-uses.js +88 -0
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/indexed-objects.js +0 -2
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +0 -6
- package/dist/frontend/lowering/containers/string-and-regexp.js +17 -17
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.d.ts +2 -1
- package/dist/frontend/lowering/containers/string-replacement.js +32 -136
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +33 -0
- package/dist/frontend/lowering/devirtualize.js +199 -0
- package/dist/frontend/lowering/devirtualize.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +0 -3
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/native-proxy.js +1 -1
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +55 -8
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.d.ts +0 -8
- package/dist/frontend/lowering/expressions/object-literals.js +8 -35
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +0 -4
- package/dist/frontend/lowering/expressions/optional-chains.js +3 -66
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/function-context.js +0 -1
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/generic-functions.js +0 -1
- package/dist/frontend/lowering/generic-functions.js.map +1 -1
- package/dist/frontend/lowering/identifier-uses.d.ts +7 -0
- package/dist/frontend/lowering/identifier-uses.js +23 -0
- package/dist/frontend/lowering/identifier-uses.js.map +1 -0
- package/dist/frontend/lowering/iterator-adapters.js +51 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +10 -77
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.js +14 -10
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.test.js +2 -2
- package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +2 -3
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.js +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +2 -27
- package/dist/frontend/lowering/lower-calls.js +111 -493
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +12 -60
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.js +2 -3
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-console.d.ts +14 -0
- package/dist/frontend/lowering/lower-console.js +195 -0
- package/dist/frontend/lowering/lower-console.js.map +1 -0
- package/dist/frontend/lowering/lower-enums.js +5 -8
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +3 -4
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-expando.js +3 -5
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +0 -8
- package/dist/frontend/lowering/lower-exprs.js +180 -905
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +9 -8
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +10 -0
- package/dist/frontend/lowering/lower-generators.js +108 -41
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +1 -50
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +0 -43
- package/dist/frontend/lowering/lower-modules.js +29 -329
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.js +5 -5
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +0 -30
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +98 -0
- package/dist/frontend/lowering/{lower-island.js → lower-stdlib.js} +97 -1160
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -0
- package/dist/frontend/lowering/lower-stmts.d.ts +0 -16
- package/dist/frontend/lowering/lower-stmts.js +58 -1016
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.test.js +1 -1
- package/dist/frontend/lowering/lower-stmts.test.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +14 -13
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +42 -155
- package/dist/frontend/lowering/lowerer.js +192 -816
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +4 -51
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +16 -0
- package/dist/frontend/lowering/nan-coded-reads.js +108 -1
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/narrowing-stability.js +1 -1
- package/dist/frontend/lowering/narrowing-stability.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.js +0 -2
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-bounds.d.ts +4 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +2 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-bounds.test.js +27 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.js.map +1 -1
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/split-consumers.js +2 -18
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/strict-equality.js +1 -1
- package/dist/frontend/lowering/strict-equality.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +6 -45
- package/dist/frontend/lowering/surfaces.js +8 -73
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/union-retag.d.ts +6 -1
- package/dist/frontend/lowering/union-retag.js +64 -1
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +46 -0
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/module-syntax.d.ts +0 -3
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/npm-node.d.ts +0 -7
- package/dist/frontend/npm-node.js +0 -7
- package/dist/frontend/npm-node.js.map +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.d.ts +1 -1
- package/dist/frontend/npm-static-rewrite-syntax.js +6 -82
- package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +1 -1
- package/dist/frontend/npm-static.js +6 -71
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +3 -319
- package/dist/frontend/npm.js +6 -1007
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +2 -197
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/pipeline-native.js +1 -2
- package/dist/frontend/pipeline-native.js.map +1 -1
- package/dist/frontend/pipeline.d.ts +3 -11
- package/dist/frontend/pipeline.js +37 -56
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/pipeline.test.js +12 -6
- package/dist/frontend/pipeline.test.js.map +1 -1
- package/dist/frontend/program.d.ts +0 -34
- package/dist/frontend/program.js +12 -97
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance-core.d.ts +0 -4
- package/dist/frontend/provenance-core.js +4 -37
- package/dist/frontend/provenance-core.js.map +1 -1
- package/dist/frontend/provenance-registry.d.ts +0 -4
- package/dist/frontend/provenance-registry.js +0 -20
- package/dist/frontend/provenance-registry.js.map +1 -1
- package/dist/frontend/resolve.d.ts +0 -12
- package/dist/frontend/resolve.js +0 -34
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/runtime-resolve.js +2 -2
- package/dist/frontend/runtime-resolve.js.map +1 -1
- package/dist/frontend/services-node.js +2 -3
- package/dist/frontend/services-node.js.map +1 -1
- package/dist/frontend/services.d.ts +1 -8
- package/dist/frontend/services.js +2 -22
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +0 -38
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/tsc-codes.js +0 -11
- package/dist/frontend/tsc-codes.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +2 -27
- package/dist/frontend/type-mapper.js +58 -156
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -10
- package/dist/index.js.map +1 -1
- package/dist/ir/api.d.ts +1 -1
- package/dist/ir/api.js +1 -1
- package/dist/ir/api.js.map +1 -1
- package/dist/ir/builtin-effects.js +2 -5
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +13 -56
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/constant-globals.test.js +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/final-fields.test.js +1 -1
- package/dist/ir/function-references.d.ts +12 -0
- package/dist/ir/function-references.js +29 -0
- package/dist/ir/function-references.js.map +1 -0
- package/dist/ir/function-references.test.d.ts +1 -0
- package/dist/ir/function-references.test.js +276 -0
- package/dist/ir/function-references.test.js.map +1 -0
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +10 -7
- package/dist/ir/int32-slots.js +219 -68
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +39 -2
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +4 -4
- package/dist/ir/integer-ranges.js +89 -64
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +71 -9
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +1 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +64 -290
- package/dist/ir/ir.js +11 -259
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +2 -7
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +3 -30
- package/dist/ir/runtime-features.js +8 -43
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +3 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/traverse.js +4 -21
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/unshare.test.js +1 -1
- package/dist/ir/validate.js +66 -213
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +31 -13
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/prepare.js +5 -20
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/cli.js +0 -2
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.test.js +2 -4
- package/dist/native/compiler.test.js.map +1 -1
- package/dist/native/prepare.js +2 -4
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.js +2 -16
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/sanitizer.test.js +0 -3
- package/dist/native/sanitizer.test.js.map +1 -1
- package/dist/startup-cache.js +0 -2
- package/dist/startup-cache.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +80 -104
- package/dist/backend/llvm/expr-island.d.ts +0 -15
- package/dist/backend/llvm/expr-island.js +0 -709
- package/dist/backend/llvm/expr-island.js.map +0 -1
- package/dist/frontend/lowering/coercions/island.d.ts +0 -37
- package/dist/frontend/lowering/coercions/island.js +0 -350
- package/dist/frontend/lowering/coercions/island.js.map +0 -1
- package/dist/frontend/lowering/lower-island.d.ts +0 -229
- package/dist/frontend/lowering/lower-island.js.map +0 -1
- package/dist/frontend/lowering/lower-island.test.js +0 -56
- package/dist/frontend/lowering/lower-island.test.js.map +0 -1
- package/dist/frontend/npm-fetch-analysis.d.ts +0 -17
- package/dist/frontend/npm-fetch-analysis.js +0 -109
- package/dist/frontend/npm-fetch-analysis.js.map +0 -1
- package/dist/frontend/npm-fetch-analysis.test.js +0 -130
- package/dist/frontend/npm-fetch-analysis.test.js.map +0 -1
- package/dist/frontend/npm-fetch-node.d.ts +0 -2
- package/dist/frontend/npm-fetch-node.js +0 -12
- package/dist/frontend/npm-fetch-node.js.map +0 -1
- package/dist/frontend/npm-fetch-syntax.d.ts +0 -6
- package/dist/frontend/npm-fetch-syntax.js +0 -202
- package/dist/frontend/npm-fetch-syntax.js.map +0 -1
- package/dist/native/runtime-typescript.d.ts +0 -4
- package/dist/native/runtime-typescript.js +0 -74
- package/dist/native/runtime-typescript.js.map +0 -1
- package/dist/native/runtime-typescript.test.js +0 -41
- package/dist/native/runtime-typescript.test.js.map +0 -1
- /package/dist/{frontend/lowering/lower-island.test.d.ts → backend/llvm/expr-calls.test.d.ts} +0 -0
- /package/dist/{frontend/npm-fetch-analysis.test.d.ts → backend/llvm/int32-abi.test.d.ts} +0 -0
- /package/dist/{native/runtime-typescript.test.d.ts → backend/llvm/regex-matchers.test.d.ts} +0 -0
|
@@ -1,225 +1,20 @@
|
|
|
1
1
|
import { dynUndefinedExpr, nodeThrowExpr } from "../../ir/build.js";
|
|
2
2
|
import { InternalCompilerError } from "../../errors.js";
|
|
3
|
-
/* Island-boundary lowering: jsval marshaling into the island (jsvalIn and
|
|
4
|
-
* its boundary fences), island-expression detection, the island method-call
|
|
5
|
-
* surface (Math and number/string methods under --dynamic), and the npm
|
|
6
|
-
* package boundary fences for node_modules-declared symbols. */
|
|
7
3
|
import * as ts from "../ts7/adapter.js";
|
|
8
4
|
import { lowerToNumberArgument } from "./lower-exprs.js";
|
|
9
|
-
import { arrayOf, BOOL, BYTES_U8, DYN, F64,
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { esmNamedImportLinkCrash, isCjsJsFile,
|
|
5
|
+
import { arrayOf, BOOL, BYTES_U8, DYN, F64, STRING, VOID, canConvertToDyn, isUnitType, } from "../../ir/ir.js";
|
|
6
|
+
import { STDLIB_SURFACE, STATIC_MATH_FNS, STATIC_MATH_PROPS, stdlibGlobalNameOf, } from "./surfaces.js";
|
|
7
|
+
import { unsupportedNativeApiDiag, unsupportedPackageValueDiag, } from "../../diagnostics/diagnostic.js";
|
|
8
|
+
import { esmNamedImportLinkCrash, isCjsJsFile, locOf, npmPackageNameOf } from "../program.js";
|
|
13
9
|
import { foldedStringKeyOf, lowerDynObjectLiteral } from "./expressions/object-literals.js";
|
|
14
|
-
import { isSafeToRepeat } from "./expressions/evaluation-safety.js";
|
|
15
10
|
import { PoisonError, newFnCtx, own } from "./lowerer.js";
|
|
16
11
|
import { NODE24_FETCH_COMPAT_PROFILE, STATIC_HEADERS_CALLS, STATIC_READABLE_STREAM_CALLS, STATIC_READABLE_STREAM_READS, STATIC_RESPONSE_CALLS, STATIC_RESPONSE_READS, } from "../../compat/fetch-profile.js";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* callees, assignment targets). ALSO true for an identifier bound to an
|
|
20
|
-
* island-HANDLE local whose declared type says otherwise (`const {
|
|
21
|
-
* readFileSync } = await import("fs")` — the binding's declared
|
|
22
|
-
* function/Buffer type never held the value; the handle is the value's
|
|
23
|
-
* only story), so its uses dispatch to engine ops instead of
|
|
24
|
-
* re-reporting the declared type. The one exclusion is promise-mapped
|
|
25
|
-
* declared types: a package promise held as a handle keeps its existing
|
|
26
|
-
* checker-driven dispatch (the await/.catch bridge lowerings own it). */
|
|
27
|
-
export function isIslandExpr(lowerer, node) {
|
|
28
|
-
// Static builds cannot contain island handles. Avoid mapping entire
|
|
29
|
-
// receiver/callee types (and their checker RPCs) just to prove that.
|
|
30
|
-
if (!lowerer.dynamic)
|
|
31
|
-
return false;
|
|
32
|
-
const mapped = lowerer.mapTypeOf(lowerer.typeOf(node));
|
|
33
|
-
if (mapped?.kind === "jsval")
|
|
34
|
-
return true;
|
|
35
|
-
if (mapped?.kind !== "promise" && ts.isIdentifier(node)) {
|
|
36
|
-
const local = lowerer.peekLocal(node);
|
|
37
|
-
if (local?.type.kind === "jsval")
|
|
38
|
-
return true;
|
|
39
|
-
// File-scope handle bindings (a module global slotted jsval by the
|
|
40
|
-
// island-pattern or unchecked-overload rules) take the same rule as
|
|
41
|
-
// locals: the handle is the value's only story.
|
|
42
|
-
if (!local && lowerer.globalOf(node)?.type.kind === "jsval")
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
/** Marshal a static value into the island (--dynamic): primitives by
|
|
48
|
-
* value, JSON-safe composites as a deep copy (the documented aliasing
|
|
49
|
-
* divergence). Values with no island representation — closures, class
|
|
50
|
-
* instances, promises, un-validated 'unknown' — are rejected with the
|
|
51
|
-
* boundary message. */
|
|
52
|
-
/** The call-time deferral of a FUNC-value island crossing in a JS
|
|
53
|
-
* source: captures the just-recorded diagnostic into the runtime-fence
|
|
54
|
-
* ledger and answers a marshaled host closure that THROWS it when
|
|
55
|
-
* invoked — building the value compiles; only a call through the
|
|
56
|
-
* island stops the run. Null (caller rethrows) outside the JS deferral
|
|
57
|
-
* gate: TypeScript sources, probe mode, ICEs. */
|
|
58
|
-
export function islandFuncValueFence(lowerer, diagsBefore, node) {
|
|
59
|
-
if (!isJsSourceFile(node.getSourceFile()))
|
|
60
|
-
return null;
|
|
61
|
-
const fence = lowerer.deferToRuntimeFence(diagsBefore, node, {
|
|
62
|
-
kind: "closure",
|
|
63
|
-
name: () => `%fn${lowerer.lambdaCounter++}_islfence`,
|
|
64
|
-
returnType: VOID,
|
|
65
|
-
type: { kind: "func", params: [], ret: VOID },
|
|
66
|
-
});
|
|
67
|
-
if (!fence)
|
|
68
|
-
return null;
|
|
69
|
-
return {
|
|
70
|
-
kind: "jsMarshal",
|
|
71
|
-
value: fence,
|
|
72
|
-
type: JSVAL,
|
|
73
|
-
loc: fence.loc,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
export function jsvalIn(lowerer, e, node) {
|
|
77
|
-
if (e.type.kind === "jsval")
|
|
78
|
-
return e;
|
|
79
|
-
// Bare unit literals (`undefined` / `null` in an 'any' slot): the
|
|
80
|
-
// engine's own units — unit-typed expressions are literals (units have
|
|
81
|
-
// no other producers), so dropping the operand loses nothing.
|
|
82
|
-
if (isUnitType(e.type)) {
|
|
83
|
-
return {
|
|
84
|
-
kind: "jsOp",
|
|
85
|
-
op: e.type.kind === "undefinedT" ? "undefLit" : "nullLit",
|
|
86
|
-
args: [],
|
|
87
|
-
type: JSVAL,
|
|
88
|
-
loc: e.loc,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
if (e.type.kind === "dyn") {
|
|
92
|
-
// A CHECKED-DYNAMIC value entering the island: the dyn tree
|
|
93
|
-
// deep-copies into engine values — exactly coerceToExpected's
|
|
94
|
-
// jsval-IN rule (data kinds only; a dyn carrying a boxed
|
|
95
|
-
// function/handle throws the catchable TypeError at runtime).
|
|
96
|
-
return { kind: "jsMarshal", value: e, type: JSVAL, loc: e.loc };
|
|
97
|
-
}
|
|
98
|
-
// Closures cross INTO the island as host functions — THE package
|
|
99
|
-
// callback pattern (`.action((a, b) => ...)`). Unannotated params stay
|
|
100
|
-
// 'any' (contextual typing against package signatures) and pass through
|
|
101
|
-
// as handles; TYPED params convert at call time through the validated-
|
|
102
|
-
// exit machinery (strict primitives, JSON round-trip composites,
|
|
103
|
-
// `T | undefined` taking the undefined arm for an absent argument), so
|
|
104
|
-
// a conversion failure throws back into the island as a TypeError.
|
|
105
|
-
// Anything outside both shapes gets the specific fix, not the generic
|
|
106
|
-
// boundary recitation.
|
|
107
|
-
if (e.type.kind === "func" &&
|
|
108
|
-
!canMarshalTypedFuncIntoIsland(e.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
109
|
-
const diagsBefore = lowerer.diags.length;
|
|
110
|
-
try {
|
|
111
|
-
lowerer.unsupported("SC1090", node, `functions with this signature crossing into dynamically-executed code ` +
|
|
112
|
-
`(a callback passed to a package/'any' API may take 'any' parameters — ` +
|
|
113
|
-
`leave them unannotated so contextual typing keeps them 'any' — or parameters ` +
|
|
114
|
-
`convertible at the boundary (number, string, boolean, JSON-safe ` +
|
|
115
|
-
`records/arrays/unions, 'T | undefined'), and return 'any', void, number, ` +
|
|
116
|
-
`string, boolean, a JSON-safe composite, or a Promise of the primitive kinds${e.type.kind === "func" && e.type.params.length > MAX_ISLAND_CALLBACK_ARITY
|
|
117
|
-
? `; at most ${MAX_ISLAND_CALLBACK_ARITY} parameters`
|
|
118
|
-
: ""})`);
|
|
119
|
-
}
|
|
120
|
-
catch (err) {
|
|
121
|
-
// JS sources defer the crossing like a statement fence, one level
|
|
122
|
-
// deeper: the slot receives a host closure that THROWS the
|
|
123
|
-
// diagnostic when INVOKED (the withPlugins aggregation shape —
|
|
124
|
-
// wrappers built at module init around functions the smoke path
|
|
125
|
-
// never calls). TypeScript and probe mode keep the poison.
|
|
126
|
-
if (!(err instanceof PoisonError))
|
|
127
|
-
throw err;
|
|
128
|
-
const fence = islandFuncValueFence(lowerer, diagsBefore, node);
|
|
129
|
-
if (fence)
|
|
130
|
-
return fence;
|
|
131
|
-
throw err;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
// A STATIC promise crossing INTO the island: a real engine thenable
|
|
135
|
-
// settled when the scriptc promise settles (the async-callback return
|
|
136
|
-
// bridge, scr_jsval_from_promise) — the loadBuiltinPlugins cache
|
|
137
|
-
// shape and the island Promise.all arm's static entries. Only
|
|
138
|
-
// fulfillments in the bridge's payload domain cross; the rest keep
|
|
139
|
-
// the boundary fence below with the promise type named.
|
|
140
|
-
if (e.type.kind === "promise" && islandPromisePayloadTag(e.type.inner) !== null) {
|
|
141
|
-
return { kind: "jsMarshal", value: e, type: JSVAL, loc: e.loc };
|
|
142
|
-
}
|
|
143
|
-
if (e.type.kind !== "func" && !lowerer.boundarySafe(e.type)) {
|
|
144
|
-
// A RegExp crossing INTO the island (`z.string().regex(/^a+$/)` —
|
|
145
|
-
// the validation-pattern argument): the engine compiles its own
|
|
146
|
-
// from source+flags. A fresh engine RegExp per marshal — identity
|
|
147
|
-
// and lastIndex state do not cross (SEMANTICS.md). Only literal
|
|
148
|
-
// and pure-read spellings lower (the rebuild reads the operand
|
|
149
|
-
// twice); computed regex values keep the boundary fence.
|
|
150
|
-
if (e.type.kind === "regex") {
|
|
151
|
-
const re = islandRegexpOf(e);
|
|
152
|
-
if (re)
|
|
153
|
-
return re;
|
|
154
|
-
}
|
|
155
|
-
// jsval-BEARING composites (an `any[]` value, a record holding one)
|
|
156
|
-
// have no JSON marshal but an honest per-field/per-element island
|
|
157
|
-
// construction — the same lift the implicit coercion path uses.
|
|
158
|
-
if (lowerer.jsvalLiftable(e.type))
|
|
159
|
-
return lowerer.jsvalLiftExpr(e, e.loc);
|
|
160
|
-
lowerer.unsupported("SC1090", node, boundaryIntoIslandMsg(lowerer.fmt(e.type)));
|
|
161
|
-
}
|
|
162
|
-
return { kind: "jsMarshal", value: e, type: JSVAL, loc: e.loc };
|
|
163
|
-
}
|
|
164
|
-
/** A static RegExp value as a fresh ENGINE RegExp — `new RegExp(source,
|
|
165
|
-
* flags)` in the island, the pattern TEXT crossing (both worlds compile
|
|
166
|
-
* the ES-spec grammar). Literals rebuild from their own pattern/flags;
|
|
167
|
-
* pure reads (a regex-typed binding) read the source/flags intrinsics —
|
|
168
|
-
* the rebuild emits the operand twice, so effectful producers return
|
|
169
|
-
* null into the caller's boundary fence. */
|
|
170
|
-
export function islandRegexpOf(e) {
|
|
171
|
-
if (e.type.kind !== "regex")
|
|
172
|
-
return null;
|
|
173
|
-
const loc = e.loc;
|
|
174
|
-
let src;
|
|
175
|
-
let flags;
|
|
176
|
-
if (e.kind === "regexLit") {
|
|
177
|
-
src = { kind: "strLit", value: e.pattern, type: STRING, loc };
|
|
178
|
-
flags = { kind: "strLit", value: e.flags, type: STRING, loc };
|
|
179
|
-
}
|
|
180
|
-
else if (isSafeToRepeat(e)) {
|
|
181
|
-
src = { kind: "regexIntrinsic", method: "source", receiver: e, args: [], type: STRING, loc };
|
|
182
|
-
flags = { kind: "regexIntrinsic", method: "flags", receiver: e, args: [], type: STRING, loc };
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
const ctor = {
|
|
188
|
-
kind: "jsOp",
|
|
189
|
-
op: "globalGet",
|
|
190
|
-
name: "RegExp",
|
|
191
|
-
args: [],
|
|
192
|
-
type: JSVAL,
|
|
193
|
-
loc,
|
|
194
|
-
};
|
|
195
|
-
return {
|
|
196
|
-
kind: "jsOp",
|
|
197
|
-
op: "construct",
|
|
198
|
-
args: [
|
|
199
|
-
ctor,
|
|
200
|
-
{ kind: "jsMarshal", value: src, type: JSVAL, loc },
|
|
201
|
-
{ kind: "jsMarshal", value: flags, type: JSVAL, loc },
|
|
202
|
-
],
|
|
203
|
-
type: JSVAL,
|
|
204
|
-
loc,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
/** The gate on every ISLAND_SURFACE lowering: under --dynamic the caller
|
|
208
|
-
* proceeds to engine ops; without it the use site is a per-site SC2012
|
|
209
|
-
* (poison-recovered, so every site in the program reports — and the
|
|
210
|
-
* coverage report groups them under "runs with --dynamic"). */
|
|
211
|
-
export function requireDynamicApi(lowerer, feature, node, hint) {
|
|
212
|
-
if (lowerer.dynamic)
|
|
213
|
-
return;
|
|
214
|
-
lowerer.pushDiag(requiresDynamicApiDiag(feature, locOf(node), hint));
|
|
12
|
+
export function refuseUnsupportedApi(lowerer, feature, node, hint) {
|
|
13
|
+
lowerer.pushDiag(unsupportedNativeApiDiag(feature, locOf(node), hint));
|
|
215
14
|
throw new PoisonError();
|
|
216
15
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
* symbol's declaration must live in the ambient file, so a user function
|
|
220
|
-
* named `parseFloat` never matches. */
|
|
221
|
-
export function islandGlobalFnOf(lowerer, ident) {
|
|
222
|
-
const entry = own(ISLAND_SURFACE.globals, ident.text);
|
|
16
|
+
export function stdlibGlobalFnOf(lowerer, ident) {
|
|
17
|
+
const entry = own(STDLIB_SURFACE.globals, ident.text);
|
|
223
18
|
if (!entry)
|
|
224
19
|
return null;
|
|
225
20
|
const symbol = lowerer.resolveValueSymbol(ident);
|
|
@@ -242,10 +37,9 @@ function requestInitLiteralKey(lowerer, prop) {
|
|
|
242
37
|
return foldedStringKeyOf(lowerer, name.expression);
|
|
243
38
|
return null;
|
|
244
39
|
}
|
|
245
|
-
/**
|
|
246
|
-
* Computed runtime keys and non-literal objects are validated
|
|
247
|
-
*
|
|
248
|
-
* rejected before the dynamic bridge can silently discard them. */
|
|
40
|
+
/** Unwrap assertions and parentheses when checking RequestInit values.
|
|
41
|
+
* Computed runtime keys and non-literal objects are also validated by the
|
|
42
|
+
* native runtime. */
|
|
249
43
|
function requestInitValueExpr(expr) {
|
|
250
44
|
let current = expr;
|
|
251
45
|
while (ts.isParenthesizedExpression(current) ||
|
|
@@ -519,7 +313,7 @@ function fenceRequestInitObject(lowerer, init, seen) {
|
|
|
519
313
|
const rows = NODE24_FETCH_COMPAT_PROFILE.inventory.entries.filter((entry) => entry.owner === "RequestInit" && entry.placement === "dictionary");
|
|
520
314
|
const shadowed = new Set();
|
|
521
315
|
const fence = (row, value, blame) => {
|
|
522
|
-
if (
|
|
316
|
+
if (row.status === "static")
|
|
523
317
|
return;
|
|
524
318
|
if (value !== null) {
|
|
525
319
|
const type = lowerer.typeOf(requestInitValueExpr(value));
|
|
@@ -531,7 +325,7 @@ function fenceRequestInitObject(lowerer, init, seen) {
|
|
|
531
325
|
const sym = contextualArms
|
|
532
326
|
.map((arm) => lowerer.checker.getPropertyOfType(arm, row.member))
|
|
533
327
|
.find((member) => member !== undefined);
|
|
534
|
-
lowerer.noLowering(`RequestInit option '${row.member}'${
|
|
328
|
+
lowerer.noLowering(`RequestInit option '${row.member}'${" in a static build"}`, blame, row.reason ??
|
|
535
329
|
"the native static RequestInit surface is method, headers, body, duplex, redirect, and signal", sym);
|
|
536
330
|
};
|
|
537
331
|
// Object spread is last-write-wins. Walk from the end and trace only the
|
|
@@ -624,28 +418,6 @@ function fenceRequestInitValueInner(lowerer, value, seen) {
|
|
|
624
418
|
function fenceRequestInitValue(lowerer, value) {
|
|
625
419
|
fenceRequestInitValueInner(lowerer, value, new Set());
|
|
626
420
|
}
|
|
627
|
-
/** USER-code `fetch(url)` / `fetch(url, init)` — the ambient global
|
|
628
|
-
* (provenance, not the name: a user's own `fetch` never matches).
|
|
629
|
-
*
|
|
630
|
-
* The static tier owns URL requests directly: scr_fetch_static runs
|
|
631
|
-
* over the native net/http/tls stack, consumes a checked-dynamic
|
|
632
|
-
* RequestInit object, and returns a promise of an opaque native
|
|
633
|
-
* Response handle. AbortSignal and readable Web Streams are native
|
|
634
|
-
* checked-dynamic handles too, so cancellation and streaming bodies
|
|
635
|
-
* stay engine-free.
|
|
636
|
-
*
|
|
637
|
-
* The engine's own fetch executes (the same one embedded npm code calls —
|
|
638
|
-
* scr_fetch.c over the native net/tls stack): the url marshals in (strings; template
|
|
639
|
-
* results), an init OBJECT LITERAL builds natively in the island through
|
|
640
|
-
* the existing 'any'-contextual literal path (RequestInit maps to jsval,
|
|
641
|
-
* so field values marshal individually and an AbortSignal handle passes
|
|
642
|
-
* straight through), and the engine's promise bridges to a static
|
|
643
|
-
* `promise of jsval` (jsBridgePromise) — `await fetch(...)` parks the
|
|
644
|
-
* fiber like any await and resumes with the Response HANDLE. Member
|
|
645
|
-
* reads/calls on the handle are engine ops; typed extraction happens at
|
|
646
|
-
* the user's narrowing sites through the validated-exit machinery.
|
|
647
|
-
* Null for anything that isn't THE ambient fetch, so lowerCall keeps
|
|
648
|
-
* trying. */
|
|
649
421
|
export function lowerFetchCall(lowerer, call) {
|
|
650
422
|
const callee = call.expression;
|
|
651
423
|
if (!ts.isIdentifier(callee) || callee.text !== "fetch")
|
|
@@ -661,7 +433,7 @@ export function lowerFetchCall(lowerer, call) {
|
|
|
661
433
|
const initNode = call.arguments[1];
|
|
662
434
|
if (initNode !== undefined)
|
|
663
435
|
fenceRequestInitValue(lowerer, initNode);
|
|
664
|
-
|
|
436
|
+
{
|
|
665
437
|
const inputNode = call.arguments[0];
|
|
666
438
|
const input = lowerer.lowerExpr(inputNode);
|
|
667
439
|
let init;
|
|
@@ -726,33 +498,12 @@ export function lowerFetchCall(lowerer, call) {
|
|
|
726
498
|
};
|
|
727
499
|
return { kind: "seqExpr", stmts, result: answer, type: answer.type, loc };
|
|
728
500
|
}
|
|
729
|
-
const fetchFn = {
|
|
730
|
-
kind: "jsOp",
|
|
731
|
-
op: "globalGet",
|
|
732
|
-
name: "fetch",
|
|
733
|
-
args: [],
|
|
734
|
-
type: JSVAL,
|
|
735
|
-
loc,
|
|
736
|
-
};
|
|
737
|
-
// Init OBJECT LITERALS build natively in the island (the general
|
|
738
|
-
// 'any'-contextual literal path can't claim them: the optional param's
|
|
739
|
-
// contextual type is `RequestInit | undefined`, a union) — field
|
|
740
|
-
// values marshal individually, so an AbortSignal HANDLE passes
|
|
741
|
-
// through and dashed header keys ("content-type") are plain engine
|
|
742
|
-
// property names. Non-literal inits marshal as a whole (JSON-safe
|
|
743
|
-
// records; a signal field inside one fences with the boundary rule).
|
|
744
|
-
const args = call.arguments.map((a) => ts.isObjectLiteralExpression(a)
|
|
745
|
-
? lowerIslandObjectLiteral(lowerer, a)
|
|
746
|
-
: lowerer.jsvalIn(lowerer.lowerExpr(a), a));
|
|
747
|
-
const raw = { kind: "jsOp", op: "callFn", args: [fetchFn, ...args], type: JSVAL, loc };
|
|
748
|
-
return { kind: "jsBridgePromise", value: raw, type: { kind: "promise", inner: JSVAL }, loc };
|
|
749
501
|
}
|
|
750
502
|
/** Static Response.json(): consume the native Response's readable body
|
|
751
503
|
* stream and parse its UTF-8 payload into the ordinary checked-dynamic
|
|
752
504
|
* JSON tree. Syntax and stream failures reject at await like the web API. */
|
|
753
505
|
export function lowerStaticResponseCall(lowerer, call) {
|
|
754
|
-
if (
|
|
755
|
-
call.questionDotToken ||
|
|
506
|
+
if (call.questionDotToken ||
|
|
756
507
|
(!ts.isPropertyAccessExpression(call.expression) &&
|
|
757
508
|
!ts.isElementAccessExpression(call.expression))) {
|
|
758
509
|
return null;
|
|
@@ -909,7 +660,7 @@ function fetchInventoryReason(owner, member, placement) {
|
|
|
909
660
|
return NODE24_FETCH_COMPAT_PROFILE.inventory.entries.find((entry) => entry.owner === owner && entry.member === member && entry.placement === placement)?.reason;
|
|
910
661
|
}
|
|
911
662
|
/** Constructor-object operations are distinct from Response instance
|
|
912
|
-
* methods. The inventory marks the former unsupported
|
|
663
|
+
* methods. The inventory marks the former unsupported; fence
|
|
913
664
|
* them explicitly so the generic call fallback cannot report SC1090 for
|
|
914
665
|
* Response.json while the other statics report SC2020. */
|
|
915
666
|
export function fenceUnsupportedFetchConstructorMember(lowerer, access) {
|
|
@@ -921,7 +672,7 @@ export function fenceUnsupportedFetchConstructorMember(lowerer, access) {
|
|
|
921
672
|
const member = members.find((candidate) => fetchInventoryStatus("Response", candidate, "static") === "unsupported");
|
|
922
673
|
if (member === undefined)
|
|
923
674
|
return null;
|
|
924
|
-
lowerer.noLowering(`Response.${member}`, access, "Response static constructor-object operations have no compiler lowering
|
|
675
|
+
lowerer.noLowering(`Response.${member}`, access, "Response static constructor-object operations have no compiler lowering");
|
|
925
676
|
}
|
|
926
677
|
function hasLiveWebMutableArm(lowerer, type) {
|
|
927
678
|
if (type.kind === "record" || type.kind === "array" || type.kind === "bytes") {
|
|
@@ -975,18 +726,15 @@ export function fenceStaticResponseMember(lowerer, access, use) {
|
|
|
975
726
|
if (members === null)
|
|
976
727
|
return null;
|
|
977
728
|
const status = (member) => fetchInventoryStatus("Response", member, member.startsWith("[Symbol.") ? "prototype-symbol" : "prototype");
|
|
978
|
-
if (lowerer.dynamic && members.every((member) => status(member) !== "unsupported")) {
|
|
979
|
-
return null;
|
|
980
|
-
}
|
|
981
729
|
const supported = (member) => use === "call" ? STATIC_RESPONSE_CALLS.has(member) : STATIC_RESPONSE_READS.has(member);
|
|
982
|
-
if (
|
|
730
|
+
if (members.every(supported))
|
|
983
731
|
return null;
|
|
984
|
-
const member = members.find((candidate) =>
|
|
732
|
+
const member = members.find((candidate) => !supported(candidate));
|
|
985
733
|
if (status(member) === "unsupported") {
|
|
986
734
|
lowerer.noLowering(`Response.${member}`, access, fetchInventoryReason("Response", member, "prototype") ??
|
|
987
|
-
"this Response operation has no compiler lowering
|
|
735
|
+
"this Response operation has no compiler lowering", sym);
|
|
988
736
|
}
|
|
989
|
-
lowerer.noLowering(`Response.${member} in a static build`, access, "the native static Response surface is status/ok/statusText/url/redirected/headers/body/bodyUsed plus json(), text(), bytes(), and arrayBuffer();
|
|
737
|
+
lowerer.noLowering(`Response.${member} in a static build`, access, "the native static Response surface is status/ok/statusText/url/redirected/headers/body/bodyUsed plus json(), text(), bytes(), and arrayBuffer(); other forms are unsupported", sym);
|
|
990
738
|
}
|
|
991
739
|
/** Response Headers are native checked-dynamic handles. Keep their exact
|
|
992
740
|
* supported method slice aligned with the compatibility census so newly
|
|
@@ -1001,30 +749,20 @@ export function fenceStaticHeadersMember(lowerer, access, use) {
|
|
|
1001
749
|
if (members === null)
|
|
1002
750
|
return null;
|
|
1003
751
|
const status = (member) => fetchInventoryStatus("Headers", member, member.startsWith("[Symbol.") ? "prototype-symbol" : "prototype");
|
|
1004
|
-
if (
|
|
752
|
+
if (use === "call" && members.every((member) => STATIC_HEADERS_CALLS.has(member))) {
|
|
1005
753
|
return null;
|
|
1006
754
|
}
|
|
1007
|
-
|
|
1008
|
-
use === "call" &&
|
|
1009
|
-
members.every((member) => STATIC_HEADERS_CALLS.has(member))) {
|
|
1010
|
-
return null;
|
|
1011
|
-
}
|
|
1012
|
-
const member = members.find((candidate) => lowerer.dynamic
|
|
1013
|
-
? status(candidate) === "unsupported"
|
|
1014
|
-
: use !== "call" || !STATIC_HEADERS_CALLS.has(candidate));
|
|
755
|
+
const member = members.find((candidate) => use !== "call" || !STATIC_HEADERS_CALLS.has(candidate));
|
|
1015
756
|
if (status(member) === "unsupported") {
|
|
1016
|
-
lowerer.noLowering(`Headers.${member}`, access, "symbol-keyed Headers iteration
|
|
757
|
+
lowerer.noLowering(`Headers.${member}`, access, "symbol-keyed Headers iteration is unsupported; use forEach()", sym);
|
|
1017
758
|
}
|
|
1018
|
-
lowerer.noLowering(`Headers.${member} in a static build`, access, "the native static Headers surface is append/delete/get/getSetCookie/has/set/forEach;
|
|
759
|
+
lowerer.noLowering(`Headers.${member} in a static build`, access, "the native static Headers surface is append/delete/get/getSetCookie/has/set/forEach; keys()/values()/entries(), symbol-keyed iteration, and construction remain unsupported", sym);
|
|
1019
760
|
}
|
|
1020
761
|
/** The native AbortController handle dispatches `abort()` directly and
|
|
1021
762
|
* exposes `.signal` as data, but it has no first-class function value for
|
|
1022
763
|
* the prototype method. Fence method extraction before the checked-dynamic
|
|
1023
|
-
* keyed-read fallback can silently answer `undefined`.
|
|
1024
|
-
* the engine's real AbortController object and retain ordinary method reads. */
|
|
764
|
+
* keyed-read fallback can silently answer `undefined`. */
|
|
1025
765
|
export function fenceStaticAbortControllerMemberRead(lowerer, access) {
|
|
1026
|
-
if (lowerer.dynamic)
|
|
1027
|
-
return null;
|
|
1028
766
|
const symbol = isStdlibFetchInterface(lowerer, access.expression, "AbortController");
|
|
1029
767
|
if (!symbol)
|
|
1030
768
|
return null;
|
|
@@ -1047,7 +785,7 @@ function isStdlibFetchInterface(lowerer, node, owner) {
|
|
|
1047
785
|
* through. Null means this is not the standard-library ReadableStream or
|
|
1048
786
|
* its element cannot be represented statically. */
|
|
1049
787
|
export function staticReadableStreamElementType(lowerer, node) {
|
|
1050
|
-
if (
|
|
788
|
+
if (!isStdlibFetchInterface(lowerer, node, "ReadableStream")) {
|
|
1051
789
|
return null;
|
|
1052
790
|
}
|
|
1053
791
|
const type = lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(node));
|
|
@@ -1107,24 +845,17 @@ function fenceFetchObjectMembers(lowerer, ownerNode, members) {
|
|
|
1107
845
|
entry.placement === "prototype-symbol"));
|
|
1108
846
|
if (!row || row.status === "out-of-scope")
|
|
1109
847
|
continue;
|
|
1110
|
-
if (lowerer.dynamic && row.status !== "unsupported")
|
|
1111
|
-
continue;
|
|
1112
848
|
// Static data properties retain the ordinary checked-dynamic keyed-read
|
|
1113
849
|
// lowering. Only a method extraction loses the receiver that its direct
|
|
1114
850
|
// call bridge would preserve; non-static rows keep their inventory fence.
|
|
1115
851
|
const operation = NODE24_FETCH_COMPAT_PROFILE.operations.find((candidate) => candidate.id === row.id);
|
|
1116
|
-
if (
|
|
852
|
+
if (row.status === "static" && operation?.kind === "property") {
|
|
1117
853
|
continue;
|
|
1118
854
|
}
|
|
1119
|
-
lowerer.noLowering(`${owner}.${member}${
|
|
855
|
+
lowerer.noLowering(`${owner}.${member}${" through object destructuring in a static build"}`, node, row.reason ??
|
|
1120
856
|
"the direct lowered read/call form has a compiler bridge, but extracting this member as a value does not", symbol);
|
|
1121
857
|
}
|
|
1122
858
|
}
|
|
1123
|
-
/** Object binding syntax reads members without constructing property-access
|
|
1124
|
-
* nodes, so the ordinary Response/Headers/ReadableStream chokepoints never
|
|
1125
|
-
* see it. Attribute those reads to the same inventory rows before generic
|
|
1126
|
-
* dyn/jsval destructuring either reports SC1031 or admits an unsupported
|
|
1127
|
-
* member in the dynamic tier. */
|
|
1128
859
|
export function fenceFetchObjectBinding(lowerer, pattern) {
|
|
1129
860
|
fenceFetchObjectMembers(lowerer, pattern, pattern.elements.flatMap((element) => {
|
|
1130
861
|
if (element.dotDotDotToken)
|
|
@@ -1144,12 +875,8 @@ export function fenceFetchObjectAssignment(lowerer, target, source) {
|
|
|
1144
875
|
}
|
|
1145
876
|
/** Iteration syntax invokes Headers[Symbol.iterator] without constructing
|
|
1146
877
|
* an element-access node, so the member chokepoint above never sees it.
|
|
1147
|
-
*
|
|
1148
|
-
* array spread, and array destructuring. The dynamic tier uses the
|
|
1149
|
-
* engine's iterator protocol and is intentionally allowed. */
|
|
878
|
+
* Use the same SC2020 profile row for for-of, array spread, and array destructuring. */
|
|
1150
879
|
export function fenceStaticHeadersIteration(lowerer, node) {
|
|
1151
|
-
if (lowerer.dynamic)
|
|
1152
|
-
return;
|
|
1153
880
|
// The initializer is the value being iterated. Asking for the binding
|
|
1154
881
|
// pattern's synthesized tuple type can panic in TypeScript serialization.
|
|
1155
882
|
const source = ts.isArrayBindingPattern(node) &&
|
|
@@ -1161,101 +888,7 @@ export function fenceStaticHeadersIteration(lowerer, node) {
|
|
|
1161
888
|
const sym = isStdlibFetchInterface(lowerer, value, "Headers");
|
|
1162
889
|
if (!sym)
|
|
1163
890
|
return;
|
|
1164
|
-
lowerer.noLowering("Headers.[Symbol.iterator] in a static build", node, "Headers iteration
|
|
1165
|
-
}
|
|
1166
|
-
/** Dynamic element-spelled Headers iteration. Symbol.iterator uses the
|
|
1167
|
-
* engine's GetIterator operation. A finite union of keys()/values()/entries()
|
|
1168
|
-
* dispatches through fixed-name engine calls after evaluating the receiver
|
|
1169
|
-
* and key once, preserving the method receiver and JavaScript evaluation
|
|
1170
|
-
* order without trying to represent the union of method values. */
|
|
1171
|
-
export function lowerDynamicHeadersIteratorCall(lowerer, call, access) {
|
|
1172
|
-
if (!lowerer.dynamic ||
|
|
1173
|
-
call.questionDotToken ||
|
|
1174
|
-
access.questionDotToken ||
|
|
1175
|
-
call.arguments.length !== 0 ||
|
|
1176
|
-
!isStdlibFetchInterface(lowerer, access.expression, "Headers")) {
|
|
1177
|
-
return null;
|
|
1178
|
-
}
|
|
1179
|
-
const members = fetchElementMemberNames(lowerer, access.argumentExpression);
|
|
1180
|
-
if (members === null)
|
|
1181
|
-
return null;
|
|
1182
|
-
const symbolIterator = members.length === 1 && members[0] === "[Symbol.iterator]";
|
|
1183
|
-
if (!symbolIterator &&
|
|
1184
|
-
!members.every((member) => member === "keys" || member === "values" || member === "entries")) {
|
|
1185
|
-
return null;
|
|
1186
|
-
}
|
|
1187
|
-
const receiver = lowerer.lowerExpr(access.expression);
|
|
1188
|
-
if (receiver.type.kind !== "jsval")
|
|
1189
|
-
return null;
|
|
1190
|
-
const loc = locOf(call);
|
|
1191
|
-
if (!symbolIterator) {
|
|
1192
|
-
const key = lowerer.lowerExpr(access.argumentExpression);
|
|
1193
|
-
if (key.type.kind !== "string")
|
|
1194
|
-
return null;
|
|
1195
|
-
const recvLocal = lowerer.declareHiddenLocal("%headers", JSVAL);
|
|
1196
|
-
const keyLocal = lowerer.declareHiddenLocal("%headersKey", STRING);
|
|
1197
|
-
const recvRef = {
|
|
1198
|
-
kind: "varRef",
|
|
1199
|
-
localId: recvLocal.id,
|
|
1200
|
-
type: JSVAL,
|
|
1201
|
-
loc,
|
|
1202
|
-
};
|
|
1203
|
-
const keyRef = {
|
|
1204
|
-
kind: "varRef",
|
|
1205
|
-
localId: keyLocal.id,
|
|
1206
|
-
type: STRING,
|
|
1207
|
-
loc,
|
|
1208
|
-
};
|
|
1209
|
-
const invoke = (member) => ({
|
|
1210
|
-
kind: "jsOp",
|
|
1211
|
-
op: "callMethod",
|
|
1212
|
-
name: member,
|
|
1213
|
-
args: [recvRef],
|
|
1214
|
-
type: JSVAL,
|
|
1215
|
-
loc,
|
|
1216
|
-
});
|
|
1217
|
-
// Same-kind literal unions erase to STRING in IR, so a lying assertion
|
|
1218
|
-
// can carry a runtime key outside `members`. Validate every arm instead
|
|
1219
|
-
// of treating the last member as an unconditional default: substituting
|
|
1220
|
-
// another method is silent corruption. The trust-but-verify fallback is
|
|
1221
|
-
// the catchable TypeError used by the compiler's other erased casts.
|
|
1222
|
-
let result = nodeThrowExpr(1, "", `${access.getText()} is not a function`, JSVAL, loc);
|
|
1223
|
-
for (let i = members.length - 1; i >= 0; i--) {
|
|
1224
|
-
const member = members[i];
|
|
1225
|
-
result = {
|
|
1226
|
-
kind: "ternary",
|
|
1227
|
-
cond: {
|
|
1228
|
-
kind: "strEq",
|
|
1229
|
-
negated: false,
|
|
1230
|
-
left: keyRef,
|
|
1231
|
-
right: { kind: "strLit", value: member, type: STRING, loc },
|
|
1232
|
-
type: BOOL,
|
|
1233
|
-
loc,
|
|
1234
|
-
},
|
|
1235
|
-
then: invoke(member),
|
|
1236
|
-
else_: result,
|
|
1237
|
-
type: JSVAL,
|
|
1238
|
-
loc,
|
|
1239
|
-
};
|
|
1240
|
-
}
|
|
1241
|
-
return {
|
|
1242
|
-
kind: "seqExpr",
|
|
1243
|
-
stmts: [
|
|
1244
|
-
{ kind: "varDecl", localId: recvLocal.id, init: receiver, loc },
|
|
1245
|
-
{ kind: "varDecl", localId: keyLocal.id, init: key, loc },
|
|
1246
|
-
],
|
|
1247
|
-
result,
|
|
1248
|
-
type: JSVAL,
|
|
1249
|
-
loc,
|
|
1250
|
-
};
|
|
1251
|
-
}
|
|
1252
|
-
return {
|
|
1253
|
-
kind: "jsOp",
|
|
1254
|
-
op: "iterNew",
|
|
1255
|
-
args: [receiver],
|
|
1256
|
-
type: JSVAL,
|
|
1257
|
-
loc,
|
|
1258
|
-
};
|
|
891
|
+
lowerer.noLowering("Headers.[Symbol.iterator] in a static build", node, "Headers iteration is unsupported; use append/delete/get/getSetCookie/has/set/forEach", sym);
|
|
1259
892
|
}
|
|
1260
893
|
/** Bracket-spelled calls on a profiled fetch/Web-stream handle. A call such
|
|
1261
894
|
* as `headers["get"](name)` is still a method reference in JavaScript: the
|
|
@@ -1283,26 +916,21 @@ export function lowerFetchElementMethodCall(lowerer, call) {
|
|
|
1283
916
|
const rows = members.map((member) => NODE24_FETCH_COMPAT_PROFILE.inventory.entries.find((entry) => entry.owner === resolved.owner &&
|
|
1284
917
|
entry.member === member &&
|
|
1285
918
|
(entry.placement === "prototype" || entry.placement === "prototype-inherited")));
|
|
1286
|
-
if (rows.some((row) => row === undefined ||
|
|
1287
|
-
row.status === "out-of-scope" ||
|
|
1288
|
-
(lowerer.dynamic ? row.status === "unsupported" : row.status !== "static"))) {
|
|
919
|
+
if (rows.some((row) => row === undefined || row.status === "out-of-scope" || row.status !== "static")) {
|
|
1289
920
|
return null;
|
|
1290
921
|
}
|
|
1291
922
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
1292
|
-
if (receiver.type.kind !==
|
|
923
|
+
if (receiver.type.kind !== "dyn")
|
|
1293
924
|
return null;
|
|
1294
925
|
const key = lowerer.lowerExpr(access.argumentExpression);
|
|
1295
926
|
if (key.type.kind !== "string")
|
|
1296
927
|
return null;
|
|
1297
928
|
const loc = locOf(call);
|
|
1298
|
-
const receiverLocal = lowerer.declareHiddenLocal("%fetchReceiver",
|
|
929
|
+
const receiverLocal = lowerer.declareHiddenLocal("%fetchReceiver", DYN);
|
|
1299
930
|
const keyLocal = lowerer.declareHiddenLocal("%fetchMember", STRING);
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
: fetchMethodArgumentIsLive(resolved.owner, members, index)
|
|
1304
|
-
? lowerLiveWebValue(lowerer, argument)
|
|
1305
|
-
: lowerer.lowerExprExpecting(argument, DYN));
|
|
931
|
+
const argumentValues = call.arguments.map((argument, index) => fetchMethodArgumentIsLive(resolved.owner, members, index)
|
|
932
|
+
? lowerLiveWebValue(lowerer, argument)
|
|
933
|
+
: lowerer.lowerExprExpecting(argument, DYN));
|
|
1306
934
|
const argumentLocals = argumentValues.map((argument) => lowerer.declareHiddenLocal("%fetchMethodArg", argument.type));
|
|
1307
935
|
const receiverRef = {
|
|
1308
936
|
kind: "varRef",
|
|
@@ -1316,46 +944,24 @@ export function lowerFetchElementMethodCall(lowerer, call) {
|
|
|
1316
944
|
type: STRING,
|
|
1317
945
|
loc,
|
|
1318
946
|
};
|
|
1319
|
-
const
|
|
1320
|
-
|
|
1321
|
-
: {
|
|
1322
|
-
kind: "
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
};
|
|
1327
|
-
const memberReadStmt = calleeLocal === null
|
|
1328
|
-
? {
|
|
1329
|
-
kind: "exprStmt",
|
|
1330
|
-
expr: {
|
|
1331
|
-
kind: "dynKeyGet",
|
|
1332
|
-
value: receiverRef,
|
|
1333
|
-
key: keyRef,
|
|
1334
|
-
type: DYN,
|
|
1335
|
-
loc,
|
|
1336
|
-
},
|
|
1337
|
-
loc,
|
|
1338
|
-
}
|
|
1339
|
-
: {
|
|
1340
|
-
kind: "varDecl",
|
|
1341
|
-
localId: calleeLocal.id,
|
|
1342
|
-
init: {
|
|
1343
|
-
kind: "jsOp",
|
|
1344
|
-
op: "getIdx",
|
|
1345
|
-
args: [receiverRef, { kind: "jsMarshal", value: keyRef, type: JSVAL, loc }],
|
|
1346
|
-
type: JSVAL,
|
|
1347
|
-
loc,
|
|
1348
|
-
},
|
|
947
|
+
const memberReadStmt = {
|
|
948
|
+
kind: "exprStmt",
|
|
949
|
+
expr: {
|
|
950
|
+
kind: "dynKeyGet",
|
|
951
|
+
value: receiverRef,
|
|
952
|
+
key: keyRef,
|
|
953
|
+
type: DYN,
|
|
1349
954
|
loc,
|
|
1350
|
-
}
|
|
955
|
+
},
|
|
956
|
+
loc,
|
|
957
|
+
};
|
|
1351
958
|
const argumentRefs = argumentLocals.map((argument) => ({
|
|
1352
959
|
kind: "varRef",
|
|
1353
960
|
localId: argument.id,
|
|
1354
961
|
type: argument.type,
|
|
1355
962
|
loc,
|
|
1356
963
|
}));
|
|
1357
|
-
const staticResponsePromise =
|
|
1358
|
-
resolved.owner === "Response" &&
|
|
964
|
+
const staticResponsePromise = resolved.owner === "Response" &&
|
|
1359
965
|
call.arguments.length === 0 &&
|
|
1360
966
|
members.every((member) => member === "text" || member === "bytes")
|
|
1361
967
|
? (() => {
|
|
@@ -1370,35 +976,27 @@ export function lowerFetchElementMethodCall(lowerer, call) {
|
|
|
1370
976
|
return inner ? { kind: "promise", inner } : null;
|
|
1371
977
|
})()
|
|
1372
978
|
: null;
|
|
1373
|
-
const invoke = (member) =>
|
|
979
|
+
const invoke = (member) => staticResponsePromise !== null
|
|
1374
980
|
? {
|
|
1375
|
-
kind: "
|
|
1376
|
-
|
|
1377
|
-
args: [
|
|
1378
|
-
type:
|
|
981
|
+
kind: "libCall",
|
|
982
|
+
fn: member === "text" ? "fetch.responseText" : "fetch.responseBytes",
|
|
983
|
+
args: [receiverRef],
|
|
984
|
+
type: staticResponsePromise,
|
|
1379
985
|
loc,
|
|
1380
986
|
}
|
|
1381
|
-
:
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
kind: "dynInvoke",
|
|
1391
|
-
recv: receiverRef,
|
|
1392
|
-
method: member,
|
|
1393
|
-
calleeName: access.getText(),
|
|
1394
|
-
args: argumentRefs,
|
|
1395
|
-
type: DYN,
|
|
1396
|
-
loc,
|
|
1397
|
-
};
|
|
987
|
+
: {
|
|
988
|
+
kind: "dynInvoke",
|
|
989
|
+
recv: receiverRef,
|
|
990
|
+
method: member,
|
|
991
|
+
calleeName: access.getText(),
|
|
992
|
+
args: argumentRefs,
|
|
993
|
+
type: DYN,
|
|
994
|
+
loc,
|
|
995
|
+
};
|
|
1398
996
|
// Literal-string unions share the STRING carrier. A cast can therefore
|
|
1399
997
|
// smuggle a different runtime key into this call; validate all arms and
|
|
1400
998
|
// fail loudly rather than dispatching every mismatch to the last member.
|
|
1401
|
-
const invocationType = staticResponsePromise ??
|
|
999
|
+
const invocationType = staticResponsePromise ?? DYN;
|
|
1402
1000
|
let result = nodeThrowExpr(1, "", `${access.getText()} is not a function`, invocationType, loc);
|
|
1403
1001
|
for (let index = members.length - 1; index >= 0; index--) {
|
|
1404
1002
|
const member = members[index];
|
|
@@ -1418,11 +1016,6 @@ export function lowerFetchElementMethodCall(lowerer, call) {
|
|
|
1418
1016
|
loc,
|
|
1419
1017
|
};
|
|
1420
1018
|
}
|
|
1421
|
-
const declared = lowerer.dynamic ? lowerer.mapTypeOf(lowerer.typeOf(call)) : null;
|
|
1422
|
-
if (declared &&
|
|
1423
|
-
(declared.kind === "f64" || declared.kind === "bool" || declared.kind === "string")) {
|
|
1424
|
-
result = { kind: "jsExit", value: result, type: declared, loc };
|
|
1425
|
-
}
|
|
1426
1019
|
return {
|
|
1427
1020
|
kind: "seqExpr",
|
|
1428
1021
|
stmts: [
|
|
@@ -1441,36 +1034,6 @@ export function lowerFetchElementMethodCall(lowerer, call) {
|
|
|
1441
1034
|
loc,
|
|
1442
1035
|
};
|
|
1443
1036
|
}
|
|
1444
|
-
/** `[...headers]` in the dynamic tier: Array.from runs inside the engine
|
|
1445
|
-
* over the real Headers iterator, then the resulting pair array exits
|
|
1446
|
-
* through the checker's declared array type. For Headers this is the
|
|
1447
|
-
* spread algorithm's exact iterable snapshot. */
|
|
1448
|
-
export function lowerDynamicHeadersSpread(lowerer, node, type) {
|
|
1449
|
-
if (!lowerer.dynamic || !isStdlibFetchInterface(lowerer, requestInitValueExpr(node), "Headers")) {
|
|
1450
|
-
return null;
|
|
1451
|
-
}
|
|
1452
|
-
const receiver = lowerer.lowerExpr(node);
|
|
1453
|
-
if (receiver.type.kind !== "jsval")
|
|
1454
|
-
return null;
|
|
1455
|
-
const loc = locOf(node);
|
|
1456
|
-
const arrayCtor = {
|
|
1457
|
-
kind: "jsOp",
|
|
1458
|
-
op: "globalGet",
|
|
1459
|
-
name: "Array",
|
|
1460
|
-
args: [],
|
|
1461
|
-
type: JSVAL,
|
|
1462
|
-
loc,
|
|
1463
|
-
};
|
|
1464
|
-
const snapshot = {
|
|
1465
|
-
kind: "jsOp",
|
|
1466
|
-
op: "callMethod",
|
|
1467
|
-
name: "from",
|
|
1468
|
-
args: [arrayCtor, receiver],
|
|
1469
|
-
type: JSVAL,
|
|
1470
|
-
loc,
|
|
1471
|
-
};
|
|
1472
|
-
return { kind: "jsExit", value: snapshot, type, loc };
|
|
1473
|
-
}
|
|
1474
1037
|
/** The fallback ambient declaration intentionally exposes only the native
|
|
1475
1038
|
* stream slice, but @types/node adopts the complete WHATWG ReadableStream
|
|
1476
1039
|
* interface. Fence that wider surface before its checked-dynamic handle can
|
|
@@ -1483,19 +1046,16 @@ export function fenceStaticReadableStreamMember(lowerer, access, use) {
|
|
|
1483
1046
|
if (members === null)
|
|
1484
1047
|
return null;
|
|
1485
1048
|
const status = (member) => fetchInventoryStatus("ReadableStream", member, member.startsWith("[Symbol.") ? "prototype-symbol" : "prototype");
|
|
1486
|
-
if (lowerer.dynamic && members.every((member) => status(member) !== "unsupported")) {
|
|
1487
|
-
return null;
|
|
1488
|
-
}
|
|
1489
1049
|
const supported = (member) => use === "call"
|
|
1490
1050
|
? STATIC_READABLE_STREAM_CALLS.has(member)
|
|
1491
1051
|
: STATIC_READABLE_STREAM_READS.has(member);
|
|
1492
|
-
if (
|
|
1052
|
+
if (members.every(supported))
|
|
1493
1053
|
return null;
|
|
1494
|
-
const member = members.find((candidate) =>
|
|
1054
|
+
const member = members.find((candidate) => !supported(candidate));
|
|
1495
1055
|
if (status(member) === "unsupported") {
|
|
1496
|
-
lowerer.noLowering(`ReadableStream.${member}`, access, fetchInventoryReason("ReadableStream", member, member.startsWith("[Symbol.") ? "prototype-symbol" : "prototype") ?? "this ReadableStream operation has no compiler lowering
|
|
1056
|
+
lowerer.noLowering(`ReadableStream.${member}`, access, fetchInventoryReason("ReadableStream", member, member.startsWith("[Symbol.") ? "prototype-symbol" : "prototype") ?? "this ReadableStream operation has no compiler lowering", sym);
|
|
1497
1057
|
}
|
|
1498
|
-
lowerer.noLowering(`ReadableStream.${member} in a static build`, access, "the native static ReadableStream surface is locked plus cancel() and getReader(); values()/[Symbol.asyncIterator]() compile when consumed directly by for await, while stored iterator handles
|
|
1058
|
+
lowerer.noLowering(`ReadableStream.${member} in a static build`, access, "the native static ReadableStream surface is locked plus cancel() and getReader(); values()/[Symbol.asyncIterator]() compile when consumed directly by for await, while stored iterator handles remain unsupported", sym);
|
|
1499
1059
|
}
|
|
1500
1060
|
/** Static AbortSignal constructors and ReadableStream.from(). These
|
|
1501
1061
|
* ambient globals have no first-class constructor-object representation;
|
|
@@ -1537,8 +1097,7 @@ function staticCallWithSurplusArgs(lowerer, call, first, result) {
|
|
|
1537
1097
|
return result(staticFirstArgWithSurplusArgs(lowerer, call, first));
|
|
1538
1098
|
}
|
|
1539
1099
|
export function lowerStaticFetchCompanionCall(lowerer, call) {
|
|
1540
|
-
if (
|
|
1541
|
-
call.questionDotToken ||
|
|
1100
|
+
if (call.questionDotToken ||
|
|
1542
1101
|
!ts.isPropertyAccessExpression(call.expression) ||
|
|
1543
1102
|
call.expression.questionDotToken ||
|
|
1544
1103
|
!ts.isIdentifier(call.expression.expression)) {
|
|
@@ -1656,8 +1215,7 @@ export function lowerStaticFetchCompanionCall(lowerer, call) {
|
|
|
1656
1215
|
* are ignored by the runtime operation. */
|
|
1657
1216
|
export function lowerStaticAbortControllerCall(lowerer, call) {
|
|
1658
1217
|
const access = call.expression;
|
|
1659
|
-
if (
|
|
1660
|
-
call.questionDotToken ||
|
|
1218
|
+
if (call.questionDotToken ||
|
|
1661
1219
|
call.arguments.some((argument) => ts.isSpreadElement(argument)) ||
|
|
1662
1220
|
(!ts.isPropertyAccessExpression(access) && !ts.isElementAccessExpression(access)) ||
|
|
1663
1221
|
access.questionDotToken ||
|
|
@@ -1695,8 +1253,7 @@ export function lowerStaticAbortControllerCall(lowerer, call) {
|
|
|
1695
1253
|
* object identity for the reader/source callbacks that observe them. */
|
|
1696
1254
|
export function lowerStaticReadableStreamControllerCall(lowerer, call) {
|
|
1697
1255
|
const access = call.expression;
|
|
1698
|
-
if (
|
|
1699
|
-
call.questionDotToken ||
|
|
1256
|
+
if (call.questionDotToken ||
|
|
1700
1257
|
call.arguments.length > 1 ||
|
|
1701
1258
|
(!ts.isPropertyAccessExpression(access) && !ts.isElementAccessExpression(access)) ||
|
|
1702
1259
|
access.questionDotToken) {
|
|
@@ -1735,8 +1292,7 @@ export function lowerStaticReadableStreamControllerCall(lowerer, call) {
|
|
|
1735
1292
|
* live typed-reference capsule instead of the general dyn boundary's copy. */
|
|
1736
1293
|
export function lowerStaticReadableStreamCancelCall(lowerer, call) {
|
|
1737
1294
|
const access = call.expression;
|
|
1738
|
-
if (
|
|
1739
|
-
call.questionDotToken ||
|
|
1295
|
+
if (call.questionDotToken ||
|
|
1740
1296
|
call.arguments.length > 1 ||
|
|
1741
1297
|
call.arguments.some((argument) => ts.isSpreadElement(argument)) ||
|
|
1742
1298
|
(!ts.isPropertyAccessExpression(access) && !ts.isElementAccessExpression(access)) ||
|
|
@@ -1771,8 +1327,7 @@ export function lowerStaticReadableStreamCancelCall(lowerer, call) {
|
|
|
1771
1327
|
* chunks so repeated crossings still denote one EventListener object. */
|
|
1772
1328
|
export function lowerStaticAbortSignalListenerCall(lowerer, call) {
|
|
1773
1329
|
const access = call.expression;
|
|
1774
|
-
if (
|
|
1775
|
-
call.questionDotToken ||
|
|
1330
|
+
if (call.questionDotToken ||
|
|
1776
1331
|
call.arguments.length < 2 ||
|
|
1777
1332
|
call.arguments.some((arg) => ts.isSpreadElement(arg)) ||
|
|
1778
1333
|
(!ts.isPropertyAccessExpression(access) && !ts.isElementAccessExpression(access)) ||
|
|
@@ -1806,10 +1361,6 @@ export function lowerStaticAbortSignalListenerCall(lowerer, call) {
|
|
|
1806
1361
|
loc,
|
|
1807
1362
|
}));
|
|
1808
1363
|
}
|
|
1809
|
-
/** `new AbortController()`. Static builds create a native controller handle
|
|
1810
|
-
* over the same signal state consumed by fetch; dynamic builds construct the
|
|
1811
|
-
* island Web object. JavaScript accepts surplus constructor arguments, so
|
|
1812
|
-
* both tiers evaluate them even though AbortController ignores their values. */
|
|
1813
1364
|
export function lowerAbortControllerNew(lowerer, expr) {
|
|
1814
1365
|
if (!ts.isIdentifier(expr.expression) || expr.expression.text !== "AbortController") {
|
|
1815
1366
|
return null;
|
|
@@ -1821,26 +1372,6 @@ export function lowerAbortControllerNew(lowerer, expr) {
|
|
|
1821
1372
|
if (args.some((argument) => ts.isSpreadElement(argument)))
|
|
1822
1373
|
return null;
|
|
1823
1374
|
const loc = locOf(expr);
|
|
1824
|
-
if (lowerer.dynamic) {
|
|
1825
|
-
const ctor = {
|
|
1826
|
-
kind: "jsOp",
|
|
1827
|
-
op: "globalGet",
|
|
1828
|
-
name: "AbortController",
|
|
1829
|
-
args: [],
|
|
1830
|
-
type: JSVAL,
|
|
1831
|
-
loc,
|
|
1832
|
-
};
|
|
1833
|
-
return {
|
|
1834
|
-
kind: "jsOp",
|
|
1835
|
-
op: "construct",
|
|
1836
|
-
args: [
|
|
1837
|
-
ctor,
|
|
1838
|
-
...args.map((argument) => lowerer.jsvalIn(lowerer.lowerExpr(argument), argument)),
|
|
1839
|
-
],
|
|
1840
|
-
type: JSVAL,
|
|
1841
|
-
loc,
|
|
1842
|
-
};
|
|
1843
|
-
}
|
|
1844
1375
|
const result = {
|
|
1845
1376
|
kind: "libCall",
|
|
1846
1377
|
fn: "fetch.abortControllerNew",
|
|
@@ -1862,9 +1393,6 @@ export function lowerAbortControllerNew(lowerer, expr) {
|
|
|
1862
1393
|
loc,
|
|
1863
1394
|
};
|
|
1864
1395
|
}
|
|
1865
|
-
/** `new ReadableStream(source?)`. Static builds box the source record into
|
|
1866
|
-
* the checked-dynamic tree; dynamic builds construct the island's Web
|
|
1867
|
-
* stream directly so the returned handle composes with dynamic fetch. */
|
|
1868
1396
|
export function lowerStaticReadableStreamNew(lowerer, expr) {
|
|
1869
1397
|
if (!ts.isIdentifier(expr.expression) || expr.expression.text !== "ReadableStream") {
|
|
1870
1398
|
return null;
|
|
@@ -1876,28 +1404,6 @@ export function lowerStaticReadableStreamNew(lowerer, expr) {
|
|
|
1876
1404
|
if (args.length > 1)
|
|
1877
1405
|
return null;
|
|
1878
1406
|
const loc = locOf(expr);
|
|
1879
|
-
if (lowerer.dynamic) {
|
|
1880
|
-
const ctor = {
|
|
1881
|
-
kind: "jsOp",
|
|
1882
|
-
op: "globalGet",
|
|
1883
|
-
name: "ReadableStream",
|
|
1884
|
-
args: [],
|
|
1885
|
-
type: JSVAL,
|
|
1886
|
-
loc,
|
|
1887
|
-
};
|
|
1888
|
-
const source = args[0] === undefined
|
|
1889
|
-
? null
|
|
1890
|
-
: ts.isObjectLiteralExpression(args[0])
|
|
1891
|
-
? lowerIslandObjectLiteral(lowerer, args[0])
|
|
1892
|
-
: lowerer.jsvalIn(lowerer.lowerExpr(args[0]), args[0]);
|
|
1893
|
-
return {
|
|
1894
|
-
kind: "jsOp",
|
|
1895
|
-
op: "construct",
|
|
1896
|
-
args: source === null ? [ctor] : [ctor, source],
|
|
1897
|
-
type: JSVAL,
|
|
1898
|
-
loc,
|
|
1899
|
-
};
|
|
1900
|
-
}
|
|
1901
1407
|
const source = args.length === 0
|
|
1902
1408
|
? dynUndefinedExpr(loc)
|
|
1903
1409
|
: ts.isObjectLiteralExpression(args[0])
|
|
@@ -1920,17 +1426,6 @@ export function lowerFetchWebNew(lowerer, expr) {
|
|
|
1920
1426
|
if (args.some(ts.isSpreadElement))
|
|
1921
1427
|
return null;
|
|
1922
1428
|
const loc = locOf(expr);
|
|
1923
|
-
if (lowerer.dynamic)
|
|
1924
|
-
return {
|
|
1925
|
-
kind: "jsOp",
|
|
1926
|
-
op: "construct",
|
|
1927
|
-
args: [
|
|
1928
|
-
{ kind: "jsOp", op: "globalGet", name, args: [], type: JSVAL, loc },
|
|
1929
|
-
...args.map((arg) => lowerer.jsvalIn(lowerer.lowerExpr(arg), arg)),
|
|
1930
|
-
],
|
|
1931
|
-
type: JSVAL,
|
|
1932
|
-
loc,
|
|
1933
|
-
};
|
|
1934
1429
|
if (name === "Request" && args[1])
|
|
1935
1430
|
fenceRequestInitValue(lowerer, args[1]);
|
|
1936
1431
|
const lowered = args.map((arg) => ts.isObjectLiteralExpression(arg)
|
|
@@ -1946,10 +1441,6 @@ export function lowerFetchWebNew(lowerer, expr) {
|
|
|
1946
1441
|
loc,
|
|
1947
1442
|
};
|
|
1948
1443
|
}
|
|
1949
|
-
/** `new Response(body?, init?)`. Dynamic builds construct the island's
|
|
1950
|
-
* Web Response directly. Static builds hand a checked-dynamic BodyInit and
|
|
1951
|
-
* ResponseInit snapshot to the native fetch runtime, which returns the same
|
|
1952
|
-
* opaque Response handle as fetch(). */
|
|
1953
1444
|
export function lowerResponseNew(lowerer, expr) {
|
|
1954
1445
|
if (stdlibGlobalNameOf(lowerer, expr.expression) !== "Response")
|
|
1955
1446
|
return null;
|
|
@@ -1957,26 +1448,6 @@ export function lowerResponseNew(lowerer, expr) {
|
|
|
1957
1448
|
if (args.some(ts.isSpreadElement))
|
|
1958
1449
|
return null;
|
|
1959
1450
|
const loc = locOf(expr);
|
|
1960
|
-
if (lowerer.dynamic) {
|
|
1961
|
-
const ctor = {
|
|
1962
|
-
kind: "jsOp",
|
|
1963
|
-
op: "globalGet",
|
|
1964
|
-
name: "Response",
|
|
1965
|
-
args: [],
|
|
1966
|
-
type: JSVAL,
|
|
1967
|
-
loc,
|
|
1968
|
-
};
|
|
1969
|
-
const lowered = args.map((arg) => ts.isObjectLiteralExpression(arg)
|
|
1970
|
-
? lowerIslandObjectLiteral(lowerer, arg)
|
|
1971
|
-
: lowerer.jsvalIn(lowerer.lowerExpr(arg), arg));
|
|
1972
|
-
return {
|
|
1973
|
-
kind: "jsOp",
|
|
1974
|
-
op: "construct",
|
|
1975
|
-
args: [ctor, ...lowered],
|
|
1976
|
-
type: JSVAL,
|
|
1977
|
-
loc,
|
|
1978
|
-
};
|
|
1979
|
-
}
|
|
1980
1451
|
const toDyn = (node, value, what) => {
|
|
1981
1452
|
if (node === undefined)
|
|
1982
1453
|
return dynUndefinedExpr(loc);
|
|
@@ -2099,8 +1570,7 @@ export function lowerResponseNew(lowerer, expr) {
|
|
|
2099
1570
|
* widening keeps the compiler's ordinary copy-based width semantics. */
|
|
2100
1571
|
export function lowerStaticReadableStreamReaderCall(lowerer, call) {
|
|
2101
1572
|
const access = call.expression;
|
|
2102
|
-
if (
|
|
2103
|
-
call.questionDotToken ||
|
|
1573
|
+
if (call.questionDotToken ||
|
|
2104
1574
|
call.arguments.length !== 0 ||
|
|
2105
1575
|
(!ts.isPropertyAccessExpression(access) && !ts.isElementAccessExpression(access)) ||
|
|
2106
1576
|
access.questionDotToken) {
|
|
@@ -2130,142 +1600,27 @@ export function lowerStaticReadableStreamReaderCall(lowerer, call) {
|
|
|
2130
1600
|
loc: locOf(call),
|
|
2131
1601
|
}));
|
|
2132
1602
|
}
|
|
2133
|
-
/** Literal `import(spec)` at a user site. Static builds compile program
|
|
2134
|
-
* modules and supported Node builtins to a native Promise<moduleNs>;
|
|
2135
|
-
* dynamic builds retain the island-backed package/module path below.
|
|
2136
|
-
* Under --dynamic the call lowers to island.importDyn(key): the engine
|
|
2137
|
-
* loads the module (embedded npm graph, a shipped local .js/.mjs the
|
|
2138
|
-
* build embedded, or a builtin shim — collectDynamicImports resolved and
|
|
2139
|
-
* embedded the specifier at collection time) and answers an ENGINE
|
|
2140
|
-
* promise of the namespace object, bridged to a static
|
|
2141
|
-
* `Promise<jsval>` (jsBridgePromise, the fetch precedent) — so `await
|
|
2142
|
-
* import(x)` parks the fiber and resumes with the namespace HANDLE, and
|
|
2143
|
-
* a load/evaluation failure crosses as a catchable rejection, exactly
|
|
2144
|
-
* where Node puts it. Specifiers must be string literals: the module
|
|
2145
|
-
* graph is a BUILD-time artifact — a runtime-computed name has nothing
|
|
2146
|
-
* to embed, and the fence says so. Static builds accept compiled program
|
|
2147
|
-
* modules and supported builtins; other execution homes report SC2012.
|
|
2148
|
-
* Null for anything that isn't `import(...)`. */
|
|
2149
1603
|
export function lowerDynamicImportCall(lowerer, call) {
|
|
2150
1604
|
if (call.expression.kind !== ts.SyntaxKind.ImportKeyword)
|
|
2151
1605
|
return null;
|
|
2152
|
-
const loc = locOf(call);
|
|
2153
1606
|
const arg = call.arguments[0];
|
|
2154
1607
|
if (arg === undefined || !ts.isStringLiteralLike(arg)) {
|
|
2155
|
-
lowerer.unsupported("SC1090", call, "dynamic import() of computed specifiers (the module graph
|
|
1608
|
+
lowerer.unsupported("SC1090", call, "dynamic import() of computed specifiers (the module graph resolves at " +
|
|
2156
1609
|
"build time — the specifier must be a string literal)");
|
|
2157
1610
|
}
|
|
2158
1611
|
if (call.arguments.length !== 1) {
|
|
2159
1612
|
lowerer.unsupported("SC1090", call, "dynamic import() with import attributes");
|
|
2160
1613
|
}
|
|
2161
1614
|
const res = lowerer.dynImports.get(`${call.getSourceFile().fileName}\u0000${arg.text}`);
|
|
2162
|
-
if (
|
|
2163
|
-
|
|
2164
|
-
return lowerOwnStaticModuleImport(lowerer, call, arg);
|
|
2165
|
-
}
|
|
2166
|
-
if (res?.kind === "static-builtin") {
|
|
2167
|
-
return lowerStaticNamespaceImport(lowerer, call, {
|
|
2168
|
-
kind: "moduleNs",
|
|
2169
|
-
moduleId: `builtin:${res.module}`,
|
|
2170
|
-
});
|
|
2171
|
-
}
|
|
2172
|
-
lowerer.requireDynamicApi("'import()'", call);
|
|
2173
|
-
throw new PoisonError();
|
|
2174
|
-
}
|
|
2175
|
-
lowerer.requireDynamicApi("'import()'", call);
|
|
2176
|
-
if (!res) {
|
|
2177
|
-
// Collection walks every file before bodies lower, so a missing
|
|
2178
|
-
// entry is a lowerer bug, not user error.
|
|
2179
|
-
throw new InternalCompilerError(`lowerer bug: unresolved dynamic import '${arg.text}'`);
|
|
2180
|
-
}
|
|
1615
|
+
if (res === undefined)
|
|
1616
|
+
lowerer.refuseUnsupportedApi("'import()'", call);
|
|
2181
1617
|
if (res.kind === "program-module") {
|
|
2182
|
-
return
|
|
2183
|
-
}
|
|
2184
|
-
if (res.kind !== "module") {
|
|
2185
|
-
throw new PoisonError(); // resolution failed — collection reported it
|
|
2186
|
-
}
|
|
2187
|
-
const raw = {
|
|
2188
|
-
kind: "libCall",
|
|
2189
|
-
fn: "island.importDyn",
|
|
2190
|
-
args: [{ kind: "strLit", value: res.key, type: STRING, loc }],
|
|
2191
|
-
type: JSVAL,
|
|
2192
|
-
loc,
|
|
2193
|
-
};
|
|
2194
|
-
return { kind: "jsBridgePromise", value: raw, type: { kind: "promise", inner: JSVAL }, loc };
|
|
2195
|
-
}
|
|
2196
|
-
/** Dynamic `import()` of one of the program's OWN modules: the compiled
|
|
2197
|
-
* module's exports, marshaled into the engine as a namespace object.
|
|
2198
|
-
* The site lowers to `Promise.resolve().then(<builder>)` in the engine —
|
|
2199
|
-
* the builder is a synthesized compiled function (dynNsBuilderOf) that
|
|
2200
|
-
* runs on the engine MICROTASK, calls the target module's run-once %init
|
|
2201
|
-
* (Node's evaluation point for a module first reached through import():
|
|
2202
|
-
* after the importer's synchronous code, before the .then handlers), and
|
|
2203
|
-
* returns the exports object. Node differences (numbered divergences,
|
|
2204
|
-
* pinned in island.test.ts): the namespace is a SNAPSHOT taken when the
|
|
2205
|
-
* import resolves (Node's is live), a plain engine object (no Module
|
|
2206
|
-
* toStringTag, keys still sorted like Node's, each import minting a
|
|
2207
|
-
* fresh object where Node caches one), and exports with no island
|
|
2208
|
-
* representation (classes, generic functions, un-marshalable
|
|
2209
|
-
* signatures) cross as trap functions that throw a pointed TypeError
|
|
2210
|
-
* when USED — the namespace still builds, exactly like Node still
|
|
2211
|
-
* resolves it. */
|
|
2212
|
-
function lowerOwnDynamicModuleImport(lowerer, call, arg) {
|
|
2213
|
-
const loc = locOf(call);
|
|
2214
|
-
let dep = null;
|
|
2215
|
-
const modSym = lowerer.checker.getSymbolAtLocation(arg);
|
|
2216
|
-
for (const d of modSym ? lowerer.checker.declarationsOf(modSym) : []) {
|
|
2217
|
-
if (ts.isSourceFile(d) && !d.isDeclarationFile) {
|
|
2218
|
-
dep = d;
|
|
2219
|
-
break;
|
|
2220
|
-
}
|
|
1618
|
+
return lowerOwnStaticModuleImport(lowerer, call, arg);
|
|
2221
1619
|
}
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
}
|
|
2227
|
-
const builder = dep !== null ? dynNsBuilderOf(lowerer, dep, loc) : null;
|
|
2228
|
-
if (builder === null) {
|
|
2229
|
-
lowerer.unsupported("SC1090", call, `dynamic import of the program's own module '${arg.text}' ` +
|
|
2230
|
-
"(this module is not part of the compiled module graph — import it statically)");
|
|
2231
|
-
}
|
|
2232
|
-
const promiseCtor = {
|
|
2233
|
-
kind: "jsOp",
|
|
2234
|
-
op: "globalGet",
|
|
2235
|
-
name: "Promise",
|
|
2236
|
-
args: [],
|
|
2237
|
-
type: JSVAL,
|
|
2238
|
-
loc,
|
|
2239
|
-
};
|
|
2240
|
-
const resolved = {
|
|
2241
|
-
kind: "jsOp",
|
|
2242
|
-
op: "callMethod",
|
|
2243
|
-
name: "resolve",
|
|
2244
|
-
args: [promiseCtor],
|
|
2245
|
-
type: JSVAL,
|
|
2246
|
-
loc,
|
|
2247
|
-
};
|
|
2248
|
-
const builderAsync = dep !== null && lowerer.asyncInitFiles.has(dep);
|
|
2249
|
-
const builderFn = {
|
|
2250
|
-
kind: "func",
|
|
2251
|
-
params: [],
|
|
2252
|
-
ret: builderAsync ? { kind: "promise", inner: JSVAL } : JSVAL,
|
|
2253
|
-
};
|
|
2254
|
-
const marshaled = {
|
|
2255
|
-
kind: "jsMarshal",
|
|
2256
|
-
value: { kind: "closure", fnName: builder, captures: [], type: builderFn, loc },
|
|
2257
|
-
type: JSVAL,
|
|
2258
|
-
loc,
|
|
2259
|
-
};
|
|
2260
|
-
const chained = {
|
|
2261
|
-
kind: "jsOp",
|
|
2262
|
-
op: "callMethod",
|
|
2263
|
-
name: "then",
|
|
2264
|
-
args: [resolved, marshaled],
|
|
2265
|
-
type: JSVAL,
|
|
2266
|
-
loc,
|
|
2267
|
-
};
|
|
2268
|
-
return { kind: "jsBridgePromise", value: chained, type: { kind: "promise", inner: JSVAL }, loc };
|
|
1620
|
+
return lowerStaticNamespaceImport(lowerer, call, {
|
|
1621
|
+
kind: "moduleNs",
|
|
1622
|
+
moduleId: `builtin:${res.module}`,
|
|
1623
|
+
});
|
|
2269
1624
|
}
|
|
2270
1625
|
/** The checker-resolved program source behind one literal import(). */
|
|
2271
1626
|
function programImportTarget(lowerer, arg) {
|
|
@@ -2410,408 +1765,25 @@ function appendStaticModuleInit(lowerer, dep, body, loc) {
|
|
|
2410
1765
|
loc,
|
|
2411
1766
|
});
|
|
2412
1767
|
}
|
|
2413
|
-
|
|
2414
|
-
* first demand and shared by every import() of that module (deterministic
|
|
2415
|
-
* name per file tag, so the discovery and emit passes agree). Body: the
|
|
2416
|
-
* module's guarded %init (skipped for the entry — it is running or ran),
|
|
2417
|
-
* then `return { <sorted exports> }` as an engine object. Null when the
|
|
2418
|
-
* module never joined the compiled graph (no %init exists — an empty
|
|
2419
|
-
* preflight order or a cycle the extension refused). */
|
|
2420
|
-
function dynNsBuilderOf(lowerer, dep, loc) {
|
|
2421
|
-
const cached = lowerer.dynNsBuilders.get(dep);
|
|
2422
|
-
if (cached !== undefined)
|
|
2423
|
-
return cached;
|
|
2424
|
-
const initName = lowerer.initNameOf.get(dep);
|
|
2425
|
-
if (initName === undefined)
|
|
2426
|
-
return null;
|
|
2427
|
-
const rawTag = lowerer.fileTag.get(dep) ?? "";
|
|
2428
|
-
const name = `%dynns.${rawTag === "" ? "e." : rawTag.replace(/^%/, "")}`;
|
|
2429
|
-
lowerer.dynNsBuilders.set(dep, name);
|
|
2430
|
-
const isAsync = lowerer.asyncInitFiles.has(dep);
|
|
2431
|
-
const fnCtx = newFnCtx(true, null, null, JSVAL);
|
|
2432
|
-
fnCtx.isAsync = isAsync;
|
|
2433
|
-
lowerer.fnStack.push(fnCtx);
|
|
2434
|
-
try {
|
|
2435
|
-
const body = [];
|
|
2436
|
-
const linkCrash = esmNamedImportLinkCrash(lowerer.program, dep);
|
|
2437
|
-
if (linkCrash !== null) {
|
|
2438
|
-
// A dynamic import links its graph when the returned promise is
|
|
2439
|
-
// settled. Throw from the synthesized namespace builder, which runs
|
|
2440
|
-
// inside the Promise reaction, so no module init executes before the
|
|
2441
|
-
// link failure and the bridge turns it into the import rejection.
|
|
2442
|
-
body.push({
|
|
2443
|
-
kind: "throw",
|
|
2444
|
-
value: {
|
|
2445
|
-
kind: "libCall",
|
|
2446
|
-
fn: "error.new",
|
|
2447
|
-
args: [{ kind: "strLit", value: linkCrash.message, type: STRING, loc }],
|
|
2448
|
-
type: { kind: "object", className: linkCrash.className },
|
|
2449
|
-
loc,
|
|
2450
|
-
},
|
|
2451
|
-
loc,
|
|
2452
|
-
});
|
|
2453
|
-
}
|
|
2454
|
-
// A synchronous entry has no run-once guard, so its historical
|
|
2455
|
-
// self-import path must not call %init again. An ASYNC entry does
|
|
2456
|
-
// have the stronger evaluation-promise cache: awaiting that cached
|
|
2457
|
-
// promise is essential for top-level `await import("./self")`,
|
|
2458
|
-
// which deadlocks (and ultimately exits 13) in Node rather than
|
|
2459
|
-
// exposing a half-evaluated namespace.
|
|
2460
|
-
if (linkCrash === null && (dep !== lowerer.entry || isAsync)) {
|
|
2461
|
-
const call = {
|
|
2462
|
-
kind: "call",
|
|
2463
|
-
callee: initName,
|
|
2464
|
-
args: [],
|
|
2465
|
-
type: isAsync ? { kind: "promise", inner: VOID } : VOID,
|
|
2466
|
-
loc,
|
|
2467
|
-
};
|
|
2468
|
-
const cyclePromiseId = lowerer.asyncCyclePromiseOf.get(dep);
|
|
2469
|
-
if (isAsync && cyclePromiseId !== undefined) {
|
|
2470
|
-
// Starting the REQUESTED member matters for dynamically-only
|
|
2471
|
-
// cycles: build-time discovery may have encountered another
|
|
2472
|
-
// member first, but Node roots evaluation at the first module
|
|
2473
|
-
// actually imported at runtime. The spawn wrapper publishes
|
|
2474
|
-
// that outermost promise in the SCC's shared slot after eager
|
|
2475
|
-
// recursive spawning returns. Discard the member promise here
|
|
2476
|
-
// and await the shared root before exposing any namespace.
|
|
2477
|
-
body.push({ kind: "exprStmt", expr: call, loc });
|
|
2478
|
-
const promiseT = { kind: "promise", inner: VOID };
|
|
2479
|
-
body.push({
|
|
2480
|
-
kind: "exprStmt",
|
|
2481
|
-
expr: {
|
|
2482
|
-
kind: "awaitExpr",
|
|
2483
|
-
value: { kind: "varRef", localId: cyclePromiseId, type: promiseT, loc },
|
|
2484
|
-
type: VOID,
|
|
2485
|
-
loc,
|
|
2486
|
-
},
|
|
2487
|
-
loc,
|
|
2488
|
-
});
|
|
2489
|
-
}
|
|
2490
|
-
else {
|
|
2491
|
-
body.push({
|
|
2492
|
-
kind: "exprStmt",
|
|
2493
|
-
expr: isAsync ? { kind: "awaitExpr", value: call, type: VOID, loc } : call,
|
|
2494
|
-
loc,
|
|
2495
|
-
});
|
|
2496
|
-
}
|
|
2497
|
-
}
|
|
2498
|
-
// Node sorts module-namespace keys (code-unit order); tsc erases
|
|
2499
|
-
// type-only exports, so only VALUE exports appear.
|
|
2500
|
-
const entries = [];
|
|
2501
|
-
const modSym = lowerer.checker.getSymbolAtLocation(dep);
|
|
2502
|
-
modSym?.getExports().forEach((sym, key) => {
|
|
2503
|
-
const n = String(key);
|
|
2504
|
-
if (!n.startsWith("__") && n !== "export=")
|
|
2505
|
-
entries.push([n, sym]);
|
|
2506
|
-
});
|
|
2507
|
-
entries.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
|
|
2508
|
-
const args = [];
|
|
2509
|
-
for (const [exportName, sym] of entries) {
|
|
2510
|
-
const value = exportJsvalValue(lowerer, exportName, sym, loc);
|
|
2511
|
-
if (value === null)
|
|
2512
|
-
continue;
|
|
2513
|
-
args.push({
|
|
2514
|
-
kind: "jsMarshal",
|
|
2515
|
-
value: { kind: "strLit", value: exportName, type: STRING, loc },
|
|
2516
|
-
type: JSVAL,
|
|
2517
|
-
loc,
|
|
2518
|
-
}, value);
|
|
2519
|
-
}
|
|
2520
|
-
body.push({
|
|
2521
|
-
kind: "return",
|
|
2522
|
-
value: { kind: "jsOp", op: "objLit", args, type: JSVAL, loc },
|
|
2523
|
-
loc,
|
|
2524
|
-
});
|
|
2525
|
-
const ctx = lowerer.ctx;
|
|
2526
|
-
lowerer.liftedFns.push({
|
|
2527
|
-
name,
|
|
2528
|
-
params: [],
|
|
2529
|
-
returnType: JSVAL,
|
|
2530
|
-
locals: ctx.locals,
|
|
2531
|
-
captures: ctx.captures ?? [],
|
|
2532
|
-
body,
|
|
2533
|
-
...(isAsync ? { async: true } : {}),
|
|
2534
|
-
loc,
|
|
2535
|
-
});
|
|
2536
|
-
}
|
|
2537
|
-
finally {
|
|
2538
|
-
lowerer.fnStack.pop();
|
|
2539
|
-
}
|
|
2540
|
-
return name;
|
|
2541
|
-
}
|
|
2542
|
-
/** One export's island value for the namespace object — the jsvalIn
|
|
2543
|
-
* marshal set (primitives and JSON-safe composites by deep copy, units as
|
|
2544
|
-
* the engine's own, marshalable closures as host functions, jsval-bearing
|
|
2545
|
-
* composites through the per-field lift), with every UN-marshalable
|
|
2546
|
-
* export crossing as a trap function that throws a pointed TypeError when
|
|
2547
|
-
* called or constructed — the namespace still builds (Node resolves it;
|
|
2548
|
-
* only the USE has no compiled story). Null for exports that do not exist
|
|
2549
|
-
* at runtime (type-only). */
|
|
2550
|
-
function exportJsvalValue(lowerer, name, sym, loc) {
|
|
2551
|
-
const trap = (what) => islandTrapFnValue(lowerer, `the '${name}' export is ${what} of the compiled program, which cannot cross into dynamically-executed code yet`, loc);
|
|
2552
|
-
let resolved = sym;
|
|
2553
|
-
if (sym.flags & ts.SymbolFlags.Alias) {
|
|
2554
|
-
// `export type { x }` / `export { type x }`: erased at runtime.
|
|
2555
|
-
for (const d of lowerer.checker.declarationsOf(sym)) {
|
|
2556
|
-
if (ts.isExportSpecifier(d)) {
|
|
2557
|
-
const exportDecl = d.parent?.parent;
|
|
2558
|
-
if (d.isTypeOnly || (ts.isExportDeclaration(exportDecl) && exportDecl.isTypeOnly))
|
|
2559
|
-
return null;
|
|
2560
|
-
}
|
|
2561
|
-
if (ts.isImportSpecifier(d)) {
|
|
2562
|
-
const clause = d.parent?.parent;
|
|
2563
|
-
if (d.isTypeOnly ||
|
|
2564
|
-
(ts.isImportClause(clause) && clause.phaseModifier === ts.SyntaxKind.TypeKeyword))
|
|
2565
|
-
return null;
|
|
2566
|
-
}
|
|
2567
|
-
}
|
|
2568
|
-
resolved = lowerer.checker.getAliasedSymbol(sym);
|
|
2569
|
-
}
|
|
2570
|
-
if (!(resolved.flags & ts.SymbolFlags.Value))
|
|
2571
|
-
return null; // pure type surface
|
|
2572
|
-
const g = lowerer.globalsBySymbol.get(resolved);
|
|
2573
|
-
if (g) {
|
|
2574
|
-
const ref = { kind: "varRef", localId: g.id, type: g.type, loc };
|
|
2575
|
-
if (ref.type.kind === "jsval")
|
|
2576
|
-
return ref;
|
|
2577
|
-
if (isUnitType(ref.type)) {
|
|
2578
|
-
return {
|
|
2579
|
-
kind: "jsOp",
|
|
2580
|
-
op: ref.type.kind === "undefinedT" ? "undefLit" : "nullLit",
|
|
2581
|
-
args: [],
|
|
2582
|
-
type: JSVAL,
|
|
2583
|
-
loc,
|
|
2584
|
-
};
|
|
2585
|
-
}
|
|
2586
|
-
if (ref.type.kind === "func") {
|
|
2587
|
-
return canMarshalTypedFuncIntoIsland(ref.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))
|
|
2588
|
-
? { kind: "jsMarshal", value: ref, type: JSVAL, loc }
|
|
2589
|
-
: trap(`a function value of type '${lowerer.fmt(ref.type)}'`);
|
|
2590
|
-
}
|
|
2591
|
-
if (lowerer.boundarySafe(ref.type))
|
|
2592
|
-
return { kind: "jsMarshal", value: ref, type: JSVAL, loc };
|
|
2593
|
-
if (lowerer.jsvalLiftable(ref.type))
|
|
2594
|
-
return lowerer.jsvalLiftExpr(ref, loc);
|
|
2595
|
-
return trap(`a value of type '${lowerer.fmt(ref.type)}'`);
|
|
2596
|
-
}
|
|
2597
|
-
const sig = lowerer.fnSigsBySymbol.get(resolved);
|
|
2598
|
-
const decl0 = lowerer.checker
|
|
2599
|
-
.declarationsOf(resolved)
|
|
2600
|
-
.find((d) => ts.isFunctionDeclaration(d) &&
|
|
2601
|
-
(ts.isSourceFile(d.parent) ||
|
|
2602
|
-
(d.parent !== undefined && lowerer.nsBlocks.get(d.parent) === "flattened")));
|
|
2603
|
-
if (sig && decl0) {
|
|
2604
|
-
if (!sig.params.every((p) => p.mode === "required")) {
|
|
2605
|
-
return trap("a function with optional, default, or rest parameters");
|
|
2606
|
-
}
|
|
2607
|
-
const funcType = {
|
|
2608
|
-
kind: "func",
|
|
2609
|
-
params: sig.params.map((p) => p.type),
|
|
2610
|
-
ret: sig.returnType,
|
|
2611
|
-
};
|
|
2612
|
-
if (!canMarshalTypedFuncIntoIsland(funcType, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
2613
|
-
return trap(`a function of type '${lowerer.fmt(funcType)}'`);
|
|
2614
|
-
}
|
|
2615
|
-
lowerer.noteEdge(sig.name);
|
|
2616
|
-
return {
|
|
2617
|
-
kind: "jsMarshal",
|
|
2618
|
-
value: { kind: "closure", fnName: sig.name, captures: [], type: funcType, loc },
|
|
2619
|
-
type: JSVAL,
|
|
2620
|
-
loc,
|
|
2621
|
-
};
|
|
2622
|
-
}
|
|
2623
|
-
if (lowerer.genericFnsBySymbol.has(resolved))
|
|
2624
|
-
return trap("a generic function");
|
|
2625
|
-
const flags = resolved.flags;
|
|
2626
|
-
if (flags & ts.SymbolFlags.Class)
|
|
2627
|
-
return trap("a class");
|
|
2628
|
-
if (flags & ts.SymbolFlags.Enum)
|
|
2629
|
-
return trap("an enum object");
|
|
2630
|
-
if (flags & ts.SymbolFlags.ValueModule || flags & ts.SymbolFlags.NamespaceModule) {
|
|
2631
|
-
return trap("a namespace object");
|
|
2632
|
-
}
|
|
2633
|
-
return trap("a binding");
|
|
2634
|
-
}
|
|
2635
|
-
/** An engine value whose any USE throws: `new Function("<throw>")` — a
|
|
2636
|
-
* real engine function, so the namespace member reads back fine (Node's
|
|
2637
|
-
* namespace holds the value too), property probes answer like a
|
|
2638
|
-
* function's, and calling or `new`-ing it runs the body, which throws
|
|
2639
|
-
* the pointed TypeError. */
|
|
2640
|
-
function islandTrapFnValue(lowerer, message, loc) {
|
|
2641
|
-
void lowerer;
|
|
2642
|
-
const code = `throw new TypeError(${JSON.stringify(message)})`;
|
|
2643
|
-
return {
|
|
2644
|
-
kind: "jsOp",
|
|
2645
|
-
op: "construct",
|
|
2646
|
-
args: [
|
|
2647
|
-
{ kind: "jsOp", op: "globalGet", name: "Function", args: [], type: JSVAL, loc },
|
|
2648
|
-
{
|
|
2649
|
-
kind: "jsMarshal",
|
|
2650
|
-
value: { kind: "strLit", value: code, type: STRING, loc },
|
|
2651
|
-
type: JSVAL,
|
|
2652
|
-
loc,
|
|
2653
|
-
},
|
|
2654
|
-
],
|
|
2655
|
-
type: JSVAL,
|
|
2656
|
-
loc,
|
|
2657
|
-
};
|
|
2658
|
-
}
|
|
2659
|
-
/** An object literal built NATIVELY in the island — one engine object,
|
|
2660
|
-
* each field marshaled individually (nested object/array literals
|
|
2661
|
-
* recurse, island handles pass straight through, everything else takes
|
|
2662
|
-
* the JSON-safe copy-marshal). The same jsOp the 'any'-contextual
|
|
2663
|
-
* literal path emits, callable from lowerings that KNOW the literal is
|
|
2664
|
-
* island-bound (fetch's init) even when the contextual type is a union
|
|
2665
|
-
* the generic path declines. Spelled and pure const-folded computed keys
|
|
2666
|
-
* are admitted; engine property names have no identifier restriction. Plain
|
|
2667
|
-
* spreads copy through the engine's CopyDataProperties operation in
|
|
2668
|
-
* source order, including nested RequestInit/header dictionaries. */
|
|
2669
|
-
function lowerIslandObjectLiteral(lowerer, expr) {
|
|
2670
|
-
const loc = locOf(expr);
|
|
2671
|
-
let args = [];
|
|
2672
|
-
let acc = null;
|
|
2673
|
-
const flushFields = () => {
|
|
2674
|
-
if (args.length === 0)
|
|
2675
|
-
return;
|
|
2676
|
-
const chunk = { kind: "jsOp", op: "objLit", args, type: JSVAL, loc };
|
|
2677
|
-
acc =
|
|
2678
|
-
acc === null
|
|
2679
|
-
? chunk
|
|
2680
|
-
: { kind: "jsOp", op: "objSpread", args: [acc, chunk], type: JSVAL, loc };
|
|
2681
|
-
args = [];
|
|
2682
|
-
};
|
|
2683
|
-
for (const prop of expr.properties) {
|
|
2684
|
-
if (ts.isSpreadAssignment(prop)) {
|
|
2685
|
-
flushFields();
|
|
2686
|
-
const spread = ts.isObjectLiteralExpression(prop.expression)
|
|
2687
|
-
? lowerIslandObjectLiteral(lowerer, prop.expression)
|
|
2688
|
-
: lowerer.jsvalIn(lowerer.lowerExpr(prop.expression), prop.expression);
|
|
2689
|
-
acc ??= { kind: "jsOp", op: "objLit", args: [], type: JSVAL, loc };
|
|
2690
|
-
acc = { kind: "jsOp", op: "objSpread", args: [acc, spread], type: JSVAL, loc: locOf(prop) };
|
|
2691
|
-
continue;
|
|
2692
|
-
}
|
|
2693
|
-
if (!ts.isPropertyAssignment(prop) &&
|
|
2694
|
-
!ts.isShorthandPropertyAssignment(prop) &&
|
|
2695
|
-
!ts.isMethodDeclaration(prop)) {
|
|
2696
|
-
lowerer.unsupported("SC1090", prop, "this property form in an island-built object literal (use a spelled or pure const-folded key with a value or method)");
|
|
2697
|
-
}
|
|
2698
|
-
const propertyName = requestInitLiteralKey(lowerer, prop);
|
|
2699
|
-
if (propertyName === null) {
|
|
2700
|
-
lowerer.unsupported("SC1090", prop, "this property key in an island-built object literal (use a spelled or pure const-folded key)");
|
|
2701
|
-
}
|
|
2702
|
-
const nameLoc = locOf(prop.name);
|
|
2703
|
-
args.push({
|
|
2704
|
-
kind: "jsMarshal",
|
|
2705
|
-
value: { kind: "strLit", value: propertyName, type: STRING, loc: nameLoc },
|
|
2706
|
-
type: JSVAL,
|
|
2707
|
-
loc: nameLoc,
|
|
2708
|
-
});
|
|
2709
|
-
const valueNode = ts.isPropertyAssignment(prop)
|
|
2710
|
-
? prop.initializer
|
|
2711
|
-
: ts.isShorthandPropertyAssignment(prop)
|
|
2712
|
-
? prop.name
|
|
2713
|
-
: prop;
|
|
2714
|
-
if (ts.isObjectLiteralExpression(valueNode)) {
|
|
2715
|
-
args.push(lowerIslandObjectLiteral(lowerer, valueNode));
|
|
2716
|
-
}
|
|
2717
|
-
else if (ts.isArrayLiteralExpression(valueNode) &&
|
|
2718
|
-
!valueNode.elements.some(ts.isSpreadElement)) {
|
|
2719
|
-
const elems = valueNode.elements.map((el) => lowerer.jsvalIn(lowerer.lowerExpr(el), el));
|
|
2720
|
-
args.push({ kind: "jsOp", op: "arrLit", args: elems, type: JSVAL, loc: locOf(valueNode) });
|
|
2721
|
-
}
|
|
2722
|
-
else {
|
|
2723
|
-
const value = ts.isMethodDeclaration(valueNode)
|
|
2724
|
-
? (lowerer.rejectThisInObjectMethod(valueNode.body ?? valueNode),
|
|
2725
|
-
lowerer.lowerLambda(valueNode))
|
|
2726
|
-
: lowerer.lowerExpr(valueNode);
|
|
2727
|
-
args.push(lowerer.jsvalIn(value, valueNode));
|
|
2728
|
-
}
|
|
2729
|
-
}
|
|
2730
|
-
flushFields();
|
|
2731
|
-
return acc ?? { kind: "jsOp", op: "objLit", args: [], type: JSVAL, loc };
|
|
2732
|
-
}
|
|
2733
|
-
/** Method calls on the island-backed ambient surface: `Math.<fn>(...)`
|
|
2734
|
-
* (the engine's own Math object executes) and the number/string methods
|
|
2735
|
-
* the static runtime doesn't implement (`x.toPrecision(2)`,
|
|
2736
|
-
* `s.replace("a", "b")`, ...). Each site is self-contained — the receiver
|
|
2737
|
-
* and arguments marshal in, the engine executes with JS-exact semantics,
|
|
2738
|
-
* and the result exits (validated) to the DECLARED static return type,
|
|
2739
|
-
* so no jsval leaks into the program's types. tsc has already checked
|
|
2740
|
-
* receiver, arity, and argument types against ambient/scriptc.d.ts; an
|
|
2741
|
-
* ambient member missing from ISLAND_SURFACE returns null into the
|
|
2742
|
-
* existing generic rejections. */
|
|
2743
|
-
export function lowerIslandMethodCall(lowerer, call, access) {
|
|
1768
|
+
export function lowerStdlibMethodCall(lowerer, call, access) {
|
|
2744
1769
|
if (lowerer.chainBlocked(access, call))
|
|
2745
1770
|
return null;
|
|
2746
1771
|
const name = access.name.text;
|
|
2747
1772
|
const loc = locOf(call);
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
const result = {
|
|
2751
|
-
kind: "jsOp",
|
|
2752
|
-
op: "callMethod",
|
|
2753
|
-
name,
|
|
2754
|
-
args: [receiver, ...args],
|
|
2755
|
-
type: JSVAL,
|
|
2756
|
-
loc,
|
|
2757
|
-
};
|
|
2758
|
-
return { kind: "jsExit", value: result, type: entry.ret, loc };
|
|
2759
|
-
};
|
|
2760
|
-
// `AbortSignal.timeout(ms)` / `.abort(reason?)` / `.any(signals)` —
|
|
2761
|
-
// the fetch-cancellation ambient: the engine's own AbortSignal mints
|
|
2762
|
-
// the signal, which stays a HANDLE (its checker type, AbortSignal,
|
|
2763
|
-
// maps to jsval — see ISLAND_AMBIENT_TYPES) so it can ride a
|
|
2764
|
-
// RequestInit literal into fetch without a JSON detour. The prelude
|
|
2765
|
-
// implements all three statics.
|
|
1773
|
+
// Supported native AbortSignal statics are handled before this generic
|
|
1774
|
+
// method path. Refuse forms that reach this point without a lowering.
|
|
2766
1775
|
{
|
|
2767
1776
|
const sigMember = lowerer.stdlibGlobalMember(access, "AbortSignal");
|
|
2768
1777
|
if ((sigMember === "timeout" || sigMember === "abort" || sigMember === "any") &&
|
|
2769
1778
|
call.arguments.every((argument) => !ts.isSpreadElement(argument))) {
|
|
2770
|
-
lowerer.
|
|
2771
|
-
const args = call.arguments.map((a) => lowerer.jsvalIn(lowerer.lowerExpr(a), a));
|
|
2772
|
-
const signalGlobal = {
|
|
2773
|
-
kind: "jsOp",
|
|
2774
|
-
op: "globalGet",
|
|
2775
|
-
name: "AbortSignal",
|
|
2776
|
-
args: [],
|
|
2777
|
-
type: JSVAL,
|
|
2778
|
-
loc,
|
|
2779
|
-
};
|
|
2780
|
-
return {
|
|
2781
|
-
kind: "jsOp",
|
|
2782
|
-
op: "callMethod",
|
|
2783
|
-
name: sigMember,
|
|
2784
|
-
args: [signalGlobal, ...args],
|
|
2785
|
-
type: JSVAL,
|
|
2786
|
-
loc,
|
|
2787
|
-
};
|
|
1779
|
+
lowerer.refuseUnsupportedApi(`'AbortSignal.${sigMember}'`, call);
|
|
2788
1780
|
}
|
|
2789
1781
|
}
|
|
2790
1782
|
if (lowerer.stdlibGlobalMember(access, "ReadableStream") === "from" &&
|
|
2791
1783
|
call.arguments.every((argument) => !ts.isSpreadElement(argument))) {
|
|
2792
|
-
lowerer.
|
|
2793
|
-
const streamGlobal = {
|
|
2794
|
-
kind: "jsOp",
|
|
2795
|
-
op: "globalGet",
|
|
2796
|
-
name: "ReadableStream",
|
|
2797
|
-
args: [],
|
|
2798
|
-
type: JSVAL,
|
|
2799
|
-
loc,
|
|
2800
|
-
};
|
|
2801
|
-
return {
|
|
2802
|
-
kind: "jsOp",
|
|
2803
|
-
op: "callMethod",
|
|
2804
|
-
name: "from",
|
|
2805
|
-
args: [
|
|
2806
|
-
streamGlobal,
|
|
2807
|
-
...call.arguments.map((argument) => lowerer.jsvalIn(lowerer.lowerExpr(argument), argument)),
|
|
2808
|
-
],
|
|
2809
|
-
type: JSVAL,
|
|
2810
|
-
loc,
|
|
2811
|
-
};
|
|
1784
|
+
lowerer.refuseUnsupportedApi("'ReadableStream.from'", call);
|
|
2812
1785
|
}
|
|
2813
1786
|
const isMath = lowerer.stdlibGlobalMember(access, "Math") !== null;
|
|
2814
|
-
// Static numeric Math calls precede the island path. The scalar methods
|
|
2815
1787
|
// use their declared arity; min/max and hypot accept their variadic forms.
|
|
2816
1788
|
const staticMath = isMath ? own(STATIC_MATH_FNS, name) : undefined;
|
|
2817
1789
|
// A missing element (a hole bound by a loop, a local or field holding a
|
|
@@ -2857,9 +1829,7 @@ export function lowerIslandMethodCall(lowerer, call, access) {
|
|
|
2857
1829
|
}
|
|
2858
1830
|
}
|
|
2859
1831
|
// `Math.max(...xs)` / `Math.min(...xs)` over a number[]: a STATIC
|
|
2860
|
-
// runtime fold (
|
|
2861
|
-
// empty array yields ∓Infinity like the zero-arg calls) — no island
|
|
2862
|
-
// involved, so it works without --dynamic too. Only the exact
|
|
1832
|
+
// runtime fold (NaN poisons and ±0 follows JS ordering). This
|
|
2863
1833
|
// one-spread form lowers; mixed spread/positional argument lists keep
|
|
2864
1834
|
// the nest-calls fence.
|
|
2865
1835
|
if (isMath &&
|
|
@@ -2887,26 +1857,22 @@ export function lowerIslandMethodCall(lowerer, call, access) {
|
|
|
2887
1857
|
loc,
|
|
2888
1858
|
};
|
|
2889
1859
|
}
|
|
2890
|
-
const mathFn = isMath ? own(
|
|
1860
|
+
const mathFn = isMath ? own(STDLIB_SURFACE.math.fns, name) : undefined;
|
|
2891
1861
|
if (mathFn && call.arguments.length === mathFn.args.length) {
|
|
2892
|
-
lowerer.
|
|
2893
|
-
return finish({ kind: "jsOp", op: "globalGet", name: "Math", args: [], type: JSVAL, loc }, mathFn);
|
|
1862
|
+
lowerer.refuseUnsupportedApi(`'Math.${name}'`, call);
|
|
2894
1863
|
}
|
|
2895
1864
|
const kind = lowerer.mapTypeOf(lowerer.typeOf(access.expression))?.kind;
|
|
2896
1865
|
const entry = kind === "f64"
|
|
2897
|
-
? own(
|
|
1866
|
+
? own(STDLIB_SURFACE.number, name)
|
|
2898
1867
|
: kind === "string"
|
|
2899
|
-
? own(
|
|
1868
|
+
? own(STDLIB_SURFACE.string, name)
|
|
2900
1869
|
: undefined;
|
|
2901
1870
|
if (!entry || call.arguments.length !== entry.args.length)
|
|
2902
1871
|
return null;
|
|
2903
1872
|
if (!lowerer.isStdlibMember(access))
|
|
2904
1873
|
return null;
|
|
2905
|
-
lowerer.
|
|
2906
|
-
return finish(lowerer.jsvalIn(lowerer.lowerExpr(access.expression), access.expression), entry);
|
|
1874
|
+
lowerer.refuseUnsupportedApi(`'.${name}()' on ${kind === "f64" ? "numbers" : "strings"}`, call);
|
|
2907
1875
|
}
|
|
2908
|
-
/** Math constants and fixed-arity numeric functions have native value forms.
|
|
2909
|
-
* Remaining properties retain the island/fence path. */
|
|
2910
1876
|
export function lowerMathProperty(lowerer, expr) {
|
|
2911
1877
|
const member = lowerer.stdlibGlobalMember(expr, "Math");
|
|
2912
1878
|
if (member === null)
|
|
@@ -2933,37 +1899,16 @@ export function lowerMathProperty(lowerer, expr) {
|
|
|
2933
1899
|
valueParams: params.map((type) => ({ mode: "required", type })),
|
|
2934
1900
|
}, `Math.${member}`, loc);
|
|
2935
1901
|
}
|
|
2936
|
-
const propType = own(
|
|
1902
|
+
const propType = own(STDLIB_SURFACE.math.props, member);
|
|
2937
1903
|
if (propType !== undefined) {
|
|
2938
|
-
lowerer.
|
|
2939
|
-
const math = {
|
|
2940
|
-
kind: "jsOp",
|
|
2941
|
-
op: "globalGet",
|
|
2942
|
-
name: "Math",
|
|
2943
|
-
args: [],
|
|
2944
|
-
type: JSVAL,
|
|
2945
|
-
loc,
|
|
2946
|
-
};
|
|
2947
|
-
const read = {
|
|
2948
|
-
kind: "jsOp",
|
|
2949
|
-
op: "getProp",
|
|
2950
|
-
name: member,
|
|
2951
|
-
args: [math],
|
|
2952
|
-
type: JSVAL,
|
|
2953
|
-
loc,
|
|
2954
|
-
};
|
|
2955
|
-
return { kind: "jsExit", value: read, type: propType, loc };
|
|
1904
|
+
lowerer.refuseUnsupportedApi(`'Math.${member}'`, expr);
|
|
2956
1905
|
}
|
|
2957
|
-
if (own(
|
|
1906
|
+
if (own(STDLIB_SURFACE.math.fns, member) !== undefined ||
|
|
2958
1907
|
own(STATIC_MATH_FNS, member) !== undefined) {
|
|
2959
1908
|
lowerer.unsupported("SC1090", expr, `Math methods as values (call '${member}' directly)`);
|
|
2960
1909
|
}
|
|
2961
1910
|
return null; // declared-but-untabled members fall through generically
|
|
2962
1911
|
}
|
|
2963
|
-
/** The npm package a type is declared by ("commander", "@scope/pkg"),
|
|
2964
|
-
* or null when the type isn't package-declared. Union parts are searched
|
|
2965
|
-
* too: `string | Command` fails mapping as a whole, but the blame (and
|
|
2966
|
-
* the --dynamic attribution) belongs to the package-declared part. */
|
|
2967
1912
|
export function npmPackageOf(lowerer, type) {
|
|
2968
1913
|
const pkg = lowerer.npmPackageOfSymbol(type.getAliasSymbol() ?? type.getSymbol());
|
|
2969
1914
|
if (pkg)
|
|
@@ -2977,20 +1922,12 @@ export function npmPackageOf(lowerer, type) {
|
|
|
2977
1922
|
}
|
|
2978
1923
|
return null;
|
|
2979
1924
|
}
|
|
2980
|
-
/** The npm chokepoint for member reads and method calls in a STATIC
|
|
2981
|
-
* build: a receiver whose type (or member whose symbol) a package's
|
|
2982
|
-
* .d.ts declares means the operation runs in the embedded engine —
|
|
2983
|
-
* attribute the site to the package instead of the generic property/
|
|
2984
|
-
* method rejection. No-op under --dynamic (the island paths claimed
|
|
2985
|
-
* these) and for non-package receivers, so callers' fallbacks apply. */
|
|
2986
1925
|
export function npmMemberFence(lowerer, access) {
|
|
2987
|
-
if (lowerer.dynamic)
|
|
2988
|
-
return;
|
|
2989
1926
|
const pkg = lowerer.npmPackageOf(lowerer.typeOf(access.expression)) ??
|
|
2990
1927
|
lowerer.npmPackageOfSymbol(lowerer.checker.getSymbolAtLocation(access.name));
|
|
2991
1928
|
if (!pkg)
|
|
2992
1929
|
return;
|
|
2993
|
-
lowerer.pushDiag(
|
|
1930
|
+
lowerer.pushDiag(unsupportedPackageValueDiag(pkg, locOf(access)));
|
|
2994
1931
|
throw new PoisonError();
|
|
2995
1932
|
}
|
|
2996
1933
|
/** The npm package a SYMBOL is declared by, or null. The symbol half of
|
|
@@ -3004,4 +1941,4 @@ export function npmPackageOfSymbol(lowerer, sym) {
|
|
|
3004
1941
|
return null;
|
|
3005
1942
|
return npmPackageNameOf(decls[0].getSourceFile().fileName);
|
|
3006
1943
|
}
|
|
3007
|
-
//# sourceMappingURL=lower-
|
|
1944
|
+
//# sourceMappingURL=lower-stdlib.js.map
|