@loopdive/js2 0.57.0
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/CHANGELOG.md +1425 -0
- package/LICENSE +189 -0
- package/README.md +451 -0
- package/dist/checker/index.d.ts +117 -0
- package/dist/checker/language-service.d.ts +39 -0
- package/dist/checker/node-capability-map.d.ts +63 -0
- package/dist/checker/type-mapper.d.ts +84 -0
- package/dist/cjs-rewrite.d.ts +19 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +363 -0
- package/dist/codegen/accessor-driver.d.ts +97 -0
- package/dist/codegen/any-helpers.d.ts +72 -0
- package/dist/codegen/array-element-typing.d.ts +46 -0
- package/dist/codegen/array-holes.d.ts +69 -0
- package/dist/codegen/array-methods.d.ts +68 -0
- package/dist/codegen/array-object-proto.d.ts +64 -0
- package/dist/codegen/array-reduce-fusion.d.ts +31 -0
- package/dist/codegen/array-to-primitive.d.ts +28 -0
- package/dist/codegen/async-cps.d.ts +239 -0
- package/dist/codegen/async-scheduler.d.ts +349 -0
- package/dist/codegen/binary-ops.d.ts +78 -0
- package/dist/codegen/binding-info.d.ts +31 -0
- package/dist/codegen/builtin-scaffold.d.ts +98 -0
- package/dist/codegen/builtin-static-globals.d.ts +8 -0
- package/dist/codegen/builtin-tags.d.ts +189 -0
- package/dist/codegen/case-convert-native.d.ts +12 -0
- package/dist/codegen/case-tables.d.ts +4 -0
- package/dist/codegen/class-bodies.d.ts +41 -0
- package/dist/codegen/class-member-keys.d.ts +33 -0
- package/dist/codegen/class-to-primitive.d.ts +39 -0
- package/dist/codegen/closed-method-dispatch.d.ts +42 -0
- package/dist/codegen/closures.d.ts +285 -0
- package/dist/codegen/coercion-engine.d.ts +154 -0
- package/dist/codegen/coercion-plan.d.ts +29 -0
- package/dist/codegen/context/bodies.d.ts +4 -0
- package/dist/codegen/context/create-context.d.ts +4 -0
- package/dist/codegen/context/errors.d.ts +39 -0
- package/dist/codegen/context/locals.d.ts +69 -0
- package/dist/codegen/context/source-pos.d.ts +5 -0
- package/dist/codegen/context/speculative.d.ts +95 -0
- package/dist/codegen/context/types.d.ts +1936 -0
- package/dist/codegen/custom-iterable.d.ts +34 -0
- package/dist/codegen/dataview-native.d.ts +51 -0
- package/dist/codegen/date-parse-native.d.ts +13 -0
- package/dist/codegen/dead-elimination.d.ts +26 -0
- package/dist/codegen/declarations.d.ts +147 -0
- package/dist/codegen/deno-api.d.ts +11 -0
- package/dist/codegen/destructuring-params.d.ts +102 -0
- package/dist/codegen/dyn-read.d.ts +26 -0
- package/dist/codegen/eval-tiering.d.ts +19 -0
- package/dist/codegen/expressions/assignment.d.ts +61 -0
- package/dist/codegen/expressions/builtins.d.ts +26 -0
- package/dist/codegen/expressions/calls-closures.d.ts +54 -0
- package/dist/codegen/expressions/calls-guards.d.ts +49 -0
- package/dist/codegen/expressions/calls-optional.d.ts +4 -0
- package/dist/codegen/expressions/calls.d.ts +83 -0
- package/dist/codegen/expressions/eval-inline.d.ts +24 -0
- package/dist/codegen/expressions/extern.d.ts +67 -0
- package/dist/codegen/expressions/fnctor-prototype.d.ts +52 -0
- package/dist/codegen/expressions/helpers.d.ts +212 -0
- package/dist/codegen/expressions/identifiers.d.ts +57 -0
- package/dist/codegen/expressions/late-imports.d.ts +81 -0
- package/dist/codegen/expressions/logical-ops.d.ts +18 -0
- package/dist/codegen/expressions/misc.d.ts +27 -0
- package/dist/codegen/expressions/new-super.d.ts +25 -0
- package/dist/codegen/expressions/promise-subclass.d.ts +38 -0
- package/dist/codegen/expressions/proto-override.d.ts +63 -0
- package/dist/codegen/expressions/unary-updates.d.ts +21 -0
- package/dist/codegen/expressions/unary.d.ts +6 -0
- package/dist/codegen/expressions.d.ts +31 -0
- package/dist/codegen/fallback-telemetry.d.ts +53 -0
- package/dist/codegen/fixups.d.ts +80 -0
- package/dist/codegen/fmod.d.ts +10 -0
- package/dist/codegen/fnctor-escape-gate.d.ts +92 -0
- package/dist/codegen/function-body.d.ts +52 -0
- package/dist/codegen/generators-native.d.ts +92 -0
- package/dist/codegen/helpers/body-references-own-this.d.ts +22 -0
- package/dist/codegen/helpers/body-uses-arguments.d.ts +12 -0
- package/dist/codegen/helpers/is-strict-function.d.ts +52 -0
- package/dist/codegen/host-import-allowlist.d.ts +140 -0
- package/dist/codegen/index.d.ts +500 -0
- package/dist/codegen/ir-tail-call.d.ts +8 -0
- package/dist/codegen/iterator-native.d.ts +44 -0
- package/dist/codegen/json-codec-native.d.ts +78 -0
- package/dist/codegen/json-runtime.d.ts +35 -0
- package/dist/codegen/json-standalone.d.ts +25 -0
- package/dist/codegen/linear-uint8-analysis.d.ts +46 -0
- package/dist/codegen/linear-uint8-arena.d.ts +7 -0
- package/dist/codegen/linear-uint8-codegen.d.ts +103 -0
- package/dist/codegen/linear-uint8-signatures.d.ts +26 -0
- package/dist/codegen/literals.d.ts +115 -0
- package/dist/codegen/map-runtime.d.ts +142 -0
- package/dist/codegen/math-helpers.d.ts +7 -0
- package/dist/codegen/member-get-dispatch.d.ts +42 -0
- package/dist/codegen/member-set-dispatch.d.ts +28 -0
- package/dist/codegen/native-proto.d.ts +98 -0
- package/dist/codegen/native-regex.d.ts +158 -0
- package/dist/codegen/native-strings.d.ts +146 -0
- package/dist/codegen/new-target.d.ts +30 -0
- package/dist/codegen/node-fs-api.d.ts +47 -0
- package/dist/codegen/number-format-native.d.ts +9 -0
- package/dist/codegen/number-ryu.d.ts +27 -0
- package/dist/codegen/object-ops.d.ts +94 -0
- package/dist/codegen/object-runtime.d.ts +171 -0
- package/dist/codegen/parse-number-native.d.ts +10 -0
- package/dist/codegen/peephole.d.ts +6 -0
- package/dist/codegen/property-access.d.ts +294 -0
- package/dist/codegen/raw-wasi-api.d.ts +13 -0
- package/dist/codegen/regex/bytecode.d.ts +140 -0
- package/dist/codegen/regex/casefold.d.ts +41 -0
- package/dist/codegen/regex/compile.d.ts +51 -0
- package/dist/codegen/regex/parse.d.ts +76 -0
- package/dist/codegen/regex/unicode.d.ts +42 -0
- package/dist/codegen/regex/vm.d.ts +24 -0
- package/dist/codegen/regexp-standalone.d.ts +350 -0
- package/dist/codegen/registry/error-types.d.ts +38 -0
- package/dist/codegen/registry/imports.d.ts +46 -0
- package/dist/codegen/registry/types.d.ts +59 -0
- package/dist/codegen/set-algebra.d.ts +17 -0
- package/dist/codegen/set-runtime.d.ts +74 -0
- package/dist/codegen/shared.d.ts +111 -0
- package/dist/codegen/stack-balance.d.ts +43 -0
- package/dist/codegen/statements/control-flow.d.ts +25 -0
- package/dist/codegen/statements/destructuring.d.ts +177 -0
- package/dist/codegen/statements/exceptions.d.ts +11 -0
- package/dist/codegen/statements/functions.d.ts +1 -0
- package/dist/codegen/statements/index.d.ts +1 -0
- package/dist/codegen/statements/loops.d.ts +7 -0
- package/dist/codegen/statements/nested-declarations.d.ts +78 -0
- package/dist/codegen/statements/shared.d.ts +38 -0
- package/dist/codegen/statements/tdz.d.ts +43 -0
- package/dist/codegen/statements/variables.d.ts +3 -0
- package/dist/codegen/statements.d.ts +9 -0
- package/dist/codegen/string-builder.d.ts +131 -0
- package/dist/codegen/string-ops.d.ts +87 -0
- package/dist/codegen/struct-accessor-closure.d.ts +36 -0
- package/dist/codegen/symbol-native.d.ts +55 -0
- package/dist/codegen/temporal-native.d.ts +8 -0
- package/dist/codegen/timsort.d.ts +2 -0
- package/dist/codegen/type-coercion.d.ts +123 -0
- package/dist/codegen/typeof-delete.d.ts +38 -0
- package/dist/codegen/uri-encoding-native.d.ts +33 -0
- package/dist/codegen/value-tags.d.ts +74 -0
- package/dist/codegen/walk-instructions.d.ts +20 -0
- package/dist/codegen/weak-collections-runtime.d.ts +16 -0
- package/dist/codegen/with-scope.d.ts +106 -0
- package/dist/codegen-linear/c-abi.d.ts +74 -0
- package/dist/codegen-linear/context.d.ts +86 -0
- package/dist/codegen-linear/index.d.ts +28 -0
- package/dist/codegen-linear/layout.d.ts +39 -0
- package/dist/codegen-linear/runtime.d.ts +161 -0
- package/dist/codegen-linear/simd.d.ts +7 -0
- package/dist/compiler/define-substitution.d.ts +27 -0
- package/dist/compiler/early-errors/assignment.d.ts +26 -0
- package/dist/compiler/early-errors/context.d.ts +17 -0
- package/dist/compiler/early-errors/duplicates.d.ts +20 -0
- package/dist/compiler/early-errors/index.d.ts +11 -0
- package/dist/compiler/early-errors/labels.d.ts +13 -0
- package/dist/compiler/early-errors/module-rules.d.ts +36 -0
- package/dist/compiler/early-errors/node-checks.d.ts +7 -0
- package/dist/compiler/early-errors/predicates.d.ts +140 -0
- package/dist/compiler/early-errors/tdz.d.ts +17 -0
- package/dist/compiler/import-manifest.d.ts +18 -0
- package/dist/compiler/output.d.ts +46 -0
- package/dist/compiler/validation.d.ts +45 -0
- package/dist/compiler.d.ts +48 -0
- package/dist/define-substitution-BcUeKC2A.js +109 -0
- package/dist/emit/binary.d.ts +50 -0
- package/dist/emit/c-header.d.ts +23 -0
- package/dist/emit/canonical-recgroup.d.ts +86 -0
- package/dist/emit/encoder.d.ts +28 -0
- package/dist/emit/object.d.ts +14 -0
- package/dist/emit/opcodes.d.ts +464 -0
- package/dist/emit/sourcemap.d.ts +33 -0
- package/dist/emit/wat.d.ts +6 -0
- package/dist/env.d.ts +46 -0
- package/dist/import-resolver.d.ts +68 -0
- package/dist/index.d.ts +486 -0
- package/dist/index.js +755 -0
- package/dist/ir/alloc-registry.d.ts +75 -0
- package/dist/ir/analysis/encoding.d.ts +38 -0
- package/dist/ir/analysis/escape.d.ts +32 -0
- package/dist/ir/analysis/lattice.d.ts +72 -0
- package/dist/ir/analysis/ownership.d.ts +31 -0
- package/dist/ir/analysis/stack-alloc.d.ts +20 -0
- package/dist/ir/backend/bytecode-emitter.d.ts +237 -0
- package/dist/ir/backend/bytecode-vm.d.ts +74 -0
- package/dist/ir/backend/emitter.d.ts +121 -0
- package/dist/ir/backend/handles.d.ts +133 -0
- package/dist/ir/backend/legality.d.ts +9 -0
- package/dist/ir/backend/linear-emitter.d.ts +41 -0
- package/dist/ir/backend/wasmgc-emitter.d.ts +43 -0
- package/dist/ir/builder.d.ts +401 -0
- package/dist/ir/from-ast.d.ts +192 -0
- package/dist/ir/index.d.ts +16 -0
- package/dist/ir/integration.d.ts +27 -0
- package/dist/ir/lower.d.ts +203 -0
- package/dist/ir/nodes.d.ts +1452 -0
- package/dist/ir/passes/alloc-discipline.d.ts +19 -0
- package/dist/ir/passes/constant-fold.d.ts +7 -0
- package/dist/ir/passes/dead-code.d.ts +18 -0
- package/dist/ir/passes/inline-small.d.ts +7 -0
- package/dist/ir/passes/monomorphize.d.ts +21 -0
- package/dist/ir/passes/simplify-cfg.d.ts +19 -0
- package/dist/ir/passes/tagged-union-types.d.ts +45 -0
- package/dist/ir/passes/tagged-unions.d.ts +22 -0
- package/dist/ir/propagate.d.ts +135 -0
- package/dist/ir/select.d.ts +81 -0
- package/dist/ir/types.d.ts +832 -0
- package/dist/ir/verify-alloc.d.ts +18 -0
- package/dist/ir/verify.d.ts +7 -0
- package/dist/link/index.d.ts +11 -0
- package/dist/link/isolation.d.ts +24 -0
- package/dist/link/linker.d.ts +37 -0
- package/dist/link/reader.d.ts +158 -0
- package/dist/link/resolver.d.ts +19 -0
- package/dist/optimize.d.ts +54 -0
- package/dist/optimize.js +262 -0
- package/dist/position-map.d.ts +64 -0
- package/dist/process-stdin-prelude.d.ts +16 -0
- package/dist/resolve.d.ts +82 -0
- package/dist/runtime/builtins.d.ts +1 -0
- package/dist/runtime-C-4q_KwU.js +164438 -0
- package/dist/runtime-containment.d.ts +6 -0
- package/dist/runtime-eval.d.ts +132 -0
- package/dist/runtime-instantiate.d.ts +16 -0
- package/dist/runtime.d.ts +128 -0
- package/dist/runtime.js +12 -0
- package/dist/shape-inference.d.ts +20 -0
- package/dist/treeshake.d.ts +17 -0
- package/dist/ts-api.d.ts +30 -0
- package/dist/wit-generator.d.ts +18 -0
- package/package.json +187 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { ValType } from '../ir/types.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
4
|
+
import { VOID_RESULT } from './shared.js';
|
|
5
|
+
/**
|
|
6
|
+
* Emit a bounds-checked array.get. Stack must contain [arrayref, i32 index].
|
|
7
|
+
* If the index is out of bounds (< 0 or >= array.len), a default value for the
|
|
8
|
+
* element type is produced instead of trapping.
|
|
9
|
+
*
|
|
10
|
+
* #1396 — `useUndefinedSentinel` (default false): when true AND `elementType`
|
|
11
|
+
* is `externref`/`ref_extern`, the OOB else-branch pushes the JS `undefined`
|
|
12
|
+
* value (via `__get_undefined` host import) instead of `ref.null.extern`.
|
|
13
|
+
* Required by destructuring callers — JS spec §13.7.5.5 fires defaults only
|
|
14
|
+
* for `undefined`, not for `null`, and `ref.null.extern` surfaces to JS as
|
|
15
|
+
* `null` causing `__extern_is_undefined` to return 0 → default never fires
|
|
16
|
+
* for OOB extern-array reads (~320 fails in `for-of/dstr`, ~171 in
|
|
17
|
+
* `assignment/dstr`).
|
|
18
|
+
*/
|
|
19
|
+
export declare function emitBoundsCheckedArrayGet(fctx: FunctionContext, arrTypeIdx: number, elementType: ValType, ctx?: CodegenContext, useUndefinedSentinel?: boolean, signedness?: "s" | "u"): void;
|
|
20
|
+
/**
|
|
21
|
+
* Clamp an index for JS array methods: if idx < 0, idx = max(0, len + idx);
|
|
22
|
+
* also clamp to max len. idxLocal is updated in-place.
|
|
23
|
+
*/
|
|
24
|
+
export declare function emitClampIndex(fctx: FunctionContext, idxLocal: number, lenLocal: number): void;
|
|
25
|
+
/**
|
|
26
|
+
* Clamp a value to be >= 0. local is updated in-place.
|
|
27
|
+
*/
|
|
28
|
+
export declare function emitClampNonNeg(fctx: FunctionContext, local: number): void;
|
|
29
|
+
/** Resolve array type info from a TS type. Returns null if not a Wasm GC vec struct. */
|
|
30
|
+
export declare function resolveArrayInfo(ctx: CodegenContext, tsType: ts.Type): {
|
|
31
|
+
vecTypeIdx: number;
|
|
32
|
+
arrTypeIdx: number;
|
|
33
|
+
elemType: ValType;
|
|
34
|
+
} | null;
|
|
35
|
+
/**
|
|
36
|
+
* Compile Array.prototype.METHOD.call(anyReceiver, callback, ...args) for any-typed receivers.
|
|
37
|
+
* Uses __extern_length + __extern_get_idx to iterate and call_ref for Wasm closure callbacks.
|
|
38
|
+
* Only handles callbacks that compile to Wasm closures (arrow functions, function declarations).
|
|
39
|
+
* Returns undefined if the pattern is not handled (caller should fall through).
|
|
40
|
+
*/
|
|
41
|
+
export declare function compileArrayLikePrototypeCall(ctx: CodegenContext, fctx: FunctionContext, callExpr: ts.CallExpression, methodName: string, receiverArg: ts.Expression): ValType | null | typeof VOID_RESULT | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Detect and compile Array.prototype.METHOD.call(obj, ...args) patterns.
|
|
44
|
+
* When `obj` is a shape-inferred array-like variable, we reuse the existing
|
|
45
|
+
* array method compilers by treating `obj` as the receiver.
|
|
46
|
+
*
|
|
47
|
+
* Returns undefined if the pattern is not matched (caller should continue).
|
|
48
|
+
* Returns ValType | null for successful/failed compilation.
|
|
49
|
+
*/
|
|
50
|
+
export declare function compileArrayPrototypeCall(ctx: CodegenContext, fctx: FunctionContext, callExpr: ts.CallExpression, propAccess: ts.PropertyAccessExpression): ValType | null | typeof VOID_RESULT | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Compile array method calls to inline Wasm instructions.
|
|
53
|
+
* Returns undefined if the call is not an array method (caller should continue).
|
|
54
|
+
* Returns ValType for successful compilation, VOID_RESULT for void methods,
|
|
55
|
+
* or null for failed compilation.
|
|
56
|
+
*/
|
|
57
|
+
export declare function compileArrayMethodCall(ctx: CodegenContext, fctx: FunctionContext, propAccess: ts.PropertyAccessExpression | ts.ElementAccessExpression, callExpr: ts.CallExpression, receiverType: ts.Type, overrideMethodName?: string, expectedType?: ValType): ValType | null | undefined | typeof VOID_RESULT;
|
|
58
|
+
/**
|
|
59
|
+
* (#2193 PR-B) Local-driven core of `Array.prototype.slice`: given the receiver
|
|
60
|
+
* vec already in `vecLocal` and the (already-truncated-to-i32) start in
|
|
61
|
+
* `startLocal`, produce a new sliced vec. `endLocal === null` means "no explicit
|
|
62
|
+
* end" (use the receiver length). This is the AST-free entry the proto-member
|
|
63
|
+
* closure body (`emitArrayProtoMemberBody`) calls after recovering the array
|
|
64
|
+
* instance from the closure `this` externref. `compileArraySlice` is now a thin
|
|
65
|
+
* wrapper that compiles the receiver/args into locals then delegates here — so the
|
|
66
|
+
* direct `a.slice(...)` lowering is behaviour-preserving (pure extraction).
|
|
67
|
+
*/
|
|
68
|
+
export declare function compileArraySliceFromVecLocal(ctx: CodegenContext, fctx: FunctionContext, vecLocal: number, vecTypeIdx: number, arrTypeIdx: number, startLocal: number, endLocal: number | null): ValType;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { CodegenContext } from './context/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Register `Array.prototype` glue (idempotent) and return its brand, or
|
|
4
|
+
* `undefined` if the Array brand isn't reserved (should not happen).
|
|
5
|
+
*/
|
|
6
|
+
export declare function ensureArrayNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
7
|
+
/** Register `Object.prototype` glue (idempotent) and return its brand. */
|
|
8
|
+
export declare function ensureObjectNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Register `String.prototype` glue (idempotent) and return its brand. (#1907 /
|
|
11
|
+
* #1888 S6-b — S4 wrapper protos.) The String brand is pre-reserved in
|
|
12
|
+
* `BUILTIN_BRAND_TABLE`; this only fills in the member CSV so a bare
|
|
13
|
+
* `String.prototype` / `String.prototype.<method>` value read resolves host-free
|
|
14
|
+
* instead of refusing. Reflective member-CLOSURE bodies still degrade to a
|
|
15
|
+
* catchable TypeError (`emitProtoMemberBodyRefusal`) until per-member native
|
|
16
|
+
* bodies land — the value-read object itself needs only the member set.
|
|
17
|
+
*/
|
|
18
|
+
export declare function ensureStringNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
19
|
+
/** Register `Number.prototype` glue (idempotent) and return its brand. */
|
|
20
|
+
export declare function ensureNumberNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
21
|
+
/** Register `Boolean.prototype` glue (idempotent) and return its brand. */
|
|
22
|
+
export declare function ensureBooleanNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Register `Date.prototype` glue (idempotent) and return its brand. (#1907 /
|
|
25
|
+
* #1888 S6-b — S5.) The Date brand is pre-reserved in `BUILTIN_BRAND_TABLE`;
|
|
26
|
+
* this only fills in the member CSV so a bare `Date.prototype` /
|
|
27
|
+
* `Date.prototype.<method>` value read resolves host-free instead of refusing.
|
|
28
|
+
* Reflective member-CLOSURE bodies still degrade to a catchable TypeError until
|
|
29
|
+
* per-member native bodies land — the value-read OBJECT + `.length`/`.name`
|
|
30
|
+
* meta folds need only the member set.
|
|
31
|
+
*/
|
|
32
|
+
export declare function ensureDateNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
33
|
+
/** Register `Error.prototype` glue (idempotent) and return its brand. (S6) */
|
|
34
|
+
export declare function ensureErrorNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
35
|
+
/** Register `Map.prototype` glue (idempotent) and return its brand. (S6) */
|
|
36
|
+
export declare function ensureMapNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
37
|
+
/** Register `Set.prototype` glue (idempotent) and return its brand. (S6) */
|
|
38
|
+
export declare function ensureSetNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
39
|
+
/** Register `Function.prototype` glue (idempotent) and return its brand. (S7) */
|
|
40
|
+
export declare function ensureFunctionNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
41
|
+
/** Register `Symbol.prototype` glue (idempotent) and return its brand. (S7) */
|
|
42
|
+
export declare function ensureSymbolNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
43
|
+
/** Register `BigInt.prototype` glue (idempotent) and return its brand. (S7) */
|
|
44
|
+
export declare function ensureBigIntNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
45
|
+
/** Register `WeakMap.prototype` glue (idempotent) and return its brand. (S7) */
|
|
46
|
+
export declare function ensureWeakMapNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
47
|
+
/** Register `WeakSet.prototype` glue (idempotent) and return its brand. (S7) */
|
|
48
|
+
export declare function ensureWeakSetNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* (#2651 M1 / D2) Register the abstract `%TypedArray%.prototype` glue (idempotent)
|
|
51
|
+
* and return its brand. This is the single shared member set; every concrete view
|
|
52
|
+
* proto reuses `TYPED_ARRAY_PROTO_METHODS` (they inherit from this intrinsic), so
|
|
53
|
+
* binary size stays proportional. The `%TypedArray%` brand is pre-reserved in
|
|
54
|
+
* `BUILTIN_BRAND_TABLE`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function ensureTypedArrayIntrinsicNativeProtoGlue(ctx: CodegenContext): number | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* (#2651 M1 / D2) Register a concrete TypedArray view's `<View>.prototype` glue
|
|
59
|
+
* (idempotent) and return its brand, or `undefined` if `viewName` is not a wired
|
|
60
|
+
* non-bigint view (caller falls through to the existing refusal). Each view shares
|
|
61
|
+
* the `%TypedArray%.prototype` member set (`TYPED_ARRAY_PROTO_METHODS`). The brand
|
|
62
|
+
* is the per-view brand pre-reserved in `BUILTIN_BRAND_TABLE`.
|
|
63
|
+
*/
|
|
64
|
+
export declare function ensureTypedArrayViewNativeProtoGlue(ctx: CodegenContext, viewName: string): number | undefined;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { CodegenContext } from './context/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* A successful match describes which statements to drop from the original
|
|
5
|
+
* statement list and which to insert in their place. The fused replacement
|
|
6
|
+
* is two statements: the `let ACC = INIT` declaration (carried over) and a
|
|
7
|
+
* single fused for-loop.
|
|
8
|
+
*/
|
|
9
|
+
export interface ReduceFusionMatch {
|
|
10
|
+
/** First index in the parent statement list to remove (the array decl). */
|
|
11
|
+
startIdx: number;
|
|
12
|
+
/** Last index (inclusive) to remove (the read-loop). */
|
|
13
|
+
endIdx: number;
|
|
14
|
+
/** Synthetic statements to splice in. Length 2: accumulator decl + fused loop. */
|
|
15
|
+
replacement: ts.Statement[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Scan a function body for the fill+reduce shape. Returns matches in
|
|
19
|
+
* back-to-front order so callers can splice without invalidating later
|
|
20
|
+
* indices. Empty array means no rewrite.
|
|
21
|
+
*
|
|
22
|
+
* Only matches at the top-level of the function body for now — nested
|
|
23
|
+
* blocks would require alpha-renaming index vars and are out of scope.
|
|
24
|
+
*/
|
|
25
|
+
export declare function detectArrayReduceFusion(ctx: CodegenContext, fnBody: ts.Block | undefined): ReduceFusionMatch[];
|
|
26
|
+
/**
|
|
27
|
+
* Apply detected fusion matches to the function body's statement list.
|
|
28
|
+
* Returns a new array of statements with each match replaced by its
|
|
29
|
+
* synthetic fused-loop pair. Iterates back-to-front so indices stay valid.
|
|
30
|
+
*/
|
|
31
|
+
export declare function applyArrayReduceFusion(stmts: readonly ts.Statement[], matches: ReduceFusionMatch[]): ts.Statement[];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CodegenContext } from './context/types.js';
|
|
2
|
+
export declare const ARRAY_TO_PRIMITIVE_STRING = "__array_to_primitive_string";
|
|
3
|
+
/**
|
|
4
|
+
* Reserve the `__array_to_primitive_string(externref arr) -> externref`
|
|
5
|
+
* placeholder and return its funcIdx. Body is a bare `unreachable` until
|
|
6
|
+
* `fillArrayToPrimitive` patches it (after `__extern_length`/`__extern_get_idx`
|
|
7
|
+
* are registered). Idempotent. Standalone only — the JS-host lane reduces arrays
|
|
8
|
+
* via the host `__extern_toString` import, so this driver is never reached there.
|
|
9
|
+
*/
|
|
10
|
+
export declare function reserveArrayToPrimitiveString(ctx: CodegenContext): number;
|
|
11
|
+
/**
|
|
12
|
+
* Fill the reserved `__array_to_primitive_string` body now that
|
|
13
|
+
* `__extern_length` / `__extern_get_idx` / `$__any_to_string` / `__str_concat`
|
|
14
|
+
* are all registered. Implements `Array.prototype.join(",")`:
|
|
15
|
+
*
|
|
16
|
+
* result = "" // empty native string
|
|
17
|
+
* len = i32(__extern_length(arr)) // ToLength; non-array → 0 → ""
|
|
18
|
+
* for (i = 0; i < len; i++):
|
|
19
|
+
* if (i > 0) result = __str_concat(result, ",")
|
|
20
|
+
* elem = __extern_get_idx(arr, f64(i)) // externref (null for a hole)
|
|
21
|
+
* // §23.1.3.31: a null/undefined element stringifies to "" (NOT "null")
|
|
22
|
+
* if (elem != null) result = __str_concat(result, $__any_to_string(any(elem)))
|
|
23
|
+
* return extern.convert_any(result)
|
|
24
|
+
*
|
|
25
|
+
* No-op when the driver was not reserved or a dependency is missing — the
|
|
26
|
+
* placeholder `unreachable` stays (unreachable from any live arm in that case).
|
|
27
|
+
*/
|
|
28
|
+
export declare function fillArrayToPrimitive(ctx: CodegenContext): void;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Master gate for the AST-side async CPS lowering.
|
|
5
|
+
*
|
|
6
|
+
* Slice 2A (#1042) built the linear single-tail-await state machine and made it
|
|
7
|
+
* *correct when it runs*: the canonical shapes resolve to the right value
|
|
8
|
+
* through `Promise_resolve` → `Promise_then2` → continuation, captures and the
|
|
9
|
+
* `return await` identity tail are handled, and the late-import shift hazard is
|
|
10
|
+
* removed by the `collectAsyncCpsImports` prepass.
|
|
11
|
+
*
|
|
12
|
+
* Flipped **ON** in #1796. The synchronous-consumption regression that kept it
|
|
13
|
+
* off is resolved by the per-function {@link asyncFnNeedsCps} predicate (#1936):
|
|
14
|
+
* an async fn is CPS-lowered (returns a real Promise) ONLY when it *genuinely
|
|
15
|
+
* suspends* — at least one await operand is not statically resolved. Fully
|
|
16
|
+
* await-elidable bodies (`return await Promise.resolve(42)`, `await 41; ...`)
|
|
17
|
+
* stay on the legacy synchronous path and keep returning the unwrapped value, so
|
|
18
|
+
* the `asyncFn() as any as number` "compile away" idiom (#1313/#1727) is
|
|
19
|
+
* preserved for those. Functions that truly suspend now return a real Promise;
|
|
20
|
+
* call sites that consume such a result as a raw value cannot be served
|
|
21
|
+
* synchronously by construction and were already semantically broken under the
|
|
22
|
+
* legacy fakery — those test cases are migrated to the Promise model in #1796.
|
|
23
|
+
*/
|
|
24
|
+
export declare const ASYNC_CPS_ENABLED = true;
|
|
25
|
+
/**
|
|
26
|
+
* Result of analysing an async function body for the CPS transform.
|
|
27
|
+
* Populated by {@link analyzeAsyncBody}, consumed by {@link emitAsyncStateMachine}.
|
|
28
|
+
*/
|
|
29
|
+
export interface AsyncCpsPlan {
|
|
30
|
+
/** Pre-order list of await points found in the body (by `ts.Node` identity). */
|
|
31
|
+
readonly awaitPoints: readonly ts.AwaitExpression[];
|
|
32
|
+
/**
|
|
33
|
+
* For each await point: the set of live local names that must be captured
|
|
34
|
+
* into the continuation that resumes after the await. "Live" = referenced in
|
|
35
|
+
* any statement/expression that executes after the await point.
|
|
36
|
+
*/
|
|
37
|
+
readonly liveAfterAwait: ReadonlyMap<ts.AwaitExpression, ReadonlySet<string>>;
|
|
38
|
+
/** Does the body contain a `try`/`catch` that spans an await? (Phase 3B — gated.) */
|
|
39
|
+
readonly hasTryAcrossAwait: boolean;
|
|
40
|
+
/** Does the body contain a `throw` that must reject the outer Promise? */
|
|
41
|
+
readonly hasUncaughtThrow: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* For each await point: `true` when its operand is *statically resolved* —
|
|
44
|
+
* i.e. the awaited value is already settled at compile time and the suspension
|
|
45
|
+
* is observably a no-op (`await 1`, `await Promise.resolve(x)`, `await` over a
|
|
46
|
+
* literal/arithmetic-of-literals). When EVERY await in a body is statically
|
|
47
|
+
* resolved (and the body otherwise matches a CPS-able shape), the function does
|
|
48
|
+
* not genuinely suspend: it can be compiled as a synchronous function that
|
|
49
|
+
* returns a fulfilled Promise (compile-time await-elision) instead of paying
|
|
50
|
+
* the CPS state-machine cost. See {@link asyncFnNeedsCps} (#1936).
|
|
51
|
+
*
|
|
52
|
+
* Conservative: only the forms enumerated in {@link awaitIsStaticallyResolved}
|
|
53
|
+
* count as resolved; anything else (a call result, a member read, an
|
|
54
|
+
* identifier that might hold a pending Promise) is `false` so the safe CPS /
|
|
55
|
+
* legacy path is chosen.
|
|
56
|
+
*/
|
|
57
|
+
readonly awaitedStaticallyResolved: ReadonlyMap<ts.AwaitExpression, boolean>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Walk the body of an async function / arrow / method and produce a plan.
|
|
61
|
+
*
|
|
62
|
+
* Pure analysis — no codegen side effects, no `ctx`/`fctx` mutation. Safe to
|
|
63
|
+
* call speculatively (the function-body hook calls it to decide whether a
|
|
64
|
+
* function needs CPS at all: zero await points ⇒ legacy path).
|
|
65
|
+
*/
|
|
66
|
+
export declare function analyzeAsyncBody(_ctx: CodegenContext, fn: ts.FunctionLikeDeclaration): AsyncCpsPlan;
|
|
67
|
+
/**
|
|
68
|
+
* Conservative compile-time predicate: is the operand of an `await` already a
|
|
69
|
+
* *settled* value, so that `await operand` performs no observable suspension?
|
|
70
|
+
*
|
|
71
|
+
* Per §27.7.5.3, `await V` ≡ `PromiseResolve(%Promise%, V)` then a job. When `V`
|
|
72
|
+
* is not a thenable the resumption is a single microtask carrying `V` unchanged;
|
|
73
|
+
* when `V` is `Promise.resolve(x)` with a non-thenable `x` it likewise settles
|
|
74
|
+
* to `x`. In both cases the *value* is statically known to be the operand (or
|
|
75
|
+
* its resolve-argument); only the scheduling differs. js2wasm's synchronous
|
|
76
|
+
* model already collapses that scheduling, so these awaits are safe to treat as
|
|
77
|
+
* pass-through.
|
|
78
|
+
*
|
|
79
|
+
* Recognised static forms (intentionally narrow — over-approximating here would
|
|
80
|
+
* mis-elide a genuinely-suspending await):
|
|
81
|
+
* - numeric / string / boolean / null literals
|
|
82
|
+
* - `void`-prefixed, unary `+`/`-`/`!` over a static operand
|
|
83
|
+
* - binary arithmetic / comparison where BOTH operands are static
|
|
84
|
+
* - parenthesised / `as`-cast wrappers around a static operand
|
|
85
|
+
* - `Promise.resolve(<static>)` and `Promise.resolve()` (settles to undefined)
|
|
86
|
+
*
|
|
87
|
+
* Everything else — a call result, a member access, a bare identifier (which may
|
|
88
|
+
* hold a pending Promise) — returns `false`.
|
|
89
|
+
*/
|
|
90
|
+
export declare function awaitIsStaticallyResolved(operand: ts.Expression): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* The per-function CPS decision (#1936) — replaces the global
|
|
93
|
+
* {@link ASYNC_CPS_ENABLED} kill-switch with a per-function predicate. Returns
|
|
94
|
+
* `true` only when the function *genuinely suspends* and the suspension is in a
|
|
95
|
+
* shape the state machine can lower:
|
|
96
|
+
*
|
|
97
|
+
* 1. at least one await point exists,
|
|
98
|
+
* 2. at least one await operand is NOT statically resolved (a real suspension —
|
|
99
|
+
* otherwise the body is await-elidable and compiles as a sync fn returning
|
|
100
|
+
* a fulfilled Promise), and
|
|
101
|
+
* 3. {@link splitBodyAtAwait} accepts the body shape (single top-level await in
|
|
102
|
+
* a canonical position; richer control flow stays on the legacy path with a
|
|
103
|
+
* `cps-unsupported-shape` census bucket), and
|
|
104
|
+
* 4. the single awaited operand is not a `Promise.<combinator>(...)` call —
|
|
105
|
+
* those already return a real Promise that the legacy `await`-identity path
|
|
106
|
+
* resolves correctly, and routing them through CPS regresses host-method
|
|
107
|
+
* argument marshaling pending #2028 (see {@link awaitedExprIsPromiseCombinator}).
|
|
108
|
+
*
|
|
109
|
+
* `ASYNC_CPS_ENABLED` is retained as a transitional master kill-switch routed
|
|
110
|
+
* through this predicate; when it is `false` the predicate always returns
|
|
111
|
+
* `false` (the pre-#1796 shipped behaviour).
|
|
112
|
+
*/
|
|
113
|
+
export declare function asyncFnNeedsCps(fn: ts.FunctionLikeDeclaration, plan: AsyncCpsPlan): boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Classification of how an async call's result is consumed at its call site —
|
|
116
|
+
* the per-call-site half of the async contract migration (#1936). The legacy
|
|
117
|
+
* boolean `asyncResultConsumedAsValue` only distinguished "raw value" from
|
|
118
|
+
* "everything else"; the census needs the three-way split so #1796 can migrate
|
|
119
|
+
* exactly the `value`-but-not-statically-resolved set.
|
|
120
|
+
*
|
|
121
|
+
* - `await` — consumed by an enclosing `await` (raw-T passthrough today).
|
|
122
|
+
* - `value` — consumed through a non-Promise cast/assertion sink
|
|
123
|
+
* (`f() as number`, `as unknown as number`, `as any`): the
|
|
124
|
+
* synchronous-consumption contract that blocks the global flip.
|
|
125
|
+
* - `thenable` — consumed as a real Promise (`.then`, `Promise.all([f()])`,
|
|
126
|
+
* `const p: Promise<T> = f()`, bare `return f()`): already
|
|
127
|
+
* spec-correct, takes the wrap path.
|
|
128
|
+
*/
|
|
129
|
+
export type AsyncConsumerKind = "await" | "value" | "thenable";
|
|
130
|
+
/**
|
|
131
|
+
* Census classifier for an async call result's consumer (#1936). Pure: depends
|
|
132
|
+
* only on the AST shape around `expr` and the `checker` for cast target types,
|
|
133
|
+
* so the offline census script can reuse it without a full `CodegenContext`.
|
|
134
|
+
*
|
|
135
|
+
* Walks the transparent wrapper chain (`(...)`, `as`, `!`, `<T>`) from
|
|
136
|
+
* `expr.parent` exactly as the shipped `asyncResultConsumedAsValue` does, then:
|
|
137
|
+
* - if the semantic consumer is an `AwaitExpression` → `await`,
|
|
138
|
+
* - else if any wrapper cast targets a non-Promise type → `value`,
|
|
139
|
+
* - else → `thenable`.
|
|
140
|
+
*
|
|
141
|
+
* Behaviour parity note: `classifyAsyncConsumer(...) !== "thenable"` is exactly
|
|
142
|
+
* the boolean the legacy `asyncResultConsumedAsValue` returns, so routing the
|
|
143
|
+
* call site through this classifier is a behaviour-preserving refactor until the
|
|
144
|
+
* #1796 flip changes the `value`/`thenable` dispatch.
|
|
145
|
+
*/
|
|
146
|
+
export declare function classifyAsyncConsumer(checker: ts.TypeChecker, expr: ts.CallExpression): AsyncConsumerKind;
|
|
147
|
+
/**
|
|
148
|
+
* Emit a CPS-lowered async function body into `fctx`, replacing the normal
|
|
149
|
+
* statement loop. Drives the entire body and leaves the result Promise
|
|
150
|
+
* (externref) on the stack as the function's return value; the caller skips
|
|
151
|
+
* its own statement loop.
|
|
152
|
+
*
|
|
153
|
+
* PR1 scope — a single tail-position await in one of the canonical shapes
|
|
154
|
+
* (`return await P`, `const x = await P; rest`, `await P; rest`). The
|
|
155
|
+
* function result type must already have been rewritten to `externref` by the
|
|
156
|
+
* activation hook (the function returns a Promise object, not the unwrapped
|
|
157
|
+
* value). Everything is gated behind {@link ASYNC_CPS_ENABLED} + the
|
|
158
|
+
* function-body activation gate, so this never runs in default compilation
|
|
159
|
+
* until that gate is flipped.
|
|
160
|
+
*
|
|
161
|
+
* Strategy (no funcref table, no manual settle):
|
|
162
|
+
* 1. Emit the synchronous prefix into `fctx`.
|
|
163
|
+
* 2. Compile the awaited expression → externref (the promise we suspend on).
|
|
164
|
+
* 3. Synthesize an exported `__cb_N(captures, awaitValue) -> externref`
|
|
165
|
+
* continuation whose body is the post-await suffix; its `return X`
|
|
166
|
+
* naturally produces `X` as the cb's externref result.
|
|
167
|
+
* 4. At the suspension point emit the creation site:
|
|
168
|
+
* push cbId; build+push captures struct; `__make_callback` → contCb;
|
|
169
|
+
* `Promise_then2(awaited, contCb, null)` → the chained result Promise.
|
|
170
|
+
* `.then`'s own returned promise resolves to the continuation's return
|
|
171
|
+
* value, so it IS this async function's result promise. A null reject
|
|
172
|
+
* callback lets rejections propagate (default rethrow).
|
|
173
|
+
*
|
|
174
|
+
* Returns nothing; on an unsupported shape it `reportError`s and leaves the
|
|
175
|
+
* caller to fall back (the activation hook only calls this for shapes
|
|
176
|
+
* `splitBodyAtAwait` accepts, so that path is defensive).
|
|
177
|
+
*/
|
|
178
|
+
export declare function emitAsyncStateMachine(ctx: CodegenContext, fctx: FunctionContext, fn: ts.FunctionLikeDeclaration, plan: AsyncCpsPlan): void;
|
|
179
|
+
/**
|
|
180
|
+
* Compile a nested `await` encountered while the surrounding
|
|
181
|
+
* {@link emitAsyncStateMachine} is driving the body (e.g. `await (x + await y)`).
|
|
182
|
+
*
|
|
183
|
+
* PR1: stub. Nested awaits within a single segment are a follow-up; the joint
|
|
184
|
+
* spec §6.2 lists `return await` as the only tail case required in Slice 2A.
|
|
185
|
+
*/
|
|
186
|
+
export declare function compileNestedAwait(ctx: CodegenContext, _fctx: FunctionContext, expr: ts.AwaitExpression): never;
|
|
187
|
+
/**
|
|
188
|
+
* IR entry point (Phase 2B / #1373b). Same machinery, IR input.
|
|
189
|
+
*
|
|
190
|
+
* PR1: stub returning `false` (means "did not handle; caller uses legacy
|
|
191
|
+
* path"). #1373b fills this in.
|
|
192
|
+
*/
|
|
193
|
+
export declare function emitAsyncStateMachineFromIr(): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* One segment boundary produced by {@link splitBodyAtAwait}.
|
|
196
|
+
*
|
|
197
|
+
* PR1 handles a body with **exactly one** top-level await appearing as the
|
|
198
|
+
* initializer/operand of one of three canonical statement shapes. The split
|
|
199
|
+
* yields:
|
|
200
|
+
* - `prefix`: statements that run synchronously before suspension (the
|
|
201
|
+
* await's own statement is NOT included here; its awaited expression is
|
|
202
|
+
* surfaced separately as `awaitedExpr`).
|
|
203
|
+
* - `awaitedExpr`: the operand of the await (the thing we suspend on).
|
|
204
|
+
* - `resumeBinding`: the `{name,type}` the resolved value binds to on resume
|
|
205
|
+
* (for `const x = await P`), or `null` for a bare `await P;` /
|
|
206
|
+
* `return await P`.
|
|
207
|
+
* - `suffix`: statements that run after resumption (the continuation body).
|
|
208
|
+
* - `isReturnAwait`: true for `return await P` — the continuation's value IS
|
|
209
|
+
* the awaited value, so `suffix` is empty and the resolved value settles
|
|
210
|
+
* the outer promise directly.
|
|
211
|
+
*/
|
|
212
|
+
export interface AwaitSplit {
|
|
213
|
+
readonly prefix: readonly ts.Statement[];
|
|
214
|
+
readonly awaitedExpr: ts.Expression;
|
|
215
|
+
readonly resumeBinding: {
|
|
216
|
+
readonly name: string;
|
|
217
|
+
readonly type: ts.TypeNode | undefined;
|
|
218
|
+
} | null;
|
|
219
|
+
readonly suffix: readonly ts.Statement[];
|
|
220
|
+
readonly isReturnAwait: boolean;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Split a single-await async function body into a prefix / awaited-expr /
|
|
224
|
+
* suffix triple for the canonical PR1 shapes. Returns `null` if the body does
|
|
225
|
+
* not match one of the three supported shapes (caller falls back to legacy).
|
|
226
|
+
*
|
|
227
|
+
* Supported shapes (the await must be the *sole* top-level await and appear at
|
|
228
|
+
* statement top-level, not nested inside an expression sub-tree):
|
|
229
|
+
*
|
|
230
|
+
* 1. `return await P;` → isReturnAwait, no suffix
|
|
231
|
+
* 2. `const x = await P; <rest>` → resumeBinding=x, suffix=rest
|
|
232
|
+
* (also `let`/`var`; single declarator only)
|
|
233
|
+
* 3. `await P; <rest>` → no binding, suffix=rest
|
|
234
|
+
*
|
|
235
|
+
* Pure: no `ctx`/`fctx` mutation. The shape gate keeps PR1 small and provably
|
|
236
|
+
* correct; richer control flow (awaits in loops/branches, multiple awaits in
|
|
237
|
+
* one segment) is deferred to follow-up slices.
|
|
238
|
+
*/
|
|
239
|
+
export declare function splitBodyAtAwait(fn: ts.FunctionLikeDeclaration, plan: AsyncCpsPlan): AwaitSplit | null;
|