@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,35 @@
|
|
|
1
|
+
import { CodegenContext } from './context/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Emit `__json_quote_string(s: externref) -> externref` and register it in
|
|
4
|
+
* `ctx.funcMap`. Idempotent. Must run after `ensureNativeStringHelpers` (called
|
|
5
|
+
* here) so `__str_flatten` exists, and before any function body that calls it.
|
|
6
|
+
*
|
|
7
|
+
* Algorithm: flatten the input to a `$NativeString`, walk its `[off, off+len)`
|
|
8
|
+
* code units twice — first to size the output buffer, then to fill it — so the
|
|
9
|
+
* output `$__str_data` is allocated exactly once at the right capacity.
|
|
10
|
+
*/
|
|
11
|
+
export declare function emitJsonQuoteString(ctx: CodegenContext): number;
|
|
12
|
+
/**
|
|
13
|
+
* Emit `__json_parse_primitive(s: externref) -> ref $AnyValue` and register it
|
|
14
|
+
* in `ctx.funcMap`. Idempotent. Parses a runtime string holding a single JSON
|
|
15
|
+
* primitive (number / `true` / `false` / `null`) entirely in Wasm — no
|
|
16
|
+
* `env::JSON_parse` host import — and boxes the result into the host-free
|
|
17
|
+
* `$AnyValue` tagged union (#1599 Phase 2):
|
|
18
|
+
*
|
|
19
|
+
* - `"null"` → tag 0 (null)
|
|
20
|
+
* - `"true"` / `"false"` → tag 4 (boolean), i32val 1 / 0
|
|
21
|
+
* - JSON number → tag 3 (f64), f64val = parsed value
|
|
22
|
+
* - anything else → `unreachable` (Wasm trap; matches a SyntaxError
|
|
23
|
+
* throw under the standalone no-host contract)
|
|
24
|
+
*
|
|
25
|
+
* The caller (`tryEmitJsonParsePrimitive` in expressions/calls.ts) gates this
|
|
26
|
+
* on `ctx.standalone || ctx.wasi` and a string-typed argument, and returns the
|
|
27
|
+
* `ref $AnyValue` type so the existing AnyValue→primitive coercion path in
|
|
28
|
+
* type-coercion.ts unboxes it to number / boolean as the consumer requires.
|
|
29
|
+
*
|
|
30
|
+
* Must run after `ensureNativeStringHelpers` (called here) so `__str_flatten`
|
|
31
|
+
* exists, and before any function body that calls it.
|
|
32
|
+
*
|
|
33
|
+
* Spec: ECMA-262 §25.5.2 `JSON.parse` / `ParseJSON`, ECMA-404 JSON grammar.
|
|
34
|
+
*/
|
|
35
|
+
export declare function emitJsonParsePrimitive(ctx: CodegenContext): number;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { ValType } from '../ir/types.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* #2166 — resolve a `JSON.stringify` `space` argument (3rd parameter) to a
|
|
6
|
+
* compile-time number or string, so the static stringify path can produce the
|
|
7
|
+
* indented form. Returns `undefined` when the value isn't statically known
|
|
8
|
+
* (caller then refuses / keeps the compact form gate). Per §25.5.2 only the
|
|
9
|
+
* first 10 characters of a string space (or `min(10, floor(n))` for a number)
|
|
10
|
+
* are used; JS's own `JSON.stringify` applies that, so we just forward.
|
|
11
|
+
*/
|
|
12
|
+
export declare function staticSpaceValue(ctx: CodegenContext, expr: ts.Expression): number | string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* (#2166 PR-B) Resolve a static `space` argument to the per-level indent unit
|
|
15
|
+
* string (the "gap") per §25.5.2 step 6: a Number → `min(10, floor(n))` spaces
|
|
16
|
+
* (≤0 / NaN → ""); a String → its first 10 code units. Returns `""` for any
|
|
17
|
+
* gap that produces no indentation (the dynamic-graph codec then serialises
|
|
18
|
+
* compactly). The caller passes the gap to `__json_stringify_root_indent`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function jsonGapFromStaticSpace(space: number | string): string;
|
|
21
|
+
export declare function isJsonParseCall(expr: ts.Expression): expr is ts.CallExpression;
|
|
22
|
+
export declare function tryEmitJsonStringifyStatic(ctx: CodegenContext, fctx: FunctionContext, arg: ts.Expression, replacerArg?: ts.Expression, spaceArg?: ts.Expression): ValType | null | undefined;
|
|
23
|
+
export declare function tryEmitJsonParseLiteral(ctx: CodegenContext, fctx: FunctionContext, call: ts.CallExpression): ValType | null | undefined;
|
|
24
|
+
export declare function tryEmitJsonParsePropertyAccess(ctx: CodegenContext, fctx: FunctionContext, expr: ts.PropertyAccessExpression): ValType | null | undefined;
|
|
25
|
+
export declare function tryEmitJsonParseElementAccess(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ElementAccessExpression): ValType | null | undefined;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
/** Result of the linear-safe `Uint8Array` analysis (frozen before codegen). */
|
|
3
|
+
export interface LinearUint8Result {
|
|
4
|
+
/**
|
|
5
|
+
* Symbols of every binding (local variable or parameter) proven linear-safe.
|
|
6
|
+
* Codegen consults this by `checker.getSymbolAtLocation(idNode)`.
|
|
7
|
+
*/
|
|
8
|
+
safeBindings: Set<ts.Symbol>;
|
|
9
|
+
/**
|
|
10
|
+
* For each function whose signature is linear-rewritten, the set of
|
|
11
|
+
* parameter indices that are linear-backed. Keyed by the function's own
|
|
12
|
+
* symbol. Callers use this to lower call arguments to `(ptr, len)` pairs and
|
|
13
|
+
* to rewrite the callee's wasm param list.
|
|
14
|
+
*/
|
|
15
|
+
linearParams: Map<ts.Symbol, Set<number>>;
|
|
16
|
+
/**
|
|
17
|
+
* The **Slice-B-eligible** subset of {@link safeBindings}: a `new
|
|
18
|
+
* Uint8Array(...)` *local* whose every use stays inside its declaring
|
|
19
|
+
* function — element load/store, `.length`, and `process.std*.{read,write}`
|
|
20
|
+
* I/O only — and which is **never** passed as an argument to a user function
|
|
21
|
+
* (nor is itself a parameter). These can be backed by linear memory
|
|
22
|
+
* intraprocedurally with no call-site or signature changes.
|
|
23
|
+
*
|
|
24
|
+
* A buffer that flows through a user-function parameter is in `safeBindings`
|
|
25
|
+
* + `linearParams` (the Slice-C interprocedural signature-rewrite targets)
|
|
26
|
+
* but is deliberately **excluded** here: backing it linearly without the
|
|
27
|
+
* C-phase signature rewrite would hand a `(ptr,len)` local to a callee that
|
|
28
|
+
* still expects a GC array, an invalid-Wasm type mismatch. Slice B consumes
|
|
29
|
+
* this set; Slice C will widen consumption to all of `safeBindings`.
|
|
30
|
+
*/
|
|
31
|
+
localOnlyBindings: Set<ts.Symbol>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build the linear-safe analysis for a WASI source file.
|
|
35
|
+
*
|
|
36
|
+
* Algorithm (monotone, terminates — classifications only ever demote):
|
|
37
|
+
* 1. Collect every candidate binding: `new Uint8Array(...)` variable inits and
|
|
38
|
+
* `Uint8Array` parameters of non-exported user functions. Exported
|
|
39
|
+
* functions' params are NOT candidates (their ABI is observable).
|
|
40
|
+
* 2. Seed every candidate as linear-safe.
|
|
41
|
+
* 3. Fixpoint: walk each function body. A candidate binding/param is demoted
|
|
42
|
+
* if it has any disqualifying use, OR is passed to a callee parameter that
|
|
43
|
+
* is currently demoted. Repeat until no demotions occur in a full pass.
|
|
44
|
+
* 4. Freeze: the survivors are the linear-safe set.
|
|
45
|
+
*/
|
|
46
|
+
export declare function analyzeLinearUint8(checker: ts.TypeChecker, sourceFile: ts.SourceFile, nodeFsSyncNames?: ReadonlySet<string>): LinearUint8Result;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Instr } from '../ir/types.js';
|
|
2
|
+
import { ts } from '../ts-api.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
4
|
+
export declare function containsLinearU8Allocation(ctx: CodegenContext, node: ts.Node | undefined): boolean;
|
|
5
|
+
export declare function emitLinearU8ArenaMark(ctx: CodegenContext, fctx: FunctionContext, name?: string): number | undefined;
|
|
6
|
+
export declare function linearU8ArenaResetInstrs(ctx: CodegenContext, markLocalIdx: number | undefined): Instr[];
|
|
7
|
+
export declare function emitLinearU8ArenaReset(ctx: CodegenContext, fctx: FunctionContext, markLocalIdx: number | undefined): void;
|
|
@@ -0,0 +1,103 @@
|
|
|
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
|
+
/**
|
|
6
|
+
* True when this `Uint8Array` binding is proven linear-safe by the #1886
|
|
7
|
+
* analysis. Slice C rewrites matching function params to `(ptr,len)`, so the
|
|
8
|
+
* codegen can consume the full safe set rather than Slice B's local-only
|
|
9
|
+
* subset. Returns false outside WASI or when the analysis did not run.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isLinearSafeBinding(ctx: CodegenContext, node: ts.Node): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* `new Uint8Array(n)` / `new Uint8Array([a,b,…])` for a linear-safe local being
|
|
14
|
+
* declared as `nameNode`. Allocates `(ptr, len)` i32 locals, calls
|
|
15
|
+
* `__lin_u8_alloc(n)`, and (for the array-literal form) stores the literal
|
|
16
|
+
* bytes. Registers the buffer in `fctx.linearU8Buffers` and leaves NOTHING on
|
|
17
|
+
* the value stack (the binding lives in the two i32 locals). Returns true if it
|
|
18
|
+
* handled the `new`; false to fall through to the GC path.
|
|
19
|
+
*
|
|
20
|
+
* Caller contract: invoked from the variable-declaration lowering for a
|
|
21
|
+
* `const/let x = new Uint8Array(...)` where `isLocalLinearNewBinding(x)` holds.
|
|
22
|
+
*/
|
|
23
|
+
export declare function tryEmitLinearU8New(ctx: CodegenContext, fctx: FunctionContext, nameNode: ts.Identifier, newExpr: ts.NewExpression): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* `b[i]` read for a linear-backed buffer → `i32.load8_u (ptr + trunc(i))`,
|
|
26
|
+
* widened to f64 to match the observable element value type the GC path
|
|
27
|
+
* returns. Returns the result ValType, or `null` if `b` is not linear-backed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function tryEmitLinearU8ElementGet(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ElementAccessExpression): ValType | null;
|
|
30
|
+
/**
|
|
31
|
+
* `b[i] = v` for a linear-backed buffer → `i32.store8 (ptr + trunc(i)),
|
|
32
|
+
* trunc(v) & 0xff`, leaving **nothing** on the stack and returning
|
|
33
|
+
* `VOID_RESULT`. Returns `null` if `b` is not a linear-backed buffer (caller
|
|
34
|
+
* falls through to GC).
|
|
35
|
+
*
|
|
36
|
+
* The assignment compiles as a statement (the common case — e.g. the
|
|
37
|
+
* native-messaging frame builder writes `buf[i] = (buf[i] + 1) & 255`). Unlike
|
|
38
|
+
* the GC `array.set` path, this does NOT push the assigned value as the
|
|
39
|
+
* expression result: `x = buf[i] = v` value-of-assignment is not yet supported
|
|
40
|
+
* for linear-backed buffers (out of scope for the I/O-buffer workloads this
|
|
41
|
+
* targets — the analysis only admits buffers that never appear as a bare
|
|
42
|
+
* identifier). See the `return VOID_RESULT` note below for why pushing the value
|
|
43
|
+
* broke void-function completion.
|
|
44
|
+
*
|
|
45
|
+
* Evaluation order matches JS + the GC path: index expression first, then the
|
|
46
|
+
* value expression, then the store.
|
|
47
|
+
*/
|
|
48
|
+
export declare function tryEmitLinearU8ElementSet(ctx: CodegenContext, fctx: FunctionContext, target: ts.ElementAccessExpression, valueExpr: ts.Expression): InnerResult;
|
|
49
|
+
/**
|
|
50
|
+
* #2045 C.8 — compound element write `b[i] op= rhs` (`+=`, `++`, `--`, …) for a
|
|
51
|
+
* linear-backed buffer → read-modify-write at a single computed address.
|
|
52
|
+
*
|
|
53
|
+
* Without this, `compileElementCompoundAssignment` compiled the buffer
|
|
54
|
+
* expression as a value (materialising the GC representation) and wrote the
|
|
55
|
+
* result back through the externref/GC path — which never touched the linear
|
|
56
|
+
* memory, so `b[0] += 1` silently kept the old byte (read 5, computed 6, stored
|
|
57
|
+
* nowhere). This emits the same `i32.load8_u` read and `i32.store8` write as the
|
|
58
|
+
* plain get/set, sharing one `addr = ptr + trunc(i)` so the index is evaluated
|
|
59
|
+
* once and the read and write hit the same byte.
|
|
60
|
+
*
|
|
61
|
+
* `emitOp` is invoked with the current element value already on the stack as
|
|
62
|
+
* f64; it must push the rhs and emit the compound operator, leaving the result
|
|
63
|
+
* f64 on the stack (the caller passes a closure over `emitCompoundOp` + the rhs
|
|
64
|
+
* expression to avoid an assignment.ts↔linear-uint8-codegen.ts import cycle).
|
|
65
|
+
*
|
|
66
|
+
* Leaves the **assigned f64 value** on the stack and returns `{kind:"f64"}` so
|
|
67
|
+
* `b[i] op= rhs` works in both statement and expression position (matching the
|
|
68
|
+
* GC/externref compound paths, which also push the result). Note the value is
|
|
69
|
+
* the full f64 result, not the truncated stored byte — same as the GC array
|
|
70
|
+
* path's compound result. Returns `null` if `b` is not a linear-backed buffer.
|
|
71
|
+
*/
|
|
72
|
+
export declare function tryEmitLinearU8ElementCompound(ctx: CodegenContext, fctx: FunctionContext, target: ts.ElementAccessExpression, emitOp: () => void): ValType | null;
|
|
73
|
+
/**
|
|
74
|
+
* #2045 C.8 — prefix/postfix `++`/`--` on a linear-backed element
|
|
75
|
+
* (`b[i]++`, `++b[i]`, `b[i]--`, `--b[i]`) → read-modify-write at one address.
|
|
76
|
+
*
|
|
77
|
+
* The generic prefix/postfix element handlers begin with
|
|
78
|
+
* `compileExpression(target.expression)` and require a `ref`/`ref_null` array —
|
|
79
|
+
* a linear buffer is a `(ptr,len)` pair, so they error/throw. This emits the
|
|
80
|
+
* linear read-modify-write directly: load `b[i]`, add/sub 1, store the low byte,
|
|
81
|
+
* and leave the **old** value (postfix) or the **new** value (prefix) on the
|
|
82
|
+
* stack as f64 — matching JS update-expression semantics. Returns `null` if `b`
|
|
83
|
+
* is not a linear-backed buffer (caller falls through to the GC handlers).
|
|
84
|
+
*/
|
|
85
|
+
export declare function tryEmitLinearU8ElementUpdate(ctx: CodegenContext, fctx: FunctionContext, target: ts.ElementAccessExpression, isIncrement: boolean, isPrefix: boolean): ValType | null;
|
|
86
|
+
/** `b.length` for a linear-backed buffer → `len` widened to f64. */
|
|
87
|
+
export declare function tryEmitLinearU8Length(ctx: CodegenContext, fctx: FunctionContext, expr: ts.PropertyAccessExpression): ValType | null;
|
|
88
|
+
/** Accessor used by the WASI I/O intrinsics to get a buffer's (ptr, len) locals. */
|
|
89
|
+
export declare function getLinearU8Buffer(ctx: CodegenContext, fctx: FunctionContext, node: ts.Node): {
|
|
90
|
+
ptrLocalIdx: number;
|
|
91
|
+
lenLocalIdx: number;
|
|
92
|
+
} | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Zero-copy `process.stdout/stderr.write(buf)` for a linear-backed buffer.
|
|
95
|
+
* `fd_write` reads straight from `ptr` for `len` bytes — no GC→linear staging
|
|
96
|
+
* copy. Returns `true` if handled (and leaves the i32 `1` write-result on the
|
|
97
|
+
* stack, matching the GC write path), `false` if `buf` is not linear-backed.
|
|
98
|
+
*
|
|
99
|
+
* `writeSinkIdx` is the func to call: `node:fs::writeSync(fd,ptr,len)` under the
|
|
100
|
+
* node shims, or `wasi_snapshot_preview1.fd_write` inline. `fd` is 1 (stdout) or
|
|
101
|
+
* 2 (stderr).
|
|
102
|
+
*/
|
|
103
|
+
export declare function tryEmitLinearU8StdWrite(ctx: CodegenContext, fctx: FunctionContext, bufArg: ts.Expression, writeSinkIdx: number, fd: number): boolean;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { ValType } from '../ir/types.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
4
|
+
type FnDecl = ts.FunctionDeclaration | ts.FunctionExpression | ts.ArrowFunction | ts.MethodDeclaration;
|
|
5
|
+
export declare function isLinearU8SafeBinding(ctx: CodegenContext, node: ts.Node): boolean;
|
|
6
|
+
export declare function isLinearU8LocalOnlyBinding(ctx: CodegenContext, node: ts.Node): boolean;
|
|
7
|
+
export declare function isLinearU8RepresentableNew(ctx: CodegenContext, newExpr: ts.NewExpression): boolean;
|
|
8
|
+
export declare function getLinearU8ParamIndicesForDeclaration(ctx: CodegenContext, decl: FnDecl): Set<number> | undefined;
|
|
9
|
+
export declare function getLinearU8ParamIndicesForCall(ctx: CodegenContext, call: ts.CallExpression): Set<number> | undefined;
|
|
10
|
+
export declare function functionHasLinearU8Params(ctx: CodegenContext, name: string): boolean;
|
|
11
|
+
export declare function expandLinearU8ParamTypes(ctx: CodegenContext, decl: FnDecl, sourceParamTypes: ValType[]): ValType[];
|
|
12
|
+
export declare function wasmParamIndexForSourceParam(sourceIndex: number, linearParams: Set<number> | undefined, leadingParams?: number): number;
|
|
13
|
+
export declare function sourceParamCountFromExpanded(wasmParamCount: number, linearParams: Set<number> | undefined, leadingParams?: number): number;
|
|
14
|
+
/**
|
|
15
|
+
* #2045: look up a linear-backed buffer by the binding's `ts.Symbol`, resolved
|
|
16
|
+
* from the identifier `node`. Symbol identity is scope-correct, so a param
|
|
17
|
+
* `buf` and an inner-block `const buf` (distinct symbols, same text) no longer
|
|
18
|
+
* collide — the previous name-keyed map addressed whichever was registered last
|
|
19
|
+
* in both shadowing directions (silent corruption).
|
|
20
|
+
*/
|
|
21
|
+
export declare function getLinearU8Buffer(ctx: CodegenContext, fctx: FunctionContext, node: ts.Node): {
|
|
22
|
+
ptrLocalIdx: number;
|
|
23
|
+
lenLocalIdx: number;
|
|
24
|
+
} | undefined;
|
|
25
|
+
export declare function registerLinearU8Buffer(fctx: FunctionContext, sym: ts.Symbol, ptrLocalIdx: number, lenLocalIdx: number): void;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { default as ts } from 'typescript';
|
|
2
|
+
import { ValType } from '../ir/types.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Ensure that a struct registered for an object literal includes fields for
|
|
6
|
+
* computed property names that TypeScript cannot statically resolve.
|
|
7
|
+
* When TS returns 0 properties (e.g. { [1+1]: 2 }), we resolve the computed
|
|
8
|
+
* keys at compile time and create proper struct fields.
|
|
9
|
+
*/
|
|
10
|
+
export declare function ensureComputedPropertyFields(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ObjectLiteralExpression, tsType: ts.Type): void;
|
|
11
|
+
/**
|
|
12
|
+
* Last-resort fallback: compile an object literal as an externref plain object via host imports.
|
|
13
|
+
* Used when the TS type can't be mapped to a WasmGC struct (e.g., `{...null}`, `{...yield}`,
|
|
14
|
+
* or bundled JS objects with types too wide for struct inference).
|
|
15
|
+
*
|
|
16
|
+
* Creates a new plain object via __new_plain_object, then:
|
|
17
|
+
* - For spread assignments: calls __object_assign(target, source) to copy properties
|
|
18
|
+
* - For regular properties: calls __set_prop(target, key, value)
|
|
19
|
+
*
|
|
20
|
+
* Returns externref, or null if the host import is unavailable.
|
|
21
|
+
*/
|
|
22
|
+
export declare function compileObjectLiteralAsExternref(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ObjectLiteralExpression): ValType | null;
|
|
23
|
+
/**
|
|
24
|
+
* (#2358) Reify a NOMINAL object struct (its ref already on the Wasm stack) into
|
|
25
|
+
* a dynamic `$Object` externref, copying each field as an own-property — so the
|
|
26
|
+
* native `__to_primitive` helper (which recognises only `$Object` via
|
|
27
|
+
* `ref.test objectTypeIdx`) can reduce a typed object that has crossed the
|
|
28
|
+
* externref boundary as an `any` value (e.g. an any-typed parameter, where the
|
|
29
|
+
* concrete typeIdx is erased inside the callee). The struct-instance analogue of
|
|
30
|
+
* `compileObjectLiteralAsExternref` (which builds the same `$Object` from AST
|
|
31
|
+
* props): both go through `__new_plain_object` + `__extern_set`, so the resulting
|
|
32
|
+
* object is read by the exact same native helpers.
|
|
33
|
+
*
|
|
34
|
+
* Returns true on success (struct consumed, `$Object` externref left on the
|
|
35
|
+
* stack); false if it declined (nothing emitted — caller must fall back to
|
|
36
|
+
* `extern.convert_any`). Declines when the struct type is unknown or the object
|
|
37
|
+
* runtime helpers are unavailable.
|
|
38
|
+
*
|
|
39
|
+
* This is a value-semantics COPY: it does not preserve nominal reference
|
|
40
|
+
* identity across the round-trip. The caller gates it to objects that carry a
|
|
41
|
+
* user ToPrimitive method (`valueOf`/`@@toPrimitive`/`toString`), for which
|
|
42
|
+
* value semantics suffice; plain data structs keep `extern.convert_any`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function materializeStructAsDynamicObject(ctx: CodegenContext, fctx: FunctionContext, structTypeIdx: number): boolean;
|
|
45
|
+
export declare function compileObjectLiteral(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ObjectLiteralExpression): ValType | null;
|
|
46
|
+
/**
|
|
47
|
+
* Try to evaluate an expression to a constant numeric or string value at compile time.
|
|
48
|
+
* Supports: numeric literals, string literals, simple arithmetic (+, -, *, /),
|
|
49
|
+
* and const variable references.
|
|
50
|
+
* Returns the resolved value (number or string) or undefined if not resolvable.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveConstantExpression(ctx: CodegenContext, expr: ts.Expression): number | string | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve the property name of an ObjectLiteralElementLike to a static string.
|
|
55
|
+
* Handles identifiers, string literals, and computed property names that can be
|
|
56
|
+
* evaluated at compile time (string literal expressions, const variables, enum members).
|
|
57
|
+
* Returns undefined if the name cannot be statically resolved.
|
|
58
|
+
*/
|
|
59
|
+
export declare function resolvePropertyNameText(ctx: CodegenContext, prop: ts.ObjectLiteralElementLike): string | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Map a well-known Symbol property name (e.g. "iterator") to a reserved
|
|
62
|
+
* property key string "@@iterator" for use as struct field names.
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolveWellKnownSymbol(name: string): string | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Get the i32 constant for a well-known symbol, or undefined if not well-known.
|
|
67
|
+
*/
|
|
68
|
+
export declare function getWellKnownSymbolId(name: string): number | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Ensure the __symbol_counter mutable global exists (lazy init).
|
|
71
|
+
* Starts at 100 so well-known symbol IDs (1-12) never collide.
|
|
72
|
+
*/
|
|
73
|
+
export declare function ensureSymbolCounter(ctx: CodegenContext): number;
|
|
74
|
+
/**
|
|
75
|
+
* Compile a Symbol() call — returns a unique i32 by incrementing a global counter.
|
|
76
|
+
* The description argument (if any) is evaluated for side effects but discarded.
|
|
77
|
+
*/
|
|
78
|
+
export declare function compileSymbolCall(ctx: CodegenContext, fctx: FunctionContext, args: readonly ts.Expression[]): ValType;
|
|
79
|
+
/**
|
|
80
|
+
* Try to evaluate a computed key expression to a static string at compile time.
|
|
81
|
+
* Supports:
|
|
82
|
+
* - String literals: ["x"]
|
|
83
|
+
* - Const variable references: [key] where const key = "x"
|
|
84
|
+
* - Enum member access: [MyEnum.Key]
|
|
85
|
+
*/
|
|
86
|
+
export declare function resolveComputedKeyExpression(ctx: CodegenContext, expr: ts.Expression): string | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Resolve the property name of a getter/setter accessor to a static string.
|
|
89
|
+
* Handles identifiers, string literals, numeric literals, and computed property names.
|
|
90
|
+
*/
|
|
91
|
+
export declare function resolveAccessorPropName(ctx: CodegenContext, name: ts.PropertyName): string | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* Compile an empty object literal ({}) that has widened properties from
|
|
94
|
+
* later property assignments (e.g. `var obj = {}; obj.x = 42;`).
|
|
95
|
+
* Registers a struct type with the widened fields and emits struct.new
|
|
96
|
+
* with default values for each field.
|
|
97
|
+
*/
|
|
98
|
+
export declare function compileWidenedEmptyObject(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ObjectLiteralExpression, widenedProps: {
|
|
99
|
+
name: string;
|
|
100
|
+
type: ValType;
|
|
101
|
+
}[]): ValType | null;
|
|
102
|
+
export declare function compileObjectLiteralForStruct(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ObjectLiteralExpression, typeName: string): ValType | null;
|
|
103
|
+
/**
|
|
104
|
+
* Compile a tuple literal [a, b, c] to a Wasm GC struct.new instruction.
|
|
105
|
+
* Each element is compiled to its corresponding field type.
|
|
106
|
+
*/
|
|
107
|
+
export declare function compileTupleLiteral(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ArrayLiteralExpression, tupleType: ts.Type): ValType | null;
|
|
108
|
+
export declare function compileArrayLiteral(ctx: CodegenContext, fctx: FunctionContext, expr: ts.ArrayLiteralExpression): ValType | null;
|
|
109
|
+
/**
|
|
110
|
+
* Compile Array(n) or Array(a,b,c) function calls (non-new).
|
|
111
|
+
* Array(n) creates a sparse array of length n (all slots undefined/default).
|
|
112
|
+
* Array(a,b,c) creates [a, b, c].
|
|
113
|
+
* These have identical semantics to new Array(...).
|
|
114
|
+
*/
|
|
115
|
+
export declare function compileArrayConstructorCall(ctx: CodegenContext, fctx: FunctionContext, expr: ts.CallExpression): ValType | null;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { ts } from '../ts-api.js';
|
|
2
|
+
import { ValType } from '../ir/types.js';
|
|
3
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
4
|
+
import { InnerResult } from './shared.js';
|
|
5
|
+
/**
|
|
6
|
+
* (#2162) `$Map` / `$MapEntry` field layout, exported so the for-of entries
|
|
7
|
+
* driver (statements/loops.ts) can walk the entries vector natively without
|
|
8
|
+
* re-deriving the constants. `entries` is the `$MapEntry[]` backing array;
|
|
9
|
+
* `entryCount` is the high-water mark (live + tombstoned); a `$MapEntry` stores
|
|
10
|
+
* `key`, `value`, and a `hash` whose top bit (`tombstoneBit`) flags deletion.
|
|
11
|
+
*/
|
|
12
|
+
export declare const MAP_LAYOUT: {
|
|
13
|
+
readonly M_ENTRIES: 1;
|
|
14
|
+
readonly M_ENTRYCOUNT: 2;
|
|
15
|
+
readonly M_LIVECOUNT: 3;
|
|
16
|
+
readonly F_KEY: 0;
|
|
17
|
+
readonly F_VALUE: 1;
|
|
18
|
+
readonly F_HASH: 3;
|
|
19
|
+
readonly TOMBSTONE_BIT: 1073741824;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Register the WasmGC struct/array types backing the native Map. Idempotent.
|
|
23
|
+
* Stores the type indices on `ctx`. Mirrors `ensureWrapperTypes` /
|
|
24
|
+
* `ensureNativeStringHelpers` type-registration.
|
|
25
|
+
*/
|
|
26
|
+
export declare function ensureMapRuntimeTypes(ctx: CodegenContext): void;
|
|
27
|
+
/**
|
|
28
|
+
* Emit the full Map runtime (hash, equality, lookup, construction, methods,
|
|
29
|
+
* iterators). Idempotent. MUST run before any user body that references a Map
|
|
30
|
+
* helper, and after the native-string helpers so `__str_equals` is available
|
|
31
|
+
* (string-key equality reuses it).
|
|
32
|
+
*/
|
|
33
|
+
export declare function ensureMapHelpers(ctx: CodegenContext): void;
|
|
34
|
+
/**
|
|
35
|
+
* (#1103a) Coerce a freshly-compiled Map key/value argument to `anyref` — the
|
|
36
|
+
* uniform slot type the runtime stores. Numbers arrive as `f64` and are boxed
|
|
37
|
+
* via `__box_number` (the contract `__same_value_zero` / `__hash_anyref`
|
|
38
|
+
* assume); native strings and other GC refs are already anyref subtypes;
|
|
39
|
+
* externrefs externalize via `any.convert_extern`.
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* (#2162) Re-exported for the Set runtime, which reuses the Map backing store
|
|
43
|
+
* and needs the identical key/value → anyref boxing for its element arg.
|
|
44
|
+
*/
|
|
45
|
+
export declare function coerceSetArgToAnyref(ctx: CodegenContext, fctx: FunctionContext, t: ValType | null): void;
|
|
46
|
+
/**
|
|
47
|
+
* (#2162) Re-exported for the WeakMap/WeakSet runtime, which reuses the Map
|
|
48
|
+
* backing store and needs the identical key/value → anyref boxing.
|
|
49
|
+
*/
|
|
50
|
+
export declare function coerceMapKeyToAnyref(ctx: CodegenContext, fctx: FunctionContext, t: ValType | null): void;
|
|
51
|
+
/**
|
|
52
|
+
* (#2606 Bug A) Compile a `Set`/`Map` element/key/value argument to an anyref
|
|
53
|
+
* for the native collection helpers, handling `null`/`undefined` literals.
|
|
54
|
+
*
|
|
55
|
+
* Root cause: `compileExpression(<null/undefined literal>)` reports ValType
|
|
56
|
+
* `externref` but emits a **typed** `ref.null` instruction on the stack (a
|
|
57
|
+
* concrete bottom, not a real externref). `coerceArgToAnyref`'s `externref` arm
|
|
58
|
+
* then emits `any.convert_extern`, which fails validation — "any.convert_extern
|
|
59
|
+
* expected type externref, found ref.null of type (ref null N)" — so
|
|
60
|
+
* `s.add(null)` / `s.has(null)` / `s.has(undefined)` failed to compile
|
|
61
|
+
* standalone (#2606).
|
|
62
|
+
*
|
|
63
|
+
* Fix: for a null/undefined-literal argument, skip `compileExpression` and emit
|
|
64
|
+
* a canonical `ref.null NONE_HEAP` — the same `none`-bottom anyref-subtype the
|
|
65
|
+
* runtime already stores for absent/`undefined` entries (lines 657/912/919/1120)
|
|
66
|
+
* and for the absent-arg case above. A stored `none`-null is then `ref.eq`-equal
|
|
67
|
+
* to a queried `none`-null, so SameValueZero null/undefined equality works once
|
|
68
|
+
* the representation is uniform.
|
|
69
|
+
*/
|
|
70
|
+
export declare function compileCollectionElementArg(ctx: CodegenContext, fctx: FunctionContext, argExpr: ts.Expression | undefined): void;
|
|
71
|
+
/**
|
|
72
|
+
* (#1103a) Intercept a `Map.prototype.*` method call in standalone /
|
|
73
|
+
* `nativeStrings` mode and route it to the WasmGC-native Map runtime
|
|
74
|
+
* (`ensureMapHelpers`). Mirrors the RegExp pre-externClass interception in
|
|
75
|
+
* `expressions/calls.ts`: returns the result `InnerResult` when handled, or
|
|
76
|
+
* `undefined` to let the generic extern/host path proceed.
|
|
77
|
+
*
|
|
78
|
+
* Slice 1 covers `set` / `get` / `has` / `delete` / `clear` for number and
|
|
79
|
+
* string keys/values. `forEach` / `for-of` and `new Map(iterable)` are slice 2
|
|
80
|
+
* (need the `$MapIter` drive + `__map_new_from_arr`).
|
|
81
|
+
*
|
|
82
|
+
* Receiver and arguments are compiled here (the caller has not pushed them).
|
|
83
|
+
*/
|
|
84
|
+
export declare function tryCompileNativeMapMethodCall(ctx: CodegenContext, fctx: FunctionContext, propAccess: ts.PropertyAccessExpression, callExpr: ts.CallExpression): InnerResult | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* (#1103a) Intercept the `Map.prototype.size` accessor in standalone /
|
|
87
|
+
* `nativeStrings` mode → `__map_size` (returns i32). Receiver is compiled
|
|
88
|
+
* here. Returns the result ValType when handled, else `undefined`.
|
|
89
|
+
*/
|
|
90
|
+
export declare function tryCompileNativeMapSizeGet(ctx: CodegenContext, fctx: FunctionContext, receiver: ts.Expression): InnerResult | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* (#2162) Intercept `Map.prototype.forEach` / `Set.prototype.forEach` in
|
|
93
|
+
* standalone / `nativeStrings` mode and drive the callback over the native
|
|
94
|
+
* `$Map` backing store. Spec 24.1.3.5 / 24.2.3.6: invoke
|
|
95
|
+
* `callbackfn(value, key, collection)` for every live entry in insertion order
|
|
96
|
+
* (a Set passes the value as both `value` and `key`). The `thisArg` 2nd
|
|
97
|
+
* argument is accepted but, like the array-method native callbacks, only honored
|
|
98
|
+
* when the callback closes over `this` itself — out of scope for this slice.
|
|
99
|
+
*
|
|
100
|
+
* Reuses the entries-vector walk from `__map_iter_next` (index 0..entryCount,
|
|
101
|
+
* skipping tombstones via `F_HASH & TOMBSTONE_BIT`) and the closure-call shape
|
|
102
|
+
* from `array-methods.ts` (push coerced args, `call_ref` the closure funcref).
|
|
103
|
+
* The callback must be a Wasm closure (arrow / function expr / named fn);
|
|
104
|
+
* otherwise we bail so the generic path can try.
|
|
105
|
+
*
|
|
106
|
+
* `isSet` selects the key passed to the callback: for a Set, value === key.
|
|
107
|
+
*/
|
|
108
|
+
export declare function tryCompileNativeCollectionForEach(ctx: CodegenContext, fctx: FunctionContext, propAccess: ts.PropertyAccessExpression, callExpr: ts.CallExpression, isSet: boolean): InnerResult | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* (#2162) Compile `map.keys()` / `map.values()` / `map.entries()` (and the Set
|
|
111
|
+
* equivalents) in standalone / `nativeStrings` mode by eagerly materializing a
|
|
112
|
+
* canonical externref `$Vec` of the requested projection — mirroring the array
|
|
113
|
+
* iterator pattern (`compileNativeArrayIterator`, array-methods.ts). The vec is
|
|
114
|
+
* returned as a `ref $Vec`, so the for-of vec-struct fast path
|
|
115
|
+
* (`compileForOfArrayTentative`) and array spread consume it directly with no
|
|
116
|
+
* `__iterator` round-trip.
|
|
117
|
+
*
|
|
118
|
+
* Projection per `kind`:
|
|
119
|
+
* - "keys" → each entry's KEY (for a Set, key === value)
|
|
120
|
+
* - "values" → each entry's VALUE (for a Set, value === key)
|
|
121
|
+
* - "entries" → a 2-element `$ObjVec` `[key, value]` pair per entry, so a
|
|
122
|
+
* consumer's `pair[0]`/`pair[1]` and `[k, v]` destructuring read back
|
|
123
|
+
* through the native `__extern_get_idx`/`__extern_length` arm — exactly as
|
|
124
|
+
* the array `.entries()` path builds its pairs.
|
|
125
|
+
*
|
|
126
|
+
* The result array is sized to `liveCount` (the exact non-tombstone count, what
|
|
127
|
+
* `size` returns), then filled by walking the entries vector with a separate
|
|
128
|
+
* write cursor, skipping tombstones.
|
|
129
|
+
*
|
|
130
|
+
* Returns the vec `ValType` when handled, or `undefined` to let the generic
|
|
131
|
+
* extern/host path proceed. The receiver (and no arguments) are compiled here.
|
|
132
|
+
*/
|
|
133
|
+
export declare function compileNativeCollectionIterator(ctx: CodegenContext, fctx: FunctionContext, propAccess: ts.PropertyAccessExpression, callExpr: ts.CallExpression, kind: "keys" | "values" | "entries", isSet: boolean): InnerResult | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* (#2162) Core of the collection-iterator materialization: given the *receiver*
|
|
136
|
+
* expression (compiled here), emit a canonical externref `$Vec` of the `kind`
|
|
137
|
+
* projection and return its `ValType`. Shared by the `keys/values/entries`
|
|
138
|
+
* method dispatch and the bare `for (… of map/set)` path (which passes the
|
|
139
|
+
* iterable expression directly). Returns `undefined` if the receiver does not
|
|
140
|
+
* lower to the native `$Map` struct.
|
|
141
|
+
*/
|
|
142
|
+
export declare function emitCollectionIteratorVec(ctx: CodegenContext, fctx: FunctionContext, receiver: ts.Expression, kind: "keys" | "values" | "entries", isSet: boolean): InnerResult | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CodegenContext } from './context/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Emit pure Wasm implementations for the requested Math methods.
|
|
4
|
+
* Methods are added as module functions (not imports) and registered
|
|
5
|
+
* in ctx.funcMap under "Math_<method>".
|
|
6
|
+
*/
|
|
7
|
+
export declare function emitInlineMathFunctions(ctx: CodegenContext, needed: Set<string>): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CodegenContext, FunctionContext } from './context/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reserve (or fetch) the member-get dispatcher `__get_member_<name>(recv) ->
|
|
4
|
+
* externref` funcIdx with a placeholder body. The real body is built by
|
|
5
|
+
* {@link fillMemberGetDispatch} at finalize. Idempotent; records the property
|
|
6
|
+
* name in `ctx.memberGetDispatchNames`. Returns the reserved funcIdx, or
|
|
7
|
+
* `undefined` if the `__extern_get` fallback import can't be registered.
|
|
8
|
+
*
|
|
9
|
+
* ALL fill-body deps are registered NOW (reserve time) so the fill only READS
|
|
10
|
+
* funcMap (no funcIdx churn at finalize):
|
|
11
|
+
* - `__extern_get` (the terminal host-read fallback),
|
|
12
|
+
* - the property-name string constant (the fallback's key),
|
|
13
|
+
* - `__box_number` (union import — a per-struct arm box-coerces an f64/i32
|
|
14
|
+
* field result up to externref via `coercionInstrs`).
|
|
15
|
+
*
|
|
16
|
+
* (#2674-residual / #2043 late-import index-shift hardening) The
|
|
17
|
+
* `ensureLateImport`/`addUnionImportsViaRegistry` calls below register imports
|
|
18
|
+
* that shift the function index space. The READ call sites bake the returned
|
|
19
|
+
* `funcIdx` into a DETACHED instruction array (the `buildFallback` terminal) AND
|
|
20
|
+
* immediately follow it with a `coercionInstrs(…, fctx)` that may itself allocate
|
|
21
|
+
* locals and register more late imports — both of which assume a SETTLED index
|
|
22
|
+
* space. Unlike the WRITE side (which pushes straight into `fctx.body`, so the
|
|
23
|
+
* body-level batched flush reaches it), a detached array left across a dangling
|
|
24
|
+
* `pendingLateImportShift` is fragile: when another import-adding pass runs before
|
|
25
|
+
* the body's deferred flush (the failure mode that surfaced only when #2075 was
|
|
26
|
+
* batched with another import-adding PR in the merge_group — `local index out of
|
|
27
|
+
* range at __module_init`, the #2043 class), the staged indices desync. So when a
|
|
28
|
+
* caller passes its `fctx`, FLUSH the pending shift here (ensure→flush discipline,
|
|
29
|
+
* matching `buildVecFromExternref`/`emitUndefined`) so the dispatcher's imports
|
|
30
|
+
* settle before the caller emits anything further. No-op when there is no pending
|
|
31
|
+
* shift or the helpers were already registered (idempotent reserve).
|
|
32
|
+
*/
|
|
33
|
+
export declare function reserveMemberGetDispatch(ctx: CodegenContext, propName: string, fctx?: FunctionContext): number | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Fill every reserved `__get_member_<name>` dispatcher body at FINALIZE, after
|
|
36
|
+
* every struct type (incl. late-registered fnctor structs) is known. READ-ONLY
|
|
37
|
+
* over funcMap. No-op when no read site reserved a dispatcher.
|
|
38
|
+
*
|
|
39
|
+
* Body local layout: param 0 = recv (externref), local 1 = `__any` (anyref, the
|
|
40
|
+
* converted receiver tested against each struct candidate).
|
|
41
|
+
*/
|
|
42
|
+
export declare function fillMemberGetDispatch(ctx: CodegenContext): void;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CodegenContext } from './context/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reserve (or fetch) the member-set dispatcher `__set_member_<name>(recv, val)`
|
|
4
|
+
* funcIdx with a placeholder body. The real body is built by
|
|
5
|
+
* {@link fillMemberSetDispatch} at finalize. Idempotent; records the property
|
|
6
|
+
* name in `ctx.memberSetDispatchNames`. Returns the reserved funcIdx.
|
|
7
|
+
*
|
|
8
|
+
* ALL of the fill body's dependencies are registered NOW (at reserve time) so
|
|
9
|
+
* the fill only READS funcMap — registering imports/globals at FINALIZE would
|
|
10
|
+
* shift baked call/global indices (the addUnionImports hazard the reserve-then-
|
|
11
|
+
* fill pattern exists to avoid):
|
|
12
|
+
* - `__extern_set_strict` (the terminal sidecar/accessor-throw fallback),
|
|
13
|
+
* - the property-name string constant (the fallback's key),
|
|
14
|
+
* - `__box_number`/`__unbox_number` (union imports — the per-struct arms may
|
|
15
|
+
* unbox the externref value into an f64/i32 field via `coercionInstrs`).
|
|
16
|
+
*/
|
|
17
|
+
export declare function reserveMemberSetDispatch(ctx: CodegenContext, propName: string, strict: boolean): number | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Fill every reserved `__set_member_<name>` dispatcher body at FINALIZE, after
|
|
20
|
+
* every struct type (incl. late-registered fnctor structs) is known. READ-ONLY
|
|
21
|
+
* over funcMap (all deps registered at reserve time), so no funcIdx churn. Sets
|
|
22
|
+
* the placeholder body to the full `ref.test`/`struct.set` chain. No-op when no
|
|
23
|
+
* write site reserved a dispatcher.
|
|
24
|
+
*
|
|
25
|
+
* Body local layout: param 0 = recv (externref), param 1 = val (externref),
|
|
26
|
+
* local 2 = `__any` (anyref, the converted receiver tested against each struct).
|
|
27
|
+
*/
|
|
28
|
+
export declare function fillMemberSetDispatch(ctx: CodegenContext): void;
|