@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,18 @@
|
|
|
1
|
+
import { AllocSiteRegistry } from './alloc-registry.js';
|
|
2
|
+
import { IrFunction } from './nodes.js';
|
|
3
|
+
export interface AllocVerifyError {
|
|
4
|
+
readonly message: string;
|
|
5
|
+
readonly func: string;
|
|
6
|
+
}
|
|
7
|
+
/** True iff the env/debug flag enables the alloc-provenance walk. */
|
|
8
|
+
export declare function allocVerifyEnabled(): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Walk every instr (including nested bodies of if / loops / for-of / try) and
|
|
11
|
+
* check the two provenance invariants against `registry`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function verifyAllocProvenance(func: IrFunction, registry: AllocSiteRegistry): AllocVerifyError[];
|
|
14
|
+
/**
|
|
15
|
+
* Throwing wrapper for the integration verify boundaries. No-op unless the
|
|
16
|
+
* debug flag is on, so it costs nothing in production.
|
|
17
|
+
*/
|
|
18
|
+
export declare function assertAllocProvenance(func: IrFunction, registry: AllocSiteRegistry): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API for the multi-memory module linker.
|
|
3
|
+
*/
|
|
4
|
+
export { validateIsolation } from './isolation.js';
|
|
5
|
+
export type { IsolationReport, IsolationViolation } from './isolation.js';
|
|
6
|
+
export { link } from './linker.js';
|
|
7
|
+
export type { LinkError, LinkOptions, LinkResult } from './linker.js';
|
|
8
|
+
export { parseObject } from './reader.js';
|
|
9
|
+
export type { CodeEntry, ElementEntry, ExportEntry, FunctionEntry, GlobalEntry, ImportEntry, MemoryEntry, ParsedObject, RelocEntry, SymbolInfo, TableEntry, TagEntry, TypeSection, } from './reader.js';
|
|
10
|
+
export { resolveSymbols } from './resolver.js';
|
|
11
|
+
export type { Resolution, ResolvedSymbol } from './resolver.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ParsedObject } from './reader.js';
|
|
2
|
+
import { Resolution } from './resolver.js';
|
|
3
|
+
export interface IsolationReport {
|
|
4
|
+
modules: string[];
|
|
5
|
+
properties: {
|
|
6
|
+
importExportOnly: boolean;
|
|
7
|
+
noSharedGlobals: boolean;
|
|
8
|
+
memoryIsolation: boolean;
|
|
9
|
+
noPrivateFunctionAccess: boolean;
|
|
10
|
+
tableIsolation: boolean;
|
|
11
|
+
};
|
|
12
|
+
violations: IsolationViolation[];
|
|
13
|
+
}
|
|
14
|
+
export interface IsolationViolation {
|
|
15
|
+
property: string;
|
|
16
|
+
module: string;
|
|
17
|
+
targetModule: string;
|
|
18
|
+
symbol: string;
|
|
19
|
+
message: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validate isolation properties across a set of linked wasm modules.
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateIsolation(objects: ParsedObject[], resolution: Resolution): IsolationReport;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { IsolationReport } from './isolation.js';
|
|
2
|
+
export interface LinkOptions {
|
|
3
|
+
/** Name of the entry module (controls which exports appear) */
|
|
4
|
+
entry?: string;
|
|
5
|
+
/** Whether to run isolation validation (default: true) */
|
|
6
|
+
validateIsolation?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface LinkResult {
|
|
9
|
+
binary: Uint8Array;
|
|
10
|
+
wat: string;
|
|
11
|
+
success: boolean;
|
|
12
|
+
errors: LinkError[];
|
|
13
|
+
isolationReport: IsolationReport;
|
|
14
|
+
}
|
|
15
|
+
export interface LinkError {
|
|
16
|
+
message: string;
|
|
17
|
+
module?: string;
|
|
18
|
+
severity: "error" | "warning";
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Link multiple relocatable .o wasm files into a single module.
|
|
22
|
+
*/
|
|
23
|
+
export declare function link(objects: Map<string, Uint8Array>, options?: LinkOptions): LinkResult;
|
|
24
|
+
/**
|
|
25
|
+
* #1840 test hook — rewrite a single function body applying only index offsets
|
|
26
|
+
* (no symbol resolution: pass empty symbols so `resolveIndex` falls through to
|
|
27
|
+
* `origIdx + baseOffset`). Lets a test verify LEB-width growth, call_indirect
|
|
28
|
+
* tableidx offsetting, and the memory.size/grow immediate rewrite without
|
|
29
|
+
* constructing a full multi-module link.
|
|
30
|
+
*/
|
|
31
|
+
export declare function rewriteCodeForTest(body: Uint8Array, off: {
|
|
32
|
+
funcOffset: number;
|
|
33
|
+
globalOffset: number;
|
|
34
|
+
typeOffset: number;
|
|
35
|
+
tableOffset: number;
|
|
36
|
+
memoryOffset: number;
|
|
37
|
+
}): Uint8Array;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relocatable Wasm object file (.o) parser.
|
|
3
|
+
*
|
|
4
|
+
* Parses LLVM-style wasm object files that include linking metadata
|
|
5
|
+
* and relocation sections. Extracts all standard wasm sections plus
|
|
6
|
+
* the "linking" custom section (symbol table) and "reloc.*" custom
|
|
7
|
+
* sections.
|
|
8
|
+
*/
|
|
9
|
+
export interface ParsedObject {
|
|
10
|
+
name: string;
|
|
11
|
+
types: TypeSection[];
|
|
12
|
+
imports: ImportEntry[];
|
|
13
|
+
functions: FunctionEntry[];
|
|
14
|
+
tables: TableEntry[];
|
|
15
|
+
memories: MemoryEntry[];
|
|
16
|
+
globals: GlobalEntry[];
|
|
17
|
+
exports: ExportEntry[];
|
|
18
|
+
elements: ElementEntry[];
|
|
19
|
+
tags: TagEntry[];
|
|
20
|
+
code: CodeEntry[];
|
|
21
|
+
symbols: SymbolInfo[];
|
|
22
|
+
relocations: Map<string, RelocEntry[]>;
|
|
23
|
+
}
|
|
24
|
+
export interface TypeSection {
|
|
25
|
+
params: number[];
|
|
26
|
+
results: number[];
|
|
27
|
+
}
|
|
28
|
+
export interface ImportEntry {
|
|
29
|
+
module: string;
|
|
30
|
+
name: string;
|
|
31
|
+
kind: number;
|
|
32
|
+
typeIdx?: number;
|
|
33
|
+
globalType?: number;
|
|
34
|
+
globalMutable?: boolean;
|
|
35
|
+
tableElementType?: number;
|
|
36
|
+
tableMin?: number;
|
|
37
|
+
tableMax?: number;
|
|
38
|
+
memoryMin?: number;
|
|
39
|
+
memoryMax?: number;
|
|
40
|
+
}
|
|
41
|
+
export interface FunctionEntry {
|
|
42
|
+
typeIdx: number;
|
|
43
|
+
}
|
|
44
|
+
export interface TableEntry {
|
|
45
|
+
elementType: number;
|
|
46
|
+
min: number;
|
|
47
|
+
max?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface MemoryEntry {
|
|
50
|
+
min: number;
|
|
51
|
+
max?: number;
|
|
52
|
+
}
|
|
53
|
+
export interface GlobalEntry {
|
|
54
|
+
type: number;
|
|
55
|
+
mutable: boolean;
|
|
56
|
+
init: Uint8Array;
|
|
57
|
+
}
|
|
58
|
+
export interface ExportEntry {
|
|
59
|
+
name: string;
|
|
60
|
+
kind: number;
|
|
61
|
+
index: number;
|
|
62
|
+
}
|
|
63
|
+
export interface ElementEntry {
|
|
64
|
+
/**
|
|
65
|
+
* Raw element-segment flags field (#1841 — the 3-bit value 0-7 per the
|
|
66
|
+
* WebAssembly spec, not just active flag-0). Determines the segment mode
|
|
67
|
+
* (active / passive / declarative), whether a tableidx + offset-expr are
|
|
68
|
+
* present, and whether the payload is funcidx* or expr*.
|
|
69
|
+
*/
|
|
70
|
+
flags: number;
|
|
71
|
+
tableIdx: number;
|
|
72
|
+
/**
|
|
73
|
+
* Active-segment offset constant-expression bytes (terminated by 0x0b),
|
|
74
|
+
* present only for active modes (flags 0, 2, 4, 6). `null` for
|
|
75
|
+
* passive/declarative (flags 1, 3, 5, 7), which have no offset.
|
|
76
|
+
*/
|
|
77
|
+
offsetExpr: Uint8Array | null;
|
|
78
|
+
/**
|
|
79
|
+
* For funcidx-payload segments (flags 0-3): the resolved function indices.
|
|
80
|
+
* Empty for expr-payload segments (flags 4-7), which keep their raw
|
|
81
|
+
* expression bytes in `elemExprs` instead.
|
|
82
|
+
*/
|
|
83
|
+
funcIndices: number[];
|
|
84
|
+
/** Number of elements in the segment (funcidx count or expr count). */
|
|
85
|
+
elemCount: number;
|
|
86
|
+
/**
|
|
87
|
+
* elemkind (flags 1-3) or reftype (flags 5-7) byte, when the segment
|
|
88
|
+
* carries one explicitly. `null` for flag 0/4 (funcref implied).
|
|
89
|
+
*/
|
|
90
|
+
kindByte: number | null;
|
|
91
|
+
/**
|
|
92
|
+
* For expr-payload segments (flags 4-7): the raw element-expression bytes
|
|
93
|
+
* (the `vec(expr)` body, excluding the leading count). Re-emitted verbatim.
|
|
94
|
+
* `null` for funcidx-payload segments.
|
|
95
|
+
*/
|
|
96
|
+
elemExprs: Uint8Array | null;
|
|
97
|
+
}
|
|
98
|
+
export interface TagEntry {
|
|
99
|
+
attribute: number;
|
|
100
|
+
typeIdx: number;
|
|
101
|
+
}
|
|
102
|
+
export interface CodeEntry {
|
|
103
|
+
locals: {
|
|
104
|
+
count: number;
|
|
105
|
+
type: number;
|
|
106
|
+
}[];
|
|
107
|
+
body: Uint8Array;
|
|
108
|
+
}
|
|
109
|
+
export interface SymbolInfo {
|
|
110
|
+
kind: number;
|
|
111
|
+
name: string;
|
|
112
|
+
index: number;
|
|
113
|
+
flags: number;
|
|
114
|
+
}
|
|
115
|
+
export interface RelocEntry {
|
|
116
|
+
type: number;
|
|
117
|
+
offset: number;
|
|
118
|
+
symbolIndex: number;
|
|
119
|
+
addend?: number;
|
|
120
|
+
}
|
|
121
|
+
export declare const SYMBOL_BINDING_WEAK = 1;
|
|
122
|
+
export declare const SYMBOL_BINDING_LOCAL = 2;
|
|
123
|
+
export declare const SYMBOL_VISIBILITY_HIDDEN = 4;
|
|
124
|
+
export declare const SYMBOL_UNDEFINED = 16;
|
|
125
|
+
export declare const SYMBOL_EXPORTED = 32;
|
|
126
|
+
export declare const SYMBOL_EXPLICIT_NAME = 64;
|
|
127
|
+
export declare const SYMBOL_NO_STRIP = 128;
|
|
128
|
+
export declare const SYMTAB_FUNCTION = 0;
|
|
129
|
+
export declare const SYMTAB_DATA = 1;
|
|
130
|
+
export declare const SYMTAB_GLOBAL = 2;
|
|
131
|
+
export declare const SYMTAB_SECTION = 3;
|
|
132
|
+
export declare const SYMTAB_EVENT = 4;
|
|
133
|
+
export declare const SYMTAB_TABLE = 5;
|
|
134
|
+
export declare const R_WASM_FUNCTION_INDEX_LEB = 0;
|
|
135
|
+
export declare const R_WASM_TABLE_INDEX_SLEB = 1;
|
|
136
|
+
export declare const R_WASM_TABLE_INDEX_I32 = 2;
|
|
137
|
+
export declare const R_WASM_MEMORY_ADDR_LEB = 3;
|
|
138
|
+
export declare const R_WASM_MEMORY_ADDR_SLEB = 4;
|
|
139
|
+
export declare const R_WASM_MEMORY_ADDR_I32 = 5;
|
|
140
|
+
export declare const R_WASM_TYPE_INDEX_LEB = 6;
|
|
141
|
+
export declare const R_WASM_GLOBAL_INDEX_LEB = 7;
|
|
142
|
+
export declare const R_WASM_FUNCTION_OFFSET_I32 = 8;
|
|
143
|
+
export declare const R_WASM_SECTION_OFFSET_I32 = 9;
|
|
144
|
+
export declare const R_WASM_TAG_INDEX_LEB = 10;
|
|
145
|
+
export declare const R_WASM_TABLE_INDEX_LEB = 15;
|
|
146
|
+
export declare const R_WASM_TABLE_NUMBER_LEB = 20;
|
|
147
|
+
export declare function parseObject(name: string, bytes: Uint8Array): ParsedObject;
|
|
148
|
+
/**
|
|
149
|
+
* #1841 test hook — parse a raw element-section body (the bytes that follow the
|
|
150
|
+
* section id + size, i.e. starting at the segment count) and return the parsed
|
|
151
|
+
* segments plus the final cursor position. The cursor MUST land exactly at the
|
|
152
|
+
* end of `bytes`; any drift means a flag case desynced the reader. Kept narrow
|
|
153
|
+
* so the internal `ByteReader` / `parseElementSection` stay unexported.
|
|
154
|
+
*/
|
|
155
|
+
export declare function parseElementSegmentsForTest(bytes: Uint8Array): {
|
|
156
|
+
elements: ElementEntry[];
|
|
157
|
+
finalPos: number;
|
|
158
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ParsedObject } from './reader.js';
|
|
2
|
+
export interface Resolution {
|
|
3
|
+
/** Map from "moduleIdx:symbolIdx" → resolved target */
|
|
4
|
+
resolved: Map<string, ResolvedSymbol>;
|
|
5
|
+
errors: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface ResolvedSymbol {
|
|
8
|
+
targetModule: number;
|
|
9
|
+
targetIndex: number;
|
|
10
|
+
name: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Resolve symbols across a set of parsed wasm object files.
|
|
14
|
+
*
|
|
15
|
+
* For each undefined symbol in a module, search other modules for an
|
|
16
|
+
* exported (or at least non-undefined, non-local) definition with the
|
|
17
|
+
* same name and kind.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveSymbols(objects: ParsedObject[]): Resolution;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-processing pass using Binaryen's wasm-opt optimizer.
|
|
3
|
+
*
|
|
4
|
+
* Tries two strategies in order:
|
|
5
|
+
* 1. The `binaryen` npm package (if installed as an optional peer dependency)
|
|
6
|
+
* 2. A system `wasm-opt` binary on PATH
|
|
7
|
+
*
|
|
8
|
+
* If neither is available, returns the original binary unchanged and emits a warning.
|
|
9
|
+
*/
|
|
10
|
+
export interface OptimizeOptions {
|
|
11
|
+
/** Optimization level: 1 (-O1), 2 (-O2), 3 (-O3), 4 (-O4). Default: 3 */
|
|
12
|
+
level?: 1 | 2 | 3 | 4;
|
|
13
|
+
/** Enable GC proposal (default: true) */
|
|
14
|
+
gc?: boolean;
|
|
15
|
+
/** Enable reference types (default: true) */
|
|
16
|
+
referenceTypes?: boolean;
|
|
17
|
+
/** Enable exception handling (default: true) */
|
|
18
|
+
exceptionHandling?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface OptimizeResult {
|
|
21
|
+
binary: Uint8Array;
|
|
22
|
+
/** true if optimization was applied */
|
|
23
|
+
optimized: boolean;
|
|
24
|
+
/** Warning message if optimization was skipped */
|
|
25
|
+
warning?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Optimize a Wasm binary using Binaryen.
|
|
29
|
+
*
|
|
30
|
+
* This is the only public optimizer entry point (#1763). The previous
|
|
31
|
+
* synchronous `optimizeBinary` was removed: after the #1757 async-compile
|
|
32
|
+
* migration every live caller goes through this async path, and the sync
|
|
33
|
+
* variant only kept alive a dead `createRequire("binaryen")` branch — the
|
|
34
|
+
* exact bundler hazard #986/#1756 set out to remove. The `binaryen` package
|
|
35
|
+
* is loaded lazily at runtime (see `getBinaryenModule`) without making
|
|
36
|
+
* bundlers embed it in standalone artifacts; the system `wasm-opt` CLI
|
|
37
|
+
* fallback still uses the dynamic node-builtin shim that bundlers
|
|
38
|
+
* intentionally cannot statically resolve.
|
|
39
|
+
*
|
|
40
|
+
* Backend preference + correctness gate (#1941):
|
|
41
|
+
* 1. Try the **system / bundled `wasm-opt` CLI first**, then the in-process
|
|
42
|
+
* binaryen module as a fallback (the reverse of the pre-#1941 order).
|
|
43
|
+
* The binaryen-123 JS module emits a stale GC ref-type encoding
|
|
44
|
+
* (`0x62` legacy non-null ref) for our closure-dispatch trampolines
|
|
45
|
+
* that V8 and wasmtime reject, while the bundled native CLI emits the
|
|
46
|
+
* correct `0x64` encoding. The CLI is the trustworthy backend; the
|
|
47
|
+
* module is the no-CLI fallback (e.g. browser playgrounds).
|
|
48
|
+
* 2. **Validate every optimizer result** with `WebAssembly.validate`. If
|
|
49
|
+
* the optimized bytes don't validate, the pass miscompiled the module:
|
|
50
|
+
* discard them, return the ORIGINAL binary, and emit a fail-loud
|
|
51
|
+
* warning. We never ship a binary that doesn't validate, regardless of
|
|
52
|
+
* which backend produced it or which binaryen version is installed.
|
|
53
|
+
*/
|
|
54
|
+
export declare function optimizeBinaryAsync(binary: Uint8Array, options?: OptimizeOptions): Promise<OptimizeResult>;
|
package/dist/optimize.js
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
let _nodeImports = null;
|
|
2
|
+
function getNodeImportsSync() {
|
|
3
|
+
if (_nodeImports) return _nodeImports;
|
|
4
|
+
if (typeof process === "undefined" || !process.versions || !process.versions.node) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
try {
|
|
8
|
+
let req;
|
|
9
|
+
const getBuiltin = process.getBuiltinModule;
|
|
10
|
+
if (typeof getBuiltin === "function") {
|
|
11
|
+
const moduleNs = getBuiltin("node:module");
|
|
12
|
+
if (moduleNs && typeof moduleNs.createRequire === "function") {
|
|
13
|
+
req = moduleNs.createRequire(`file://${process.cwd()}/`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (!req || typeof req !== "function") return null;
|
|
17
|
+
const cp = req("node:child_process");
|
|
18
|
+
const fs = req("node:fs");
|
|
19
|
+
const path = req("node:path");
|
|
20
|
+
const os = req("node:os");
|
|
21
|
+
_nodeImports = {
|
|
22
|
+
execFileSync: cp.execFileSync,
|
|
23
|
+
writeFileSync: fs.writeFileSync,
|
|
24
|
+
readFileSync: fs.readFileSync,
|
|
25
|
+
unlinkSync: fs.unlinkSync,
|
|
26
|
+
rmdirSync: fs.rmdirSync,
|
|
27
|
+
mkdtempSync: fs.mkdtempSync,
|
|
28
|
+
join: path.join,
|
|
29
|
+
tmpdir: os.tmpdir
|
|
30
|
+
};
|
|
31
|
+
return _nodeImports;
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
let _binaryenModulePromise = null;
|
|
37
|
+
function isBrowserLikeRuntime() {
|
|
38
|
+
return typeof window !== "undefined" || typeof globalThis.WorkerGlobalScope !== "undefined";
|
|
39
|
+
}
|
|
40
|
+
function optimizedBinaryValidates(binary) {
|
|
41
|
+
const WA = globalThis.WebAssembly;
|
|
42
|
+
if (!WA || typeof WA.validate !== "function") return true;
|
|
43
|
+
try {
|
|
44
|
+
return WA.validate(binary);
|
|
45
|
+
} catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function optimizeBinaryAsync(binary, options = {}) {
|
|
50
|
+
const level = options.level ?? 3;
|
|
51
|
+
const gc = options.gc !== false;
|
|
52
|
+
const referenceTypes = options.referenceTypes !== false;
|
|
53
|
+
const exceptionHandling = options.exceptionHandling !== false;
|
|
54
|
+
try {
|
|
55
|
+
const result = optimizeWithSystemBinary(binary, level, gc, referenceTypes, exceptionHandling);
|
|
56
|
+
if (result && result.optimized) {
|
|
57
|
+
if (optimizedBinaryValidates(result.binary)) return result;
|
|
58
|
+
} else if (result) {
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
} catch {
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const binaryen = await getBinaryenModule();
|
|
65
|
+
if (binaryen) {
|
|
66
|
+
const result = optimizeWithBinaryenModule(binaryen, binary, level, gc, referenceTypes, exceptionHandling);
|
|
67
|
+
if (result && result.optimized) {
|
|
68
|
+
if (optimizedBinaryValidates(result.binary)) return result;
|
|
69
|
+
return {
|
|
70
|
+
binary,
|
|
71
|
+
optimized: false,
|
|
72
|
+
warning: "wasm-opt produced an invalid binary (it failed WebAssembly.validate); shipping unoptimized output instead. This is a known binaryen-JS-module encoder bug for WasmGC ref types (#1941) — installing a native wasm-opt on PATH avoids it."
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (result) return result;
|
|
76
|
+
}
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
binary,
|
|
81
|
+
optimized: false,
|
|
82
|
+
warning: "wasm-opt not available: install the 'binaryen' npm package or add wasm-opt to PATH. Skipping optimization."
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async function getBinaryenModule() {
|
|
86
|
+
if (_binaryenModulePromise) return _binaryenModulePromise;
|
|
87
|
+
_binaryenModulePromise = (async () => {
|
|
88
|
+
const browserLike = isBrowserLikeRuntime();
|
|
89
|
+
const globalObject = globalThis;
|
|
90
|
+
const hadProcess = "process" in globalObject;
|
|
91
|
+
const hadOwnProcess = Object.prototype.hasOwnProperty.call(globalObject, "process");
|
|
92
|
+
const previousProcess = globalObject.process;
|
|
93
|
+
if (browserLike && hadProcess) {
|
|
94
|
+
try {
|
|
95
|
+
globalObject.process = void 0;
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const specifier = globalObject.__js2wasmBinaryenModuleSpecifier ?? "binaryen";
|
|
101
|
+
const mod = await import(
|
|
102
|
+
/* @vite-ignore */
|
|
103
|
+
specifier
|
|
104
|
+
);
|
|
105
|
+
return mod.default ?? mod;
|
|
106
|
+
} catch {
|
|
107
|
+
return null;
|
|
108
|
+
} finally {
|
|
109
|
+
if (browserLike) {
|
|
110
|
+
if (hadProcess && hadOwnProcess) {
|
|
111
|
+
globalObject.process = previousProcess;
|
|
112
|
+
} else {
|
|
113
|
+
globalObject.process = void 0;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
})();
|
|
118
|
+
return _binaryenModulePromise;
|
|
119
|
+
}
|
|
120
|
+
function optimizeWithBinaryenModule(binaryen, binary, level, gc, referenceTypes, exceptionHandling) {
|
|
121
|
+
const featureFlags = binaryen.Features ?? binaryen.features;
|
|
122
|
+
if (!featureFlags) return null;
|
|
123
|
+
let mod;
|
|
124
|
+
try {
|
|
125
|
+
mod = binaryen.readBinary(binary);
|
|
126
|
+
} catch (e) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
const previousOptimizeLevel = typeof binaryen.getOptimizeLevel === "function" ? binaryen.getOptimizeLevel() : void 0;
|
|
131
|
+
const previousShrinkLevel = typeof binaryen.getShrinkLevel === "function" ? binaryen.getShrinkLevel() : void 0;
|
|
132
|
+
let features = 0;
|
|
133
|
+
if (gc) features |= (featureFlags.GC ?? 0) | (featureFlags.ReferenceTypes ?? 0);
|
|
134
|
+
if (referenceTypes) features |= featureFlags.ReferenceTypes ?? 0;
|
|
135
|
+
if (exceptionHandling) features |= featureFlags.ExceptionHandling ?? 0;
|
|
136
|
+
features |= featureFlags.BulkMemory ?? 0;
|
|
137
|
+
features |= featureFlags.MutableGlobals ?? 0;
|
|
138
|
+
features |= featureFlags.SignExt ?? 0;
|
|
139
|
+
features |= featureFlags.TruncSat ?? 0;
|
|
140
|
+
features |= featureFlags.TailCall ?? 0;
|
|
141
|
+
features |= featureFlags.Multivalue ?? 0;
|
|
142
|
+
features |= featureFlags.TypedFunctionReferences ?? 0;
|
|
143
|
+
features |= featureFlags.Strings ?? 0;
|
|
144
|
+
features |= featureFlags.GCNNLocals ?? 0;
|
|
145
|
+
features |= featureFlags.RelaxedSIMD ?? 0;
|
|
146
|
+
features |= featureFlags.ExtendedConst ?? 0;
|
|
147
|
+
features |= featureFlags.SIMD128 ?? 0;
|
|
148
|
+
features |= featureFlags.Atomics ?? 0;
|
|
149
|
+
features |= featureFlags.MultiMemory ?? 0;
|
|
150
|
+
features |= featureFlags.CallIndirectOverlong ?? 0;
|
|
151
|
+
if (featureFlags.CustomDescriptors !== void 0) {
|
|
152
|
+
features &= ~featureFlags.CustomDescriptors;
|
|
153
|
+
}
|
|
154
|
+
mod.setFeatures(features);
|
|
155
|
+
if (typeof binaryen.setOptimizeLevel === "function") {
|
|
156
|
+
binaryen.setOptimizeLevel(level >= 4 ? 3 : level);
|
|
157
|
+
}
|
|
158
|
+
if (typeof binaryen.setShrinkLevel === "function") {
|
|
159
|
+
binaryen.setShrinkLevel(level >= 4 ? 1 : 0);
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
mod.optimize();
|
|
163
|
+
if (level >= 4) mod.optimize();
|
|
164
|
+
} finally {
|
|
165
|
+
if (typeof binaryen.setOptimizeLevel === "function" && previousOptimizeLevel !== void 0) {
|
|
166
|
+
binaryen.setOptimizeLevel(previousOptimizeLevel);
|
|
167
|
+
}
|
|
168
|
+
if (typeof binaryen.setShrinkLevel === "function" && previousShrinkLevel !== void 0) {
|
|
169
|
+
binaryen.setShrinkLevel(previousShrinkLevel);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const optimizedBinary = mod.emitBinary();
|
|
173
|
+
return { binary: new Uint8Array(optimizedBinary), optimized: true };
|
|
174
|
+
} finally {
|
|
175
|
+
mod.dispose();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function optimizeWithSystemBinary(binary, level, gc, referenceTypes, exceptionHandling) {
|
|
179
|
+
const n = getNodeImportsSync();
|
|
180
|
+
if (!n) return null;
|
|
181
|
+
let wasmOptPath;
|
|
182
|
+
try {
|
|
183
|
+
const p = n.execFileSync("which", ["wasm-opt"], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
184
|
+
if (p) wasmOptPath = p;
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
if (!wasmOptPath) {
|
|
188
|
+
try {
|
|
189
|
+
let req;
|
|
190
|
+
const getBuiltin = process.getBuiltinModule;
|
|
191
|
+
if (typeof getBuiltin === "function") {
|
|
192
|
+
const moduleNs = getBuiltin("node:module");
|
|
193
|
+
if (moduleNs && typeof moduleNs.createRequire === "function") {
|
|
194
|
+
req = moduleNs.createRequire(`file://${process.cwd()}/`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (req && typeof req.resolve === "function") {
|
|
198
|
+
const pkgJsonPath = req.resolve("binaryen/package.json");
|
|
199
|
+
const wasmOptCandidate = n.join(pkgJsonPath, "..", "bin", "wasm-opt");
|
|
200
|
+
n.execFileSync(wasmOptCandidate, ["--version"], {
|
|
201
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
202
|
+
timeout: 5e3
|
|
203
|
+
});
|
|
204
|
+
wasmOptPath = wasmOptCandidate;
|
|
205
|
+
}
|
|
206
|
+
} catch {
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (!wasmOptPath) return null;
|
|
210
|
+
const tmpDir = n.mkdtempSync(n.join(n.tmpdir(), "js2wasm-opt-"));
|
|
211
|
+
const inputPath = n.join(tmpDir, "input.wasm");
|
|
212
|
+
const outputPath = n.join(tmpDir, "output.wasm");
|
|
213
|
+
try {
|
|
214
|
+
n.writeFileSync(inputPath, binary);
|
|
215
|
+
const args = [
|
|
216
|
+
inputPath,
|
|
217
|
+
`-O${level}`,
|
|
218
|
+
"-o",
|
|
219
|
+
outputPath,
|
|
220
|
+
"--all-features",
|
|
221
|
+
"--disable-custom-descriptors"
|
|
222
|
+
];
|
|
223
|
+
void gc;
|
|
224
|
+
void referenceTypes;
|
|
225
|
+
void exceptionHandling;
|
|
226
|
+
let stderr = "";
|
|
227
|
+
try {
|
|
228
|
+
n.execFileSync(wasmOptPath, args, {
|
|
229
|
+
timeout: 6e4,
|
|
230
|
+
// 60 second timeout
|
|
231
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
232
|
+
});
|
|
233
|
+
} catch (err) {
|
|
234
|
+
const e = err;
|
|
235
|
+
stderr = e.stderr ?? e.message ?? "unknown error";
|
|
236
|
+
const text = Buffer.isBuffer(stderr) ? stderr.toString("utf-8") : String(stderr);
|
|
237
|
+
return {
|
|
238
|
+
binary,
|
|
239
|
+
optimized: false,
|
|
240
|
+
warning: `wasm-opt -O${level} failed: ${text.slice(0, 800).trim()}`
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
const optimizedBinary = n.readFileSync(outputPath);
|
|
244
|
+
return { binary: new Uint8Array(optimizedBinary), optimized: true };
|
|
245
|
+
} finally {
|
|
246
|
+
try {
|
|
247
|
+
n.unlinkSync(inputPath);
|
|
248
|
+
} catch {
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
n.unlinkSync(outputPath);
|
|
252
|
+
} catch {
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
n.rmdirSync(tmpDir);
|
|
256
|
+
} catch {
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
export {
|
|
261
|
+
optimizeBinaryAsync
|
|
262
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #1928 — source-position remapping for pre-parse rewrites.
|
|
3
|
+
*
|
|
4
|
+
* Diagnostics are computed by the TS checker against the *rewritten* source
|
|
5
|
+
* (timer shim prepended, imports replaced by `declare` stubs, CJS `require`
|
|
6
|
+
* rewritten, `define` substitutions), so a reported `(line, column)` is wrong
|
|
7
|
+
* — often by several lines — whenever any pre-parse rewrite fires. There is no
|
|
8
|
+
* way to recover the user's position from the processed source alone.
|
|
9
|
+
*
|
|
10
|
+
* A `PositionMap` records the character-level edits a rewriter applied (each in
|
|
11
|
+
* the coordinate space of the text it consumed) and translates an offset in the
|
|
12
|
+
* *output* text back to an offset in the *input* text. Rewriters run in a
|
|
13
|
+
* pipeline (define → CJS → eval/super → imports+shim), so the maps compose:
|
|
14
|
+
* `outer.compose(inner)` yields a map from the outermost output straight back
|
|
15
|
+
* to the original source.
|
|
16
|
+
*
|
|
17
|
+
* Mapping policy (matches the issue's pragmatic guidance):
|
|
18
|
+
* - An offset OUTSIDE every edited span maps back by the net length delta of
|
|
19
|
+
* all edits that ended before it — exact.
|
|
20
|
+
* - An offset INSIDE a replaced span (e.g. within an injected `declare`
|
|
21
|
+
* stub, which has no user-source counterpart) maps to the START of the
|
|
22
|
+
* original replaced span. Diagnostics rarely point inside an injected stub;
|
|
23
|
+
* anchoring at the original statement is the correct, stable fallback.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* One text edit, in the coordinate space of the INPUT this rewriter consumed:
|
|
27
|
+
* the half-open span `[origStart, origEnd)` was replaced by text of length
|
|
28
|
+
* `newLength`. A pure prepend is `origStart = origEnd = 0` with `newLength` =
|
|
29
|
+
* the prepended length.
|
|
30
|
+
*/
|
|
31
|
+
export interface SourceEdit {
|
|
32
|
+
readonly origStart: number;
|
|
33
|
+
readonly origEnd: number;
|
|
34
|
+
readonly newLength: number;
|
|
35
|
+
}
|
|
36
|
+
export declare class PositionMap {
|
|
37
|
+
/**
|
|
38
|
+
* A single-stage map is described by its edit list; a composed map is a
|
|
39
|
+
* chain `outer → inner` translated by function composition (apply `outer`'s
|
|
40
|
+
* single-stage transform, then defer to `inner`). Keeping composition as
|
|
41
|
+
* function composition (rather than flattening two edit lists into one)
|
|
42
|
+
* avoids the interleaving-delta correctness traps of merging transforms.
|
|
43
|
+
*/
|
|
44
|
+
private readonly edits;
|
|
45
|
+
private readonly inner?;
|
|
46
|
+
constructor(edits: readonly SourceEdit[], inner?: PositionMap);
|
|
47
|
+
/** Identity map — output offsets equal input offsets. */
|
|
48
|
+
static identity(): PositionMap;
|
|
49
|
+
/** Apply only THIS stage's single transform (output → its direct input). */
|
|
50
|
+
private toDirectInputOffset;
|
|
51
|
+
/**
|
|
52
|
+
* Translate an offset in this map's OUTPUT text all the way back to the
|
|
53
|
+
* ORIGINAL source: apply this stage, then defer to the earlier stage(s).
|
|
54
|
+
*/
|
|
55
|
+
toInputOffset(outOffset: number): number;
|
|
56
|
+
/**
|
|
57
|
+
* Compose with the map of an EARLIER pipeline stage. `this` maps
|
|
58
|
+
* stage-N-output → stage-N-input; `inner` maps stage-N-input (== stage-(N−1)
|
|
59
|
+
* output) → original. The result maps stage-N-output → original.
|
|
60
|
+
*/
|
|
61
|
+
compose(inner: PositionMap): PositionMap;
|
|
62
|
+
/** True when this is the identity (no edits and no earlier stage). */
|
|
63
|
+
get isIdentity(): boolean;
|
|
64
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PositionMap } from './position-map.js';
|
|
2
|
+
export interface StdinPreludeResult {
|
|
3
|
+
/** The transformed source (prelude prepended + `process.stdin` rewritten), or the input unchanged. */
|
|
4
|
+
source: string;
|
|
5
|
+
/** Output→input position map (identity when nothing was injected). */
|
|
6
|
+
positionMap: PositionMap;
|
|
7
|
+
/** True when the prelude was injected (the program references `process.stdin`). */
|
|
8
|
+
injected: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* #2632 Phase 3 — inject the faithful `process.stdin` Readable prelude when the
|
|
12
|
+
* program references `process.stdin`. Byte-neutral (identity map, unchanged
|
|
13
|
+
* source) otherwise. Only the caller decides WASI gating; this function injects
|
|
14
|
+
* whenever a `process.stdin` access is present.
|
|
15
|
+
*/
|
|
16
|
+
export declare function injectProcessStdinPrelude(source: string): StdinPreludeResult;
|