@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,25 @@
|
|
|
1
|
+
import { ValType } from '../../ir/types.js';
|
|
2
|
+
import { ts } from '../../ts-api.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from '../context/types.js';
|
|
4
|
+
import { InnerResult } from '../shared.js';
|
|
5
|
+
declare function compileSuperMethodCall(ctx: CodegenContext, fctx: FunctionContext, expr: ts.CallExpression): InnerResult;
|
|
6
|
+
/**
|
|
7
|
+
* Compile `super['method'](args)` — resolve to ParentClass_method and call with this.
|
|
8
|
+
* Same logic as compileSuperMethodCall but the method name comes from a computed key.
|
|
9
|
+
*/
|
|
10
|
+
declare function compileSuperElementMethodCall(ctx: CodegenContext, fctx: FunctionContext, expr: ts.CallExpression, methodName: string): ValType | null;
|
|
11
|
+
/**
|
|
12
|
+
* Compile `super.prop` — access a parent class property or getter via `this`.
|
|
13
|
+
* For getter accessors, calls the parent's getter function.
|
|
14
|
+
* For struct fields, accesses the field on `this` (child struct inherits parent fields).
|
|
15
|
+
*/
|
|
16
|
+
export declare function compileSuperPropertyAccess(ctx: CodegenContext, fctx: FunctionContext, expr: ts.PropertyAccessExpression, propName: string): ValType | null;
|
|
17
|
+
/**
|
|
18
|
+
* Compile `super[expr]` — access a parent class property via computed key on `this`.
|
|
19
|
+
* Resolves the key at compile time if possible and delegates to compileSuperPropertyAccess logic.
|
|
20
|
+
* For dynamic keys, falls back to default value for the access type.
|
|
21
|
+
*/
|
|
22
|
+
export declare function compileSuperElementAccess(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ElementAccessExpression): ValType | null;
|
|
23
|
+
declare function compileClassExpression(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ClassExpression): ValType | null;
|
|
24
|
+
declare function compileNewExpression(ctx: CodegenContext, fctx: FunctionContext, expr: ts.NewExpression): ValType | null;
|
|
25
|
+
export { compileClassExpression, compileNewExpression, compileSuperElementMethodCall, compileSuperMethodCall };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ts } from '../../ts-api.js';
|
|
2
|
+
import { CodegenContext, FunctionContext } from '../context/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the resolved class name if `name` (a user-visible identifier or
|
|
5
|
+
* class-expression alias) denotes a `class … extends Promise` (transitively,
|
|
6
|
+
* through a chain of user subclasses), else `undefined`.
|
|
7
|
+
*
|
|
8
|
+
* Walks the parent chain because `classBuiltinParentMap` only records the
|
|
9
|
+
* *immediate* builtin parent: for `class B extends A` / `class A extends
|
|
10
|
+
* Promise`, B maps to "A", not "Promise". `classParentMap` carries the
|
|
11
|
+
* user-class edges, so we climb until we hit a builtin Promise parent.
|
|
12
|
+
*
|
|
13
|
+
* Standalone (WASI) mode has no JS host, so `__promise_subclass_ctor` is
|
|
14
|
+
* unsatisfiable there — return `undefined` so callers fall back.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolvePromiseSubclassName(ctx: CodegenContext, name: string): string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Emits an externref that is the cached `__promise_subclass_ctor` for the given
|
|
19
|
+
* resolved class name (one synthesized `class extends Promise {}` per name).
|
|
20
|
+
* `resolved` MUST be the name returned by {@link resolvePromiseSubclassName}
|
|
21
|
+
* (i.e. already alias-resolved through `classExprNameMap`).
|
|
22
|
+
*
|
|
23
|
+
* Returns true on success (instruction(s) pushed), false if the import could
|
|
24
|
+
* not be registered (caller should fall back to its default emission).
|
|
25
|
+
*/
|
|
26
|
+
export declare function emitPromiseSubclassCtor(ctx: CodegenContext, fctx: FunctionContext, resolved: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Convenience for the value-read position: if `name` denotes a `class extends
|
|
29
|
+
* Promise`, emit the unified `__promise_subclass_ctor` externref and return
|
|
30
|
+
* true; else return false (caller falls through to its normal handling).
|
|
31
|
+
*/
|
|
32
|
+
export declare function tryEmitPromiseSubclassValue(ctx: CodegenContext, fctx: FunctionContext, name: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Receiver-position helper (combinator `thisArg`): same unification, but the
|
|
35
|
+
* argument arrives as a `ts.Expression`. Only a bare identifier (or class-expr
|
|
36
|
+
* alias) is eligible. Returns true if it emitted the unified ctor externref.
|
|
37
|
+
*/
|
|
38
|
+
export declare function tryEmitPromiseSubclassReceiver(ctx: CodegenContext, fctx: FunctionContext, argExpr: ts.Expression): boolean;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ts } from '../../ts-api.js';
|
|
2
|
+
import { CodegenContext, FunctionContext } from '../context/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* (#1719 CPR) AST-only predicate (no `ctx`) for the module-init statement filter:
|
|
5
|
+
* true when `target` is `Array.prototype[Symbol.iterator]` / `Array.prototype.values`,
|
|
6
|
+
* so the override assignment is kept in `__module_init` instead of being dropped.
|
|
7
|
+
* Matches the LHS shape recognised by `sourceOverridesArrayIterator`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isArrayProtoIteratorAssignTarget(target: ts.Expression): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* If `target = value` is an `Array.prototype` iterator override, capture the
|
|
12
|
+
* lifted RHS closure into `ctx.protoOverrides` (rooted in a module global) and
|
|
13
|
+
* return `true` (the caller must NOT fall through to the normal element/property
|
|
14
|
+
* assignment). Returns `false` (no-op) for every other assignment — byte-identical.
|
|
15
|
+
*
|
|
16
|
+
* Leaves the override closure externref on the stack as the assignment's value
|
|
17
|
+
* (an assignment expression evaluates to its RHS).
|
|
18
|
+
*/
|
|
19
|
+
export declare function maybeCaptureArrayProtoOverride(ctx: CodegenContext, fctx: FunctionContext, target: ts.Expression, value: ts.Expression): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Returns the rooted override-closure global index for the Array `@@iterator`
|
|
22
|
+
* override (the CPR drive consults this), or `undefined` when no override was
|
|
23
|
+
* captured. `values` is treated as an alias for `@@iterator` per §23.1.3.36
|
|
24
|
+
* (`Array.prototype.values` IS `Array.prototype[@@iterator]`), so either capture
|
|
25
|
+
* drives array iteration.
|
|
26
|
+
*/
|
|
27
|
+
export declare function arrayIteratorOverrideGlobalIdx(ctx: CodegenContext): number | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* (#1719 CPR read-drive — option (a)) Fill the reserved `__drive_proto_iterator`
|
|
30
|
+
* driver body in post-processing, AFTER `emitClosureMethodCallExportN(0)` has
|
|
31
|
+
* registered `__call_fn_method_0` in `funcMap`. The driver is a thin wrapper:
|
|
32
|
+
*
|
|
33
|
+
* __drive_proto_iterator(thisVal, closure) =
|
|
34
|
+
* return __call_fn_method_0(thisVal, closure)
|
|
35
|
+
*
|
|
36
|
+
* reusing the proven re-entrancy-safe `__current_this` install/restore dispatch
|
|
37
|
+
* (#1636-S1) instead of duplicating funcref-type dispatch at each read site. The
|
|
38
|
+
* override closure is arity-0 (`Array.prototype[@@iterator]()` takes no args), so
|
|
39
|
+
* arity-0 `__call_fn_method_0` is the exact driver. No-op when the driver was
|
|
40
|
+
* never reserved (brand clear / no read-drive site).
|
|
41
|
+
*/
|
|
42
|
+
export declare function fillProtoIteratorDriver(ctx: CodegenContext): void;
|
|
43
|
+
/**
|
|
44
|
+
* (#1719 CPR read-drive) Emit the override drive at an array-destructuring /
|
|
45
|
+
* for-of / spread observation site. PRECONDITION: the RHS vec ref is on the
|
|
46
|
+
* stack and the caller has already gated on
|
|
47
|
+
* `arrayIteratorMaybeOverridden && arrayIteratorOverrideGlobalIdx(ctx)!==undefined`.
|
|
48
|
+
*
|
|
49
|
+
* Lowers (§7.4.2 GetIterator + §8.5.2 IteratorBindingInitialization):
|
|
50
|
+
* 1. `extern.convert_any` the vec → the array-as-`this` externref;
|
|
51
|
+
* 2. `global.get` the captured override closure;
|
|
52
|
+
* 3. `call __drive_proto_iterator(array, closure)` → the override-produced
|
|
53
|
+
* iterator externref, stashed in `iterLocal`.
|
|
54
|
+
*
|
|
55
|
+
* Returns the local holding the iterator externref. The caller drains it via
|
|
56
|
+
* `__iterator_next` into the binding elements. Standalone-clean: the drive runs
|
|
57
|
+
* in-Wasm (no host import, no host-Array reflection); only the per-element drain
|
|
58
|
+
* uses the existing `__iterator_next` host import (dual-mode boundary, same as
|
|
59
|
+
* for-of). The brand only fires here at the observation boundary, so internal
|
|
60
|
+
* array iterations inside the override body stay on the typed-vec fast path —
|
|
61
|
+
* no re-entrancy.
|
|
62
|
+
*/
|
|
63
|
+
export declare function emitArrayProtoIteratorDrive(ctx: CodegenContext, fctx: FunctionContext, overrideGlobalIdx: number): number;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ts } from '../../ts-api.js';
|
|
2
|
+
import { ValType } from '../../ir/types.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from '../context/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Compile prefix/postfix increment/decrement on member expressions:
|
|
6
|
+
* ++obj.x, obj.x++, --obj[i], obj[i]--, etc.
|
|
7
|
+
*
|
|
8
|
+
* For prefix: evaluates new value (old +/- 1), stores, returns new value.
|
|
9
|
+
* For postfix: evaluates old value, stores new value (old +/- 1), returns old value.
|
|
10
|
+
*/
|
|
11
|
+
declare function compileMemberIncDec(ctx: CodegenContext, fctx: FunctionContext, operand: ts.Expression, arithOp: "add" | "sub", mode: "prefix" | "postfix"): ValType | null;
|
|
12
|
+
/**
|
|
13
|
+
* Compile a prefix UpdateExpression: `++x` or `--x` on any target shape
|
|
14
|
+
* (identifier, property access, element access, boxed capture, global).
|
|
15
|
+
*
|
|
16
|
+
* Caller must have already established that `expr.operator` is either
|
|
17
|
+
* `PlusPlusToken` or `MinusMinusToken`.
|
|
18
|
+
*/
|
|
19
|
+
declare function compilePrefixUpdate(ctx: CodegenContext, fctx: FunctionContext, expr: ts.PrefixUnaryExpression): ValType | null;
|
|
20
|
+
declare function compilePostfixUnary(ctx: CodegenContext, fctx: FunctionContext, expr: ts.PostfixUnaryExpression): ValType | null;
|
|
21
|
+
export { compileMemberIncDec, compilePostfixUnary, compilePrefixUpdate };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ts } from '../../ts-api.js';
|
|
2
|
+
import { ValType } from '../../ir/types.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from '../context/types.js';
|
|
4
|
+
import { compileMemberIncDec, compilePostfixUnary } from './unary-updates.js';
|
|
5
|
+
declare function compilePrefixUnary(ctx: CodegenContext, fctx: FunctionContext, expr: ts.PrefixUnaryExpression): ValType | null;
|
|
6
|
+
export { compileMemberIncDec, compilePostfixUnary, compilePrefixUnary };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { ValType } from '../ir/types.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
4
|
+
export { compileArrayMethodCall, compileArrayPrototypeCall, emitBoundsCheckedArrayGet, emitClampIndex, emitClampNonNeg, } from './array-methods.js';
|
|
5
|
+
export { compileNumericBinaryOp } from './binary-ops.js';
|
|
6
|
+
export { collectReferencedIdentifiers, collectWrittenIdentifiers } from './closures.js';
|
|
7
|
+
export { getWellKnownSymbolId, resolveComputedKeyExpression, resolveConstantExpression } from './literals.js';
|
|
8
|
+
export { compileObjectDefineProperties, compileObjectDefineProperty, compileObjectKeysOrValues, compilePropertyIntrospection, } from './object-ops.js';
|
|
9
|
+
export { compileElementAccess, compileOptionalPropertyAccess, compilePropertyAccess, emitNullCheckThrow, isProvablyNonNull, } from './property-access.js';
|
|
10
|
+
export { getCol, getLine, resolveEnclosingClassName, valTypesMatch, VOID_RESULT } from './shared.js';
|
|
11
|
+
export { compileNativeStringLiteral, compileNativeStringMethodCall, compileNativeTemplateExpression, compileStringBinaryOp, compileStringLiteral, compileTaggedTemplateExpression, compileTemplateExpression, emitBoolToString, } from './string-ops.js';
|
|
12
|
+
export { coercionInstrs, defaultValueInstrs, pushDefaultValue, pushParamSentinel } from './type-coercion.js';
|
|
13
|
+
export { compileInstanceOf, compileTypeofComparison } from './typeof-delete.js';
|
|
14
|
+
export { compileAssignment, compileCompoundAssignment, compileLogicalAssignment, isCompoundAssignment, } from './expressions/assignment.js';
|
|
15
|
+
export { compileCallExpression, compileIIFE, compileOptionalCallExpression } from './expressions/calls.js';
|
|
16
|
+
export { emitLazyProtoGet, findExternInfoForMember } from './expressions/extern.js';
|
|
17
|
+
export { emitThrowString, getFuncParamTypes } from './expressions/helpers.js';
|
|
18
|
+
export { analyzeTdzAccessByPos, compileIdentifier, computeElidableTopLevelTdzNames, narrowTypeToUnbox, } from './expressions/identifiers.js';
|
|
19
|
+
export { emitUndefined, ensureExternIsUndefinedImport, ensureGetUndefined, ensureLateImport, flushLateImportShifts, patchStructNewForAddedField, shiftLateImportIndices, } from './expressions/late-imports.js';
|
|
20
|
+
export { compileLogicalAnd, compileLogicalOr, compileNullishCoalescing } from './expressions/logical-ops.js';
|
|
21
|
+
export { getIteratorResultValueType, isGeneratorIteratorResultLike, resolveStructName, tryStaticToNumber, } from './expressions/misc.js';
|
|
22
|
+
export { compileClassExpression, compileNewExpression, compileSuperElementAccess, compileSuperPropertyAccess, } from './expressions/new-super.js';
|
|
23
|
+
export { compileMemberIncDec, compilePostfixUnary, compilePrefixUnary } from './expressions/unary.js';
|
|
24
|
+
export declare function resetCompileDepth(): void;
|
|
25
|
+
export declare function compileExpression(ctx: CodegenContext, fctx: FunctionContext, expr: ts.Expression, expectedType?: ValType): ValType | null;
|
|
26
|
+
/**
|
|
27
|
+
* Emit a local.set with automatic type coercion.
|
|
28
|
+
*/
|
|
29
|
+
export declare function emitCoercedLocalSet(ctx: CodegenContext, fctx: FunctionContext, localIdx: number, stackType: ValType): void;
|
|
30
|
+
/** Coerce a value on the stack from one type to another */
|
|
31
|
+
export declare function coerceType(ctx: CodegenContext, fctx: FunctionContext, from: ValType, to: ValType, toPrimitiveHint?: "number" | "string" | "default"): void;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { CodegenContext } from './context/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The seven silent-fallback pattern classes from the fail-loud audit
|
|
5
|
+
* (`plan/log/analysis-2026-06/04-fail-loud-audit.md` §summary table).
|
|
6
|
+
*/
|
|
7
|
+
export type SilentFallbackClass = "null-fallback" | "lookup-miss-skip" | "const-fallback" | "arity-truncation" | "allowlist-miss" | "cap-exceeded-path" | "compiler-catch";
|
|
8
|
+
/** All known classes, in declaration order — the canonical iteration order. */
|
|
9
|
+
export declare const SILENT_FALLBACK_CLASSES: readonly SilentFallbackClass[];
|
|
10
|
+
/**
|
|
11
|
+
* Per-class → per-site → hit count. Sites are stable string keys of the form
|
|
12
|
+
* `"<file-stem>:<short-label>"` (e.g. `"unary-updates:incdec-unresolvable-receiver"`)
|
|
13
|
+
* so the baseline JSON diff is readable and resilient to line moves.
|
|
14
|
+
*/
|
|
15
|
+
export type FallbackCounts = Map<SilentFallbackClass, Map<string, number>>;
|
|
16
|
+
/** Build an empty {@link FallbackCounts} with every class pre-seeded. */
|
|
17
|
+
export declare function createFallbackCounts(): FallbackCounts;
|
|
18
|
+
/**
|
|
19
|
+
* Classes promoted to hard errors once their corpus baseline hits zero —
|
|
20
|
+
* the codegen analogue of `STRICT_IR_REASONS` (index.ts). Empty in Phase 0
|
|
21
|
+
* (telemetry only); Phase 4 flips `lookup-miss-skip`/`null-fallback` in here
|
|
22
|
+
* as their buckets zero out. A site in a strict class pushes a hard error.
|
|
23
|
+
*/
|
|
24
|
+
export declare const STRICT_FALLBACK_CLASSES: ReadonlySet<SilentFallbackClass>;
|
|
25
|
+
/**
|
|
26
|
+
* Whether a *strict* class should hard-fail in the current environment.
|
|
27
|
+
* Auto-on under CI / vitest / `NODE_ENV=test`, mirroring
|
|
28
|
+
* `irVerifierHardFailureEnabled` (index.ts:934), or forced via
|
|
29
|
+
* `JS2WASM_STRICT_FALLBACKS=1`. Phase 0 has no strict classes, so this only
|
|
30
|
+
* matters once a class is promoted.
|
|
31
|
+
*/
|
|
32
|
+
export declare function strictFallbacksEnabled(env?: Record<string, string | undefined>): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Record that a silent fallback was taken at `site`.
|
|
35
|
+
*
|
|
36
|
+
* Three escalation levels (identical lifecycle to `STRICT_IR_REASONS`):
|
|
37
|
+
* 1. always — increments `ctx.fallbackCounts[cls][site]`.
|
|
38
|
+
* 2. opt-in — when `ctx.trackSilentFallbacks` (or `JS2WASM_LOG_CODEGEN_FALLBACKS=1`),
|
|
39
|
+
* pushes a structured *warning* error so the diagnostic surfaces.
|
|
40
|
+
* 3. strict — when `cls ∈ STRICT_FALLBACK_CLASSES` and {@link strictFallbacksEnabled},
|
|
41
|
+
* pushes a *hard* error so the fallback can no longer hide.
|
|
42
|
+
*
|
|
43
|
+
* Pure bookkeeping otherwise — it never touches the wasm body, so adding a
|
|
44
|
+
* call at a site is behavior-preserving in Phase 0.
|
|
45
|
+
*/
|
|
46
|
+
export declare function reportSilentFallback(ctx: CodegenContext, cls: SilentFallbackClass, site: string, node?: ts.Node, detail?: string): void;
|
|
47
|
+
/** Total hits across all classes/sites — used by the gate for a quick summary. */
|
|
48
|
+
export declare function totalFallbackHits(counts: FallbackCounts): number;
|
|
49
|
+
/**
|
|
50
|
+
* Flatten {@link FallbackCounts} into a stable, JSON-serializable shape for the
|
|
51
|
+
* baseline file: `{ [class]: { [site]: count } }`, classes and sites sorted.
|
|
52
|
+
*/
|
|
53
|
+
export declare function fallbackCountsToJson(counts: FallbackCounts): Record<string, Record<string, number>>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Instr, ValType, WasmModule } from '../ir/types.js';
|
|
2
|
+
import { CodegenContext } from './context/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Post-processing pass: mark leaf struct types in subtype hierarchies as final.
|
|
5
|
+
*
|
|
6
|
+
* V8 can devirtualize struct.get/struct.set when a type is known to be final
|
|
7
|
+
* (no subtypes). Struct types without superTypeIdx are already implicitly final
|
|
8
|
+
* in the Wasm binary encoding. This pass finds struct types that participate in
|
|
9
|
+
* subtyping (have superTypeIdx set) but are never referenced as a parent by any
|
|
10
|
+
* other type, and marks them as final so the emitter uses sub_final (0x4F).
|
|
11
|
+
*
|
|
12
|
+
* Caveat (#1173): emitting `(sub final $T)` causes Binaryen ≥ 124 (when run
|
|
13
|
+
* with `--all-features`, e.g. `wasm-opt --all-features -O4`) to convert
|
|
14
|
+
* `(ref $T)` references into `(ref exact $T)` in the re-emitted binary. The
|
|
15
|
+
* exact-reference encoding is part of the WasmGC custom-descriptors proposal
|
|
16
|
+
* and is rejected by wasmtime ≤ 44 with:
|
|
17
|
+
* "custom descriptors required for exact reference types"
|
|
18
|
+
*
|
|
19
|
+
* The benchmark/standalone path (`--target wasi` → `wasm-opt --all-features`
|
|
20
|
+
* → `wasmtime`) is the canonical victim. Browsers (V8) accept the exact
|
|
21
|
+
* encoding, so the devirtualization optimization is preserved there.
|
|
22
|
+
*
|
|
23
|
+
* `skipFinal` is intended for callers who know their output will go through a
|
|
24
|
+
* runtime that doesn't support custom-descriptors (today: wasmtime / standalone
|
|
25
|
+
* Wasm consumers). Pass `true` to leave subtypes as plain `(sub $parent ...)`
|
|
26
|
+
* so wasm-opt has nothing to convert into an exact ref.
|
|
27
|
+
*/
|
|
28
|
+
export declare function markLeafStructsFinal(mod: WasmModule, skipFinal?: boolean): void;
|
|
29
|
+
/**
|
|
30
|
+
* Post-processing pass: repair struct.get/struct.set type mismatches.
|
|
31
|
+
*
|
|
32
|
+
* When code generation emits ref.null.extern or local.get of an externref local
|
|
33
|
+
* immediately before a struct.get/struct.set, Wasm validation fails because
|
|
34
|
+
* struct.get/struct.set require a reference to the specific struct type.
|
|
35
|
+
*
|
|
36
|
+
* This pass fixes two patterns:
|
|
37
|
+
*
|
|
38
|
+
* 1. ref.null.extern + struct.get/struct.set → ref.null $typeIdx
|
|
39
|
+
* (null externref replaced with typed null for the expected struct type)
|
|
40
|
+
*
|
|
41
|
+
* 2. local.get $externref + struct.get/struct.set → local.get + any.convert_extern + ref.cast $typeIdx
|
|
42
|
+
* (externref converted to the expected struct reference type)
|
|
43
|
+
*
|
|
44
|
+
* 3. call returning externref + struct.get/struct.set → call + any.convert_extern + ref.cast $typeIdx
|
|
45
|
+
*
|
|
46
|
+
* Recurses into nested blocks, loops, if/then/else, and try/catch bodies.
|
|
47
|
+
*/
|
|
48
|
+
export declare function repairStructTypeMismatches(mod: WasmModule): number;
|
|
49
|
+
export declare function repairBody(body: Instr[], localTypes: ValType[], mod: WasmModule): number;
|
|
50
|
+
/**
|
|
51
|
+
* Compute the net stack delta for a single instruction.
|
|
52
|
+
* Returns (values_pushed - values_consumed). Used by repairStructTypeMismatches
|
|
53
|
+
* to walk backwards and find the instruction that produces a specific stack value.
|
|
54
|
+
*
|
|
55
|
+
* This is a conservative approximation — block/loop/if/try are treated as opaque
|
|
56
|
+
* (delta 0), which is safe because struct.get/struct.set operands are almost never
|
|
57
|
+
* produced by branching constructs.
|
|
58
|
+
*/
|
|
59
|
+
export declare function instrStackDelta(instr: Instr, mod: WasmModule): number;
|
|
60
|
+
/**
|
|
61
|
+
* Post-compilation fixup: reconcile struct.new argument counts.
|
|
62
|
+
*
|
|
63
|
+
* During expression compilation, fields can be dynamically added to struct
|
|
64
|
+
* types (e.g., when a property access finds a field the TS type checker knows
|
|
65
|
+
* about but wasn't in the original struct definition). This causes the
|
|
66
|
+
* struct type to have more fields than the constructor's struct.new pushes
|
|
67
|
+
* values for, resulting in Wasm validation failure.
|
|
68
|
+
*
|
|
69
|
+
* This pass scans all function bodies for struct.new instructions on class
|
|
70
|
+
* struct types and inserts default-value instructions for any missing fields.
|
|
71
|
+
*/
|
|
72
|
+
export declare function fixupStructNewArgCounts(ctx: CodegenContext): void;
|
|
73
|
+
export declare function fixupStructNewResultCoercion(ctx: CodegenContext): void;
|
|
74
|
+
/**
|
|
75
|
+
* Late-stage fixup: repair extern.convert_any applied to non-anyref values.
|
|
76
|
+
* extern.convert_any expects anyref input, but various passes can produce
|
|
77
|
+
* extern.convert_any on externref (redundant) or funcref (invalid — separate hierarchy).
|
|
78
|
+
* Must run after ALL other codegen/fixup passes.
|
|
79
|
+
*/
|
|
80
|
+
export declare function fixupExternConvertAny(ctx: CodegenContext): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CodegenContext } from './context/types.js';
|
|
2
|
+
/** Reserved name for the f64 remainder helper. */
|
|
3
|
+
export declare const FMOD_FN = "__fmod";
|
|
4
|
+
/**
|
|
5
|
+
* Ensure the `__fmod` helper function exists in the module and return its
|
|
6
|
+
* funcIdx. Idempotent — a second call returns the already-registered index.
|
|
7
|
+
*
|
|
8
|
+
* Signature: `(f64 a, f64 b) -> f64`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function ensureFmod(ctx: CodegenContext): number;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
3
|
+
/** Classification of a `new F()` fnctor allocation site. */
|
|
4
|
+
export type FnctorGateClass =
|
|
5
|
+
/** (A)∧(B): dynamically consumed, no typed own-field consumer → S3 candidate. */
|
|
6
|
+
"reconstruct"
|
|
7
|
+
/** Has a typed own-field consumer (clause B fails) → never reconstruct (hot path). */
|
|
8
|
+
| "keep-typed"
|
|
9
|
+
/** No dynamic consumer found (clause A fails) → no reconstruction needed. */
|
|
10
|
+
| "keep-static";
|
|
11
|
+
/** Result of the #2660 S1 fnctor escape/dynamic-use analysis (frozen before codegen). */
|
|
12
|
+
export interface FnctorEscapeGateResult {
|
|
13
|
+
/**
|
|
14
|
+
* Per `new F()` site classification, keyed by the `NewExpression` AST node.
|
|
15
|
+
* S3 consults this via the node identity at `compileNewFunctionDeclaration`.
|
|
16
|
+
*/
|
|
17
|
+
readonly sites: ReadonlyMap<ts.NewExpression, FnctorGateClass>;
|
|
18
|
+
/** Sites approved for reconstruction (`reconstruct`) — the (A)∧(B) set. */
|
|
19
|
+
readonly approved: ReadonlySet<ts.NewExpression>;
|
|
20
|
+
/**
|
|
21
|
+
* Fnctor symbol NAMES that have ≥1 `reconstruct`-classified `new F()` site —
|
|
22
|
+
* i.e. the constructors S3 will reconstruct as `$Object`. #2660 S2 gates its
|
|
23
|
+
* per-fnctor prototype `$Object` materialization on this set so it ONLY touches
|
|
24
|
+
* constructors whose instances need the `$proto` walk; a `keep-typed` /
|
|
25
|
+
* `keep-static` / never-`new`'d function (e.g. `Test262Error`, a species
|
|
26
|
+
* `Ctor` used only via `Object.getPrototypeOf`) keeps its existing prototype
|
|
27
|
+
* behaviour untouched (avoids the identity/harness regressions an unscoped
|
|
28
|
+
* interception caused).
|
|
29
|
+
*/
|
|
30
|
+
readonly approvedNames: ReadonlySet<string>;
|
|
31
|
+
/**
|
|
32
|
+
* #2660 PART-1 — receiver-expression → `__fnctor_<Name>` struct-name flow map.
|
|
33
|
+
*
|
|
34
|
+
* Keyed by every USE-site expression (the identifier nodes) of a LOCAL binding
|
|
35
|
+
* `const/let/var x = <call>` whose initializer call is a *single-return-
|
|
36
|
+
* inferable* fnctor-returning method (e.g. `var node = this.startNode()` where
|
|
37
|
+
* `startNode` is the aliased-prototype method `pp.startNode = function(){ return
|
|
38
|
+
* new Node(...) }`). The mapped value is the `__fnctor_<Name>` struct name
|
|
39
|
+
* (the `ctx.structMap` key from `new-super.ts`). It lets the PART-2 dispatch
|
|
40
|
+
* pin the dynamic `x.<field>` read/write/compound to that one struct instead of
|
|
41
|
+
* the open-scan `findAlternateStructsForField` — the local-receiver half of the
|
|
42
|
+
* #2660 substrate (the `this`-receiver half is `FunctionContext.thisStructName`,
|
|
43
|
+
* resolution case (1)).
|
|
44
|
+
*
|
|
45
|
+
* **Conservative-closed**: only bindings whose initializer resolves to a SINGLE
|
|
46
|
+
* `return new X()` / `return <single-return call>` chain (depth-capped,
|
|
47
|
+
* memoized) are recorded; anything ambiguous is omitted ⇒ `resolveReceiverStruct`
|
|
48
|
+
* returns `undefined` ⇒ the consumer stays on the dynamic path. A miss NEVER
|
|
49
|
+
* yields a wrong struct.
|
|
50
|
+
*
|
|
51
|
+
* **INERT in PART-1**: produced here but consulted only by the (as-yet-uncalled)
|
|
52
|
+
* `resolveReceiverStruct`; no lowering reads it, so emitted Wasm is byte-identical.
|
|
53
|
+
*/
|
|
54
|
+
readonly receiverStruct: ReadonlyMap<ts.Expression, string>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether `expr` resolves to a plain function constructor (fnctor) rather than a
|
|
58
|
+
* `class`. Mirrors the recognition `compileNewExpression` uses to route to
|
|
59
|
+
* `compileNewFunctionDeclaration`: the callee symbol has a `FunctionDeclaration`
|
|
60
|
+
* / `FunctionExpression` declaration (or a `var F = function …`), and is not a
|
|
61
|
+
* class. Returns the resolved constructor symbol when it is a fnctor, else
|
|
62
|
+
* `undefined`.
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolveFnctorSymbol(checker: ts.TypeChecker, calleeExpr: ts.Expression): ts.Symbol | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* #2660 PART-1 — resolve the WasmGC struct a member-access RECEIVER expression
|
|
67
|
+
* concretely is, for the dynamic read/write/compound dispatch to PIN to.
|
|
68
|
+
*
|
|
69
|
+
* Resolution order (the consumer pins to the first hit; a miss ⇒ dynamic path):
|
|
70
|
+
* 1. `this` receiver → `fctx.thisStructName` (the #2681 syntactic prototype
|
|
71
|
+
* resolver's result, populated by the PART-2 dispatch slice);
|
|
72
|
+
* 2. a local receiver in the {@link FnctorEscapeGateResult.receiverStruct} flow
|
|
73
|
+
* map (bound from a single-return-inferable fnctor call);
|
|
74
|
+
* 3. otherwise `undefined` → the consumer keeps its existing dynamic
|
|
75
|
+
* (`__extern_get` / open-scan) lowering.
|
|
76
|
+
*
|
|
77
|
+
* **Conservative-closed**: a returned name is additionally gated on
|
|
78
|
+
* `ctx.structMap.has(name)`, so a struct not (yet) registered at the call site
|
|
79
|
+
* yields `undefined` rather than a dangling pin — a miss NEVER produces a wrong
|
|
80
|
+
* struct. **INERT in PART-1**: exported for the PART-2 dispatch to consume; no
|
|
81
|
+
* lowering calls it yet, so emitted Wasm is byte-identical.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveReceiverStruct(ctx: CodegenContext, fctx: FunctionContext, recvExpr: ts.Expression): string | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* #2660 S1 — classify every `new F()` fnctor site in the program.
|
|
86
|
+
*
|
|
87
|
+
* @param checker the program type checker
|
|
88
|
+
* @param sourceFile the (already import-preprocessed) module source
|
|
89
|
+
* @returns a frozen {@link FnctorEscapeGateResult}; empty when no fnctor `new`
|
|
90
|
+
* sites exist (so the pass is a no-op for class-only / fnctor-free code).
|
|
91
|
+
*/
|
|
92
|
+
export declare function analyzeFnctorEscapeGate(checker: ts.TypeChecker, sourceFile: ts.SourceFile): FnctorEscapeGateResult;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { WasmFunction } from '../ir/types.js';
|
|
3
|
+
import { CodegenContext } from './context/types.js';
|
|
4
|
+
/** Maximum number of instructions for a function body to be considered inlinable */
|
|
5
|
+
export declare const INLINE_MAX_INSTRS = 10;
|
|
6
|
+
/** Set of instruction ops that disqualify a function body from inlining */
|
|
7
|
+
export declare const INLINE_DISALLOWED_OPS: Set<string>;
|
|
8
|
+
/**
|
|
9
|
+
* #1120: Detect locals that should be allocated as `i32` instead of `f64`
|
|
10
|
+
* because every value flowing through them is constrained to a 32-bit
|
|
11
|
+
* signed integer by explicit `| 0` (or other bitwise) coercion.
|
|
12
|
+
*
|
|
13
|
+
* The classic pattern, from the iterative Fibonacci benchmark, is:
|
|
14
|
+
*
|
|
15
|
+
* let a = 0;
|
|
16
|
+
* let b = 1;
|
|
17
|
+
* for (let i = 0; i < n; i++) {
|
|
18
|
+
* const next = (a + b) | 0; // every write is ToInt32-coerced
|
|
19
|
+
* a = b;
|
|
20
|
+
* b = next;
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* Each of `a`, `b`, and `next` only ever holds an int32, so allocating
|
|
24
|
+
* them as f64 forces the compiler into a heavy `f64 -> ToInt32 -> f64`
|
|
25
|
+
* round-trip on every iteration. By proving they are i32 we let the
|
|
26
|
+
* binary-op layer collapse the loop body to native i32 arithmetic.
|
|
27
|
+
*
|
|
28
|
+
* Detection rules (conservative; any rule failing leaves the local as f64):
|
|
29
|
+
* 1. Declared via `let` or `const` (not `var`, not module-global, not param).
|
|
30
|
+
* 2. Initializer is i32-safe (see `isI32SafeExpr`).
|
|
31
|
+
* 3. Every assignment / compound-assignment / increment/decrement to the
|
|
32
|
+
* local also produces an i32-safe value.
|
|
33
|
+
*
|
|
34
|
+
* The set is fixpoint-iterated because membership of one local can depend
|
|
35
|
+
* on membership of another (e.g. `a = b; b = next;` requires all three
|
|
36
|
+
* to reach the i32 set together).
|
|
37
|
+
*/
|
|
38
|
+
export declare function collectI32CoercedLocals(decl: ts.FunctionLikeDeclaration): Set<string>;
|
|
39
|
+
/**
|
|
40
|
+
* After compiling a function, check if it is eligible for call-site inlining.
|
|
41
|
+
* Criteria:
|
|
42
|
+
* - Body has <= INLINE_MAX_INSTRS instructions
|
|
43
|
+
* - No control flow, calls, or local mutations
|
|
44
|
+
* - No extra locals beyond parameters
|
|
45
|
+
* - Not a rest-param or capture function
|
|
46
|
+
*/
|
|
47
|
+
export declare function registerInlinableFunction(ctx: CodegenContext, funcName: string, func: WasmFunction): void;
|
|
48
|
+
export declare function compileFunctionBody(ctx: CodegenContext, decl: ts.FunctionDeclaration, func: WasmFunction): void;
|
|
49
|
+
/**
|
|
50
|
+
* Build throw instructions for TypeError when destructuring null/undefined.
|
|
51
|
+
* Per JS spec, destructuring null/undefined must throw TypeError.
|
|
52
|
+
*/
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { ValType } from '../ir/types.js';
|
|
3
|
+
import { CodegenContext, FunctionContext, NativeGeneratorInfo } from './context/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* (#2571) A native-generator candidate is either a named `function*`
|
|
6
|
+
* declaration or a class / object-literal generator METHOD. Both expose
|
|
7
|
+
* `.body` / `.parameters` / `.asteriskToken` / `.name`, so the plan builder and
|
|
8
|
+
* the state model treat them uniformly; the only method-specific handling is the
|
|
9
|
+
* synthetic `this` leading param (threaded in `registerNativeGenerator`).
|
|
10
|
+
*/
|
|
11
|
+
export type GeneratorDecl = ts.FunctionDeclaration | ts.MethodDeclaration;
|
|
12
|
+
export declare function isNativeGeneratorCandidate(ctx: CodegenContext, decl: GeneratorDecl): boolean;
|
|
13
|
+
export declare function sourceNeedsGeneratorHostImports(ctx: CodegenContext, sourceFile: ts.SourceFile): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Result struct (`{ value, done }`) for a generator whose yields have the given
|
|
16
|
+
* `elemValType`. The numeric (f64) variant is cached on
|
|
17
|
+
* `ctx.nativeGeneratorResultTypeIdx` (the historical singleton, kept so the many
|
|
18
|
+
* f64 callers are unchanged); any other elem type (e.g. the native string ref,
|
|
19
|
+
* #2171) gets its own `__NativeGeneratorResult_<kind>` struct, cached in
|
|
20
|
+
* `structMap` by name. Defaults to f64 when no elem type is supplied.
|
|
21
|
+
*/
|
|
22
|
+
export declare function ensureNativeGeneratorResultType(ctx: CodegenContext, elemValType?: ValType): number;
|
|
23
|
+
export declare function registerNativeGenerator(ctx: CodegenContext, decl: GeneratorDecl, functionName: string, paramTypes: ValType[], synthesizedThis?: boolean): NativeGeneratorInfo | null;
|
|
24
|
+
export declare function ensureNativeGeneratorResumeFunction(ctx: CodegenContext, info: NativeGeneratorInfo): number;
|
|
25
|
+
export declare function compileNativeGeneratorFunction(ctx: CodegenContext, fctx: FunctionContext, decl: GeneratorDecl, info: NativeGeneratorInfo): void;
|
|
26
|
+
export declare function tryCompileNativeGeneratorMethodCall(ctx: CodegenContext, fctx: FunctionContext, receiverExpr: ts.Expression, methodName: string, args: readonly ts.Expression[]): ValType | null | undefined;
|
|
27
|
+
export declare function tryCompileNativeGeneratorResultProperty(ctx: CodegenContext, fctx: FunctionContext, resultExpr: ts.Expression, propName: string): ValType | null | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Look up a native-generator info by the **TS type** of a for-of subject
|
|
30
|
+
* expression, mapping the resolved wasm state struct typeIdx back to its
|
|
31
|
+
* NativeGeneratorInfo. Returns undefined when the subject is not a native
|
|
32
|
+
* generator value.
|
|
33
|
+
*/
|
|
34
|
+
export declare function nativeGeneratorInfoForForOfSubject(ctx: CodegenContext, subjectType: ValType): NativeGeneratorInfo | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* #1665 — drive a `for (… of gen())` loop over a Wasm-native generator state
|
|
37
|
+
* machine WITHOUT the JS-host iterator protocol. The generator state ref is
|
|
38
|
+
* expected to already be on the stack (the caller compiled the iterable
|
|
39
|
+
* expression); `subjectType` is its ValType.
|
|
40
|
+
*
|
|
41
|
+
* Emits, structurally identical to the host iterator loop but calling the
|
|
42
|
+
* generator's resume function directly:
|
|
43
|
+
*
|
|
44
|
+
* iter = <subject>
|
|
45
|
+
* block:
|
|
46
|
+
* loop:
|
|
47
|
+
* res = __gen_resume_<g>(iter) ;; ref $result {value:f64, done:i32}
|
|
48
|
+
* if (res.done) br block
|
|
49
|
+
* elem = res.value ;; f64 (or coerced to elem decl type)
|
|
50
|
+
* <body>
|
|
51
|
+
* br loop
|
|
52
|
+
*
|
|
53
|
+
* Only numeric (f64) yields are supported by the existing native generator
|
|
54
|
+
* (`isNativeGeneratorCandidate`), so the loop variable is f64. Returns true on
|
|
55
|
+
* success; false (with the stack untouched-by-contract: caller resets) when the
|
|
56
|
+
* shape is unsupported so the caller can fall back.
|
|
57
|
+
*/
|
|
58
|
+
export declare function tryCompileNativeGeneratorForOf(ctx: CodegenContext, fctx: FunctionContext, stmt: ts.ForOfStatement, subjectType: ValType, info: NativeGeneratorInfo): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* #2169 — materialize a Wasm-native generator into a `__vec` of f64 by driving
|
|
61
|
+
* its resume function to completion, WITHOUT the JS-host iterator protocol.
|
|
62
|
+
*
|
|
63
|
+
* The non-`for-of` iterator consumers (array spread `[...g()]`, `Array.from(g())`,
|
|
64
|
+
* array-destructuring `[a,b]=g()`) previously treated the generator's state
|
|
65
|
+
* struct as if it were a `__vec` (reading field 0 as a `$length`), producing a
|
|
66
|
+
* garbage-length array of defaults / leaking host imports. This helper gives
|
|
67
|
+
* them the same `next()`-until-`done` drain the for-of driver uses, but
|
|
68
|
+
* collects the values into a growable backing array and leaves a freshly
|
|
69
|
+
* constructed `ref $vec_f64` on the stack (so the caller can treat it as a
|
|
70
|
+
* normal materialized vec).
|
|
71
|
+
*
|
|
72
|
+
* Contract: the generator state ref (`subjectType`, a ref/ref_null to the
|
|
73
|
+
* `info.stateTypeIdx` struct) MUST already be on the stack. On return the stack
|
|
74
|
+
* top is `(ref <vecTypeIdx>)` of element type f64. Numeric yields only (native
|
|
75
|
+
* generators are numeric today; non-numeric is #2171 / SF-4).
|
|
76
|
+
*
|
|
77
|
+
* The vec struct layout matches `getVecInfo`: field 0 = `$length` (i32),
|
|
78
|
+
* field 1 = `$data` (ref $arr). `vecTypeIdx`/`arrTypeIdx` are supplied by the
|
|
79
|
+
* caller (an f64 vec from `getOrRegisterVecType`).
|
|
80
|
+
*
|
|
81
|
+
* `trimToLength` (#2169 destructure consumer): when true, the backing array is
|
|
82
|
+
* resized to EXACTLY `len` before the final `struct.new`, so `array.len(data)`
|
|
83
|
+
* equals the logical `$length`. The default (false) leaves the capacity-padded
|
|
84
|
+
* array in place — fine for consumers that read the `$length` field (spread,
|
|
85
|
+
* Array.from), but the array-destructuring path bounds-checks against
|
|
86
|
+
* `array.len(data)` (`emitBoundsCheckedArrayGet`), so a capacity-padded array
|
|
87
|
+
* would make an out-of-length index read a default-initialized `0.0` slot
|
|
88
|
+
* instead of being OOB, silently skipping binding defaults (`const [a,b=9]=g()`
|
|
89
|
+
* with one yield). Trimming restores the literal-array invariant the destructure
|
|
90
|
+
* machinery relies on (backing-array length == logical length).
|
|
91
|
+
*/
|
|
92
|
+
export declare function emitNativeGeneratorToVec(ctx: CodegenContext, fctx: FunctionContext, info: NativeGeneratorInfo, subjectType: ValType, vecTypeIdx: number, arrTypeIdx: number, trimToLength?: boolean): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ts } from '../../ts-api.js';
|
|
2
|
+
/**
|
|
3
|
+
* #2152 — Check whether a node tree references `this` in its OWN function scope.
|
|
4
|
+
*
|
|
5
|
+
* A non-arrow `function` / method / accessor / constructor / class rebinds
|
|
6
|
+
* `this`, so a `this` inside such a nested scope is unrelated to the function
|
|
7
|
+
* whose body we are scanning — we do NOT descend into those. Arrow functions
|
|
8
|
+
* are lexically `this`-bound, so a `this` inside a nested arrow DOES refer to
|
|
9
|
+
* the enclosing function's `this` and counts — we traverse into arrows.
|
|
10
|
+
*
|
|
11
|
+
* Used to decide whether a (nested or top-level) function declaration body
|
|
12
|
+
* should read the `__current_this` module global for `this` (#1636-S1 / #1702):
|
|
13
|
+
* when such a function is passed by reference as an array-HOF callback
|
|
14
|
+
* (`arr.filter(callbackfn, thisArg)`), the dispatcher installs the spec
|
|
15
|
+
* `thisArg` into `__current_this` before the `call_ref`. For direct calls the
|
|
16
|
+
* global is null and the null-guarded read falls back to `undefined`, so
|
|
17
|
+
* enabling the read is behavior-preserving for ordinary calls.
|
|
18
|
+
*
|
|
19
|
+
* Iterative DFS to avoid stack overflow on deep ASTs (CI cgroup limits,
|
|
20
|
+
* mirrors `bodyUsesArguments`), memoized so overlapping subtrees stay O(N).
|
|
21
|
+
*/
|
|
22
|
+
export declare function bodyReferencesOwnThis(node: ts.Node): boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ts } from '../../ts-api.js';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a node tree references the `arguments` identifier.
|
|
4
|
+
* Skips nested function declarations and function expressions (which have
|
|
5
|
+
* their own `arguments` binding), but traverses into arrow functions
|
|
6
|
+
* because arrows inherit the enclosing function's `arguments`.
|
|
7
|
+
*
|
|
8
|
+
* Uses iterative DFS to avoid stack overflow on deeply nested ASTs
|
|
9
|
+
* (CI cgroup limits, #1085). Results are memoized so repeated calls on
|
|
10
|
+
* overlapping subtrees collapse from O(N²) to O(N) total (#1086).
|
|
11
|
+
*/
|
|
12
|
+
export declare function bodyUsesArguments(node: ts.Node): boolean;
|