From 99a2383a4c1c30ab06db6795b6668f25deda7454 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:27:04 -0400 Subject: [PATCH 001/247] build: init package files --- .gitignore | 6 ++++++ ts/.editorconfig | 14 ++++++++++++++ ts/README.md | 34 ++++++++++++++++++++++++++++++++++ ts/package-lock.json | 33 +++++++++++++++++++++++++++++++++ ts/package.json | 33 +++++++++++++++++++++++++++++++++ ts/src/binaryen.ts | 1 + ts/tsconfig.json | 25 +++++++++++++++++++++++++ 7 files changed, 146 insertions(+) create mode 100644 ts/.editorconfig create mode 100644 ts/README.md create mode 100644 ts/package-lock.json create mode 100644 ts/package.json create mode 100644 ts/src/binaryen.ts create mode 100644 ts/tsconfig.json diff --git a/.gitignore b/.gitignore index b88109b38e0..f866caa990f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ Makefile TAGS tags +# dependency directories +node_modules/ + # autogenerated during the build /src/passes/WasmIntrinsics.cpp @@ -46,6 +49,9 @@ CMakeUserPresets.json # files commonly related to building out-of-tree /build/ +# compiling TypeScript +/ts/dist/ + # macOS .DS_Store diff --git a/ts/.editorconfig b/ts/.editorconfig new file mode 100644 index 00000000000..9ed5f2c1ab3 --- /dev/null +++ b/ts/.editorconfig @@ -0,0 +1,14 @@ +# EditorConfig: https://EditorConfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_size = tab +indent_style = tab +insert_final_newline = true +max_line_length = off +trim_trailing_whitespace = true + +[**/package{,-lock}.json] +indent_size = 2 +indent_style = space diff --git a/ts/README.md b/ts/README.md new file mode 100644 index 00000000000..e447ba426cd --- /dev/null +++ b/ts/README.md @@ -0,0 +1,34 @@ +# Binaryen.TS +Binaryen API ported to TypeScript for use in the browser and in Node.JS. + +## How To Use +```zsh +$ npm install binaryen.ts +``` +```ts +import * as binaryen from "binaryen.ts"; + +const mod: binaryen.Module = new binaryen.Module(); + +mod.addFunction("add", binaryen.createType([binaryen.i32, binaryen.i32]), binaryen.i32, [binaryen.i32], (() => { + const param0: binaryen.ExpressionRef = mod.local.get(0, binaryen.i32); + const param1: binaryen.ExpressionRef = mod.local.get(1, binaryen.i32); + const result: binaryen.ExpressionRef = mod.i32.add(param0, param1); + return mod.block(null, [ + mod.local.set(2, result), + mod.local.get(2, binaryen.i32), + ], binaryen.i32); +})()); +mod.addFunctionExport("add", "add"); +mod.optimize(); +if (!mod.validate()) { + throw new Error("Invalid WebAssembly module."); +} + +const textData = mod.emitText(); +const wasmData = mod.emitBinary() as Uint8Array; +const compiled = new WebAssembly.Module(wasmData); +const instance = new WebAssembly.Instance(compiled, {}); + +console.log(instance.exports.add(41, 1)); // 42 +``` diff --git a/ts/package-lock.json b/ts/package-lock.json new file mode 100644 index 00000000000..1084fad86e3 --- /dev/null +++ b/ts/package-lock.json @@ -0,0 +1,33 @@ +{ + "name": "binaryen.ts", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "binaryen.ts", + "version": "0.1.0", + "license": "Apache-2.0", + "devDependencies": { + "typescript": "~6.0.0" + }, + "engines": { + "node": "^22 || ^24" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + } + } +} diff --git a/ts/package.json b/ts/package.json new file mode 100644 index 00000000000..657f58ad42c --- /dev/null +++ b/ts/package.json @@ -0,0 +1,33 @@ +{ + "name": "binaryen.ts", + "description": "Browser & Node.js builds of Binaryen, a compiler infrastructure and toolchain library for WebAssembly.", + "version": "0.1.0", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/WebAssembly/binaryen.git" + }, + "keywords": [ + "webassembly", + "wasm", + "typescript", + "javascript" + ], + "type": "module", + "main": "./dist/binaryen.js", + "scripts": { + "compile": "tsc" + }, + "files": [ + "package.json", + "package-lock.json", + "./dist/*.d.ts", + "./dist/*.js" + ], + "devDependencies": { + "typescript": "~6.0.0" + }, + "engines": { + "node": "^22 || ^24" + } +} diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts new file mode 100644 index 00000000000..cb0ff5c3b54 --- /dev/null +++ b/ts/src/binaryen.ts @@ -0,0 +1 @@ +export {}; diff --git a/ts/tsconfig.json b/ts/tsconfig.json new file mode 100644 index 00000000000..134d6aeb5cc --- /dev/null +++ b/ts/tsconfig.json @@ -0,0 +1,25 @@ +{ + // Reference: https://www.typescriptlang.org/tsconfig/ + "compilerOptions": { + // Type Checking + "exactOptionalPropertyTypes": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noPropertyAccessFromIndexSignature": true, + + // Modules + "rewriteRelativeImportExtensions": true, + "rootDir": "./src/", + + // Emit + "declaration": true, + "outDir": "./dist/", + + // Interop Constraints + "verbatimModuleSyntax": true, + + // Completeness + "skipLibCheck": true, + }, + "include": ["./src/"], +} From fa4659ff5273e7de939194e26eec9ee2b1c196e1 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 28 Apr 2026 20:29:25 -0400 Subject: [PATCH 002/247] feat: start utils & expressions --- ts/src/binaryen.ts | 2 +- ts/src/expressions.ts | 237 ++++++++++++++++++++++++++++++++++++++++++ ts/src/pre.ts | 14 +++ ts/src/utils.ts | 66 ++++++++++++ 4 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 ts/src/expressions.ts create mode 100644 ts/src/pre.ts create mode 100644 ts/src/utils.ts diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index cb0ff5c3b54..845c54273bd 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1 +1 @@ -export {}; +export * from "./expressions.ts"; diff --git a/ts/src/expressions.ts b/ts/src/expressions.ts new file mode 100644 index 00000000000..7ebc66af74d --- /dev/null +++ b/ts/src/expressions.ts @@ -0,0 +1,237 @@ +import { + BinaryenObj, + stackAlloc, +} from "./pre.ts"; +import { + HEAPU32, + i32sToStack, + preserveStack, +} from "./utils.ts"; + + + +// # Expressions, Types, and Constants # // +// Compile-time types used by TypeScript, Binaryen types, and expression types. + + + +// ## Static Types ## // +export type Type = number; +export type HeapType = number; +export type ElementSegmentRef = number; +export type ExpressionRef = number; +export type FunctionRef = number; +export type GlobalRef = number; +export type ExportRef = number; +export type TableRef = number; +export type TagRef = number; +export type RelooperBlockRef = number; +export type ExpressionRunnerRef = number; +export type TypeBuilderRef = number; + + + +// ## Expression Types ## // +// see https://webassembly.github.io/spec/core/syntax/types.html + +// ### Binaryen-Only Types ### // +/** Type with stack effect `[t*] -> [t*]`. */ +export const unreachable: Type = BinaryenObj["_BinaryenTypeUnreachable"](); +/** Type with stack effect `[t*] -> []`. Not to be confused with the WASM heap type `none`. */ +export const none: Type = BinaryenObj["_BinaryenTypeNone"](); +/** Used only for auto-detecting block types. */ +export const auto: Type = BinaryenObj["_BinaryenTypeAuto"](); + +// ### Number & Vector Types ### // +export const i32: Type = BinaryenObj["_BinaryenTypeInt32"](); +export const i64: Type = BinaryenObj["_BinaryenTypeInt64"](); +export const f32: Type = BinaryenObj["_BinaryenTypeFloat32"](); +export const f64: Type = BinaryenObj["_BinaryenTypeFloat64"](); +export const v128: Type = BinaryenObj["_BinaryenTypeVec128"](); + +// ### Reference Types ### // +/** Reference type `(ref null any)`. */ +export const anyref: Type = BinaryenObj["_BinaryenTypeAnyref"](); +/** Reference type `(ref null eq)`. */ +export const eqref: Type = BinaryenObj["_BinaryenTypeEqref"](); +/** Reference type `(ref null i31)`. */ +export const i31ref: Type = BinaryenObj["_BinaryenTypeI31ref"](); +/** Reference type `(ref null struct)`. */ +export const structref: Type = BinaryenObj["_BinaryenTypeStructref"](); +/** Reference type `(ref null array)`. */ +export const arrayref: Type = BinaryenObj["_BinaryenTypeArrayref"](); +/** Reference type `(ref null func)`. */ +export const funcref: Type = BinaryenObj["_BinaryenTypeFuncref"](); +/** Reference type `(ref null exn)`. */ +// export const exnref: Type = BinaryenObj["_BinaryenTypeExnref"](); // TODO: uncomment once supported in Binaryen +/** Reference type `(ref null extern)`. */ +export const externref: Type = BinaryenObj["_BinaryenTypeExternref"](); +/** Reference type `(ref null none)`. */ +export const nullref: Type = BinaryenObj["_BinaryenTypeNullref"](); +/** Reference type `(ref null nofunc)`. */ +export const nullfuncref: Type = BinaryenObj["_BinaryenTypeNullFuncref"](); +/** Reference type `(ref null noexn)`. */ +// export const nullexnref: Type = BinaryenObj["_BinaryenTypeNullExnref"](); // TODO: uncomment once supported in Binaryen +/** Reference type `(ref null noextern)`. */ +export const nullexternref: Type = BinaryenObj["_BinaryenTypeNullExternref"](); + +// ### Packed Types ### // +export const notPacked: Type = BinaryenObj["_BinaryenPackedTypeNotPacked"](); +export const i8: Type = BinaryenObj["_BinaryenPackedTypeInt8"](); +export const i16: Type = BinaryenObj["_BinaryenPackedTypeInt16"](); + +// ### Proposed Types ### // +// These types are not yet in the WASM spec. Move them to their respective sections once finalized. +/** Reference type `(ref null string)`. */ +export const stringref: Type = BinaryenObj["_BinaryenTypeStringref"](); + + + +export function createType(types: readonly Type[]): Type { + return preserveStack(() => BinaryenObj["_BinaryenTypeCreate"](i32sToStack(types), types.length)); +} + +export function expandType(typ: Type): Type[] { + return preserveStack(() => { + const numTypes = BinaryenObj["_BinaryenTypeArity"](typ); + const array = stackAlloc(numTypes << 2); + BinaryenObj["_BinaryenTypeExpand"](typ, array); + const types = new Array(numTypes); + for (let i = 0; i < numTypes; i++) { + types[i] = HEAPU32[(array >>> 2) + i]; + } + return types; + }); +} + + + +// ## Instructions ## // +// see https://webassembly.github.io/spec/core/syntax/instructions.html +export enum ExpressionId { + // ### Binaryen-Only Instruction Ids ### // + Invalid = BinaryenObj["_BinaryenInvalidId"](), + Pop = BinaryenObj["_BinaryenPopId"](), + TupleMake = BinaryenObj["_BinaryenTupleMakeId"](), + TupleExtract = BinaryenObj["_BinaryenTupleExtractId"](), + + // ### Parametric Instruction Ids ### // + Nop = BinaryenObj["_BinaryenNopId"](), + Unreachable = BinaryenObj["_BinaryenUnreachableId"](), + Drop = BinaryenObj["_BinaryenDropId"](), + Select = BinaryenObj["_BinaryenSelectId"](), + + // ### Control Instruction Ids ### // + Block = BinaryenObj["_BinaryenBlockId"](), + Loop = BinaryenObj["_BinaryenLoopId"](), + If = BinaryenObj["_BinaryenIfId"](), + Break = BinaryenObj["_BinaryenBreakId"](), + Switch = BinaryenObj["_BinaryenSwitchId"](), + BrOn = BinaryenObj["_BinaryenBrOnId"](), + Call = BinaryenObj["_BinaryenCallId"](), + CallRef = BinaryenObj["_BinaryenCallRefId"](), + CallIndirect = BinaryenObj["_BinaryenCallIndirectId"](), + Return = BinaryenObj["_BinaryenReturnId"](), + Throw = BinaryenObj["_BinaryenThrowId"](), + Rethrow = BinaryenObj["_BinaryenRethrowId"](), + Try = BinaryenObj["_BinaryenTryId"](), + + // ### Variable Instruction Ids ### // + LocalGet = BinaryenObj["_BinaryenLocalGetId"](), + LocalSet = BinaryenObj["_BinaryenLocalSetId"](), + GlobalGet = BinaryenObj["_BinaryenGlobalGetId"](), + GlobalSet = BinaryenObj["_BinaryenGlobalSetId"](), + + // ### Table Instruction Ids ### // + TableGet = BinaryenObj["_BinaryenTableGetId"](), + TableSet = BinaryenObj["_BinaryenTableSetId"](), + TableSize = BinaryenObj["_BinaryenTableSizeId"](), + TableGrow = BinaryenObj["_BinaryenTableGrowId"](), + + // ### Memory Instruction Ids ### // + Load = BinaryenObj["_BinaryenLoadId"](), + Store = BinaryenObj["_BinaryenStoreId"](), + SIMDLoad = BinaryenObj["_BinaryenSIMDLoadId"](), + SIMDLoadStoreLane = BinaryenObj["_BinaryenSIMDLoadStoreLaneId"](), + MemorySize = BinaryenObj["_BinaryenMemorySizeId"](), + MemoryGrow = BinaryenObj["_BinaryenMemoryGrowId"](), + MemoryFill = BinaryenObj["_BinaryenMemoryFillId"](), + MemoryCopy = BinaryenObj["_BinaryenMemoryCopyId"](), + MemoryInit = BinaryenObj["_BinaryenMemoryInitId"](), + DataDrop = BinaryenObj["_BinaryenDataDropId"](), + + // ### Reference Instruction Ids ### // + RefFunc = BinaryenObj["_BinaryenRefFuncId"](), + RefNull = BinaryenObj["_BinaryenRefNullId"](), + RefIsNull = BinaryenObj["_BinaryenRefIsNullId"](), + RefAs = BinaryenObj["_BinaryenRefAsId"](), + RefEq = BinaryenObj["_BinaryenRefEqId"](), + RefTest = BinaryenObj["_BinaryenRefTestId"](), + RefCast = BinaryenObj["_BinaryenRefCastId"](), + + // ### Aggregate Instruction Ids ### // + StructNew = BinaryenObj["_BinaryenStructNewId"](), + StructGet = BinaryenObj["_BinaryenStructGetId"](), + StructSet = BinaryenObj["_BinaryenStructSetId"](), + ArrayNew = BinaryenObj["_BinaryenArrayNewId"](), + ArrayNewFixed = BinaryenObj["_BinaryenArrayNewFixedId"](), + ArrayNewData = BinaryenObj["_BinaryenArrayNewDataId"](), + ArrayNewElem = BinaryenObj["_BinaryenArrayNewElemId"](), + ArrayGet = BinaryenObj["_BinaryenArrayGetId"](), + ArraySet = BinaryenObj["_BinaryenArraySetId"](), + ArrayLen = BinaryenObj["_BinaryenArrayLenId"](), + ArrayFill = BinaryenObj["_BinaryenArrayFillId"](), + ArrayCopy = BinaryenObj["_BinaryenArrayCopyId"](), + ArrayInitData = BinaryenObj["_BinaryenArrayInitDataId"](), + ArrayInitElem = BinaryenObj["_BinaryenArrayInitElemId"](), + RefI31 = BinaryenObj["_BinaryenRefI31Id"](), + I31Get = BinaryenObj["_BinaryenI31GetId"](), + + // ### Numeric & Vector Instruction Ids ### // + Const = BinaryenObj["_BinaryenConstId"](), + Unary = BinaryenObj["_BinaryenUnaryId"](), + Binary = BinaryenObj["_BinaryenBinaryId"](), + SIMDTernary = BinaryenObj["_BinaryenSIMDTernaryId"](), + SIMDShift = BinaryenObj["_BinaryenSIMDShiftId"](), + SIMDShuffle = BinaryenObj["_BinaryenSIMDShuffleId"](), + SIMDExtract = BinaryenObj["_BinaryenSIMDExtractId"](), + SIMDReplace = BinaryenObj["_BinaryenSIMDReplaceId"](), + + // ### Atomic Instruction Ids ### // + AtomicCmpxchg = BinaryenObj["_BinaryenAtomicCmpxchgId"](), + AtomicRMW = BinaryenObj["_BinaryenAtomicRMWId"](), + AtomicWait = BinaryenObj["_BinaryenAtomicWaitId"](), + AtomicNotify = BinaryenObj["_BinaryenAtomicNotifyId"](), + AtomicFence = BinaryenObj["_BinaryenAtomicFenceId"](), + + // ### Proposed Instruction Ids ### // + // These insructions are not yet in the WASM spec. Move them to their respective sections once finalized. + StringNew = BinaryenObj["_BinaryenStringNewId"](), + StringConst = BinaryenObj["_BinaryenStringConstId"](), + StringMeasure = BinaryenObj["_BinaryenStringMeasureId"](), + StringEncode = BinaryenObj["_BinaryenStringEncodeId"](), + StringConcat = BinaryenObj["_BinaryenStringConcatId"](), + StringEq = BinaryenObj["_BinaryenStringEqId"](), + StringWTF16Get = BinaryenObj["_BinaryenStringWTF16GetId"](), + StringSliceWTF = BinaryenObj["_BinaryenStringSliceWTFId"](), +} + + + +// ## Externals ## // +// see https://webassembly.github.io/spec/core/syntax/modules.html +export enum ExternalKind { + ExternalTag = BinaryenObj["_BinaryenExternalTag"](), + ExternalGlobal = BinaryenObj["_BinaryenExternalGlobal"](), + ExternalMemory = BinaryenObj["_BinaryenExternalMemory"](), + ExternalTable = BinaryenObj["_BinaryenExternalTable"](), + ExternalFunction = BinaryenObj["_BinaryenExternalFunction"](), +} + + + +export enum MemoryOrder { + unordered = BinaryenObj["_BinaryenMemoryOrderUnordered"](), + seqcst = BinaryenObj["_BinaryenMemoryOrderSeqCst"](), + acqrel = BinaryenObj["_BinaryenMemoryOrderAcqRel"](), +} diff --git a/ts/src/pre.ts b/ts/src/pre.ts new file mode 100644 index 00000000000..324068f6e69 --- /dev/null +++ b/ts/src/pre.ts @@ -0,0 +1,14 @@ +// # Preprocess # // +// Artifacts provided by the Emscripten build. + + + +/** The main object provided by Emscripten. This is what gets wrapped. */ +export declare const BinaryenObj: Readonly>; + + + +export declare function stackSave(): unknown; +export declare function stackRestore(stack: unknown): unknown; +export declare function stackAlloc(length: number): number; +export declare function stringToUTF8OnStack(str: string): number; diff --git a/ts/src/utils.ts b/ts/src/utils.ts new file mode 100644 index 00000000000..d4fa82bf686 --- /dev/null +++ b/ts/src/utils.ts @@ -0,0 +1,66 @@ +import { + BinaryenObj, + stackAlloc, + stackRestore, + stackSave, + stringToUTF8OnStack, +} from "./pre.ts"; + + + +// # Utilities # // +// Global functions and constants needed across all `.ts` files. These are not exported publicly. + + + +export const HEAP8: Int8Array = BinaryenObj["HEAP8"]; +export const HEAPU8: Uint8Array = BinaryenObj["HEAPU8"]; +export const HEAP32: Int32Array = BinaryenObj["HEAP32"]; +export const HEAPU32: Uint32Array = BinaryenObj["HEAPU32"]; + + + +/** + * Exports friendly API methods. + * @param func [description] + * @return [description] + */ +export function preserveStack(func: () => T): T { + try { + var stack = stackSave(); + return func(); + } finally { + stackRestore(stack); + } +} + +/** + * [description] + * @param str [description] + * @return [description] + */ +export function strToStack(str?: string): number { + return str ? stringToUTF8OnStack(str) : 0; +} + +/** + * [description] + * @param i32s [description] + * @return [description] + */ +export function i32sToStack(i32s: readonly number[]): number { + const ret = stackAlloc(i32s.length << 2); + HEAP32.set(i32s, ret >>> 2); + return ret; +} + +/** + * [description] + * @param i8s [description] + * @return [description] + */ +export function i8sToStack(i8s: readonly number[]): number { + const ret = stackAlloc(i8s.length); + HEAP8.set(i8s, ret); + return ret; +} From f04b5c21e6454c6edcbef97041c2c7746aadf592 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 01:04:06 -0400 Subject: [PATCH 003/247] feat: add enums Operation & SideEffect --- ts/src/expressions.ts | 481 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 481 insertions(+) diff --git a/ts/src/expressions.ts b/ts/src/expressions.ts index 7ebc66af74d..0a0728f4d55 100644 --- a/ts/src/expressions.ts +++ b/ts/src/expressions.ts @@ -218,6 +218,465 @@ export enum ExpressionId { +// ## Numeric Operations ## // +// see https://webassembly.github.io/spec/core/exec/numerics.html +export enum Operation { + // ### Control Operations ### // + BrOnNull = BinaryenObj["_BinaryenBrOnNull"](), + BrOnNonNull = BinaryenObj["_BinaryenBrOnNonNull"](), + BrOnCast = BinaryenObj["_BinaryenBrOnCast"](), + BrOnCastFail = BinaryenObj["_BinaryenBrOnCastFail"](), + + // ### Memory Operations ### // + Load8LaneVec128 = BinaryenObj["_BinaryenLoad8LaneVec128"](), + Load16LaneVec128 = BinaryenObj["_BinaryenLoad16LaneVec128"](), + Load32LaneVec128 = BinaryenObj["_BinaryenLoad32LaneVec128"](), + Load64LaneVec128 = BinaryenObj["_BinaryenLoad64LaneVec128"](), + Load8x8UVec128 = BinaryenObj["_BinaryenLoad8x8UVec128"](), + Load8x8SVec128 = BinaryenObj["_BinaryenLoad8x8SVec128"](), + Load16x4UVec128 = BinaryenObj["_BinaryenLoad16x4UVec128"](), + Load16x4SVec128 = BinaryenObj["_BinaryenLoad16x4SVec128"](), + Load32x2UVec128 = BinaryenObj["_BinaryenLoad32x2UVec128"](), + Load32x2SVec128 = BinaryenObj["_BinaryenLoad32x2SVec128"](), + Load8SplatVec128 = BinaryenObj["_BinaryenLoad8SplatVec128"](), + Load16SplatVec128 = BinaryenObj["_BinaryenLoad16SplatVec128"](), + Load32SplatVec128 = BinaryenObj["_BinaryenLoad32SplatVec128"](), + Load64SplatVec128 = BinaryenObj["_BinaryenLoad64SplatVec128"](), + Load32ZeroVec128 = BinaryenObj["_BinaryenLoad32ZeroVec128"](), + Load64ZeroVec128 = BinaryenObj["_BinaryenLoad64ZeroVec128"](), + Store8LaneVec128 = BinaryenObj["_BinaryenStore8LaneVec128"](), + Store16LaneVec128 = BinaryenObj["_BinaryenStore16LaneVec128"](), + Store32LaneVec128 = BinaryenObj["_BinaryenStore32LaneVec128"](), + Store64LaneVec128 = BinaryenObj["_BinaryenStore64LaneVec128"](), + + // ### Reference Operations ### // + RefAsNonNull = BinaryenObj["_BinaryenRefAsNonNull"](), + RefAsExternInternalize = BinaryenObj["_BinaryenRefAsExternInternalize"](), + RefAsExternExternalize = BinaryenObj["_BinaryenRefAsExternExternalize"](), + RefAsAnyConvertExtern = BinaryenObj["_BinaryenRefAsAnyConvertExtern"](), + RefAsExternConvertAny = BinaryenObj["_BinaryenRefAsExternConvertAny"](), + + // ### Integer Operations ### // + AddInt32 = BinaryenObj["_BinaryenAddInt32"](), + AddInt64 = BinaryenObj["_BinaryenAddInt64"](), + SubInt32 = BinaryenObj["_BinaryenSubInt32"](), + SubInt64 = BinaryenObj["_BinaryenSubInt64"](), + MulInt32 = BinaryenObj["_BinaryenMulInt32"](), + MulInt64 = BinaryenObj["_BinaryenMulInt64"](), + DivUInt32 = BinaryenObj["_BinaryenDivUInt32"](), + DivUInt64 = BinaryenObj["_BinaryenDivUInt64"](), + DivSInt32 = BinaryenObj["_BinaryenDivSInt32"](), + DivSInt64 = BinaryenObj["_BinaryenDivSInt64"](), + RemUInt32 = BinaryenObj["_BinaryenRemUInt32"](), + RemUInt64 = BinaryenObj["_BinaryenRemUInt64"](), + RemSInt32 = BinaryenObj["_BinaryenRemSInt32"](), + RemSInt64 = BinaryenObj["_BinaryenRemSInt64"](), + AndInt32 = BinaryenObj["_BinaryenAndInt32"](), + AndInt64 = BinaryenObj["_BinaryenAndInt64"](), + OrInt32 = BinaryenObj["_BinaryenOrInt32"](), + OrInt64 = BinaryenObj["_BinaryenOrInt64"](), + XorInt32 = BinaryenObj["_BinaryenXorInt32"](), + XorInt64 = BinaryenObj["_BinaryenXorInt64"](), + ShlInt32 = BinaryenObj["_BinaryenShlInt32"](), + ShlInt64 = BinaryenObj["_BinaryenShlInt64"](), + ShrUInt32 = BinaryenObj["_BinaryenShrUInt32"](), + ShrUInt64 = BinaryenObj["_BinaryenShrUInt64"](), + ShrSInt32 = BinaryenObj["_BinaryenShrSInt32"](), + ShrSInt64 = BinaryenObj["_BinaryenShrSInt64"](), + RotLInt32 = BinaryenObj["_BinaryenRotLInt32"](), + RotLInt64 = BinaryenObj["_BinaryenRotLInt64"](), + RotRInt32 = BinaryenObj["_BinaryenRotRInt32"](), + RotRInt64 = BinaryenObj["_BinaryenRotRInt64"](), + ClzInt32 = BinaryenObj["_BinaryenClzInt32"](), + ClzInt64 = BinaryenObj["_BinaryenClzInt64"](), + CtzInt32 = BinaryenObj["_BinaryenCtzInt32"](), + CtzInt64 = BinaryenObj["_BinaryenCtzInt64"](), + PopcntInt32 = BinaryenObj["_BinaryenPopcntInt32"](), + PopcntInt64 = BinaryenObj["_BinaryenPopcntInt64"](), + EqZInt32 = BinaryenObj["_BinaryenEqZInt32"](), + EqZInt64 = BinaryenObj["_BinaryenEqZInt64"](), + EqInt32 = BinaryenObj["_BinaryenEqInt32"](), + EqInt64 = BinaryenObj["_BinaryenEqInt64"](), + NeInt32 = BinaryenObj["_BinaryenNeInt32"](), + NeInt64 = BinaryenObj["_BinaryenNeInt64"](), + LtUInt32 = BinaryenObj["_BinaryenLtUInt32"](), + LtUInt64 = BinaryenObj["_BinaryenLtUInt64"](), + LtSInt32 = BinaryenObj["_BinaryenLtSInt32"](), + LtSInt64 = BinaryenObj["_BinaryenLtSInt64"](), + GtUInt32 = BinaryenObj["_BinaryenGtUInt32"](), + GtUInt64 = BinaryenObj["_BinaryenGtUInt64"](), + GtSInt32 = BinaryenObj["_BinaryenGtSInt32"](), + GtSInt64 = BinaryenObj["_BinaryenGtSInt64"](), + LeUInt32 = BinaryenObj["_BinaryenLeUInt32"](), + LeUInt64 = BinaryenObj["_BinaryenLeUInt64"](), + LeSInt32 = BinaryenObj["_BinaryenLeSInt32"](), + LeSInt64 = BinaryenObj["_BinaryenLeSInt64"](), + GeUInt32 = BinaryenObj["_BinaryenGeUInt32"](), + GeUInt64 = BinaryenObj["_BinaryenGeUInt64"](), + GeSInt32 = BinaryenObj["_BinaryenGeSInt32"](), + GeSInt64 = BinaryenObj["_BinaryenGeSInt64"](), + ExtendS8Int32 = BinaryenObj["_BinaryenExtendS8Int32"](), + ExtendS8Int64 = BinaryenObj["_BinaryenExtendS8Int64"](), + ExtendS16Int32 = BinaryenObj["_BinaryenExtendS16Int32"](), + ExtendS16Int64 = BinaryenObj["_BinaryenExtendS16Int64"](), + ExtendS32Int64 = BinaryenObj["_BinaryenExtendS32Int64"](), + + // ### Floating-Point Operations ### // + AddFloat32 = BinaryenObj["_BinaryenAddFloat32"](), + AddFloat64 = BinaryenObj["_BinaryenAddFloat64"](), + SubFloat32 = BinaryenObj["_BinaryenSubFloat32"](), + SubFloat64 = BinaryenObj["_BinaryenSubFloat64"](), + MulFloat32 = BinaryenObj["_BinaryenMulFloat32"](), + MulFloat64 = BinaryenObj["_BinaryenMulFloat64"](), + DivFloat32 = BinaryenObj["_BinaryenDivFloat32"](), + DivFloat64 = BinaryenObj["_BinaryenDivFloat64"](), + MinFloat32 = BinaryenObj["_BinaryenMinFloat32"](), + MinFloat64 = BinaryenObj["_BinaryenMinFloat64"](), + MaxFloat32 = BinaryenObj["_BinaryenMaxFloat32"](), + MaxFloat64 = BinaryenObj["_BinaryenMaxFloat64"](), + CopySignFloat32 = BinaryenObj["_BinaryenCopySignFloat32"](), + CopySignFloat64 = BinaryenObj["_BinaryenCopySignFloat64"](), + AbsFloat32 = BinaryenObj["_BinaryenAbsFloat32"](), + AbsFloat64 = BinaryenObj["_BinaryenAbsFloat64"](), + NegFloat32 = BinaryenObj["_BinaryenNegFloat32"](), + NegFloat64 = BinaryenObj["_BinaryenNegFloat64"](), + SqrtFloat32 = BinaryenObj["_BinaryenSqrtFloat32"](), + SqrtFloat64 = BinaryenObj["_BinaryenSqrtFloat64"](), + CeilFloat32 = BinaryenObj["_BinaryenCeilFloat32"](), + CeilFloat64 = BinaryenObj["_BinaryenCeilFloat64"](), + FloorFloat32 = BinaryenObj["_BinaryenFloorFloat32"](), + FloorFloat64 = BinaryenObj["_BinaryenFloorFloat64"](), + TruncFloat32 = BinaryenObj["_BinaryenTruncFloat32"](), + TruncFloat64 = BinaryenObj["_BinaryenTruncFloat64"](), + NearestFloat32 = BinaryenObj["_BinaryenNearestFloat32"](), + NearestFloat64 = BinaryenObj["_BinaryenNearestFloat64"](), + EqFloat32 = BinaryenObj["_BinaryenEqFloat32"](), + EqFloat64 = BinaryenObj["_BinaryenEqFloat64"](), + NeFloat32 = BinaryenObj["_BinaryenNeFloat32"](), + NeFloat64 = BinaryenObj["_BinaryenNeFloat64"](), + LtFloat32 = BinaryenObj["_BinaryenLtFloat32"](), + LtFloat64 = BinaryenObj["_BinaryenLtFloat64"](), + GtFloat32 = BinaryenObj["_BinaryenGtFloat32"](), + GtFloat64 = BinaryenObj["_BinaryenGtFloat64"](), + LeFloat32 = BinaryenObj["_BinaryenLeFloat32"](), + LeFloat64 = BinaryenObj["_BinaryenLeFloat64"](), + GeFloat32 = BinaryenObj["_BinaryenGeFloat32"](), + GeFloat64 = BinaryenObj["_BinaryenGeFloat64"](), + + // ### Conversions ### // + ExtendSInt32 = BinaryenObj["_BinaryenExtendSInt32"](), + ExtendUInt32 = BinaryenObj["_BinaryenExtendUInt32"](), + WrapInt64 = BinaryenObj["_BinaryenWrapInt64"](), + TruncUFloat32ToInt32 = BinaryenObj["_BinaryenTruncUFloat32ToInt32"](), + TruncUFloat32ToInt64 = BinaryenObj["_BinaryenTruncUFloat32ToInt64"](), + TruncUFloat64ToInt32 = BinaryenObj["_BinaryenTruncUFloat64ToInt32"](), + TruncUFloat64ToInt64 = BinaryenObj["_BinaryenTruncUFloat64ToInt64"](), + TruncSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSFloat32ToInt32"](), + TruncSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSFloat32ToInt64"](), + TruncSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSFloat64ToInt32"](), + TruncSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSFloat64ToInt64"](), + TruncSatUFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt32"](), + TruncSatUFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt64"](), + TruncSatUFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt32"](), + TruncSatUFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt64"](), + TruncSatSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt32"](), + TruncSatSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt64"](), + TruncSatSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt32"](), + TruncSatSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt64"](), + PromoteFloat32 = BinaryenObj["_BinaryenPromoteFloat32"](), + DemoteFloat64 = BinaryenObj["_BinaryenDemoteFloat64"](), + ConvertUInt32ToFloat32 = BinaryenObj["_BinaryenConvertUInt32ToFloat32"](), + ConvertUInt32ToFloat64 = BinaryenObj["_BinaryenConvertUInt32ToFloat64"](), + ConvertUInt64ToFloat32 = BinaryenObj["_BinaryenConvertUInt64ToFloat32"](), + ConvertUInt64ToFloat64 = BinaryenObj["_BinaryenConvertUInt64ToFloat64"](), + ConvertSInt32ToFloat32 = BinaryenObj["_BinaryenConvertSInt32ToFloat32"](), + ConvertSInt32ToFloat64 = BinaryenObj["_BinaryenConvertSInt32ToFloat64"](), + ConvertSInt64ToFloat32 = BinaryenObj["_BinaryenConvertSInt64ToFloat32"](), + ConvertSInt64ToFloat64 = BinaryenObj["_BinaryenConvertSInt64ToFloat64"](), + ReinterpretInt32 = BinaryenObj["_BinaryenReinterpretInt32"](), + ReinterpretInt64 = BinaryenObj["_BinaryenReinterpretInt64"](), + ReinterpretFloat32 = BinaryenObj["_BinaryenReinterpretFloat32"](), + ReinterpretFloat64 = BinaryenObj["_BinaryenReinterpretFloat64"](), + + // ### Vector Operations ### // + // #### vvunop #### // + NotVec128 = BinaryenObj["_BinaryenNotVec128"](), + // #### vvbinop #### // + AndVec128 = BinaryenObj["_BinaryenAndVec128"](), + AndNotVec128 = BinaryenObj["_BinaryenAndNotVec128"](), + OrVec128 = BinaryenObj["_BinaryenOrVec128"](), + XorVec128 = BinaryenObj["_BinaryenXorVec128"](), + // #### vvternop #### // + BitselectVec128 = BinaryenObj["_BinaryenBitselectVec128"](), + // #### vvtestop #### // + AnyTrueVec128 = BinaryenObj["_BinaryenAnyTrueVec128"](), + // #### vunop_i #### // + AbsVecI8x16 = BinaryenObj["_BinaryenAbsVecI8x16"](), + AbsVecI16x8 = BinaryenObj["_BinaryenAbsVecI16x8"](), + AbsVecI32x4 = BinaryenObj["_BinaryenAbsVecI32x4"](), + AbsVecI64x2 = BinaryenObj["_BinaryenAbsVecI64x2"](), + NegVecI8x16 = BinaryenObj["_BinaryenNegVecI8x16"](), + NegVecI16x8 = BinaryenObj["_BinaryenNegVecI16x8"](), + NegVecI32x4 = BinaryenObj["_BinaryenNegVecI32x4"](), + NegVecI64x2 = BinaryenObj["_BinaryenNegVecI64x2"](), + PopcntVecI8x16 = BinaryenObj["_BinaryenPopcntVecI8x16"](), + // #### vunop_f #### // + AbsVecF32x4 = BinaryenObj["_BinaryenAbsVecF32x4"](), + AbsVecF64x2 = BinaryenObj["_BinaryenAbsVecF64x2"](), + NegVecF32x4 = BinaryenObj["_BinaryenNegVecF32x4"](), + NegVecF64x2 = BinaryenObj["_BinaryenNegVecF64x2"](), + SqrtVecF32x4 = BinaryenObj["_BinaryenSqrtVecF32x4"](), + SqrtVecF64x2 = BinaryenObj["_BinaryenSqrtVecF64x2"](), + CeilVecF32x4 = BinaryenObj["_BinaryenCeilVecF32x4"](), + CeilVecF64x2 = BinaryenObj["_BinaryenCeilVecF64x2"](), + FloorVecF32x4 = BinaryenObj["_BinaryenFloorVecF32x4"](), + FloorVecF64x2 = BinaryenObj["_BinaryenFloorVecF64x2"](), + TruncVecF32x4 = BinaryenObj["_BinaryenTruncVecF32x4"](), + TruncVecF64x2 = BinaryenObj["_BinaryenTruncVecF64x2"](), + NearestVecF32x4 = BinaryenObj["_BinaryenNearestVecF32x4"](), + NearestVecF64x2 = BinaryenObj["_BinaryenNearestVecF64x2"](), + // #### vbinop_i #### // + AddVecI8x16 = BinaryenObj["_BinaryenAddVecI8x16"](), + AddVecI16x8 = BinaryenObj["_BinaryenAddVecI16x8"](), + AddVecI32x4 = BinaryenObj["_BinaryenAddVecI32x4"](), + AddVecI64x2 = BinaryenObj["_BinaryenAddVecI64x2"](), + SubVecI8x16 = BinaryenObj["_BinaryenSubVecI8x16"](), + SubVecI16x8 = BinaryenObj["_BinaryenSubVecI16x8"](), + SubVecI32x4 = BinaryenObj["_BinaryenSubVecI32x4"](), + SubVecI64x2 = BinaryenObj["_BinaryenSubVecI64x2"](), + AddSatUVecI8x16 = BinaryenObj["_BinaryenAddSatUVecI8x16"](), + AddSatUVecI16x8 = BinaryenObj["_BinaryenAddSatUVecI16x8"](), + AddSatSVecI8x16 = BinaryenObj["_BinaryenAddSatSVecI8x16"](), + AddSatSVecI16x8 = BinaryenObj["_BinaryenAddSatSVecI16x8"](), + SubSatUVecI8x16 = BinaryenObj["_BinaryenSubSatUVecI8x16"](), + SubSatUVecI16x8 = BinaryenObj["_BinaryenSubSatUVecI16x8"](), + SubSatSVecI8x16 = BinaryenObj["_BinaryenSubSatSVecI8x16"](), + SubSatSVecI16x8 = BinaryenObj["_BinaryenSubSatSVecI16x8"](), + MulVecI16x8 = BinaryenObj["_BinaryenMulVecI16x8"](), + MulVecI32x4 = BinaryenObj["_BinaryenMulVecI32x4"](), + MulVecI64x2 = BinaryenObj["_BinaryenMulVecI64x2"](), + AvgrUVecI8x16 = BinaryenObj["_BinaryenAvgrUVecI8x16"](), + AvgrUVecI16x8 = BinaryenObj["_BinaryenAvgrUVecI16x8"](), + Q15MulrSatSVecI16x8 = BinaryenObj["_BinaryenQ15MulrSatSVecI16x8"](), + RelaxedQ15MulrSVecI16x8 = BinaryenObj["_BinaryenRelaxedQ15MulrSVecI16x8"](), + MinUVecI8x16 = BinaryenObj["_BinaryenMinUVecI8x16"](), + MinUVecI16x8 = BinaryenObj["_BinaryenMinUVecI16x8"](), + MinUVecI32x4 = BinaryenObj["_BinaryenMinUVecI32x4"](), + MinSVecI8x16 = BinaryenObj["_BinaryenMinSVecI8x16"](), + MinSVecI16x8 = BinaryenObj["_BinaryenMinSVecI16x8"](), + MinSVecI32x4 = BinaryenObj["_BinaryenMinSVecI32x4"](), + MaxUVecI8x16 = BinaryenObj["_BinaryenMaxUVecI8x16"](), + MaxUVecI16x8 = BinaryenObj["_BinaryenMaxUVecI16x8"](), + MaxUVecI32x4 = BinaryenObj["_BinaryenMaxUVecI32x4"](), + MaxSVecI8x16 = BinaryenObj["_BinaryenMaxSVecI8x16"](), + MaxSVecI16x8 = BinaryenObj["_BinaryenMaxSVecI16x8"](), + MaxSVecI32x4 = BinaryenObj["_BinaryenMaxSVecI32x4"](), + // #### vbinop_f #### // + AddVecF32x4 = BinaryenObj["_BinaryenAddVecF32x4"](), + AddVecF64x2 = BinaryenObj["_BinaryenAddVecF64x2"](), + SubVecF32x4 = BinaryenObj["_BinaryenSubVecF32x4"](), + SubVecF64x2 = BinaryenObj["_BinaryenSubVecF64x2"](), + MulVecF32x4 = BinaryenObj["_BinaryenMulVecF32x4"](), + MulVecF64x2 = BinaryenObj["_BinaryenMulVecF64x2"](), + DivVecF32x4 = BinaryenObj["_BinaryenDivVecF32x4"](), + DivVecF64x2 = BinaryenObj["_BinaryenDivVecF64x2"](), + MinVecF32x4 = BinaryenObj["_BinaryenMinVecF32x4"](), + MinVecF64x2 = BinaryenObj["_BinaryenMinVecF64x2"](), + MaxVecF32x4 = BinaryenObj["_BinaryenMaxVecF32x4"](), + MaxVecF64x2 = BinaryenObj["_BinaryenMaxVecF64x2"](), + PMinVecF32x4 = BinaryenObj["_BinaryenPMinVecF32x4"](), + PMinVecF64x2 = BinaryenObj["_BinaryenPMinVecF64x2"](), + PMaxVecF32x4 = BinaryenObj["_BinaryenPMaxVecF32x4"](), + PMaxVecF64x2 = BinaryenObj["_BinaryenPMaxVecF64x2"](), + RelaxedMinVecF32x4 = BinaryenObj["_BinaryenRelaxedMinVecF32x4"](), + RelaxedMinVecF64x2 = BinaryenObj["_BinaryenRelaxedMinVecF64x2"](), + RelaxedMaxVecF32x4 = BinaryenObj["_BinaryenRelaxedMaxVecF32x4"](), + RelaxedMaxVecF64x2 = BinaryenObj["_BinaryenRelaxedMaxVecF64x2"](), + // #### vternop_i #### // + LaneselectI8x16 = BinaryenObj["_BinaryenLaneselectI8x16"](), + LaneselectI16x8 = BinaryenObj["_BinaryenLaneselectI16x8"](), + LaneselectI32x4 = BinaryenObj["_BinaryenLaneselectI32x4"](), + LaneselectI64x2 = BinaryenObj["_BinaryenLaneselectI64x2"](), + // #### vternop_f #### // + RelaxedMaddVecF32x4 = BinaryenObj["_BinaryenRelaxedMaddVecF32x4"](), + RelaxedMaddVecF64x2 = BinaryenObj["_BinaryenRelaxedMaddVecF64x2"](), + RelaxedNmaddVecF32x4 = BinaryenObj["_BinaryenRelaxedNmaddVecF32x4"](), + RelaxedNmaddVecF64x2 = BinaryenObj["_BinaryenRelaxedNmaddVecF64x2"](), + // #### vtestop_i #### // + AllTrueVecI8x16 = BinaryenObj["_BinaryenAllTrueVecI8x16"](), + AllTrueVecI16x8 = BinaryenObj["_BinaryenAllTrueVecI16x8"](), + AllTrueVecI32x4 = BinaryenObj["_BinaryenAllTrueVecI32x4"](), + AllTrueVecI64x2 = BinaryenObj["_BinaryenAllTrueVecI64x2"](), + // #### vrelop_i #### // + EqVecI8x16 = BinaryenObj["_BinaryenEqVecI8x16"](), + EqVecI16x8 = BinaryenObj["_BinaryenEqVecI16x8"](), + EqVecI32x4 = BinaryenObj["_BinaryenEqVecI32x4"](), + EqVecI64x2 = BinaryenObj["_BinaryenEqVecI64x2"](), + NeVecI8x16 = BinaryenObj["_BinaryenNeVecI8x16"](), + NeVecI16x8 = BinaryenObj["_BinaryenNeVecI16x8"](), + NeVecI32x4 = BinaryenObj["_BinaryenNeVecI32x4"](), + NeVecI64x2 = BinaryenObj["_BinaryenNeVecI64x2"](), + LtUVecI8x16 = BinaryenObj["_BinaryenLtUVecI8x16"](), + LtUVecI16x8 = BinaryenObj["_BinaryenLtUVecI16x8"](), + LtUVecI32x4 = BinaryenObj["_BinaryenLtUVecI32x4"](), + LtSVecI8x16 = BinaryenObj["_BinaryenLtSVecI8x16"](), + LtSVecI16x8 = BinaryenObj["_BinaryenLtSVecI16x8"](), + LtSVecI32x4 = BinaryenObj["_BinaryenLtSVecI32x4"](), + LtSVecI64x2 = BinaryenObj["_BinaryenLtSVecI64x2"](), + GtUVecI8x16 = BinaryenObj["_BinaryenGtUVecI8x16"](), + GtUVecI16x8 = BinaryenObj["_BinaryenGtUVecI16x8"](), + GtUVecI32x4 = BinaryenObj["_BinaryenGtUVecI32x4"](), + GtSVecI8x16 = BinaryenObj["_BinaryenGtSVecI8x16"](), + GtSVecI16x8 = BinaryenObj["_BinaryenGtSVecI16x8"](), + GtSVecI32x4 = BinaryenObj["_BinaryenGtSVecI32x4"](), + GtSVecI64x2 = BinaryenObj["_BinaryenGtSVecI64x2"](), + LeUVecI8x16 = BinaryenObj["_BinaryenLeUVecI8x16"](), + LeUVecI16x8 = BinaryenObj["_BinaryenLeUVecI16x8"](), + LeUVecI32x4 = BinaryenObj["_BinaryenLeUVecI32x4"](), + LeSVecI8x16 = BinaryenObj["_BinaryenLeSVecI8x16"](), + LeSVecI16x8 = BinaryenObj["_BinaryenLeSVecI16x8"](), + LeSVecI32x4 = BinaryenObj["_BinaryenLeSVecI32x4"](), + LeSVecI64x2 = BinaryenObj["_BinaryenLeSVecI64x2"](), + GeUVecI8x16 = BinaryenObj["_BinaryenGeUVecI8x16"](), + GeUVecI16x8 = BinaryenObj["_BinaryenGeUVecI16x8"](), + GeUVecI32x4 = BinaryenObj["_BinaryenGeUVecI32x4"](), + GeSVecI8x16 = BinaryenObj["_BinaryenGeSVecI8x16"](), + GeSVecI16x8 = BinaryenObj["_BinaryenGeSVecI16x8"](), + GeSVecI32x4 = BinaryenObj["_BinaryenGeSVecI32x4"](), + GeSVecI64x2 = BinaryenObj["_BinaryenGeSVecI64x2"](), + // #### vrelop_f #### // + EqVecF32x4 = BinaryenObj["_BinaryenEqVecF32x4"](), + EqVecF64x2 = BinaryenObj["_BinaryenEqVecF64x2"](), + NeVecF32x4 = BinaryenObj["_BinaryenNeVecF32x4"](), + NeVecF64x2 = BinaryenObj["_BinaryenNeVecF64x2"](), + LtVecF32x4 = BinaryenObj["_BinaryenLtVecF32x4"](), + LtVecF64x2 = BinaryenObj["_BinaryenLtVecF64x2"](), + GtVecF32x4 = BinaryenObj["_BinaryenGtVecF32x4"](), + GtVecF64x2 = BinaryenObj["_BinaryenGtVecF64x2"](), + LeVecF32x4 = BinaryenObj["_BinaryenLeVecF32x4"](), + LeVecF64x2 = BinaryenObj["_BinaryenLeVecF64x2"](), + GeVecF32x4 = BinaryenObj["_BinaryenGeVecF32x4"](), + GeVecF64x2 = BinaryenObj["_BinaryenGeVecF64x2"](), + // #### vshiftop #### // + ShlVecI8x16 = BinaryenObj["_BinaryenShlVecI8x16"](), + ShlVecI16x8 = BinaryenObj["_BinaryenShlVecI16x8"](), + ShlVecI32x4 = BinaryenObj["_BinaryenShlVecI32x4"](), + ShlVecI64x2 = BinaryenObj["_BinaryenShlVecI64x2"](), + ShrUVecI8x16 = BinaryenObj["_BinaryenShrUVecI8x16"](), + ShrUVecI16x8 = BinaryenObj["_BinaryenShrUVecI16x8"](), + ShrUVecI32x4 = BinaryenObj["_BinaryenShrUVecI32x4"](), + ShrUVecI64x2 = BinaryenObj["_BinaryenShrUVecI64x2"](), + ShrSVecI8x16 = BinaryenObj["_BinaryenShrSVecI8x16"](), + ShrSVecI16x8 = BinaryenObj["_BinaryenShrSVecI16x8"](), + ShrSVecI32x4 = BinaryenObj["_BinaryenShrSVecI32x4"](), + ShrSVecI64x2 = BinaryenObj["_BinaryenShrSVecI64x2"](), + // #### bitmask #### // + BitmaskVecI8x16 = BinaryenObj["_BinaryenBitmaskVecI8x16"](), + BitmaskVecI16x8 = BinaryenObj["_BinaryenBitmaskVecI16x8"](), + BitmaskVecI32x4 = BinaryenObj["_BinaryenBitmaskVecI32x4"](), + BitmaskVecI64x2 = BinaryenObj["_BinaryenBitmaskVecI64x2"](), + // #### vswizzleop #### // + SwizzleVecI8x16 = BinaryenObj["_BinaryenSwizzleVecI8x16"](), + RelaxedSwizzleVecI8x16 = BinaryenObj["_BinaryenRelaxedSwizzleVecI8x16"](), + // #### vextunop #### // + ExtAddPairwiseUVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseUVecI8x16ToI16x8"](), + ExtAddPairwiseUVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseUVecI16x8ToI32x4"](), + ExtAddPairwiseSVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseSVecI8x16ToI16x8"](), + ExtAddPairwiseSVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseSVecI16x8ToI32x4"](), + // #### vextbinop #### // + ExtMulLowUVecI16x8 = BinaryenObj["_BinaryenExtMulLowUVecI16x8"](), + ExtMulLowUVecI32x4 = BinaryenObj["_BinaryenExtMulLowUVecI32x4"](), + ExtMulLowUVecI64x2 = BinaryenObj["_BinaryenExtMulLowUVecI64x2"](), + ExtMulLowSVecI16x8 = BinaryenObj["_BinaryenExtMulLowSVecI16x8"](), + ExtMulLowSVecI32x4 = BinaryenObj["_BinaryenExtMulLowSVecI32x4"](), + ExtMulLowSVecI64x2 = BinaryenObj["_BinaryenExtMulLowSVecI64x2"](), + ExtMulHighUVecI16x8 = BinaryenObj["_BinaryenExtMulHighUVecI16x8"](), + ExtMulHighUVecI32x4 = BinaryenObj["_BinaryenExtMulHighUVecI32x4"](), + ExtMulHighUVecI64x2 = BinaryenObj["_BinaryenExtMulHighUVecI64x2"](), + ExtMulHighSVecI16x8 = BinaryenObj["_BinaryenExtMulHighSVecI16x8"](), + ExtMulHighSVecI32x4 = BinaryenObj["_BinaryenExtMulHighSVecI32x4"](), + ExtMulHighSVecI64x2 = BinaryenObj["_BinaryenExtMulHighSVecI64x2"](), + DotI8x16I7x16AddSToVecI32x4 = BinaryenObj["_BinaryenDotI8x16I7x16AddSToVecI32x4"](), + DotI8x16I7x16SToVecI16x8 = BinaryenObj["_BinaryenDotI8x16I7x16SToVecI16x8"](), + DotSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenDotSVecI16x8ToVecI32x4"](), + // #### narrow #### // + NarrowSVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowSVecI16x8ToVecI8x16"](), + NarrowUVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowUVecI16x8ToVecI8x16"](), + NarrowSVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowSVecI32x4ToVecI16x8"](), + NarrowUVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowUVecI32x4ToVecI16x8"](), + // #### vcvtop #### // + ExtendLowUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowUVecI8x16ToVecI16x8"](), + ExtendLowUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowUVecI16x8ToVecI32x4"](), + ExtendLowUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowUVecI32x4ToVecI64x2"](), + ExtendLowSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowSVecI8x16ToVecI16x8"](), + ExtendLowSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowSVecI16x8ToVecI32x4"](), + ExtendLowSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowSVecI32x4ToVecI64x2"](), + ExtendHighUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighUVecI8x16ToVecI16x8"](), + ExtendHighUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighUVecI16x8ToVecI32x4"](), + ExtendHighUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighUVecI32x4ToVecI64x2"](), + ExtendHighSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighSVecI8x16ToVecI16x8"](), + ExtendHighSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighSVecI16x8ToVecI32x4"](), + ExtendHighSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighSVecI32x4ToVecI64x2"](), + ConvertUVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertUVecI32x4ToVecF32x4"](), + ConvertSVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertSVecI32x4ToVecF32x4"](), + ConvertLowUVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowUVecI32x4ToVecF64x2"](), + ConvertLowSVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowSVecI32x4ToVecF64x2"](), + TruncSatUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatUVecF32x4ToVecI32x4"](), + TruncSatSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatSVecF32x4ToVecI32x4"](), + TruncSatZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroUVecF64x2ToVecI32x4"](), + TruncSatZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroSVecF64x2ToVecI32x4"](), + RelaxedTruncUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncUVecF32x4ToVecI32x4"](), + RelaxedTruncSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncSVecF32x4ToVecI32x4"](), + RelaxedTruncZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4"](), + RelaxedTruncZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroSVecF64x2ToVecI32x4"](), + DemoteZeroVecF64x2ToVecF32x4 = BinaryenObj["_BinaryenDemoteZeroVecF64x2ToVecF32x4"](), + PromoteLowVecF32x4ToVecF64x2 = BinaryenObj["_BinaryenPromoteLowVecF32x4ToVecF64x2"](), + // #### splat #### // + SplatVecI8x16 = BinaryenObj["_BinaryenSplatVecI8x16"](), + SplatVecI16x8 = BinaryenObj["_BinaryenSplatVecI16x8"](), + SplatVecI32x4 = BinaryenObj["_BinaryenSplatVecI32x4"](), + SplatVecI64x2 = BinaryenObj["_BinaryenSplatVecI64x2"](), + SplatVecF32x4 = BinaryenObj["_BinaryenSplatVecF32x4"](), + SplatVecF64x2 = BinaryenObj["_BinaryenSplatVecF64x2"](), + // #### extract_lane #### // + ExtractLaneUVecI8x16 = BinaryenObj["_BinaryenExtractLaneUVecI8x16"](), + ExtractLaneUVecI16x8 = BinaryenObj["_BinaryenExtractLaneUVecI16x8"](), + ExtractLaneSVecI8x16 = BinaryenObj["_BinaryenExtractLaneSVecI8x16"](), + ExtractLaneSVecI16x8 = BinaryenObj["_BinaryenExtractLaneSVecI16x8"](), + ExtractLaneVecI32x4 = BinaryenObj["_BinaryenExtractLaneVecI32x4"](), + ExtractLaneVecI64x2 = BinaryenObj["_BinaryenExtractLaneVecI64x2"](), + ExtractLaneVecF32x4 = BinaryenObj["_BinaryenExtractLaneVecF32x4"](), + ExtractLaneVecF64x2 = BinaryenObj["_BinaryenExtractLaneVecF64x2"](), + // #### replace_lane #### // + ReplaceLaneVecI8x16 = BinaryenObj["_BinaryenReplaceLaneVecI8x16"](), + ReplaceLaneVecI16x8 = BinaryenObj["_BinaryenReplaceLaneVecI16x8"](), + ReplaceLaneVecI32x4 = BinaryenObj["_BinaryenReplaceLaneVecI32x4"](), + ReplaceLaneVecI64x2 = BinaryenObj["_BinaryenReplaceLaneVecI64x2"](), + ReplaceLaneVecF32x4 = BinaryenObj["_BinaryenReplaceLaneVecF32x4"](), + ReplaceLaneVecF64x2 = BinaryenObj["_BinaryenReplaceLaneVecF64x2"](), + + // ### Atomic Operations ### // + AtomicRMWAdd = BinaryenObj["_BinaryenAtomicRMWAdd"](), + AtomicRMWSub = BinaryenObj["_BinaryenAtomicRMWSub"](), + AtomicRMWAnd = BinaryenObj["_BinaryenAtomicRMWAnd"](), + AtomicRMWOr = BinaryenObj["_BinaryenAtomicRMWOr"](), + AtomicRMWXor = BinaryenObj["_BinaryenAtomicRMWXor"](), + AtomicRMWXchg = BinaryenObj["_BinaryenAtomicRMWXchg"](), + + // ### String Operations ### // + StringNewLossyUTF8Array = BinaryenObj["_BinaryenStringNewLossyUTF8Array"](), + StringNewWTF16Array = BinaryenObj["_BinaryenStringNewWTF16Array"](), + StringNewFromCodePoint = BinaryenObj["_BinaryenStringNewFromCodePoint"](), + StringMeasureUTF8 = BinaryenObj["_BinaryenStringMeasureUTF8"](), + StringMeasureWTF16 = BinaryenObj["_BinaryenStringMeasureWTF16"](), + StringEncodeLossyUTF8Array = BinaryenObj["_BinaryenStringEncodeLossyUTF8Array"](), + StringEncodeWTF16Array = BinaryenObj["_BinaryenStringEncodeWTF16Array"](), + StringEqEqual = BinaryenObj["_BinaryenStringEqEqual"](), + StringEqCompare = BinaryenObj["_BinaryenStringEqCompare"](), +} + + + // ## Externals ## // // see https://webassembly.github.io/spec/core/syntax/modules.html export enum ExternalKind { @@ -235,3 +694,25 @@ export enum MemoryOrder { seqcst = BinaryenObj["_BinaryenMemoryOrderSeqCst"](), acqrel = BinaryenObj["_BinaryenMemoryOrderAcqRel"](), } + + + +export enum SideEffect { + None = BinaryenObj["_BinaryenSideEffectNone"](), + Branches = BinaryenObj["_BinaryenSideEffectBranches"](), + Calls = BinaryenObj["_BinaryenSideEffectCalls"](), + ReadsLocal = BinaryenObj["_BinaryenSideEffectReadsLocal"](), + WritesLocal = BinaryenObj["_BinaryenSideEffectWritesLocal"](), + ReadsGlobal = BinaryenObj["_BinaryenSideEffectReadsGlobal"](), + WritesGlobal = BinaryenObj["_BinaryenSideEffectWritesGlobal"](), + ReadsMemory = BinaryenObj["_BinaryenSideEffectReadsMemory"](), + WritesMemory = BinaryenObj["_BinaryenSideEffectWritesMemory"](), + ReadsTable = BinaryenObj["_BinaryenSideEffectReadsTable"](), + WritesTable = BinaryenObj["_BinaryenSideEffectWritesTable"](), + ImplicitTrap = BinaryenObj["_BinaryenSideEffectImplicitTrap"](), + IsAtomic = BinaryenObj["_BinaryenSideEffectIsAtomic"](), + Throws = BinaryenObj["_BinaryenSideEffectThrows"](), + DanglingPop = BinaryenObj["_BinaryenSideEffectDanglingPop"](), + TrapsNeverHappen = BinaryenObj["_BinaryenSideEffectTrapsNeverHappen"](), + Any = BinaryenObj["_BinaryenSideEffectAny"](), +} From 5264b459bee7bc14a775f8dd65151da6058fc9dd Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 01:42:29 -0400 Subject: [PATCH 004/247] docs: improve types & comments --- ts/src/expressions.ts | 10 ++++++++++ ts/src/pre.ts | 2 +- ts/src/utils.ts | 8 ++++---- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ts/src/expressions.ts b/ts/src/expressions.ts index 0a0728f4d55..d49e7830c31 100644 --- a/ts/src/expressions.ts +++ b/ts/src/expressions.ts @@ -87,10 +87,20 @@ export const stringref: Type = BinaryenObj["_BinaryenTypeStringref"](); +/** + * Creates a multi-value type from an array of types. + * @param types the array of types + * @return a tuple type containing the array’s components + */ export function createType(types: readonly Type[]): Type { return preserveStack(() => BinaryenObj["_BinaryenTypeCreate"](i32sToStack(types), types.length)); } +/** + * Expands a multi-value type to an array of types. + * @param typ the tuple type + * @return an array containing the tuple’s components + */ export function expandType(typ: Type): Type[] { return preserveStack(() => { const numTypes = BinaryenObj["_BinaryenTypeArity"](typ); diff --git a/ts/src/pre.ts b/ts/src/pre.ts index 324068f6e69..e6d59d2a14c 100644 --- a/ts/src/pre.ts +++ b/ts/src/pre.ts @@ -4,7 +4,7 @@ /** The main object provided by Emscripten. This is what gets wrapped. */ -export declare const BinaryenObj: Readonly>; +export declare const BinaryenObj: Readonly number>>; diff --git a/ts/src/utils.ts b/ts/src/utils.ts index d4fa82bf686..711bdec7088 100644 --- a/ts/src/utils.ts +++ b/ts/src/utils.ts @@ -13,10 +13,10 @@ import { -export const HEAP8: Int8Array = BinaryenObj["HEAP8"]; -export const HEAPU8: Uint8Array = BinaryenObj["HEAPU8"]; -export const HEAP32: Int32Array = BinaryenObj["HEAP32"]; -export const HEAPU32: Uint32Array = BinaryenObj["HEAPU32"]; +export const HEAP8: Int8Array = BinaryenObj["HEAP8"] as any; +export const HEAPU8: Uint8Array = BinaryenObj["HEAPU8"] as any; +export const HEAP32: Int32Array = BinaryenObj["HEAP32"] as any; +export const HEAPU32: Uint32Array = BinaryenObj["HEAPU32"] as any; From 4288bbc6821da67ed2787b890a467a2c41c29696 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 02:45:30 -0400 Subject: [PATCH 005/247] feat: setup global functions --- ts/src/binaryen.ts | 1 + ts/src/expressions.ts | 85 +++++++++++++++++++---------- ts/src/global.ts | 123 ++++++++++++++++++++++++++++++++++++++++++ ts/src/pre.ts | 1 + 4 files changed, 181 insertions(+), 29 deletions(-) create mode 100644 ts/src/global.ts diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 845c54273bd..95475e0ed13 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1 +1,2 @@ +export * from "./global.ts"; export * from "./expressions.ts"; diff --git a/ts/src/expressions.ts b/ts/src/expressions.ts index d49e7830c31..894d8e74aed 100644 --- a/ts/src/expressions.ts +++ b/ts/src/expressions.ts @@ -87,35 +87,6 @@ export const stringref: Type = BinaryenObj["_BinaryenTypeStringref"](); -/** - * Creates a multi-value type from an array of types. - * @param types the array of types - * @return a tuple type containing the array’s components - */ -export function createType(types: readonly Type[]): Type { - return preserveStack(() => BinaryenObj["_BinaryenTypeCreate"](i32sToStack(types), types.length)); -} - -/** - * Expands a multi-value type to an array of types. - * @param typ the tuple type - * @return an array containing the tuple’s components - */ -export function expandType(typ: Type): Type[] { - return preserveStack(() => { - const numTypes = BinaryenObj["_BinaryenTypeArity"](typ); - const array = stackAlloc(numTypes << 2); - BinaryenObj["_BinaryenTypeExpand"](typ, array); - const types = new Array(numTypes); - for (let i = 0; i < numTypes; i++) { - types[i] = HEAPU32[(array >>> 2) + i]; - } - return types; - }); -} - - - // ## Instructions ## // // see https://webassembly.github.io/spec/core/syntax/instructions.html export enum ExpressionId { @@ -726,3 +697,59 @@ export enum SideEffect { TrapsNeverHappen = BinaryenObj["_BinaryenSideEffectTrapsNeverHappen"](), Any = BinaryenObj["_BinaryenSideEffectAny"](), } + + + +/** + * Creates a multi-value type from an array of types. + * @param types the array of types + * @return a tuple type containing the array’s components + */ +export function createType(types: readonly Type[]): Type { + return preserveStack(() => BinaryenObj["_BinaryenTypeCreate"](i32sToStack(types), types.length)); +} + +/** + * Expands a multi-value type to an array of types. + * @param typ the tuple type + * @return an array containing the tuple’s components + */ +export function expandType(typ: Type): Type[] { + return preserveStack(() => { + const numTypes = BinaryenObj["_BinaryenTypeArity"](typ); + const array = stackAlloc(numTypes << 2); + BinaryenObj["_BinaryenTypeExpand"](typ, array); + const types = new Array(numTypes); + for (let i = 0; i < numTypes; i++) { + types[i] = HEAPU32[(array >>> 2) + i]; + } + return types; + }); +} + +/** + * Gets the type from a heap type generated by TypeBuilder. + * @param heapType the heap type from which to get the type + * @param nullable whether the return type should be nullable + * @return given `ht`: `(ref null? ht)` + */ +export function getTypeFromHeapType(heapType: HeapType, nullable: boolean): Type { + return BinaryenObj["_BinaryenTypeFromHeapType"](heapType, nullable); +} + +/** + * Gets the heap type of a type. + * @param typ the type from which to get the heap type + * @return given `(ref null? ht)`: `ht` + */ +export function getHeapType(typ: Type): HeapType { + return BinaryenObj["_BinaryenTypeGetHeapType"](typ); +} + +export function getExpressionId() {} + +export function getExpressionType() {} + +export function getExpressionInfo() {} + +export function getSideEffects() {} diff --git a/ts/src/global.ts b/ts/src/global.ts new file mode 100644 index 00000000000..4d0470186cc --- /dev/null +++ b/ts/src/global.ts @@ -0,0 +1,123 @@ +import {getExceptionMessage} from "./pre.ts"; + + + +// # Globals # // +// Top-level functions available in the public API. + + + +/** + * Calls a function, wrapping it in error handling code so that if it hits a + * fatal error, we throw a JS exception (which JS can handle) rather than + * abort the entire process (which would not be a friendly behavior). + * @param func the function to call + * @return the return value of the given function + */ +function handleFatalError(func: () => number): number { + try { + return func(); + } catch (e) { + // Fatal errors begin with a specific prefix. Strip it out, and the newline. + if (typeof e === "number") { + // Older version of emscripten can throw C++ exceptions as pointers (numbers) in release builds. + const [_, message] = getExceptionMessage(e); + if (message?.startsWith("Fatal: ")) { + throw new Error(message.substr(7).trim()); + } + } else { + const err = e as Error; + // Newer version of emscripten always throw CppException object but don’t + // always populate the `.message` field. + // TODO: Set EXCEPTION_STACK_TRACES instead? + if (!err.message) { + const [_, message] = getExceptionMessage(err); + err.message = message; + } + err.message = err.message.replace("Fatal:", ""); + err.message = err.message.trim(); + } + // Rethrow anything else. + throw e; + } +} + + + +export function emitText() {}; + +export function readBinary() {}; + +export function readBinaryWithFeatures() {}; + +export function parseText() {}; + +export function exit() {}; + +export function getOptimizeLevel() {}; + +export function setOptimizeLevel() {}; + +export function getShrinkLevel() {}; + +export function setShrinkLevel() {}; + +export function getDebugInfo() {}; + +export function setDebugInfo() {}; + +export function getTrapsNeverHappen() {}; + +export function setTrapsNeverHappen() {}; + +export function getClosedWorld() {}; + +export function setClosedWorld() {}; + +export function getLowMemoryUnused() {}; + +export function setLowMemoryUnused() {}; + +export function getZeroFilledMemory() {}; + +export function setZeroFilledMemory() {}; + +export function getFastMath() {}; + +export function setFastMath() {}; + +export function getGenerateStackIR() {}; + +export function setGenerateStackIR() {}; + +export function getOptimizeStackIR() {}; + +export function setOptimizeStackIR() {}; + +export function getPassArgument() {}; + +export function setPassArgument() {}; + +export function clearPassArguments() {}; + +export function hasPassToSkip() {}; + +export function addPassToSkip() {}; + +export function clearPassesToSkip() {}; + +export function getAlwaysInlineMaxSize() {}; + +export function setAlwaysInlineMaxSize() {}; + +export function getFlexibleInlineMaxSize() {}; + +export function setFlexibleInlineMaxSize() {}; + +export function getOneCallerInlineMaxSize() {}; + +export function setOneCallerInlineMaxSize() {}; + +export function getAllowInliningFunctionsWithLoops() {}; + +export function setAllowInliningFunctionsWithLoops() {}; diff --git a/ts/src/pre.ts b/ts/src/pre.ts index e6d59d2a14c..331f3dede33 100644 --- a/ts/src/pre.ts +++ b/ts/src/pre.ts @@ -12,3 +12,4 @@ export declare function stackSave(): unknown; export declare function stackRestore(stack: unknown): unknown; export declare function stackAlloc(length: number): number; export declare function stringToUTF8OnStack(str: string): number; +export declare function getExceptionMessage(e: number | Error): [any, string]; From a90e6adc105304ac79f269d1957f83f0974189af Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 01:32:16 -0400 Subject: [PATCH 006/247] feat: start class files --- ts/src/ExpressionRunner.ts | 39 ++++++++++ ts/src/Module.ts | 150 +++++++++++++++++++++++++++++++++++++ ts/src/Relooper.ts | 22 ++++++ ts/src/TypeBuilder.ts | 35 +++++++++ ts/src/binaryen.ts | 10 +++ 5 files changed, 256 insertions(+) create mode 100644 ts/src/ExpressionRunner.ts create mode 100644 ts/src/Module.ts create mode 100644 ts/src/Relooper.ts create mode 100644 ts/src/TypeBuilder.ts diff --git a/ts/src/ExpressionRunner.ts b/ts/src/ExpressionRunner.ts new file mode 100644 index 00000000000..0e6e9046345 --- /dev/null +++ b/ts/src/ExpressionRunner.ts @@ -0,0 +1,39 @@ +import {BinaryenObj} from "./pre.ts"; +import { + preserveStack, + strToStack, +} from "./utils.ts"; +import type { + ExpressionRef, + ExpressionRunnerRef, +} from "./expressions.ts"; +import type {Module} from "./Module.ts"; + + + +export enum ExpressionRunnerFlag { + Default = BinaryenObj["_ExpressionRunnerFlagsDefault"](), + PreserveSideeffects = BinaryenObj["_ExpressionRunnerFlagsPreserveSideeffects"](), +} + + + +export class ExpressionRunner { + readonly ptr: ExpressionRunnerRef; + + constructor(module: Module, flags: ExpressionRunnerFlag, maxDepth: number, maxLoopIterations: number) { + this.ptr = BinaryenObj["_ExpressionRunnerCreate"](module.ptr, flags, maxDepth, maxLoopIterations); + } + + setLocalValue(index: number, valueExpr: ExpressionRef): boolean { + return Boolean(BinaryenObj["_ExpressionRunnerSetLocalValue"](this.ptr, index, valueExpr)); + } + + setGlobalValue(name: string, valueExpr: ExpressionRef): boolean { + return preserveStack(() => Boolean(BinaryenObj["_ExpressionRunnerSetGlobalValue"](this.ptr, strToStack(name), valueExpr))); + } + + runAndDispose(expr: ExpressionRef): ExpressionRef { + return BinaryenObj["_ExpressionRunnerRunAndDispose"](this.ptr, expr); + } +} diff --git a/ts/src/Module.ts b/ts/src/Module.ts new file mode 100644 index 00000000000..71faea3a906 --- /dev/null +++ b/ts/src/Module.ts @@ -0,0 +1,150 @@ +import {BinaryenObj} from "./pre.ts"; + + + +/** + * The size of a single literal in memory as used in Const creation, + * which is a little different: we don’t want users to need to make + * their own Literals, as the C API handles them by value, which means + * we would leak them. Instead, Const creation is fused together with + * an intermediate stack allocation of this size to pass the value. + */ +const SIZE_OF_LITERAL = BinaryenObj["_BinaryenSizeofLiteral"](); + + + +export enum Feature { + MVP = BinaryenObj["_BinaryenFeatureMVP"](), + Atomics = BinaryenObj["_BinaryenFeatureAtomics"](), + MutableGlobals = BinaryenObj["_BinaryenFeatureMutableGlobals"](), + NontrappingFPToInt = BinaryenObj["_BinaryenFeatureNontrappingFPToInt"](), + SIMD128 = BinaryenObj["_BinaryenFeatureSIMD128"](), + BulkMemory = BinaryenObj["_BinaryenFeatureBulkMemory"](), + SignExt = BinaryenObj["_BinaryenFeatureSignExt"](), + ExceptionHandling = BinaryenObj["_BinaryenFeatureExceptionHandling"](), + TailCall = BinaryenObj["_BinaryenFeatureTailCall"](), + ReferenceTypes = BinaryenObj["_BinaryenFeatureReferenceTypes"](), + Multivalue = BinaryenObj["_BinaryenFeatureMultivalue"](), + GC = BinaryenObj["_BinaryenFeatureGC"](), + Memory64 = BinaryenObj["_BinaryenFeatureMemory64"](), + RelaxedSIMD = BinaryenObj["_BinaryenFeatureRelaxedSIMD"](), + ExtendedConst = BinaryenObj["_BinaryenFeatureExtendedConst"](), + Strings = BinaryenObj["_BinaryenFeatureStrings"](), + MultiMemory = BinaryenObj["_BinaryenFeatureMultiMemory"](), + StackSwitching = BinaryenObj["_BinaryenFeatureStackSwitching"](), + SharedEverything = BinaryenObj["_BinaryenFeatureSharedEverything"](), + FP16 = BinaryenObj["_BinaryenFeatureFP16"](), + BulkMemoryOpt = BinaryenObj["_BinaryenFeatureBulkMemoryOpt"](), + CallIndirectOverlong = BinaryenObj["_BinaryenFeatureCallIndirectOverlong"](), + RelaxedAtomics = BinaryenObj["_BinaryenFeatureRelaxedAtomics"](), + CustomPageSizes = BinaryenObj["_BinaryenFeatureCustomPageSizes"](), + WideArithmetic = BinaryenObj["_BinaryenFeatureWideArithmetic"](), + All = BinaryenObj["_BinaryenFeatureAll"](), +} + + + +export class Module { + readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); + + // ## Expression Creation ## // + + // ## Module Operations ## // + // see https://webassembly.github.io/spec/core/syntax/modules.html + + // ### Tags ### // + addTag() {} + + getTag() {} + + removeTag() {} + + // ### Globals ### // + addGlobal() {} + + getGlobal() {} + + removeGlobal() {} + + // ### Memories ### // + setMemory() {} + + hasMemory() {} + + getMemoryInfo() {} + + // ### Tables ### // + addTable() {} + + getTable() {} + + getTableSegments() {} + + removeTable() {} + + // ### Functions ### // + addFunction() {} + + getFunction() {} + + removeFunction() {} + + // ### Data Segments ### // + getNumDataSegments() {} + + getDataSegment() {} + + getDataSegmentByIndex() {} + + getDataSegmentInfo() {} + + // ### Element Segments ### // + addActiveElementSegment() {} + + addPassiveElementSegment() {} + + getElementSegment() {} + + removeElementSegment() {} + + // ### Start Function ### // + getStart() {} + + // ### Imports ### // + addTagImport() {} + + addGlobalImport() {} + + addMemoryImport() {} + + addTableImport() {} + + addFunctionImport() {} + + // ### Exports ### // + addTagExport() {} + + addGlobalExport() {} + + addMemoryExport() {} + + addTableExport() {} + + addFunctionExport() {} + + removeExport() {} +} + + + +export function getTagInfo() {} + +export function getGlobalInfo() {} + +export function getTableInfo() {} + +export function getFunctionInfo() {} + +export function getElementSegmentInfo() {} + +export function getExportInfo() {} diff --git a/ts/src/Relooper.ts b/ts/src/Relooper.ts new file mode 100644 index 00000000000..77f4e28f45a --- /dev/null +++ b/ts/src/Relooper.ts @@ -0,0 +1,22 @@ +import {BinaryenObj} from "./pre.ts"; +import type {Module} from "./Module.ts"; + + + +export class Relooper { + readonly ptr: number; + + constructor(module: Module) { + this.ptr = BinaryenObj["_RelooperCreate"](module.ptr) + } + + addBlock() {} + + addBranch() {} + + addBlockWithSwitch() {} + + addBranchForSwitch() {} + + renderAndDispose() {} +} diff --git a/ts/src/TypeBuilder.ts b/ts/src/TypeBuilder.ts new file mode 100644 index 00000000000..34473000dbd --- /dev/null +++ b/ts/src/TypeBuilder.ts @@ -0,0 +1,35 @@ +import {BinaryenObj} from "./pre.ts"; + + + +export class TypeBuilder { + readonly ptr: number; + + constructor(size: number) { + this.ptr = BinaryenObj["_TypeBuilderCreate"](size); + } + + grow() {} + + getSize() {} + + setSignatureType() {} + + setStructType() {} + + setArrayType() {} + + getTempHeapType() {} + + getTempTupleType() {} + + getTempRefType() {} + + setSubType() {} + + setOpen() {} + + createRecGroup() {} + + buildAndDispose() {} +} diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 95475e0ed13..8edb185ad20 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1,2 +1,12 @@ export * from "./global.ts"; export * from "./expressions.ts"; +export { + Feature, + Module, +} from "./Module.ts"; +export { + ExpressionRunner, + ExpressionRunnerFlag, +} from "./ExpressionRunner.ts"; +export {TypeBuilder} from "./TypeBuilder.ts"; +export {Relooper} from "./Relooper.ts"; From 8240fe8db4d3cc9e69ce09cebcb3a7007cfafff2 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 03:52:28 -0400 Subject: [PATCH 007/247] refactor: rename expressions -> constants --- ts/src/ExpressionRunner.ts | 2 +- ts/src/binaryen.ts | 2 +- ts/src/{expressions.ts => constants.ts} | 68 +--------------------- ts/src/global.ts | 76 ++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 69 deletions(-) rename ts/src/{expressions.ts => constants.ts} (95%) diff --git a/ts/src/ExpressionRunner.ts b/ts/src/ExpressionRunner.ts index 0e6e9046345..841c41e332a 100644 --- a/ts/src/ExpressionRunner.ts +++ b/ts/src/ExpressionRunner.ts @@ -6,7 +6,7 @@ import { import type { ExpressionRef, ExpressionRunnerRef, -} from "./expressions.ts"; +} from "./constants.ts"; import type {Module} from "./Module.ts"; diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 8edb185ad20..dfb530562fb 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1,5 +1,5 @@ export * from "./global.ts"; -export * from "./expressions.ts"; +export * from "./constants.ts"; export { Feature, Module, diff --git a/ts/src/expressions.ts b/ts/src/constants.ts similarity index 95% rename from ts/src/expressions.ts rename to ts/src/constants.ts index 894d8e74aed..09fa43f2575 100644 --- a/ts/src/expressions.ts +++ b/ts/src/constants.ts @@ -1,17 +1,9 @@ -import { - BinaryenObj, - stackAlloc, -} from "./pre.ts"; -import { - HEAPU32, - i32sToStack, - preserveStack, -} from "./utils.ts"; +import {BinaryenObj} from "./pre.ts"; // # Expressions, Types, and Constants # // -// Compile-time types used by TypeScript, Binaryen types, and expression types. +// Compile-time types used by TypeScript, Binaryen types, expression types, and other enums. @@ -697,59 +689,3 @@ export enum SideEffect { TrapsNeverHappen = BinaryenObj["_BinaryenSideEffectTrapsNeverHappen"](), Any = BinaryenObj["_BinaryenSideEffectAny"](), } - - - -/** - * Creates a multi-value type from an array of types. - * @param types the array of types - * @return a tuple type containing the array’s components - */ -export function createType(types: readonly Type[]): Type { - return preserveStack(() => BinaryenObj["_BinaryenTypeCreate"](i32sToStack(types), types.length)); -} - -/** - * Expands a multi-value type to an array of types. - * @param typ the tuple type - * @return an array containing the tuple’s components - */ -export function expandType(typ: Type): Type[] { - return preserveStack(() => { - const numTypes = BinaryenObj["_BinaryenTypeArity"](typ); - const array = stackAlloc(numTypes << 2); - BinaryenObj["_BinaryenTypeExpand"](typ, array); - const types = new Array(numTypes); - for (let i = 0; i < numTypes; i++) { - types[i] = HEAPU32[(array >>> 2) + i]; - } - return types; - }); -} - -/** - * Gets the type from a heap type generated by TypeBuilder. - * @param heapType the heap type from which to get the type - * @param nullable whether the return type should be nullable - * @return given `ht`: `(ref null? ht)` - */ -export function getTypeFromHeapType(heapType: HeapType, nullable: boolean): Type { - return BinaryenObj["_BinaryenTypeFromHeapType"](heapType, nullable); -} - -/** - * Gets the heap type of a type. - * @param typ the type from which to get the heap type - * @return given `(ref null? ht)`: `ht` - */ -export function getHeapType(typ: Type): HeapType { - return BinaryenObj["_BinaryenTypeGetHeapType"](typ); -} - -export function getExpressionId() {} - -export function getExpressionType() {} - -export function getExpressionInfo() {} - -export function getSideEffects() {} diff --git a/ts/src/global.ts b/ts/src/global.ts index 4d0470186cc..f1fff83d3d3 100644 --- a/ts/src/global.ts +++ b/ts/src/global.ts @@ -1,4 +1,17 @@ -import {getExceptionMessage} from "./pre.ts"; +import { + BinaryenObj, + getExceptionMessage, + stackAlloc, +} from "./pre.ts"; +import { + HEAPU32, + i32sToStack, + preserveStack, +} from "./utils.ts"; +import type { + HeapType, + Type, +} from "./constants.ts"; @@ -44,6 +57,7 @@ function handleFatalError(func: () => number): number { +// ## General Binaryen Functions ## // export function emitText() {}; export function readBinary() {}; @@ -54,6 +68,66 @@ export function parseText() {}; export function exit() {}; + + +// ## Types and Expressions ## // +/** + * Creates a multi-value type from an array of types. + * @param types the array of types + * @return a tuple type containing the array’s components + */ +export function createType(types: readonly Type[]): Type { + return preserveStack(() => BinaryenObj["_BinaryenTypeCreate"](i32sToStack(types), types.length)); +} + +/** + * Expands a multi-value type to an array of types. + * @param typ the tuple type + * @return an array containing the tuple’s components + */ +export function expandType(typ: Type): Type[] { + return preserveStack(() => { + const numTypes = BinaryenObj["_BinaryenTypeArity"](typ); + const array = stackAlloc(numTypes << 2); + BinaryenObj["_BinaryenTypeExpand"](typ, array); + const types = new Array(numTypes); + for (let i = 0; i < numTypes; i++) { + types[i] = HEAPU32[(array >>> 2) + i]; + } + return types; + }); +} + +/** + * Gets the type from a heap type generated by TypeBuilder. + * @param heapType the heap type from which to get the type + * @param nullable whether the return type should be nullable + * @return given `ht`: `(ref null? ht)` + */ +export function getTypeFromHeapType(heapType: HeapType, nullable: boolean): Type { + return BinaryenObj["_BinaryenTypeFromHeapType"](heapType, nullable); +} + +/** + * Gets the heap type of a type. + * @param typ the type from which to get the heap type + * @return given `(ref null? ht)`: `ht` + */ +export function getHeapType(typ: Type): HeapType { + return BinaryenObj["_BinaryenTypeGetHeapType"](typ); +} + +export function getExpressionId() {} + +export function getExpressionType() {} + +export function getExpressionInfo() {} + +export function getSideEffects() {} + + + +// ## Global Getters and Setters ## // export function getOptimizeLevel() {}; export function setOptimizeLevel() {}; From 449de24f6d08bce06a0b4a8644ff4c876aae06f8 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 04:32:49 -0400 Subject: [PATCH 008/247] lint: alphabetical imports --- ts/src/ExpressionRunner.ts | 10 +++++----- ts/src/Relooper.ts | 2 +- ts/src/binaryen.ts | 14 +++++++------- ts/src/global.ts | 8 ++++---- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ts/src/ExpressionRunner.ts b/ts/src/ExpressionRunner.ts index 841c41e332a..29d96a4a745 100644 --- a/ts/src/ExpressionRunner.ts +++ b/ts/src/ExpressionRunner.ts @@ -1,13 +1,13 @@ +import type {Module} from "./Module.ts"; +import type { + ExpressionRef, + ExpressionRunnerRef, +} from "./constants.ts"; import {BinaryenObj} from "./pre.ts"; import { preserveStack, strToStack, } from "./utils.ts"; -import type { - ExpressionRef, - ExpressionRunnerRef, -} from "./constants.ts"; -import type {Module} from "./Module.ts"; diff --git a/ts/src/Relooper.ts b/ts/src/Relooper.ts index 77f4e28f45a..65f9a7407ce 100644 --- a/ts/src/Relooper.ts +++ b/ts/src/Relooper.ts @@ -1,5 +1,5 @@ -import {BinaryenObj} from "./pre.ts"; import type {Module} from "./Module.ts"; +import {BinaryenObj} from "./pre.ts"; diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index dfb530562fb..f223d807f4e 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1,12 +1,12 @@ -export * from "./global.ts"; -export * from "./constants.ts"; -export { - Feature, - Module, -} from "./Module.ts"; export { ExpressionRunner, ExpressionRunnerFlag, } from "./ExpressionRunner.ts"; -export {TypeBuilder} from "./TypeBuilder.ts"; +export { + Feature, + Module, +} from "./Module.ts"; export {Relooper} from "./Relooper.ts"; +export {TypeBuilder} from "./TypeBuilder.ts"; +export * from "./constants.ts"; +export * from "./global.ts"; diff --git a/ts/src/global.ts b/ts/src/global.ts index f1fff83d3d3..4b35d7489cd 100644 --- a/ts/src/global.ts +++ b/ts/src/global.ts @@ -1,3 +1,7 @@ +import type { + HeapType, + Type, +} from "./constants.ts"; import { BinaryenObj, getExceptionMessage, @@ -8,10 +12,6 @@ import { i32sToStack, preserveStack, } from "./utils.ts"; -import type { - HeapType, - Type, -} from "./constants.ts"; From aba47733f78fc8fb9a02d9f0be339261e99362bb Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 04:33:23 -0400 Subject: [PATCH 009/247] lint: rename `module` -> `mod` `module` is a reserved name in ES6 --- ts/src/ExpressionRunner.ts | 4 ++-- ts/src/Relooper.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ts/src/ExpressionRunner.ts b/ts/src/ExpressionRunner.ts index 29d96a4a745..3fa3791bf81 100644 --- a/ts/src/ExpressionRunner.ts +++ b/ts/src/ExpressionRunner.ts @@ -21,8 +21,8 @@ export enum ExpressionRunnerFlag { export class ExpressionRunner { readonly ptr: ExpressionRunnerRef; - constructor(module: Module, flags: ExpressionRunnerFlag, maxDepth: number, maxLoopIterations: number) { - this.ptr = BinaryenObj["_ExpressionRunnerCreate"](module.ptr, flags, maxDepth, maxLoopIterations); + constructor(mod: Module, flags: ExpressionRunnerFlag, maxDepth: number, maxLoopIterations: number) { + this.ptr = BinaryenObj["_ExpressionRunnerCreate"](mod.ptr, flags, maxDepth, maxLoopIterations); } setLocalValue(index: number, valueExpr: ExpressionRef): boolean { diff --git a/ts/src/Relooper.ts b/ts/src/Relooper.ts index 65f9a7407ce..9128b6c81da 100644 --- a/ts/src/Relooper.ts +++ b/ts/src/Relooper.ts @@ -6,8 +6,8 @@ import {BinaryenObj} from "./pre.ts"; export class Relooper { readonly ptr: number; - constructor(module: Module) { - this.ptr = BinaryenObj["_RelooperCreate"](module.ptr) + constructor(mod: Module) { + this.ptr = BinaryenObj["_RelooperCreate"](mod.ptr) } addBlock() {} From 87888a9536fd1b4f460940b6c29d98793d137caf Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 04:47:40 -0400 Subject: [PATCH 010/247] feat: lay groundwork for expression wrappers & Module methods --- ts/src/Module.ts | 3 +++ ts/src/binaryen.ts | 1 + ts/src/expressions/Block.ts | 41 ++++++++++++++++++++++++++++++++ ts/src/expressions/Expression.ts | 28 ++++++++++++++++++++++ ts/src/expressions/index.ts | 1 + ts/src/utils.ts | 5 ++++ 6 files changed, 79 insertions(+) create mode 100644 ts/src/expressions/Block.ts create mode 100644 ts/src/expressions/Expression.ts create mode 100644 ts/src/expressions/index.ts diff --git a/ts/src/Module.ts b/ts/src/Module.ts index 71faea3a906..5d844895b2d 100644 --- a/ts/src/Module.ts +++ b/ts/src/Module.ts @@ -1,3 +1,4 @@ +import {block} from "./expressions/Block.ts"; import {BinaryenObj} from "./pre.ts"; @@ -48,6 +49,8 @@ export class Module { readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); // ## Expression Creation ## // + // ### Control Instructions ### // + block = block; // ## Module Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index f223d807f4e..1dfb04c901f 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -9,4 +9,5 @@ export { export {Relooper} from "./Relooper.ts"; export {TypeBuilder} from "./TypeBuilder.ts"; export * from "./constants.ts"; +export * from "./expressions/index.ts"; export * from "./global.ts"; diff --git a/ts/src/expressions/Block.ts b/ts/src/expressions/Block.ts new file mode 100644 index 00000000000..f27236a7cfe --- /dev/null +++ b/ts/src/expressions/Block.ts @@ -0,0 +1,41 @@ +import {Module} from "../Module.ts"; +import { + type ExpressionRef, + type Type, + none, +} from "../constants.ts"; +import {BinaryenObj} from "../pre.ts"; +import { + i32sToStack, + preserveStack, + strToStack, +} from "../utils.ts"; +import {Expression} from "./Expression.ts"; + + + +export class Block extends Expression { + // TODO: static methods are deprecated; convert to instance and log warnings + static getName() {} + static setName() {} + static getNumChildren() {} + static getChildren() {} + static setChildren() {} + static getChildAt() {} + static setChildAt() {} + static appendChild() {} + static insertChildAt() {} + static removeChildAt() {} +} + + + +export function block(this: Module, name: string, children: readonly ExpressionRef[], resultType: Type = none) { + return preserveStack(() => BinaryenObj["_BinaryenBlock"]( + this.ptr, + strToStack(name), + i32sToStack(children), + children.length, + resultType, + )); +} diff --git a/ts/src/expressions/Expression.ts b/ts/src/expressions/Expression.ts new file mode 100644 index 00000000000..6993b66b700 --- /dev/null +++ b/ts/src/expressions/Expression.ts @@ -0,0 +1,28 @@ +import type {ExpressionRef} from "../constants.ts"; +import {BinaryenObj} from "../pre.ts"; +import {THIS_PTR} from "../utils.ts"; + + + +/** Base class of all expression wrappers. */ +export class Expression { + // TODO: static methods are deprecated; convert to instance and log warnings + static getId(expr: number) { + return BinaryenObj["_BinaryenExpressionGetId"](expr); + } + static getType() {} + static setType() {} + static finalize() {} + static toText() {} + + + protected readonly [THIS_PTR]: number; + + constructor(expr: ExpressionRef) { + this[THIS_PTR] = expr; + } + + valueOf() { + return this[THIS_PTR]; + } +} diff --git a/ts/src/expressions/index.ts b/ts/src/expressions/index.ts new file mode 100644 index 00000000000..bcdd81b3906 --- /dev/null +++ b/ts/src/expressions/index.ts @@ -0,0 +1 @@ +export {Block} from "./Block.ts"; diff --git a/ts/src/utils.ts b/ts/src/utils.ts index 711bdec7088..b3913ce639e 100644 --- a/ts/src/utils.ts +++ b/ts/src/utils.ts @@ -20,6 +20,11 @@ export const HEAPU32: Uint32Array = BinaryenObj["HEAPU32"] as any; +/** Private symbol used to store the underlying C-API pointer of a wrapped object. */ +export const THIS_PTR: unique symbol = Symbol(); + + + /** * Exports friendly API methods. * @param func [description] From ae40beae963c3a402212f4b2a819903769fa8c45 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 05:01:05 -0400 Subject: [PATCH 011/247] feat: start more class files --- ts/src/Function.ts | 32 ++++++++++++++++++++++++++++++++ ts/src/Table.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 ts/src/Function.ts create mode 100644 ts/src/Table.ts diff --git a/ts/src/Function.ts b/ts/src/Function.ts new file mode 100644 index 00000000000..75a56c9899a --- /dev/null +++ b/ts/src/Function.ts @@ -0,0 +1,32 @@ +import type {FunctionRef} from "./constants.ts"; +import {THIS_PTR} from "./utils.ts"; + + + +class BinaryenFunction { + // TODO: static methods are deprecated; convert to instance and log warnings + static getName() {} + static getType() {} + static getParams() {} + static getResults() {} + static getNumVars() {} + static getVar() {} + static getNumLocals() {} + static hasLocalName() {} + static getLocalName() {} + static setLocalName() {} + static getBody() {} + static setBody() {} + + + readonly [THIS_PTR]: FunctionRef; + + constructor(func: FunctionRef) { + this[THIS_PTR] = func; + } + + valueOf() { + return this[THIS_PTR]; + } +} +export {BinaryenFunction as Function}; diff --git a/ts/src/Table.ts b/ts/src/Table.ts new file mode 100644 index 00000000000..bac8a4b1b7e --- /dev/null +++ b/ts/src/Table.ts @@ -0,0 +1,28 @@ +import type {TableRef} from "./constants.ts"; +import {THIS_PTR} from "./utils.ts"; + + + +export class Table { + // TODO: static methods are deprecated; convert to instance and log warnings + static getName() {} + static setName() {} + static getInitial() {} + static setInitial() {} + static hasMax() {} + static getMax() {} + static setMax() {} + static getType() {} + static setType() {} + + + readonly [THIS_PTR]: TableRef; + + constructor(table: TableRef) { + this[THIS_PTR] = table; + } + + valueOf() { + return this[THIS_PTR]; + } +} From 9027a6b47356e7307b548d449205e5f4495b909f Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 05:10:36 -0400 Subject: [PATCH 012/247] refactor: reorganize & rename files --- ts/src/{pre.ts => -pre.ts} | 0 ts/src/binaryen.ts | 14 +++++++------- ts/src/{ => class}/ExpressionRunner.ts | 8 ++++---- ts/src/{ => class}/Function.ts | 4 ++-- ts/src/{ => class}/Module.ts | 4 ++-- ts/src/{ => class}/Relooper.ts | 2 +- ts/src/{ => class}/Table.ts | 4 ++-- ts/src/{ => class}/TypeBuilder.ts | 2 +- ts/src/{expressions => class/expression}/Block.ts | 8 ++++---- .../expression}/Expression.ts | 6 +++--- ts/src/{expressions => class/expression}/index.ts | 0 ts/src/constants.ts | 2 +- ts/src/global.ts | 10 +++++----- ts/src/utils.ts | 2 +- 14 files changed, 33 insertions(+), 33 deletions(-) rename ts/src/{pre.ts => -pre.ts} (100%) rename ts/src/{ => class}/ExpressionRunner.ts (92%) rename ts/src/{ => class}/Function.ts (86%) rename ts/src/{ => class}/Module.ts (97%) rename ts/src/{ => class}/Relooper.ts (87%) rename ts/src/{ => class}/Table.ts (83%) rename ts/src/{ => class}/TypeBuilder.ts (90%) rename ts/src/{expressions => class/expression}/Block.ts (84%) rename ts/src/{expressions => class/expression}/Expression.ts (77%) rename ts/src/{expressions => class/expression}/index.ts (100%) diff --git a/ts/src/pre.ts b/ts/src/-pre.ts similarity index 100% rename from ts/src/pre.ts rename to ts/src/-pre.ts diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 1dfb04c901f..e32cabeeb4d 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1,13 +1,13 @@ +export * from "./constants.ts"; +export * from "./global.ts"; export { ExpressionRunner, ExpressionRunnerFlag, -} from "./ExpressionRunner.ts"; +} from "./class/ExpressionRunner.ts"; export { Feature, Module, -} from "./Module.ts"; -export {Relooper} from "./Relooper.ts"; -export {TypeBuilder} from "./TypeBuilder.ts"; -export * from "./constants.ts"; -export * from "./expressions/index.ts"; -export * from "./global.ts"; +} from "./class/Module.ts"; +export {Relooper} from "./class/Relooper.ts"; +export {TypeBuilder} from "./class/TypeBuilder.ts"; +export * from "./class/expression/index.ts"; diff --git a/ts/src/ExpressionRunner.ts b/ts/src/class/ExpressionRunner.ts similarity index 92% rename from ts/src/ExpressionRunner.ts rename to ts/src/class/ExpressionRunner.ts index 3fa3791bf81..76c770fd109 100644 --- a/ts/src/ExpressionRunner.ts +++ b/ts/src/class/ExpressionRunner.ts @@ -1,13 +1,13 @@ -import type {Module} from "./Module.ts"; +import {BinaryenObj} from "../-pre.ts"; import type { ExpressionRef, ExpressionRunnerRef, -} from "./constants.ts"; -import {BinaryenObj} from "./pre.ts"; +} from "../constants.ts"; import { preserveStack, strToStack, -} from "./utils.ts"; +} from "../utils.ts"; +import type {Module} from "./Module.ts"; diff --git a/ts/src/Function.ts b/ts/src/class/Function.ts similarity index 86% rename from ts/src/Function.ts rename to ts/src/class/Function.ts index 75a56c9899a..d773cc46700 100644 --- a/ts/src/Function.ts +++ b/ts/src/class/Function.ts @@ -1,5 +1,5 @@ -import type {FunctionRef} from "./constants.ts"; -import {THIS_PTR} from "./utils.ts"; +import type {FunctionRef} from "../constants.ts"; +import {THIS_PTR} from "../utils.ts"; diff --git a/ts/src/Module.ts b/ts/src/class/Module.ts similarity index 97% rename from ts/src/Module.ts rename to ts/src/class/Module.ts index 5d844895b2d..48a6be613ed 100644 --- a/ts/src/Module.ts +++ b/ts/src/class/Module.ts @@ -1,5 +1,5 @@ -import {block} from "./expressions/Block.ts"; -import {BinaryenObj} from "./pre.ts"; +import {BinaryenObj} from "../-pre.ts"; +import {block} from "./expression/Block.ts"; diff --git a/ts/src/Relooper.ts b/ts/src/class/Relooper.ts similarity index 87% rename from ts/src/Relooper.ts rename to ts/src/class/Relooper.ts index 9128b6c81da..44e61216bee 100644 --- a/ts/src/Relooper.ts +++ b/ts/src/class/Relooper.ts @@ -1,5 +1,5 @@ +import {BinaryenObj} from "../-pre.ts"; import type {Module} from "./Module.ts"; -import {BinaryenObj} from "./pre.ts"; diff --git a/ts/src/Table.ts b/ts/src/class/Table.ts similarity index 83% rename from ts/src/Table.ts rename to ts/src/class/Table.ts index bac8a4b1b7e..f45f098375e 100644 --- a/ts/src/Table.ts +++ b/ts/src/class/Table.ts @@ -1,5 +1,5 @@ -import type {TableRef} from "./constants.ts"; -import {THIS_PTR} from "./utils.ts"; +import type {TableRef} from "../constants.ts"; +import {THIS_PTR} from "../utils.ts"; diff --git a/ts/src/TypeBuilder.ts b/ts/src/class/TypeBuilder.ts similarity index 90% rename from ts/src/TypeBuilder.ts rename to ts/src/class/TypeBuilder.ts index 34473000dbd..c06c95cc468 100644 --- a/ts/src/TypeBuilder.ts +++ b/ts/src/class/TypeBuilder.ts @@ -1,4 +1,4 @@ -import {BinaryenObj} from "./pre.ts"; +import {BinaryenObj} from "../-pre.ts"; diff --git a/ts/src/expressions/Block.ts b/ts/src/class/expression/Block.ts similarity index 84% rename from ts/src/expressions/Block.ts rename to ts/src/class/expression/Block.ts index f27236a7cfe..76a523995c5 100644 --- a/ts/src/expressions/Block.ts +++ b/ts/src/class/expression/Block.ts @@ -1,15 +1,15 @@ -import {Module} from "../Module.ts"; +import {BinaryenObj} from "../../-pre.ts"; import { type ExpressionRef, type Type, none, -} from "../constants.ts"; -import {BinaryenObj} from "../pre.ts"; +} from "../../constants.ts"; import { i32sToStack, preserveStack, strToStack, -} from "../utils.ts"; +} from "../../utils.ts"; +import type {Module} from "../Module.ts"; import {Expression} from "./Expression.ts"; diff --git a/ts/src/expressions/Expression.ts b/ts/src/class/expression/Expression.ts similarity index 77% rename from ts/src/expressions/Expression.ts rename to ts/src/class/expression/Expression.ts index 6993b66b700..c74e1b3fd38 100644 --- a/ts/src/expressions/Expression.ts +++ b/ts/src/class/expression/Expression.ts @@ -1,6 +1,6 @@ -import type {ExpressionRef} from "../constants.ts"; -import {BinaryenObj} from "../pre.ts"; -import {THIS_PTR} from "../utils.ts"; +import {BinaryenObj} from "../../-pre.ts"; +import type {ExpressionRef} from "../../constants.ts"; +import {THIS_PTR} from "../../utils.ts"; diff --git a/ts/src/expressions/index.ts b/ts/src/class/expression/index.ts similarity index 100% rename from ts/src/expressions/index.ts rename to ts/src/class/expression/index.ts diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 09fa43f2575..b05bd417835 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -1,4 +1,4 @@ -import {BinaryenObj} from "./pre.ts"; +import {BinaryenObj} from "./-pre.ts"; diff --git a/ts/src/global.ts b/ts/src/global.ts index 4b35d7489cd..83d3e87b19a 100644 --- a/ts/src/global.ts +++ b/ts/src/global.ts @@ -1,12 +1,12 @@ -import type { - HeapType, - Type, -} from "./constants.ts"; import { BinaryenObj, getExceptionMessage, stackAlloc, -} from "./pre.ts"; +} from "./-pre.ts"; +import type { + HeapType, + Type, +} from "./constants.ts"; import { HEAPU32, i32sToStack, diff --git a/ts/src/utils.ts b/ts/src/utils.ts index b3913ce639e..b9c1a8cb559 100644 --- a/ts/src/utils.ts +++ b/ts/src/utils.ts @@ -4,7 +4,7 @@ import { stackRestore, stackSave, stringToUTF8OnStack, -} from "./pre.ts"; +} from "./-pre.ts"; From 7629cc9c25260adf2c242809a73b4b5054ffca61 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 05:27:06 -0400 Subject: [PATCH 013/247] docs: update header comments --- ts/src/class/Function.ts | 2 +- ts/src/class/Table.ts | 2 +- ts/src/constants.ts | 32 ++++++++++++++++---------------- ts/src/global.ts | 12 ++++++------ ts/src/utils.ts | 10 +++++----- ts/tsconfig.json | 2 +- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ts/src/class/Function.ts b/ts/src/class/Function.ts index d773cc46700..6230aafb499 100644 --- a/ts/src/class/Function.ts +++ b/ts/src/class/Function.ts @@ -19,7 +19,7 @@ class BinaryenFunction { static setBody() {} - readonly [THIS_PTR]: FunctionRef; + private readonly [THIS_PTR]: FunctionRef; constructor(func: FunctionRef) { this[THIS_PTR] = func; diff --git a/ts/src/class/Table.ts b/ts/src/class/Table.ts index f45f098375e..6a504f0ac0b 100644 --- a/ts/src/class/Table.ts +++ b/ts/src/class/Table.ts @@ -16,7 +16,7 @@ export class Table { static setType() {} - readonly [THIS_PTR]: TableRef; + private readonly [THIS_PTR]: TableRef; constructor(table: TableRef) { this[THIS_PTR] = table; diff --git a/ts/src/constants.ts b/ts/src/constants.ts index b05bd417835..f356200a54d 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -1,9 +1,9 @@ -import {BinaryenObj} from "./-pre.ts"; +// # Expressions, Types, and Constants # // +// Compile-time types used by TypeScript, Binaryen types, expression types, and other enums. -// # Expressions, Types, and Constants # // -// Compile-time types used by TypeScript, Binaryen types, expression types, and other enums. +import {BinaryenObj} from "./-pre.ts"; @@ -42,29 +42,29 @@ export const f64: Type = BinaryenObj["_BinaryenTypeFloat64"](); export const v128: Type = BinaryenObj["_BinaryenTypeVec128"](); // ### Reference Types ### // -/** Reference type `(ref null any)`. */ +/** `(ref null any)` */ export const anyref: Type = BinaryenObj["_BinaryenTypeAnyref"](); -/** Reference type `(ref null eq)`. */ +/** `(ref null eq)` */ export const eqref: Type = BinaryenObj["_BinaryenTypeEqref"](); -/** Reference type `(ref null i31)`. */ +/** `(ref null i31)` */ export const i31ref: Type = BinaryenObj["_BinaryenTypeI31ref"](); -/** Reference type `(ref null struct)`. */ +/** `(ref null struct)` */ export const structref: Type = BinaryenObj["_BinaryenTypeStructref"](); -/** Reference type `(ref null array)`. */ +/** `(ref null array)` */ export const arrayref: Type = BinaryenObj["_BinaryenTypeArrayref"](); -/** Reference type `(ref null func)`. */ +/** `(ref null func)` */ export const funcref: Type = BinaryenObj["_BinaryenTypeFuncref"](); -/** Reference type `(ref null exn)`. */ +/** `(ref null exn)` */ // export const exnref: Type = BinaryenObj["_BinaryenTypeExnref"](); // TODO: uncomment once supported in Binaryen -/** Reference type `(ref null extern)`. */ +/** `(ref null extern)` */ export const externref: Type = BinaryenObj["_BinaryenTypeExternref"](); -/** Reference type `(ref null none)`. */ +/** `(ref null none)` */ export const nullref: Type = BinaryenObj["_BinaryenTypeNullref"](); -/** Reference type `(ref null nofunc)`. */ +/** `(ref null nofunc)` */ export const nullfuncref: Type = BinaryenObj["_BinaryenTypeNullFuncref"](); -/** Reference type `(ref null noexn)`. */ +/** `(ref null noexn)` */ // export const nullexnref: Type = BinaryenObj["_BinaryenTypeNullExnref"](); // TODO: uncomment once supported in Binaryen -/** Reference type `(ref null noextern)`. */ +/** `(ref null noextern)` */ export const nullexternref: Type = BinaryenObj["_BinaryenTypeNullExternref"](); // ### Packed Types ### // @@ -74,7 +74,7 @@ export const i16: Type = BinaryenObj["_BinaryenPackedTypeInt16"](); // ### Proposed Types ### // // These types are not yet in the WASM spec. Move them to their respective sections once finalized. -/** Reference type `(ref null string)`. */ +/** `(ref null string)` */ export const stringref: Type = BinaryenObj["_BinaryenTypeStringref"](); diff --git a/ts/src/global.ts b/ts/src/global.ts index 83d3e87b19a..e81882282e2 100644 --- a/ts/src/global.ts +++ b/ts/src/global.ts @@ -1,3 +1,8 @@ +// # Globals # // +// Top-level functions available in the public API. + + + import { BinaryenObj, getExceptionMessage, @@ -15,11 +20,6 @@ import { -// # Globals # // -// Top-level functions available in the public API. - - - /** * Calls a function, wrapping it in error handling code so that if it hits a * fatal error, we throw a JS exception (which JS can handle) rather than @@ -127,7 +127,7 @@ export function getSideEffects() {} -// ## Global Getters and Setters ## // +// ## Global Getters & Setters ## // export function getOptimizeLevel() {}; export function setOptimizeLevel() {}; diff --git a/ts/src/utils.ts b/ts/src/utils.ts index b9c1a8cb559..6031cb54851 100644 --- a/ts/src/utils.ts +++ b/ts/src/utils.ts @@ -1,3 +1,8 @@ +// # Utilities # // +// Functions and constants used internally. These are not exported publicly. + + + import { BinaryenObj, stackAlloc, @@ -8,11 +13,6 @@ import { -// # Utilities # // -// Global functions and constants needed across all `.ts` files. These are not exported publicly. - - - export const HEAP8: Int8Array = BinaryenObj["HEAP8"] as any; export const HEAPU8: Uint8Array = BinaryenObj["HEAPU8"] as any; export const HEAP32: Int32Array = BinaryenObj["HEAP32"] as any; diff --git a/ts/tsconfig.json b/ts/tsconfig.json index 134d6aeb5cc..4338b96da6f 100644 --- a/ts/tsconfig.json +++ b/ts/tsconfig.json @@ -1,5 +1,5 @@ { - // Reference: https://www.typescriptlang.org/tsconfig/ + // TSConfig: https://www.typescriptlang.org/tsconfig/ "compilerOptions": { // Type Checking "exactOptionalPropertyTypes": true, From 70844161bdc3fc447710ebf8629bd7598b675f88 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 06:07:57 -0400 Subject: [PATCH 014/247] feat: setup more module methods --- ts/src/class/Module.ts | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/ts/src/class/Module.ts b/ts/src/class/Module.ts index 48a6be613ed..2d92a83ec74 100644 --- a/ts/src/class/Module.ts +++ b/ts/src/class/Module.ts @@ -67,6 +67,10 @@ export class Module { getGlobal() {} + getGlobalByIndex() {} + + getNumGlobals() {} + removeGlobal() {} // ### Memories ### // @@ -81,6 +85,10 @@ export class Module { getTable() {} + getTableByIndex() {} + + getNumTables() {} + getTableSegments() {} removeTable() {} @@ -92,6 +100,10 @@ export class Module { removeFunction() {} + getNumFunctions() {} + + getFunctionByIndex() {} + // ### Data Segments ### // getNumDataSegments() {} @@ -108,6 +120,10 @@ export class Module { getElementSegment() {} + getElementSegmentByIndex() {} + + getNumElementSegments() {} + removeElementSegment() {} // ### Start Function ### // @@ -135,7 +151,56 @@ export class Module { addFunctionExport() {} + getExport() {} + + getNumExports() {} + + getExportByIndex() {} + removeExport() {} + + // ## Binaryen Operations ## // + emitText() {} + + emitStackIR() {} + + emitAsmjs() {} + + emitBinary() {} + + getFeatures() {} + + setFeatures() {} + + setTypeName() {} + + setFieldName() {} + + addCustomSection() {} + + interpret() {} + + validate() {} + + optimize() {} + + optimizeFunction() {} + + updateMaps() {} + + runPasses() {} + + runPassesOnFunction() {} + + dispose() {} + + addDebugInfoFileName() {} + + getDebugInfoFileName() {} + + setDebugLocation() {} + + copyExpression() {} } From 31c537e3a89915b0843aebc3f1bdb7f73bd578fb Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 06:09:35 -0400 Subject: [PATCH 015/247] fix: backwards-compatible enum names --- ts/src/class/Module.ts | 2 ++ ts/src/constants.ts | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/ts/src/class/Module.ts b/ts/src/class/Module.ts index 2d92a83ec74..18a6bc57dfe 100644 --- a/ts/src/class/Module.ts +++ b/ts/src/class/Module.ts @@ -42,6 +42,8 @@ export enum Feature { WideArithmetic = BinaryenObj["_BinaryenFeatureWideArithmetic"](), All = BinaryenObj["_BinaryenFeatureAll"](), } +/** @deprecated Enum name is now singular. */ +export const Features = Feature; diff --git a/ts/src/constants.ts b/ts/src/constants.ts index f356200a54d..0f50115ecaa 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -188,6 +188,8 @@ export enum ExpressionId { StringWTF16Get = BinaryenObj["_BinaryenStringWTF16GetId"](), StringSliceWTF = BinaryenObj["_BinaryenStringSliceWTFId"](), } +/** @deprecated Enum name is now singular. */ +export const ExpressionIds = ExpressionId; @@ -647,6 +649,8 @@ export enum Operation { StringEqEqual = BinaryenObj["_BinaryenStringEqEqual"](), StringEqCompare = BinaryenObj["_BinaryenStringEqCompare"](), } +/** @deprecated Enum name is now singular. */ +export const Operations = Operation; @@ -659,6 +663,8 @@ export enum ExternalKind { ExternalTable = BinaryenObj["_BinaryenExternalTable"](), ExternalFunction = BinaryenObj["_BinaryenExternalFunction"](), } +/** @deprecated Enum name is now singular. */ +export const ExternalKinds = ExternalKind; @@ -689,3 +695,5 @@ export enum SideEffect { TrapsNeverHappen = BinaryenObj["_BinaryenSideEffectTrapsNeverHappen"](), Any = BinaryenObj["_BinaryenSideEffectAny"](), } +/** @deprecated Enum name is now singular. */ +export const SideEffects = SideEffect; From d166932ed111cb319b32b4aff9c92c874a5c0279 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 06:16:45 -0400 Subject: [PATCH 016/247] lint: private pointers --- ts/src/class/ExpressionRunner.ts | 10 +++++----- ts/src/class/Relooper.ts | 4 ++-- ts/src/class/TypeBuilder.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ts/src/class/ExpressionRunner.ts b/ts/src/class/ExpressionRunner.ts index 76c770fd109..83fe32099cb 100644 --- a/ts/src/class/ExpressionRunner.ts +++ b/ts/src/class/ExpressionRunner.ts @@ -19,21 +19,21 @@ export enum ExpressionRunnerFlag { export class ExpressionRunner { - readonly ptr: ExpressionRunnerRef; + readonly #ptr: ExpressionRunnerRef; constructor(mod: Module, flags: ExpressionRunnerFlag, maxDepth: number, maxLoopIterations: number) { - this.ptr = BinaryenObj["_ExpressionRunnerCreate"](mod.ptr, flags, maxDepth, maxLoopIterations); + this.#ptr = BinaryenObj["_ExpressionRunnerCreate"](mod.ptr, flags, maxDepth, maxLoopIterations); } setLocalValue(index: number, valueExpr: ExpressionRef): boolean { - return Boolean(BinaryenObj["_ExpressionRunnerSetLocalValue"](this.ptr, index, valueExpr)); + return Boolean(BinaryenObj["_ExpressionRunnerSetLocalValue"](this.#ptr, index, valueExpr)); } setGlobalValue(name: string, valueExpr: ExpressionRef): boolean { - return preserveStack(() => Boolean(BinaryenObj["_ExpressionRunnerSetGlobalValue"](this.ptr, strToStack(name), valueExpr))); + return preserveStack(() => Boolean(BinaryenObj["_ExpressionRunnerSetGlobalValue"](this.#ptr, strToStack(name), valueExpr))); } runAndDispose(expr: ExpressionRef): ExpressionRef { - return BinaryenObj["_ExpressionRunnerRunAndDispose"](this.ptr, expr); + return BinaryenObj["_ExpressionRunnerRunAndDispose"](this.#ptr, expr); } } diff --git a/ts/src/class/Relooper.ts b/ts/src/class/Relooper.ts index 44e61216bee..6024272af20 100644 --- a/ts/src/class/Relooper.ts +++ b/ts/src/class/Relooper.ts @@ -4,10 +4,10 @@ import type {Module} from "./Module.ts"; export class Relooper { - readonly ptr: number; + readonly #ptr: number; constructor(mod: Module) { - this.ptr = BinaryenObj["_RelooperCreate"](mod.ptr) + this.#ptr = BinaryenObj["_RelooperCreate"](mod.ptr); } addBlock() {} diff --git a/ts/src/class/TypeBuilder.ts b/ts/src/class/TypeBuilder.ts index c06c95cc468..278b027dc70 100644 --- a/ts/src/class/TypeBuilder.ts +++ b/ts/src/class/TypeBuilder.ts @@ -3,10 +3,10 @@ import {BinaryenObj} from "../-pre.ts"; export class TypeBuilder { - readonly ptr: number; + readonly #ptr: number; constructor(size: number) { - this.ptr = BinaryenObj["_TypeBuilderCreate"](size); + this.#ptr = BinaryenObj["_TypeBuilderCreate"](size); } grow() {} From 46b4b8df94627572380069d75ada27b955bdd12c Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 06:46:24 -0400 Subject: [PATCH 017/247] feat: add classes for locals --- ts/src/class/Module.ts | 14 ++++++++++++++ ts/src/class/expression/Block.ts | 2 +- ts/src/class/expression/LocalGet.ts | 21 +++++++++++++++++++++ ts/src/class/expression/LocalSet.ts | 28 ++++++++++++++++++++++++++++ ts/src/class/expression/index.ts | 2 ++ 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 ts/src/class/expression/LocalGet.ts create mode 100644 ts/src/class/expression/LocalSet.ts diff --git a/ts/src/class/Module.ts b/ts/src/class/Module.ts index 18a6bc57dfe..9f2d81800a2 100644 --- a/ts/src/class/Module.ts +++ b/ts/src/class/Module.ts @@ -1,5 +1,10 @@ import {BinaryenObj} from "../-pre.ts"; import {block} from "./expression/Block.ts"; +import {localGet} from "./expression/LocalGet.ts"; +import { + localSet, + localTee, +} from "./expression/LocalSet.ts"; @@ -54,6 +59,15 @@ export class Module { // ### Control Instructions ### // block = block; + // ### Variable Instructions ### // + get local() { + return { + get: localGet.bind(this), + set: localSet.bind(this), + tee: localTee.bind(this), + }; + } + // ## Module Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html diff --git a/ts/src/class/expression/Block.ts b/ts/src/class/expression/Block.ts index 76a523995c5..c25bc47aa25 100644 --- a/ts/src/class/expression/Block.ts +++ b/ts/src/class/expression/Block.ts @@ -30,7 +30,7 @@ export class Block extends Expression { -export function block(this: Module, name: string, children: readonly ExpressionRef[], resultType: Type = none) { +export function block(this: Module, name: string, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef { return preserveStack(() => BinaryenObj["_BinaryenBlock"]( this.ptr, strToStack(name), diff --git a/ts/src/class/expression/LocalGet.ts b/ts/src/class/expression/LocalGet.ts new file mode 100644 index 00000000000..4eed08c1b3a --- /dev/null +++ b/ts/src/class/expression/LocalGet.ts @@ -0,0 +1,21 @@ +import {BinaryenObj} from "../../-pre.ts"; +import { + type ExpressionRef, + type Type, +} from "../../constants.ts"; +import type {Module} from "../Module.ts"; +import {Expression} from "./Expression.ts"; + + + +export class LocalGet extends Expression { + // TODO: static methods are deprecated; convert to instance and log warnings + static getIndex() {} + static setIndex() {} +} + + + +export function localGet(this: Module, index: number, type: Type): ExpressionRef { + return BinaryenObj["_BinaryenLocalGet"](this.ptr, index, type); +} diff --git a/ts/src/class/expression/LocalSet.ts b/ts/src/class/expression/LocalSet.ts new file mode 100644 index 00000000000..f4b59286467 --- /dev/null +++ b/ts/src/class/expression/LocalSet.ts @@ -0,0 +1,28 @@ +import {BinaryenObj} from "../../-pre.ts"; +import { + type ExpressionRef, + type Type, +} from "../../constants.ts"; +import type {Module} from "../Module.ts"; +import {Expression} from "./Expression.ts"; + + + +export class LocalSet extends Expression { + // TODO: static methods are deprecated; convert to instance and log warnings + static getIndex() {} + static setIndex() {} + static isTee() {} + static getValue() {} + static setValue() {} +} + + + +export function localSet(this: Module, index: number, value: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenLocalSet"](this.ptr, index, value); +} + +export function localTee(this: Module, index: number, value: ExpressionRef, type: Type): ExpressionRef { + return BinaryenObj["_BinaryenLocalTee"](this.ptr, index, value, type); +} diff --git a/ts/src/class/expression/index.ts b/ts/src/class/expression/index.ts index bcdd81b3906..bab69332479 100644 --- a/ts/src/class/expression/index.ts +++ b/ts/src/class/expression/index.ts @@ -1 +1,3 @@ export {Block} from "./Block.ts"; +export {LocalGet} from "./LocalGet.ts"; +export {LocalSet} from "./LocalSet.ts"; From 5695e2057462759eb061e9d66fec0993b59b9f14 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 06:54:39 -0400 Subject: [PATCH 018/247] feat: add EXPR_WRAPPERS --- ts/src/class/expression/Block.ts | 6 ++++++ ts/src/class/expression/Expression.ts | 13 +++++++++++-- ts/src/class/expression/LocalGet.ts | 6 ++++++ ts/src/class/expression/LocalSet.ts | 6 ++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/ts/src/class/expression/Block.ts b/ts/src/class/expression/Block.ts index c25bc47aa25..d0ce910d29d 100644 --- a/ts/src/class/expression/Block.ts +++ b/ts/src/class/expression/Block.ts @@ -1,5 +1,6 @@ import {BinaryenObj} from "../../-pre.ts"; import { + ExpressionId, type ExpressionRef, type Type, none, @@ -26,6 +27,11 @@ export class Block extends Expression { static appendChild() {} static insertChildAt() {} static removeChildAt() {} + + + constructor(expr: ExpressionRef) { + super(ExpressionId.Block, expr); + } } diff --git a/ts/src/class/expression/Expression.ts b/ts/src/class/expression/Expression.ts index c74e1b3fd38..157338a81a0 100644 --- a/ts/src/class/expression/Expression.ts +++ b/ts/src/class/expression/Expression.ts @@ -1,9 +1,17 @@ import {BinaryenObj} from "../../-pre.ts"; -import type {ExpressionRef} from "../../constants.ts"; +import type { + ExpressionId, + ExpressionRef, +} from "../../constants.ts"; import {THIS_PTR} from "../../utils.ts"; +/** Expression ID-to-wrapper map. */ +export const EXPR_WRAPPERS = new Map(); + + + /** Base class of all expression wrappers. */ export class Expression { // TODO: static methods are deprecated; convert to instance and log warnings @@ -18,8 +26,9 @@ export class Expression { protected readonly [THIS_PTR]: number; - constructor(expr: ExpressionRef) { + constructor(exprId: ExpressionId, expr: ExpressionRef) { this[THIS_PTR] = expr; + EXPR_WRAPPERS.set(exprId, this); } valueOf() { diff --git a/ts/src/class/expression/LocalGet.ts b/ts/src/class/expression/LocalGet.ts index 4eed08c1b3a..e5f70396095 100644 --- a/ts/src/class/expression/LocalGet.ts +++ b/ts/src/class/expression/LocalGet.ts @@ -1,5 +1,6 @@ import {BinaryenObj} from "../../-pre.ts"; import { + ExpressionId, type ExpressionRef, type Type, } from "../../constants.ts"; @@ -12,6 +13,11 @@ export class LocalGet extends Expression { // TODO: static methods are deprecated; convert to instance and log warnings static getIndex() {} static setIndex() {} + + + constructor(expr: ExpressionRef) { + super(ExpressionId.LocalGet, expr); + } } diff --git a/ts/src/class/expression/LocalSet.ts b/ts/src/class/expression/LocalSet.ts index f4b59286467..866e00dc39a 100644 --- a/ts/src/class/expression/LocalSet.ts +++ b/ts/src/class/expression/LocalSet.ts @@ -1,5 +1,6 @@ import {BinaryenObj} from "../../-pre.ts"; import { + ExpressionId, type ExpressionRef, type Type, } from "../../constants.ts"; @@ -15,6 +16,11 @@ export class LocalSet extends Expression { static isTee() {} static getValue() {} static setValue() {} + + + constructor(expr: ExpressionRef) { + super(ExpressionId.LocalSet, expr); + } } From b016ac494a9b3a96dae47de63ea5a265d4571304 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:30:07 -0400 Subject: [PATCH 019/247] feat: finish Relooper class --- ts/src/class/Relooper.ts | 68 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/ts/src/class/Relooper.ts b/ts/src/class/Relooper.ts index 6024272af20..780687f3c10 100644 --- a/ts/src/class/Relooper.ts +++ b/ts/src/class/Relooper.ts @@ -1,4 +1,12 @@ import {BinaryenObj} from "../-pre.ts"; +import type { + ExpressionRef, + RelooperBlockRef, +} from "../constants.ts"; +import { + i32sToStack, + preserveStack, +} from "../utils.ts"; import type {Module} from "./Module.ts"; @@ -6,17 +14,67 @@ import type {Module} from "./Module.ts"; export class Relooper { readonly #ptr: number; + /** + * Constructs a relooper instance. + * This lets you provide an arbitrary CFG, and the relooper will structure it for WebAssembly. + * @param mod the binaryen Module + */ constructor(mod: Module) { this.#ptr = BinaryenObj["_RelooperCreate"](mod.ptr); } - addBlock() {} + /** + * Adds a new block to the CFG, containing the provided code as its body. + * @param code the block expression + * @return a reference to the block + */ + addBlock(code: ExpressionRef): RelooperBlockRef { + return BinaryenObj["_RelooperAddBlock"](this.#ptr, code); + } - addBranch() {} + /** + * Adds a branch from a block to another block, with a condition + * (or nothing, if this is the default branch to take from the origin — + * each block must have one such branch), and optional code to execute + * on the branch (useful for phis). + * @param from source block + * @param to destination block + * @param condition contition to evaluate: if true, jumps to the given block; else does nothing + * @param code code to evaluate in between block jumps + */ + addBranch(from: RelooperBlockRef, to: RelooperBlockRef, condition: ExpressionRef, code: ExpressionRef): void { + BinaryenObj["_RelooperAddBranch"](from, to, condition, code); + } - addBlockWithSwitch() {} + /** + * Adds a new block, which ends with a switch/br_table, with provided code and condition + * (that determines where we go in the switch). + * @param code the block expression + * @param condition contition to determine the jump destination + */ + addBlockWithSwitch(code: ExpressionRef, condition: ExpressionRef): RelooperBlockRef { + return BinaryenObj["_RelooperAddBlockWithSwitch"](this.#ptr, code, condition); + } - addBranchForSwitch() {} + /** + * Adds a branch from a block ending in a switch, to another block, + * using an array of indexes that determine where to go, and optional code to execute on the branch. + * @param from source block + * @param to destination block + * @param indexes array containing corresponding indices for destination blocks + * @param code code to evaluate in between block jumps + */ + addBranchForSwitch(from: RelooperBlockRef, to: RelooperBlockRef, indexes: readonly number[], code: ExpressionRef): void { + preserveStack(() => BinaryenObj["_RelooperAddBranchForSwitch"](from, to, i32sToStack(indexes), indexes.length, code)); + } - renderAndDispose() {} + /** + * Renders and cleans up the Relooper instance. + * Call this after you have created all the blocks and branches, giving it the entry block (where control flow begins), + * a label helper variable (an index of a local we can use, necessary for irreducible control flow), and the module. + * This returns an expression — normal WebAssembly code — that you can use normally anywhere. + */ + renderAndDispose(entry: RelooperBlockRef, labelHelper: number): ExpressionRef { + return BinaryenObj["_RelooperRenderAndDispose"](this.#ptr, entry, labelHelper); + } } From 4007de3abb3d5d55fa12c6e5815e1b731f057856 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 13:54:48 -0400 Subject: [PATCH 020/247] build: install & enable eslint --- ts/.editorconfig | 2 + ts/eslint.config.js | 160 ++++++ ts/package-lock.json | 1299 +++++++++++++++++++++++++++++++++++++++++- ts/package.json | 13 +- 4 files changed, 1469 insertions(+), 5 deletions(-) create mode 100644 ts/eslint.config.js diff --git a/ts/.editorconfig b/ts/.editorconfig index 9ed5f2c1ab3..555ff2e4735 100644 --- a/ts/.editorconfig +++ b/ts/.editorconfig @@ -1,5 +1,7 @@ # EditorConfig: https://EditorConfig.org +root = true + [*] charset = utf-8 end_of_line = lf diff --git a/ts/eslint.config.js b/ts/eslint.config.js new file mode 100644 index 00000000000..14dea8f6482 --- /dev/null +++ b/ts/eslint.config.js @@ -0,0 +1,160 @@ +import eslint from "@eslint/js"; +import stylistic from "@stylistic/eslint-plugin"; +import globals from "globals"; +import tseslint from "typescript-eslint"; + + + +export default [ + {ignores: ["./dist/"]}, + + eslint.configs.recommended, // https://github.com/eslint/eslint/blob/v10.2.1/packages/js/src/configs/eslint-recommended.js + { + name: "All", // all JS and TS files + files: ["./eslint.config.js", "./src/**/*.{js,ts}"], + languageOptions: {globals: {...globals.node}}, + linterOptions: {reportUnusedDisableDirectives: "error"}, + plugins: {"@stylistic": stylistic}, + + rules: { + /* # File Conventions (should be consistent with `/.editorconfig` file) */ + "@stylistic/eol-last": "error", + "@stylistic/linebreak-style": "error", + "@stylistic/no-trailing-spaces": "error", + + /* # Layout & Formatting */ + /* ## Indentation, Spacing, and Alignment */ + "@stylistic/arrow-spacing": "error", + "@stylistic/comma-spacing": "error", + "@stylistic/dot-location": ["error", "property"], + "@stylistic/function-call-spacing": "error", + "@stylistic/indent": ["error", "tab", { + SwitchCase: 1, + flatTernaryExpressions: true, + }], + "@stylistic/key-spacing": "error", + "@stylistic/keyword-spacing": "error", + "@stylistic/no-mixed-spaces-and-tabs": "error", + "@stylistic/semi-spacing": "error", + "@stylistic/space-before-blocks": "error", + "@stylistic/space-before-function-paren": ["error", {named: "never"}], + "@stylistic/space-infix-ops": "error", + "@stylistic/space-unary-ops": "error", + "@stylistic/spaced-comment": "error", + "@stylistic/type-annotation-spacing": "error", + + /* ## Grouping Structure Style */ + "@stylistic/array-bracket-newline": ["error", "consistent"], + "@stylistic/array-bracket-spacing": "error", + "@stylistic/array-element-newline": ["error", "consistent"], + "arrow-body-style": "error", + "@stylistic/brace-style": "error", + "@stylistic/computed-property-spacing": "error", + curly: "error", + "@stylistic/function-call-argument-newline": ["error", "consistent"], + "@stylistic/function-paren-newline": "error", + "func-style": ["error", "declaration", {allowArrowFunctions: true}], + "@stylistic/lines-between-class-members": ["error", "always", {exceptAfterSingleLine: true}], + "@stylistic/member-delimiter-style": ["error", { + overrides: { + interface: {singleline: {requireLast: true}}, + typeLiteral: { + multiline: {delimiter: "comma"}, + singleline: {delimiter: "comma"}, + }, + }, + }], + "no-useless-computed-key": "error", + "@stylistic/object-curly-newline": ["error", { + ObjectExpression: {multiline: true}, + ObjectPattern: {multiline: true}, + ImportDeclaration: "always", + ExportDeclaration: {multiline: true}, + TSTypeLiteral: {multiline: true}, + TSInterfaceBody: "always", + TSEnumBody: "always", + }], + "@stylistic/object-curly-spacing": "error", + "@stylistic/object-property-newline": ["error", {allowAllPropertiesOnSameLine: true}], + "object-shorthand": ["error", "properties", {avoidQuotes: true}], + "@stylistic/padded-blocks": ["error", "never"], + "@stylistic/quote-props": ["error", "as-needed"], + "@stylistic/space-in-parens": "error", + + /* ## Operator Style */ + "@stylistic/arrow-parens": "error", + "@stylistic/comma-dangle": ["error", "always-multiline"], + "@stylistic/comma-style": "error", + "dot-notation": "error", + "@stylistic/implicit-arrow-linebreak": "error", + "@stylistic/new-parens": "error", + "@stylistic/quotes": "error", + "@stylistic/semi": "error", + "@stylistic/semi-style": "error", + "@stylistic/wrap-iife": ["error", "inside", {functionPrototypeMethods: true}], + + /* # Best Practices */ + /* ## Preferred Operators & Methods */ + eqeqeq: "error", + "no-lonely-if": "error", + "no-unneeded-ternary": ["error", {defaultAssignment: false}], + "no-useless-concat": "error", + "operator-assignment": "error", + "prefer-object-spread": "error", + "prefer-template": "error", + + /* ## Variable Declarations */ + "init-declarations": "error", + "no-shadow": "error", + "no-use-before-define": "error", + "one-var": ["error", "never"], + "prefer-const": "error", + + /* ## Function & Module Design */ + "default-param-last": "error", + "func-names": ["error", "never"], + "prefer-arrow-callback": ["error", {allowUnboundThis: false}], + }, + }, + { + name: "TypeScript Only", // rules that break on JS files, and rules that need TSConfig to work + files: ["./src/**/*.ts"], + languageOptions: { + globals: {...globals.node}, + parser: tseslint.parser, + parserOptions: {project: ["./tsconfig.json"]}, + }, + plugins: {"@typescript-eslint": tseslint.plugin}, + + rules: { + /* # Layout & Formatting */ + /* ## Operator Style */ + "dot-notation": "off", + "@typescript-eslint/dot-notation": "error", + + /* # Best Practices */ + /* ## Variable Declarations */ + "init-declarations": "off", + "@typescript-eslint/init-declarations": "error", + "no-shadow": "off", + "@typescript-eslint/no-shadow": "error", + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": ["error", { + argsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + ignoreRestSiblings: true, + reportUsedIgnorePattern: true, + }], + "no-use-before-define": "off", + "@typescript-eslint/no-use-before-define": "error", + + /* ## Function & Module Design */ + "default-param-last": "off", + "@typescript-eslint/default-param-last": "error", + "@typescript-eslint/no-import-type-side-effects": "error", + + /* ## Strictness */ + "@typescript-eslint/explicit-member-accessibility": ["error", {accessibility: "no-public"}], + }, + }, +]; diff --git a/ts/package-lock.json b/ts/package-lock.json index 1084fad86e3..cf4a8f494e2 100644 --- a/ts/package-lock.json +++ b/ts/package-lock.json @@ -9,10 +9,1232 @@ "version": "0.1.0", "license": "Apache-2.0", "devDependencies": { - "typescript": "~6.0.0" + "@eslint/js": "^10.0.1", + "@stylistic/eslint-plugin": "^5.10.0", + "eslint": "^10.2.1", + "globals": "^17.5.0", + "typescript": "~6.0.0", + "typescript-eslint": "^8.59.1" }, "engines": { - "node": "^22 || ^24" + "node": "^22.6 || ^24" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", + "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz", + "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", + "integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/types": "^8.56.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.0.0 || ^10.0.0" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.1.tgz", + "integrity": "sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.59.1", + "@typescript-eslint/type-utils": "8.59.1", + "@typescript-eslint/utils": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.59.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.1.tgz", + "integrity": "sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz", + "integrity": "sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.59.1", + "@typescript-eslint/types": "^8.59.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz", + "integrity": "sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz", + "integrity": "sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.1.tgz", + "integrity": "sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1", + "@typescript-eslint/utils": "8.59.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz", + "integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz", + "integrity": "sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.59.1", + "@typescript-eslint/tsconfig-utils": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.1.tgz", + "integrity": "sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz", + "integrity": "sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.1.tgz", + "integrity": "sha512-wiyGaKsDgqXvF40P8mDwiUp/KQjE1FdrIEJsM8PZ3XCiniTMXS3OHWWUe5FI5agoCnr8x4xPrTDZuxsBlNHl+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.5.5", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.5.0.tgz", + "integrity": "sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, "node_modules/typescript": { @@ -28,6 +1250,79 @@ "engines": { "node": ">=14.17" } + }, + "node_modules/typescript-eslint": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.1.tgz", + "integrity": "sha512-xqDcFVBmlrltH64lklOVp1wYxgJr6LVdg3NamBgH2OOQDLFdTKfIZXF5PfghrnXQKXZGTQs8tr1vL7fJvq8CTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.59.1", + "@typescript-eslint/parser": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1", + "@typescript-eslint/utils": "8.59.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/ts/package.json b/ts/package.json index 657f58ad42c..b63813efa5b 100644 --- a/ts/package.json +++ b/ts/package.json @@ -16,7 +16,9 @@ "type": "module", "main": "./dist/binaryen.js", "scripts": { - "compile": "tsc" + "compile": "tsc", + "lint": "eslint ./", + "build": "npm run compile && npm run lint" }, "files": [ "package.json", @@ -25,9 +27,14 @@ "./dist/*.js" ], "devDependencies": { - "typescript": "~6.0.0" + "@eslint/js": "^10.0.1", + "@stylistic/eslint-plugin": "^5.10.0", + "eslint": "^10.2.1", + "globals": "^17.5.0", + "typescript": "~6.0.0", + "typescript-eslint": "^8.59.1" }, "engines": { - "node": "^22 || ^24" + "node": "^22.6 || ^24" } } From 33e284c56d523b9d8a8e8b792b17748d94d28d51 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 13:56:51 -0400 Subject: [PATCH 021/247] lint: run eslint --- ts/src/-pre.ts | 2 +- ts/src/class/ExpressionRunner.ts | 8 ++++++-- ts/src/class/Function.ts | 8 ++++++-- ts/src/class/Module.ts | 13 ++++++++++--- ts/src/class/Relooper.ts | 8 ++++++-- ts/src/class/Table.ts | 8 ++++++-- ts/src/class/TypeBuilder.ts | 5 ++++- ts/src/class/expression/Block.ts | 12 +++++++++--- ts/src/class/expression/Expression.ts | 9 +++++++-- ts/src/class/expression/LocalGet.ts | 12 +++++++++--- ts/src/class/expression/LocalSet.ts | 12 +++++++++--- ts/src/constants.ts | 4 +++- ts/src/global.ts | 2 ++ 13 files changed, 78 insertions(+), 25 deletions(-) diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index 331f3dede33..d844ab51e68 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -12,4 +12,4 @@ export declare function stackSave(): unknown; export declare function stackRestore(stack: unknown): unknown; export declare function stackAlloc(length: number): number; export declare function stringToUTF8OnStack(str: string): number; -export declare function getExceptionMessage(e: number | Error): [any, string]; +export declare function getExceptionMessage(e: number | Error): [unknown, string]; diff --git a/ts/src/class/ExpressionRunner.ts b/ts/src/class/ExpressionRunner.ts index 83fe32099cb..e0b40b5527b 100644 --- a/ts/src/class/ExpressionRunner.ts +++ b/ts/src/class/ExpressionRunner.ts @@ -1,4 +1,6 @@ -import {BinaryenObj} from "../-pre.ts"; +import { + BinaryenObj, +} from "../-pre.ts"; import type { ExpressionRef, ExpressionRunnerRef, @@ -7,7 +9,9 @@ import { preserveStack, strToStack, } from "../utils.ts"; -import type {Module} from "./Module.ts"; +import type { + Module, +} from "./Module.ts"; diff --git a/ts/src/class/Function.ts b/ts/src/class/Function.ts index 6230aafb499..89070f72559 100644 --- a/ts/src/class/Function.ts +++ b/ts/src/class/Function.ts @@ -1,5 +1,9 @@ -import type {FunctionRef} from "../constants.ts"; -import {THIS_PTR} from "../utils.ts"; +import type { + FunctionRef, +} from "../constants.ts"; +import { + THIS_PTR, +} from "../utils.ts"; diff --git a/ts/src/class/Module.ts b/ts/src/class/Module.ts index 9f2d81800a2..dd6e9f27cc4 100644 --- a/ts/src/class/Module.ts +++ b/ts/src/class/Module.ts @@ -1,6 +1,12 @@ -import {BinaryenObj} from "../-pre.ts"; -import {block} from "./expression/Block.ts"; -import {localGet} from "./expression/LocalGet.ts"; +import { + BinaryenObj, +} from "../-pre.ts"; +import { + block, +} from "./expression/Block.ts"; +import { + localGet, +} from "./expression/LocalGet.ts"; import { localSet, localTee, @@ -15,6 +21,7 @@ import { * we would leak them. Instead, Const creation is fused together with * an intermediate stack allocation of this size to pass the value. */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars const SIZE_OF_LITERAL = BinaryenObj["_BinaryenSizeofLiteral"](); diff --git a/ts/src/class/Relooper.ts b/ts/src/class/Relooper.ts index 780687f3c10..cc356341fc3 100644 --- a/ts/src/class/Relooper.ts +++ b/ts/src/class/Relooper.ts @@ -1,4 +1,6 @@ -import {BinaryenObj} from "../-pre.ts"; +import { + BinaryenObj, +} from "../-pre.ts"; import type { ExpressionRef, RelooperBlockRef, @@ -7,7 +9,9 @@ import { i32sToStack, preserveStack, } from "../utils.ts"; -import type {Module} from "./Module.ts"; +import type { + Module, +} from "./Module.ts"; diff --git a/ts/src/class/Table.ts b/ts/src/class/Table.ts index 6a504f0ac0b..1c5d21ad9f4 100644 --- a/ts/src/class/Table.ts +++ b/ts/src/class/Table.ts @@ -1,5 +1,9 @@ -import type {TableRef} from "../constants.ts"; -import {THIS_PTR} from "../utils.ts"; +import type { + TableRef, +} from "../constants.ts"; +import { + THIS_PTR, +} from "../utils.ts"; diff --git a/ts/src/class/TypeBuilder.ts b/ts/src/class/TypeBuilder.ts index 278b027dc70..d9210f8fbae 100644 --- a/ts/src/class/TypeBuilder.ts +++ b/ts/src/class/TypeBuilder.ts @@ -1,8 +1,11 @@ -import {BinaryenObj} from "../-pre.ts"; +import { + BinaryenObj, +} from "../-pre.ts"; export class TypeBuilder { + // eslint-disable-next-line no-unused-private-class-members readonly #ptr: number; constructor(size: number) { diff --git a/ts/src/class/expression/Block.ts b/ts/src/class/expression/Block.ts index d0ce910d29d..3a4a195e81d 100644 --- a/ts/src/class/expression/Block.ts +++ b/ts/src/class/expression/Block.ts @@ -1,4 +1,6 @@ -import {BinaryenObj} from "../../-pre.ts"; +import { + BinaryenObj, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, @@ -10,8 +12,12 @@ import { preserveStack, strToStack, } from "../../utils.ts"; -import type {Module} from "../Module.ts"; -import {Expression} from "./Expression.ts"; +import type { + Module, +} from "../Module.ts"; +import { + Expression, +} from "./Expression.ts"; diff --git a/ts/src/class/expression/Expression.ts b/ts/src/class/expression/Expression.ts index 157338a81a0..ce72a1b44ce 100644 --- a/ts/src/class/expression/Expression.ts +++ b/ts/src/class/expression/Expression.ts @@ -1,9 +1,13 @@ -import {BinaryenObj} from "../../-pre.ts"; +import { + BinaryenObj, +} from "../../-pre.ts"; import type { ExpressionId, ExpressionRef, } from "../../constants.ts"; -import {THIS_PTR} from "../../utils.ts"; +import { + THIS_PTR, +} from "../../utils.ts"; @@ -18,6 +22,7 @@ export class Expression { static getId(expr: number) { return BinaryenObj["_BinaryenExpressionGetId"](expr); } + static getType() {} static setType() {} static finalize() {} diff --git a/ts/src/class/expression/LocalGet.ts b/ts/src/class/expression/LocalGet.ts index e5f70396095..8ebcab96544 100644 --- a/ts/src/class/expression/LocalGet.ts +++ b/ts/src/class/expression/LocalGet.ts @@ -1,11 +1,17 @@ -import {BinaryenObj} from "../../-pre.ts"; +import { + BinaryenObj, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, type Type, } from "../../constants.ts"; -import type {Module} from "../Module.ts"; -import {Expression} from "./Expression.ts"; +import type { + Module, +} from "../Module.ts"; +import { + Expression, +} from "./Expression.ts"; diff --git a/ts/src/class/expression/LocalSet.ts b/ts/src/class/expression/LocalSet.ts index 866e00dc39a..d3af9c5dc57 100644 --- a/ts/src/class/expression/LocalSet.ts +++ b/ts/src/class/expression/LocalSet.ts @@ -1,11 +1,17 @@ -import {BinaryenObj} from "../../-pre.ts"; +import { + BinaryenObj, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, type Type, } from "../../constants.ts"; -import type {Module} from "../Module.ts"; -import {Expression} from "./Expression.ts"; +import type { + Module, +} from "../Module.ts"; +import { + Expression, +} from "./Expression.ts"; diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 0f50115ecaa..931dff24345 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -3,7 +3,9 @@ -import {BinaryenObj} from "./-pre.ts"; +import { + BinaryenObj, +} from "./-pre.ts"; diff --git a/ts/src/global.ts b/ts/src/global.ts index e81882282e2..30c02d3069b 100644 --- a/ts/src/global.ts +++ b/ts/src/global.ts @@ -27,6 +27,7 @@ import { * @param func the function to call * @return the return value of the given function */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars function handleFatalError(func: () => number): number { try { return func(); @@ -36,6 +37,7 @@ function handleFatalError(func: () => number): number { // Older version of emscripten can throw C++ exceptions as pointers (numbers) in release builds. const [_, message] = getExceptionMessage(e); if (message?.startsWith("Fatal: ")) { + // eslint-disable-next-line preserve-caught-error throw new Error(message.substr(7).trim()); } } else { From 9fcfbd6040f0d5dc6b9a334773f303b5556eb225 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 15:38:01 -0400 Subject: [PATCH 022/247] feat: finish TypeBuilder class --- ts/src/class/TypeBuilder.ts | 161 +++++++++++++++++++++++++++++++++--- ts/src/constants.ts | 1 + 2 files changed, 149 insertions(+), 13 deletions(-) diff --git a/ts/src/class/TypeBuilder.ts b/ts/src/class/TypeBuilder.ts index d9210f8fbae..0afe05c460c 100644 --- a/ts/src/class/TypeBuilder.ts +++ b/ts/src/class/TypeBuilder.ts @@ -1,38 +1,173 @@ import { BinaryenObj, + stackAlloc, } from "../-pre.ts"; +import type { + HeapType, + PackedType, + Type, +} from "../constants.ts"; +import { + HEAPU32, + i8sToStack, + i32sToStack, + preserveStack, +} from "../utils.ts"; + + + +type Field = { + /** The type of the struct field. */ + type: Type, + /** The field’s packed type. */ + packedType: PackedType, + /** Is the field mutable? */ + mutable: boolean, +}; export class TypeBuilder { - // eslint-disable-next-line no-unused-private-class-members readonly #ptr: number; constructor(size: number) { this.#ptr = BinaryenObj["_TypeBuilderCreate"](size); } - grow() {} + /** + * Grow the builder by the given number of types. + * @param count the number of slots to add + */ + grow(count: number): void { + BinaryenObj["_TypeBuilderGrow"](this.#ptr, count); + } - getSize() {} + /** + * @return the number of types in the builder + */ + getSize(): number { + return BinaryenObj["_TypeBuilderGetSize"](this.#ptr); + } - setSignatureType() {} + /** + * Add a function signature type + * @param index index of the type to add + * @param paramTypes function’s parameter types, as a multi-value type + * @param resultTypes function’s result types, as a multi-value type + */ + setSignatureType(index: number, paramTypes: Type, resultTypes: Type): void { + BinaryenObj["_TypeBuilderSetSignatureType"](this.#ptr, index, paramTypes, resultTypes); + } - setStructType() {} + /** + * Add a struct type. + * @param index index of the type to add + * @param fields array of fields in the struct + */ + setStructType(index: number, fields: readonly Field[]): void { + preserveStack(() => { + const numFields = fields.length; + const types = new Array(numFields); + const packedTypes = new Array(numFields); + const mutables = new Array(numFields); + for (let i = 0; i < numFields; i++) { + const {type: typ, packedType, mutable} = fields[i]; + types[i] = typ; + packedTypes[i] = packedType; + mutables[i] = mutable; + } + BinaryenObj["_TypeBuilderSetStructType"]( + this.#ptr, + index, + i32sToStack(types), + i32sToStack(packedTypes), + i8sToStack(mutables), + numFields, + ); + }); + } - setArrayType() {} + /** + * Add an array type. + * @param index index of the type to add + * @param elementType type of element in the array + * @param elementPackedType packed type of elements + * @param elementMutable are array entries mutable? + */ + setArrayType(index: number, elementType: Type, elementPackedType: Type, elementMutable: boolean): void { + BinaryenObj["_TypeBuilderSetArrayType"](this.#ptr, index, elementType, elementPackedType, elementMutable); + } - getTempHeapType() {} + /** + * Retrieve a heap type from the builder, before disposal. + * @param index index of the type to get + * @return the heap type at the given index + */ + getTempHeapType(index: number): HeapType { + return BinaryenObj["_TypeBuilderGetTempHeapType"](this.#ptr, index); + } - getTempTupleType() {} + /** + * Retrieve a tuple type. + * @param types types in the tuple + * @return the tuple type + */ + getTempTupleType(types: readonly Type[]): Type { + return preserveStack(() => BinaryenObj["_TypeBuilderGetTempTupleType"](this.#ptr, i32sToStack(types), types.length)); + } - getTempRefType() {} + /** + * Generate a refence type from the given temporary heap type. + * @param heapType the heap type in the type builder to use + * @param nullable is the reference type nullable? + * @return the reference type + */ + getTempRefType(heapType: HeapType, nullable: boolean): Type { + return BinaryenObj["_TypeBuilderGetTempRefType"](this.#ptr, heapType, nullable); + } - setSubType() {} + /** + * Declare a type as a subtype of another. + * @param index the index of the type to set + * @param superType the supertype + */ + setSubType(index: number, superType: Type): void { + BinaryenObj["_TypeBuilderSetSubType"](this.#ptr, index, superType); + } - setOpen() {} + /** + * Declare a type as “open”, i.e., not “final” (it may be extended/subtyped). + * @param index the index of the type to set + */ + setOpen(index: number): void { + BinaryenObj["_TypeBuilderSetOpen"](this.#ptr, index); + } - createRecGroup() {} + /** + * Create a recursive group. + * @param index index in the builder to create the group + * @param length number of types in the group + */ + createRecGroup(index: number, length: number): void { + BinaryenObj["_TypeBuilderCreateRecGroup"](this.#ptr, index, length); + } - buildAndDispose() {} + /** + * Resolve any and all recursive types in the TypeBuilder and return their finalized forms. + * @return list of finalized heap types in the builder + */ + buildAndDispose(): HeapType[] { + return preserveStack(() => { + const numTypes = this.getSize(); + const array = stackAlloc(numTypes << 2); + if (!BinaryenObj["_TypeBuilderBuildAndDispose"](this.#ptr, array, 0, 0)) { + throw new TypeError("TypeBuilder.buildAndDispose failed"); + } + const types = new Array(numTypes); + for (let i = 0; i < numTypes; i++) { + types[i] = HEAPU32[(array >>> 2) + i]; + } + return types; + }); + } } diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 931dff24345..1d5176b832b 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -12,6 +12,7 @@ import { // ## Static Types ## // export type Type = number; export type HeapType = number; +export type PackedType = number; export type ElementSegmentRef = number; export type ExpressionRef = number; export type FunctionRef = number; From 0d23b9b556a3c6e32192d4cec08c93839ce847e3 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 17:39:54 -0400 Subject: [PATCH 023/247] refactor: Function instance methods --- ts/src/-pre.ts | 1 + ts/src/class/Function.ts | 89 ++++++++++++++++++++++++++++++++++------ ts/src/lib.ts | 28 +++++++++++++ 3 files changed, 105 insertions(+), 13 deletions(-) create mode 100644 ts/src/lib.ts diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index d844ab51e68..72a156e61ed 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -12,4 +12,5 @@ export declare function stackSave(): unknown; export declare function stackRestore(stack: unknown): unknown; export declare function stackAlloc(length: number): number; export declare function stringToUTF8OnStack(str: string): number; +export declare function UTF8ToString(n: number): string; export declare function getExceptionMessage(e: number | Error): [unknown, string]; diff --git a/ts/src/class/Function.ts b/ts/src/class/Function.ts index 89070f72559..ff481eebf26 100644 --- a/ts/src/class/Function.ts +++ b/ts/src/class/Function.ts @@ -1,26 +1,38 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../-pre.ts"; import type { + ExpressionRef, FunctionRef, + Type, } from "../constants.ts"; +import { + replacedBy, +} from "../lib.ts"; import { THIS_PTR, + preserveStack, + strToStack, } from "../utils.ts"; class BinaryenFunction { - // TODO: static methods are deprecated; convert to instance and log warnings - static getName() {} - static getType() {} - static getParams() {} - static getResults() {} - static getNumVars() {} - static getVar() {} - static getNumLocals() {} - static hasLocalName() {} - static getLocalName() {} - static setLocalName() {} - static getBody() {} - static setBody() {} + /* eslint-disable @stylistic/brace-style */ + @replacedBy("`instance.getName`") static getName(func: FunctionRef) { return BinaryenFunction.prototype.getName.call({[THIS_PTR]: func}); } + @replacedBy("`instance.getType`") static getType(func: FunctionRef) { return BinaryenFunction.prototype.getType.call({[THIS_PTR]: func}); } + @replacedBy("`instance.getParams`") static getParams(func: FunctionRef) { return BinaryenFunction.prototype.getParams.call({[THIS_PTR]: func}); } + @replacedBy("`instance.getResults`") static getResults(func: FunctionRef) { return BinaryenFunction.prototype.getResults.call({[THIS_PTR]: func}); } + @replacedBy("`instance.getNumVars`") static getNumVars(func: FunctionRef) { return BinaryenFunction.prototype.getNumVars.call({[THIS_PTR]: func}); } + @replacedBy("`instance.getVar`") static getVar(func: FunctionRef, index: number) { return BinaryenFunction.prototype.getVar.call({[THIS_PTR]: func}, index); } + @replacedBy("`instance.getNumLocals`") static getNumLocals(func: FunctionRef) { return BinaryenFunction.prototype.getNumLocals.call({[THIS_PTR]: func}); } + @replacedBy("`instance.hasLocalName`") static hasLocalName(func: FunctionRef, index: number) { return BinaryenFunction.prototype.hasLocalName.call({[THIS_PTR]: func}, index); } + @replacedBy("`instance.getLocalName`") static getLocalName(func: FunctionRef, index: number) { return BinaryenFunction.prototype.getLocalName.call({[THIS_PTR]: func}, index); } + @replacedBy("`instance.setLocalName`") static setLocalName(func: FunctionRef, index: number, name: string) { return BinaryenFunction.prototype.setLocalName.call({[THIS_PTR]: func}, index, name); } + @replacedBy("`instance.getBody`") static getBody(func: FunctionRef) { return BinaryenFunction.prototype.getBody.call({[THIS_PTR]: func}); } + @replacedBy("`instance.setBody`") static setBody(func: FunctionRef, bodyExpr: ExpressionRef) { return BinaryenFunction.prototype.setBody.call({[THIS_PTR]: func}, bodyExpr); } + /* eslint-enable @stylistic/brace-style */ private readonly [THIS_PTR]: FunctionRef; @@ -32,5 +44,56 @@ class BinaryenFunction { valueOf() { return this[THIS_PTR]; } + + // TODO: post.js has converted all methods starting with `get` to getters and `set` to setters + getName(): string { + return UTF8ToString(BinaryenObj["_BinaryenFunctionGetName"](this[THIS_PTR])); + } + + getType() { + return BinaryenObj["_BinaryenFunctionGetType"](this[THIS_PTR]); + } + + getParams(): Type { + return BinaryenObj["_BinaryenFunctionGetParams"](this[THIS_PTR]); + } + + getResults(): Type { + return BinaryenObj["_BinaryenFunctionGetResults"](this[THIS_PTR]); + } + + getNumVars(): number { + return BinaryenObj["_BinaryenFunctionGetNumVars"](this[THIS_PTR]); + } + + getVar(index: number): Type { + return BinaryenObj["_BinaryenFunctionGetVar"](this[THIS_PTR], index); + } + + getNumLocals(): number { + return BinaryenObj["_BinaryenFunctionGetNumLocals"](this[THIS_PTR]); + } + + hasLocalName(index: number): boolean { + return Boolean(BinaryenObj["_BinaryenFunctionHasLocalName"](this[THIS_PTR], index)); + } + + getLocalName(index: number): string { + return UTF8ToString(BinaryenObj["_BinaryenFunctionGetLocalName"](this[THIS_PTR], index)); + } + + setLocalName(index: number, name: string): void { + preserveStack(() => { + BinaryenObj["_BinaryenFunctionSetLocalName"](this[THIS_PTR], index, strToStack(name)); + }); + } + + getBody(): ExpressionRef { + return BinaryenObj["_BinaryenFunctionGetBody"](this[THIS_PTR]); + } + + setBody(bodyExpr: ExpressionRef): void { + BinaryenObj["_BinaryenFunctionSetBody"](this[THIS_PTR], bodyExpr); + } } export {BinaryenFunction as Function}; diff --git a/ts/src/lib.ts b/ts/src/lib.ts new file mode 100644 index 00000000000..be7a1a5ebd3 --- /dev/null +++ b/ts/src/lib.ts @@ -0,0 +1,28 @@ +// # Library # // +// Project-agnostic library artifacts for TypeScript development. + + + +/** + * Mark a method as deprecated by logging a warning in the console. + * @example + * class Module { + * \@replacedBy("`this.global.addExport`") + * addGlobalExport(...args) { + * return this.global.addExport(...args); + * } + * } + * + * @param replacement the name or signature of the new method replacing the deprecated one + * @return a method decorator + */ +export function replacedBy(replacement: string = ""): ( + method: (this: This, ...args: Params) => Return, + context: ClassMethodDecoratorContext, +) => (typeof method) | void { + return (method, context) => function (...args) { + const message = `WARNING: ${ context.static ? "Static" : "Instance" } method \`${ String(context.name) }\` is deprecated${ replacement && `; use ${ replacement } instead` }.`; + (console?.warn ?? console?.log)?.(message); + return method.call(this, ...args); + }; +} From 7c0ea86692e7b647fad53d013c0834130d23e6d0 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 18:01:49 -0400 Subject: [PATCH 024/247] refactor: Table instance methods --- ts/src/class/Table.ts | 97 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 10 deletions(-) diff --git a/ts/src/class/Table.ts b/ts/src/class/Table.ts index 1c5d21ad9f4..73576e55dbf 100644 --- a/ts/src/class/Table.ts +++ b/ts/src/class/Table.ts @@ -1,23 +1,34 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../-pre.ts"; import type { TableRef, + Type, } from "../constants.ts"; +import { + replacedBy, +} from "../lib.ts"; import { THIS_PTR, + preserveStack, + strToStack, } from "../utils.ts"; export class Table { - // TODO: static methods are deprecated; convert to instance and log warnings - static getName() {} - static setName() {} - static getInitial() {} - static setInitial() {} - static hasMax() {} - static getMax() {} - static setMax() {} - static getType() {} - static setType() {} + /* eslint-disable @stylistic/brace-style */ + @replacedBy("`instance.getName`") static getName(table: TableRef) { return Table.prototype.getName.call({[THIS_PTR]: table}); } + @replacedBy("`instance.setName`") static setName(table: TableRef, name: string) { return Table.prototype.setName.call({[THIS_PTR]: table}, name); } + @replacedBy("`instance.getInitial`") static getInitial(table: TableRef) { return Table.prototype.getInitial.call({[THIS_PTR]: table}); } + @replacedBy("`instance.setInitial`") static setInitial(table: TableRef, initial: number) { return Table.prototype.setInitial.call({[THIS_PTR]: table}, initial); } + @replacedBy("`instance.hasMax`") static hasMax(table: TableRef) { return Table.prototype.hasMax.call({[THIS_PTR]: table}); } + @replacedBy("`instance.getMax`") static getMax(table: TableRef) { return Table.prototype.getMax.call({[THIS_PTR]: table}); } + @replacedBy("`instance.setMax`") static setMax(table: TableRef, max: number) { return Table.prototype.setMax.call({[THIS_PTR]: table}, max); } + @replacedBy("`instance.getType`") static getType(table: TableRef) { return Table.prototype.getType.call({[THIS_PTR]: table}); } + @replacedBy("`instance.setType`") static setType(table: TableRef, tableType: Type) { return Table.prototype.setType.call({[THIS_PTR]: table}, tableType); } + /* eslint-enable @stylistic/brace-style */ private readonly [THIS_PTR]: TableRef; @@ -29,4 +40,70 @@ export class Table { valueOf() { return this[THIS_PTR]; } + + // TODO: post.js has converted all methods starting with `get` to getters and `set` to setters + /** + * @return the name of this table + */ + getName(): string { + return UTF8ToString(BinaryenObj["_BinaryenTableGetName"](this[THIS_PTR])); + } + + /** + * @param name the new name for the this table + */ + setName(name: string): void { + preserveStack(() => { + BinaryenObj["_BinaryenTableSetName"](this[THIS_PTR], strToStack(name)); + }); + } + + /** + * @return the initial number of pages of the `Table` + */ + getInitial(): number { + return BinaryenObj["_BinaryenTableGetInitial"](this[THIS_PTR]); + } + + /** + * @param initial the new initial number of pages for this table + */ + setInitial(initial: number): void { + BinaryenObj["_BinaryenTableSetInitial"](this[THIS_PTR], initial); + } + + /** + * @return does this table have a maximum number of pages? + */ + hasMax(): boolean { + return Boolean(BinaryenObj["_BinaryenTableHasMax"](this[THIS_PTR])); + } + + /** + * @return the maximum number of pages of this table + */ + getMax(): number { + return BinaryenObj["_BinaryenTableGetMax"](this[THIS_PTR]); + } + + /** + * @param max the maximum number of pages of this table + */ + setMax(max: number): void { + BinaryenObj["_BinaryenTableSetMax"](this[THIS_PTR], max); + } + + /** + * @return the type of this table + */ + getType(): Type { + return BinaryenObj["_BinaryenTableGetType"](this[THIS_PTR]); + } + + /** + * @param tableType the new type for this table + */ + setType(tableType: Type): void { + BinaryenObj["_BinaryenTableSetType"](this[THIS_PTR], tableType); + } } From 63e9f2c0e07d6feecd1e4fefa948dc648cf7af33 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 20:12:06 -0400 Subject: [PATCH 025/247] feat: global functions & Expression methods --- ts/src/-pre.ts | 3 + ts/src/class/Module.ts | 11 +++- ts/src/class/expression/Expression.ts | 44 ++++++++++--- ts/src/global.ts | 90 +++++++++++++++++++++++---- 4 files changed, 127 insertions(+), 21 deletions(-) diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index 72a156e61ed..a866cdf3081 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -8,9 +8,12 @@ export declare const BinaryenObj: Readonly(); /** Base class of all expression wrappers. */ export class Expression { - // TODO: static methods are deprecated; convert to instance and log warnings - static getId(expr: number) { - return BinaryenObj["_BinaryenExpressionGetId"](expr); - } - - static getType() {} - static setType() {} - static finalize() {} - static toText() {} + /* eslint-disable @stylistic/brace-style */ + @replacedBy("`instance.getId`") static getId(expr: ExpressionRef) { return Expression.prototype.getId.call({[THIS_PTR]: expr}); } + @replacedBy("`instance.getType`") static getType(expr: ExpressionRef) { return Expression.prototype.getType.call({[THIS_PTR]: expr}); } + @replacedBy("`instance.setType`") static setType(expr: ExpressionRef, typ: Type) { return Expression.prototype.setType.call({[THIS_PTR]: expr}, typ); } + @replacedBy("`instance.finalize`") static finalize(expr: ExpressionRef) { return Expression.prototype.finalize.call({[THIS_PTR]: expr}); } + @replacedBy("`instance.toText`") static toText(expr: ExpressionRef): string { return Expression.prototype.toText.call({[THIS_PTR]: expr}); } + /* eslint-enable @stylistic/brace-style */ protected readonly [THIS_PTR]: number; @@ -39,4 +44,25 @@ export class Expression { valueOf() { return this[THIS_PTR]; } + + // TODO: post.js has converted all methods starting with `get` to getters and `set` to setters + getId(): ExpressionId { + return BinaryenObj["_BinaryenExpressionGetId"](this[THIS_PTR]); + } + + getType(): Type { + return BinaryenObj["_BinaryenExpressionGetType"](this[THIS_PTR]); + } + + setType(typ: Type): void { + BinaryenObj["_BinaryenExpressionSetType"](this[THIS_PTR], typ); + } + + finalize(): void { + BinaryenObj["_BinaryenExpressionFinalize"](this[THIS_PTR]); + } + + toText(): string { + return emitText(this[THIS_PTR]); + } } diff --git a/ts/src/global.ts b/ts/src/global.ts index 30c02d3069b..606c76ba03b 100644 --- a/ts/src/global.ts +++ b/ts/src/global.ts @@ -4,15 +4,30 @@ import { + _free, + _malloc, BinaryenObj, getExceptionMessage, stackAlloc, + stringToAscii, } from "./-pre.ts"; +import { + Feature, + Module, +} from "./class/Module.ts"; +import { + EXPR_WRAPPERS, + Expression, +} from "./class/expression/Expression.ts"; import type { + ExpressionId, + ExpressionRef, HeapType, + SideEffect, Type, } from "./constants.ts"; import { + HEAP8, HEAPU32, i32sToStack, preserveStack, @@ -20,6 +35,17 @@ import { +/** + * Private utility to create a Module from a given pointer. + * Users don’t have access to this. + */ +function wrapModule(ptr: number): Module { + const returned = new Module(); + // @ts-expect-error -- warning: reassigning a readonly field + returned.ptr = ptr; + return returned; +} + /** * Calls a function, wrapping it in error handling code so that if it hits a * fatal error, we throw a JS exception (which JS can handle) rather than @@ -27,8 +53,7 @@ import { * @param func the function to call * @return the return value of the given function */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -function handleFatalError(func: () => number): number { +function handleFatalError(func: () => T): T { try { return func(); } catch (e) { @@ -60,15 +85,49 @@ function handleFatalError(func: () => number): number { // ## General Binaryen Functions ## // -export function emitText() {}; +/** Probably used in `BinaryenObj["_BinaryenExpressionPrint"]`. */ +declare let out: any; +export function emitText(expr: ExpressionRef): string { + let returned = ""; + const saved = out; + out = (x: string) => { + returned += `${ x }\n`; + }; + BinaryenObj["_BinaryenExpressionPrint"](expr); + out = saved; + return returned; +} -export function readBinary() {}; +export function readBinary(data: Uint8Array): Module { + const buffer = _malloc(data.length); + HEAP8.set(data, buffer); + const ptr = handleFatalError(() => BinaryenObj["_BinaryenModuleRead"](buffer, data.length)); + _free(buffer); + return wrapModule(ptr); +} -export function readBinaryWithFeatures() {}; +export function readBinaryWithFeatures(data: Uint8Array, features: Feature) { + const buffer = _malloc(data.length); + HEAP8.set(data, buffer); + const ptr = handleFatalError(() => BinaryenObj["_BinaryenModuleReadWithFeatures"](buffer, data.length, features)); + _free(buffer); + return wrapModule(ptr); +} -export function parseText() {}; +export function parseText(text: string): Module { + const buffer = _malloc(text.length + 1); + stringToAscii(text, buffer); + const ptr = handleFatalError(() => BinaryenObj["_BinaryenModuleParse"](buffer)); + _free(buffer); + return wrapModule(ptr); +} -export function exit() {}; +export function exit(status: number): void { + // Instead of exiting silently on errors, always show an error with a stack trace, for debuggability. + if (status !== 0) { + throw new Error(`exiting due to error: ${ status }`); + } +} @@ -119,13 +178,22 @@ export function getHeapType(typ: Type): HeapType { return BinaryenObj["_BinaryenTypeGetHeapType"](typ); } -export function getExpressionId() {} +export function getExpressionId(expr: ExpressionRef): ExpressionId { + return BinaryenObj["_BinaryenExpressionGetId"](expr); +} -export function getExpressionType() {} +export function getExpressionType(expr: ExpressionRef): Type { + return BinaryenObj["_BinaryenExpressionGetType"](expr); +} -export function getExpressionInfo() {} +export function getExpressionInfo(expr: ExpressionRef): Expression { + const id = getExpressionId(expr); + return EXPR_WRAPPERS.get(id) ?? new Expression(id, expr); +} -export function getSideEffects() {} +export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { + return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, mod.ptr); +} From c8ada29804eca76c37341ce1f76f373124e5185e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 20:36:42 -0400 Subject: [PATCH 026/247] fix: expression ids --- ts/src/class/expression/Expression.ts | 25 ++++++++++++++++--------- ts/src/constants.ts | 1 + ts/src/global.ts | 7 ++++--- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/ts/src/class/expression/Expression.ts b/ts/src/class/expression/Expression.ts index a1e964ca78b..31f127daf34 100644 --- a/ts/src/class/expression/Expression.ts +++ b/ts/src/class/expression/Expression.ts @@ -8,6 +8,7 @@ import type { } from "../../constants.ts"; import { emitText, + getExpressionType, } from "../../global.ts"; import { replacedBy, @@ -18,11 +19,6 @@ import { -/** Expression ID-to-wrapper map. */ -export const EXPR_WRAPPERS = new Map(); - - - /** Base class of all expression wrappers. */ export class Expression { /* eslint-disable @stylistic/brace-style */ @@ -34,11 +30,22 @@ export class Expression { /* eslint-enable @stylistic/brace-style */ - protected readonly [THIS_PTR]: number; + protected readonly [THIS_PTR]: ExpressionRef; + + /** Not really an “ID”, just the “kind” of expression. */ + readonly #id: ExpressionId; + /** + * Construct a new Expression object given an ID and reference. + * + * Without an ID, you can still call `binaryen.getExpressionInfo(expr)`, + * which will compute the ID and construct an Expression object from there. + * @param exprId the expression “kind” id + * @param expr the expression reference + */ constructor(exprId: ExpressionId, expr: ExpressionRef) { this[THIS_PTR] = expr; - EXPR_WRAPPERS.set(exprId, this); + this.#id = exprId; } valueOf() { @@ -47,11 +54,11 @@ export class Expression { // TODO: post.js has converted all methods starting with `get` to getters and `set` to setters getId(): ExpressionId { - return BinaryenObj["_BinaryenExpressionGetId"](this[THIS_PTR]); + return this.#id; } getType(): Type { - return BinaryenObj["_BinaryenExpressionGetType"](this[THIS_PTR]); + return getExpressionType(this[THIS_PTR]); } setType(typ: Type): void { diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 1d5176b832b..33e41272f69 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -84,6 +84,7 @@ export const stringref: Type = BinaryenObj["_BinaryenTypeStringref"](); // ## Instructions ## // // see https://webassembly.github.io/spec/core/syntax/instructions.html +/** An enumeration of all the “kinds” of expressions. */ export enum ExpressionId { // ### Binaryen-Only Instruction Ids ### // Invalid = BinaryenObj["_BinaryenInvalidId"](), diff --git a/ts/src/global.ts b/ts/src/global.ts index 606c76ba03b..3daf8f4bae6 100644 --- a/ts/src/global.ts +++ b/ts/src/global.ts @@ -16,7 +16,6 @@ import { Module, } from "./class/Module.ts"; import { - EXPR_WRAPPERS, Expression, } from "./class/expression/Expression.ts"; import type { @@ -178,6 +177,9 @@ export function getHeapType(typ: Type): HeapType { return BinaryenObj["_BinaryenTypeGetHeapType"](typ); } +/** + * A misnomer — returns not a unique “ID”, but the “kind” of the expression. + */ export function getExpressionId(expr: ExpressionRef): ExpressionId { return BinaryenObj["_BinaryenExpressionGetId"](expr); } @@ -187,8 +189,7 @@ export function getExpressionType(expr: ExpressionRef): Type { } export function getExpressionInfo(expr: ExpressionRef): Expression { - const id = getExpressionId(expr); - return EXPR_WRAPPERS.get(id) ?? new Expression(id, expr); + return new Expression(getExpressionId(expr), expr); } export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { From 93eabda97308ebc5ca6faa08d63b7703362475c4 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 20:44:45 -0400 Subject: [PATCH 027/247] docs: add deprecation comments --- ts/eslint.config.js | 1 + ts/src/class/Function.ts | 24 ++++++++++++------------ ts/src/class/Table.ts | 18 +++++++++--------- ts/src/class/expression/Expression.ts | 10 +++++----- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/ts/eslint.config.js b/ts/eslint.config.js index 14dea8f6482..90430e49af5 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -155,6 +155,7 @@ export default [ /* ## Strictness */ "@typescript-eslint/explicit-member-accessibility": ["error", {accessibility: "no-public"}], + "@typescript-eslint/no-deprecated": "warn", }, }, ]; diff --git a/ts/src/class/Function.ts b/ts/src/class/Function.ts index ff481eebf26..895ebcb2014 100644 --- a/ts/src/class/Function.ts +++ b/ts/src/class/Function.ts @@ -20,18 +20,18 @@ import { class BinaryenFunction { /* eslint-disable @stylistic/brace-style */ - @replacedBy("`instance.getName`") static getName(func: FunctionRef) { return BinaryenFunction.prototype.getName.call({[THIS_PTR]: func}); } - @replacedBy("`instance.getType`") static getType(func: FunctionRef) { return BinaryenFunction.prototype.getType.call({[THIS_PTR]: func}); } - @replacedBy("`instance.getParams`") static getParams(func: FunctionRef) { return BinaryenFunction.prototype.getParams.call({[THIS_PTR]: func}); } - @replacedBy("`instance.getResults`") static getResults(func: FunctionRef) { return BinaryenFunction.prototype.getResults.call({[THIS_PTR]: func}); } - @replacedBy("`instance.getNumVars`") static getNumVars(func: FunctionRef) { return BinaryenFunction.prototype.getNumVars.call({[THIS_PTR]: func}); } - @replacedBy("`instance.getVar`") static getVar(func: FunctionRef, index: number) { return BinaryenFunction.prototype.getVar.call({[THIS_PTR]: func}, index); } - @replacedBy("`instance.getNumLocals`") static getNumLocals(func: FunctionRef) { return BinaryenFunction.prototype.getNumLocals.call({[THIS_PTR]: func}); } - @replacedBy("`instance.hasLocalName`") static hasLocalName(func: FunctionRef, index: number) { return BinaryenFunction.prototype.hasLocalName.call({[THIS_PTR]: func}, index); } - @replacedBy("`instance.getLocalName`") static getLocalName(func: FunctionRef, index: number) { return BinaryenFunction.prototype.getLocalName.call({[THIS_PTR]: func}, index); } - @replacedBy("`instance.setLocalName`") static setLocalName(func: FunctionRef, index: number, name: string) { return BinaryenFunction.prototype.setLocalName.call({[THIS_PTR]: func}, index, name); } - @replacedBy("`instance.getBody`") static getBody(func: FunctionRef) { return BinaryenFunction.prototype.getBody.call({[THIS_PTR]: func}); } - @replacedBy("`instance.setBody`") static setBody(func: FunctionRef, bodyExpr: ExpressionRef) { return BinaryenFunction.prototype.setBody.call({[THIS_PTR]: func}, bodyExpr); } + /** @deprecated */ @replacedBy("`instance.getName`") static getName(func: FunctionRef) { return BinaryenFunction.prototype.getName.call({[THIS_PTR]: func}); } + /** @deprecated */ @replacedBy("`instance.getType`") static getType(func: FunctionRef) { return BinaryenFunction.prototype.getType.call({[THIS_PTR]: func}); } + /** @deprecated */ @replacedBy("`instance.getParams`") static getParams(func: FunctionRef) { return BinaryenFunction.prototype.getParams.call({[THIS_PTR]: func}); } + /** @deprecated */ @replacedBy("`instance.getResults`") static getResults(func: FunctionRef) { return BinaryenFunction.prototype.getResults.call({[THIS_PTR]: func}); } + /** @deprecated */ @replacedBy("`instance.getNumVars`") static getNumVars(func: FunctionRef) { return BinaryenFunction.prototype.getNumVars.call({[THIS_PTR]: func}); } + /** @deprecated */ @replacedBy("`instance.getVar`") static getVar(func: FunctionRef, index: number) { return BinaryenFunction.prototype.getVar.call({[THIS_PTR]: func}, index); } + /** @deprecated */ @replacedBy("`instance.getNumLocals`") static getNumLocals(func: FunctionRef) { return BinaryenFunction.prototype.getNumLocals.call({[THIS_PTR]: func}); } + /** @deprecated */ @replacedBy("`instance.hasLocalName`") static hasLocalName(func: FunctionRef, index: number) { return BinaryenFunction.prototype.hasLocalName.call({[THIS_PTR]: func}, index); } + /** @deprecated */ @replacedBy("`instance.getLocalName`") static getLocalName(func: FunctionRef, index: number) { return BinaryenFunction.prototype.getLocalName.call({[THIS_PTR]: func}, index); } + /** @deprecated */ @replacedBy("`instance.setLocalName`") static setLocalName(func: FunctionRef, index: number, name: string) { return BinaryenFunction.prototype.setLocalName.call({[THIS_PTR]: func}, index, name); } + /** @deprecated */ @replacedBy("`instance.getBody`") static getBody(func: FunctionRef) { return BinaryenFunction.prototype.getBody.call({[THIS_PTR]: func}); } + /** @deprecated */ @replacedBy("`instance.setBody`") static setBody(func: FunctionRef, bodyExpr: ExpressionRef) { return BinaryenFunction.prototype.setBody.call({[THIS_PTR]: func}, bodyExpr); } /* eslint-enable @stylistic/brace-style */ diff --git a/ts/src/class/Table.ts b/ts/src/class/Table.ts index 73576e55dbf..1b83ed069db 100644 --- a/ts/src/class/Table.ts +++ b/ts/src/class/Table.ts @@ -19,15 +19,15 @@ import { export class Table { /* eslint-disable @stylistic/brace-style */ - @replacedBy("`instance.getName`") static getName(table: TableRef) { return Table.prototype.getName.call({[THIS_PTR]: table}); } - @replacedBy("`instance.setName`") static setName(table: TableRef, name: string) { return Table.prototype.setName.call({[THIS_PTR]: table}, name); } - @replacedBy("`instance.getInitial`") static getInitial(table: TableRef) { return Table.prototype.getInitial.call({[THIS_PTR]: table}); } - @replacedBy("`instance.setInitial`") static setInitial(table: TableRef, initial: number) { return Table.prototype.setInitial.call({[THIS_PTR]: table}, initial); } - @replacedBy("`instance.hasMax`") static hasMax(table: TableRef) { return Table.prototype.hasMax.call({[THIS_PTR]: table}); } - @replacedBy("`instance.getMax`") static getMax(table: TableRef) { return Table.prototype.getMax.call({[THIS_PTR]: table}); } - @replacedBy("`instance.setMax`") static setMax(table: TableRef, max: number) { return Table.prototype.setMax.call({[THIS_PTR]: table}, max); } - @replacedBy("`instance.getType`") static getType(table: TableRef) { return Table.prototype.getType.call({[THIS_PTR]: table}); } - @replacedBy("`instance.setType`") static setType(table: TableRef, tableType: Type) { return Table.prototype.setType.call({[THIS_PTR]: table}, tableType); } + /** @deprecated */ @replacedBy("`instance.getName`") static getName(table: TableRef) { return Table.prototype.getName.call({[THIS_PTR]: table}); } + /** @deprecated */ @replacedBy("`instance.setName`") static setName(table: TableRef, name: string) { return Table.prototype.setName.call({[THIS_PTR]: table}, name); } + /** @deprecated */ @replacedBy("`instance.getInitial`") static getInitial(table: TableRef) { return Table.prototype.getInitial.call({[THIS_PTR]: table}); } + /** @deprecated */ @replacedBy("`instance.setInitial`") static setInitial(table: TableRef, initial: number) { return Table.prototype.setInitial.call({[THIS_PTR]: table}, initial); } + /** @deprecated */ @replacedBy("`instance.hasMax`") static hasMax(table: TableRef) { return Table.prototype.hasMax.call({[THIS_PTR]: table}); } + /** @deprecated */ @replacedBy("`instance.getMax`") static getMax(table: TableRef) { return Table.prototype.getMax.call({[THIS_PTR]: table}); } + /** @deprecated */ @replacedBy("`instance.setMax`") static setMax(table: TableRef, max: number) { return Table.prototype.setMax.call({[THIS_PTR]: table}, max); } + /** @deprecated */ @replacedBy("`instance.getType`") static getType(table: TableRef) { return Table.prototype.getType.call({[THIS_PTR]: table}); } + /** @deprecated */ @replacedBy("`instance.setType`") static setType(table: TableRef, tableType: Type) { return Table.prototype.setType.call({[THIS_PTR]: table}, tableType); } /* eslint-enable @stylistic/brace-style */ diff --git a/ts/src/class/expression/Expression.ts b/ts/src/class/expression/Expression.ts index 31f127daf34..d10396b9505 100644 --- a/ts/src/class/expression/Expression.ts +++ b/ts/src/class/expression/Expression.ts @@ -22,11 +22,11 @@ import { /** Base class of all expression wrappers. */ export class Expression { /* eslint-disable @stylistic/brace-style */ - @replacedBy("`instance.getId`") static getId(expr: ExpressionRef) { return Expression.prototype.getId.call({[THIS_PTR]: expr}); } - @replacedBy("`instance.getType`") static getType(expr: ExpressionRef) { return Expression.prototype.getType.call({[THIS_PTR]: expr}); } - @replacedBy("`instance.setType`") static setType(expr: ExpressionRef, typ: Type) { return Expression.prototype.setType.call({[THIS_PTR]: expr}, typ); } - @replacedBy("`instance.finalize`") static finalize(expr: ExpressionRef) { return Expression.prototype.finalize.call({[THIS_PTR]: expr}); } - @replacedBy("`instance.toText`") static toText(expr: ExpressionRef): string { return Expression.prototype.toText.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.getId`") static getId(expr: ExpressionRef) { return Expression.prototype.getId.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.getType`") static getType(expr: ExpressionRef) { return Expression.prototype.getType.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.setType`") static setType(expr: ExpressionRef, typ: Type) { return Expression.prototype.setType.call({[THIS_PTR]: expr}, typ); } + /** @deprecated */ @replacedBy("`instance.finalize`") static finalize(expr: ExpressionRef) { return Expression.prototype.finalize.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.toText`") static toText(expr: ExpressionRef): string { return Expression.prototype.toText.call({[THIS_PTR]: expr}); } /* eslint-enable @stylistic/brace-style */ From acb5fce523e0aa92bbb0364d76356441f81eeec1 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 21:37:21 -0400 Subject: [PATCH 028/247] feat: add Const class --- ts/src/class/expression/Const.ts | 112 +++++++++++++++++++++++++++++++ ts/src/class/expression/index.ts | 6 ++ 2 files changed, 118 insertions(+) create mode 100644 ts/src/class/expression/Const.ts diff --git a/ts/src/class/expression/Const.ts b/ts/src/class/expression/Const.ts new file mode 100644 index 00000000000..feec49dc8d4 --- /dev/null +++ b/ts/src/class/expression/Const.ts @@ -0,0 +1,112 @@ +import { + BinaryenObj, + stackAlloc, +} from "../../-pre.ts"; +import { + ExpressionId, + type ExpressionRef, + i32, + i64, + f32, + f64, + v128, +} from "../../constants.ts"; +import { + replacedBy, +} from "../../lib.ts"; +import { + HEAPU8, + THIS_PTR, + preserveStack, +} from "../../utils.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Const extends Expression { + /* eslint-disable @stylistic/brace-style */ + /** @deprecated */ @replacedBy("`instance.getValueI32`") static getValueI32(expr: ExpressionRef) { return Const.prototype.getValueI32.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.setValueI32`") static setValueI32(expr: ExpressionRef, value: number) { return Const.prototype.setValueI32.call({[THIS_PTR]: expr}, value); } + /** @deprecated */ @replacedBy("`instance.getValueI64`") static getValueI64(expr: ExpressionRef) { return Const.prototype.getValueI64.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.setValueI64`") static setValueI64(expr: ExpressionRef, value: number) { return Const.prototype.setValueI64.call({[THIS_PTR]: expr}, value); } + /** @deprecated */ @replacedBy("`instance.getValueF32`") static getValueF32(expr: ExpressionRef) { return Const.prototype.getValueF32.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.setValueF32`") static setValueF32(expr: ExpressionRef, value: number) { return Const.prototype.setValueF32.call({[THIS_PTR]: expr}, value); } + /** @deprecated */ @replacedBy("`instance.getValueF64`") static getValueF64(expr: ExpressionRef) { return Const.prototype.getValueF64.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.setValueF64`") static setValueF64(expr: ExpressionRef, value: number) { return Const.prototype.setValueF64.call({[THIS_PTR]: expr}, value); } + /** @deprecated */ @replacedBy("`instance.getValueV128`") static getValueV128(expr: ExpressionRef) { return Const.prototype.getValueV128.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.setValueV128`") static setValueV128(expr: ExpressionRef, value: readonly number[]) { return Const.prototype.setValueV128.call({[THIS_PTR]: expr}, value); } + /* eslint-enable @stylistic/brace-style */ + + + constructor(expr: ExpressionRef) { + super(ExpressionId.Const, expr); + } + + get value(): number | number[] { + const this_type = this.getType(); + switch (this.getType()) { + case i32: { return this.getValueI32(); } + case i64: { return this.getValueI64(); } + case f32: { return this.getValueF32(); } + case f64: { return this.getValueF64(); } + case v128: { return this.getValueV128(); } + } + throw new Error(`Unexpected type: ${ this_type }.`); + } + + getValueI32(): number { + return BinaryenObj["_BinaryenConstGetValueI32"](this[THIS_PTR]); + } + + setValueI32(value: number): void { + BinaryenObj["_BinaryenConstSetValueI32"](this[THIS_PTR], value); + } + + getValueI64(): number { + return BinaryenObj["_BinaryenConstGetValueI64"](this[THIS_PTR]); + } + + setValueI64(value: number): void { + BinaryenObj["_BinaryenConstSetValueI64"](this[THIS_PTR], BigInt(value)); + } + + getValueF32(): number { + return BinaryenObj["_BinaryenConstGetValueF32"](this[THIS_PTR]); + } + + setValueF32(value: number): void { + BinaryenObj["_BinaryenConstSetValueF32"](this[THIS_PTR], value); + } + + getValueF64(): number { + return BinaryenObj["_BinaryenConstGetValueF64"](this[THIS_PTR]); + } + + setValueF64(value: number): void { + BinaryenObj["_BinaryenConstSetValueF64"](this[THIS_PTR], value); + } + + getValueV128(): number[] { + const value: number[] = []; + preserveStack(() => { + const tempBuffer = stackAlloc(16); + BinaryenObj["_BinaryenConstGetValueV128"](this[THIS_PTR], tempBuffer); + for (let i = 0; i < 16; ++i) { + value[i] = HEAPU8[tempBuffer + i]; + } + }); + return value; + } + + setValueV128(value: readonly number[]): void { + preserveStack(() => { + const tempBuffer = stackAlloc(16); + for (let i = 0; i < 16; ++i) { + HEAPU8[tempBuffer + i] = value[i]; + } + BinaryenObj["_BinaryenConstSetValueV128"](this[THIS_PTR], tempBuffer); + }); + } +} diff --git a/ts/src/class/expression/index.ts b/ts/src/class/expression/index.ts index bab69332479..1b6bc7fedc3 100644 --- a/ts/src/class/expression/index.ts +++ b/ts/src/class/expression/index.ts @@ -1,3 +1,9 @@ +// ## Control ## // export {Block} from "./Block.ts"; + +// ## Variable ## // export {LocalGet} from "./LocalGet.ts"; export {LocalSet} from "./LocalSet.ts"; + +// ## Numeric & Vector ## // +export {Const} from "./Const.ts"; From 201a450d99776695488d7ca98da6cfa5d97e22f0 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 21:37:43 -0400 Subject: [PATCH 029/247] lint: consistent types --- ts/eslint.config.js | 1 + ts/src/-pre.ts | 2 +- ts/src/global.ts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ts/eslint.config.js b/ts/eslint.config.js index 90430e49af5..b8995c9453f 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -149,6 +149,7 @@ export default [ "@typescript-eslint/no-use-before-define": "error", /* ## Function & Module Design */ + "@typescript-eslint/consistent-type-imports": "error", "default-param-last": "off", "@typescript-eslint/default-param-last": "error", "@typescript-eslint/no-import-type-side-effects": "error", diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index a866cdf3081..3a72c8d8b26 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -4,7 +4,7 @@ /** The main object provided by Emscripten. This is what gets wrapped. */ -export declare const BinaryenObj: Readonly number>>; +export declare const BinaryenObj: Readonly number>>; diff --git a/ts/src/global.ts b/ts/src/global.ts index 3daf8f4bae6..1eddb535382 100644 --- a/ts/src/global.ts +++ b/ts/src/global.ts @@ -12,7 +12,7 @@ import { stringToAscii, } from "./-pre.ts"; import { - Feature, + type Feature, Module, } from "./class/Module.ts"; import { From e8e0289560c6ba372a4211ce208313f624d299d0 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 22:08:04 -0400 Subject: [PATCH 030/247] feat: global setting functions --- ts/src/global.ts | 234 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 182 insertions(+), 52 deletions(-) diff --git a/ts/src/global.ts b/ts/src/global.ts index 1eddb535382..6198a6d3086 100644 --- a/ts/src/global.ts +++ b/ts/src/global.ts @@ -7,6 +7,7 @@ import { _free, _malloc, BinaryenObj, + UTF8ToString, getExceptionMessage, stackAlloc, stringToAscii, @@ -30,6 +31,7 @@ import { HEAPU32, i32sToStack, preserveStack, + strToStack, } from "./utils.ts"; @@ -198,71 +200,199 @@ export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { -// ## Global Getters & Setters ## // -export function getOptimizeLevel() {}; +// ## Getters & Setters for Settings ## // +// TODO: These should all be moved to a `Settings` class with getter and setter methods. +/** Gets the currently set optimize level. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ +export function getOptimizeLevel(): number { + return BinaryenObj["_BinaryenGetOptimizeLevel"](); +}; -export function setOptimizeLevel() {}; +/** Sets the optimization level to use. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ +export function setOptimizeLevel(level: number): void { + BinaryenObj["_BinaryenSetOptimizeLevel"](level); +}; -export function getShrinkLevel() {}; +/** Gets the currently set shrink level. 0, 1, 2 correspond to -O0, -Os, -Oz. */ +export function getShrinkLevel(): number { + return BinaryenObj["_BinaryenGetShrinkLevel"](); +}; -export function setShrinkLevel() {}; +/** Sets the shrink level to use. 0, 1, 2 correspond to -O0, -Os, -Oz. */ +export function setShrinkLevel(level: number): void { + BinaryenObj["_BinaryenSetShrinkLevel"](level); +}; -export function getDebugInfo() {}; +/** Gets whether generating debug information is currently enabled or not. */ +export function getDebugInfo(): boolean { + return Boolean(BinaryenObj["_BinaryenGetDebugInfo"]()); +}; -export function setDebugInfo() {}; +/** Enables or disables debug information in emitted binaries. */ +export function setDebugInfo(on: boolean) { + BinaryenObj["_BinaryenSetDebugInfo"](on); +}; -export function getTrapsNeverHappen() {}; +/** Gets whether no traps can be considered reached at runtime when optimizing. */ +export function getTrapsNeverHappen(): boolean { + return Boolean(BinaryenObj["_BinaryenGetTrapsNeverHappen"]()); +}; -export function setTrapsNeverHappen() {}; +/** Enables or disables whether no traps can be considered reached at runtime when optimizing. */ +export function setTrapsNeverHappen(on: boolean) { + BinaryenObj["_BinaryenSetTrapsNeverHappen"](on); +}; -export function getClosedWorld() {}; - -export function setClosedWorld() {}; - -export function getLowMemoryUnused() {}; - -export function setLowMemoryUnused() {}; - -export function getZeroFilledMemory() {}; - -export function setZeroFilledMemory() {}; - -export function getFastMath() {}; - -export function setFastMath() {}; - -export function getGenerateStackIR() {}; - -export function setGenerateStackIR() {}; - -export function getOptimizeStackIR() {}; - -export function setOptimizeStackIR() {}; - -export function getPassArgument() {}; - -export function setPassArgument() {}; - -export function clearPassArguments() {}; - -export function hasPassToSkip() {}; - -export function addPassToSkip() {}; - -export function clearPassesToSkip() {}; +/** + * Gets whether considering that the code outside of the module does + * not inspect or interact with GC and function references. + */ +export function getClosedWorld(): boolean { + return Boolean(BinaryenObj["_BinaryenGetClosedWorld"]()); +}; -export function getAlwaysInlineMaxSize() {}; +/** + * Enables or disables whether considering that the code outside of + * the module does not inspect or interact with GC and function references. + */ +export function setClosedWorld(on: boolean) { + BinaryenObj["_BinaryenSetClosedWorld"](on); +}; + +/** Gets whether the low 1K of memory can be considered unused when optimizing. */ +export function getLowMemoryUnused(): boolean { + return Boolean(BinaryenObj["_BinaryenGetLowMemoryUnused"]()); +}; + +/** Enables or disables whether the low 1K of memory can be considered unused when optimizing. */ +export function setLowMemoryUnused(on: boolean) { + BinaryenObj["_BinaryenSetLowMemoryUnused"](on); +}; + +/** Gets whether that an imported memory will be zero-initialized speculation. */ +export function getZeroFilledMemory(): boolean { + return Boolean(BinaryenObj["_BinaryenGetZeroFilledMemory"]()); +}; + +/** Enables or disables whether that an imported memory will be zero-initialized speculation. */ +export function setZeroFilledMemory(on: boolean) { + BinaryenObj["_BinaryenSetZeroFilledMemory"](on); +}; -export function setAlwaysInlineMaxSize() {}; +/** + * Gets whether fast math optimizations are enabled, ignoring for example + * corner cases of floating-point math like NaN changes. + */ +export function getFastMath(): boolean { + return Boolean(BinaryenObj["_BinaryenGetFastMath"]()); +}; -export function getFlexibleInlineMaxSize() {}; +/** + * Enables or disables fast math optimizations, ignoring for example + * corner cases of floating-point math like NaN changes. + */ +export function setFastMath(on: boolean) { + BinaryenObj["_BinaryenSetFastMath"](on); +}; + +/** Gets whether to generate StackIR during binary writing. */ +export function getGenerateStackIR(): boolean { + return Boolean(BinaryenObj["_BinaryenGetGenerateStackIR"]()); +}; + +/** Enable or disable StackIR generation during binary writing. */ +export function setGenerateStackIR(on: boolean) { + BinaryenObj["_BinaryenSetGenerateStackIR"](on); +}; + +/** Gets whether to optimize StackIR during binary writing. */ +export function getOptimizeStackIR(): boolean { + return Boolean(BinaryenObj["_BinaryenGetOptimizeStackIR"]()); +}; + +/** Enable or disable StackIR optimisation during binary writing. */ +export function setOptimizeStackIR(on: boolean) { + BinaryenObj["_BinaryenSetOptimizeStackIR"](on); +}; + +/** Gets the function size at which we always inline. */ +export function getAlwaysInlineMaxSize(): number { + return BinaryenObj["_BinaryenGetAlwaysInlineMaxSize"](); +}; + +/** Sets the function size at which we always inline. */ +export function setAlwaysInlineMaxSize(size: number) { + BinaryenObj["_BinaryenSetAlwaysInlineMaxSize"](size); +}; + +/** Gets the function size which we inline when functions are lightweight. */ +export function getFlexibleInlineMaxSize(): number { + return BinaryenObj["_BinaryenGetFlexibleInlineMaxSize"](); +}; + +/** Sets the function size which we inline when functions are lightweight. */ +export function setFlexibleInlineMaxSize(size: number) { + BinaryenObj["_BinaryenSetFlexibleInlineMaxSize"](size); +}; + +/** Gets the function size which we inline when there is only one caller. */ +export function getOneCallerInlineMaxSize(): number { + return BinaryenObj["_BinaryenGetOneCallerInlineMaxSize"](); +}; + +/** Sets the function size which we inline when there is only one caller. */ +export function setOneCallerInlineMaxSize(size: number) { + BinaryenObj["_BinaryenSetOneCallerInlineMaxSize"](size); +}; + +/** Gets whether functions with loops are allowed to be inlined. */ +export function getAllowInliningFunctionsWithLoops(): boolean { + return Boolean(BinaryenObj["_BinaryenGetAllowInliningFunctionsWithLoops"]()); +}; + +/** Sets whether functions with loops are allowed to be inlined. */ +export function setAllowInliningFunctionsWithLoops(on: boolean) { + BinaryenObj["_BinaryenSetAllowInliningFunctionsWithLoops"](on); +}; + + + +// ## Pass Settings ## // +/** Gets the value of the specified arbitrary pass argument. */ +export function getPassArgument(key: string): string | undefined { + return preserveStack(() => { + const returned = BinaryenObj["_BinaryenGetPassArgument"](strToStack(key)); + return returned ? UTF8ToString(returned) : undefined; + }); +}; -export function setFlexibleInlineMaxSize() {}; +/** + * Sets the value of the specified arbitrary pass argument. + * Removes the respective argument if `value` is NULL. + */ +export function setPassArgument(key: string, value: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenSetPassArgument"](strToStack(key), strToStack(value)); + }); +}; -export function getOneCallerInlineMaxSize() {}; +/** Clears all arbitrary pass arguments. */ +export function clearPassArguments(): void { + BinaryenObj["_BinaryenClearPassArguments"](); +}; -export function setOneCallerInlineMaxSize() {}; +/** Gets whether a pass is in the set of passes to skip. */ +export function hasPassToSkip(pass: string): boolean { + return preserveStack(() => Boolean(BinaryenObj["_BinaryenHasPassToSkip"](strToStack(pass)))); +}; -export function getAllowInliningFunctionsWithLoops() {}; +/** Add a pass to the set of passes to skip. */ +export function addPassToSkip(pass: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddPassToSkip"](strToStack(pass)); + }); +}; -export function setAllowInliningFunctionsWithLoops() {}; +/** Clears the set of passes to skip. */ +export function clearPassesToSkip(): void { + BinaryenObj["_BinaryenClearPassesToSkip"](); +}; From f62c2064a38678167b0f8dea99aa29e8afd20415 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 29 Apr 2026 22:25:22 -0400 Subject: [PATCH 031/247] style: order Operation enum membes: signed before unsigned --- ts/src/constants.ts | 154 ++++++++++++++++++++++---------------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 33e41272f69..a1d06f28976 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -211,12 +211,12 @@ export enum Operation { Load16LaneVec128 = BinaryenObj["_BinaryenLoad16LaneVec128"](), Load32LaneVec128 = BinaryenObj["_BinaryenLoad32LaneVec128"](), Load64LaneVec128 = BinaryenObj["_BinaryenLoad64LaneVec128"](), - Load8x8UVec128 = BinaryenObj["_BinaryenLoad8x8UVec128"](), Load8x8SVec128 = BinaryenObj["_BinaryenLoad8x8SVec128"](), - Load16x4UVec128 = BinaryenObj["_BinaryenLoad16x4UVec128"](), + Load8x8UVec128 = BinaryenObj["_BinaryenLoad8x8UVec128"](), Load16x4SVec128 = BinaryenObj["_BinaryenLoad16x4SVec128"](), - Load32x2UVec128 = BinaryenObj["_BinaryenLoad32x2UVec128"](), + Load16x4UVec128 = BinaryenObj["_BinaryenLoad16x4UVec128"](), Load32x2SVec128 = BinaryenObj["_BinaryenLoad32x2SVec128"](), + Load32x2UVec128 = BinaryenObj["_BinaryenLoad32x2UVec128"](), Load8SplatVec128 = BinaryenObj["_BinaryenLoad8SplatVec128"](), Load16SplatVec128 = BinaryenObj["_BinaryenLoad16SplatVec128"](), Load32SplatVec128 = BinaryenObj["_BinaryenLoad32SplatVec128"](), @@ -242,14 +242,14 @@ export enum Operation { SubInt64 = BinaryenObj["_BinaryenSubInt64"](), MulInt32 = BinaryenObj["_BinaryenMulInt32"](), MulInt64 = BinaryenObj["_BinaryenMulInt64"](), - DivUInt32 = BinaryenObj["_BinaryenDivUInt32"](), - DivUInt64 = BinaryenObj["_BinaryenDivUInt64"](), DivSInt32 = BinaryenObj["_BinaryenDivSInt32"](), DivSInt64 = BinaryenObj["_BinaryenDivSInt64"](), - RemUInt32 = BinaryenObj["_BinaryenRemUInt32"](), - RemUInt64 = BinaryenObj["_BinaryenRemUInt64"](), + DivUInt32 = BinaryenObj["_BinaryenDivUInt32"](), + DivUInt64 = BinaryenObj["_BinaryenDivUInt64"](), RemSInt32 = BinaryenObj["_BinaryenRemSInt32"](), RemSInt64 = BinaryenObj["_BinaryenRemSInt64"](), + RemUInt32 = BinaryenObj["_BinaryenRemUInt32"](), + RemUInt64 = BinaryenObj["_BinaryenRemUInt64"](), AndInt32 = BinaryenObj["_BinaryenAndInt32"](), AndInt64 = BinaryenObj["_BinaryenAndInt64"](), OrInt32 = BinaryenObj["_BinaryenOrInt32"](), @@ -258,10 +258,10 @@ export enum Operation { XorInt64 = BinaryenObj["_BinaryenXorInt64"](), ShlInt32 = BinaryenObj["_BinaryenShlInt32"](), ShlInt64 = BinaryenObj["_BinaryenShlInt64"](), - ShrUInt32 = BinaryenObj["_BinaryenShrUInt32"](), - ShrUInt64 = BinaryenObj["_BinaryenShrUInt64"](), ShrSInt32 = BinaryenObj["_BinaryenShrSInt32"](), ShrSInt64 = BinaryenObj["_BinaryenShrSInt64"](), + ShrUInt32 = BinaryenObj["_BinaryenShrUInt32"](), + ShrUInt64 = BinaryenObj["_BinaryenShrUInt64"](), RotLInt32 = BinaryenObj["_BinaryenRotLInt32"](), RotLInt64 = BinaryenObj["_BinaryenRotLInt64"](), RotRInt32 = BinaryenObj["_BinaryenRotRInt32"](), @@ -278,22 +278,22 @@ export enum Operation { EqInt64 = BinaryenObj["_BinaryenEqInt64"](), NeInt32 = BinaryenObj["_BinaryenNeInt32"](), NeInt64 = BinaryenObj["_BinaryenNeInt64"](), - LtUInt32 = BinaryenObj["_BinaryenLtUInt32"](), - LtUInt64 = BinaryenObj["_BinaryenLtUInt64"](), LtSInt32 = BinaryenObj["_BinaryenLtSInt32"](), LtSInt64 = BinaryenObj["_BinaryenLtSInt64"](), - GtUInt32 = BinaryenObj["_BinaryenGtUInt32"](), - GtUInt64 = BinaryenObj["_BinaryenGtUInt64"](), + LtUInt32 = BinaryenObj["_BinaryenLtUInt32"](), + LtUInt64 = BinaryenObj["_BinaryenLtUInt64"](), GtSInt32 = BinaryenObj["_BinaryenGtSInt32"](), GtSInt64 = BinaryenObj["_BinaryenGtSInt64"](), - LeUInt32 = BinaryenObj["_BinaryenLeUInt32"](), - LeUInt64 = BinaryenObj["_BinaryenLeUInt64"](), + GtUInt32 = BinaryenObj["_BinaryenGtUInt32"](), + GtUInt64 = BinaryenObj["_BinaryenGtUInt64"](), LeSInt32 = BinaryenObj["_BinaryenLeSInt32"](), LeSInt64 = BinaryenObj["_BinaryenLeSInt64"](), - GeUInt32 = BinaryenObj["_BinaryenGeUInt32"](), - GeUInt64 = BinaryenObj["_BinaryenGeUInt64"](), + LeUInt32 = BinaryenObj["_BinaryenLeUInt32"](), + LeUInt64 = BinaryenObj["_BinaryenLeUInt64"](), GeSInt32 = BinaryenObj["_BinaryenGeSInt32"](), GeSInt64 = BinaryenObj["_BinaryenGeSInt64"](), + GeUInt32 = BinaryenObj["_BinaryenGeUInt32"](), + GeUInt64 = BinaryenObj["_BinaryenGeUInt64"](), ExtendS8Int32 = BinaryenObj["_BinaryenExtendS8Int32"](), ExtendS8Int64 = BinaryenObj["_BinaryenExtendS8Int64"](), ExtendS16Int32 = BinaryenObj["_BinaryenExtendS16Int32"](), @@ -346,32 +346,32 @@ export enum Operation { ExtendSInt32 = BinaryenObj["_BinaryenExtendSInt32"](), ExtendUInt32 = BinaryenObj["_BinaryenExtendUInt32"](), WrapInt64 = BinaryenObj["_BinaryenWrapInt64"](), - TruncUFloat32ToInt32 = BinaryenObj["_BinaryenTruncUFloat32ToInt32"](), - TruncUFloat32ToInt64 = BinaryenObj["_BinaryenTruncUFloat32ToInt64"](), - TruncUFloat64ToInt32 = BinaryenObj["_BinaryenTruncUFloat64ToInt32"](), - TruncUFloat64ToInt64 = BinaryenObj["_BinaryenTruncUFloat64ToInt64"](), TruncSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSFloat32ToInt32"](), TruncSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSFloat32ToInt64"](), TruncSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSFloat64ToInt32"](), TruncSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSFloat64ToInt64"](), - TruncSatUFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt32"](), - TruncSatUFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt64"](), - TruncSatUFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt32"](), - TruncSatUFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt64"](), + TruncUFloat32ToInt32 = BinaryenObj["_BinaryenTruncUFloat32ToInt32"](), + TruncUFloat32ToInt64 = BinaryenObj["_BinaryenTruncUFloat32ToInt64"](), + TruncUFloat64ToInt32 = BinaryenObj["_BinaryenTruncUFloat64ToInt32"](), + TruncUFloat64ToInt64 = BinaryenObj["_BinaryenTruncUFloat64ToInt64"](), TruncSatSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt32"](), TruncSatSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt64"](), TruncSatSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt32"](), TruncSatSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt64"](), + TruncSatUFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt32"](), + TruncSatUFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt64"](), + TruncSatUFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt32"](), + TruncSatUFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt64"](), PromoteFloat32 = BinaryenObj["_BinaryenPromoteFloat32"](), DemoteFloat64 = BinaryenObj["_BinaryenDemoteFloat64"](), - ConvertUInt32ToFloat32 = BinaryenObj["_BinaryenConvertUInt32ToFloat32"](), - ConvertUInt32ToFloat64 = BinaryenObj["_BinaryenConvertUInt32ToFloat64"](), - ConvertUInt64ToFloat32 = BinaryenObj["_BinaryenConvertUInt64ToFloat32"](), - ConvertUInt64ToFloat64 = BinaryenObj["_BinaryenConvertUInt64ToFloat64"](), ConvertSInt32ToFloat32 = BinaryenObj["_BinaryenConvertSInt32ToFloat32"](), ConvertSInt32ToFloat64 = BinaryenObj["_BinaryenConvertSInt32ToFloat64"](), ConvertSInt64ToFloat32 = BinaryenObj["_BinaryenConvertSInt64ToFloat32"](), ConvertSInt64ToFloat64 = BinaryenObj["_BinaryenConvertSInt64ToFloat64"](), + ConvertUInt32ToFloat32 = BinaryenObj["_BinaryenConvertUInt32ToFloat32"](), + ConvertUInt32ToFloat64 = BinaryenObj["_BinaryenConvertUInt32ToFloat64"](), + ConvertUInt64ToFloat32 = BinaryenObj["_BinaryenConvertUInt64ToFloat32"](), + ConvertUInt64ToFloat64 = BinaryenObj["_BinaryenConvertUInt64ToFloat64"](), ReinterpretInt32 = BinaryenObj["_BinaryenReinterpretInt32"](), ReinterpretInt64 = BinaryenObj["_BinaryenReinterpretInt64"](), ReinterpretFloat32 = BinaryenObj["_BinaryenReinterpretFloat32"](), @@ -423,14 +423,14 @@ export enum Operation { SubVecI16x8 = BinaryenObj["_BinaryenSubVecI16x8"](), SubVecI32x4 = BinaryenObj["_BinaryenSubVecI32x4"](), SubVecI64x2 = BinaryenObj["_BinaryenSubVecI64x2"](), - AddSatUVecI8x16 = BinaryenObj["_BinaryenAddSatUVecI8x16"](), - AddSatUVecI16x8 = BinaryenObj["_BinaryenAddSatUVecI16x8"](), AddSatSVecI8x16 = BinaryenObj["_BinaryenAddSatSVecI8x16"](), AddSatSVecI16x8 = BinaryenObj["_BinaryenAddSatSVecI16x8"](), - SubSatUVecI8x16 = BinaryenObj["_BinaryenSubSatUVecI8x16"](), - SubSatUVecI16x8 = BinaryenObj["_BinaryenSubSatUVecI16x8"](), + AddSatUVecI8x16 = BinaryenObj["_BinaryenAddSatUVecI8x16"](), + AddSatUVecI16x8 = BinaryenObj["_BinaryenAddSatUVecI16x8"](), SubSatSVecI8x16 = BinaryenObj["_BinaryenSubSatSVecI8x16"](), SubSatSVecI16x8 = BinaryenObj["_BinaryenSubSatSVecI16x8"](), + SubSatUVecI8x16 = BinaryenObj["_BinaryenSubSatUVecI8x16"](), + SubSatUVecI16x8 = BinaryenObj["_BinaryenSubSatUVecI16x8"](), MulVecI16x8 = BinaryenObj["_BinaryenMulVecI16x8"](), MulVecI32x4 = BinaryenObj["_BinaryenMulVecI32x4"](), MulVecI64x2 = BinaryenObj["_BinaryenMulVecI64x2"](), @@ -438,18 +438,18 @@ export enum Operation { AvgrUVecI16x8 = BinaryenObj["_BinaryenAvgrUVecI16x8"](), Q15MulrSatSVecI16x8 = BinaryenObj["_BinaryenQ15MulrSatSVecI16x8"](), RelaxedQ15MulrSVecI16x8 = BinaryenObj["_BinaryenRelaxedQ15MulrSVecI16x8"](), - MinUVecI8x16 = BinaryenObj["_BinaryenMinUVecI8x16"](), - MinUVecI16x8 = BinaryenObj["_BinaryenMinUVecI16x8"](), - MinUVecI32x4 = BinaryenObj["_BinaryenMinUVecI32x4"](), MinSVecI8x16 = BinaryenObj["_BinaryenMinSVecI8x16"](), MinSVecI16x8 = BinaryenObj["_BinaryenMinSVecI16x8"](), MinSVecI32x4 = BinaryenObj["_BinaryenMinSVecI32x4"](), - MaxUVecI8x16 = BinaryenObj["_BinaryenMaxUVecI8x16"](), - MaxUVecI16x8 = BinaryenObj["_BinaryenMaxUVecI16x8"](), - MaxUVecI32x4 = BinaryenObj["_BinaryenMaxUVecI32x4"](), + MinUVecI8x16 = BinaryenObj["_BinaryenMinUVecI8x16"](), + MinUVecI16x8 = BinaryenObj["_BinaryenMinUVecI16x8"](), + MinUVecI32x4 = BinaryenObj["_BinaryenMinUVecI32x4"](), MaxSVecI8x16 = BinaryenObj["_BinaryenMaxSVecI8x16"](), MaxSVecI16x8 = BinaryenObj["_BinaryenMaxSVecI16x8"](), MaxSVecI32x4 = BinaryenObj["_BinaryenMaxSVecI32x4"](), + MaxUVecI8x16 = BinaryenObj["_BinaryenMaxUVecI8x16"](), + MaxUVecI16x8 = BinaryenObj["_BinaryenMaxUVecI16x8"](), + MaxUVecI32x4 = BinaryenObj["_BinaryenMaxUVecI32x4"](), // #### vbinop_f #### // AddVecF32x4 = BinaryenObj["_BinaryenAddVecF32x4"](), AddVecF64x2 = BinaryenObj["_BinaryenAddVecF64x2"](), @@ -495,34 +495,34 @@ export enum Operation { NeVecI16x8 = BinaryenObj["_BinaryenNeVecI16x8"](), NeVecI32x4 = BinaryenObj["_BinaryenNeVecI32x4"](), NeVecI64x2 = BinaryenObj["_BinaryenNeVecI64x2"](), - LtUVecI8x16 = BinaryenObj["_BinaryenLtUVecI8x16"](), - LtUVecI16x8 = BinaryenObj["_BinaryenLtUVecI16x8"](), - LtUVecI32x4 = BinaryenObj["_BinaryenLtUVecI32x4"](), LtSVecI8x16 = BinaryenObj["_BinaryenLtSVecI8x16"](), LtSVecI16x8 = BinaryenObj["_BinaryenLtSVecI16x8"](), LtSVecI32x4 = BinaryenObj["_BinaryenLtSVecI32x4"](), LtSVecI64x2 = BinaryenObj["_BinaryenLtSVecI64x2"](), - GtUVecI8x16 = BinaryenObj["_BinaryenGtUVecI8x16"](), - GtUVecI16x8 = BinaryenObj["_BinaryenGtUVecI16x8"](), - GtUVecI32x4 = BinaryenObj["_BinaryenGtUVecI32x4"](), + LtUVecI8x16 = BinaryenObj["_BinaryenLtUVecI8x16"](), + LtUVecI16x8 = BinaryenObj["_BinaryenLtUVecI16x8"](), + LtUVecI32x4 = BinaryenObj["_BinaryenLtUVecI32x4"](), GtSVecI8x16 = BinaryenObj["_BinaryenGtSVecI8x16"](), GtSVecI16x8 = BinaryenObj["_BinaryenGtSVecI16x8"](), GtSVecI32x4 = BinaryenObj["_BinaryenGtSVecI32x4"](), GtSVecI64x2 = BinaryenObj["_BinaryenGtSVecI64x2"](), - LeUVecI8x16 = BinaryenObj["_BinaryenLeUVecI8x16"](), - LeUVecI16x8 = BinaryenObj["_BinaryenLeUVecI16x8"](), - LeUVecI32x4 = BinaryenObj["_BinaryenLeUVecI32x4"](), + GtUVecI8x16 = BinaryenObj["_BinaryenGtUVecI8x16"](), + GtUVecI16x8 = BinaryenObj["_BinaryenGtUVecI16x8"](), + GtUVecI32x4 = BinaryenObj["_BinaryenGtUVecI32x4"](), LeSVecI8x16 = BinaryenObj["_BinaryenLeSVecI8x16"](), LeSVecI16x8 = BinaryenObj["_BinaryenLeSVecI16x8"](), LeSVecI32x4 = BinaryenObj["_BinaryenLeSVecI32x4"](), LeSVecI64x2 = BinaryenObj["_BinaryenLeSVecI64x2"](), - GeUVecI8x16 = BinaryenObj["_BinaryenGeUVecI8x16"](), - GeUVecI16x8 = BinaryenObj["_BinaryenGeUVecI16x8"](), - GeUVecI32x4 = BinaryenObj["_BinaryenGeUVecI32x4"](), + LeUVecI8x16 = BinaryenObj["_BinaryenLeUVecI8x16"](), + LeUVecI16x8 = BinaryenObj["_BinaryenLeUVecI16x8"](), + LeUVecI32x4 = BinaryenObj["_BinaryenLeUVecI32x4"](), GeSVecI8x16 = BinaryenObj["_BinaryenGeSVecI8x16"](), GeSVecI16x8 = BinaryenObj["_BinaryenGeSVecI16x8"](), GeSVecI32x4 = BinaryenObj["_BinaryenGeSVecI32x4"](), GeSVecI64x2 = BinaryenObj["_BinaryenGeSVecI64x2"](), + GeUVecI8x16 = BinaryenObj["_BinaryenGeUVecI8x16"](), + GeUVecI16x8 = BinaryenObj["_BinaryenGeUVecI16x8"](), + GeUVecI32x4 = BinaryenObj["_BinaryenGeUVecI32x4"](), // #### vrelop_f #### // EqVecF32x4 = BinaryenObj["_BinaryenEqVecF32x4"](), EqVecF64x2 = BinaryenObj["_BinaryenEqVecF64x2"](), @@ -541,14 +541,14 @@ export enum Operation { ShlVecI16x8 = BinaryenObj["_BinaryenShlVecI16x8"](), ShlVecI32x4 = BinaryenObj["_BinaryenShlVecI32x4"](), ShlVecI64x2 = BinaryenObj["_BinaryenShlVecI64x2"](), - ShrUVecI8x16 = BinaryenObj["_BinaryenShrUVecI8x16"](), - ShrUVecI16x8 = BinaryenObj["_BinaryenShrUVecI16x8"](), - ShrUVecI32x4 = BinaryenObj["_BinaryenShrUVecI32x4"](), - ShrUVecI64x2 = BinaryenObj["_BinaryenShrUVecI64x2"](), ShrSVecI8x16 = BinaryenObj["_BinaryenShrSVecI8x16"](), ShrSVecI16x8 = BinaryenObj["_BinaryenShrSVecI16x8"](), ShrSVecI32x4 = BinaryenObj["_BinaryenShrSVecI32x4"](), ShrSVecI64x2 = BinaryenObj["_BinaryenShrSVecI64x2"](), + ShrUVecI8x16 = BinaryenObj["_BinaryenShrUVecI8x16"](), + ShrUVecI16x8 = BinaryenObj["_BinaryenShrUVecI16x8"](), + ShrUVecI32x4 = BinaryenObj["_BinaryenShrUVecI32x4"](), + ShrUVecI64x2 = BinaryenObj["_BinaryenShrUVecI64x2"](), // #### bitmask #### // BitmaskVecI8x16 = BinaryenObj["_BinaryenBitmaskVecI8x16"](), BitmaskVecI16x8 = BinaryenObj["_BinaryenBitmaskVecI16x8"](), @@ -558,23 +558,23 @@ export enum Operation { SwizzleVecI8x16 = BinaryenObj["_BinaryenSwizzleVecI8x16"](), RelaxedSwizzleVecI8x16 = BinaryenObj["_BinaryenRelaxedSwizzleVecI8x16"](), // #### vextunop #### // - ExtAddPairwiseUVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseUVecI8x16ToI16x8"](), - ExtAddPairwiseUVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseUVecI16x8ToI32x4"](), ExtAddPairwiseSVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseSVecI8x16ToI16x8"](), ExtAddPairwiseSVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseSVecI16x8ToI32x4"](), + ExtAddPairwiseUVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseUVecI8x16ToI16x8"](), + ExtAddPairwiseUVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseUVecI16x8ToI32x4"](), // #### vextbinop #### // - ExtMulLowUVecI16x8 = BinaryenObj["_BinaryenExtMulLowUVecI16x8"](), - ExtMulLowUVecI32x4 = BinaryenObj["_BinaryenExtMulLowUVecI32x4"](), - ExtMulLowUVecI64x2 = BinaryenObj["_BinaryenExtMulLowUVecI64x2"](), ExtMulLowSVecI16x8 = BinaryenObj["_BinaryenExtMulLowSVecI16x8"](), ExtMulLowSVecI32x4 = BinaryenObj["_BinaryenExtMulLowSVecI32x4"](), ExtMulLowSVecI64x2 = BinaryenObj["_BinaryenExtMulLowSVecI64x2"](), - ExtMulHighUVecI16x8 = BinaryenObj["_BinaryenExtMulHighUVecI16x8"](), - ExtMulHighUVecI32x4 = BinaryenObj["_BinaryenExtMulHighUVecI32x4"](), - ExtMulHighUVecI64x2 = BinaryenObj["_BinaryenExtMulHighUVecI64x2"](), + ExtMulLowUVecI16x8 = BinaryenObj["_BinaryenExtMulLowUVecI16x8"](), + ExtMulLowUVecI32x4 = BinaryenObj["_BinaryenExtMulLowUVecI32x4"](), + ExtMulLowUVecI64x2 = BinaryenObj["_BinaryenExtMulLowUVecI64x2"](), ExtMulHighSVecI16x8 = BinaryenObj["_BinaryenExtMulHighSVecI16x8"](), ExtMulHighSVecI32x4 = BinaryenObj["_BinaryenExtMulHighSVecI32x4"](), ExtMulHighSVecI64x2 = BinaryenObj["_BinaryenExtMulHighSVecI64x2"](), + ExtMulHighUVecI16x8 = BinaryenObj["_BinaryenExtMulHighUVecI16x8"](), + ExtMulHighUVecI32x4 = BinaryenObj["_BinaryenExtMulHighUVecI32x4"](), + ExtMulHighUVecI64x2 = BinaryenObj["_BinaryenExtMulHighUVecI64x2"](), DotI8x16I7x16AddSToVecI32x4 = BinaryenObj["_BinaryenDotI8x16I7x16AddSToVecI32x4"](), DotI8x16I7x16SToVecI16x8 = BinaryenObj["_BinaryenDotI8x16I7x16SToVecI16x8"](), DotSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenDotSVecI16x8ToVecI32x4"](), @@ -584,30 +584,30 @@ export enum Operation { NarrowSVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowSVecI32x4ToVecI16x8"](), NarrowUVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowUVecI32x4ToVecI16x8"](), // #### vcvtop #### // - ExtendLowUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowUVecI8x16ToVecI16x8"](), - ExtendLowUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowUVecI16x8ToVecI32x4"](), - ExtendLowUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowUVecI32x4ToVecI64x2"](), ExtendLowSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowSVecI8x16ToVecI16x8"](), ExtendLowSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowSVecI16x8ToVecI32x4"](), ExtendLowSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowSVecI32x4ToVecI64x2"](), - ExtendHighUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighUVecI8x16ToVecI16x8"](), - ExtendHighUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighUVecI16x8ToVecI32x4"](), - ExtendHighUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighUVecI32x4ToVecI64x2"](), + ExtendLowUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowUVecI8x16ToVecI16x8"](), + ExtendLowUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowUVecI16x8ToVecI32x4"](), + ExtendLowUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowUVecI32x4ToVecI64x2"](), ExtendHighSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighSVecI8x16ToVecI16x8"](), ExtendHighSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighSVecI16x8ToVecI32x4"](), ExtendHighSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighSVecI32x4ToVecI64x2"](), - ConvertUVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertUVecI32x4ToVecF32x4"](), + ExtendHighUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighUVecI8x16ToVecI16x8"](), + ExtendHighUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighUVecI16x8ToVecI32x4"](), + ExtendHighUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighUVecI32x4ToVecI64x2"](), ConvertSVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertSVecI32x4ToVecF32x4"](), - ConvertLowUVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowUVecI32x4ToVecF64x2"](), + ConvertUVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertUVecI32x4ToVecF32x4"](), ConvertLowSVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowSVecI32x4ToVecF64x2"](), - TruncSatUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatUVecF32x4ToVecI32x4"](), + ConvertLowUVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowUVecI32x4ToVecF64x2"](), TruncSatSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatSVecF32x4ToVecI32x4"](), - TruncSatZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroUVecF64x2ToVecI32x4"](), + TruncSatUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatUVecF32x4ToVecI32x4"](), TruncSatZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroSVecF64x2ToVecI32x4"](), - RelaxedTruncUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncUVecF32x4ToVecI32x4"](), + TruncSatZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroUVecF64x2ToVecI32x4"](), RelaxedTruncSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncSVecF32x4ToVecI32x4"](), - RelaxedTruncZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4"](), + RelaxedTruncUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncUVecF32x4ToVecI32x4"](), RelaxedTruncZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroSVecF64x2ToVecI32x4"](), + RelaxedTruncZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4"](), DemoteZeroVecF64x2ToVecF32x4 = BinaryenObj["_BinaryenDemoteZeroVecF64x2ToVecF32x4"](), PromoteLowVecF32x4ToVecF64x2 = BinaryenObj["_BinaryenPromoteLowVecF32x4ToVecF64x2"](), // #### splat #### // @@ -618,10 +618,10 @@ export enum Operation { SplatVecF32x4 = BinaryenObj["_BinaryenSplatVecF32x4"](), SplatVecF64x2 = BinaryenObj["_BinaryenSplatVecF64x2"](), // #### extract_lane #### // - ExtractLaneUVecI8x16 = BinaryenObj["_BinaryenExtractLaneUVecI8x16"](), - ExtractLaneUVecI16x8 = BinaryenObj["_BinaryenExtractLaneUVecI16x8"](), ExtractLaneSVecI8x16 = BinaryenObj["_BinaryenExtractLaneSVecI8x16"](), ExtractLaneSVecI16x8 = BinaryenObj["_BinaryenExtractLaneSVecI16x8"](), + ExtractLaneUVecI8x16 = BinaryenObj["_BinaryenExtractLaneUVecI8x16"](), + ExtractLaneUVecI16x8 = BinaryenObj["_BinaryenExtractLaneUVecI16x8"](), ExtractLaneVecI32x4 = BinaryenObj["_BinaryenExtractLaneVecI32x4"](), ExtractLaneVecI64x2 = BinaryenObj["_BinaryenExtractLaneVecI64x2"](), ExtractLaneVecF32x4 = BinaryenObj["_BinaryenExtractLaneVecF32x4"](), From ca7449f525ea517faae51297269d58d5555dc87b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 30 Apr 2026 00:10:21 -0400 Subject: [PATCH 032/247] renamed: src/global.ts -> src/globals.ts --- ts/src/binaryen.ts | 2 +- ts/src/class/Module.ts | 14 -------------- ts/src/class/expression/Expression.ts | 2 +- ts/src/{global.ts => globals.ts} | 7 +++++++ 4 files changed, 9 insertions(+), 16 deletions(-) rename ts/src/{global.ts => globals.ts} (98%) diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index e32cabeeb4d..b37107a45a9 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1,5 +1,5 @@ export * from "./constants.ts"; -export * from "./global.ts"; +export * from "./globals.ts"; export { ExpressionRunner, ExpressionRunnerFlag, diff --git a/ts/src/class/Module.ts b/ts/src/class/Module.ts index cde85dc0626..2619d756ee3 100644 --- a/ts/src/class/Module.ts +++ b/ts/src/class/Module.ts @@ -234,17 +234,3 @@ export class Module { copyExpression() {} } - - - -export function getTagInfo() {} - -export function getGlobalInfo() {} - -export function getTableInfo() {} - -export function getFunctionInfo() {} - -export function getElementSegmentInfo() {} - -export function getExportInfo() {} diff --git a/ts/src/class/expression/Expression.ts b/ts/src/class/expression/Expression.ts index d10396b9505..1964bd1f0fa 100644 --- a/ts/src/class/expression/Expression.ts +++ b/ts/src/class/expression/Expression.ts @@ -9,7 +9,7 @@ import type { import { emitText, getExpressionType, -} from "../../global.ts"; +} from "../../globals.ts"; import { replacedBy, } from "../../lib.ts"; diff --git a/ts/src/global.ts b/ts/src/globals.ts similarity index 98% rename from ts/src/global.ts rename to ts/src/globals.ts index 6198a6d3086..1d79950a700 100644 --- a/ts/src/global.ts +++ b/ts/src/globals.ts @@ -198,6 +198,13 @@ export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, mod.ptr); } +export function getTagInfo() {} +export function getGlobalInfo() {} +export function getTableInfo() {} +export function getFunctionInfo() {} +export function getElementSegmentInfo() {} +export function getExportInfo() {} + // ## Getters & Setters for Settings ## // From d1398ac9be279f4541f12adf525cd1093cb784c2 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 30 Apr 2026 01:00:35 -0400 Subject: [PATCH 033/247] refactor: add deprecations file --- ts/src/-deprecations.ts | 38 ++++++++++++++++++++++++++++++++++++++ ts/src/binaryen.ts | 1 + ts/src/class/Module.ts | 10 ++++++++++ ts/src/constants.ts | 8 -------- 4 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 ts/src/-deprecations.ts diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts new file mode 100644 index 00000000000..866560d6089 --- /dev/null +++ b/ts/src/-deprecations.ts @@ -0,0 +1,38 @@ +// # Deprecations # // + + + +import { + ExpressionId, + ExternalKind, + Operation, + SideEffect, +} from "./constants.ts"; +import { + Function as BinaryenFunction, +} from "./class/Function.ts"; +import { + Table as BinaryenTable, +} from "./class/Table.ts"; + + + +/** @deprecated `ExpressionIds` has been renamed to `ExpressionId`. */ +export const ExpressionIds = ExpressionId; + +/** @deprecated `Operations` has been renamed to `Operation`. */ +export const Operations = Operation; + +/** @deprecated `ExternalKinds` has been renamed to `ExternalKind`. */ +export const ExternalKinds = ExternalKind; + +/** @deprecated `SideEffects` has been renamed to `SideEffect`. */ +export const SideEffects = SideEffect; + + + +/** @deprecated The `Function` class now lives as a static member of the `Module` class. Use `Module.Function`. */ +export const Function = BinaryenFunction; + +/** @deprecated The `Table` class now lives as a static member of the `Module` class. Use `Module.Table`. */ +export const Table = BinaryenTable; diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index b37107a45a9..18822df8ee6 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -11,3 +11,4 @@ export { export {Relooper} from "./class/Relooper.ts"; export {TypeBuilder} from "./class/TypeBuilder.ts"; export * from "./class/expression/index.ts"; +export * from "./-deprecations.ts"; diff --git a/ts/src/class/Module.ts b/ts/src/class/Module.ts index 2619d756ee3..a7ca60fe3c2 100644 --- a/ts/src/class/Module.ts +++ b/ts/src/class/Module.ts @@ -3,6 +3,12 @@ import { BinaryenObj, UTF8ToString, } from "../-pre.ts"; +import { + Function as BinaryenFunction, +} from "./Function.ts"; +import { + Table, +} from "./Table.ts"; import { block, } from "./expression/Block.ts"; @@ -62,6 +68,10 @@ export const Features = Feature; export class Module { + static Table = Table; + static Function = BinaryenFunction; + + readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); // ## Expression Creation ## // diff --git a/ts/src/constants.ts b/ts/src/constants.ts index a1d06f28976..054870283c1 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -192,8 +192,6 @@ export enum ExpressionId { StringWTF16Get = BinaryenObj["_BinaryenStringWTF16GetId"](), StringSliceWTF = BinaryenObj["_BinaryenStringSliceWTFId"](), } -/** @deprecated Enum name is now singular. */ -export const ExpressionIds = ExpressionId; @@ -653,8 +651,6 @@ export enum Operation { StringEqEqual = BinaryenObj["_BinaryenStringEqEqual"](), StringEqCompare = BinaryenObj["_BinaryenStringEqCompare"](), } -/** @deprecated Enum name is now singular. */ -export const Operations = Operation; @@ -667,8 +663,6 @@ export enum ExternalKind { ExternalTable = BinaryenObj["_BinaryenExternalTable"](), ExternalFunction = BinaryenObj["_BinaryenExternalFunction"](), } -/** @deprecated Enum name is now singular. */ -export const ExternalKinds = ExternalKind; @@ -699,5 +693,3 @@ export enum SideEffect { TrapsNeverHappen = BinaryenObj["_BinaryenSideEffectTrapsNeverHappen"](), Any = BinaryenObj["_BinaryenSideEffectAny"](), } -/** @deprecated Enum name is now singular. */ -export const SideEffects = SideEffect; From ba4cb4af1b6b89a69f4686491d5bda1a662cf846 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 30 Apr 2026 02:03:23 -0400 Subject: [PATCH 034/247] refactor: deprecate `get*Info` globals --- ts/src/-deprecations.ts | 50 ++++++++++++++++++++++++++++++ ts/src/class/ElementSegment.ts | 31 +++++++++++++++++++ ts/src/class/Export.ts | 23 ++++++++++++++ ts/src/class/Function.ts | 12 +++++++- ts/src/class/Global.ts | 30 ++++++++++++++++++ ts/src/class/Module.ts | 22 +++++++++++++ ts/src/class/Table.ts | 7 +++++ ts/src/class/Tag.ts | 27 ++++++++++++++++ ts/src/constants.ts | 15 ++++++--- ts/src/globals.ts | 7 ----- ts/src/lib.ts | 8 ++++- ts/src/utils.ts | 56 ++++++++++++++++++++++++++++++++++ 12 files changed, 274 insertions(+), 14 deletions(-) create mode 100644 ts/src/class/ElementSegment.ts create mode 100644 ts/src/class/Export.ts create mode 100644 ts/src/class/Global.ts create mode 100644 ts/src/class/Tag.ts diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 866560d6089..3c978ad4b52 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -7,13 +7,25 @@ import { ExternalKind, Operation, SideEffect, + type TagRef, + type GlobalRef, + type TableRef, + type FunctionRef, + type ElementSegmentRef, + type ExportRef, } from "./constants.ts"; import { Function as BinaryenFunction, } from "./class/Function.ts"; +import { + Module, +} from "./class/Module.ts"; import { Table as BinaryenTable, } from "./class/Table.ts"; +import { + consoleWarn, +} from "./lib.ts"; @@ -36,3 +48,41 @@ export const Function = BinaryenFunction; /** @deprecated The `Table` class now lives as a static member of the `Module` class. Use `Module.Table`. */ export const Table = BinaryenTable; + + + +/** @deprecated Use `new Module.Tag(tagref)` instead. */ +export function getTagInfo(tag: TagRef) { + consoleWarn("Global function `getTagInfo` is deprecated; use `new Module.Tag(tagref)` instead."); + return new Module.Tag(tag); +} + +/** @deprecated Use `new Module.Global(globalref)` instead. */ +export function getGlobalInfo(global: GlobalRef) { + consoleWarn("Global function `getGlobalInfo` is deprecated; use `new Module.Global(globalref)` instead."); + return new Module.Global(global); +} + +/** @deprecated Use `new Module.Table(tableref)` instead. */ +export function getTableInfo(table: TableRef) { + consoleWarn("Global function `getTableInfo` is deprecated; use `new Module.Table(tableref)` instead."); + return new Module.Table(table); +} + +/** @deprecated Use `new Module.Function(funcref)` instead. */ +export function getFunctionInfo(func: FunctionRef) { + consoleWarn("Global function `getFunctionInfo` is deprecated; use `new Module.Function(funcref)` instead."); + return new Module.Function(func); +} + +/** @deprecated Use `new Module.ElementSegment(segmentref)` instead. */ +export function getElementSegmentInfo(segment: ElementSegmentRef) { + consoleWarn("Global function `getElementSegmentInfo` is deprecated; use `new Module.ElementSegment(segmentref)` instead."); + return new Module.ElementSegment(segment); +} + +/** @deprecated Use `new Module.Export(exportref)` instead. */ +export function getExportInfo(xport: ExportRef) { + consoleWarn("Global function `getExportInfo` is deprecated; use `new Module.Export(exportref)` instead."); + return new Module.Export(xport); +} diff --git a/ts/src/class/ElementSegment.ts b/ts/src/class/ElementSegment.ts new file mode 100644 index 00000000000..e13a20a0e3b --- /dev/null +++ b/ts/src/class/ElementSegment.ts @@ -0,0 +1,31 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../-pre.ts"; +import type { + ElementSegmentRef, +} from "../constants.ts"; + + + +export class ElementSegment { + readonly name: string; + readonly table: string; + readonly offset: number; + readonly data: readonly string[]; + + + constructor(segment: ElementSegmentRef) { + const segmentLength = BinaryenObj["_BinaryenElementSegmentGetLength"](segment); + const names: string[] = []; + for (let j = 0; j !== segmentLength; ++j) { + const ptr = BinaryenObj["_BinaryenElementSegmentGetData"](segment, j); + names[j] = UTF8ToString(ptr); + } + + this.name = UTF8ToString(BinaryenObj["_BinaryenElementSegmentGetName"](segment)); + this.table = UTF8ToString(BinaryenObj["_BinaryenElementSegmentGetTable"](segment)); + this.offset = BinaryenObj["_BinaryenElementSegmentGetOffset"](segment); + this.data = names; + } +} diff --git a/ts/src/class/Export.ts b/ts/src/class/Export.ts new file mode 100644 index 00000000000..029522feefc --- /dev/null +++ b/ts/src/class/Export.ts @@ -0,0 +1,23 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../-pre.ts"; +import type { + ExportRef, + ExternalKind, +} from "../constants.ts"; + + + +export class Export { + readonly kind: ExternalKind; + readonly name: string; + readonly value: string; + + + constructor(xport: ExportRef) { + this.kind = BinaryenObj["_BinaryenExportGetKind"](xport); + this.name = UTF8ToString(BinaryenObj["_BinaryenExportGetName"](xport)); + this.value = UTF8ToString(BinaryenObj["_BinaryenExportGetValue"](xport)); + } +} diff --git a/ts/src/class/Function.ts b/ts/src/class/Function.ts index 895ebcb2014..8fba46b03bd 100644 --- a/ts/src/class/Function.ts +++ b/ts/src/class/Function.ts @@ -12,6 +12,7 @@ import { } from "../lib.ts"; import { THIS_PTR, + getAllNested, preserveStack, strToStack, } from "../utils.ts"; @@ -37,10 +38,19 @@ class BinaryenFunction { private readonly [THIS_PTR]: FunctionRef; + readonly module: string; + readonly base: string; + readonly vars: readonly Type[]; + + constructor(func: FunctionRef) { this[THIS_PTR] = func; + this.module = UTF8ToString(BinaryenObj["_BinaryenFunctionImportGetModule"](this[THIS_PTR])); + this.base = UTF8ToString(BinaryenObj["_BinaryenFunctionImportGetBase"](this[THIS_PTR])); + this.vars = getAllNested(func, BinaryenObj["_BinaryenFunctionGetNumVars"], BinaryenObj["_BinaryenFunctionGetVar"]); } + valueOf() { return this[THIS_PTR]; } @@ -50,7 +60,7 @@ class BinaryenFunction { return UTF8ToString(BinaryenObj["_BinaryenFunctionGetName"](this[THIS_PTR])); } - getType() { + getType(): Type { return BinaryenObj["_BinaryenFunctionGetType"](this[THIS_PTR]); } diff --git a/ts/src/class/Global.ts b/ts/src/class/Global.ts new file mode 100644 index 00000000000..ba40e6a222c --- /dev/null +++ b/ts/src/class/Global.ts @@ -0,0 +1,30 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../-pre.ts"; +import type { + ExpressionRef, + GlobalRef, + Type, +} from "../constants.ts"; + + + +export class Global { + readonly name: string; + readonly module: string; + readonly base: string; + readonly type: Type; + readonly mutable: boolean; + readonly init: ExpressionRef; + + + constructor(global: GlobalRef) { + this.name = UTF8ToString(BinaryenObj["_BinaryenGlobalGetName"](global)); + this.module = UTF8ToString(BinaryenObj["_BinaryenGlobalImportGetModule"](global)); + this.base = UTF8ToString(BinaryenObj["_BinaryenGlobalImportGetBase"](global)); + this.type = BinaryenObj["_BinaryenGlobalGetType"](global); + this.mutable = Boolean(BinaryenObj["_BinaryenGlobalIsMutable"](global)); + this.init = BinaryenObj["_BinaryenGlobalGetInitExpr"](global); + } +} diff --git a/ts/src/class/Module.ts b/ts/src/class/Module.ts index a7ca60fe3c2..8d17dea4f99 100644 --- a/ts/src/class/Module.ts +++ b/ts/src/class/Module.ts @@ -3,12 +3,24 @@ import { BinaryenObj, UTF8ToString, } from "../-pre.ts"; +import { + ElementSegment, +} from "./ElementSegment.ts"; +import { + Export, +} from "./Export.ts"; import { Function as BinaryenFunction, } from "./Function.ts"; +import { + Global, +} from "./Global.ts"; import { Table, } from "./Table.ts"; +import { + Tag, +} from "./Tag.ts"; import { block, } from "./expression/Block.ts"; @@ -68,8 +80,12 @@ export const Features = Feature; export class Module { + static Tag = Tag; + static Global = Global; static Table = Table; static Function = BinaryenFunction; + static ElementSegment = ElementSegment; + static Export = Export; readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); @@ -91,6 +107,7 @@ export class Module { // see https://webassembly.github.io/spec/core/syntax/modules.html // ### Tags ### // + // TODO: move these to the Tag class addTag() {} getTag() {} @@ -98,6 +115,7 @@ export class Module { removeTag() {} // ### Globals ### // + // TODO: move these to the Global class addGlobal() {} getGlobal() {} @@ -116,6 +134,7 @@ export class Module { getMemoryInfo() {} // ### Tables ### // + // TODO: move these to the Table class addTable() {} getTable() {} @@ -129,6 +148,7 @@ export class Module { removeTable() {} // ### Functions ### // + // TODO: move these to the Function class addFunction() {} getFunction() {} @@ -149,6 +169,7 @@ export class Module { getDataSegmentInfo() {} // ### Element Segments ### // + // TODO: move these to the ElementSegment class addActiveElementSegment() {} addPassiveElementSegment() {} @@ -176,6 +197,7 @@ export class Module { addFunctionImport() {} // ### Exports ### // + // TODO: move these to the Export class addTagExport() {} addGlobalExport() {} diff --git a/ts/src/class/Table.ts b/ts/src/class/Table.ts index 1b83ed069db..ccf70d97c04 100644 --- a/ts/src/class/Table.ts +++ b/ts/src/class/Table.ts @@ -33,10 +33,17 @@ export class Table { private readonly [THIS_PTR]: TableRef; + readonly module: string; + readonly base: string; + + constructor(table: TableRef) { this[THIS_PTR] = table; + this.module = UTF8ToString(BinaryenObj["_BinaryenTableImportGetModule"](this[THIS_PTR])); + this.base = UTF8ToString(BinaryenObj["_BinaryenTableImportGetBase"](this[THIS_PTR])); } + valueOf() { return this[THIS_PTR]; } diff --git a/ts/src/class/Tag.ts b/ts/src/class/Tag.ts new file mode 100644 index 00000000000..2253d499cad --- /dev/null +++ b/ts/src/class/Tag.ts @@ -0,0 +1,27 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../-pre.ts"; +import type { + TagRef, + Type, +} from "../constants.ts"; + + + +export class Tag { + readonly name: string; + readonly module: string; + readonly base: string; + readonly params: Type; + readonly results: Type; + + + constructor(tag: TagRef) { + this.name = UTF8ToString(BinaryenObj["_BinaryenTagGetName"](tag)); + this.module = UTF8ToString(BinaryenObj["_BinaryenTagImportGetModule"](tag)); + this.base = UTF8ToString(BinaryenObj["_BinaryenTagImportGetBase"](tag)); + this.params = BinaryenObj["_BinaryenTagGetParams"](tag); + this.results = BinaryenObj["_BinaryenTagGetResults"](tag); + } +} diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 054870283c1..32b91eb0360 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -10,18 +10,23 @@ import { // ## Static Types ## // +// ### Expressions ### // export type Type = number; export type HeapType = number; export type PackedType = number; -export type ElementSegmentRef = number; export type ExpressionRef = number; -export type FunctionRef = number; + +// ### Module Components ### // +export type TagRef = number; export type GlobalRef = number; -export type ExportRef = number; export type TableRef = number; -export type TagRef = number; -export type RelooperBlockRef = number; +export type FunctionRef = number; +export type ElementSegmentRef = number; +export type ExportRef = number; + +// ### Binaryen Tools ### // export type ExpressionRunnerRef = number; +export type RelooperBlockRef = number; export type TypeBuilderRef = number; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 1d79950a700..6198a6d3086 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -198,13 +198,6 @@ export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, mod.ptr); } -export function getTagInfo() {} -export function getGlobalInfo() {} -export function getTableInfo() {} -export function getFunctionInfo() {} -export function getElementSegmentInfo() {} -export function getExportInfo() {} - // ## Getters & Setters for Settings ## // diff --git a/ts/src/lib.ts b/ts/src/lib.ts index be7a1a5ebd3..26d73aef19c 100644 --- a/ts/src/lib.ts +++ b/ts/src/lib.ts @@ -3,6 +3,12 @@ +export function consoleWarn(...args: any[]): void { + return (console?.warn ?? console?.log)?.call(undefined, ...args); +} + + + /** * Mark a method as deprecated by logging a warning in the console. * @example @@ -22,7 +28,7 @@ export function replacedBy(replacement: ) => (typeof method) | void { return (method, context) => function (...args) { const message = `WARNING: ${ context.static ? "Static" : "Instance" } method \`${ String(context.name) }\` is deprecated${ replacement && `; use ${ replacement } instead` }.`; - (console?.warn ?? console?.log)?.(message); + consoleWarn(message); return method.call(this, ...args); }; } diff --git a/ts/src/utils.ts b/ts/src/utils.ts index 6031cb54851..61e8f99aae9 100644 --- a/ts/src/utils.ts +++ b/ts/src/utils.ts @@ -69,3 +69,59 @@ export function i8sToStack(i8s: readonly number[]): number { HEAP8.set(i8s, ret); return ret; } + + + +/** + * [description] + * @param ref [description] + * @param numFn [description] + * @param getFn [description] + * @return [description] + */ +export function getAllNested( + ref: T, + numFn: (ref: T) => number, + getFn: (ref: T, i: number) => U, +): U[] { + const num = numFn.call(undefined, ref); + const ret: U[] = []; + for (let i = 0; i < num; ++i) { + ret[i] = getFn.call(undefined, ref, i); + } + return ret; +} + +/** + * [description] + * @param ref [description] + * @param values [description] + * @param numFn [description] + * @param setFn [description] + * @param appendFn [description] + * @param removeFn [description] + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function setAllNested( + ref: T, + values: readonly U[], + numFn: (ref: T) => number, + setFn: (ref: T, i: number, val: U) => void, + appendFn: (ef: T, val: U) => void, + removeFn: (ef: T, num: number) => void, +): void { + const num = values.length; + let prevNum = numFn(ref); + let index = 0; + while (index < num) { + if (index < prevNum) { + setFn(ref, index, values[index]); + } else { + appendFn(ref, values[index]); + } + ++index; + } + while (prevNum > index) { + removeFn(ref, --prevNum); + } +} From 9bb9653705d9db762517ef174d61d70409ce1c5c Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 30 Apr 2026 02:07:41 -0400 Subject: [PATCH 035/247] refactor: move files into module folder --- ts/src/-deprecations.ts | 6 +++--- ts/src/binaryen.ts | 2 +- ts/src/class/ExpressionRunner.ts | 2 +- ts/src/class/Relooper.ts | 2 +- ts/src/class/expression/Block.ts | 2 +- ts/src/class/expression/LocalGet.ts | 2 +- ts/src/class/expression/LocalSet.ts | 2 +- ts/src/class/{ => module}/ElementSegment.ts | 4 ++-- ts/src/class/{ => module}/Export.ts | 4 ++-- ts/src/class/{ => module}/Function.ts | 8 ++++---- ts/src/class/{ => module}/Global.ts | 4 ++-- ts/src/class/{ => module}/Module.ts | 22 ++++++++++----------- ts/src/class/{ => module}/Table.ts | 8 ++++---- ts/src/class/{ => module}/Tag.ts | 4 ++-- ts/src/globals.ts | 2 +- 15 files changed, 37 insertions(+), 37 deletions(-) rename ts/src/class/{ => module}/ElementSegment.ts (93%) rename ts/src/class/{ => module}/Export.ts (89%) rename ts/src/class/{ => module}/Function.ts (97%) rename ts/src/class/{ => module}/Global.ts (93%) rename ts/src/class/{ => module}/Module.ts (97%) rename ts/src/class/{ => module}/Table.ts (97%) rename ts/src/class/{ => module}/Tag.ts (91%) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 3c978ad4b52..6a98e2185f5 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -16,13 +16,13 @@ import { } from "./constants.ts"; import { Function as BinaryenFunction, -} from "./class/Function.ts"; +} from "./class/module/Function.ts"; import { Module, -} from "./class/Module.ts"; +} from "./class/module/Module.ts"; import { Table as BinaryenTable, -} from "./class/Table.ts"; +} from "./class/module/Table.ts"; import { consoleWarn, } from "./lib.ts"; diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 18822df8ee6..2a48e0e876e 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -7,7 +7,7 @@ export { export { Feature, Module, -} from "./class/Module.ts"; +} from "./class/module/Module.ts"; export {Relooper} from "./class/Relooper.ts"; export {TypeBuilder} from "./class/TypeBuilder.ts"; export * from "./class/expression/index.ts"; diff --git a/ts/src/class/ExpressionRunner.ts b/ts/src/class/ExpressionRunner.ts index e0b40b5527b..02607e689fb 100644 --- a/ts/src/class/ExpressionRunner.ts +++ b/ts/src/class/ExpressionRunner.ts @@ -11,7 +11,7 @@ import { } from "../utils.ts"; import type { Module, -} from "./Module.ts"; +} from "./module/Module.ts"; diff --git a/ts/src/class/Relooper.ts b/ts/src/class/Relooper.ts index cc356341fc3..48d1caeb6f9 100644 --- a/ts/src/class/Relooper.ts +++ b/ts/src/class/Relooper.ts @@ -11,7 +11,7 @@ import { } from "../utils.ts"; import type { Module, -} from "./Module.ts"; +} from "./module/Module.ts"; diff --git a/ts/src/class/expression/Block.ts b/ts/src/class/expression/Block.ts index 3a4a195e81d..4383528a58e 100644 --- a/ts/src/class/expression/Block.ts +++ b/ts/src/class/expression/Block.ts @@ -14,7 +14,7 @@ import { } from "../../utils.ts"; import type { Module, -} from "../Module.ts"; +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/class/expression/LocalGet.ts b/ts/src/class/expression/LocalGet.ts index 8ebcab96544..7ce6fec678e 100644 --- a/ts/src/class/expression/LocalGet.ts +++ b/ts/src/class/expression/LocalGet.ts @@ -8,7 +8,7 @@ import { } from "../../constants.ts"; import type { Module, -} from "../Module.ts"; +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/class/expression/LocalSet.ts b/ts/src/class/expression/LocalSet.ts index d3af9c5dc57..e364a9360b8 100644 --- a/ts/src/class/expression/LocalSet.ts +++ b/ts/src/class/expression/LocalSet.ts @@ -8,7 +8,7 @@ import { } from "../../constants.ts"; import type { Module, -} from "../Module.ts"; +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/class/ElementSegment.ts b/ts/src/class/module/ElementSegment.ts similarity index 93% rename from ts/src/class/ElementSegment.ts rename to ts/src/class/module/ElementSegment.ts index e13a20a0e3b..cdec3ba0765 100644 --- a/ts/src/class/ElementSegment.ts +++ b/ts/src/class/module/ElementSegment.ts @@ -1,10 +1,10 @@ import { BinaryenObj, UTF8ToString, -} from "../-pre.ts"; +} from "../../-pre.ts"; import type { ElementSegmentRef, -} from "../constants.ts"; +} from "../../constants.ts"; diff --git a/ts/src/class/Export.ts b/ts/src/class/module/Export.ts similarity index 89% rename from ts/src/class/Export.ts rename to ts/src/class/module/Export.ts index 029522feefc..ebffd250211 100644 --- a/ts/src/class/Export.ts +++ b/ts/src/class/module/Export.ts @@ -1,11 +1,11 @@ import { BinaryenObj, UTF8ToString, -} from "../-pre.ts"; +} from "../../-pre.ts"; import type { ExportRef, ExternalKind, -} from "../constants.ts"; +} from "../../constants.ts"; diff --git a/ts/src/class/Function.ts b/ts/src/class/module/Function.ts similarity index 97% rename from ts/src/class/Function.ts rename to ts/src/class/module/Function.ts index 8fba46b03bd..a4f6d224466 100644 --- a/ts/src/class/Function.ts +++ b/ts/src/class/module/Function.ts @@ -1,21 +1,21 @@ import { BinaryenObj, UTF8ToString, -} from "../-pre.ts"; +} from "../../-pre.ts"; import type { ExpressionRef, FunctionRef, Type, -} from "../constants.ts"; +} from "../../constants.ts"; import { replacedBy, -} from "../lib.ts"; +} from "../../lib.ts"; import { THIS_PTR, getAllNested, preserveStack, strToStack, -} from "../utils.ts"; +} from "../../utils.ts"; diff --git a/ts/src/class/Global.ts b/ts/src/class/module/Global.ts similarity index 93% rename from ts/src/class/Global.ts rename to ts/src/class/module/Global.ts index ba40e6a222c..626e7f2ff44 100644 --- a/ts/src/class/Global.ts +++ b/ts/src/class/module/Global.ts @@ -1,12 +1,12 @@ import { BinaryenObj, UTF8ToString, -} from "../-pre.ts"; +} from "../../-pre.ts"; import type { ExpressionRef, GlobalRef, Type, -} from "../constants.ts"; +} from "../../constants.ts"; diff --git a/ts/src/class/Module.ts b/ts/src/class/module/Module.ts similarity index 97% rename from ts/src/class/Module.ts rename to ts/src/class/module/Module.ts index 8d17dea4f99..043e2ce5f54 100644 --- a/ts/src/class/Module.ts +++ b/ts/src/class/module/Module.ts @@ -2,7 +2,17 @@ import { _free, BinaryenObj, UTF8ToString, -} from "../-pre.ts"; +} from "../../-pre.ts"; +import { + block, +} from "../expression/Block.ts"; +import { + localGet, +} from "../expression/LocalGet.ts"; +import { + localSet, + localTee, +} from "../expression/LocalSet.ts"; import { ElementSegment, } from "./ElementSegment.ts"; @@ -21,16 +31,6 @@ import { import { Tag, } from "./Tag.ts"; -import { - block, -} from "./expression/Block.ts"; -import { - localGet, -} from "./expression/LocalGet.ts"; -import { - localSet, - localTee, -} from "./expression/LocalSet.ts"; diff --git a/ts/src/class/Table.ts b/ts/src/class/module/Table.ts similarity index 97% rename from ts/src/class/Table.ts rename to ts/src/class/module/Table.ts index ccf70d97c04..513a7c025b2 100644 --- a/ts/src/class/Table.ts +++ b/ts/src/class/module/Table.ts @@ -1,19 +1,19 @@ import { BinaryenObj, UTF8ToString, -} from "../-pre.ts"; +} from "../../-pre.ts"; import type { TableRef, Type, -} from "../constants.ts"; +} from "../../constants.ts"; import { replacedBy, -} from "../lib.ts"; +} from "../../lib.ts"; import { THIS_PTR, preserveStack, strToStack, -} from "../utils.ts"; +} from "../../utils.ts"; diff --git a/ts/src/class/Tag.ts b/ts/src/class/module/Tag.ts similarity index 91% rename from ts/src/class/Tag.ts rename to ts/src/class/module/Tag.ts index 2253d499cad..afa60527099 100644 --- a/ts/src/class/Tag.ts +++ b/ts/src/class/module/Tag.ts @@ -1,11 +1,11 @@ import { BinaryenObj, UTF8ToString, -} from "../-pre.ts"; +} from "../../-pre.ts"; import type { TagRef, Type, -} from "../constants.ts"; +} from "../../constants.ts"; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 6198a6d3086..e374b81b2b1 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -15,7 +15,7 @@ import { import { type Feature, Module, -} from "./class/Module.ts"; +} from "./class/module/Module.ts"; import { Expression, } from "./class/expression/Expression.ts"; From 458d4e07de8d3fceb62ffd05b62fda8a0f56e784 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:11:12 -0400 Subject: [PATCH 036/247] feat: add DataSegment & Memory classes --- ts/src/class/module/DataSegment.ts | 42 ++++++++++++++++++++++++++++++ ts/src/class/module/Memory.ts | 33 +++++++++++++++++++++++ ts/src/class/module/Module.ts | 19 ++++++++++++-- ts/src/constants.ts | 1 + 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 ts/src/class/module/DataSegment.ts create mode 100644 ts/src/class/module/Memory.ts diff --git a/ts/src/class/module/DataSegment.ts b/ts/src/class/module/DataSegment.ts new file mode 100644 index 00000000000..bb2e76ccb27 --- /dev/null +++ b/ts/src/class/module/DataSegment.ts @@ -0,0 +1,42 @@ +import { + _free, + _malloc, + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import type { + DataSegmentRef, +} from "../../constants.ts"; +import { + HEAP8, +} from "../../utils.ts"; +import type { + Module, +} from "./Module.ts"; + + + +export class DataSegment { + readonly name: string; + readonly offset?: number; + readonly data: ArrayBuffer; + readonly passive: boolean; + + + constructor(mod: Module, segment: DataSegmentRef) { + this.name = UTF8ToString(BinaryenObj["_BinaryenDataSegmentGetName"](segment)); + this.passive = Boolean(BinaryenObj["_BinaryenGetDataSegmentPassive"](segment)); + if (!this.passive) { + this.offset = BinaryenObj["_BinaryenGetDataSegmentByteOffset"](mod.ptr, segment); + } + + const size = BinaryenObj["_BinaryenGetDataSegmentByteLength"](segment); + const ptr = _malloc(size); + BinaryenObj["_BinaryenCopyDataSegmentData"](segment, ptr); + const res = new Uint8Array(size); + res.set(HEAP8.subarray(ptr, ptr + size)); + _free(ptr); + + this.data = res.buffer; + } +} diff --git a/ts/src/class/module/Memory.ts b/ts/src/class/module/Memory.ts new file mode 100644 index 00000000000..a2faeb01aec --- /dev/null +++ b/ts/src/class/module/Memory.ts @@ -0,0 +1,33 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + strToStack, +} from "../../utils.ts"; +import type { + Module, +} from "./Module.ts"; + + + +export class Memory { + readonly module: string; + readonly base: string; + readonly initial: number; + readonly shared: boolean; + readonly is64: boolean; + readonly max?: number; + + + constructor(mod: Module, name: string) { + this.module = UTF8ToString(BinaryenObj["_BinaryenMemoryImportGetModule"](mod.ptr, strToStack(name))); + this.base = UTF8ToString(BinaryenObj["_BinaryenMemoryImportGetBase"](mod.ptr, strToStack(name))); + this.initial = BinaryenObj["_BinaryenMemoryGetInitial"](mod.ptr, strToStack(name)); + this.shared = Boolean(BinaryenObj["_BinaryenMemoryIsShared"](mod.ptr, strToStack(name))); + this.is64 = Boolean(BinaryenObj["_BinaryenMemoryIs64"](mod.ptr, strToStack(name))); + if (BinaryenObj["_BinaryenMemoryHasMax"](mod.ptr, strToStack(name))) { + this.max = BinaryenObj["_BinaryenMemoryGetMax"](mod.ptr, strToStack(name)); + } + } +} diff --git a/ts/src/class/module/Module.ts b/ts/src/class/module/Module.ts index 043e2ce5f54..dd0586ec21d 100644 --- a/ts/src/class/module/Module.ts +++ b/ts/src/class/module/Module.ts @@ -3,6 +3,9 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; +import type { + DataSegmentRef, +} from "../../constants.ts"; import { block, } from "../expression/Block.ts"; @@ -13,6 +16,9 @@ import { localSet, localTee, } from "../expression/LocalSet.ts"; +import { + DataSegment, +} from "./DataSegment.ts"; import { ElementSegment, } from "./ElementSegment.ts"; @@ -25,6 +31,9 @@ import { import { Global, } from "./Global.ts"; +import { + Memory, +} from "./Memory.ts"; import { Table, } from "./Table.ts"; @@ -82,8 +91,10 @@ export const Features = Feature; export class Module { static Tag = Tag; static Global = Global; + static Memory = Memory; static Table = Table; static Function = BinaryenFunction; + static DataSegment = DataSegment; static ElementSegment = ElementSegment; static Export = Export; @@ -131,7 +142,9 @@ export class Module { hasMemory() {} - getMemoryInfo() {} + getMemoryInfo(name: string): Memory { + return new Memory(this, name); + } // ### Tables ### // // TODO: move these to the Table class @@ -166,7 +179,9 @@ export class Module { getDataSegmentByIndex() {} - getDataSegmentInfo() {} + getDataSegmentInfo(segment: DataSegmentRef): DataSegment { + return new DataSegment(this, segment); + } // ### Element Segments ### // // TODO: move these to the ElementSegment class diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 32b91eb0360..f8ab363b386 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -21,6 +21,7 @@ export type TagRef = number; export type GlobalRef = number; export type TableRef = number; export type FunctionRef = number; +export type DataSegmentRef = number; export type ElementSegmentRef = number; export type ExportRef = number; From 2b8ed7e093922e7d7d785f94a3740164fa358ca7 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 30 Apr 2026 19:09:53 -0400 Subject: [PATCH 037/247] feat: module component methods --- ts/src/class/module/Module.ts | 336 +++++++++++++++++++++++++++++----- 1 file changed, 288 insertions(+), 48 deletions(-) diff --git a/ts/src/class/module/Module.ts b/ts/src/class/module/Module.ts index dd0586ec21d..019f5718e73 100644 --- a/ts/src/class/module/Module.ts +++ b/ts/src/class/module/Module.ts @@ -1,11 +1,27 @@ import { _free, + _malloc, BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import type { - DataSegmentRef, +import { + type DataSegmentRef, + type ElementSegmentRef, + type ExportRef, + type ExpressionRef, + type FunctionRef, + type GlobalRef, + type TableRef, + type TagRef, + type Type, + funcref, } from "../../constants.ts"; +import { + HEAP8, + i32sToStack, + preserveStack, + strToStack, +} from "../../utils.ts"; import { block, } from "../expression/Block.ts"; @@ -43,6 +59,16 @@ import { +/** Similar to a `DataSegment` but with some minor differences. */ +interface MemorySegment { + name?: string; + offset: ExpressionRef; + data: Uint8Array; + passive: boolean; +} + + + /** * The size of a single literal in memory as used in Const creation, * which is a little different: we don’t want users to need to make @@ -119,28 +145,93 @@ export class Module { // ### Tags ### // // TODO: move these to the Tag class - addTag() {} + addTag(name: string, params: Type, results: Type): TagRef { + return preserveStack(() => BinaryenObj["_BinaryenAddTag"](this.ptr, strToStack(name), params, results)); + } - getTag() {} + getTag(name: string): TagRef { + return preserveStack(() => BinaryenObj["_BinaryenGetTag"](this.ptr, strToStack(name))); + } - removeTag() {} + removeTag(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveTag"](this.ptr, strToStack(name)); + }); + } // ### Globals ### // // TODO: move these to the Global class - addGlobal() {} + addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef): GlobalRef { + return preserveStack(() => BinaryenObj["_BinaryenAddGlobal"](this.ptr, strToStack(name), type, mutable, init)); + } - getGlobal() {} + getGlobal(name: string): GlobalRef { + return preserveStack(() => BinaryenObj["_BinaryenGetGlobal"](this.ptr, strToStack(name))); + } - getGlobalByIndex() {} + getGlobalByIndex(index: number): GlobalRef { + return BinaryenObj["_BinaryenGetGlobalByIndex"](this.ptr, index); + } - getNumGlobals() {} + getNumGlobals(): number { + return BinaryenObj["_BinaryenGetNumGlobals"](this.ptr); + } - removeGlobal() {} + removeGlobal(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveGlobal"](this.ptr, strToStack(name)); + }); + } // ### Memories ### // - setMemory() {} + setMemory( + initial: number, + maximum: number, + exportName: string, + segments: readonly MemorySegment[] = [], + shared: boolean = false, + memory64: boolean = false, + internalName?: string, + ): void { + return preserveStack(() => { + const names: number[] = []; + const datas: number[] = []; + const passives: number[] = []; + const offsets: number[] = []; + const lengths: number[] = []; + for (let i = 0; i < segments.length; i++) { + const {name, data, passive, offset} = segments[i]; + names[i] = strToStack(name); + datas[i] = _malloc(data.length); + passives[i] = Number(passive); + offsets[i] = offset; + HEAP8.set(data, datas[i]); + lengths[i] = data.length; + } + BinaryenObj["_BinaryenSetMemory"]( + this.ptr, + initial, + maximum, + strToStack(exportName), + i32sToStack(names), + i32sToStack(datas), + i32sToStack(passives), + i32sToStack(offsets), + i32sToStack(lengths), + segments.length, + shared, + memory64, + strToStack(internalName), + ); + for (const dataptr of datas) { + _free(dataptr); + } + }); + } - hasMemory() {} + hasMemory(): boolean { + return Boolean(BinaryenObj["_BinaryenHasMemory"](this.ptr)); + } getMemoryInfo(name: string): Memory { return new Memory(this, name); @@ -148,36 +239,86 @@ export class Module { // ### Tables ### // // TODO: move these to the Table class - addTable() {} + addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef): TableRef { + return preserveStack(() => BinaryenObj["_BinaryenAddTable"](this.ptr, strToStack(name), initial, maximum, type, init ?? 0)); + } - getTable() {} + getTable(name: string): TableRef { + return preserveStack(() => BinaryenObj["_BinaryenGetTable"](this.ptr, strToStack(name))); + } - getTableByIndex() {} + getTableByIndex(index: number): TableRef { + return BinaryenObj["_BinaryenGetTableByIndex"](this.ptr, index); + } - getNumTables() {} + getNumTables(): number { + return BinaryenObj["_BinaryenGetNumTables"](this.ptr); + } - getTableSegments() {} + getTableSegments(table: TableRef): ElementSegmentRef[] { + const numElementSegments = BinaryenObj["_BinaryenGetNumElementSegments"](this.ptr); + const tableName = UTF8ToString(BinaryenObj["_BinaryenTableGetName"](table)); + const ret = []; + for (let i = 0; i < numElementSegments; i++) { + const segment = BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.ptr, i); + const elemTableName = UTF8ToString(BinaryenObj["_BinaryenElementSegmentGetTable"](segment)); + if (tableName === elemTableName) { + ret.push(segment); + } + } + return ret; + } - removeTable() {} + removeTable(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveTable"](this.ptr, strToStack(name)); + }); + } // ### Functions ### // // TODO: move these to the Function class - addFunction() {} + addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef): FunctionRef { + return preserveStack(() => BinaryenObj["_BinaryenAddFunction"]( + this.ptr, + strToStack(name), + params, + results, + i32sToStack(varTypes), + varTypes.length, + body, + )); + } - getFunction() {} + getFunction(name: string): FunctionRef { + return preserveStack(() => BinaryenObj["_BinaryenGetFunction"](this.ptr, strToStack(name))); + } - removeFunction() {} + removeFunction(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveFunction"](this.ptr, strToStack(name)); + }); + } - getNumFunctions() {} + getNumFunctions(): number { + return BinaryenObj["_BinaryenGetNumFunctions"](this.ptr); + } - getFunctionByIndex() {} + getFunctionByIndex(index: number): FunctionRef { + return BinaryenObj["_BinaryenGetFunctionByIndex"](this.ptr, index); + } // ### Data Segments ### // - getNumDataSegments() {} + getDataSegment(name: string): DataSegmentRef { + return preserveStack(() => BinaryenObj["_BinaryenGetDataSegment"](this.ptr, strToStack(name))); + } - getDataSegment() {} + getDataSegmentByIndex(index: number): DataSegmentRef { + return BinaryenObj["_BinaryenGetDataSegmentByIndex"](this.ptr, index); + } - getDataSegmentByIndex() {} + getNumDataSegments(): number { + return BinaryenObj["_BinaryenGetNumDataSegments"](this.ptr); + } getDataSegmentInfo(segment: DataSegmentRef): DataSegment { return new DataSegment(this, segment); @@ -185,51 +326,150 @@ export class Module { // ### Element Segments ### // // TODO: move these to the ElementSegment class - addActiveElementSegment() {} + addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef): ElementSegmentRef { + return preserveStack(() => BinaryenObj["_BinaryenAddActiveElementSegment"]( + this.ptr, + strToStack(table), + strToStack(name), + i32sToStack(funcNames.map(strToStack)), + funcNames.length, + offset, + )); + } - addPassiveElementSegment() {} + addPassiveElementSegment(name: string, funcNames: readonly string[]): ElementSegmentRef { + return preserveStack(() => BinaryenObj["_BinaryenAddPassiveElementSegment"]( + this.ptr, + strToStack(name), + i32sToStack(funcNames.map(strToStack)), + funcNames.length, + )); + } - getElementSegment() {} + getElementSegment(name: string): ElementSegmentRef { + return preserveStack(() => BinaryenObj["_BinaryenGetElementSegment"](this.ptr, strToStack(name))); + } - getElementSegmentByIndex() {} + getElementSegmentByIndex(index: number): ElementSegmentRef { + return BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.ptr, index); + } - getNumElementSegments() {} + getNumElementSegments(): number { + return BinaryenObj["_BinaryenGetNumElementSegments"](this.ptr); + } - removeElementSegment() {} + removeElementSegment(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveElementSegment"](this.ptr, strToStack(name)); + }); + } // ### Start Function ### // - getStart() {} + getStart(): FunctionRef { + return BinaryenObj["_BinaryenGetStart"](this.ptr); + } // ### Imports ### // - addTagImport() {} + addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddTagImport"]( + this.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + params, + results, + ); + }); + } - addGlobalImport() {} + addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddGlobalImport"]( + this.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + globalType, + mutable, + ); + }); + } - addMemoryImport() {} + addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddMemoryImport"]( + this.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + shared, + ); + }); + } - addTableImport() {} + addTableImport(internalName: string, externalModuleName: string, externalBaseName: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddTableImport"]( + this.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + ); + }); + } - addFunctionImport() {} + addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddFunctionImport"]( + this.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + params, + results, + ); + }); + } // ### Exports ### // - // TODO: move these to the Export class - addTagExport() {} + addTagExport(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddTagExport"](this.ptr, strToStack(internalName), strToStack(externalName))); + } - addGlobalExport() {} + addGlobalExport(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddGlobalExport"](this.ptr, strToStack(internalName), strToStack(externalName))); + } - addMemoryExport() {} + addMemoryExport(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddMemoryExport"](this.ptr, strToStack(internalName), strToStack(externalName))); + } - addTableExport() {} + addTableExport(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddTableExport"](this.ptr, strToStack(internalName), strToStack(externalName))); + } - addFunctionExport() {} + addFunctionExport(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddFunctionExport"](this.ptr, strToStack(internalName), strToStack(externalName))); + } - getExport() {} + getExport(externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenGetExport"](this.ptr, strToStack(externalName))); + } - getNumExports() {} + getNumExports(): number { + return BinaryenObj["_BinaryenGetNumExports"](this.ptr); + } - getExportByIndex() {} + getExportByIndex(index: number): ExportRef { + return BinaryenObj["_BinaryenGetExportByIndex"](this.ptr, index); + } - removeExport() {} + removeExport(externalName: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveExport"](this.ptr, strToStack(externalName)); + }); + } // ## Binaryen Operations ## // emitText(): string { From ba65b98bd65940a675230854d5ebe27c4b01a16b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 30 Apr 2026 21:30:39 -0400 Subject: [PATCH 038/247] refactor: move module component functions to mixins --- ts/src/class/module/DataSegment.ts | 20 ++ ts/src/class/module/ElementSegment.ts | 53 ++++ ts/src/class/module/Export.ts | 51 ++++ ts/src/class/module/Function.ts | 40 +++ ts/src/class/module/Global.ts | 35 +++ ts/src/class/module/Import.ts | 81 ++++++ ts/src/class/module/Module.ts | 346 ++++++-------------------- ts/src/class/module/Table.ts | 54 +++- ts/src/class/module/Tag.ts | 27 ++ 9 files changed, 432 insertions(+), 275 deletions(-) create mode 100644 ts/src/class/module/Import.ts diff --git a/ts/src/class/module/DataSegment.ts b/ts/src/class/module/DataSegment.ts index bb2e76ccb27..7bfbb5c10f9 100644 --- a/ts/src/class/module/DataSegment.ts +++ b/ts/src/class/module/DataSegment.ts @@ -9,6 +9,8 @@ import type { } from "../../constants.ts"; import { HEAP8, + preserveStack, + strToStack, } from "../../utils.ts"; import type { Module, @@ -40,3 +42,21 @@ export class DataSegment { this.data = res.buffer; } } + + + +export class ModuleDataSegments { + constructor(private readonly mod: Module) {} + + get(name: string): DataSegmentRef { + return preserveStack(() => BinaryenObj["_BinaryenGetDataSegment"](this.mod.ptr, strToStack(name))); + } + + getByIndex(index: number): DataSegmentRef { + return BinaryenObj["_BinaryenGetDataSegmentByIndex"](this.mod.ptr, index); + } + + count(): number { + return BinaryenObj["_BinaryenGetNumDataSegments"](this.mod.ptr); + } +} diff --git a/ts/src/class/module/ElementSegment.ts b/ts/src/class/module/ElementSegment.ts index cdec3ba0765..b82391955f4 100644 --- a/ts/src/class/module/ElementSegment.ts +++ b/ts/src/class/module/ElementSegment.ts @@ -3,8 +3,17 @@ import { UTF8ToString, } from "../../-pre.ts"; import type { + ExpressionRef, ElementSegmentRef, } from "../../constants.ts"; +import { + i32sToStack, + preserveStack, + strToStack, +} from "../../utils.ts"; +import type { + Module, +} from "./Module.ts"; @@ -29,3 +38,47 @@ export class ElementSegment { this.data = names; } } + + + +export class ModuleElementSegments { + constructor(private readonly mod: Module) {} + + addActive(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef): ElementSegmentRef { + return preserveStack(() => BinaryenObj["_BinaryenAddActiveElementSegment"]( + this.mod.ptr, + strToStack(table), + strToStack(name), + i32sToStack(funcNames.map(strToStack)), + funcNames.length, + offset, + )); + } + + addPassive(name: string, funcNames: readonly string[]): ElementSegmentRef { + return preserveStack(() => BinaryenObj["_BinaryenAddPassiveElementSegment"]( + this.mod.ptr, + strToStack(name), + i32sToStack(funcNames.map(strToStack)), + funcNames.length, + )); + } + + get(name: string): ElementSegmentRef { + return preserveStack(() => BinaryenObj["_BinaryenGetElementSegment"](this.mod.ptr, strToStack(name))); + } + + getByIndex(index: number): ElementSegmentRef { + return BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.mod.ptr, index); + } + + count(): number { + return BinaryenObj["_BinaryenGetNumElementSegments"](this.mod.ptr); + } + + remove(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveElementSegment"](this.mod.ptr, strToStack(name)); + }); + } +} diff --git a/ts/src/class/module/Export.ts b/ts/src/class/module/Export.ts index ebffd250211..1b117160022 100644 --- a/ts/src/class/module/Export.ts +++ b/ts/src/class/module/Export.ts @@ -6,6 +6,13 @@ import type { ExportRef, ExternalKind, } from "../../constants.ts"; +import { + preserveStack, + strToStack, +} from "../../utils.ts"; +import type { + Module, +} from "./Module.ts"; @@ -21,3 +28,47 @@ export class Export { this.value = UTF8ToString(BinaryenObj["_BinaryenExportGetValue"](xport)); } } + + + +export class ModuleExports { + constructor(private readonly mod: Module) {} + + addTag(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddTagExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + } + + addGlobal(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddGlobalExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + } + + addMemory(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddMemoryExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + } + + addTable(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddTableExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + } + + addFunction(internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenAddFunctionExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + } + + get(externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenGetExport"](this.mod.ptr, strToStack(externalName))); + } + + getByIndex(index: number): ExportRef { + return BinaryenObj["_BinaryenGetExportByIndex"](this.mod.ptr, index); + } + + count(): number { + return BinaryenObj["_BinaryenGetNumExports"](this.mod.ptr); + } + + remove(externalName: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveExport"](this.mod.ptr, strToStack(externalName)); + }); + } +} diff --git a/ts/src/class/module/Function.ts b/ts/src/class/module/Function.ts index a4f6d224466..9fbb07af3ac 100644 --- a/ts/src/class/module/Function.ts +++ b/ts/src/class/module/Function.ts @@ -13,9 +13,13 @@ import { import { THIS_PTR, getAllNested, + i32sToStack, preserveStack, strToStack, } from "../../utils.ts"; +import type { + Module, +} from "./Module.ts"; @@ -107,3 +111,39 @@ class BinaryenFunction { } } export {BinaryenFunction as Function}; + + + +export class ModuleFunctions { + constructor(private readonly mod: Module) {} + + add(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef): FunctionRef { + return preserveStack(() => BinaryenObj["_BinaryenAddFunction"]( + this.mod.ptr, + strToStack(name), + params, + results, + i32sToStack(varTypes), + varTypes.length, + body, + )); + } + + get(name: string): FunctionRef { + return preserveStack(() => BinaryenObj["_BinaryenGetFunction"](this.mod.ptr, strToStack(name))); + } + + getByIndex(index: number): FunctionRef { + return BinaryenObj["_BinaryenGetFunctionByIndex"](this.mod.ptr, index); + } + + count(): number { + return BinaryenObj["_BinaryenGetNumFunctions"](this.mod.ptr); + } + + remove(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveFunction"](this.mod.ptr, strToStack(name)); + }); + } +} diff --git a/ts/src/class/module/Global.ts b/ts/src/class/module/Global.ts index 626e7f2ff44..5cfbefea95a 100644 --- a/ts/src/class/module/Global.ts +++ b/ts/src/class/module/Global.ts @@ -7,6 +7,13 @@ import type { GlobalRef, Type, } from "../../constants.ts"; +import { + preserveStack, + strToStack, +} from "../../utils.ts"; +import type { + Module, +} from "./Module.ts"; @@ -28,3 +35,31 @@ export class Global { this.init = BinaryenObj["_BinaryenGlobalGetInitExpr"](global); } } + + + +export class ModuleGlobals { + constructor(private readonly mod: Module) {} + + add(name: string, type: Type, mutable: boolean, init: ExpressionRef): GlobalRef { + return preserveStack(() => BinaryenObj["_BinaryenAddGlobal"](this.mod.ptr, strToStack(name), type, mutable, init)); + } + + get(name: string): GlobalRef { + return preserveStack(() => BinaryenObj["_BinaryenGetGlobal"](this.mod.ptr, strToStack(name))); + } + + getByIndex(index: number): GlobalRef { + return BinaryenObj["_BinaryenGetGlobalByIndex"](this.mod.ptr, index); + } + + count(): number { + return BinaryenObj["_BinaryenGetNumGlobals"](this.mod.ptr); + } + + remove(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveGlobal"](this.mod.ptr, strToStack(name)); + }); + } +} diff --git a/ts/src/class/module/Import.ts b/ts/src/class/module/Import.ts new file mode 100644 index 00000000000..4b94371291e --- /dev/null +++ b/ts/src/class/module/Import.ts @@ -0,0 +1,81 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; +import type { + Type, +} from "../../constants.ts"; +import { + preserveStack, + strToStack, +} from "../../utils.ts"; +import type { + Module, +} from "./Module.ts"; + + + +export class ModuleImports { + constructor(private readonly mod: Module) {} + + addTag(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddTagImport"]( + this.mod.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + params, + results, + ); + }); + } + + addGlobal(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddGlobalImport"]( + this.mod.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + globalType, + mutable, + ); + }); + } + + addMemory(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddMemoryImport"]( + this.mod.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + shared, + ); + }); + } + + addTable(internalName: string, externalModuleName: string, externalBaseName: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddTableImport"]( + this.mod.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + ); + }); + } + + addFunction(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddFunctionImport"]( + this.mod.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + params, + results, + ); + }); + } +} diff --git a/ts/src/class/module/Module.ts b/ts/src/class/module/Module.ts index 019f5718e73..d28eaecfe07 100644 --- a/ts/src/class/module/Module.ts +++ b/ts/src/class/module/Module.ts @@ -6,16 +6,15 @@ import { } from "../../-pre.ts"; import { type DataSegmentRef, - type ElementSegmentRef, - type ExportRef, type ExpressionRef, type FunctionRef, - type GlobalRef, type TableRef, - type TagRef, type Type, funcref, } from "../../constants.ts"; +import { + replacedBy, +} from "../../lib.ts"; import { HEAP8, i32sToStack, @@ -34,27 +33,37 @@ import { } from "../expression/LocalSet.ts"; import { DataSegment, + ModuleDataSegments, } from "./DataSegment.ts"; import { ElementSegment, + ModuleElementSegments, } from "./ElementSegment.ts"; import { Export, + ModuleExports, } from "./Export.ts"; import { Function as BinaryenFunction, + ModuleFunctions, } from "./Function.ts"; import { Global, + ModuleGlobals, } from "./Global.ts"; +import { + ModuleImports, +} from "./Import.ts"; import { Memory, } from "./Memory.ts"; import { Table, + ModuleTables, } from "./Table.ts"; import { Tag, + ModuleTags, } from "./Tag.ts"; @@ -140,50 +149,69 @@ export class Module { }; } - // ## Module Operations ## // + // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html + tags = new ModuleTags(this); + globals = new ModuleGlobals(this); + tables = new ModuleTables(this); + functions = new ModuleFunctions(this); + dataSegments = new ModuleDataSegments(this); + elementSegments = new ModuleElementSegments(this); + imports = new ModuleImports(this); + exports = new ModuleExports(this); + + /* eslint-disable @stylistic/brace-style */ + /** @deprecated Use `this.tags.add` instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } + /** @deprecated Use `this.tags.get` instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } + /** @deprecated Use `this.tags.remove` instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } + + /** @deprecated Use `this.globals.add` instead. */ @replacedBy("`this.globals.add`") addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef) { return this.globals.add(name, type, mutable, init); } + /** @deprecated Use `this.globals.get` instead. */ @replacedBy("`this.globals.get`") getGlobal(name: string) { return this.globals.get(name); } + /** @deprecated Use `this.globals.getByIndex` instead. */ @replacedBy("`this.globals.getByIndex`") getGlobalByIndex(index: number) { return this.globals.getByIndex(index); } + /** @deprecated Use `this.globals.count` instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } + /** @deprecated Use `this.globals.remove` instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } + + /** @deprecated Use `this.tables.add` instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } + /** @deprecated Use `this.tables.get` instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } + /** @deprecated Use `this.tables.getByIndex` instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } + /** @deprecated Use `this.tables.getSegments` instead. */ @replacedBy("`this.tables.getSegments`") getTableSegments(table: TableRef) { return this.tables.getSegments(table); } + /** @deprecated Use `this.tables.count` instead. */ @replacedBy("`this.tables.count`") getNumTables() { return this.tables.count(); } + /** @deprecated Use `this.tables.remove` instead. */ @replacedBy("`this.tables.remove`") removeTable(name: string) { return this.tables.remove(name); } + + /** @deprecated Use `this.functions.add` instead. */ @replacedBy("`this.functions.add`") addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef) { return this.functions.add(name, params, results, varTypes, body); } + /** @deprecated Use `this.functions.get` instead. */ @replacedBy("`this.functions.get`") getFunction(name: string) { return this.functions.get(name); } + /** @deprecated Use `this.functions.getByIndex` instead. */ @replacedBy("`this.functions.getByIndex`") getFunctionByIndex(index: number) { return this.functions.getByIndex(index); } + /** @deprecated Use `this.functions.count` instead. */ @replacedBy("`this.functions.count`") getNumFunctions() { return this.functions.count(); } + /** @deprecated Use `this.functions.remove` instead. */ @replacedBy("`this.functions.remove`") removeFunction(name: string) { return this.functions.remove(name); } + + /** @deprecated Use `this.dataSegments.get` instead. */ @replacedBy("`this.dataSegments.get`") getDataSegment(name: string) { return this.dataSegments.get(name); } + /** @deprecated Use `this.dataSegments.getByIndex` instead. */ @replacedBy("`this.dataSegments.getByIndex`") getDataSegmentByIndex(index: number) { return this.dataSegments.getByIndex(index); } + /** @deprecated Use `this.dataSegments.count` instead. */ @replacedBy("`this.dataSegments.count`") getNumDataSegments() { return this.dataSegments.count(); } + + /** @deprecated Use `this.elementSegments.addActive` instead. */ @replacedBy("`this.elementSegments.addActive`") addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef) { return this.elementSegments.addActive(table, name, funcNames, offset); } + /** @deprecated Use `this.elementSegments.addPassive` instead. */ @replacedBy("`this.elementSegments.addPassive`") addPassiveElementSegment(name: string, funcNames: readonly string[]) { return this.elementSegments.addPassive(name, funcNames); } + /** @deprecated Use `this.elementSegments.get` instead. */ @replacedBy("`this.elementSegments.get`") getElementSegment(name: string) { return this.elementSegments.get(name); } + /** @deprecated Use `this.elementSegments.getByIndex` instead. */ @replacedBy("`this.elementSegments.getByIndex`") getElementSegmentByIndex(index: number) { return this.elementSegments.getByIndex(index); } + /** @deprecated Use `this.elementSegments.count` instead. */ @replacedBy("`this.elementSegments.count`") getNumElementSegments() { return this.elementSegments.count(); } + /** @deprecated Use `this.elementSegments.remove` instead. */ @replacedBy("`this.elementSegments.remove`") removeElementSegment(name: string) { return this.elementSegments.remove(name); } + + /** @deprecated Use `this.imports.addTag` instead. */ @replacedBy("`this.imports.addTag`") addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addTag(internalName, externalModuleName, externalBaseName, params, results); } + /** @deprecated Use `this.imports.addGlobal` instead. */ @replacedBy("`this.imports.addGlobal`") addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean) { return this.imports.addGlobal(internalName, externalModuleName, externalBaseName, globalType, mutable); } + /** @deprecated Use `this.imports.addMemory` instead. */ @replacedBy("`this.imports.addMemory`") addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean) { return this.imports.addMemory(internalName, externalModuleName, externalBaseName, shared); } + /** @deprecated Use `this.imports.addTable` instead. */ @replacedBy("`this.imports.addTable`") addTableImport(internalName: string, externalModuleName: string, externalBaseName: string) { return this.imports.addTable(internalName, externalModuleName, externalBaseName); } + /** @deprecated Use `this.imports.addFunction` instead. */ @replacedBy("`this.imports.addFunction`") addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addFunction(internalName, externalModuleName, externalBaseName, params, results); } + + /** @deprecated Use `this.exports.addTag` instead. */ @replacedBy("`this.exports.addTag`") addTagExport(internalName: string, externalName: string) { return this.exports.addTag(internalName, externalName); } + /** @deprecated Use `this.exports.addGlobal` instead. */ @replacedBy("`this.exports.addGlobal`") addGlobalExport(internalName: string, externalName: string) { return this.exports.addGlobal(internalName, externalName); } + /** @deprecated Use `this.exports.addMemory` instead. */ @replacedBy("`this.exports.addMemory`") addMemoryExport(internalName: string, externalName: string) { return this.exports.addMemory(internalName, externalName); } + /** @deprecated Use `this.exports.addTable` instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } + /** @deprecated Use `this.exports.addFunction` instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } + /** @deprecated Use `this.exports.get` instead. */ @replacedBy("`this.exports.get`") getExport(externalName: string) { return this.exports.get(externalName); } + /** @deprecated Use `this.exports.getByIndex` instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } + /** @deprecated Use `this.exports.count` instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } + /** @deprecated Use `this.exports.remove` instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } + /* eslint-enable @stylistic/brace-style */ - // ### Tags ### // - // TODO: move these to the Tag class - addTag(name: string, params: Type, results: Type): TagRef { - return preserveStack(() => BinaryenObj["_BinaryenAddTag"](this.ptr, strToStack(name), params, results)); - } - - getTag(name: string): TagRef { - return preserveStack(() => BinaryenObj["_BinaryenGetTag"](this.ptr, strToStack(name))); - } - - removeTag(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveTag"](this.ptr, strToStack(name)); - }); - } - - // ### Globals ### // - // TODO: move these to the Global class - addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef): GlobalRef { - return preserveStack(() => BinaryenObj["_BinaryenAddGlobal"](this.ptr, strToStack(name), type, mutable, init)); - } - - getGlobal(name: string): GlobalRef { - return preserveStack(() => BinaryenObj["_BinaryenGetGlobal"](this.ptr, strToStack(name))); - } - - getGlobalByIndex(index: number): GlobalRef { - return BinaryenObj["_BinaryenGetGlobalByIndex"](this.ptr, index); - } - - getNumGlobals(): number { - return BinaryenObj["_BinaryenGetNumGlobals"](this.ptr); - } - - removeGlobal(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveGlobal"](this.ptr, strToStack(name)); - }); - } - - // ### Memories ### // setMemory( initial: number, maximum: number, @@ -237,240 +265,14 @@ export class Module { return new Memory(this, name); } - // ### Tables ### // - // TODO: move these to the Table class - addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef): TableRef { - return preserveStack(() => BinaryenObj["_BinaryenAddTable"](this.ptr, strToStack(name), initial, maximum, type, init ?? 0)); - } - - getTable(name: string): TableRef { - return preserveStack(() => BinaryenObj["_BinaryenGetTable"](this.ptr, strToStack(name))); - } - - getTableByIndex(index: number): TableRef { - return BinaryenObj["_BinaryenGetTableByIndex"](this.ptr, index); - } - - getNumTables(): number { - return BinaryenObj["_BinaryenGetNumTables"](this.ptr); - } - - getTableSegments(table: TableRef): ElementSegmentRef[] { - const numElementSegments = BinaryenObj["_BinaryenGetNumElementSegments"](this.ptr); - const tableName = UTF8ToString(BinaryenObj["_BinaryenTableGetName"](table)); - const ret = []; - for (let i = 0; i < numElementSegments; i++) { - const segment = BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.ptr, i); - const elemTableName = UTF8ToString(BinaryenObj["_BinaryenElementSegmentGetTable"](segment)); - if (tableName === elemTableName) { - ret.push(segment); - } - } - return ret; - } - - removeTable(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveTable"](this.ptr, strToStack(name)); - }); - } - - // ### Functions ### // - // TODO: move these to the Function class - addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef): FunctionRef { - return preserveStack(() => BinaryenObj["_BinaryenAddFunction"]( - this.ptr, - strToStack(name), - params, - results, - i32sToStack(varTypes), - varTypes.length, - body, - )); - } - - getFunction(name: string): FunctionRef { - return preserveStack(() => BinaryenObj["_BinaryenGetFunction"](this.ptr, strToStack(name))); - } - - removeFunction(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveFunction"](this.ptr, strToStack(name)); - }); - } - - getNumFunctions(): number { - return BinaryenObj["_BinaryenGetNumFunctions"](this.ptr); - } - - getFunctionByIndex(index: number): FunctionRef { - return BinaryenObj["_BinaryenGetFunctionByIndex"](this.ptr, index); - } - - // ### Data Segments ### // - getDataSegment(name: string): DataSegmentRef { - return preserveStack(() => BinaryenObj["_BinaryenGetDataSegment"](this.ptr, strToStack(name))); - } - - getDataSegmentByIndex(index: number): DataSegmentRef { - return BinaryenObj["_BinaryenGetDataSegmentByIndex"](this.ptr, index); - } - - getNumDataSegments(): number { - return BinaryenObj["_BinaryenGetNumDataSegments"](this.ptr); - } - getDataSegmentInfo(segment: DataSegmentRef): DataSegment { return new DataSegment(this, segment); } - // ### Element Segments ### // - // TODO: move these to the ElementSegment class - addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef): ElementSegmentRef { - return preserveStack(() => BinaryenObj["_BinaryenAddActiveElementSegment"]( - this.ptr, - strToStack(table), - strToStack(name), - i32sToStack(funcNames.map(strToStack)), - funcNames.length, - offset, - )); - } - - addPassiveElementSegment(name: string, funcNames: readonly string[]): ElementSegmentRef { - return preserveStack(() => BinaryenObj["_BinaryenAddPassiveElementSegment"]( - this.ptr, - strToStack(name), - i32sToStack(funcNames.map(strToStack)), - funcNames.length, - )); - } - - getElementSegment(name: string): ElementSegmentRef { - return preserveStack(() => BinaryenObj["_BinaryenGetElementSegment"](this.ptr, strToStack(name))); - } - - getElementSegmentByIndex(index: number): ElementSegmentRef { - return BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.ptr, index); - } - - getNumElementSegments(): number { - return BinaryenObj["_BinaryenGetNumElementSegments"](this.ptr); - } - - removeElementSegment(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveElementSegment"](this.ptr, strToStack(name)); - }); - } - - // ### Start Function ### // getStart(): FunctionRef { return BinaryenObj["_BinaryenGetStart"](this.ptr); } - // ### Imports ### // - addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddTagImport"]( - this.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - params, - results, - ); - }); - } - - addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddGlobalImport"]( - this.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - globalType, - mutable, - ); - }); - } - - addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddMemoryImport"]( - this.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - shared, - ); - }); - } - - addTableImport(internalName: string, externalModuleName: string, externalBaseName: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddTableImport"]( - this.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - ); - }); - } - - addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddFunctionImport"]( - this.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - params, - results, - ); - }); - } - - // ### Exports ### // - addTagExport(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddTagExport"](this.ptr, strToStack(internalName), strToStack(externalName))); - } - - addGlobalExport(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddGlobalExport"](this.ptr, strToStack(internalName), strToStack(externalName))); - } - - addMemoryExport(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddMemoryExport"](this.ptr, strToStack(internalName), strToStack(externalName))); - } - - addTableExport(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddTableExport"](this.ptr, strToStack(internalName), strToStack(externalName))); - } - - addFunctionExport(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddFunctionExport"](this.ptr, strToStack(internalName), strToStack(externalName))); - } - - getExport(externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenGetExport"](this.ptr, strToStack(externalName))); - } - - getNumExports(): number { - return BinaryenObj["_BinaryenGetNumExports"](this.ptr); - } - - getExportByIndex(index: number): ExportRef { - return BinaryenObj["_BinaryenGetExportByIndex"](this.ptr, index); - } - - removeExport(externalName: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveExport"](this.ptr, strToStack(externalName)); - }); - } - // ## Binaryen Operations ## // emitText(): string { const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteText"](this.ptr); diff --git a/ts/src/class/module/Table.ts b/ts/src/class/module/Table.ts index 513a7c025b2..6a8b56a0fc7 100644 --- a/ts/src/class/module/Table.ts +++ b/ts/src/class/module/Table.ts @@ -2,9 +2,12 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import type { - TableRef, - Type, +import { + type ElementSegmentRef, + type ExpressionRef, + type TableRef, + type Type, + funcref, } from "../../constants.ts"; import { replacedBy, @@ -14,6 +17,9 @@ import { preserveStack, strToStack, } from "../../utils.ts"; +import type { + Module, +} from "./Module.ts"; @@ -114,3 +120,45 @@ export class Table { BinaryenObj["_BinaryenTableSetType"](this[THIS_PTR], tableType); } } + + + +export class ModuleTables { + constructor(private readonly mod: Module) {} + + add(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef): TableRef { + return preserveStack(() => BinaryenObj["_BinaryenAddTable"](this.mod.ptr, strToStack(name), initial, maximum, type, init ?? 0)); + } + + get(name: string): TableRef { + return preserveStack(() => BinaryenObj["_BinaryenGetTable"](this.mod.ptr, strToStack(name))); + } + + getByIndex(index: number): TableRef { + return BinaryenObj["_BinaryenGetTableByIndex"](this.mod.ptr, index); + } + + getSegments(table: TableRef): ElementSegmentRef[] { + const numElementSegments = BinaryenObj["_BinaryenGetNumElementSegments"](this.mod.ptr); + const tableName = UTF8ToString(BinaryenObj["_BinaryenTableGetName"](table)); + const ret = []; + for (let i = 0; i < numElementSegments; i++) { + const segment = BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.mod.ptr, i); + const elemTableName = UTF8ToString(BinaryenObj["_BinaryenElementSegmentGetTable"](segment)); + if (tableName === elemTableName) { + ret.push(segment); + } + } + return ret; + } + + count(): number { + return BinaryenObj["_BinaryenGetNumTables"](this.mod.ptr); + } + + remove(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveTable"](this.mod.ptr, strToStack(name)); + }); + } +} diff --git a/ts/src/class/module/Tag.ts b/ts/src/class/module/Tag.ts index afa60527099..738cfdef04e 100644 --- a/ts/src/class/module/Tag.ts +++ b/ts/src/class/module/Tag.ts @@ -6,6 +6,13 @@ import type { TagRef, Type, } from "../../constants.ts"; +import { + preserveStack, + strToStack, +} from "../../utils.ts"; +import type { + Module, +} from "./Module.ts"; @@ -25,3 +32,23 @@ export class Tag { this.results = BinaryenObj["_BinaryenTagGetResults"](tag); } } + + + +export class ModuleTags { + constructor(private readonly mod: Module) {} + + add(name: string, params: Type, results: Type): TagRef { + return preserveStack(() => BinaryenObj["_BinaryenAddTag"](this.mod.ptr, strToStack(name), params, results)); + } + + get(name: string): TagRef { + return preserveStack(() => BinaryenObj["_BinaryenGetTag"](this.mod.ptr, strToStack(name))); + } + + remove(name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveTag"](this.mod.ptr, strToStack(name)); + }); + } +} From 9d782a73cceace8ffe4a228ebe11f14428969177 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 30 Apr 2026 21:41:31 -0400 Subject: [PATCH 039/247] refactor: Imports/Exports methods --- ts/src/class/module/Export.ts | 14 ++++++---- ts/src/class/module/Import.ts | 52 ++++++++--------------------------- 2 files changed, 20 insertions(+), 46 deletions(-) diff --git a/ts/src/class/module/Export.ts b/ts/src/class/module/Export.ts index 1b117160022..7853ea0db3e 100644 --- a/ts/src/class/module/Export.ts +++ b/ts/src/class/module/Export.ts @@ -34,24 +34,28 @@ export class Export { export class ModuleExports { constructor(private readonly mod: Module) {} + #addComponent(binaryenFuncName: string, internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj[binaryenFuncName](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + } + addTag(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddTagExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + return this.#addComponent("_BinaryenAddTagExport", internalName, externalName); } addGlobal(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddGlobalExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + return this.#addComponent("_BinaryenAddGlobalExport", internalName, externalName); } addMemory(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddMemoryExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + return this.#addComponent("_BinaryenAddMemoryExport", internalName, externalName); } addTable(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddTableExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + return this.#addComponent("_BinaryenAddTableExport", internalName, externalName); } addFunction(internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenAddFunctionExport"](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + return this.#addComponent("_BinaryenAddFunctionExport", internalName, externalName); } get(externalName: string): ExportRef { diff --git a/ts/src/class/module/Import.ts b/ts/src/class/module/Import.ts index 4b94371291e..e698e1e987e 100644 --- a/ts/src/class/module/Import.ts +++ b/ts/src/class/module/Import.ts @@ -17,65 +17,35 @@ import type { export class ModuleImports { constructor(private readonly mod: Module) {} - addTag(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { + #addComponent(binaryenFuncName: string, internalName: string, externalModuleName: string, externalBaseName: string, ...rest: any[]): void { return preserveStack(() => { - BinaryenObj["_BinaryenAddTagImport"]( + BinaryenObj[binaryenFuncName]( this.mod.ptr, strToStack(internalName), strToStack(externalModuleName), strToStack(externalBaseName), - params, - results, + ...rest, ); }); } + addTag(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { + return this.#addComponent("_BinaryenAddTagImport", internalName, externalModuleName, externalBaseName, params, results); + } + addGlobal(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddGlobalImport"]( - this.mod.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - globalType, - mutable, - ); - }); + return this.#addComponent("_BinaryenAddGlobalImport", internalName, externalModuleName, externalBaseName, globalType, mutable); } addMemory(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddMemoryImport"]( - this.mod.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - shared, - ); - }); + return this.#addComponent("_BinaryenAddMemoryImport", internalName, externalModuleName, externalBaseName, shared); } addTable(internalName: string, externalModuleName: string, externalBaseName: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddTableImport"]( - this.mod.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - ); - }); + return this.#addComponent("_BinaryenAddTableImport", internalName, externalModuleName, externalBaseName); } addFunction(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddFunctionImport"]( - this.mod.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - params, - results, - ); - }); + return this.#addComponent("_BinaryenAddFunctionImport", internalName, externalModuleName, externalBaseName, params, results); } } From 1e40dd43ac5d4d1e396d443c1484eeb766ebe0dd Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 30 Apr 2026 22:01:01 -0400 Subject: [PATCH 040/247] build: update lint rules --- ts/eslint.config.js | 6 +++ ts/package.json | 2 +- ts/src/-pre.ts | 2 +- ts/src/binaryen.ts | 10 ++-- ts/src/class/expression/Expression.ts | 4 +- ts/src/class/expression/index.ts | 2 + ts/src/class/module/Function.ts | 2 +- ts/src/class/module/Table.ts | 2 +- ts/src/constants.ts | 2 +- ts/src/globals.ts | 72 +++++++++++++-------------- ts/src/lib.ts | 1 + ts/tsconfig.json | 10 ++-- 12 files changed, 62 insertions(+), 53 deletions(-) diff --git a/ts/eslint.config.js b/ts/eslint.config.js index b8995c9453f..78aba9f151f 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -129,8 +129,13 @@ export default [ rules: { /* # Layout & Formatting */ /* ## Operator Style */ + "@typescript-eslint/array-type": ["error", { + default: "array-simple", + readonly: "array", + }], "dot-notation": "off", "@typescript-eslint/dot-notation": "error", + "@typescript-eslint/no-unnecessary-condition": "error", /* # Best Practices */ /* ## Variable Declarations */ @@ -157,6 +162,7 @@ export default [ /* ## Strictness */ "@typescript-eslint/explicit-member-accessibility": ["error", {accessibility: "no-public"}], "@typescript-eslint/no-deprecated": "warn", + "@typescript-eslint/prefer-readonly": "error", }, }, ]; diff --git a/ts/package.json b/ts/package.json index b63813efa5b..5f1c06de865 100644 --- a/ts/package.json +++ b/ts/package.json @@ -16,7 +16,7 @@ "type": "module", "main": "./dist/binaryen.js", "scripts": { - "compile": "tsc", + "compile": "rm -r ./dist/ && tsc", "lint": "eslint ./", "build": "npm run compile && npm run lint" }, diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index 3a72c8d8b26..6e30b085ff6 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -16,4 +16,4 @@ export declare function stackAlloc(length: number): number; export declare function stringToUTF8OnStack(str: string): number; export declare function UTF8ToString(n: number): string; export declare function stringToAscii(text: string, buffer: number): void; -export declare function getExceptionMessage(e: number | Error): [unknown, string]; +export declare function getExceptionMessage(e: number | Error): [string, string]; // https://emscripten.org/docs/porting/exceptions.html#handling-c-exceptions-from-javascript diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 2a48e0e876e..c20b9738fc9 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1,14 +1,14 @@ export * from "./constants.ts"; export * from "./globals.ts"; -export { - ExpressionRunner, - ExpressionRunnerFlag, -} from "./class/ExpressionRunner.ts"; export { Feature, Module, } from "./class/module/Module.ts"; -export {Relooper} from "./class/Relooper.ts"; export {TypeBuilder} from "./class/TypeBuilder.ts"; +export { + ExpressionRunner, + ExpressionRunnerFlag, +} from "./class/ExpressionRunner.ts"; +export {Relooper} from "./class/Relooper.ts"; export * from "./class/expression/index.ts"; export * from "./-deprecations.ts"; diff --git a/ts/src/class/expression/Expression.ts b/ts/src/class/expression/Expression.ts index 1964bd1f0fa..acea1804bfe 100644 --- a/ts/src/class/expression/Expression.ts +++ b/ts/src/class/expression/Expression.ts @@ -26,7 +26,7 @@ export class Expression { /** @deprecated */ @replacedBy("`instance.getType`") static getType(expr: ExpressionRef) { return Expression.prototype.getType.call({[THIS_PTR]: expr}); } /** @deprecated */ @replacedBy("`instance.setType`") static setType(expr: ExpressionRef, typ: Type) { return Expression.prototype.setType.call({[THIS_PTR]: expr}, typ); } /** @deprecated */ @replacedBy("`instance.finalize`") static finalize(expr: ExpressionRef) { return Expression.prototype.finalize.call({[THIS_PTR]: expr}); } - /** @deprecated */ @replacedBy("`instance.toText`") static toText(expr: ExpressionRef): string { return Expression.prototype.toText.call({[THIS_PTR]: expr}); } + /** @deprecated */ @replacedBy("`instance.toText`") static toText(expr: ExpressionRef) { return Expression.prototype.toText.call({[THIS_PTR]: expr}); } /* eslint-enable @stylistic/brace-style */ @@ -48,7 +48,7 @@ export class Expression { this.#id = exprId; } - valueOf() { + valueOf(): ExpressionRef { return this[THIS_PTR]; } diff --git a/ts/src/class/expression/index.ts b/ts/src/class/expression/index.ts index 1b6bc7fedc3..4b29792653a 100644 --- a/ts/src/class/expression/index.ts +++ b/ts/src/class/expression/index.ts @@ -1,3 +1,5 @@ +export {Expression} from "./Expression.ts"; + // ## Control ## // export {Block} from "./Block.ts"; diff --git a/ts/src/class/module/Function.ts b/ts/src/class/module/Function.ts index 9fbb07af3ac..c089c1501fe 100644 --- a/ts/src/class/module/Function.ts +++ b/ts/src/class/module/Function.ts @@ -55,7 +55,7 @@ class BinaryenFunction { } - valueOf() { + valueOf(): FunctionRef { return this[THIS_PTR]; } diff --git a/ts/src/class/module/Table.ts b/ts/src/class/module/Table.ts index 6a8b56a0fc7..7168d46e835 100644 --- a/ts/src/class/module/Table.ts +++ b/ts/src/class/module/Table.ts @@ -50,7 +50,7 @@ export class Table { } - valueOf() { + valueOf(): TableRef { return this[THIS_PTR]; } diff --git a/ts/src/constants.ts b/ts/src/constants.ts index f8ab363b386..f0188be5bde 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -26,9 +26,9 @@ export type ElementSegmentRef = number; export type ExportRef = number; // ### Binaryen Tools ### // +export type TypeBuilderRef = number; export type ExpressionRunnerRef = number; export type RelooperBlockRef = number; -export type TypeBuilderRef = number; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index e374b81b2b1..8c7d40e40f2 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -62,7 +62,7 @@ function handleFatalError(func: () => T): T { if (typeof e === "number") { // Older version of emscripten can throw C++ exceptions as pointers (numbers) in release builds. const [_, message] = getExceptionMessage(e); - if (message?.startsWith("Fatal: ")) { + if (message.startsWith("Fatal: ")) { // eslint-disable-next-line preserve-caught-error throw new Error(message.substr(7).trim()); } @@ -107,7 +107,7 @@ export function readBinary(data: Uint8Array): Module { return wrapModule(ptr); } -export function readBinaryWithFeatures(data: Uint8Array, features: Feature) { +export function readBinaryWithFeatures(data: Uint8Array, features: Feature): Module { const buffer = _malloc(data.length); HEAP8.set(data, buffer); const ptr = handleFatalError(() => BinaryenObj["_BinaryenModuleReadWithFeatures"](buffer, data.length, features)); @@ -205,42 +205,42 @@ export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { /** Gets the currently set optimize level. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ export function getOptimizeLevel(): number { return BinaryenObj["_BinaryenGetOptimizeLevel"](); -}; +} /** Sets the optimization level to use. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ export function setOptimizeLevel(level: number): void { BinaryenObj["_BinaryenSetOptimizeLevel"](level); -}; +} /** Gets the currently set shrink level. 0, 1, 2 correspond to -O0, -Os, -Oz. */ export function getShrinkLevel(): number { return BinaryenObj["_BinaryenGetShrinkLevel"](); -}; +} /** Sets the shrink level to use. 0, 1, 2 correspond to -O0, -Os, -Oz. */ export function setShrinkLevel(level: number): void { BinaryenObj["_BinaryenSetShrinkLevel"](level); -}; +} /** Gets whether generating debug information is currently enabled or not. */ export function getDebugInfo(): boolean { return Boolean(BinaryenObj["_BinaryenGetDebugInfo"]()); -}; +} /** Enables or disables debug information in emitted binaries. */ export function setDebugInfo(on: boolean) { BinaryenObj["_BinaryenSetDebugInfo"](on); -}; +} /** Gets whether no traps can be considered reached at runtime when optimizing. */ export function getTrapsNeverHappen(): boolean { return Boolean(BinaryenObj["_BinaryenGetTrapsNeverHappen"]()); -}; +} /** Enables or disables whether no traps can be considered reached at runtime when optimizing. */ export function setTrapsNeverHappen(on: boolean) { BinaryenObj["_BinaryenSetTrapsNeverHappen"](on); -}; +} /** * Gets whether considering that the code outside of the module does @@ -248,7 +248,7 @@ export function setTrapsNeverHappen(on: boolean) { */ export function getClosedWorld(): boolean { return Boolean(BinaryenObj["_BinaryenGetClosedWorld"]()); -}; +} /** * Enables or disables whether considering that the code outside of @@ -256,27 +256,27 @@ export function getClosedWorld(): boolean { */ export function setClosedWorld(on: boolean) { BinaryenObj["_BinaryenSetClosedWorld"](on); -}; +} /** Gets whether the low 1K of memory can be considered unused when optimizing. */ export function getLowMemoryUnused(): boolean { return Boolean(BinaryenObj["_BinaryenGetLowMemoryUnused"]()); -}; +} /** Enables or disables whether the low 1K of memory can be considered unused when optimizing. */ export function setLowMemoryUnused(on: boolean) { BinaryenObj["_BinaryenSetLowMemoryUnused"](on); -}; +} /** Gets whether that an imported memory will be zero-initialized speculation. */ export function getZeroFilledMemory(): boolean { return Boolean(BinaryenObj["_BinaryenGetZeroFilledMemory"]()); -}; +} /** Enables or disables whether that an imported memory will be zero-initialized speculation. */ export function setZeroFilledMemory(on: boolean) { BinaryenObj["_BinaryenSetZeroFilledMemory"](on); -}; +} /** * Gets whether fast math optimizations are enabled, ignoring for example @@ -284,7 +284,7 @@ export function setZeroFilledMemory(on: boolean) { */ export function getFastMath(): boolean { return Boolean(BinaryenObj["_BinaryenGetFastMath"]()); -}; +} /** * Enables or disables fast math optimizations, ignoring for example @@ -292,67 +292,67 @@ export function getFastMath(): boolean { */ export function setFastMath(on: boolean) { BinaryenObj["_BinaryenSetFastMath"](on); -}; +} /** Gets whether to generate StackIR during binary writing. */ export function getGenerateStackIR(): boolean { return Boolean(BinaryenObj["_BinaryenGetGenerateStackIR"]()); -}; +} /** Enable or disable StackIR generation during binary writing. */ export function setGenerateStackIR(on: boolean) { BinaryenObj["_BinaryenSetGenerateStackIR"](on); -}; +} /** Gets whether to optimize StackIR during binary writing. */ export function getOptimizeStackIR(): boolean { return Boolean(BinaryenObj["_BinaryenGetOptimizeStackIR"]()); -}; +} /** Enable or disable StackIR optimisation during binary writing. */ export function setOptimizeStackIR(on: boolean) { BinaryenObj["_BinaryenSetOptimizeStackIR"](on); -}; +} /** Gets the function size at which we always inline. */ export function getAlwaysInlineMaxSize(): number { return BinaryenObj["_BinaryenGetAlwaysInlineMaxSize"](); -}; +} /** Sets the function size at which we always inline. */ export function setAlwaysInlineMaxSize(size: number) { BinaryenObj["_BinaryenSetAlwaysInlineMaxSize"](size); -}; +} /** Gets the function size which we inline when functions are lightweight. */ export function getFlexibleInlineMaxSize(): number { return BinaryenObj["_BinaryenGetFlexibleInlineMaxSize"](); -}; +} /** Sets the function size which we inline when functions are lightweight. */ export function setFlexibleInlineMaxSize(size: number) { BinaryenObj["_BinaryenSetFlexibleInlineMaxSize"](size); -}; +} /** Gets the function size which we inline when there is only one caller. */ export function getOneCallerInlineMaxSize(): number { return BinaryenObj["_BinaryenGetOneCallerInlineMaxSize"](); -}; +} /** Sets the function size which we inline when there is only one caller. */ export function setOneCallerInlineMaxSize(size: number) { BinaryenObj["_BinaryenSetOneCallerInlineMaxSize"](size); -}; +} /** Gets whether functions with loops are allowed to be inlined. */ export function getAllowInliningFunctionsWithLoops(): boolean { return Boolean(BinaryenObj["_BinaryenGetAllowInliningFunctionsWithLoops"]()); -}; +} /** Sets whether functions with loops are allowed to be inlined. */ export function setAllowInliningFunctionsWithLoops(on: boolean) { BinaryenObj["_BinaryenSetAllowInliningFunctionsWithLoops"](on); -}; +} @@ -363,7 +363,7 @@ export function getPassArgument(key: string): string | undefined { const returned = BinaryenObj["_BinaryenGetPassArgument"](strToStack(key)); return returned ? UTF8ToString(returned) : undefined; }); -}; +} /** * Sets the value of the specified arbitrary pass argument. @@ -373,26 +373,26 @@ export function setPassArgument(key: string, value: string): void { return preserveStack(() => { BinaryenObj["_BinaryenSetPassArgument"](strToStack(key), strToStack(value)); }); -}; +} /** Clears all arbitrary pass arguments. */ export function clearPassArguments(): void { BinaryenObj["_BinaryenClearPassArguments"](); -}; +} /** Gets whether a pass is in the set of passes to skip. */ export function hasPassToSkip(pass: string): boolean { return preserveStack(() => Boolean(BinaryenObj["_BinaryenHasPassToSkip"](strToStack(pass)))); -}; +} /** Add a pass to the set of passes to skip. */ export function addPassToSkip(pass: string): void { return preserveStack(() => { BinaryenObj["_BinaryenAddPassToSkip"](strToStack(pass)); }); -}; +} /** Clears the set of passes to skip. */ export function clearPassesToSkip(): void { BinaryenObj["_BinaryenClearPassesToSkip"](); -}; +} diff --git a/ts/src/lib.ts b/ts/src/lib.ts index 26d73aef19c..021c5c280a2 100644 --- a/ts/src/lib.ts +++ b/ts/src/lib.ts @@ -4,6 +4,7 @@ export function consoleWarn(...args: any[]): void { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition return (console?.warn ?? console?.log)?.call(undefined, ...args); } diff --git a/ts/tsconfig.json b/ts/tsconfig.json index 4338b96da6f..ec6584661eb 100644 --- a/ts/tsconfig.json +++ b/ts/tsconfig.json @@ -2,18 +2,18 @@ // TSConfig: https://www.typescriptlang.org/tsconfig/ "compilerOptions": { // Type Checking - "exactOptionalPropertyTypes": true, - "noImplicitOverride": true, - "noImplicitReturns": true, + "exactOptionalPropertyTypes": true, + "noImplicitOverride": true, + "noImplicitReturns": true, "noPropertyAccessFromIndexSignature": true, // Modules "rewriteRelativeImportExtensions": true, - "rootDir": "./src/", + "rootDir": "./src/", // Emit "declaration": true, - "outDir": "./dist/", + "outDir": "./dist/", // Interop Constraints "verbatimModuleSyntax": true, From b9d6c94611622b1de8b2d078b2c11f6084bdd32c Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 00:45:02 -0400 Subject: [PATCH 041/247] refactor: move settings functions to service --- ts/src/-deprecations.ts | 146 ++++++++++++++++++++++++++++ ts/src/binaryen.ts | 1 + ts/src/globals.ts | 156 ------------------------------ ts/src/service/SettingsService.ts | 102 +++++++++++++++++++ 4 files changed, 249 insertions(+), 156 deletions(-) create mode 100644 ts/src/service/SettingsService.ts diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 6a98e2185f5..508e081f479 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -26,6 +26,9 @@ import { import { consoleWarn, } from "./lib.ts"; +import { + settings, +} from "./service/SettingsService.ts"; @@ -86,3 +89,146 @@ export function getExportInfo(xport: ExportRef) { consoleWarn("Global function `getExportInfo` is deprecated; use `new Module.Export(exportref)` instead."); return new Module.Export(xport); } + + + +/** @deprecated Use `settings.optimizeLevel` instead. */ +export function getOptimizeLevel() { + consoleWarn("Global function `getOptimizeLevel` is deprecated; use `settings.optimizeLevel` instead."); + return settings.optimizeLevel; +} +/** @deprecated Use `settings.optimizeLevel = level` instead. */ +export function setOptimizeLevel(level: number) { + consoleWarn("Global function `setOptimizeLevel` is deprecated; use `settings.optimizeLevel = level` instead."); + settings.optimizeLevel = level; +} +/** @deprecated Use `settings.shrinkLevel` instead. */ +export function getShrinkLevel() { + consoleWarn("Global function `getShrinkLevel` is deprecated; use `settings.shrinkLevel` instead."); + return settings.shrinkLevel; +} +/** @deprecated Use `settings.shrinkLevel = level` instead. */ +export function setShrinkLevel(level: number) { + consoleWarn("Global function `setShrinkLevel` is deprecated; use `settings.shrinkLevel = level` instead."); + settings.shrinkLevel = level; +} +/** @deprecated Use `settings.debugInfo` instead. */ +export function getDebugInfo(): boolean { + consoleWarn("Global function `getDebugInfo` is deprecated; use `settings.debugInfo` instead."); + return settings.debugInfo; +} +/** @deprecated Use `settings.debugInfo = enabled` instead. */ +export function setDebugInfo(enabled: boolean) { + consoleWarn("Global function `setDebugInfo` is deprecated; use `settings.debugInfo = enabled` instead."); + settings.debugInfo = enabled; +} +/** @deprecated Use `settings.trapsNeverHappen` instead. */ +export function getTrapsNeverHappen(): boolean { + consoleWarn("Global function `getTrapsNeverHappen` is deprecated; use `settings.trapsNeverHappen` instead."); + return settings.trapsNeverHappen; +} +/** @deprecated Use `settings.trapsNeverHappen = enabled` instead. */ +export function setTrapsNeverHappen(enabled: boolean) { + consoleWarn("Global function `setTrapsNeverHappen` is deprecated; use `settings.trapsNeverHappen = enabled` instead."); + settings.trapsNeverHappen = enabled; +} +/** @deprecated Use `settings.closedWorld` instead. */ +export function getClosedWorld() { + consoleWarn("Global function `getClosedWorld` is deprecated; use `settings.closedWorld` instead."); + return settings.closedWorld; +} +/** @deprecated Use `settings.closedWorld = enabled` instead. */ +export function setClosedWorld(enabled: boolean) { + consoleWarn("Global function `setClosedWorld` is deprecated; use `settings.closedWorld = enabled` instead."); + settings.closedWorld = enabled; +} +/** @deprecated Use `settings.lowMemoryUnused` instead. */ +export function getLowMemoryUnused() { + consoleWarn("Global function `getLowMemoryUnused` is deprecated; use `settings.lowMemoryUnused` instead."); + return settings.lowMemoryUnused; +} +/** @deprecated Use `settings.lowMemoryUnused = enabled` instead. */ +export function setLowMemoryUnused(enabled: boolean) { + consoleWarn("Global function `setLowMemoryUnused` is deprecated; use `settings.lowMemoryUnused = enabled` instead."); + settings.lowMemoryUnused = enabled; +} +/** @deprecated Use `settings.zeroFilledMemory` instead. */ +export function getZeroFilledMemory() { + consoleWarn("Global function `getZeroFilledMemory` is deprecated; use `settings.zeroFilledMemory` instead."); + return settings.zeroFilledMemory; +} +/** @deprecated Use `settings.zeroFilledMemory = enabled` instead. */ +export function setZeroFilledMemory(enabled: boolean) { + consoleWarn("Global function `setZeroFilledMemory` is deprecated; use `settings.zeroFilledMemory = enabled` instead."); + settings.zeroFilledMemory = enabled; +} +/** @deprecated Use `settings.fastMath` instead. */ +export function getFastMath() { + consoleWarn("Global function `getFastMath` is deprecated; use `settings.fastMath` instead."); + return settings.fastMath; +} +/** @deprecated Use `settings.fastMath = enabled` instead. */ +export function setFastMath(enabled: boolean) { + consoleWarn("Global function `setFastMath` is deprecated; use `settings.fastMath = enabled` instead."); + settings.fastMath = enabled; +} +/** @deprecated Use `settings.generateStackIR` instead. */ +export function getGenerateStackIR() { + consoleWarn("Global function `getGenerateStackIR` is deprecated; use `settings.generateStackIR` instead."); + return settings.generateStackIR; +} +/** @deprecated Use `settings.generateStackIR = enabled` instead. */ +export function setGenerateStackIR(enabled: boolean) { + consoleWarn("Global function `setGenerateStackIR` is deprecated; use `settings.generateStackIR = enabled` instead."); + settings.generateStackIR = enabled; +} +/** @deprecated Use `settings.optimizeStackIR` instead. */ +export function getOptimizeStackIR() { + consoleWarn("Global function `getOptimizeStackIR` is deprecated; use `settings.optimizeStackIR` instead."); + return settings.optimizeStackIR; +} +/** @deprecated Use `settings.optimizeStackIR = enabled` instead. */ +export function setOptimizeStackIR(enabled: boolean) { + consoleWarn("Global function `setOptimizeStackIR` is deprecated; use `settings.optimizeStackIR = enabled` instead."); + settings.optimizeStackIR = enabled; +} +/** @deprecated Use `settings.alwaysInlineMaxSize` instead. */ +export function getAlwaysInlineMaxSize() { + consoleWarn("Global function `getAlwaysInlineMaxSize` is deprecated; use `settings.alwaysInlineMaxSize` instead."); + return settings.alwaysInlineMaxSize; +} +/** @deprecated Use `settings.alwaysInlineMaxSize = size` instead. */ +export function setAlwaysInlineMaxSize(size: number) { + consoleWarn("Global function `setAlwaysInlineMaxSize` is deprecated; use `settings.alwaysInlineMaxSize = size` instead."); + settings.alwaysInlineMaxSize = size; +} +/** @deprecated Use `settings.flexibleInlineMaxSize` instead. */ +export function getFlexibleInlineMaxSize() { + consoleWarn("Global function `getFlexibleInlineMaxSize` is deprecated; use `settings.flexibleInlineMaxSize` instead."); + return settings.flexibleInlineMaxSize; +} +/** @deprecated Use `settings.flexibleInlineMaxSize = size` instead. */ +export function setFlexibleInlineMaxSize(size: number) { + consoleWarn("Global function `setFlexibleInlineMaxSize` is deprecated; use `settings.flexibleInlineMaxSize = size` instead."); + settings.flexibleInlineMaxSize = size; +} +/** @deprecated Use `settings.oneCallerInlineMaxSize` instead. */ +export function getOneCallerInlineMaxSize() { + consoleWarn("Global function `getOneCallerInlineMaxSize` is deprecated; use `settings.oneCallerInlineMaxSize` instead."); + return settings.oneCallerInlineMaxSize; +} +/** @deprecated Use `settings.oneCallerInlineMaxSize = size` instead. */ +export function setOneCallerInlineMaxSize(size: number) { + consoleWarn("Global function `setOneCallerInlineMaxSize` is deprecated; use `settings.oneCallerInlineMaxSize = size` instead."); + settings.oneCallerInlineMaxSize = size; +} +/** @deprecated Use `settings.allowInliningFunctionsWithLoops` instead. */ +export function getAllowInliningFunctionsWithLoops() { + consoleWarn("Global function `getAllowInliningFunctionsWithLoops` is deprecated; use `settings.allowInliningFunctionsWithLoops` instead."); + return settings.allowInliningFunctionsWithLoops; +} +/** @deprecated Use `settings.allowInliningFunctionsWithLoops = enabled` instead. */ +export function setAllowInliningFunctionsWithLoops(enabled: boolean) { + consoleWarn("Global function `setAllowInliningFunctionsWithLoops` is deprecated; use `settings.allowInliningFunctionsWithLoops = enabled` instead."); + settings.allowInliningFunctionsWithLoops = enabled; +} diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index c20b9738fc9..67b996290fe 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -10,5 +10,6 @@ export { ExpressionRunnerFlag, } from "./class/ExpressionRunner.ts"; export {Relooper} from "./class/Relooper.ts"; +export {settings} from "./service/SettingsService.ts"; export * from "./class/expression/index.ts"; export * from "./-deprecations.ts"; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 8c7d40e40f2..1931300a420 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -200,162 +200,6 @@ export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { -// ## Getters & Setters for Settings ## // -// TODO: These should all be moved to a `Settings` class with getter and setter methods. -/** Gets the currently set optimize level. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ -export function getOptimizeLevel(): number { - return BinaryenObj["_BinaryenGetOptimizeLevel"](); -} - -/** Sets the optimization level to use. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ -export function setOptimizeLevel(level: number): void { - BinaryenObj["_BinaryenSetOptimizeLevel"](level); -} - -/** Gets the currently set shrink level. 0, 1, 2 correspond to -O0, -Os, -Oz. */ -export function getShrinkLevel(): number { - return BinaryenObj["_BinaryenGetShrinkLevel"](); -} - -/** Sets the shrink level to use. 0, 1, 2 correspond to -O0, -Os, -Oz. */ -export function setShrinkLevel(level: number): void { - BinaryenObj["_BinaryenSetShrinkLevel"](level); -} - -/** Gets whether generating debug information is currently enabled or not. */ -export function getDebugInfo(): boolean { - return Boolean(BinaryenObj["_BinaryenGetDebugInfo"]()); -} - -/** Enables or disables debug information in emitted binaries. */ -export function setDebugInfo(on: boolean) { - BinaryenObj["_BinaryenSetDebugInfo"](on); -} - -/** Gets whether no traps can be considered reached at runtime when optimizing. */ -export function getTrapsNeverHappen(): boolean { - return Boolean(BinaryenObj["_BinaryenGetTrapsNeverHappen"]()); -} - -/** Enables or disables whether no traps can be considered reached at runtime when optimizing. */ -export function setTrapsNeverHappen(on: boolean) { - BinaryenObj["_BinaryenSetTrapsNeverHappen"](on); -} - -/** - * Gets whether considering that the code outside of the module does - * not inspect or interact with GC and function references. - */ -export function getClosedWorld(): boolean { - return Boolean(BinaryenObj["_BinaryenGetClosedWorld"]()); -} - -/** - * Enables or disables whether considering that the code outside of - * the module does not inspect or interact with GC and function references. - */ -export function setClosedWorld(on: boolean) { - BinaryenObj["_BinaryenSetClosedWorld"](on); -} - -/** Gets whether the low 1K of memory can be considered unused when optimizing. */ -export function getLowMemoryUnused(): boolean { - return Boolean(BinaryenObj["_BinaryenGetLowMemoryUnused"]()); -} - -/** Enables or disables whether the low 1K of memory can be considered unused when optimizing. */ -export function setLowMemoryUnused(on: boolean) { - BinaryenObj["_BinaryenSetLowMemoryUnused"](on); -} - -/** Gets whether that an imported memory will be zero-initialized speculation. */ -export function getZeroFilledMemory(): boolean { - return Boolean(BinaryenObj["_BinaryenGetZeroFilledMemory"]()); -} - -/** Enables or disables whether that an imported memory will be zero-initialized speculation. */ -export function setZeroFilledMemory(on: boolean) { - BinaryenObj["_BinaryenSetZeroFilledMemory"](on); -} - -/** - * Gets whether fast math optimizations are enabled, ignoring for example - * corner cases of floating-point math like NaN changes. - */ -export function getFastMath(): boolean { - return Boolean(BinaryenObj["_BinaryenGetFastMath"]()); -} - -/** - * Enables or disables fast math optimizations, ignoring for example - * corner cases of floating-point math like NaN changes. - */ -export function setFastMath(on: boolean) { - BinaryenObj["_BinaryenSetFastMath"](on); -} - -/** Gets whether to generate StackIR during binary writing. */ -export function getGenerateStackIR(): boolean { - return Boolean(BinaryenObj["_BinaryenGetGenerateStackIR"]()); -} - -/** Enable or disable StackIR generation during binary writing. */ -export function setGenerateStackIR(on: boolean) { - BinaryenObj["_BinaryenSetGenerateStackIR"](on); -} - -/** Gets whether to optimize StackIR during binary writing. */ -export function getOptimizeStackIR(): boolean { - return Boolean(BinaryenObj["_BinaryenGetOptimizeStackIR"]()); -} - -/** Enable or disable StackIR optimisation during binary writing. */ -export function setOptimizeStackIR(on: boolean) { - BinaryenObj["_BinaryenSetOptimizeStackIR"](on); -} - -/** Gets the function size at which we always inline. */ -export function getAlwaysInlineMaxSize(): number { - return BinaryenObj["_BinaryenGetAlwaysInlineMaxSize"](); -} - -/** Sets the function size at which we always inline. */ -export function setAlwaysInlineMaxSize(size: number) { - BinaryenObj["_BinaryenSetAlwaysInlineMaxSize"](size); -} - -/** Gets the function size which we inline when functions are lightweight. */ -export function getFlexibleInlineMaxSize(): number { - return BinaryenObj["_BinaryenGetFlexibleInlineMaxSize"](); -} - -/** Sets the function size which we inline when functions are lightweight. */ -export function setFlexibleInlineMaxSize(size: number) { - BinaryenObj["_BinaryenSetFlexibleInlineMaxSize"](size); -} - -/** Gets the function size which we inline when there is only one caller. */ -export function getOneCallerInlineMaxSize(): number { - return BinaryenObj["_BinaryenGetOneCallerInlineMaxSize"](); -} - -/** Sets the function size which we inline when there is only one caller. */ -export function setOneCallerInlineMaxSize(size: number) { - BinaryenObj["_BinaryenSetOneCallerInlineMaxSize"](size); -} - -/** Gets whether functions with loops are allowed to be inlined. */ -export function getAllowInliningFunctionsWithLoops(): boolean { - return Boolean(BinaryenObj["_BinaryenGetAllowInliningFunctionsWithLoops"]()); -} - -/** Sets whether functions with loops are allowed to be inlined. */ -export function setAllowInliningFunctionsWithLoops(on: boolean) { - BinaryenObj["_BinaryenSetAllowInliningFunctionsWithLoops"](on); -} - - - // ## Pass Settings ## // /** Gets the value of the specified arbitrary pass argument. */ export function getPassArgument(key: string): string | undefined { diff --git a/ts/src/service/SettingsService.ts b/ts/src/service/SettingsService.ts new file mode 100644 index 00000000000..06474913ff6 --- /dev/null +++ b/ts/src/service/SettingsService.ts @@ -0,0 +1,102 @@ +import { + BinaryenObj, +} from "../-pre.ts"; + + + +interface Settings { + /** The currently set optimize level. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ + optimizeLevel: number; + + /** The currently set shrink level. 0, 1, 2 correspond to -O0, -Os, -Oz. */ + shrinkLevel: number; + + /** Is generating debug information currently enabled? */ + debugInfo: boolean; + + /** Whether no traps can be considered reached at runtime when optimizing. */ + trapsNeverHappen: boolean; + + /** Whether considering that the code outside of the module does not inspect or interact with GC and function references. */ + closedWorld: boolean; + + /** Whether the low 1K of memory can be considered unused when optimizing. */ + lowMemoryUnused: boolean; + + /** Whether that an imported memory will be zero-initialized speculation. */ + zeroFilledMemory: boolean; + + /** Whether fast math optimizations are enabled, ignoring for example corner cases of floating-point math like NaN changes. */ + fastMath: boolean; + + /** Whether to generate StackIR during binary writing. */ + generateStackIR: boolean; + + /** Whether to optimize StackIR during binary writing. */ + optimizeStackIR: boolean; + + /** The function size at which we always inline. */ + alwaysInlineMaxSize: number; + + /** The function size which we inline when functions are lightweight. */ + flexibleInlineMaxSize: number; + + /** The function size which we inline when there is only one caller. */ + oneCallerInlineMaxSize: number; + + /** Whether functions with loops are allowed to be inlined. */ + allowInliningFunctionsWithLoops: boolean; +} + + + +class SettingsService implements Settings { + /* eslint-disable @stylistic/brace-style */ + get optimizeLevel(): number { return BinaryenObj["_BinaryenGetOptimizeLevel"](); } + set optimizeLevel(level: number) { BinaryenObj["_BinaryenSetOptimizeLevel"](level); } + + get shrinkLevel(): number { return BinaryenObj["_BinaryenGetShrinkLevel"](); } + set shrinkLevel(level: number) { BinaryenObj["_BinaryenSetShrinkLevel"](level); } + + get debugInfo(): boolean { return Boolean(BinaryenObj["_BinaryenGetDebugInfo"]()); } + set debugInfo(enabled: boolean) { BinaryenObj["_BinaryenSetDebugInfo"](enabled); } + + get trapsNeverHappen(): boolean { return Boolean(BinaryenObj["_BinaryenGetTrapsNeverHappen"]()); } + set trapsNeverHappen(enabled: boolean) { BinaryenObj["_BinaryenSetTrapsNeverHappen"](enabled); } + + get closedWorld(): boolean { return Boolean(BinaryenObj["_BinaryenGetClosedWorld"]()); } + set closedWorld(enabled: boolean) { BinaryenObj["_BinaryenSetClosedWorld"](enabled); } + + get lowMemoryUnused(): boolean { return Boolean(BinaryenObj["_BinaryenGetLowMemoryUnused"]()); } + set lowMemoryUnused(enabled: boolean) { BinaryenObj["_BinaryenSetLowMemoryUnused"](enabled); } + + get zeroFilledMemory(): boolean { return Boolean(BinaryenObj["_BinaryenGetZeroFilledMemory"]()); } + set zeroFilledMemory(enabled: boolean) { BinaryenObj["_BinaryenSetZeroFilledMemory"](enabled); } + + get fastMath(): boolean { return Boolean(BinaryenObj["_BinaryenGetFastMath"]()); } + set fastMath(enabled: boolean) { BinaryenObj["_BinaryenSetFastMath"](enabled); } + + get generateStackIR(): boolean { return Boolean(BinaryenObj["_BinaryenGetGenerateStackIR"]()); } + set generateStackIR(enabled: boolean) { BinaryenObj["_BinaryenSetGenerateStackIR"](enabled); } + + get optimizeStackIR(): boolean { return Boolean(BinaryenObj["_BinaryenGetOptimizeStackIR"]()); } + set optimizeStackIR(enabled: boolean) { BinaryenObj["_BinaryenSetOptimizeStackIR"](enabled); } + + get alwaysInlineMaxSize(): number { return BinaryenObj["_BinaryenGetAlwaysInlineMaxSize"](); } + set alwaysInlineMaxSize(size: number) { BinaryenObj["_BinaryenSetAlwaysInlineMaxSize"](size); } + + get flexibleInlineMaxSize(): number { return BinaryenObj["_BinaryenGetFlexibleInlineMaxSize"](); } + set flexibleInlineMaxSize(size: number) { BinaryenObj["_BinaryenSetFlexibleInlineMaxSize"](size); } + + get oneCallerInlineMaxSize(): number { return BinaryenObj["_BinaryenGetOneCallerInlineMaxSize"](); } + set oneCallerInlineMaxSize(size: number) { BinaryenObj["_BinaryenSetOneCallerInlineMaxSize"](size); } + + get allowInliningFunctionsWithLoops(): boolean { return Boolean(BinaryenObj["_BinaryenGetAllowInliningFunctionsWithLoops"]()); } + set allowInliningFunctionsWithLoops(enabled: boolean) { BinaryenObj["_BinaryenSetAllowInliningFunctionsWithLoops"](enabled); } + /* eslint-enable @stylistic/brace-style */ +} + + + +/** The global settings control. */ +export const settings: Settings = new SettingsService(); From f062531fd54f7f90d5f0c641bdd1d9e8e17cf2c8 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 00:59:00 -0400 Subject: [PATCH 042/247] refactor: pluralize folder names --- ts/src/-deprecations.ts | 8 ++++---- ts/src/binaryen.ts | 12 ++++++------ ts/src/{class => classes}/ExpressionRunner.ts | 0 ts/src/{class => classes}/Relooper.ts | 0 ts/src/{class => classes}/TypeBuilder.ts | 0 ts/src/{class => classes}/expression/Block.ts | 0 ts/src/{class => classes}/expression/Const.ts | 0 ts/src/{class => classes}/expression/Expression.ts | 0 ts/src/{class => classes}/expression/LocalGet.ts | 0 ts/src/{class => classes}/expression/LocalSet.ts | 0 ts/src/{class => classes}/expression/index.ts | 0 ts/src/{class => classes}/module/DataSegment.ts | 0 ts/src/{class => classes}/module/ElementSegment.ts | 0 ts/src/{class => classes}/module/Export.ts | 0 ts/src/{class => classes}/module/Function.ts | 0 ts/src/{class => classes}/module/Global.ts | 0 ts/src/{class => classes}/module/Import.ts | 0 ts/src/{class => classes}/module/Memory.ts | 0 ts/src/{class => classes}/module/Module.ts | 0 ts/src/{class => classes}/module/Table.ts | 0 ts/src/{class => classes}/module/Tag.ts | 0 ts/src/globals.ts | 4 ++-- ts/src/{service => services}/SettingsService.ts | 0 23 files changed, 12 insertions(+), 12 deletions(-) rename ts/src/{class => classes}/ExpressionRunner.ts (100%) rename ts/src/{class => classes}/Relooper.ts (100%) rename ts/src/{class => classes}/TypeBuilder.ts (100%) rename ts/src/{class => classes}/expression/Block.ts (100%) rename ts/src/{class => classes}/expression/Const.ts (100%) rename ts/src/{class => classes}/expression/Expression.ts (100%) rename ts/src/{class => classes}/expression/LocalGet.ts (100%) rename ts/src/{class => classes}/expression/LocalSet.ts (100%) rename ts/src/{class => classes}/expression/index.ts (100%) rename ts/src/{class => classes}/module/DataSegment.ts (100%) rename ts/src/{class => classes}/module/ElementSegment.ts (100%) rename ts/src/{class => classes}/module/Export.ts (100%) rename ts/src/{class => classes}/module/Function.ts (100%) rename ts/src/{class => classes}/module/Global.ts (100%) rename ts/src/{class => classes}/module/Import.ts (100%) rename ts/src/{class => classes}/module/Memory.ts (100%) rename ts/src/{class => classes}/module/Module.ts (100%) rename ts/src/{class => classes}/module/Table.ts (100%) rename ts/src/{class => classes}/module/Tag.ts (100%) rename ts/src/{service => services}/SettingsService.ts (100%) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 508e081f479..f15351d738d 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -16,19 +16,19 @@ import { } from "./constants.ts"; import { Function as BinaryenFunction, -} from "./class/module/Function.ts"; +} from "./classes/module/Function.ts"; import { Module, -} from "./class/module/Module.ts"; +} from "./classes/module/Module.ts"; import { Table as BinaryenTable, -} from "./class/module/Table.ts"; +} from "./classes/module/Table.ts"; import { consoleWarn, } from "./lib.ts"; import { settings, -} from "./service/SettingsService.ts"; +} from "./services/SettingsService.ts"; diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 67b996290fe..02e40fc3ddf 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -3,13 +3,13 @@ export * from "./globals.ts"; export { Feature, Module, -} from "./class/module/Module.ts"; -export {TypeBuilder} from "./class/TypeBuilder.ts"; +} from "./classes/module/Module.ts"; +export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, ExpressionRunnerFlag, -} from "./class/ExpressionRunner.ts"; -export {Relooper} from "./class/Relooper.ts"; -export {settings} from "./service/SettingsService.ts"; -export * from "./class/expression/index.ts"; +} from "./classes/ExpressionRunner.ts"; +export {Relooper} from "./classes/Relooper.ts"; +export {settings} from "./services/SettingsService.ts"; +export * from "./classes/expression/index.ts"; export * from "./-deprecations.ts"; diff --git a/ts/src/class/ExpressionRunner.ts b/ts/src/classes/ExpressionRunner.ts similarity index 100% rename from ts/src/class/ExpressionRunner.ts rename to ts/src/classes/ExpressionRunner.ts diff --git a/ts/src/class/Relooper.ts b/ts/src/classes/Relooper.ts similarity index 100% rename from ts/src/class/Relooper.ts rename to ts/src/classes/Relooper.ts diff --git a/ts/src/class/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts similarity index 100% rename from ts/src/class/TypeBuilder.ts rename to ts/src/classes/TypeBuilder.ts diff --git a/ts/src/class/expression/Block.ts b/ts/src/classes/expression/Block.ts similarity index 100% rename from ts/src/class/expression/Block.ts rename to ts/src/classes/expression/Block.ts diff --git a/ts/src/class/expression/Const.ts b/ts/src/classes/expression/Const.ts similarity index 100% rename from ts/src/class/expression/Const.ts rename to ts/src/classes/expression/Const.ts diff --git a/ts/src/class/expression/Expression.ts b/ts/src/classes/expression/Expression.ts similarity index 100% rename from ts/src/class/expression/Expression.ts rename to ts/src/classes/expression/Expression.ts diff --git a/ts/src/class/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts similarity index 100% rename from ts/src/class/expression/LocalGet.ts rename to ts/src/classes/expression/LocalGet.ts diff --git a/ts/src/class/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts similarity index 100% rename from ts/src/class/expression/LocalSet.ts rename to ts/src/classes/expression/LocalSet.ts diff --git a/ts/src/class/expression/index.ts b/ts/src/classes/expression/index.ts similarity index 100% rename from ts/src/class/expression/index.ts rename to ts/src/classes/expression/index.ts diff --git a/ts/src/class/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts similarity index 100% rename from ts/src/class/module/DataSegment.ts rename to ts/src/classes/module/DataSegment.ts diff --git a/ts/src/class/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts similarity index 100% rename from ts/src/class/module/ElementSegment.ts rename to ts/src/classes/module/ElementSegment.ts diff --git a/ts/src/class/module/Export.ts b/ts/src/classes/module/Export.ts similarity index 100% rename from ts/src/class/module/Export.ts rename to ts/src/classes/module/Export.ts diff --git a/ts/src/class/module/Function.ts b/ts/src/classes/module/Function.ts similarity index 100% rename from ts/src/class/module/Function.ts rename to ts/src/classes/module/Function.ts diff --git a/ts/src/class/module/Global.ts b/ts/src/classes/module/Global.ts similarity index 100% rename from ts/src/class/module/Global.ts rename to ts/src/classes/module/Global.ts diff --git a/ts/src/class/module/Import.ts b/ts/src/classes/module/Import.ts similarity index 100% rename from ts/src/class/module/Import.ts rename to ts/src/classes/module/Import.ts diff --git a/ts/src/class/module/Memory.ts b/ts/src/classes/module/Memory.ts similarity index 100% rename from ts/src/class/module/Memory.ts rename to ts/src/classes/module/Memory.ts diff --git a/ts/src/class/module/Module.ts b/ts/src/classes/module/Module.ts similarity index 100% rename from ts/src/class/module/Module.ts rename to ts/src/classes/module/Module.ts diff --git a/ts/src/class/module/Table.ts b/ts/src/classes/module/Table.ts similarity index 100% rename from ts/src/class/module/Table.ts rename to ts/src/classes/module/Table.ts diff --git a/ts/src/class/module/Tag.ts b/ts/src/classes/module/Tag.ts similarity index 100% rename from ts/src/class/module/Tag.ts rename to ts/src/classes/module/Tag.ts diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 1931300a420..969041116ee 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -15,10 +15,10 @@ import { import { type Feature, Module, -} from "./class/module/Module.ts"; +} from "./classes/module/Module.ts"; import { Expression, -} from "./class/expression/Expression.ts"; +} from "./classes/expression/Expression.ts"; import type { ExpressionId, ExpressionRef, diff --git a/ts/src/service/SettingsService.ts b/ts/src/services/SettingsService.ts similarity index 100% rename from ts/src/service/SettingsService.ts rename to ts/src/services/SettingsService.ts From 33eba18080bdcb42a7f38a457b2e974b6be8f196 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 01:38:39 -0400 Subject: [PATCH 043/247] feat: Module binaryen operations --- ts/src/-pre.ts | 1 + ts/src/classes/module/Module.ts | 139 +++++++++++++++++++++++++++----- 2 files changed, 120 insertions(+), 20 deletions(-) diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index 6e30b085ff6..63a1dc87ac5 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -17,3 +17,4 @@ export declare function stringToUTF8OnStack(str: string): number; export declare function UTF8ToString(n: number): string; export declare function stringToAscii(text: string, buffer: number): void; export declare function getExceptionMessage(e: number | Error): [string, string]; // https://emscripten.org/docs/porting/exceptions.html#handling-c-exceptions-from-javascript +export declare function _BinaryenSizeofAllocateAndWriteResult(): number; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index d28eaecfe07..3ae7df16c53 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -1,13 +1,16 @@ import { + _BinaryenSizeofAllocateAndWriteResult, _free, _malloc, BinaryenObj, UTF8ToString, + stackAlloc, } from "../../-pre.ts"; import { type DataSegmentRef, type ExpressionRef, type FunctionRef, + type HeapType, type TableRef, type Type, funcref, @@ -17,6 +20,9 @@ import { } from "../../lib.ts"; import { HEAP8, + HEAPU8, + HEAPU32, + i8sToStack, i32sToStack, preserveStack, strToStack, @@ -68,6 +74,11 @@ import { +/** Probably used in `BinaryenObj["_BinaryenModulePrintAsmjs"]`. */ +declare let out: any; + + + /** Similar to a `DataSegment` but with some minor differences. */ interface MemorySegment { name?: string; @@ -283,43 +294,131 @@ export class Module { return text; } - emitStackIR() {} + emitStackIR(): string { + const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteStackIR"](this.ptr); + const text = UTF8ToString(textPtr); + if (textPtr) { + _free(textPtr); + } + return text; + } - emitAsmjs() {} + emitAsmjs(): string { + let returned = ""; + const saved = out; + out = (x: string) => { + returned += `${ x }\n`; + }; + BinaryenObj["_BinaryenModulePrintAsmjs"](this.ptr); + out = saved; + return returned; + } - emitBinary() {} + emitBinary(): Uint8Array; + emitBinary(sourceMapUrl: string): {binary: Uint8Array, sourceMap: string}; + emitBinary(sourceMapUrl?: string): Uint8Array | {binary: Uint8Array, sourceMap: string} { + return preserveStack(() => { + const tempBuffer = stackAlloc(_BinaryenSizeofAllocateAndWriteResult()); + BinaryenObj["_BinaryenModuleAllocateAndWrite"](tempBuffer, this.ptr, strToStack(sourceMapUrl)); + const binaryPtr = HEAPU32[tempBuffer >>> 2]; + const binaryBytes = HEAPU32[(tempBuffer >>> 2) + 1]; + const sourceMapPtr = HEAPU32[(tempBuffer >>> 2) + 2]; + try { + const buffer = new Uint8Array(binaryBytes); + buffer.set(HEAPU8.subarray(binaryPtr, binaryPtr + binaryBytes)); + return typeof sourceMapUrl === "undefined" + ? buffer + : {binary: buffer, sourceMap: UTF8ToString(sourceMapPtr)}; + } finally { + _free(binaryPtr); + if (sourceMapPtr) { + _free(sourceMapPtr); + } + } + }); + } - getFeatures() {} + getFeatures(): Feature { + return BinaryenObj["_BinaryenModuleGetFeatures"](this.ptr); + } - setFeatures() {} + setFeatures(features: Feature): void { + BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); + } - setTypeName() {} + setTypeName(heapType: HeapType, name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenModuleSetTypeName"](this.ptr, heapType, strToStack(name)); + }); + } - setFieldName() {} + setFieldName(heapType: HeapType, index: number, name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenModuleSetFieldName"](this.ptr, heapType, index, strToStack(name)); + }); + } - addCustomSection() {} + addCustomSection(name: string, contents: Uint8Array): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddCustomSection"](this.ptr, strToStack(name), i8sToStack([...contents]), contents.length); + }); + } - interpret() {} + interpret(): void { + BinaryenObj["_BinaryenModuleInterpret"](this.ptr); + } - validate() {} + validate(): number { + return BinaryenObj["_BinaryenModuleValidate"](this.ptr); + } - optimize() {} + optimize(): void { + BinaryenObj["_BinaryenModuleOptimize"](this.ptr); + } - optimizeFunction() {} + optimizeFunction(func: FunctionRef | string): void { + if (typeof func === "string") { + func = this.functions.get(func); + } + BinaryenObj["_BinaryenFunctionOptimize"](func, this.ptr); + } - updateMaps() {} + updateMaps(): void { + BinaryenObj["_BinaryenModuleUpdateMaps"](this.ptr); + } - runPasses() {} + runPasses(passes: readonly string[]): void { + return preserveStack(() => { + BinaryenObj["_BinaryenModuleRunPasses"](this.ptr, i32sToStack(passes.map(strToStack)), passes.length); + }); + } - runPassesOnFunction() {} + runPassesOnFunction(func: string | FunctionRef, passes: readonly string[]): void { + if (typeof func === "string") { + func = this.functions.get(func); + } + return preserveStack(() => { + BinaryenObj["_BinaryenFunctionRunPasses"](func, this.ptr, i32sToStack(passes.map(strToStack)), passes.length); + }); + } - dispose() {} + dispose(): void { + BinaryenObj["_BinaryenModuleDispose"](this.ptr); + } - addDebugInfoFileName() {} + addDebugInfoFileName(filename: string): number { + return preserveStack(() => BinaryenObj["_BinaryenModuleAddDebugInfoFileName"](this.ptr, strToStack(filename))); + } - getDebugInfoFileName() {} + getDebugInfoFileName(index: number): string { + return UTF8ToString(BinaryenObj["_BinaryenModuleGetDebugInfoFileName"](this.ptr, index)); + } - setDebugLocation() {} + setDebugLocation(func: FunctionRef, expr: ExpressionRef, fileIndex: number, lineNumber: number, columnNumber: number): void { + BinaryenObj["_BinaryenFunctionSetDebugLocation"](func, expr, fileIndex, lineNumber, columnNumber); + } - copyExpression() {} + copyExpression(expr: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenExpressionCopy"](expr, this.ptr); + } } From 6ad1c428a63c57ef19e06caabf85e5f1dd91912b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 01:39:37 -0400 Subject: [PATCH 044/247] fix: i8sToStack typing --- ts/src/classes/TypeBuilder.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index 0afe05c460c..e74ea9887fa 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -66,15 +66,14 @@ export class TypeBuilder { */ setStructType(index: number, fields: readonly Field[]): void { preserveStack(() => { - const numFields = fields.length; - const types = new Array(numFields); - const packedTypes = new Array(numFields); - const mutables = new Array(numFields); - for (let i = 0; i < numFields; i++) { + const types = []; + const packedTypes = []; + const mutables = []; + for (let i = 0; i < fields.length; i++) { const {type: typ, packedType, mutable} = fields[i]; types[i] = typ; packedTypes[i] = packedType; - mutables[i] = mutable; + mutables[i] = +mutable; } BinaryenObj["_TypeBuilderSetStructType"]( this.#ptr, @@ -82,7 +81,7 @@ export class TypeBuilder { i32sToStack(types), i32sToStack(packedTypes), i8sToStack(mutables), - numFields, + fields.length, ); }); } From 0a3c94882a9f360eeabb03e4710134d2e3536544 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 01:58:31 -0400 Subject: [PATCH 045/247] docs: fix enum deprecations --- ts/src/-deprecations.ts | 20 +++++++------------- ts/src/classes/ExpressionRunner.ts | 4 ++++ ts/src/classes/module/Module.ts | 2 -- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index f15351d738d..6b4922611e2 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -18,6 +18,7 @@ import { Function as BinaryenFunction, } from "./classes/module/Function.ts"; import { + Feature, Module, } from "./classes/module/Module.ts"; import { @@ -32,23 +33,21 @@ import { -/** @deprecated `ExpressionIds` has been renamed to `ExpressionId`. */ +/** @deprecated The `ExpressionIds` enum has been renamed to `ExpressionId`. */ export const ExpressionIds = ExpressionId; - -/** @deprecated `Operations` has been renamed to `Operation`. */ +/** @deprecated The `Operations` enum has been renamed to `Operation`. */ export const Operations = Operation; - -/** @deprecated `ExternalKinds` has been renamed to `ExternalKind`. */ +/** @deprecated The `ExternalKinds` enum has been renamed to `ExternalKind`. */ export const ExternalKinds = ExternalKind; - -/** @deprecated `SideEffects` has been renamed to `SideEffect`. */ +/** @deprecated The `SideEffects` enum has been renamed to `SideEffect`. */ export const SideEffects = SideEffect; +/** @deprecated The `Features` enum has been renamed to `Feature`. */ +export const Features = Feature; /** @deprecated The `Function` class now lives as a static member of the `Module` class. Use `Module.Function`. */ export const Function = BinaryenFunction; - /** @deprecated The `Table` class now lives as a static member of the `Module` class. Use `Module.Table`. */ export const Table = BinaryenTable; @@ -59,31 +58,26 @@ export function getTagInfo(tag: TagRef) { consoleWarn("Global function `getTagInfo` is deprecated; use `new Module.Tag(tagref)` instead."); return new Module.Tag(tag); } - /** @deprecated Use `new Module.Global(globalref)` instead. */ export function getGlobalInfo(global: GlobalRef) { consoleWarn("Global function `getGlobalInfo` is deprecated; use `new Module.Global(globalref)` instead."); return new Module.Global(global); } - /** @deprecated Use `new Module.Table(tableref)` instead. */ export function getTableInfo(table: TableRef) { consoleWarn("Global function `getTableInfo` is deprecated; use `new Module.Table(tableref)` instead."); return new Module.Table(table); } - /** @deprecated Use `new Module.Function(funcref)` instead. */ export function getFunctionInfo(func: FunctionRef) { consoleWarn("Global function `getFunctionInfo` is deprecated; use `new Module.Function(funcref)` instead."); return new Module.Function(func); } - /** @deprecated Use `new Module.ElementSegment(segmentref)` instead. */ export function getElementSegmentInfo(segment: ElementSegmentRef) { consoleWarn("Global function `getElementSegmentInfo` is deprecated; use `new Module.ElementSegment(segmentref)` instead."); return new Module.ElementSegment(segment); } - /** @deprecated Use `new Module.Export(exportref)` instead. */ export function getExportInfo(xport: ExportRef) { consoleWarn("Global function `getExportInfo` is deprecated; use `new Module.Export(exportref)` instead."); diff --git a/ts/src/classes/ExpressionRunner.ts b/ts/src/classes/ExpressionRunner.ts index 02607e689fb..371c4ebf8fe 100644 --- a/ts/src/classes/ExpressionRunner.ts +++ b/ts/src/classes/ExpressionRunner.ts @@ -23,6 +23,10 @@ export enum ExpressionRunnerFlag { export class ExpressionRunner { + /** @deprecated Static field `ExpressionRunner.Flags` is now a standalone enum `ExpressionRunnerFlag`. */ + static Flags = ExpressionRunnerFlag; + + readonly #ptr: ExpressionRunnerRef; constructor(mod: Module, flags: ExpressionRunnerFlag, maxDepth: number, maxLoopIterations: number) { diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 3ae7df16c53..13fdb92dc6a 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -129,8 +129,6 @@ export enum Feature { WideArithmetic = BinaryenObj["_BinaryenFeatureWideArithmetic"](), All = BinaryenObj["_BinaryenFeatureAll"](), } -/** @deprecated Enum name is now singular. */ -export const Features = Feature; From 3c047c9be54fa722c40ba189020e2e13e7698bc3 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 06:57:17 -0400 Subject: [PATCH 046/247] fix: Module members readonly --- ts/src/classes/module/Module.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 13fdb92dc6a..597cb14f7c7 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -133,14 +133,14 @@ export enum Feature { export class Module { - static Tag = Tag; - static Global = Global; - static Memory = Memory; - static Table = Table; - static Function = BinaryenFunction; - static DataSegment = DataSegment; - static ElementSegment = ElementSegment; - static Export = Export; + static readonly Tag = Tag; + static readonly Global = Global; + static readonly Memory = Memory; + static readonly Table = Table; + static readonly Function = BinaryenFunction; + static readonly DataSegment = DataSegment; + static readonly ElementSegment = ElementSegment; + static readonly Export = Export; readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); @@ -160,14 +160,14 @@ export class Module { // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html - tags = new ModuleTags(this); - globals = new ModuleGlobals(this); - tables = new ModuleTables(this); - functions = new ModuleFunctions(this); - dataSegments = new ModuleDataSegments(this); - elementSegments = new ModuleElementSegments(this); - imports = new ModuleImports(this); - exports = new ModuleExports(this); + readonly tags = new ModuleTags(this); + readonly globals = new ModuleGlobals(this); + readonly tables = new ModuleTables(this); + readonly functions = new ModuleFunctions(this); + readonly dataSegments = new ModuleDataSegments(this); + readonly elementSegments = new ModuleElementSegments(this); + readonly imports = new ModuleImports(this); + readonly exports = new ModuleExports(this); /* eslint-disable @stylistic/brace-style */ /** @deprecated Use `this.tags.add` instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } From 86c96ae3e6a2e8b7dc13f8cbf442e4b96b6badfa Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 07:23:16 -0400 Subject: [PATCH 047/247] fix: delete unused static members post.js converts statically-defined members into instance members, but hides the static ones from public API. The deprecations can be deleted. --- ts/src/classes/expression/Block.ts | 26 ++++++++++++------------- ts/src/classes/expression/Const.ts | 18 +---------------- ts/src/classes/expression/Expression.ts | 14 +------------ ts/src/classes/expression/LocalGet.ts | 10 +++++----- ts/src/classes/expression/LocalSet.ts | 16 +++++++-------- ts/src/classes/module/Function.ts | 21 +------------------- ts/src/classes/module/Table.ts | 18 +---------------- 7 files changed, 30 insertions(+), 93 deletions(-) diff --git a/ts/src/classes/expression/Block.ts b/ts/src/classes/expression/Block.ts index 4383528a58e..50d877b8e08 100644 --- a/ts/src/classes/expression/Block.ts +++ b/ts/src/classes/expression/Block.ts @@ -22,22 +22,22 @@ import { export class Block extends Expression { - // TODO: static methods are deprecated; convert to instance and log warnings - static getName() {} - static setName() {} - static getNumChildren() {} - static getChildren() {} - static setChildren() {} - static getChildAt() {} - static setChildAt() {} - static appendChild() {} - static insertChildAt() {} - static removeChildAt() {} - - constructor(expr: ExpressionRef) { super(ExpressionId.Block, expr); } + + + // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters + getName() {} + setName() {} + getNumChildren() {} + getChildren() {} + setChildren() {} + getChildAt() {} + setChildAt() {} + appendChild() {} + insertChildAt() {} + removeChildAt() {} } diff --git a/ts/src/classes/expression/Const.ts b/ts/src/classes/expression/Const.ts index feec49dc8d4..a1766db5a18 100644 --- a/ts/src/classes/expression/Const.ts +++ b/ts/src/classes/expression/Const.ts @@ -11,9 +11,6 @@ import { f64, v128, } from "../../constants.ts"; -import { - replacedBy, -} from "../../lib.ts"; import { HEAPU8, THIS_PTR, @@ -26,20 +23,6 @@ import { export class Const extends Expression { - /* eslint-disable @stylistic/brace-style */ - /** @deprecated */ @replacedBy("`instance.getValueI32`") static getValueI32(expr: ExpressionRef) { return Const.prototype.getValueI32.call({[THIS_PTR]: expr}); } - /** @deprecated */ @replacedBy("`instance.setValueI32`") static setValueI32(expr: ExpressionRef, value: number) { return Const.prototype.setValueI32.call({[THIS_PTR]: expr}, value); } - /** @deprecated */ @replacedBy("`instance.getValueI64`") static getValueI64(expr: ExpressionRef) { return Const.prototype.getValueI64.call({[THIS_PTR]: expr}); } - /** @deprecated */ @replacedBy("`instance.setValueI64`") static setValueI64(expr: ExpressionRef, value: number) { return Const.prototype.setValueI64.call({[THIS_PTR]: expr}, value); } - /** @deprecated */ @replacedBy("`instance.getValueF32`") static getValueF32(expr: ExpressionRef) { return Const.prototype.getValueF32.call({[THIS_PTR]: expr}); } - /** @deprecated */ @replacedBy("`instance.setValueF32`") static setValueF32(expr: ExpressionRef, value: number) { return Const.prototype.setValueF32.call({[THIS_PTR]: expr}, value); } - /** @deprecated */ @replacedBy("`instance.getValueF64`") static getValueF64(expr: ExpressionRef) { return Const.prototype.getValueF64.call({[THIS_PTR]: expr}); } - /** @deprecated */ @replacedBy("`instance.setValueF64`") static setValueF64(expr: ExpressionRef, value: number) { return Const.prototype.setValueF64.call({[THIS_PTR]: expr}, value); } - /** @deprecated */ @replacedBy("`instance.getValueV128`") static getValueV128(expr: ExpressionRef) { return Const.prototype.getValueV128.call({[THIS_PTR]: expr}); } - /** @deprecated */ @replacedBy("`instance.setValueV128`") static setValueV128(expr: ExpressionRef, value: readonly number[]) { return Const.prototype.setValueV128.call({[THIS_PTR]: expr}, value); } - /* eslint-enable @stylistic/brace-style */ - - constructor(expr: ExpressionRef) { super(ExpressionId.Const, expr); } @@ -56,6 +39,7 @@ export class Const extends Expression { throw new Error(`Unexpected type: ${ this_type }.`); } + // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters getValueI32(): number { return BinaryenObj["_BinaryenConstGetValueI32"](this[THIS_PTR]); } diff --git a/ts/src/classes/expression/Expression.ts b/ts/src/classes/expression/Expression.ts index acea1804bfe..1a43bd2146e 100644 --- a/ts/src/classes/expression/Expression.ts +++ b/ts/src/classes/expression/Expression.ts @@ -10,9 +10,6 @@ import { emitText, getExpressionType, } from "../../globals.ts"; -import { - replacedBy, -} from "../../lib.ts"; import { THIS_PTR, } from "../../utils.ts"; @@ -21,15 +18,6 @@ import { /** Base class of all expression wrappers. */ export class Expression { - /* eslint-disable @stylistic/brace-style */ - /** @deprecated */ @replacedBy("`instance.getId`") static getId(expr: ExpressionRef) { return Expression.prototype.getId.call({[THIS_PTR]: expr}); } - /** @deprecated */ @replacedBy("`instance.getType`") static getType(expr: ExpressionRef) { return Expression.prototype.getType.call({[THIS_PTR]: expr}); } - /** @deprecated */ @replacedBy("`instance.setType`") static setType(expr: ExpressionRef, typ: Type) { return Expression.prototype.setType.call({[THIS_PTR]: expr}, typ); } - /** @deprecated */ @replacedBy("`instance.finalize`") static finalize(expr: ExpressionRef) { return Expression.prototype.finalize.call({[THIS_PTR]: expr}); } - /** @deprecated */ @replacedBy("`instance.toText`") static toText(expr: ExpressionRef) { return Expression.prototype.toText.call({[THIS_PTR]: expr}); } - /* eslint-enable @stylistic/brace-style */ - - protected readonly [THIS_PTR]: ExpressionRef; /** Not really an “ID”, just the “kind” of expression. */ @@ -52,7 +40,7 @@ export class Expression { return this[THIS_PTR]; } - // TODO: post.js has converted all methods starting with `get` to getters and `set` to setters + // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters getId(): ExpressionId { return this.#id; } diff --git a/ts/src/classes/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts index 7ce6fec678e..a1a31e5a27f 100644 --- a/ts/src/classes/expression/LocalGet.ts +++ b/ts/src/classes/expression/LocalGet.ts @@ -16,14 +16,14 @@ import { export class LocalGet extends Expression { - // TODO: static methods are deprecated; convert to instance and log warnings - static getIndex() {} - static setIndex() {} - - constructor(expr: ExpressionRef) { super(ExpressionId.LocalGet, expr); } + + + // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters + getIndex() {} + setIndex() {} } diff --git a/ts/src/classes/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts index e364a9360b8..f3540791f88 100644 --- a/ts/src/classes/expression/LocalSet.ts +++ b/ts/src/classes/expression/LocalSet.ts @@ -16,17 +16,17 @@ import { export class LocalSet extends Expression { - // TODO: static methods are deprecated; convert to instance and log warnings - static getIndex() {} - static setIndex() {} - static isTee() {} - static getValue() {} - static setValue() {} - - constructor(expr: ExpressionRef) { super(ExpressionId.LocalSet, expr); } + + + // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters + getIndex() {} + setIndex() {} + isTee() {} + getValue() {} + setValue() {} } diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index c089c1501fe..db42cf7adcb 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -7,9 +7,6 @@ import type { FunctionRef, Type, } from "../../constants.ts"; -import { - replacedBy, -} from "../../lib.ts"; import { THIS_PTR, getAllNested, @@ -24,22 +21,6 @@ import type { class BinaryenFunction { - /* eslint-disable @stylistic/brace-style */ - /** @deprecated */ @replacedBy("`instance.getName`") static getName(func: FunctionRef) { return BinaryenFunction.prototype.getName.call({[THIS_PTR]: func}); } - /** @deprecated */ @replacedBy("`instance.getType`") static getType(func: FunctionRef) { return BinaryenFunction.prototype.getType.call({[THIS_PTR]: func}); } - /** @deprecated */ @replacedBy("`instance.getParams`") static getParams(func: FunctionRef) { return BinaryenFunction.prototype.getParams.call({[THIS_PTR]: func}); } - /** @deprecated */ @replacedBy("`instance.getResults`") static getResults(func: FunctionRef) { return BinaryenFunction.prototype.getResults.call({[THIS_PTR]: func}); } - /** @deprecated */ @replacedBy("`instance.getNumVars`") static getNumVars(func: FunctionRef) { return BinaryenFunction.prototype.getNumVars.call({[THIS_PTR]: func}); } - /** @deprecated */ @replacedBy("`instance.getVar`") static getVar(func: FunctionRef, index: number) { return BinaryenFunction.prototype.getVar.call({[THIS_PTR]: func}, index); } - /** @deprecated */ @replacedBy("`instance.getNumLocals`") static getNumLocals(func: FunctionRef) { return BinaryenFunction.prototype.getNumLocals.call({[THIS_PTR]: func}); } - /** @deprecated */ @replacedBy("`instance.hasLocalName`") static hasLocalName(func: FunctionRef, index: number) { return BinaryenFunction.prototype.hasLocalName.call({[THIS_PTR]: func}, index); } - /** @deprecated */ @replacedBy("`instance.getLocalName`") static getLocalName(func: FunctionRef, index: number) { return BinaryenFunction.prototype.getLocalName.call({[THIS_PTR]: func}, index); } - /** @deprecated */ @replacedBy("`instance.setLocalName`") static setLocalName(func: FunctionRef, index: number, name: string) { return BinaryenFunction.prototype.setLocalName.call({[THIS_PTR]: func}, index, name); } - /** @deprecated */ @replacedBy("`instance.getBody`") static getBody(func: FunctionRef) { return BinaryenFunction.prototype.getBody.call({[THIS_PTR]: func}); } - /** @deprecated */ @replacedBy("`instance.setBody`") static setBody(func: FunctionRef, bodyExpr: ExpressionRef) { return BinaryenFunction.prototype.setBody.call({[THIS_PTR]: func}, bodyExpr); } - /* eslint-enable @stylistic/brace-style */ - - private readonly [THIS_PTR]: FunctionRef; readonly module: string; @@ -59,7 +40,7 @@ class BinaryenFunction { return this[THIS_PTR]; } - // TODO: post.js has converted all methods starting with `get` to getters and `set` to setters + // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters getName(): string { return UTF8ToString(BinaryenObj["_BinaryenFunctionGetName"](this[THIS_PTR])); } diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 7168d46e835..8cba34c7b2c 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -9,9 +9,6 @@ import { type Type, funcref, } from "../../constants.ts"; -import { - replacedBy, -} from "../../lib.ts"; import { THIS_PTR, preserveStack, @@ -24,19 +21,6 @@ import type { export class Table { - /* eslint-disable @stylistic/brace-style */ - /** @deprecated */ @replacedBy("`instance.getName`") static getName(table: TableRef) { return Table.prototype.getName.call({[THIS_PTR]: table}); } - /** @deprecated */ @replacedBy("`instance.setName`") static setName(table: TableRef, name: string) { return Table.prototype.setName.call({[THIS_PTR]: table}, name); } - /** @deprecated */ @replacedBy("`instance.getInitial`") static getInitial(table: TableRef) { return Table.prototype.getInitial.call({[THIS_PTR]: table}); } - /** @deprecated */ @replacedBy("`instance.setInitial`") static setInitial(table: TableRef, initial: number) { return Table.prototype.setInitial.call({[THIS_PTR]: table}, initial); } - /** @deprecated */ @replacedBy("`instance.hasMax`") static hasMax(table: TableRef) { return Table.prototype.hasMax.call({[THIS_PTR]: table}); } - /** @deprecated */ @replacedBy("`instance.getMax`") static getMax(table: TableRef) { return Table.prototype.getMax.call({[THIS_PTR]: table}); } - /** @deprecated */ @replacedBy("`instance.setMax`") static setMax(table: TableRef, max: number) { return Table.prototype.setMax.call({[THIS_PTR]: table}, max); } - /** @deprecated */ @replacedBy("`instance.getType`") static getType(table: TableRef) { return Table.prototype.getType.call({[THIS_PTR]: table}); } - /** @deprecated */ @replacedBy("`instance.setType`") static setType(table: TableRef, tableType: Type) { return Table.prototype.setType.call({[THIS_PTR]: table}, tableType); } - /* eslint-enable @stylistic/brace-style */ - - private readonly [THIS_PTR]: TableRef; readonly module: string; @@ -54,7 +38,7 @@ export class Table { return this[THIS_PTR]; } - // TODO: post.js has converted all methods starting with `get` to getters and `set` to setters + // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters /** * @return the name of this table */ From eaf2577776ff2f39554f3053903c4fce99e1aa23 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 07:34:58 -0400 Subject: [PATCH 048/247] refactor: condense Settings interface --- ts/src/services/SettingsService.ts | 64 ++++++++---------------------- 1 file changed, 16 insertions(+), 48 deletions(-) diff --git a/ts/src/services/SettingsService.ts b/ts/src/services/SettingsService.ts index 06474913ff6..c403c1fb65d 100644 --- a/ts/src/services/SettingsService.ts +++ b/ts/src/services/SettingsService.ts @@ -4,93 +4,61 @@ import { -interface Settings { - /** The currently set optimize level. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ - optimizeLevel: number; - - /** The currently set shrink level. 0, 1, 2 correspond to -O0, -Os, -Oz. */ - shrinkLevel: number; - - /** Is generating debug information currently enabled? */ - debugInfo: boolean; - - /** Whether no traps can be considered reached at runtime when optimizing. */ - trapsNeverHappen: boolean; - - /** Whether considering that the code outside of the module does not inspect or interact with GC and function references. */ - closedWorld: boolean; - - /** Whether the low 1K of memory can be considered unused when optimizing. */ - lowMemoryUnused: boolean; - - /** Whether that an imported memory will be zero-initialized speculation. */ - zeroFilledMemory: boolean; - - /** Whether fast math optimizations are enabled, ignoring for example corner cases of floating-point math like NaN changes. */ - fastMath: boolean; - - /** Whether to generate StackIR during binary writing. */ - generateStackIR: boolean; - - /** Whether to optimize StackIR during binary writing. */ - optimizeStackIR: boolean; - - /** The function size at which we always inline. */ - alwaysInlineMaxSize: number; - - /** The function size which we inline when functions are lightweight. */ - flexibleInlineMaxSize: number; - - /** The function size which we inline when there is only one caller. */ - oneCallerInlineMaxSize: number; - - /** Whether functions with loops are allowed to be inlined. */ - allowInliningFunctionsWithLoops: boolean; -} - - - -class SettingsService implements Settings { +class SettingsService { /* eslint-disable @stylistic/brace-style */ + /** The currently set optimize level. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ get optimizeLevel(): number { return BinaryenObj["_BinaryenGetOptimizeLevel"](); } set optimizeLevel(level: number) { BinaryenObj["_BinaryenSetOptimizeLevel"](level); } + /** The currently set shrink level. 0, 1, 2 correspond to -O0, -Os, -Oz. */ get shrinkLevel(): number { return BinaryenObj["_BinaryenGetShrinkLevel"](); } set shrinkLevel(level: number) { BinaryenObj["_BinaryenSetShrinkLevel"](level); } + /** Is generating debug information currently enabled? */ get debugInfo(): boolean { return Boolean(BinaryenObj["_BinaryenGetDebugInfo"]()); } set debugInfo(enabled: boolean) { BinaryenObj["_BinaryenSetDebugInfo"](enabled); } + /** Whether no traps can be considered reached at runtime when optimizing. */ get trapsNeverHappen(): boolean { return Boolean(BinaryenObj["_BinaryenGetTrapsNeverHappen"]()); } set trapsNeverHappen(enabled: boolean) { BinaryenObj["_BinaryenSetTrapsNeverHappen"](enabled); } + /** Whether considering that the code outside of the module does not inspect or interact with GC and function references. */ get closedWorld(): boolean { return Boolean(BinaryenObj["_BinaryenGetClosedWorld"]()); } set closedWorld(enabled: boolean) { BinaryenObj["_BinaryenSetClosedWorld"](enabled); } + /** Can the low 1K of memory be considered unused when optimizing? */ get lowMemoryUnused(): boolean { return Boolean(BinaryenObj["_BinaryenGetLowMemoryUnused"]()); } set lowMemoryUnused(enabled: boolean) { BinaryenObj["_BinaryenSetLowMemoryUnused"](enabled); } + /** Will an imported memory be zero-initialized speculation? */ get zeroFilledMemory(): boolean { return Boolean(BinaryenObj["_BinaryenGetZeroFilledMemory"]()); } set zeroFilledMemory(enabled: boolean) { BinaryenObj["_BinaryenSetZeroFilledMemory"](enabled); } + /** Whether fast math optimizations are enabled, ignoring for example corner cases of floating-point math like NaN changes. */ get fastMath(): boolean { return Boolean(BinaryenObj["_BinaryenGetFastMath"]()); } set fastMath(enabled: boolean) { BinaryenObj["_BinaryenSetFastMath"](enabled); } + /** Generate StackIR during binary writing? */ get generateStackIR(): boolean { return Boolean(BinaryenObj["_BinaryenGetGenerateStackIR"]()); } set generateStackIR(enabled: boolean) { BinaryenObj["_BinaryenSetGenerateStackIR"](enabled); } + /** Optimize StackIR during binary writing? */ get optimizeStackIR(): boolean { return Boolean(BinaryenObj["_BinaryenGetOptimizeStackIR"]()); } set optimizeStackIR(enabled: boolean) { BinaryenObj["_BinaryenSetOptimizeStackIR"](enabled); } + /** The function size at which we always inline. */ get alwaysInlineMaxSize(): number { return BinaryenObj["_BinaryenGetAlwaysInlineMaxSize"](); } set alwaysInlineMaxSize(size: number) { BinaryenObj["_BinaryenSetAlwaysInlineMaxSize"](size); } + /** The function size which we inline when functions are lightweight. */ get flexibleInlineMaxSize(): number { return BinaryenObj["_BinaryenGetFlexibleInlineMaxSize"](); } set flexibleInlineMaxSize(size: number) { BinaryenObj["_BinaryenSetFlexibleInlineMaxSize"](size); } + /** The function size which we inline when there is only one caller. */ get oneCallerInlineMaxSize(): number { return BinaryenObj["_BinaryenGetOneCallerInlineMaxSize"](); } set oneCallerInlineMaxSize(size: number) { BinaryenObj["_BinaryenSetOneCallerInlineMaxSize"](size); } + /** Are functions with loops allowed to be inlined? */ get allowInliningFunctionsWithLoops(): boolean { return Boolean(BinaryenObj["_BinaryenGetAllowInliningFunctionsWithLoops"]()); } set allowInliningFunctionsWithLoops(enabled: boolean) { BinaryenObj["_BinaryenSetAllowInliningFunctionsWithLoops"](enabled); } /* eslint-enable @stylistic/brace-style */ @@ -99,4 +67,4 @@ class SettingsService implements Settings { /** The global settings control. */ -export const settings: Settings = new SettingsService(); +export const settings = new SettingsService(); From f9a91fe211d8dc779b60831c6005b3697e62bbae Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 07:43:56 -0400 Subject: [PATCH 049/247] refactor: move pass settings to SettingsService --- ts/src/-deprecations.ts | 33 +++++++++++++++++++++ ts/src/globals.ts | 45 ----------------------------- ts/src/services/SettingsService.ts | 46 ++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 45 deletions(-) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 6b4922611e2..25e3dd8e2ad 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -226,3 +226,36 @@ export function setAllowInliningFunctionsWithLoops(enabled: boolean) { consoleWarn("Global function `setAllowInliningFunctionsWithLoops` is deprecated; use `settings.allowInliningFunctionsWithLoops = enabled` instead."); settings.allowInliningFunctionsWithLoops = enabled; } + + + +/** @deprecated Use `settings.getPassArgument(key)` instead. */ +export function getPassArgument(key: string) { + consoleWarn("Global function `getPassArgument` is deprecated; use `settings.getPassArgument(key)` instead."); + return settings.getPassArgument(key); +} +/** @deprecated Use `settings.setPassArgument(key, value)` instead. */ +export function setPassArgument(key: string, value?: string) { + consoleWarn("Global function `setPassArgument` is deprecated; use `settings.setPassArgument(key, value)` instead."); + return settings.setPassArgument(key, value); +} +/** @deprecated Use `settings.clearPassArguments()` instead. */ +export function clearPassArguments() { + consoleWarn("Global function `clearPassArguments` is deprecated; use `settings.clearPassArguments()` instead."); + return settings.clearPassArguments(); +} +/** @deprecated Use `settings.hasPassToSkip(pass)` instead. */ +export function hasPassToSkip(pass: string) { + consoleWarn("Global function `hasPassToSkip` is deprecated; use `settings.hasPassToSkip(pass)` instead."); + return settings.hasPassToSkip(pass); +} +/** @deprecated Use `settings.addPassToSkip(pass)` instead. */ +export function addPassToSkip(pass: string) { + consoleWarn("Global function `addPassToSkip` is deprecated; use `settings.addPassToSkip(pass)` instead."); + return settings.addPassToSkip(pass); +} +/** @deprecated Use `settings.clearPassesToSkip()` instead. */ +export function clearPassesToSkip() { + consoleWarn("Global function `clearPassesToSkip` is deprecated; use `settings.clearPassesToSkip()` instead."); + return settings.clearPassesToSkip(); +} diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 969041116ee..9ed7f554bbe 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -7,7 +7,6 @@ import { _free, _malloc, BinaryenObj, - UTF8ToString, getExceptionMessage, stackAlloc, stringToAscii, @@ -31,7 +30,6 @@ import { HEAPU32, i32sToStack, preserveStack, - strToStack, } from "./utils.ts"; @@ -197,46 +195,3 @@ export function getExpressionInfo(expr: ExpressionRef): Expression { export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, mod.ptr); } - - - -// ## Pass Settings ## // -/** Gets the value of the specified arbitrary pass argument. */ -export function getPassArgument(key: string): string | undefined { - return preserveStack(() => { - const returned = BinaryenObj["_BinaryenGetPassArgument"](strToStack(key)); - return returned ? UTF8ToString(returned) : undefined; - }); -} - -/** - * Sets the value of the specified arbitrary pass argument. - * Removes the respective argument if `value` is NULL. - */ -export function setPassArgument(key: string, value: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenSetPassArgument"](strToStack(key), strToStack(value)); - }); -} - -/** Clears all arbitrary pass arguments. */ -export function clearPassArguments(): void { - BinaryenObj["_BinaryenClearPassArguments"](); -} - -/** Gets whether a pass is in the set of passes to skip. */ -export function hasPassToSkip(pass: string): boolean { - return preserveStack(() => Boolean(BinaryenObj["_BinaryenHasPassToSkip"](strToStack(pass)))); -} - -/** Add a pass to the set of passes to skip. */ -export function addPassToSkip(pass: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddPassToSkip"](strToStack(pass)); - }); -} - -/** Clears the set of passes to skip. */ -export function clearPassesToSkip(): void { - BinaryenObj["_BinaryenClearPassesToSkip"](); -} diff --git a/ts/src/services/SettingsService.ts b/ts/src/services/SettingsService.ts index c403c1fb65d..fe67564a4c9 100644 --- a/ts/src/services/SettingsService.ts +++ b/ts/src/services/SettingsService.ts @@ -1,6 +1,11 @@ import { BinaryenObj, + UTF8ToString, } from "../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../utils.ts"; @@ -62,6 +67,47 @@ class SettingsService { get allowInliningFunctionsWithLoops(): boolean { return Boolean(BinaryenObj["_BinaryenGetAllowInliningFunctionsWithLoops"]()); } set allowInliningFunctionsWithLoops(enabled: boolean) { BinaryenObj["_BinaryenSetAllowInliningFunctionsWithLoops"](enabled); } /* eslint-enable @stylistic/brace-style */ + + + /** Gets the value of the specified arbitrary pass argument. */ + getPassArgument(key: string): string | undefined { + return preserveStack(() => { + const returned = BinaryenObj["_BinaryenGetPassArgument"](strToStack(key)); + return returned ? UTF8ToString(returned) : undefined; + }); + } + + /** + * Sets the value of the specified arbitrary pass argument. + * Removes the respective argument if `value` is `undefined` or an empty string. + */ + setPassArgument(key: string, value?: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenSetPassArgument"](strToStack(key), strToStack(value)); + }); + } + + /** Clears all arbitrary pass arguments. */ + clearPassArguments(): void { + BinaryenObj["_BinaryenClearPassArguments"](); + } + + /** Gets whether a pass is in the set of passes to skip. */ + hasPassToSkip(pass: string): boolean { + return preserveStack(() => Boolean(BinaryenObj["_BinaryenHasPassToSkip"](strToStack(pass)))); + } + + /** Add a pass to the set of passes to skip. */ + addPassToSkip(pass: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddPassToSkip"](strToStack(pass)); + }); + } + + /** Clears the set of passes to skip. */ + clearPassesToSkip(): void { + BinaryenObj["_BinaryenClearPassesToSkip"](); + } } From 14b29f0b38c6ed18169c3d1405751f98f879a02b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 20:01:24 -0400 Subject: [PATCH 050/247] refactor: Module as a namespace --- ts/src/-deprecations.ts | 45 ++++++--- ts/src/classes/module/DataSegment.ts | 2 + ts/src/classes/module/ElementSegment.ts | 2 + ts/src/classes/module/Export.ts | 2 + ts/src/classes/module/Function.ts | 2 + ts/src/classes/module/Global.ts | 2 + ts/src/classes/module/Import.ts | 1 + ts/src/classes/module/Memory.ts | 1 + ts/src/classes/module/Module.ts | 129 ++++++++++++++---------- ts/src/classes/module/Table.ts | 2 + ts/src/classes/module/Tag.ts | 2 + 11 files changed, 119 insertions(+), 71 deletions(-) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 25e3dd8e2ad..b4719790824 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -3,27 +3,21 @@ import { + type ElementSegmentRef, + type ExportRef, ExpressionId, ExternalKind, + type FunctionRef, + type GlobalRef, Operation, SideEffect, - type TagRef, - type GlobalRef, type TableRef, - type FunctionRef, - type ElementSegmentRef, - type ExportRef, + type TagRef, } from "./constants.ts"; -import { - Function as BinaryenFunction, -} from "./classes/module/Function.ts"; import { Feature, Module, } from "./classes/module/Module.ts"; -import { - Table as BinaryenTable, -} from "./classes/module/Table.ts"; import { consoleWarn, } from "./lib.ts"; @@ -46,10 +40,28 @@ export const Features = Feature; -/** @deprecated The `Function` class now lives as a static member of the `Module` class. Use `Module.Function`. */ -export const Function = BinaryenFunction; -/** @deprecated The `Table` class now lives as a static member of the `Module` class. Use `Module.Table`. */ -export const Table = BinaryenTable; +/** @deprecated The `TagInfo` object type is now called `Module.Tag`. */ +export type TagInfo = Module.Tag; +/** @deprecated The `GlobalInfo` object type is now called `Module.Global`. */ +export type GlobalInfo = Module.Global; +/** @deprecated The `MemoryInfo` object type is now called `Module.Memory`*/ +export type MemoryInfo = Module.Memory; +/** @deprecated The `TableInfo` object type is now called `Module.Table`. */ +export type TableInfo = Module.Table; +/** @deprecated The `FunctionInfo` object type is now called `Module.Function`. */ +export type FunctionInfo = Module.Function; +// type `DataSegmentInfo` never existed +/** @deprecated The `ElementSegmentInfo` object type is now called `Module.ElementSegment`. */ +export type ElementSegmentInfo = Module.ElementSegment; +// type `ImportInfo` never existed +/** @deprecated The `ExportInfo` object type is now called `Module.Export`. */ +export type ExportInfo = Module.Export; + + +/** @deprecated The `Function` class now lives under the `Module` namespace. Use `Module.Function`. */ +export const Function = Module.Function; +/** @deprecated The `Table` class now lives under the `Module` namespace. Use `Module.Table`. */ +export const Table = Module.Table; @@ -63,6 +75,7 @@ export function getGlobalInfo(global: GlobalRef) { consoleWarn("Global function `getGlobalInfo` is deprecated; use `new Module.Global(globalref)` instead."); return new Module.Global(global); } +// function `getMemoryInfo` always existed in `Module` /** @deprecated Use `new Module.Table(tableref)` instead. */ export function getTableInfo(table: TableRef) { consoleWarn("Global function `getTableInfo` is deprecated; use `new Module.Table(tableref)` instead."); @@ -73,11 +86,13 @@ export function getFunctionInfo(func: FunctionRef) { consoleWarn("Global function `getFunctionInfo` is deprecated; use `new Module.Function(funcref)` instead."); return new Module.Function(func); } +// function `getDataSegmentInfo` always existed in `Module` /** @deprecated Use `new Module.ElementSegment(segmentref)` instead. */ export function getElementSegmentInfo(segment: ElementSegmentRef) { consoleWarn("Global function `getElementSegmentInfo` is deprecated; use `new Module.ElementSegment(segmentref)` instead."); return new Module.ElementSegment(segment); } +// no function `getImportInfo` ever existed /** @deprecated Use `new Module.Export(exportref)` instead. */ export function getExportInfo(xport: ExportRef) { consoleWarn("Global function `getExportInfo` is deprecated; use `new Module.Export(exportref)` instead."); diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index 7bfbb5c10f9..4579bd09754 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -18,6 +18,7 @@ import type { +/** Information about a data segment in a WASM module. */ export class DataSegment { readonly name: string; readonly offset?: number; @@ -45,6 +46,7 @@ export class DataSegment { +/** Methods for manipulating data segments in a WASM module. */ export class ModuleDataSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index b82391955f4..0e80ea5b72a 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -17,6 +17,7 @@ import type { +/** Information about an element segment in a WASM module. */ export class ElementSegment { readonly name: string; readonly table: string; @@ -41,6 +42,7 @@ export class ElementSegment { +/** Methods for manipulating element segments in a WASM module. */ export class ModuleElementSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index 7853ea0db3e..5f42e55167a 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -16,6 +16,7 @@ import type { +/** Information about an export in a WASM module. */ export class Export { readonly kind: ExternalKind; readonly name: string; @@ -31,6 +32,7 @@ export class Export { +/** Methods for manipulating exports in a WASM module. */ export class ModuleExports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index db42cf7adcb..4ffcf814bfb 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -20,6 +20,7 @@ import type { +/** Information about a function in a WASM module. */ class BinaryenFunction { private readonly [THIS_PTR]: FunctionRef; @@ -95,6 +96,7 @@ export {BinaryenFunction as Function}; +/** Methods for manipulating functions in a WASM module. */ export class ModuleFunctions { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Global.ts b/ts/src/classes/module/Global.ts index 5cfbefea95a..653e151ef06 100644 --- a/ts/src/classes/module/Global.ts +++ b/ts/src/classes/module/Global.ts @@ -17,6 +17,7 @@ import type { +/** Information about a global in a WASM module. */ export class Global { readonly name: string; readonly module: string; @@ -38,6 +39,7 @@ export class Global { +/** Methods for manipulating globals in a WASM module. */ export class ModuleGlobals { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index e698e1e987e..8d8a61bae32 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -14,6 +14,7 @@ import type { +/** Methods for manipulating imports in a WASM module. */ export class ModuleImports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index a2faeb01aec..1b5305648ae 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -11,6 +11,7 @@ import type { +/** Information about a memory in a WASM module. */ export class Memory { readonly module: string; readonly base: string; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 597cb14f7c7..d5e6a3bbacb 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -37,40 +37,15 @@ import { localSet, localTee, } from "../expression/LocalSet.ts"; -import { - DataSegment, - ModuleDataSegments, -} from "./DataSegment.ts"; -import { - ElementSegment, - ModuleElementSegments, -} from "./ElementSegment.ts"; -import { - Export, - ModuleExports, -} from "./Export.ts"; -import { - Function as BinaryenFunction, - ModuleFunctions, -} from "./Function.ts"; -import { - Global, - ModuleGlobals, -} from "./Global.ts"; -import { - ModuleImports, -} from "./Import.ts"; -import { - Memory, -} from "./Memory.ts"; -import { - Table, - ModuleTables, -} from "./Table.ts"; -import { - Tag, - ModuleTags, -} from "./Tag.ts"; +import * as DATA_SEGMENT from "./DataSegment.ts"; +import * as ELEMENT_SEGMENT from "./ElementSegment.ts"; +import * as EXPORT from "./Export.ts"; +import * as FUNCTION from "./Function.ts"; +import * as GLOBAL from "./Global.ts"; +import * as IMPORT from "./Import.ts"; +import * as MEMORY from "./Memory.ts"; +import * as TABLE from "./Table.ts"; +import * as TAG from "./Tag.ts"; @@ -132,17 +107,36 @@ export enum Feature { +/** + * A WASM module. + * + * `Module` itself is: + * - an instantiable class (via `new Module()`) + * - a namespace containing the following members, which themselves are classes (see related documentation): + * - {@link Tag} + * - {@link Global} + * - {@link Memory} + * - {@link Table} + * - {@link Function} + * - {@link DataSegment} + * - {@link ElementSegment} + * - (no `Import`) + * - {@link Export} + * + * Each instance of `Module` is: + * - a WASM module with module manipulation methods (`.emitText()`, `.validate()`, etc.). + * - an individual namespace containing mixins, each with its own component manipulation methods (`.tags.add()`, `.globals.get()`, etc): + * - {@link TAG.ModuleTags|tags} + * - {@link GLOBAL.ModuleGlobals|globals} + * - (no `memories`) + * - {@link TABLE.ModuleTables|tables} + * - {@link FUNCTION.ModuleFunctions|functions} + * - {@link DATA_SEGMENT.ModuleDataSegments|dataSegments} + * - {@link ELEMENT_SEGMENT.ModuleElementSegments|elementSegments} + * - {@link IMPORT.ModuleImports|imports} + * - {@link EXPORT.ModuleExports|exports} + */ export class Module { - static readonly Tag = Tag; - static readonly Global = Global; - static readonly Memory = Memory; - static readonly Table = Table; - static readonly Function = BinaryenFunction; - static readonly DataSegment = DataSegment; - static readonly ElementSegment = ElementSegment; - static readonly Export = Export; - - readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); // ## Expression Creation ## // @@ -160,14 +154,14 @@ export class Module { // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html - readonly tags = new ModuleTags(this); - readonly globals = new ModuleGlobals(this); - readonly tables = new ModuleTables(this); - readonly functions = new ModuleFunctions(this); - readonly dataSegments = new ModuleDataSegments(this); - readonly elementSegments = new ModuleElementSegments(this); - readonly imports = new ModuleImports(this); - readonly exports = new ModuleExports(this); + readonly tags = new TAG.ModuleTags(this); + readonly globals = new GLOBAL.ModuleGlobals(this); + readonly tables = new TABLE.ModuleTables(this); + readonly functions = new FUNCTION.ModuleFunctions(this); + readonly dataSegments = new DATA_SEGMENT.ModuleDataSegments(this); + readonly elementSegments = new ELEMENT_SEGMENT.ModuleElementSegments(this); + readonly imports = new IMPORT.ModuleImports(this); + readonly exports = new EXPORT.ModuleExports(this); /* eslint-disable @stylistic/brace-style */ /** @deprecated Use `this.tags.add` instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } @@ -270,12 +264,12 @@ export class Module { return Boolean(BinaryenObj["_BinaryenHasMemory"](this.ptr)); } - getMemoryInfo(name: string): Memory { - return new Memory(this, name); + getMemoryInfo(name: string): MEMORY.Memory { + return new MEMORY.Memory(this, name); } - getDataSegmentInfo(segment: DataSegmentRef): DataSegment { - return new DataSegment(this, segment); + getDataSegmentInfo(segment: DataSegmentRef): DATA_SEGMENT.DataSegment { + return new DATA_SEGMENT.DataSegment(this, segment); } getStart(): FunctionRef { @@ -420,3 +414,26 @@ export class Module { return BinaryenObj["_BinaryenExpressionCopy"](expr, this.ptr); } } + + + +// eslint-disable-next-line no-redeclare +export namespace Module { + export type Tag = TAG.Tag; + export type Global = GLOBAL.Global; + export type Memory = MEMORY.Memory; + export type Table = TABLE.Table; + export type Function = FUNCTION.Function; + export type DataSegment = DATA_SEGMENT.DataSegment; + export type ElementSegment = ELEMENT_SEGMENT.ElementSegment; + export type Export = EXPORT.Export; + + export const Tag = TAG.Tag; + export const Global = GLOBAL.Global; + export const Memory = MEMORY.Memory; + export const Table = TABLE.Table; + export const Function = FUNCTION.Function; + export const DataSegment = DATA_SEGMENT.DataSegment; + export const ElementSegment = ELEMENT_SEGMENT.ElementSegment; + export const Export = EXPORT.Export; +} diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 8cba34c7b2c..7200b663979 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -20,6 +20,7 @@ import type { +/** Information about a table in a WASM module. */ export class Table { private readonly [THIS_PTR]: TableRef; @@ -107,6 +108,7 @@ export class Table { +/** Methods for manipulating tables in a WASM module. */ export class ModuleTables { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Tag.ts b/ts/src/classes/module/Tag.ts index 738cfdef04e..475276d7a6a 100644 --- a/ts/src/classes/module/Tag.ts +++ b/ts/src/classes/module/Tag.ts @@ -16,6 +16,7 @@ import type { +/** Information about a tag in a WASM module. */ export class Tag { readonly name: string; readonly module: string; @@ -35,6 +36,7 @@ export class Tag { +/** Methods for manipulating tags in a WASM module. */ export class ModuleTags { constructor(private readonly mod: Module) {} From 1028d800747f0843bf26ab689f3ac75d9e6d28ee Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 22:16:45 -0400 Subject: [PATCH 051/247] refactor: add `ModuleMemories` --- ts/src/classes/module/Memory.ts | 75 +++++++++++++++++++++++++++++++++ ts/src/classes/module/Module.ts | 67 +++-------------------------- 2 files changed, 80 insertions(+), 62 deletions(-) diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index 1b5305648ae..20654a40386 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -1,8 +1,16 @@ import { + _free, + _malloc, BinaryenObj, UTF8ToString, } from "../../-pre.ts"; +import type { + ExpressionRef, +} from "../../constants.ts"; import { + HEAP8, + i32sToStack, + preserveStack, strToStack, } from "../../utils.ts"; import type { @@ -11,6 +19,16 @@ import type { +/** Similar to a `DataSegment` but with some minor differences. */ +interface MemorySegment { + name?: string; + offset: ExpressionRef; + data: Uint8Array; + passive: boolean; +} + + + /** Information about a memory in a WASM module. */ export class Memory { readonly module: string; @@ -32,3 +50,60 @@ export class Memory { } } } + + + +/** Methods for manipulating memories in a WASM module. */ +export class ModuleMemories { + constructor(private readonly mod: Module) {} + + /** Sets the memory. There’s just one memory for now, using name "0". Providing `exportName` also creates a memory export. */ + set( + initial: number, + maximum: number, + exportName: string, + segments: readonly MemorySegment[] = [], + shared: boolean = false, + memory64: boolean = false, + internalName?: string, + ): void { + return preserveStack(() => { + const names: number[] = []; + const datas: number[] = []; + const passives: number[] = []; + const offsets: number[] = []; + const lengths: number[] = []; + for (let i = 0; i < segments.length; i++) { + const {name, data, passive, offset} = segments[i]; + names[i] = strToStack(name); + datas[i] = _malloc(data.length); + passives[i] = Number(passive); + offsets[i] = offset; + HEAP8.set(data, datas[i]); + lengths[i] = data.length; + } + BinaryenObj["_BinaryenSetMemory"]( + this.mod.ptr, + initial, + maximum, + strToStack(exportName), + i32sToStack(names), + i32sToStack(datas), + i32sToStack(passives), + i32sToStack(offsets), + i32sToStack(lengths), + segments.length, + shared, + memory64, + strToStack(internalName), + ); + for (const dataptr of datas) { + _free(dataptr); + } + }); + } + + has(): boolean { + return Boolean(BinaryenObj["_BinaryenHasMemory"](this.mod.ptr)); + } +} diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index d5e6a3bbacb..649a507265a 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -1,7 +1,6 @@ import { _BinaryenSizeofAllocateAndWriteResult, _free, - _malloc, BinaryenObj, UTF8ToString, stackAlloc, @@ -19,7 +18,6 @@ import { replacedBy, } from "../../lib.ts"; import { - HEAP8, HEAPU8, HEAPU32, i8sToStack, @@ -54,16 +52,6 @@ declare let out: any; -/** Similar to a `DataSegment` but with some minor differences. */ -interface MemorySegment { - name?: string; - offset: ExpressionRef; - data: Uint8Array; - passive: boolean; -} - - - /** * The size of a single literal in memory as used in Const creation, * which is a little different: we don’t want users to need to make @@ -128,7 +116,7 @@ export enum Feature { * - an individual namespace containing mixins, each with its own component manipulation methods (`.tags.add()`, `.globals.get()`, etc): * - {@link TAG.ModuleTags|tags} * - {@link GLOBAL.ModuleGlobals|globals} - * - (no `memories`) + * - {@link MEMORY.ModuleMemories|memories} * - {@link TABLE.ModuleTables|tables} * - {@link FUNCTION.ModuleFunctions|functions} * - {@link DATA_SEGMENT.ModuleDataSegments|dataSegments} @@ -156,6 +144,7 @@ export class Module { // see https://webassembly.github.io/spec/core/syntax/modules.html readonly tags = new TAG.ModuleTags(this); readonly globals = new GLOBAL.ModuleGlobals(this); + readonly memories = new MEMORY.ModuleMemories(this); readonly tables = new TABLE.ModuleTables(this); readonly functions = new FUNCTION.ModuleFunctions(this); readonly dataSegments = new DATA_SEGMENT.ModuleDataSegments(this); @@ -174,6 +163,9 @@ export class Module { /** @deprecated Use `this.globals.count` instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } /** @deprecated Use `this.globals.remove` instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } + /** @deprecated Use `this.memories.set` instead. */ @replacedBy("`this.memories.set`") setMemory(initial: number, maximum: number, exportName: string, segments?: readonly any[], shared?: boolean, memory64?: boolean, internalName?: string) { return this.memories.set(initial, maximum, exportName, segments, shared, memory64, internalName); } + /** @deprecated Use `this.memories.has` instead. */ @replacedBy("`this.memories.has`") hasMemory() { return this.memories.has(); } + /** @deprecated Use `this.tables.add` instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } /** @deprecated Use `this.tables.get` instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } /** @deprecated Use `this.tables.getByIndex` instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } @@ -215,55 +207,6 @@ export class Module { /** @deprecated Use `this.exports.remove` instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } /* eslint-enable @stylistic/brace-style */ - setMemory( - initial: number, - maximum: number, - exportName: string, - segments: readonly MemorySegment[] = [], - shared: boolean = false, - memory64: boolean = false, - internalName?: string, - ): void { - return preserveStack(() => { - const names: number[] = []; - const datas: number[] = []; - const passives: number[] = []; - const offsets: number[] = []; - const lengths: number[] = []; - for (let i = 0; i < segments.length; i++) { - const {name, data, passive, offset} = segments[i]; - names[i] = strToStack(name); - datas[i] = _malloc(data.length); - passives[i] = Number(passive); - offsets[i] = offset; - HEAP8.set(data, datas[i]); - lengths[i] = data.length; - } - BinaryenObj["_BinaryenSetMemory"]( - this.ptr, - initial, - maximum, - strToStack(exportName), - i32sToStack(names), - i32sToStack(datas), - i32sToStack(passives), - i32sToStack(offsets), - i32sToStack(lengths), - segments.length, - shared, - memory64, - strToStack(internalName), - ); - for (const dataptr of datas) { - _free(dataptr); - } - }); - } - - hasMemory(): boolean { - return Boolean(BinaryenObj["_BinaryenHasMemory"](this.ptr)); - } - getMemoryInfo(name: string): MEMORY.Memory { return new MEMORY.Memory(this, name); } From 5026d8a7c87a82fb5c9ceca7ff9109f77e3ca7ed Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 22:23:00 -0400 Subject: [PATCH 052/247] feat: add `Import` for consistency --- ts/src/classes/module/Import.ts | 7 +++++++ ts/src/classes/module/Module.ts | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index 8d8a61bae32..c0827c1a33a 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -14,6 +14,13 @@ import type { +/** Information about an import in a WASM module. */ +export class Import { + constructor() {} +} + + + /** Methods for manipulating imports in a WASM module. */ export class ModuleImports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 649a507265a..3b23aa2da39 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -108,7 +108,7 @@ export enum Feature { * - {@link Function} * - {@link DataSegment} * - {@link ElementSegment} - * - (no `Import`) + * - {@link Import} * - {@link Export} * * Each instance of `Module` is: @@ -369,6 +369,7 @@ export namespace Module { export type Function = FUNCTION.Function; export type DataSegment = DATA_SEGMENT.DataSegment; export type ElementSegment = ELEMENT_SEGMENT.ElementSegment; + export type Import = IMPORT.Import; export type Export = EXPORT.Export; export const Tag = TAG.Tag; @@ -378,5 +379,6 @@ export namespace Module { export const Function = FUNCTION.Function; export const DataSegment = DATA_SEGMENT.DataSegment; export const ElementSegment = ELEMENT_SEGMENT.ElementSegment; + export const Import = IMPORT.Import; export const Export = EXPORT.Export; } From 08e5fd494ba2bd785fe1ad46de385bf34a3ac4b6 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 22:24:04 -0400 Subject: [PATCH 053/247] refactor: arrange `Module{Import,Export}s` methods --- ts/src/classes/module/Export.ts | 36 ++++++++++++++++----------------- ts/src/classes/module/Import.ts | 24 +++++++++++----------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index 5f42e55167a..5b794e4c6d4 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -36,8 +36,22 @@ export class Export { export class ModuleExports { constructor(private readonly mod: Module) {} - #addComponent(binaryenFuncName: string, internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj[binaryenFuncName](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + get(externalName: string): ExportRef { + return preserveStack(() => BinaryenObj["_BinaryenGetExport"](this.mod.ptr, strToStack(externalName))); + } + + getByIndex(index: number): ExportRef { + return BinaryenObj["_BinaryenGetExportByIndex"](this.mod.ptr, index); + } + + count(): number { + return BinaryenObj["_BinaryenGetNumExports"](this.mod.ptr); + } + + remove(externalName: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenRemoveExport"](this.mod.ptr, strToStack(externalName)); + }); } addTag(internalName: string, externalName: string): ExportRef { @@ -60,21 +74,7 @@ export class ModuleExports { return this.#addComponent("_BinaryenAddFunctionExport", internalName, externalName); } - get(externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenGetExport"](this.mod.ptr, strToStack(externalName))); - } - - getByIndex(index: number): ExportRef { - return BinaryenObj["_BinaryenGetExportByIndex"](this.mod.ptr, index); - } - - count(): number { - return BinaryenObj["_BinaryenGetNumExports"](this.mod.ptr); - } - - remove(externalName: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveExport"](this.mod.ptr, strToStack(externalName)); - }); + #addComponent(binaryenFuncName: string, internalName: string, externalName: string): ExportRef { + return preserveStack(() => BinaryenObj[binaryenFuncName](this.mod.ptr, strToStack(internalName), strToStack(externalName))); } } diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index c0827c1a33a..50792f62ea8 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -25,18 +25,6 @@ export class Import { export class ModuleImports { constructor(private readonly mod: Module) {} - #addComponent(binaryenFuncName: string, internalName: string, externalModuleName: string, externalBaseName: string, ...rest: any[]): void { - return preserveStack(() => { - BinaryenObj[binaryenFuncName]( - this.mod.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - ...rest, - ); - }); - } - addTag(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { return this.#addComponent("_BinaryenAddTagImport", internalName, externalModuleName, externalBaseName, params, results); } @@ -56,4 +44,16 @@ export class ModuleImports { addFunction(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { return this.#addComponent("_BinaryenAddFunctionImport", internalName, externalModuleName, externalBaseName, params, results); } + + #addComponent(binaryenFuncName: string, internalName: string, externalModuleName: string, externalBaseName: string, ...rest: any[]): void { + return preserveStack(() => { + BinaryenObj[binaryenFuncName]( + this.mod.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + ...rest, + ); + }); + } } From b0b09cea5bd6476bfc2af7d469aa46387e3f7500 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 23:20:25 -0400 Subject: [PATCH 054/247] docs: doccomment module manipulation methods --- ts/src/classes/module/DataSegment.ts | 3 +++ ts/src/classes/module/ElementSegment.ts | 6 +++++ ts/src/classes/module/Export.ts | 9 +++++++ ts/src/classes/module/Function.ts | 5 ++++ ts/src/classes/module/Global.ts | 5 ++++ ts/src/classes/module/Import.ts | 5 ++++ ts/src/classes/module/Memory.ts | 1 + ts/src/classes/module/Module.ts | 34 +++++++++++++++++++++++++ ts/src/classes/module/Table.ts | 6 +++++ ts/src/classes/module/Tag.ts | 3 +++ ts/src/constants.ts | 14 +++++++--- ts/src/globals.ts | 14 +++++++--- 12 files changed, 99 insertions(+), 6 deletions(-) diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index 4579bd09754..71240e72101 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -50,14 +50,17 @@ export class DataSegment { export class ModuleDataSegments { constructor(private readonly mod: Module) {} + /** Gets a data segment by name. */ get(name: string): DataSegmentRef { return preserveStack(() => BinaryenObj["_BinaryenGetDataSegment"](this.mod.ptr, strToStack(name))); } + /** Gets a data segment by index. */ getByIndex(index: number): DataSegmentRef { return BinaryenObj["_BinaryenGetDataSegmentByIndex"](this.mod.ptr, index); } + /** Gets the number of data segments within the module. */ count(): number { return BinaryenObj["_BinaryenGetNumDataSegments"](this.mod.ptr); } diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index 0e80ea5b72a..aac32bb3783 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -46,6 +46,7 @@ export class ElementSegment { export class ModuleElementSegments { constructor(private readonly mod: Module) {} + /** Adds an active element segment. */ addActive(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef): ElementSegmentRef { return preserveStack(() => BinaryenObj["_BinaryenAddActiveElementSegment"]( this.mod.ptr, @@ -57,6 +58,7 @@ export class ModuleElementSegments { )); } + /** Adds a passive element segment. */ addPassive(name: string, funcNames: readonly string[]): ElementSegmentRef { return preserveStack(() => BinaryenObj["_BinaryenAddPassiveElementSegment"]( this.mod.ptr, @@ -66,18 +68,22 @@ export class ModuleElementSegments { )); } + /** Gets an element segment by name. */ get(name: string): ElementSegmentRef { return preserveStack(() => BinaryenObj["_BinaryenGetElementSegment"](this.mod.ptr, strToStack(name))); } + /** Gets an element segment by index. */ getByIndex(index: number): ElementSegmentRef { return BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.mod.ptr, index); } + /** Gets the number of element segments within the module. */ count(): number { return BinaryenObj["_BinaryenGetNumElementSegments"](this.mod.ptr); } + /** Removes an element segment by name. */ remove(name: string): void { return preserveStack(() => { BinaryenObj["_BinaryenRemoveElementSegment"](this.mod.ptr, strToStack(name)); diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index 5b794e4c6d4..e3e46be1443 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -36,40 +36,49 @@ export class Export { export class ModuleExports { constructor(private readonly mod: Module) {} + /** Gets an export by name. */ get(externalName: string): ExportRef { return preserveStack(() => BinaryenObj["_BinaryenGetExport"](this.mod.ptr, strToStack(externalName))); } + /** Gets an export by index. */ getByIndex(index: number): ExportRef { return BinaryenObj["_BinaryenGetExportByIndex"](this.mod.ptr, index); } + /** Gets the number of exports witin the module. */ count(): number { return BinaryenObj["_BinaryenGetNumExports"](this.mod.ptr); } + /** Removes an export, by external name. */ remove(externalName: string): void { return preserveStack(() => { BinaryenObj["_BinaryenRemoveExport"](this.mod.ptr, strToStack(externalName)); }); } + /** Adds a tag export. */ addTag(internalName: string, externalName: string): ExportRef { return this.#addComponent("_BinaryenAddTagExport", internalName, externalName); } + /** Adds a global variable export. Exported globals must be immutable. */ addGlobal(internalName: string, externalName: string): ExportRef { return this.#addComponent("_BinaryenAddGlobalExport", internalName, externalName); } + /** Adds a memory export. There’s just one memory for now, using name "0". */ addMemory(internalName: string, externalName: string): ExportRef { return this.#addComponent("_BinaryenAddMemoryExport", internalName, externalName); } + /** Adds a table export. There’s just one table for now, using name "0". */ addTable(internalName: string, externalName: string): ExportRef { return this.#addComponent("_BinaryenAddTableExport", internalName, externalName); } + /** Adds a function export. */ addFunction(internalName: string, externalName: string): ExportRef { return this.#addComponent("_BinaryenAddFunctionExport", internalName, externalName); } diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index 4ffcf814bfb..aefc184293f 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -100,6 +100,7 @@ export {BinaryenFunction as Function}; export class ModuleFunctions { constructor(private readonly mod: Module) {} + /** Adds a function. `varTypes` indicate additional locals, in the given order. */ add(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef): FunctionRef { return preserveStack(() => BinaryenObj["_BinaryenAddFunction"]( this.mod.ptr, @@ -112,18 +113,22 @@ export class ModuleFunctions { )); } + /** Gets a function by name. */ get(name: string): FunctionRef { return preserveStack(() => BinaryenObj["_BinaryenGetFunction"](this.mod.ptr, strToStack(name))); } + /** Gets a function by index. */ getByIndex(index: number): FunctionRef { return BinaryenObj["_BinaryenGetFunctionByIndex"](this.mod.ptr, index); } + /** Gets the number of functions within the module. */ count(): number { return BinaryenObj["_BinaryenGetNumFunctions"](this.mod.ptr); } + /** Removes a function by name. */ remove(name: string): void { return preserveStack(() => { BinaryenObj["_BinaryenRemoveFunction"](this.mod.ptr, strToStack(name)); diff --git a/ts/src/classes/module/Global.ts b/ts/src/classes/module/Global.ts index 653e151ef06..0527c019b63 100644 --- a/ts/src/classes/module/Global.ts +++ b/ts/src/classes/module/Global.ts @@ -43,22 +43,27 @@ export class Global { export class ModuleGlobals { constructor(private readonly mod: Module) {} + /** Adds a global instance variable. */ add(name: string, type: Type, mutable: boolean, init: ExpressionRef): GlobalRef { return preserveStack(() => BinaryenObj["_BinaryenAddGlobal"](this.mod.ptr, strToStack(name), type, mutable, init)); } + /** Gets a global by name. */ get(name: string): GlobalRef { return preserveStack(() => BinaryenObj["_BinaryenGetGlobal"](this.mod.ptr, strToStack(name))); } + /** Gets a global by index. */ getByIndex(index: number): GlobalRef { return BinaryenObj["_BinaryenGetGlobalByIndex"](this.mod.ptr, index); } + /** Gets the number of globals within the module. */ count(): number { return BinaryenObj["_BinaryenGetNumGlobals"](this.mod.ptr); } + /** Removes a global by name. */ remove(name: string): void { return preserveStack(() => { BinaryenObj["_BinaryenRemoveGlobal"](this.mod.ptr, strToStack(name)); diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index 50792f62ea8..98a9104cb45 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -25,22 +25,27 @@ export class Import { export class ModuleImports { constructor(private readonly mod: Module) {} + /** Adds a tag import. */ addTag(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { return this.#addComponent("_BinaryenAddTagImport", internalName, externalModuleName, externalBaseName, params, results); } + /** Adds a global variable import. Imported globals must be immutable. */ addGlobal(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean): void { return this.#addComponent("_BinaryenAddGlobalImport", internalName, externalModuleName, externalBaseName, globalType, mutable); } + /** Adds a memory import. There’s just one memory for now, using name "0". */ addMemory(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean): void { return this.#addComponent("_BinaryenAddMemoryImport", internalName, externalModuleName, externalBaseName, shared); } + /** Adds a table import. There’s just one table for now, using name "0". */ addTable(internalName: string, externalModuleName: string, externalBaseName: string): void { return this.#addComponent("_BinaryenAddTableImport", internalName, externalModuleName, externalBaseName); } + /** Adds a function import. */ addFunction(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type): void { return this.#addComponent("_BinaryenAddFunctionImport", internalName, externalModuleName, externalBaseName, params, results); } diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index 20654a40386..7cfe57300c5 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -103,6 +103,7 @@ export class ModuleMemories { }); } + /** Returns whether the module has a memory. */ has(): boolean { return Boolean(BinaryenObj["_BinaryenHasMemory"](this.mod.ptr)); } diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 3b23aa2da39..5fce4254a91 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -215,11 +215,19 @@ export class Module { return new DATA_SEGMENT.DataSegment(this, segment); } + // TODO: turn this into a getter/setter + /** Gets the start function, if any. */ getStart(): FunctionRef { return BinaryenObj["_BinaryenGetStart"](this.ptr); } + /** Sets the start function. */ + setStart(start: FunctionRef): void { + BinaryenObj["_BinaryenSetStart"](this.ptr, start); + } + // ## Binaryen Operations ## // + /** Returns the module in Binaryen’s s-expression text format (not official stack-style text format). */ emitText(): string { const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteText"](this.ptr); const text = UTF8ToString(textPtr); @@ -229,6 +237,7 @@ export class Module { return text; } + /** Returns the module in official stack-style text format. */ emitStackIR(): string { const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteStackIR"](this.ptr); const text = UTF8ToString(textPtr); @@ -238,6 +247,7 @@ export class Module { return text; } + /** Returns the [asm.js](http://asmjs.org/) representation of the module. */ emitAsmjs(): string { let returned = ""; const saved = out; @@ -249,7 +259,9 @@ export class Module { return returned; } + /** Returns the module in binary format. */ emitBinary(): Uint8Array; + /** Returns the module in binary format with a given source map. */ emitBinary(sourceMapUrl: string): {binary: Uint8Array, sourceMap: string}; emitBinary(sourceMapUrl?: string): Uint8Array | {binary: Uint8Array, sourceMap: string} { return preserveStack(() => { @@ -273,10 +285,19 @@ export class Module { }); } + // TODO: turn this into a getter/setter + /** + * Gets the WebAssembly features enabled for this module. + * Features are a bitmask of `Feature` enum members. + */ getFeatures(): Feature { return BinaryenObj["_BinaryenModuleGetFeatures"](this.ptr); } + /** + * Sets the WebAssembly features enabled for this module. + * Features are a bitmask of `Feature` enum members. + */ setFeatures(features: Feature): void { BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); } @@ -293,24 +314,29 @@ export class Module { }); } + /** Adds a custom section to the binary */ addCustomSection(name: string, contents: Uint8Array): void { return preserveStack(() => { BinaryenObj["_BinaryenAddCustomSection"](this.ptr, strToStack(name), i8sToStack([...contents]), contents.length); }); } + /** Runs the module in the interpreter, calling the start function. */ interpret(): void { BinaryenObj["_BinaryenModuleInterpret"](this.ptr); } + /** Validates the module. Returns `true` if valid, otherwise prints validation errors and returns `false`. */ validate(): number { return BinaryenObj["_BinaryenModuleValidate"](this.ptr); } + /** Optimizes the module using the default optimization passes. */ optimize(): void { BinaryenObj["_BinaryenModuleOptimize"](this.ptr); } + /** Optimizes a single function using the default optimization passes. */ optimizeFunction(func: FunctionRef | string): void { if (typeof func === "string") { func = this.functions.get(func); @@ -318,16 +344,19 @@ export class Module { BinaryenObj["_BinaryenFunctionOptimize"](func, this.ptr); } + /** [description] */ updateMaps(): void { BinaryenObj["_BinaryenModuleUpdateMaps"](this.ptr); } + /** Runs the specified passes on the module. */ runPasses(passes: readonly string[]): void { return preserveStack(() => { BinaryenObj["_BinaryenModuleRunPasses"](this.ptr, i32sToStack(passes.map(strToStack)), passes.length); }); } + /** Runs the specified passes on a single function. */ runPassesOnFunction(func: string | FunctionRef, passes: readonly string[]): void { if (typeof func === "string") { func = this.functions.get(func); @@ -337,22 +366,27 @@ export class Module { }); } + /** Releases the resources held by the module once it isn't needed anymore. */ dispose(): void { BinaryenObj["_BinaryenModuleDispose"](this.ptr); } + /** Adds a debug info file name to the module and returns its index. */ addDebugInfoFileName(filename: string): number { return preserveStack(() => BinaryenObj["_BinaryenModuleAddDebugInfoFileName"](this.ptr, strToStack(filename))); } + /** Gets the name of the debug info file at the specified index. */ getDebugInfoFileName(index: number): string { return UTF8ToString(BinaryenObj["_BinaryenModuleGetDebugInfoFileName"](this.ptr, index)); } + /** Sets the debug location of the specified `ExpressionRef` within the specified `FunctionRef`. */ setDebugLocation(func: FunctionRef, expr: ExpressionRef, fileIndex: number, lineNumber: number, columnNumber: number): void { BinaryenObj["_BinaryenFunctionSetDebugLocation"](func, expr, fileIndex, lineNumber, columnNumber); } + /** Creates a deep copy of an expression. */ copyExpression(expr: ExpressionRef): ExpressionRef { return BinaryenObj["_BinaryenExpressionCopy"](expr, this.ptr); } diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 7200b663979..a7e3c27b001 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -112,18 +112,22 @@ export class Table { export class ModuleTables { constructor(private readonly mod: Module) {} + /** Adds a table. */ add(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef): TableRef { return preserveStack(() => BinaryenObj["_BinaryenAddTable"](this.mod.ptr, strToStack(name), initial, maximum, type, init ?? 0)); } + /** Gets a table by name. */ get(name: string): TableRef { return preserveStack(() => BinaryenObj["_BinaryenGetTable"](this.mod.ptr, strToStack(name))); } + /** Gets a table by index. */ getByIndex(index: number): TableRef { return BinaryenObj["_BinaryenGetTableByIndex"](this.mod.ptr, index); } + /** Gets the number of table segments within the module. */ getSegments(table: TableRef): ElementSegmentRef[] { const numElementSegments = BinaryenObj["_BinaryenGetNumElementSegments"](this.mod.ptr); const tableName = UTF8ToString(BinaryenObj["_BinaryenTableGetName"](table)); @@ -138,10 +142,12 @@ export class ModuleTables { return ret; } + /** Gets the number of tables within the module. */ count(): number { return BinaryenObj["_BinaryenGetNumTables"](this.mod.ptr); } + /** Removes a table by name. */ remove(name: string): void { return preserveStack(() => { BinaryenObj["_BinaryenRemoveTable"](this.mod.ptr, strToStack(name)); diff --git a/ts/src/classes/module/Tag.ts b/ts/src/classes/module/Tag.ts index 475276d7a6a..2944246699e 100644 --- a/ts/src/classes/module/Tag.ts +++ b/ts/src/classes/module/Tag.ts @@ -40,14 +40,17 @@ export class Tag { export class ModuleTags { constructor(private readonly mod: Module) {} + /** Adds a tag. */ add(name: string, params: Type, results: Type): TagRef { return preserveStack(() => BinaryenObj["_BinaryenAddTag"](this.mod.ptr, strToStack(name), params, results)); } + /** Gets a tag by name. */ get(name: string): TagRef { return preserveStack(() => BinaryenObj["_BinaryenGetTag"](this.mod.ptr, strToStack(name))); } + /** Removes a tag by name. */ remove(name: string): void { return preserveStack(() => { BinaryenObj["_BinaryenRemoveTag"](this.mod.ptr, strToStack(name)); diff --git a/ts/src/constants.ts b/ts/src/constants.ts index f0188be5bde..80f3d251cef 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -19,10 +19,12 @@ export type ExpressionRef = number; // ### Module Components ### // export type TagRef = number; export type GlobalRef = number; +// no `MemoryRef` export type TableRef = number; export type FunctionRef = number; export type DataSegmentRef = number; export type ElementSegmentRef = number; +// no `ImportRef` export type ExportRef = number; // ### Binaryen Tools ### // @@ -44,10 +46,15 @@ export const none: Type = BinaryenObj["_BinaryenTypeNone"](); export const auto: Type = BinaryenObj["_BinaryenTypeAuto"](); // ### Number & Vector Types ### // +/** 32-bit integer. */ export const i32: Type = BinaryenObj["_BinaryenTypeInt32"](); +/** 64-bit integer. */ export const i64: Type = BinaryenObj["_BinaryenTypeInt64"](); +/** 64-bit float. */ export const f32: Type = BinaryenObj["_BinaryenTypeFloat32"](); +/** 64-bit float. */ export const f64: Type = BinaryenObj["_BinaryenTypeFloat64"](); +/** 128-bit vector (SIMD). */ export const v128: Type = BinaryenObj["_BinaryenTypeVec128"](); // ### Reference Types ### // @@ -77,9 +84,9 @@ export const nullfuncref: Type = BinaryenObj["_BinaryenTypeNullFuncref"](); export const nullexternref: Type = BinaryenObj["_BinaryenTypeNullExternref"](); // ### Packed Types ### // -export const notPacked: Type = BinaryenObj["_BinaryenPackedTypeNotPacked"](); -export const i8: Type = BinaryenObj["_BinaryenPackedTypeInt8"](); -export const i16: Type = BinaryenObj["_BinaryenPackedTypeInt16"](); +export const notPacked: PackedType = BinaryenObj["_BinaryenPackedTypeNotPacked"](); +export const i8: PackedType = BinaryenObj["_BinaryenPackedTypeInt8"](); +export const i16: PackedType = BinaryenObj["_BinaryenPackedTypeInt16"](); // ### Proposed Types ### // // These types are not yet in the WASM spec. Move them to their respective sections once finalized. @@ -680,6 +687,7 @@ export enum MemoryOrder { +/** Expression side-effects. */ export enum SideEffect { None = BinaryenObj["_BinaryenSideEffectNone"](), Branches = BinaryenObj["_BinaryenSideEffectBranches"](), diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 9ed7f554bbe..e7a669b7815 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -86,6 +86,7 @@ function handleFatalError(func: () => T): T { // ## General Binaryen Functions ## // /** Probably used in `BinaryenObj["_BinaryenExpressionPrint"]`. */ declare let out: any; +/** Emits the expression in Binaryen’s s-expression text format (not official stack-style text format). */ export function emitText(expr: ExpressionRef): string { let returned = ""; const saved = out; @@ -97,6 +98,7 @@ export function emitText(expr: ExpressionRef): string { return returned; } +/** Creates a module from binary data. */ export function readBinary(data: Uint8Array): Module { const buffer = _malloc(data.length); HEAP8.set(data, buffer); @@ -113,6 +115,7 @@ export function readBinaryWithFeatures(data: Uint8Array, features: Feature): Mod return wrapModule(ptr); } +/** Creates a module from Binaryen’s s-expression text format (not official stack-style text format). */ export function parseText(text: string): Module { const buffer = _malloc(text.length + 1); stringToAscii(text, buffer); @@ -177,21 +180,26 @@ export function getHeapType(typ: Type): HeapType { return BinaryenObj["_BinaryenTypeGetHeapType"](typ); } -/** - * A misnomer — returns not a unique “ID”, but the “kind” of the expression. - */ +/** A misnomer — returns not a unique “ID”, but the “kind” of the expression. */ export function getExpressionId(expr: ExpressionRef): ExpressionId { return BinaryenObj["_BinaryenExpressionGetId"](expr); } +/** Gets the type of the specified expression. */ export function getExpressionType(expr: ExpressionRef): Type { return BinaryenObj["_BinaryenExpressionGetType"](expr); } +/** + * Obtains information about an expression. + * Additional properties depend on the expression’s ID + * and are usually equivalent to the respective parameters when creating such an expression. + */ export function getExpressionInfo(expr: ExpressionRef): Expression { return new Expression(getExpressionId(expr), expr); } +/** Gets the side effects of the specified expression. */ export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, mod.ptr); } From 09df7714e691251ad216c581ba20d7f2dbe1b91e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 23:42:43 -0400 Subject: [PATCH 055/247] refactor: convert Module start & features to getters --- ts/src/classes/module/Module.ts | 56 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 5fce4254a91..519a968074d 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -152,6 +152,34 @@ export class Module { readonly imports = new IMPORT.ModuleImports(this); readonly exports = new EXPORT.ModuleExports(this); + /* eslint-disable @stylistic/brace-style */ + /** @deprecated Use `this.start` instead. */ @replacedBy("`this.start`") getStart() { return this.start; } + /** @deprecated Use `this.start` instead. */ @replacedBy("`this.start`") setStart(start: FunctionRef) { this.start = start; } + /** @deprecated Use `this.features` instead. */ @replacedBy("`this.features`") getFeatures() { return this.features; } + /** @deprecated Use `this.features` instead. */ @replacedBy("`this.features`") setFeatures(features: Feature) { return this.features = features; } + /* eslint-enable @stylistic/brace-style */ + + /** The start function. */ + get start(): FunctionRef { + return BinaryenObj["_BinaryenGetStart"](this.ptr); + } + + set start(start: FunctionRef) { + BinaryenObj["_BinaryenSetStart"](this.ptr, start); + } + + /** + * The WebAssembly features enabled for this module. + * Features are a bitmask of `Feature` enum members. + */ + get features(): Feature { + return BinaryenObj["_BinaryenModuleGetFeatures"](this.ptr); + } + + set features(features: Feature) { + BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); + } + /* eslint-disable @stylistic/brace-style */ /** @deprecated Use `this.tags.add` instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } /** @deprecated Use `this.tags.get` instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } @@ -215,17 +243,6 @@ export class Module { return new DATA_SEGMENT.DataSegment(this, segment); } - // TODO: turn this into a getter/setter - /** Gets the start function, if any. */ - getStart(): FunctionRef { - return BinaryenObj["_BinaryenGetStart"](this.ptr); - } - - /** Sets the start function. */ - setStart(start: FunctionRef): void { - BinaryenObj["_BinaryenSetStart"](this.ptr, start); - } - // ## Binaryen Operations ## // /** Returns the module in Binaryen’s s-expression text format (not official stack-style text format). */ emitText(): string { @@ -285,23 +302,6 @@ export class Module { }); } - // TODO: turn this into a getter/setter - /** - * Gets the WebAssembly features enabled for this module. - * Features are a bitmask of `Feature` enum members. - */ - getFeatures(): Feature { - return BinaryenObj["_BinaryenModuleGetFeatures"](this.ptr); - } - - /** - * Sets the WebAssembly features enabled for this module. - * Features are a bitmask of `Feature` enum members. - */ - setFeatures(features: Feature): void { - BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); - } - setTypeName(heapType: HeapType, name: string): void { return preserveStack(() => { BinaryenObj["_BinaryenModuleSetTypeName"](this.ptr, heapType, strToStack(name)); From cc72a89713c59bf549df05d01e6cf4944121ce51 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 1 May 2026 23:42:43 -0400 Subject: [PATCH 056/247] refactor: move `Module#copyExpression` to global --- ts/src/classes/module/Module.ts | 10 +++++++--- ts/src/globals.ts | 5 +++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 519a968074d..8d0ef254f59 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -14,6 +14,9 @@ import { type Type, funcref, } from "../../constants.ts"; +import { + copyExpression, +} from "../../globals.ts"; import { replacedBy, } from "../../lib.ts"; @@ -386,9 +389,10 @@ export class Module { BinaryenObj["_BinaryenFunctionSetDebugLocation"](func, expr, fileIndex, lineNumber, columnNumber); } - /** Creates a deep copy of an expression. */ - copyExpression(expr: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenExpressionCopy"](expr, this.ptr); + /** @deprecated Use global `copyExpression(expr, this)` instead. */ + @replacedBy("global `copyExpression(expr, this)`") + copyExpression(expr: ExpressionRef) { + return copyExpression(expr, this); } } diff --git a/ts/src/globals.ts b/ts/src/globals.ts index e7a669b7815..e043649a7e6 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -203,3 +203,8 @@ export function getExpressionInfo(expr: ExpressionRef): Expression { export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, mod.ptr); } + +/** Creates a deep copy of an expression. */ +export function copyExpression(expr: ExpressionRef, mod: Module): ExpressionRef { + return BinaryenObj["_BinaryenExpressionCopy"](expr, mod.ptr); +} From 40976ac4d6016e532f0684416d226274549069cf Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 00:05:50 -0400 Subject: [PATCH 057/247] refactor: rearrange Module methods --- ts/src/classes/module/Module.ts | 64 ++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 8d0ef254f59..f89884070c4 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -247,6 +247,7 @@ export class Module { } // ## Binaryen Operations ## // + // ### Emission & Execution ### // /** Returns the module in Binaryen’s s-expression text format (not official stack-style text format). */ emitText(): string { const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteText"](this.ptr); @@ -305,30 +306,17 @@ export class Module { }); } - setTypeName(heapType: HeapType, name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenModuleSetTypeName"](this.ptr, heapType, strToStack(name)); - }); - } - - setFieldName(heapType: HeapType, index: number, name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenModuleSetFieldName"](this.ptr, heapType, index, strToStack(name)); - }); - } - - /** Adds a custom section to the binary */ - addCustomSection(name: string, contents: Uint8Array): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddCustomSection"](this.ptr, strToStack(name), i8sToStack([...contents]), contents.length); - }); - } - /** Runs the module in the interpreter, calling the start function. */ interpret(): void { BinaryenObj["_BinaryenModuleInterpret"](this.ptr); } + /** Releases the resources held by the module once it isn't needed anymore. */ + dispose(): void { + BinaryenObj["_BinaryenModuleDispose"](this.ptr); + } + + // ### Validation & Optimization ### // /** Validates the module. Returns `true` if valid, otherwise prints validation errors and returns `false`. */ validate(): number { return BinaryenObj["_BinaryenModuleValidate"](this.ptr); @@ -347,11 +335,6 @@ export class Module { BinaryenObj["_BinaryenFunctionOptimize"](func, this.ptr); } - /** [description] */ - updateMaps(): void { - BinaryenObj["_BinaryenModuleUpdateMaps"](this.ptr); - } - /** Runs the specified passes on the module. */ runPasses(passes: readonly string[]): void { return preserveStack(() => { @@ -369,11 +352,7 @@ export class Module { }); } - /** Releases the resources held by the module once it isn't needed anymore. */ - dispose(): void { - BinaryenObj["_BinaryenModuleDispose"](this.ptr); - } - + // ### Debugging ### // /** Adds a debug info file name to the module and returns its index. */ addDebugInfoFileName(filename: string): number { return preserveStack(() => BinaryenObj["_BinaryenModuleAddDebugInfoFileName"](this.ptr, strToStack(filename))); @@ -389,6 +368,33 @@ export class Module { BinaryenObj["_BinaryenFunctionSetDebugLocation"](func, expr, fileIndex, lineNumber, columnNumber); } + // ### Other ### // + /** [description] */ + setTypeName(heapType: HeapType, name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenModuleSetTypeName"](this.ptr, heapType, strToStack(name)); + }); + } + + /** [description] */ + setFieldName(heapType: HeapType, index: number, name: string): void { + return preserveStack(() => { + BinaryenObj["_BinaryenModuleSetFieldName"](this.ptr, heapType, index, strToStack(name)); + }); + } + + /** Adds a custom section to the binary. */ + addCustomSection(name: string, contents: Uint8Array): void { + return preserveStack(() => { + BinaryenObj["_BinaryenAddCustomSection"](this.ptr, strToStack(name), i8sToStack([...contents]), contents.length); + }); + } + + /** [description] */ + updateMaps(): void { + BinaryenObj["_BinaryenModuleUpdateMaps"](this.ptr); + } + /** @deprecated Use global `copyExpression(expr, this)` instead. */ @replacedBy("global `copyExpression(expr, this)`") copyExpression(expr: ExpressionRef) { From 05954dd1a13b44acfc1d1326ff95f66ff2fde692 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 00:11:57 -0400 Subject: [PATCH 058/247] refactor: move Operation enum --- ts/src/-deprecations.ts | 12 +- ts/src/classes/expression/Operation.ts | 472 +++++++++++++++++++++++ ts/src/constants.ts | 501 +------------------------ 3 files changed, 496 insertions(+), 489 deletions(-) create mode 100644 ts/src/classes/expression/Operation.ts diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index b4719790824..e5434cec11c 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -9,11 +9,13 @@ import { ExternalKind, type FunctionRef, type GlobalRef, - Operation, SideEffect, type TableRef, type TagRef, } from "./constants.ts"; +import { + Operation, +} from "./classes/expression/Operation.ts"; import { Feature, Module, @@ -29,14 +31,14 @@ import { /** @deprecated The `ExpressionIds` enum has been renamed to `ExpressionId`. */ export const ExpressionIds = ExpressionId; -/** @deprecated The `Operations` enum has been renamed to `Operation`. */ -export const Operations = Operation; -/** @deprecated The `ExternalKinds` enum has been renamed to `ExternalKind`. */ -export const ExternalKinds = ExternalKind; /** @deprecated The `SideEffects` enum has been renamed to `SideEffect`. */ export const SideEffects = SideEffect; +/** @deprecated The `ExternalKinds` enum has been renamed to `ExternalKind`. */ +export const ExternalKinds = ExternalKind; /** @deprecated The `Features` enum has been renamed to `Feature`. */ export const Features = Feature; +/** @deprecated The `Operations` enum has been renamed to `Operation`. */ +export const Operations = Operation; diff --git a/ts/src/classes/expression/Operation.ts b/ts/src/classes/expression/Operation.ts new file mode 100644 index 00000000000..03ada68805e --- /dev/null +++ b/ts/src/classes/expression/Operation.ts @@ -0,0 +1,472 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; + + + +/** + * Operations + * @see https://webassembly.github.io/spec/core/exec/numerics.html + */ +export enum Operation { + // ### Control Operations ### // + BrOnNull = BinaryenObj["_BinaryenBrOnNull"](), + BrOnNonNull = BinaryenObj["_BinaryenBrOnNonNull"](), + BrOnCast = BinaryenObj["_BinaryenBrOnCast"](), + BrOnCastFail = BinaryenObj["_BinaryenBrOnCastFail"](), + + // ### Memory Operations ### // + Load8LaneVec128 = BinaryenObj["_BinaryenLoad8LaneVec128"](), + Load16LaneVec128 = BinaryenObj["_BinaryenLoad16LaneVec128"](), + Load32LaneVec128 = BinaryenObj["_BinaryenLoad32LaneVec128"](), + Load64LaneVec128 = BinaryenObj["_BinaryenLoad64LaneVec128"](), + Load8x8SVec128 = BinaryenObj["_BinaryenLoad8x8SVec128"](), + Load8x8UVec128 = BinaryenObj["_BinaryenLoad8x8UVec128"](), + Load16x4SVec128 = BinaryenObj["_BinaryenLoad16x4SVec128"](), + Load16x4UVec128 = BinaryenObj["_BinaryenLoad16x4UVec128"](), + Load32x2SVec128 = BinaryenObj["_BinaryenLoad32x2SVec128"](), + Load32x2UVec128 = BinaryenObj["_BinaryenLoad32x2UVec128"](), + Load8SplatVec128 = BinaryenObj["_BinaryenLoad8SplatVec128"](), + Load16SplatVec128 = BinaryenObj["_BinaryenLoad16SplatVec128"](), + Load32SplatVec128 = BinaryenObj["_BinaryenLoad32SplatVec128"](), + Load64SplatVec128 = BinaryenObj["_BinaryenLoad64SplatVec128"](), + Load32ZeroVec128 = BinaryenObj["_BinaryenLoad32ZeroVec128"](), + Load64ZeroVec128 = BinaryenObj["_BinaryenLoad64ZeroVec128"](), + Store8LaneVec128 = BinaryenObj["_BinaryenStore8LaneVec128"](), + Store16LaneVec128 = BinaryenObj["_BinaryenStore16LaneVec128"](), + Store32LaneVec128 = BinaryenObj["_BinaryenStore32LaneVec128"](), + Store64LaneVec128 = BinaryenObj["_BinaryenStore64LaneVec128"](), + + // ### Reference Operations ### // + RefAsNonNull = BinaryenObj["_BinaryenRefAsNonNull"](), + RefAsExternInternalize = BinaryenObj["_BinaryenRefAsExternInternalize"](), + RefAsExternExternalize = BinaryenObj["_BinaryenRefAsExternExternalize"](), + RefAsAnyConvertExtern = BinaryenObj["_BinaryenRefAsAnyConvertExtern"](), + RefAsExternConvertAny = BinaryenObj["_BinaryenRefAsExternConvertAny"](), + + // ### Integer Operations ### // + AddInt32 = BinaryenObj["_BinaryenAddInt32"](), + AddInt64 = BinaryenObj["_BinaryenAddInt64"](), + SubInt32 = BinaryenObj["_BinaryenSubInt32"](), + SubInt64 = BinaryenObj["_BinaryenSubInt64"](), + MulInt32 = BinaryenObj["_BinaryenMulInt32"](), + MulInt64 = BinaryenObj["_BinaryenMulInt64"](), + DivSInt32 = BinaryenObj["_BinaryenDivSInt32"](), + DivSInt64 = BinaryenObj["_BinaryenDivSInt64"](), + DivUInt32 = BinaryenObj["_BinaryenDivUInt32"](), + DivUInt64 = BinaryenObj["_BinaryenDivUInt64"](), + RemSInt32 = BinaryenObj["_BinaryenRemSInt32"](), + RemSInt64 = BinaryenObj["_BinaryenRemSInt64"](), + RemUInt32 = BinaryenObj["_BinaryenRemUInt32"](), + RemUInt64 = BinaryenObj["_BinaryenRemUInt64"](), + AndInt32 = BinaryenObj["_BinaryenAndInt32"](), + AndInt64 = BinaryenObj["_BinaryenAndInt64"](), + OrInt32 = BinaryenObj["_BinaryenOrInt32"](), + OrInt64 = BinaryenObj["_BinaryenOrInt64"](), + XorInt32 = BinaryenObj["_BinaryenXorInt32"](), + XorInt64 = BinaryenObj["_BinaryenXorInt64"](), + ShlInt32 = BinaryenObj["_BinaryenShlInt32"](), + ShlInt64 = BinaryenObj["_BinaryenShlInt64"](), + ShrSInt32 = BinaryenObj["_BinaryenShrSInt32"](), + ShrSInt64 = BinaryenObj["_BinaryenShrSInt64"](), + ShrUInt32 = BinaryenObj["_BinaryenShrUInt32"](), + ShrUInt64 = BinaryenObj["_BinaryenShrUInt64"](), + RotLInt32 = BinaryenObj["_BinaryenRotLInt32"](), + RotLInt64 = BinaryenObj["_BinaryenRotLInt64"](), + RotRInt32 = BinaryenObj["_BinaryenRotRInt32"](), + RotRInt64 = BinaryenObj["_BinaryenRotRInt64"](), + ClzInt32 = BinaryenObj["_BinaryenClzInt32"](), + ClzInt64 = BinaryenObj["_BinaryenClzInt64"](), + CtzInt32 = BinaryenObj["_BinaryenCtzInt32"](), + CtzInt64 = BinaryenObj["_BinaryenCtzInt64"](), + PopcntInt32 = BinaryenObj["_BinaryenPopcntInt32"](), + PopcntInt64 = BinaryenObj["_BinaryenPopcntInt64"](), + EqZInt32 = BinaryenObj["_BinaryenEqZInt32"](), + EqZInt64 = BinaryenObj["_BinaryenEqZInt64"](), + EqInt32 = BinaryenObj["_BinaryenEqInt32"](), + EqInt64 = BinaryenObj["_BinaryenEqInt64"](), + NeInt32 = BinaryenObj["_BinaryenNeInt32"](), + NeInt64 = BinaryenObj["_BinaryenNeInt64"](), + LtSInt32 = BinaryenObj["_BinaryenLtSInt32"](), + LtSInt64 = BinaryenObj["_BinaryenLtSInt64"](), + LtUInt32 = BinaryenObj["_BinaryenLtUInt32"](), + LtUInt64 = BinaryenObj["_BinaryenLtUInt64"](), + GtSInt32 = BinaryenObj["_BinaryenGtSInt32"](), + GtSInt64 = BinaryenObj["_BinaryenGtSInt64"](), + GtUInt32 = BinaryenObj["_BinaryenGtUInt32"](), + GtUInt64 = BinaryenObj["_BinaryenGtUInt64"](), + LeSInt32 = BinaryenObj["_BinaryenLeSInt32"](), + LeSInt64 = BinaryenObj["_BinaryenLeSInt64"](), + LeUInt32 = BinaryenObj["_BinaryenLeUInt32"](), + LeUInt64 = BinaryenObj["_BinaryenLeUInt64"](), + GeSInt32 = BinaryenObj["_BinaryenGeSInt32"](), + GeSInt64 = BinaryenObj["_BinaryenGeSInt64"](), + GeUInt32 = BinaryenObj["_BinaryenGeUInt32"](), + GeUInt64 = BinaryenObj["_BinaryenGeUInt64"](), + ExtendS8Int32 = BinaryenObj["_BinaryenExtendS8Int32"](), + ExtendS8Int64 = BinaryenObj["_BinaryenExtendS8Int64"](), + ExtendS16Int32 = BinaryenObj["_BinaryenExtendS16Int32"](), + ExtendS16Int64 = BinaryenObj["_BinaryenExtendS16Int64"](), + ExtendS32Int64 = BinaryenObj["_BinaryenExtendS32Int64"](), + + // ### Floating-Point Operations ### // + AddFloat32 = BinaryenObj["_BinaryenAddFloat32"](), + AddFloat64 = BinaryenObj["_BinaryenAddFloat64"](), + SubFloat32 = BinaryenObj["_BinaryenSubFloat32"](), + SubFloat64 = BinaryenObj["_BinaryenSubFloat64"](), + MulFloat32 = BinaryenObj["_BinaryenMulFloat32"](), + MulFloat64 = BinaryenObj["_BinaryenMulFloat64"](), + DivFloat32 = BinaryenObj["_BinaryenDivFloat32"](), + DivFloat64 = BinaryenObj["_BinaryenDivFloat64"](), + MinFloat32 = BinaryenObj["_BinaryenMinFloat32"](), + MinFloat64 = BinaryenObj["_BinaryenMinFloat64"](), + MaxFloat32 = BinaryenObj["_BinaryenMaxFloat32"](), + MaxFloat64 = BinaryenObj["_BinaryenMaxFloat64"](), + CopySignFloat32 = BinaryenObj["_BinaryenCopySignFloat32"](), + CopySignFloat64 = BinaryenObj["_BinaryenCopySignFloat64"](), + AbsFloat32 = BinaryenObj["_BinaryenAbsFloat32"](), + AbsFloat64 = BinaryenObj["_BinaryenAbsFloat64"](), + NegFloat32 = BinaryenObj["_BinaryenNegFloat32"](), + NegFloat64 = BinaryenObj["_BinaryenNegFloat64"](), + SqrtFloat32 = BinaryenObj["_BinaryenSqrtFloat32"](), + SqrtFloat64 = BinaryenObj["_BinaryenSqrtFloat64"](), + CeilFloat32 = BinaryenObj["_BinaryenCeilFloat32"](), + CeilFloat64 = BinaryenObj["_BinaryenCeilFloat64"](), + FloorFloat32 = BinaryenObj["_BinaryenFloorFloat32"](), + FloorFloat64 = BinaryenObj["_BinaryenFloorFloat64"](), + TruncFloat32 = BinaryenObj["_BinaryenTruncFloat32"](), + TruncFloat64 = BinaryenObj["_BinaryenTruncFloat64"](), + NearestFloat32 = BinaryenObj["_BinaryenNearestFloat32"](), + NearestFloat64 = BinaryenObj["_BinaryenNearestFloat64"](), + EqFloat32 = BinaryenObj["_BinaryenEqFloat32"](), + EqFloat64 = BinaryenObj["_BinaryenEqFloat64"](), + NeFloat32 = BinaryenObj["_BinaryenNeFloat32"](), + NeFloat64 = BinaryenObj["_BinaryenNeFloat64"](), + LtFloat32 = BinaryenObj["_BinaryenLtFloat32"](), + LtFloat64 = BinaryenObj["_BinaryenLtFloat64"](), + GtFloat32 = BinaryenObj["_BinaryenGtFloat32"](), + GtFloat64 = BinaryenObj["_BinaryenGtFloat64"](), + LeFloat32 = BinaryenObj["_BinaryenLeFloat32"](), + LeFloat64 = BinaryenObj["_BinaryenLeFloat64"](), + GeFloat32 = BinaryenObj["_BinaryenGeFloat32"](), + GeFloat64 = BinaryenObj["_BinaryenGeFloat64"](), + + // ### Conversions ### // + ExtendSInt32 = BinaryenObj["_BinaryenExtendSInt32"](), + ExtendUInt32 = BinaryenObj["_BinaryenExtendUInt32"](), + WrapInt64 = BinaryenObj["_BinaryenWrapInt64"](), + TruncSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSFloat32ToInt32"](), + TruncSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSFloat32ToInt64"](), + TruncSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSFloat64ToInt32"](), + TruncSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSFloat64ToInt64"](), + TruncUFloat32ToInt32 = BinaryenObj["_BinaryenTruncUFloat32ToInt32"](), + TruncUFloat32ToInt64 = BinaryenObj["_BinaryenTruncUFloat32ToInt64"](), + TruncUFloat64ToInt32 = BinaryenObj["_BinaryenTruncUFloat64ToInt32"](), + TruncUFloat64ToInt64 = BinaryenObj["_BinaryenTruncUFloat64ToInt64"](), + TruncSatSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt32"](), + TruncSatSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt64"](), + TruncSatSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt32"](), + TruncSatSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt64"](), + TruncSatUFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt32"](), + TruncSatUFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt64"](), + TruncSatUFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt32"](), + TruncSatUFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt64"](), + PromoteFloat32 = BinaryenObj["_BinaryenPromoteFloat32"](), + DemoteFloat64 = BinaryenObj["_BinaryenDemoteFloat64"](), + ConvertSInt32ToFloat32 = BinaryenObj["_BinaryenConvertSInt32ToFloat32"](), + ConvertSInt32ToFloat64 = BinaryenObj["_BinaryenConvertSInt32ToFloat64"](), + ConvertSInt64ToFloat32 = BinaryenObj["_BinaryenConvertSInt64ToFloat32"](), + ConvertSInt64ToFloat64 = BinaryenObj["_BinaryenConvertSInt64ToFloat64"](), + ConvertUInt32ToFloat32 = BinaryenObj["_BinaryenConvertUInt32ToFloat32"](), + ConvertUInt32ToFloat64 = BinaryenObj["_BinaryenConvertUInt32ToFloat64"](), + ConvertUInt64ToFloat32 = BinaryenObj["_BinaryenConvertUInt64ToFloat32"](), + ConvertUInt64ToFloat64 = BinaryenObj["_BinaryenConvertUInt64ToFloat64"](), + ReinterpretInt32 = BinaryenObj["_BinaryenReinterpretInt32"](), + ReinterpretInt64 = BinaryenObj["_BinaryenReinterpretInt64"](), + ReinterpretFloat32 = BinaryenObj["_BinaryenReinterpretFloat32"](), + ReinterpretFloat64 = BinaryenObj["_BinaryenReinterpretFloat64"](), + + // ### Vector Operations ### // + // #### vvunop #### // + NotVec128 = BinaryenObj["_BinaryenNotVec128"](), + // #### vvbinop #### // + AndVec128 = BinaryenObj["_BinaryenAndVec128"](), + AndNotVec128 = BinaryenObj["_BinaryenAndNotVec128"](), + OrVec128 = BinaryenObj["_BinaryenOrVec128"](), + XorVec128 = BinaryenObj["_BinaryenXorVec128"](), + // #### vvternop #### // + BitselectVec128 = BinaryenObj["_BinaryenBitselectVec128"](), + // #### vvtestop #### // + AnyTrueVec128 = BinaryenObj["_BinaryenAnyTrueVec128"](), + // #### vunop_i #### // + AbsVecI8x16 = BinaryenObj["_BinaryenAbsVecI8x16"](), + AbsVecI16x8 = BinaryenObj["_BinaryenAbsVecI16x8"](), + AbsVecI32x4 = BinaryenObj["_BinaryenAbsVecI32x4"](), + AbsVecI64x2 = BinaryenObj["_BinaryenAbsVecI64x2"](), + NegVecI8x16 = BinaryenObj["_BinaryenNegVecI8x16"](), + NegVecI16x8 = BinaryenObj["_BinaryenNegVecI16x8"](), + NegVecI32x4 = BinaryenObj["_BinaryenNegVecI32x4"](), + NegVecI64x2 = BinaryenObj["_BinaryenNegVecI64x2"](), + PopcntVecI8x16 = BinaryenObj["_BinaryenPopcntVecI8x16"](), + // #### vunop_f #### // + AbsVecF32x4 = BinaryenObj["_BinaryenAbsVecF32x4"](), + AbsVecF64x2 = BinaryenObj["_BinaryenAbsVecF64x2"](), + NegVecF32x4 = BinaryenObj["_BinaryenNegVecF32x4"](), + NegVecF64x2 = BinaryenObj["_BinaryenNegVecF64x2"](), + SqrtVecF32x4 = BinaryenObj["_BinaryenSqrtVecF32x4"](), + SqrtVecF64x2 = BinaryenObj["_BinaryenSqrtVecF64x2"](), + CeilVecF32x4 = BinaryenObj["_BinaryenCeilVecF32x4"](), + CeilVecF64x2 = BinaryenObj["_BinaryenCeilVecF64x2"](), + FloorVecF32x4 = BinaryenObj["_BinaryenFloorVecF32x4"](), + FloorVecF64x2 = BinaryenObj["_BinaryenFloorVecF64x2"](), + TruncVecF32x4 = BinaryenObj["_BinaryenTruncVecF32x4"](), + TruncVecF64x2 = BinaryenObj["_BinaryenTruncVecF64x2"](), + NearestVecF32x4 = BinaryenObj["_BinaryenNearestVecF32x4"](), + NearestVecF64x2 = BinaryenObj["_BinaryenNearestVecF64x2"](), + // #### vbinop_i #### // + AddVecI8x16 = BinaryenObj["_BinaryenAddVecI8x16"](), + AddVecI16x8 = BinaryenObj["_BinaryenAddVecI16x8"](), + AddVecI32x4 = BinaryenObj["_BinaryenAddVecI32x4"](), + AddVecI64x2 = BinaryenObj["_BinaryenAddVecI64x2"](), + SubVecI8x16 = BinaryenObj["_BinaryenSubVecI8x16"](), + SubVecI16x8 = BinaryenObj["_BinaryenSubVecI16x8"](), + SubVecI32x4 = BinaryenObj["_BinaryenSubVecI32x4"](), + SubVecI64x2 = BinaryenObj["_BinaryenSubVecI64x2"](), + AddSatSVecI8x16 = BinaryenObj["_BinaryenAddSatSVecI8x16"](), + AddSatSVecI16x8 = BinaryenObj["_BinaryenAddSatSVecI16x8"](), + AddSatUVecI8x16 = BinaryenObj["_BinaryenAddSatUVecI8x16"](), + AddSatUVecI16x8 = BinaryenObj["_BinaryenAddSatUVecI16x8"](), + SubSatSVecI8x16 = BinaryenObj["_BinaryenSubSatSVecI8x16"](), + SubSatSVecI16x8 = BinaryenObj["_BinaryenSubSatSVecI16x8"](), + SubSatUVecI8x16 = BinaryenObj["_BinaryenSubSatUVecI8x16"](), + SubSatUVecI16x8 = BinaryenObj["_BinaryenSubSatUVecI16x8"](), + MulVecI16x8 = BinaryenObj["_BinaryenMulVecI16x8"](), + MulVecI32x4 = BinaryenObj["_BinaryenMulVecI32x4"](), + MulVecI64x2 = BinaryenObj["_BinaryenMulVecI64x2"](), + AvgrUVecI8x16 = BinaryenObj["_BinaryenAvgrUVecI8x16"](), + AvgrUVecI16x8 = BinaryenObj["_BinaryenAvgrUVecI16x8"](), + Q15MulrSatSVecI16x8 = BinaryenObj["_BinaryenQ15MulrSatSVecI16x8"](), + RelaxedQ15MulrSVecI16x8 = BinaryenObj["_BinaryenRelaxedQ15MulrSVecI16x8"](), + MinSVecI8x16 = BinaryenObj["_BinaryenMinSVecI8x16"](), + MinSVecI16x8 = BinaryenObj["_BinaryenMinSVecI16x8"](), + MinSVecI32x4 = BinaryenObj["_BinaryenMinSVecI32x4"](), + MinUVecI8x16 = BinaryenObj["_BinaryenMinUVecI8x16"](), + MinUVecI16x8 = BinaryenObj["_BinaryenMinUVecI16x8"](), + MinUVecI32x4 = BinaryenObj["_BinaryenMinUVecI32x4"](), + MaxSVecI8x16 = BinaryenObj["_BinaryenMaxSVecI8x16"](), + MaxSVecI16x8 = BinaryenObj["_BinaryenMaxSVecI16x8"](), + MaxSVecI32x4 = BinaryenObj["_BinaryenMaxSVecI32x4"](), + MaxUVecI8x16 = BinaryenObj["_BinaryenMaxUVecI8x16"](), + MaxUVecI16x8 = BinaryenObj["_BinaryenMaxUVecI16x8"](), + MaxUVecI32x4 = BinaryenObj["_BinaryenMaxUVecI32x4"](), + // #### vbinop_f #### // + AddVecF32x4 = BinaryenObj["_BinaryenAddVecF32x4"](), + AddVecF64x2 = BinaryenObj["_BinaryenAddVecF64x2"](), + SubVecF32x4 = BinaryenObj["_BinaryenSubVecF32x4"](), + SubVecF64x2 = BinaryenObj["_BinaryenSubVecF64x2"](), + MulVecF32x4 = BinaryenObj["_BinaryenMulVecF32x4"](), + MulVecF64x2 = BinaryenObj["_BinaryenMulVecF64x2"](), + DivVecF32x4 = BinaryenObj["_BinaryenDivVecF32x4"](), + DivVecF64x2 = BinaryenObj["_BinaryenDivVecF64x2"](), + MinVecF32x4 = BinaryenObj["_BinaryenMinVecF32x4"](), + MinVecF64x2 = BinaryenObj["_BinaryenMinVecF64x2"](), + MaxVecF32x4 = BinaryenObj["_BinaryenMaxVecF32x4"](), + MaxVecF64x2 = BinaryenObj["_BinaryenMaxVecF64x2"](), + PMinVecF32x4 = BinaryenObj["_BinaryenPMinVecF32x4"](), + PMinVecF64x2 = BinaryenObj["_BinaryenPMinVecF64x2"](), + PMaxVecF32x4 = BinaryenObj["_BinaryenPMaxVecF32x4"](), + PMaxVecF64x2 = BinaryenObj["_BinaryenPMaxVecF64x2"](), + RelaxedMinVecF32x4 = BinaryenObj["_BinaryenRelaxedMinVecF32x4"](), + RelaxedMinVecF64x2 = BinaryenObj["_BinaryenRelaxedMinVecF64x2"](), + RelaxedMaxVecF32x4 = BinaryenObj["_BinaryenRelaxedMaxVecF32x4"](), + RelaxedMaxVecF64x2 = BinaryenObj["_BinaryenRelaxedMaxVecF64x2"](), + // #### vternop_i #### // + LaneselectI8x16 = BinaryenObj["_BinaryenLaneselectI8x16"](), + LaneselectI16x8 = BinaryenObj["_BinaryenLaneselectI16x8"](), + LaneselectI32x4 = BinaryenObj["_BinaryenLaneselectI32x4"](), + LaneselectI64x2 = BinaryenObj["_BinaryenLaneselectI64x2"](), + // #### vternop_f #### // + RelaxedMaddVecF32x4 = BinaryenObj["_BinaryenRelaxedMaddVecF32x4"](), + RelaxedMaddVecF64x2 = BinaryenObj["_BinaryenRelaxedMaddVecF64x2"](), + RelaxedNmaddVecF32x4 = BinaryenObj["_BinaryenRelaxedNmaddVecF32x4"](), + RelaxedNmaddVecF64x2 = BinaryenObj["_BinaryenRelaxedNmaddVecF64x2"](), + // #### vtestop_i #### // + AllTrueVecI8x16 = BinaryenObj["_BinaryenAllTrueVecI8x16"](), + AllTrueVecI16x8 = BinaryenObj["_BinaryenAllTrueVecI16x8"](), + AllTrueVecI32x4 = BinaryenObj["_BinaryenAllTrueVecI32x4"](), + AllTrueVecI64x2 = BinaryenObj["_BinaryenAllTrueVecI64x2"](), + // #### vrelop_i #### // + EqVecI8x16 = BinaryenObj["_BinaryenEqVecI8x16"](), + EqVecI16x8 = BinaryenObj["_BinaryenEqVecI16x8"](), + EqVecI32x4 = BinaryenObj["_BinaryenEqVecI32x4"](), + EqVecI64x2 = BinaryenObj["_BinaryenEqVecI64x2"](), + NeVecI8x16 = BinaryenObj["_BinaryenNeVecI8x16"](), + NeVecI16x8 = BinaryenObj["_BinaryenNeVecI16x8"](), + NeVecI32x4 = BinaryenObj["_BinaryenNeVecI32x4"](), + NeVecI64x2 = BinaryenObj["_BinaryenNeVecI64x2"](), + LtSVecI8x16 = BinaryenObj["_BinaryenLtSVecI8x16"](), + LtSVecI16x8 = BinaryenObj["_BinaryenLtSVecI16x8"](), + LtSVecI32x4 = BinaryenObj["_BinaryenLtSVecI32x4"](), + LtSVecI64x2 = BinaryenObj["_BinaryenLtSVecI64x2"](), + LtUVecI8x16 = BinaryenObj["_BinaryenLtUVecI8x16"](), + LtUVecI16x8 = BinaryenObj["_BinaryenLtUVecI16x8"](), + LtUVecI32x4 = BinaryenObj["_BinaryenLtUVecI32x4"](), + GtSVecI8x16 = BinaryenObj["_BinaryenGtSVecI8x16"](), + GtSVecI16x8 = BinaryenObj["_BinaryenGtSVecI16x8"](), + GtSVecI32x4 = BinaryenObj["_BinaryenGtSVecI32x4"](), + GtSVecI64x2 = BinaryenObj["_BinaryenGtSVecI64x2"](), + GtUVecI8x16 = BinaryenObj["_BinaryenGtUVecI8x16"](), + GtUVecI16x8 = BinaryenObj["_BinaryenGtUVecI16x8"](), + GtUVecI32x4 = BinaryenObj["_BinaryenGtUVecI32x4"](), + LeSVecI8x16 = BinaryenObj["_BinaryenLeSVecI8x16"](), + LeSVecI16x8 = BinaryenObj["_BinaryenLeSVecI16x8"](), + LeSVecI32x4 = BinaryenObj["_BinaryenLeSVecI32x4"](), + LeSVecI64x2 = BinaryenObj["_BinaryenLeSVecI64x2"](), + LeUVecI8x16 = BinaryenObj["_BinaryenLeUVecI8x16"](), + LeUVecI16x8 = BinaryenObj["_BinaryenLeUVecI16x8"](), + LeUVecI32x4 = BinaryenObj["_BinaryenLeUVecI32x4"](), + GeSVecI8x16 = BinaryenObj["_BinaryenGeSVecI8x16"](), + GeSVecI16x8 = BinaryenObj["_BinaryenGeSVecI16x8"](), + GeSVecI32x4 = BinaryenObj["_BinaryenGeSVecI32x4"](), + GeSVecI64x2 = BinaryenObj["_BinaryenGeSVecI64x2"](), + GeUVecI8x16 = BinaryenObj["_BinaryenGeUVecI8x16"](), + GeUVecI16x8 = BinaryenObj["_BinaryenGeUVecI16x8"](), + GeUVecI32x4 = BinaryenObj["_BinaryenGeUVecI32x4"](), + // #### vrelop_f #### // + EqVecF32x4 = BinaryenObj["_BinaryenEqVecF32x4"](), + EqVecF64x2 = BinaryenObj["_BinaryenEqVecF64x2"](), + NeVecF32x4 = BinaryenObj["_BinaryenNeVecF32x4"](), + NeVecF64x2 = BinaryenObj["_BinaryenNeVecF64x2"](), + LtVecF32x4 = BinaryenObj["_BinaryenLtVecF32x4"](), + LtVecF64x2 = BinaryenObj["_BinaryenLtVecF64x2"](), + GtVecF32x4 = BinaryenObj["_BinaryenGtVecF32x4"](), + GtVecF64x2 = BinaryenObj["_BinaryenGtVecF64x2"](), + LeVecF32x4 = BinaryenObj["_BinaryenLeVecF32x4"](), + LeVecF64x2 = BinaryenObj["_BinaryenLeVecF64x2"](), + GeVecF32x4 = BinaryenObj["_BinaryenGeVecF32x4"](), + GeVecF64x2 = BinaryenObj["_BinaryenGeVecF64x2"](), + // #### vshiftop #### // + ShlVecI8x16 = BinaryenObj["_BinaryenShlVecI8x16"](), + ShlVecI16x8 = BinaryenObj["_BinaryenShlVecI16x8"](), + ShlVecI32x4 = BinaryenObj["_BinaryenShlVecI32x4"](), + ShlVecI64x2 = BinaryenObj["_BinaryenShlVecI64x2"](), + ShrSVecI8x16 = BinaryenObj["_BinaryenShrSVecI8x16"](), + ShrSVecI16x8 = BinaryenObj["_BinaryenShrSVecI16x8"](), + ShrSVecI32x4 = BinaryenObj["_BinaryenShrSVecI32x4"](), + ShrSVecI64x2 = BinaryenObj["_BinaryenShrSVecI64x2"](), + ShrUVecI8x16 = BinaryenObj["_BinaryenShrUVecI8x16"](), + ShrUVecI16x8 = BinaryenObj["_BinaryenShrUVecI16x8"](), + ShrUVecI32x4 = BinaryenObj["_BinaryenShrUVecI32x4"](), + ShrUVecI64x2 = BinaryenObj["_BinaryenShrUVecI64x2"](), + // #### bitmask #### // + BitmaskVecI8x16 = BinaryenObj["_BinaryenBitmaskVecI8x16"](), + BitmaskVecI16x8 = BinaryenObj["_BinaryenBitmaskVecI16x8"](), + BitmaskVecI32x4 = BinaryenObj["_BinaryenBitmaskVecI32x4"](), + BitmaskVecI64x2 = BinaryenObj["_BinaryenBitmaskVecI64x2"](), + // #### vswizzleop #### // + SwizzleVecI8x16 = BinaryenObj["_BinaryenSwizzleVecI8x16"](), + RelaxedSwizzleVecI8x16 = BinaryenObj["_BinaryenRelaxedSwizzleVecI8x16"](), + // #### vextunop #### // + ExtAddPairwiseSVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseSVecI8x16ToI16x8"](), + ExtAddPairwiseSVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseSVecI16x8ToI32x4"](), + ExtAddPairwiseUVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseUVecI8x16ToI16x8"](), + ExtAddPairwiseUVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseUVecI16x8ToI32x4"](), + // #### vextbinop #### // + ExtMulLowSVecI16x8 = BinaryenObj["_BinaryenExtMulLowSVecI16x8"](), + ExtMulLowSVecI32x4 = BinaryenObj["_BinaryenExtMulLowSVecI32x4"](), + ExtMulLowSVecI64x2 = BinaryenObj["_BinaryenExtMulLowSVecI64x2"](), + ExtMulLowUVecI16x8 = BinaryenObj["_BinaryenExtMulLowUVecI16x8"](), + ExtMulLowUVecI32x4 = BinaryenObj["_BinaryenExtMulLowUVecI32x4"](), + ExtMulLowUVecI64x2 = BinaryenObj["_BinaryenExtMulLowUVecI64x2"](), + ExtMulHighSVecI16x8 = BinaryenObj["_BinaryenExtMulHighSVecI16x8"](), + ExtMulHighSVecI32x4 = BinaryenObj["_BinaryenExtMulHighSVecI32x4"](), + ExtMulHighSVecI64x2 = BinaryenObj["_BinaryenExtMulHighSVecI64x2"](), + ExtMulHighUVecI16x8 = BinaryenObj["_BinaryenExtMulHighUVecI16x8"](), + ExtMulHighUVecI32x4 = BinaryenObj["_BinaryenExtMulHighUVecI32x4"](), + ExtMulHighUVecI64x2 = BinaryenObj["_BinaryenExtMulHighUVecI64x2"](), + DotI8x16I7x16AddSToVecI32x4 = BinaryenObj["_BinaryenDotI8x16I7x16AddSToVecI32x4"](), + DotI8x16I7x16SToVecI16x8 = BinaryenObj["_BinaryenDotI8x16I7x16SToVecI16x8"](), + DotSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenDotSVecI16x8ToVecI32x4"](), + // #### narrow #### // + NarrowSVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowSVecI16x8ToVecI8x16"](), + NarrowUVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowUVecI16x8ToVecI8x16"](), + NarrowSVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowSVecI32x4ToVecI16x8"](), + NarrowUVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowUVecI32x4ToVecI16x8"](), + // #### vcvtop #### // + ExtendLowSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowSVecI8x16ToVecI16x8"](), + ExtendLowSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowSVecI16x8ToVecI32x4"](), + ExtendLowSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowSVecI32x4ToVecI64x2"](), + ExtendLowUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowUVecI8x16ToVecI16x8"](), + ExtendLowUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowUVecI16x8ToVecI32x4"](), + ExtendLowUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowUVecI32x4ToVecI64x2"](), + ExtendHighSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighSVecI8x16ToVecI16x8"](), + ExtendHighSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighSVecI16x8ToVecI32x4"](), + ExtendHighSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighSVecI32x4ToVecI64x2"](), + ExtendHighUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighUVecI8x16ToVecI16x8"](), + ExtendHighUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighUVecI16x8ToVecI32x4"](), + ExtendHighUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighUVecI32x4ToVecI64x2"](), + ConvertSVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertSVecI32x4ToVecF32x4"](), + ConvertUVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertUVecI32x4ToVecF32x4"](), + ConvertLowSVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowSVecI32x4ToVecF64x2"](), + ConvertLowUVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowUVecI32x4ToVecF64x2"](), + TruncSatSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatSVecF32x4ToVecI32x4"](), + TruncSatUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatUVecF32x4ToVecI32x4"](), + TruncSatZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroSVecF64x2ToVecI32x4"](), + TruncSatZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroUVecF64x2ToVecI32x4"](), + RelaxedTruncSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncSVecF32x4ToVecI32x4"](), + RelaxedTruncUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncUVecF32x4ToVecI32x4"](), + RelaxedTruncZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroSVecF64x2ToVecI32x4"](), + RelaxedTruncZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4"](), + DemoteZeroVecF64x2ToVecF32x4 = BinaryenObj["_BinaryenDemoteZeroVecF64x2ToVecF32x4"](), + PromoteLowVecF32x4ToVecF64x2 = BinaryenObj["_BinaryenPromoteLowVecF32x4ToVecF64x2"](), + // #### splat #### // + SplatVecI8x16 = BinaryenObj["_BinaryenSplatVecI8x16"](), + SplatVecI16x8 = BinaryenObj["_BinaryenSplatVecI16x8"](), + SplatVecI32x4 = BinaryenObj["_BinaryenSplatVecI32x4"](), + SplatVecI64x2 = BinaryenObj["_BinaryenSplatVecI64x2"](), + SplatVecF32x4 = BinaryenObj["_BinaryenSplatVecF32x4"](), + SplatVecF64x2 = BinaryenObj["_BinaryenSplatVecF64x2"](), + // #### extract_lane #### // + ExtractLaneSVecI8x16 = BinaryenObj["_BinaryenExtractLaneSVecI8x16"](), + ExtractLaneSVecI16x8 = BinaryenObj["_BinaryenExtractLaneSVecI16x8"](), + ExtractLaneUVecI8x16 = BinaryenObj["_BinaryenExtractLaneUVecI8x16"](), + ExtractLaneUVecI16x8 = BinaryenObj["_BinaryenExtractLaneUVecI16x8"](), + ExtractLaneVecI32x4 = BinaryenObj["_BinaryenExtractLaneVecI32x4"](), + ExtractLaneVecI64x2 = BinaryenObj["_BinaryenExtractLaneVecI64x2"](), + ExtractLaneVecF32x4 = BinaryenObj["_BinaryenExtractLaneVecF32x4"](), + ExtractLaneVecF64x2 = BinaryenObj["_BinaryenExtractLaneVecF64x2"](), + // #### replace_lane #### // + ReplaceLaneVecI8x16 = BinaryenObj["_BinaryenReplaceLaneVecI8x16"](), + ReplaceLaneVecI16x8 = BinaryenObj["_BinaryenReplaceLaneVecI16x8"](), + ReplaceLaneVecI32x4 = BinaryenObj["_BinaryenReplaceLaneVecI32x4"](), + ReplaceLaneVecI64x2 = BinaryenObj["_BinaryenReplaceLaneVecI64x2"](), + ReplaceLaneVecF32x4 = BinaryenObj["_BinaryenReplaceLaneVecF32x4"](), + ReplaceLaneVecF64x2 = BinaryenObj["_BinaryenReplaceLaneVecF64x2"](), + + // ### Atomic Operations ### // + AtomicRMWAdd = BinaryenObj["_BinaryenAtomicRMWAdd"](), + AtomicRMWSub = BinaryenObj["_BinaryenAtomicRMWSub"](), + AtomicRMWAnd = BinaryenObj["_BinaryenAtomicRMWAnd"](), + AtomicRMWOr = BinaryenObj["_BinaryenAtomicRMWOr"](), + AtomicRMWXor = BinaryenObj["_BinaryenAtomicRMWXor"](), + AtomicRMWXchg = BinaryenObj["_BinaryenAtomicRMWXchg"](), + + // ### String Operations ### // + StringNewLossyUTF8Array = BinaryenObj["_BinaryenStringNewLossyUTF8Array"](), + StringNewWTF16Array = BinaryenObj["_BinaryenStringNewWTF16Array"](), + StringNewFromCodePoint = BinaryenObj["_BinaryenStringNewFromCodePoint"](), + StringMeasureUTF8 = BinaryenObj["_BinaryenStringMeasureUTF8"](), + StringMeasureWTF16 = BinaryenObj["_BinaryenStringMeasureWTF16"](), + StringEncodeLossyUTF8Array = BinaryenObj["_BinaryenStringEncodeLossyUTF8Array"](), + StringEncodeWTF16Array = BinaryenObj["_BinaryenStringEncodeWTF16Array"](), + StringEqEqual = BinaryenObj["_BinaryenStringEqEqual"](), + StringEqCompare = BinaryenObj["_BinaryenStringEqCompare"](), +} + + + +export enum MemoryOrder { + unordered = BinaryenObj["_BinaryenMemoryOrderUnordered"](), + seqcst = BinaryenObj["_BinaryenMemoryOrderSeqCst"](), + acqrel = BinaryenObj["_BinaryenMemoryOrderAcqRel"](), +} diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 80f3d251cef..cd2323192a8 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -95,9 +95,11 @@ export const stringref: Type = BinaryenObj["_BinaryenTypeStringref"](); -// ## Instructions ## // -// see https://webassembly.github.io/spec/core/syntax/instructions.html -/** An enumeration of all the “kinds” of expressions. */ +// ## Enumerated Values ## // +/** + * An enumeration of all the “kinds” of expressions. + * @see https://webassembly.github.io/spec/core/syntax/instructions.html + */ export enum ExpressionId { // ### Binaryen-Only Instruction Ids ### // Invalid = BinaryenObj["_BinaryenInvalidId"](), @@ -206,487 +208,6 @@ export enum ExpressionId { StringSliceWTF = BinaryenObj["_BinaryenStringSliceWTFId"](), } - - -// ## Numeric Operations ## // -// see https://webassembly.github.io/spec/core/exec/numerics.html -export enum Operation { - // ### Control Operations ### // - BrOnNull = BinaryenObj["_BinaryenBrOnNull"](), - BrOnNonNull = BinaryenObj["_BinaryenBrOnNonNull"](), - BrOnCast = BinaryenObj["_BinaryenBrOnCast"](), - BrOnCastFail = BinaryenObj["_BinaryenBrOnCastFail"](), - - // ### Memory Operations ### // - Load8LaneVec128 = BinaryenObj["_BinaryenLoad8LaneVec128"](), - Load16LaneVec128 = BinaryenObj["_BinaryenLoad16LaneVec128"](), - Load32LaneVec128 = BinaryenObj["_BinaryenLoad32LaneVec128"](), - Load64LaneVec128 = BinaryenObj["_BinaryenLoad64LaneVec128"](), - Load8x8SVec128 = BinaryenObj["_BinaryenLoad8x8SVec128"](), - Load8x8UVec128 = BinaryenObj["_BinaryenLoad8x8UVec128"](), - Load16x4SVec128 = BinaryenObj["_BinaryenLoad16x4SVec128"](), - Load16x4UVec128 = BinaryenObj["_BinaryenLoad16x4UVec128"](), - Load32x2SVec128 = BinaryenObj["_BinaryenLoad32x2SVec128"](), - Load32x2UVec128 = BinaryenObj["_BinaryenLoad32x2UVec128"](), - Load8SplatVec128 = BinaryenObj["_BinaryenLoad8SplatVec128"](), - Load16SplatVec128 = BinaryenObj["_BinaryenLoad16SplatVec128"](), - Load32SplatVec128 = BinaryenObj["_BinaryenLoad32SplatVec128"](), - Load64SplatVec128 = BinaryenObj["_BinaryenLoad64SplatVec128"](), - Load32ZeroVec128 = BinaryenObj["_BinaryenLoad32ZeroVec128"](), - Load64ZeroVec128 = BinaryenObj["_BinaryenLoad64ZeroVec128"](), - Store8LaneVec128 = BinaryenObj["_BinaryenStore8LaneVec128"](), - Store16LaneVec128 = BinaryenObj["_BinaryenStore16LaneVec128"](), - Store32LaneVec128 = BinaryenObj["_BinaryenStore32LaneVec128"](), - Store64LaneVec128 = BinaryenObj["_BinaryenStore64LaneVec128"](), - - // ### Reference Operations ### // - RefAsNonNull = BinaryenObj["_BinaryenRefAsNonNull"](), - RefAsExternInternalize = BinaryenObj["_BinaryenRefAsExternInternalize"](), - RefAsExternExternalize = BinaryenObj["_BinaryenRefAsExternExternalize"](), - RefAsAnyConvertExtern = BinaryenObj["_BinaryenRefAsAnyConvertExtern"](), - RefAsExternConvertAny = BinaryenObj["_BinaryenRefAsExternConvertAny"](), - - // ### Integer Operations ### // - AddInt32 = BinaryenObj["_BinaryenAddInt32"](), - AddInt64 = BinaryenObj["_BinaryenAddInt64"](), - SubInt32 = BinaryenObj["_BinaryenSubInt32"](), - SubInt64 = BinaryenObj["_BinaryenSubInt64"](), - MulInt32 = BinaryenObj["_BinaryenMulInt32"](), - MulInt64 = BinaryenObj["_BinaryenMulInt64"](), - DivSInt32 = BinaryenObj["_BinaryenDivSInt32"](), - DivSInt64 = BinaryenObj["_BinaryenDivSInt64"](), - DivUInt32 = BinaryenObj["_BinaryenDivUInt32"](), - DivUInt64 = BinaryenObj["_BinaryenDivUInt64"](), - RemSInt32 = BinaryenObj["_BinaryenRemSInt32"](), - RemSInt64 = BinaryenObj["_BinaryenRemSInt64"](), - RemUInt32 = BinaryenObj["_BinaryenRemUInt32"](), - RemUInt64 = BinaryenObj["_BinaryenRemUInt64"](), - AndInt32 = BinaryenObj["_BinaryenAndInt32"](), - AndInt64 = BinaryenObj["_BinaryenAndInt64"](), - OrInt32 = BinaryenObj["_BinaryenOrInt32"](), - OrInt64 = BinaryenObj["_BinaryenOrInt64"](), - XorInt32 = BinaryenObj["_BinaryenXorInt32"](), - XorInt64 = BinaryenObj["_BinaryenXorInt64"](), - ShlInt32 = BinaryenObj["_BinaryenShlInt32"](), - ShlInt64 = BinaryenObj["_BinaryenShlInt64"](), - ShrSInt32 = BinaryenObj["_BinaryenShrSInt32"](), - ShrSInt64 = BinaryenObj["_BinaryenShrSInt64"](), - ShrUInt32 = BinaryenObj["_BinaryenShrUInt32"](), - ShrUInt64 = BinaryenObj["_BinaryenShrUInt64"](), - RotLInt32 = BinaryenObj["_BinaryenRotLInt32"](), - RotLInt64 = BinaryenObj["_BinaryenRotLInt64"](), - RotRInt32 = BinaryenObj["_BinaryenRotRInt32"](), - RotRInt64 = BinaryenObj["_BinaryenRotRInt64"](), - ClzInt32 = BinaryenObj["_BinaryenClzInt32"](), - ClzInt64 = BinaryenObj["_BinaryenClzInt64"](), - CtzInt32 = BinaryenObj["_BinaryenCtzInt32"](), - CtzInt64 = BinaryenObj["_BinaryenCtzInt64"](), - PopcntInt32 = BinaryenObj["_BinaryenPopcntInt32"](), - PopcntInt64 = BinaryenObj["_BinaryenPopcntInt64"](), - EqZInt32 = BinaryenObj["_BinaryenEqZInt32"](), - EqZInt64 = BinaryenObj["_BinaryenEqZInt64"](), - EqInt32 = BinaryenObj["_BinaryenEqInt32"](), - EqInt64 = BinaryenObj["_BinaryenEqInt64"](), - NeInt32 = BinaryenObj["_BinaryenNeInt32"](), - NeInt64 = BinaryenObj["_BinaryenNeInt64"](), - LtSInt32 = BinaryenObj["_BinaryenLtSInt32"](), - LtSInt64 = BinaryenObj["_BinaryenLtSInt64"](), - LtUInt32 = BinaryenObj["_BinaryenLtUInt32"](), - LtUInt64 = BinaryenObj["_BinaryenLtUInt64"](), - GtSInt32 = BinaryenObj["_BinaryenGtSInt32"](), - GtSInt64 = BinaryenObj["_BinaryenGtSInt64"](), - GtUInt32 = BinaryenObj["_BinaryenGtUInt32"](), - GtUInt64 = BinaryenObj["_BinaryenGtUInt64"](), - LeSInt32 = BinaryenObj["_BinaryenLeSInt32"](), - LeSInt64 = BinaryenObj["_BinaryenLeSInt64"](), - LeUInt32 = BinaryenObj["_BinaryenLeUInt32"](), - LeUInt64 = BinaryenObj["_BinaryenLeUInt64"](), - GeSInt32 = BinaryenObj["_BinaryenGeSInt32"](), - GeSInt64 = BinaryenObj["_BinaryenGeSInt64"](), - GeUInt32 = BinaryenObj["_BinaryenGeUInt32"](), - GeUInt64 = BinaryenObj["_BinaryenGeUInt64"](), - ExtendS8Int32 = BinaryenObj["_BinaryenExtendS8Int32"](), - ExtendS8Int64 = BinaryenObj["_BinaryenExtendS8Int64"](), - ExtendS16Int32 = BinaryenObj["_BinaryenExtendS16Int32"](), - ExtendS16Int64 = BinaryenObj["_BinaryenExtendS16Int64"](), - ExtendS32Int64 = BinaryenObj["_BinaryenExtendS32Int64"](), - - // ### Floating-Point Operations ### // - AddFloat32 = BinaryenObj["_BinaryenAddFloat32"](), - AddFloat64 = BinaryenObj["_BinaryenAddFloat64"](), - SubFloat32 = BinaryenObj["_BinaryenSubFloat32"](), - SubFloat64 = BinaryenObj["_BinaryenSubFloat64"](), - MulFloat32 = BinaryenObj["_BinaryenMulFloat32"](), - MulFloat64 = BinaryenObj["_BinaryenMulFloat64"](), - DivFloat32 = BinaryenObj["_BinaryenDivFloat32"](), - DivFloat64 = BinaryenObj["_BinaryenDivFloat64"](), - MinFloat32 = BinaryenObj["_BinaryenMinFloat32"](), - MinFloat64 = BinaryenObj["_BinaryenMinFloat64"](), - MaxFloat32 = BinaryenObj["_BinaryenMaxFloat32"](), - MaxFloat64 = BinaryenObj["_BinaryenMaxFloat64"](), - CopySignFloat32 = BinaryenObj["_BinaryenCopySignFloat32"](), - CopySignFloat64 = BinaryenObj["_BinaryenCopySignFloat64"](), - AbsFloat32 = BinaryenObj["_BinaryenAbsFloat32"](), - AbsFloat64 = BinaryenObj["_BinaryenAbsFloat64"](), - NegFloat32 = BinaryenObj["_BinaryenNegFloat32"](), - NegFloat64 = BinaryenObj["_BinaryenNegFloat64"](), - SqrtFloat32 = BinaryenObj["_BinaryenSqrtFloat32"](), - SqrtFloat64 = BinaryenObj["_BinaryenSqrtFloat64"](), - CeilFloat32 = BinaryenObj["_BinaryenCeilFloat32"](), - CeilFloat64 = BinaryenObj["_BinaryenCeilFloat64"](), - FloorFloat32 = BinaryenObj["_BinaryenFloorFloat32"](), - FloorFloat64 = BinaryenObj["_BinaryenFloorFloat64"](), - TruncFloat32 = BinaryenObj["_BinaryenTruncFloat32"](), - TruncFloat64 = BinaryenObj["_BinaryenTruncFloat64"](), - NearestFloat32 = BinaryenObj["_BinaryenNearestFloat32"](), - NearestFloat64 = BinaryenObj["_BinaryenNearestFloat64"](), - EqFloat32 = BinaryenObj["_BinaryenEqFloat32"](), - EqFloat64 = BinaryenObj["_BinaryenEqFloat64"](), - NeFloat32 = BinaryenObj["_BinaryenNeFloat32"](), - NeFloat64 = BinaryenObj["_BinaryenNeFloat64"](), - LtFloat32 = BinaryenObj["_BinaryenLtFloat32"](), - LtFloat64 = BinaryenObj["_BinaryenLtFloat64"](), - GtFloat32 = BinaryenObj["_BinaryenGtFloat32"](), - GtFloat64 = BinaryenObj["_BinaryenGtFloat64"](), - LeFloat32 = BinaryenObj["_BinaryenLeFloat32"](), - LeFloat64 = BinaryenObj["_BinaryenLeFloat64"](), - GeFloat32 = BinaryenObj["_BinaryenGeFloat32"](), - GeFloat64 = BinaryenObj["_BinaryenGeFloat64"](), - - // ### Conversions ### // - ExtendSInt32 = BinaryenObj["_BinaryenExtendSInt32"](), - ExtendUInt32 = BinaryenObj["_BinaryenExtendUInt32"](), - WrapInt64 = BinaryenObj["_BinaryenWrapInt64"](), - TruncSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSFloat32ToInt32"](), - TruncSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSFloat32ToInt64"](), - TruncSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSFloat64ToInt32"](), - TruncSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSFloat64ToInt64"](), - TruncUFloat32ToInt32 = BinaryenObj["_BinaryenTruncUFloat32ToInt32"](), - TruncUFloat32ToInt64 = BinaryenObj["_BinaryenTruncUFloat32ToInt64"](), - TruncUFloat64ToInt32 = BinaryenObj["_BinaryenTruncUFloat64ToInt32"](), - TruncUFloat64ToInt64 = BinaryenObj["_BinaryenTruncUFloat64ToInt64"](), - TruncSatSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt32"](), - TruncSatSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt64"](), - TruncSatSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt32"](), - TruncSatSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt64"](), - TruncSatUFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt32"](), - TruncSatUFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt64"](), - TruncSatUFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt32"](), - TruncSatUFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt64"](), - PromoteFloat32 = BinaryenObj["_BinaryenPromoteFloat32"](), - DemoteFloat64 = BinaryenObj["_BinaryenDemoteFloat64"](), - ConvertSInt32ToFloat32 = BinaryenObj["_BinaryenConvertSInt32ToFloat32"](), - ConvertSInt32ToFloat64 = BinaryenObj["_BinaryenConvertSInt32ToFloat64"](), - ConvertSInt64ToFloat32 = BinaryenObj["_BinaryenConvertSInt64ToFloat32"](), - ConvertSInt64ToFloat64 = BinaryenObj["_BinaryenConvertSInt64ToFloat64"](), - ConvertUInt32ToFloat32 = BinaryenObj["_BinaryenConvertUInt32ToFloat32"](), - ConvertUInt32ToFloat64 = BinaryenObj["_BinaryenConvertUInt32ToFloat64"](), - ConvertUInt64ToFloat32 = BinaryenObj["_BinaryenConvertUInt64ToFloat32"](), - ConvertUInt64ToFloat64 = BinaryenObj["_BinaryenConvertUInt64ToFloat64"](), - ReinterpretInt32 = BinaryenObj["_BinaryenReinterpretInt32"](), - ReinterpretInt64 = BinaryenObj["_BinaryenReinterpretInt64"](), - ReinterpretFloat32 = BinaryenObj["_BinaryenReinterpretFloat32"](), - ReinterpretFloat64 = BinaryenObj["_BinaryenReinterpretFloat64"](), - - // ### Vector Operations ### // - // #### vvunop #### // - NotVec128 = BinaryenObj["_BinaryenNotVec128"](), - // #### vvbinop #### // - AndVec128 = BinaryenObj["_BinaryenAndVec128"](), - AndNotVec128 = BinaryenObj["_BinaryenAndNotVec128"](), - OrVec128 = BinaryenObj["_BinaryenOrVec128"](), - XorVec128 = BinaryenObj["_BinaryenXorVec128"](), - // #### vvternop #### // - BitselectVec128 = BinaryenObj["_BinaryenBitselectVec128"](), - // #### vvtestop #### // - AnyTrueVec128 = BinaryenObj["_BinaryenAnyTrueVec128"](), - // #### vunop_i #### // - AbsVecI8x16 = BinaryenObj["_BinaryenAbsVecI8x16"](), - AbsVecI16x8 = BinaryenObj["_BinaryenAbsVecI16x8"](), - AbsVecI32x4 = BinaryenObj["_BinaryenAbsVecI32x4"](), - AbsVecI64x2 = BinaryenObj["_BinaryenAbsVecI64x2"](), - NegVecI8x16 = BinaryenObj["_BinaryenNegVecI8x16"](), - NegVecI16x8 = BinaryenObj["_BinaryenNegVecI16x8"](), - NegVecI32x4 = BinaryenObj["_BinaryenNegVecI32x4"](), - NegVecI64x2 = BinaryenObj["_BinaryenNegVecI64x2"](), - PopcntVecI8x16 = BinaryenObj["_BinaryenPopcntVecI8x16"](), - // #### vunop_f #### // - AbsVecF32x4 = BinaryenObj["_BinaryenAbsVecF32x4"](), - AbsVecF64x2 = BinaryenObj["_BinaryenAbsVecF64x2"](), - NegVecF32x4 = BinaryenObj["_BinaryenNegVecF32x4"](), - NegVecF64x2 = BinaryenObj["_BinaryenNegVecF64x2"](), - SqrtVecF32x4 = BinaryenObj["_BinaryenSqrtVecF32x4"](), - SqrtVecF64x2 = BinaryenObj["_BinaryenSqrtVecF64x2"](), - CeilVecF32x4 = BinaryenObj["_BinaryenCeilVecF32x4"](), - CeilVecF64x2 = BinaryenObj["_BinaryenCeilVecF64x2"](), - FloorVecF32x4 = BinaryenObj["_BinaryenFloorVecF32x4"](), - FloorVecF64x2 = BinaryenObj["_BinaryenFloorVecF64x2"](), - TruncVecF32x4 = BinaryenObj["_BinaryenTruncVecF32x4"](), - TruncVecF64x2 = BinaryenObj["_BinaryenTruncVecF64x2"](), - NearestVecF32x4 = BinaryenObj["_BinaryenNearestVecF32x4"](), - NearestVecF64x2 = BinaryenObj["_BinaryenNearestVecF64x2"](), - // #### vbinop_i #### // - AddVecI8x16 = BinaryenObj["_BinaryenAddVecI8x16"](), - AddVecI16x8 = BinaryenObj["_BinaryenAddVecI16x8"](), - AddVecI32x4 = BinaryenObj["_BinaryenAddVecI32x4"](), - AddVecI64x2 = BinaryenObj["_BinaryenAddVecI64x2"](), - SubVecI8x16 = BinaryenObj["_BinaryenSubVecI8x16"](), - SubVecI16x8 = BinaryenObj["_BinaryenSubVecI16x8"](), - SubVecI32x4 = BinaryenObj["_BinaryenSubVecI32x4"](), - SubVecI64x2 = BinaryenObj["_BinaryenSubVecI64x2"](), - AddSatSVecI8x16 = BinaryenObj["_BinaryenAddSatSVecI8x16"](), - AddSatSVecI16x8 = BinaryenObj["_BinaryenAddSatSVecI16x8"](), - AddSatUVecI8x16 = BinaryenObj["_BinaryenAddSatUVecI8x16"](), - AddSatUVecI16x8 = BinaryenObj["_BinaryenAddSatUVecI16x8"](), - SubSatSVecI8x16 = BinaryenObj["_BinaryenSubSatSVecI8x16"](), - SubSatSVecI16x8 = BinaryenObj["_BinaryenSubSatSVecI16x8"](), - SubSatUVecI8x16 = BinaryenObj["_BinaryenSubSatUVecI8x16"](), - SubSatUVecI16x8 = BinaryenObj["_BinaryenSubSatUVecI16x8"](), - MulVecI16x8 = BinaryenObj["_BinaryenMulVecI16x8"](), - MulVecI32x4 = BinaryenObj["_BinaryenMulVecI32x4"](), - MulVecI64x2 = BinaryenObj["_BinaryenMulVecI64x2"](), - AvgrUVecI8x16 = BinaryenObj["_BinaryenAvgrUVecI8x16"](), - AvgrUVecI16x8 = BinaryenObj["_BinaryenAvgrUVecI16x8"](), - Q15MulrSatSVecI16x8 = BinaryenObj["_BinaryenQ15MulrSatSVecI16x8"](), - RelaxedQ15MulrSVecI16x8 = BinaryenObj["_BinaryenRelaxedQ15MulrSVecI16x8"](), - MinSVecI8x16 = BinaryenObj["_BinaryenMinSVecI8x16"](), - MinSVecI16x8 = BinaryenObj["_BinaryenMinSVecI16x8"](), - MinSVecI32x4 = BinaryenObj["_BinaryenMinSVecI32x4"](), - MinUVecI8x16 = BinaryenObj["_BinaryenMinUVecI8x16"](), - MinUVecI16x8 = BinaryenObj["_BinaryenMinUVecI16x8"](), - MinUVecI32x4 = BinaryenObj["_BinaryenMinUVecI32x4"](), - MaxSVecI8x16 = BinaryenObj["_BinaryenMaxSVecI8x16"](), - MaxSVecI16x8 = BinaryenObj["_BinaryenMaxSVecI16x8"](), - MaxSVecI32x4 = BinaryenObj["_BinaryenMaxSVecI32x4"](), - MaxUVecI8x16 = BinaryenObj["_BinaryenMaxUVecI8x16"](), - MaxUVecI16x8 = BinaryenObj["_BinaryenMaxUVecI16x8"](), - MaxUVecI32x4 = BinaryenObj["_BinaryenMaxUVecI32x4"](), - // #### vbinop_f #### // - AddVecF32x4 = BinaryenObj["_BinaryenAddVecF32x4"](), - AddVecF64x2 = BinaryenObj["_BinaryenAddVecF64x2"](), - SubVecF32x4 = BinaryenObj["_BinaryenSubVecF32x4"](), - SubVecF64x2 = BinaryenObj["_BinaryenSubVecF64x2"](), - MulVecF32x4 = BinaryenObj["_BinaryenMulVecF32x4"](), - MulVecF64x2 = BinaryenObj["_BinaryenMulVecF64x2"](), - DivVecF32x4 = BinaryenObj["_BinaryenDivVecF32x4"](), - DivVecF64x2 = BinaryenObj["_BinaryenDivVecF64x2"](), - MinVecF32x4 = BinaryenObj["_BinaryenMinVecF32x4"](), - MinVecF64x2 = BinaryenObj["_BinaryenMinVecF64x2"](), - MaxVecF32x4 = BinaryenObj["_BinaryenMaxVecF32x4"](), - MaxVecF64x2 = BinaryenObj["_BinaryenMaxVecF64x2"](), - PMinVecF32x4 = BinaryenObj["_BinaryenPMinVecF32x4"](), - PMinVecF64x2 = BinaryenObj["_BinaryenPMinVecF64x2"](), - PMaxVecF32x4 = BinaryenObj["_BinaryenPMaxVecF32x4"](), - PMaxVecF64x2 = BinaryenObj["_BinaryenPMaxVecF64x2"](), - RelaxedMinVecF32x4 = BinaryenObj["_BinaryenRelaxedMinVecF32x4"](), - RelaxedMinVecF64x2 = BinaryenObj["_BinaryenRelaxedMinVecF64x2"](), - RelaxedMaxVecF32x4 = BinaryenObj["_BinaryenRelaxedMaxVecF32x4"](), - RelaxedMaxVecF64x2 = BinaryenObj["_BinaryenRelaxedMaxVecF64x2"](), - // #### vternop_i #### // - LaneselectI8x16 = BinaryenObj["_BinaryenLaneselectI8x16"](), - LaneselectI16x8 = BinaryenObj["_BinaryenLaneselectI16x8"](), - LaneselectI32x4 = BinaryenObj["_BinaryenLaneselectI32x4"](), - LaneselectI64x2 = BinaryenObj["_BinaryenLaneselectI64x2"](), - // #### vternop_f #### // - RelaxedMaddVecF32x4 = BinaryenObj["_BinaryenRelaxedMaddVecF32x4"](), - RelaxedMaddVecF64x2 = BinaryenObj["_BinaryenRelaxedMaddVecF64x2"](), - RelaxedNmaddVecF32x4 = BinaryenObj["_BinaryenRelaxedNmaddVecF32x4"](), - RelaxedNmaddVecF64x2 = BinaryenObj["_BinaryenRelaxedNmaddVecF64x2"](), - // #### vtestop_i #### // - AllTrueVecI8x16 = BinaryenObj["_BinaryenAllTrueVecI8x16"](), - AllTrueVecI16x8 = BinaryenObj["_BinaryenAllTrueVecI16x8"](), - AllTrueVecI32x4 = BinaryenObj["_BinaryenAllTrueVecI32x4"](), - AllTrueVecI64x2 = BinaryenObj["_BinaryenAllTrueVecI64x2"](), - // #### vrelop_i #### // - EqVecI8x16 = BinaryenObj["_BinaryenEqVecI8x16"](), - EqVecI16x8 = BinaryenObj["_BinaryenEqVecI16x8"](), - EqVecI32x4 = BinaryenObj["_BinaryenEqVecI32x4"](), - EqVecI64x2 = BinaryenObj["_BinaryenEqVecI64x2"](), - NeVecI8x16 = BinaryenObj["_BinaryenNeVecI8x16"](), - NeVecI16x8 = BinaryenObj["_BinaryenNeVecI16x8"](), - NeVecI32x4 = BinaryenObj["_BinaryenNeVecI32x4"](), - NeVecI64x2 = BinaryenObj["_BinaryenNeVecI64x2"](), - LtSVecI8x16 = BinaryenObj["_BinaryenLtSVecI8x16"](), - LtSVecI16x8 = BinaryenObj["_BinaryenLtSVecI16x8"](), - LtSVecI32x4 = BinaryenObj["_BinaryenLtSVecI32x4"](), - LtSVecI64x2 = BinaryenObj["_BinaryenLtSVecI64x2"](), - LtUVecI8x16 = BinaryenObj["_BinaryenLtUVecI8x16"](), - LtUVecI16x8 = BinaryenObj["_BinaryenLtUVecI16x8"](), - LtUVecI32x4 = BinaryenObj["_BinaryenLtUVecI32x4"](), - GtSVecI8x16 = BinaryenObj["_BinaryenGtSVecI8x16"](), - GtSVecI16x8 = BinaryenObj["_BinaryenGtSVecI16x8"](), - GtSVecI32x4 = BinaryenObj["_BinaryenGtSVecI32x4"](), - GtSVecI64x2 = BinaryenObj["_BinaryenGtSVecI64x2"](), - GtUVecI8x16 = BinaryenObj["_BinaryenGtUVecI8x16"](), - GtUVecI16x8 = BinaryenObj["_BinaryenGtUVecI16x8"](), - GtUVecI32x4 = BinaryenObj["_BinaryenGtUVecI32x4"](), - LeSVecI8x16 = BinaryenObj["_BinaryenLeSVecI8x16"](), - LeSVecI16x8 = BinaryenObj["_BinaryenLeSVecI16x8"](), - LeSVecI32x4 = BinaryenObj["_BinaryenLeSVecI32x4"](), - LeSVecI64x2 = BinaryenObj["_BinaryenLeSVecI64x2"](), - LeUVecI8x16 = BinaryenObj["_BinaryenLeUVecI8x16"](), - LeUVecI16x8 = BinaryenObj["_BinaryenLeUVecI16x8"](), - LeUVecI32x4 = BinaryenObj["_BinaryenLeUVecI32x4"](), - GeSVecI8x16 = BinaryenObj["_BinaryenGeSVecI8x16"](), - GeSVecI16x8 = BinaryenObj["_BinaryenGeSVecI16x8"](), - GeSVecI32x4 = BinaryenObj["_BinaryenGeSVecI32x4"](), - GeSVecI64x2 = BinaryenObj["_BinaryenGeSVecI64x2"](), - GeUVecI8x16 = BinaryenObj["_BinaryenGeUVecI8x16"](), - GeUVecI16x8 = BinaryenObj["_BinaryenGeUVecI16x8"](), - GeUVecI32x4 = BinaryenObj["_BinaryenGeUVecI32x4"](), - // #### vrelop_f #### // - EqVecF32x4 = BinaryenObj["_BinaryenEqVecF32x4"](), - EqVecF64x2 = BinaryenObj["_BinaryenEqVecF64x2"](), - NeVecF32x4 = BinaryenObj["_BinaryenNeVecF32x4"](), - NeVecF64x2 = BinaryenObj["_BinaryenNeVecF64x2"](), - LtVecF32x4 = BinaryenObj["_BinaryenLtVecF32x4"](), - LtVecF64x2 = BinaryenObj["_BinaryenLtVecF64x2"](), - GtVecF32x4 = BinaryenObj["_BinaryenGtVecF32x4"](), - GtVecF64x2 = BinaryenObj["_BinaryenGtVecF64x2"](), - LeVecF32x4 = BinaryenObj["_BinaryenLeVecF32x4"](), - LeVecF64x2 = BinaryenObj["_BinaryenLeVecF64x2"](), - GeVecF32x4 = BinaryenObj["_BinaryenGeVecF32x4"](), - GeVecF64x2 = BinaryenObj["_BinaryenGeVecF64x2"](), - // #### vshiftop #### // - ShlVecI8x16 = BinaryenObj["_BinaryenShlVecI8x16"](), - ShlVecI16x8 = BinaryenObj["_BinaryenShlVecI16x8"](), - ShlVecI32x4 = BinaryenObj["_BinaryenShlVecI32x4"](), - ShlVecI64x2 = BinaryenObj["_BinaryenShlVecI64x2"](), - ShrSVecI8x16 = BinaryenObj["_BinaryenShrSVecI8x16"](), - ShrSVecI16x8 = BinaryenObj["_BinaryenShrSVecI16x8"](), - ShrSVecI32x4 = BinaryenObj["_BinaryenShrSVecI32x4"](), - ShrSVecI64x2 = BinaryenObj["_BinaryenShrSVecI64x2"](), - ShrUVecI8x16 = BinaryenObj["_BinaryenShrUVecI8x16"](), - ShrUVecI16x8 = BinaryenObj["_BinaryenShrUVecI16x8"](), - ShrUVecI32x4 = BinaryenObj["_BinaryenShrUVecI32x4"](), - ShrUVecI64x2 = BinaryenObj["_BinaryenShrUVecI64x2"](), - // #### bitmask #### // - BitmaskVecI8x16 = BinaryenObj["_BinaryenBitmaskVecI8x16"](), - BitmaskVecI16x8 = BinaryenObj["_BinaryenBitmaskVecI16x8"](), - BitmaskVecI32x4 = BinaryenObj["_BinaryenBitmaskVecI32x4"](), - BitmaskVecI64x2 = BinaryenObj["_BinaryenBitmaskVecI64x2"](), - // #### vswizzleop #### // - SwizzleVecI8x16 = BinaryenObj["_BinaryenSwizzleVecI8x16"](), - RelaxedSwizzleVecI8x16 = BinaryenObj["_BinaryenRelaxedSwizzleVecI8x16"](), - // #### vextunop #### // - ExtAddPairwiseSVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseSVecI8x16ToI16x8"](), - ExtAddPairwiseSVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseSVecI16x8ToI32x4"](), - ExtAddPairwiseUVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseUVecI8x16ToI16x8"](), - ExtAddPairwiseUVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseUVecI16x8ToI32x4"](), - // #### vextbinop #### // - ExtMulLowSVecI16x8 = BinaryenObj["_BinaryenExtMulLowSVecI16x8"](), - ExtMulLowSVecI32x4 = BinaryenObj["_BinaryenExtMulLowSVecI32x4"](), - ExtMulLowSVecI64x2 = BinaryenObj["_BinaryenExtMulLowSVecI64x2"](), - ExtMulLowUVecI16x8 = BinaryenObj["_BinaryenExtMulLowUVecI16x8"](), - ExtMulLowUVecI32x4 = BinaryenObj["_BinaryenExtMulLowUVecI32x4"](), - ExtMulLowUVecI64x2 = BinaryenObj["_BinaryenExtMulLowUVecI64x2"](), - ExtMulHighSVecI16x8 = BinaryenObj["_BinaryenExtMulHighSVecI16x8"](), - ExtMulHighSVecI32x4 = BinaryenObj["_BinaryenExtMulHighSVecI32x4"](), - ExtMulHighSVecI64x2 = BinaryenObj["_BinaryenExtMulHighSVecI64x2"](), - ExtMulHighUVecI16x8 = BinaryenObj["_BinaryenExtMulHighUVecI16x8"](), - ExtMulHighUVecI32x4 = BinaryenObj["_BinaryenExtMulHighUVecI32x4"](), - ExtMulHighUVecI64x2 = BinaryenObj["_BinaryenExtMulHighUVecI64x2"](), - DotI8x16I7x16AddSToVecI32x4 = BinaryenObj["_BinaryenDotI8x16I7x16AddSToVecI32x4"](), - DotI8x16I7x16SToVecI16x8 = BinaryenObj["_BinaryenDotI8x16I7x16SToVecI16x8"](), - DotSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenDotSVecI16x8ToVecI32x4"](), - // #### narrow #### // - NarrowSVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowSVecI16x8ToVecI8x16"](), - NarrowUVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowUVecI16x8ToVecI8x16"](), - NarrowSVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowSVecI32x4ToVecI16x8"](), - NarrowUVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowUVecI32x4ToVecI16x8"](), - // #### vcvtop #### // - ExtendLowSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowSVecI8x16ToVecI16x8"](), - ExtendLowSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowSVecI16x8ToVecI32x4"](), - ExtendLowSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowSVecI32x4ToVecI64x2"](), - ExtendLowUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowUVecI8x16ToVecI16x8"](), - ExtendLowUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowUVecI16x8ToVecI32x4"](), - ExtendLowUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowUVecI32x4ToVecI64x2"](), - ExtendHighSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighSVecI8x16ToVecI16x8"](), - ExtendHighSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighSVecI16x8ToVecI32x4"](), - ExtendHighSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighSVecI32x4ToVecI64x2"](), - ExtendHighUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighUVecI8x16ToVecI16x8"](), - ExtendHighUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighUVecI16x8ToVecI32x4"](), - ExtendHighUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighUVecI32x4ToVecI64x2"](), - ConvertSVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertSVecI32x4ToVecF32x4"](), - ConvertUVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertUVecI32x4ToVecF32x4"](), - ConvertLowSVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowSVecI32x4ToVecF64x2"](), - ConvertLowUVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowUVecI32x4ToVecF64x2"](), - TruncSatSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatSVecF32x4ToVecI32x4"](), - TruncSatUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatUVecF32x4ToVecI32x4"](), - TruncSatZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroSVecF64x2ToVecI32x4"](), - TruncSatZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroUVecF64x2ToVecI32x4"](), - RelaxedTruncSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncSVecF32x4ToVecI32x4"](), - RelaxedTruncUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncUVecF32x4ToVecI32x4"](), - RelaxedTruncZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroSVecF64x2ToVecI32x4"](), - RelaxedTruncZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4"](), - DemoteZeroVecF64x2ToVecF32x4 = BinaryenObj["_BinaryenDemoteZeroVecF64x2ToVecF32x4"](), - PromoteLowVecF32x4ToVecF64x2 = BinaryenObj["_BinaryenPromoteLowVecF32x4ToVecF64x2"](), - // #### splat #### // - SplatVecI8x16 = BinaryenObj["_BinaryenSplatVecI8x16"](), - SplatVecI16x8 = BinaryenObj["_BinaryenSplatVecI16x8"](), - SplatVecI32x4 = BinaryenObj["_BinaryenSplatVecI32x4"](), - SplatVecI64x2 = BinaryenObj["_BinaryenSplatVecI64x2"](), - SplatVecF32x4 = BinaryenObj["_BinaryenSplatVecF32x4"](), - SplatVecF64x2 = BinaryenObj["_BinaryenSplatVecF64x2"](), - // #### extract_lane #### // - ExtractLaneSVecI8x16 = BinaryenObj["_BinaryenExtractLaneSVecI8x16"](), - ExtractLaneSVecI16x8 = BinaryenObj["_BinaryenExtractLaneSVecI16x8"](), - ExtractLaneUVecI8x16 = BinaryenObj["_BinaryenExtractLaneUVecI8x16"](), - ExtractLaneUVecI16x8 = BinaryenObj["_BinaryenExtractLaneUVecI16x8"](), - ExtractLaneVecI32x4 = BinaryenObj["_BinaryenExtractLaneVecI32x4"](), - ExtractLaneVecI64x2 = BinaryenObj["_BinaryenExtractLaneVecI64x2"](), - ExtractLaneVecF32x4 = BinaryenObj["_BinaryenExtractLaneVecF32x4"](), - ExtractLaneVecF64x2 = BinaryenObj["_BinaryenExtractLaneVecF64x2"](), - // #### replace_lane #### // - ReplaceLaneVecI8x16 = BinaryenObj["_BinaryenReplaceLaneVecI8x16"](), - ReplaceLaneVecI16x8 = BinaryenObj["_BinaryenReplaceLaneVecI16x8"](), - ReplaceLaneVecI32x4 = BinaryenObj["_BinaryenReplaceLaneVecI32x4"](), - ReplaceLaneVecI64x2 = BinaryenObj["_BinaryenReplaceLaneVecI64x2"](), - ReplaceLaneVecF32x4 = BinaryenObj["_BinaryenReplaceLaneVecF32x4"](), - ReplaceLaneVecF64x2 = BinaryenObj["_BinaryenReplaceLaneVecF64x2"](), - - // ### Atomic Operations ### // - AtomicRMWAdd = BinaryenObj["_BinaryenAtomicRMWAdd"](), - AtomicRMWSub = BinaryenObj["_BinaryenAtomicRMWSub"](), - AtomicRMWAnd = BinaryenObj["_BinaryenAtomicRMWAnd"](), - AtomicRMWOr = BinaryenObj["_BinaryenAtomicRMWOr"](), - AtomicRMWXor = BinaryenObj["_BinaryenAtomicRMWXor"](), - AtomicRMWXchg = BinaryenObj["_BinaryenAtomicRMWXchg"](), - - // ### String Operations ### // - StringNewLossyUTF8Array = BinaryenObj["_BinaryenStringNewLossyUTF8Array"](), - StringNewWTF16Array = BinaryenObj["_BinaryenStringNewWTF16Array"](), - StringNewFromCodePoint = BinaryenObj["_BinaryenStringNewFromCodePoint"](), - StringMeasureUTF8 = BinaryenObj["_BinaryenStringMeasureUTF8"](), - StringMeasureWTF16 = BinaryenObj["_BinaryenStringMeasureWTF16"](), - StringEncodeLossyUTF8Array = BinaryenObj["_BinaryenStringEncodeLossyUTF8Array"](), - StringEncodeWTF16Array = BinaryenObj["_BinaryenStringEncodeWTF16Array"](), - StringEqEqual = BinaryenObj["_BinaryenStringEqEqual"](), - StringEqCompare = BinaryenObj["_BinaryenStringEqCompare"](), -} - - - -// ## Externals ## // -// see https://webassembly.github.io/spec/core/syntax/modules.html -export enum ExternalKind { - ExternalTag = BinaryenObj["_BinaryenExternalTag"](), - ExternalGlobal = BinaryenObj["_BinaryenExternalGlobal"](), - ExternalMemory = BinaryenObj["_BinaryenExternalMemory"](), - ExternalTable = BinaryenObj["_BinaryenExternalTable"](), - ExternalFunction = BinaryenObj["_BinaryenExternalFunction"](), -} - - - -export enum MemoryOrder { - unordered = BinaryenObj["_BinaryenMemoryOrderUnordered"](), - seqcst = BinaryenObj["_BinaryenMemoryOrderSeqCst"](), - acqrel = BinaryenObj["_BinaryenMemoryOrderAcqRel"](), -} - - - /** Expression side-effects. */ export enum SideEffect { None = BinaryenObj["_BinaryenSideEffectNone"](), @@ -707,3 +228,15 @@ export enum SideEffect { TrapsNeverHappen = BinaryenObj["_BinaryenSideEffectTrapsNeverHappen"](), Any = BinaryenObj["_BinaryenSideEffectAny"](), } + +/** + * External kinds. + * @see https://webassembly.github.io/spec/core/syntax/modules.html + */ +export enum ExternalKind { + ExternalTag = BinaryenObj["_BinaryenExternalTag"](), + ExternalGlobal = BinaryenObj["_BinaryenExternalGlobal"](), + ExternalMemory = BinaryenObj["_BinaryenExternalMemory"](), + ExternalTable = BinaryenObj["_BinaryenExternalTable"](), + ExternalFunction = BinaryenObj["_BinaryenExternalFunction"](), +} From 5e1918bbec9c22d46057791b134725a77a7c8ad8 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 00:29:28 -0400 Subject: [PATCH 059/247] docs: make API.md --- ts/API.md | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 ts/API.md diff --git a/ts/API.md b/ts/API.md new file mode 100644 index 00000000000..a30e64b6a43 --- /dev/null +++ b/ts/API.md @@ -0,0 +1,251 @@ +# API Documentation +Please note that the Binaryen API is evolving fast. +Definitions and documentation provided by the C++ codebase don’t always immediately find their way here into TypeScript. +If you rely on Binaryen.TS and spot an issue, please consider sending a PR our way. Thank you! + +### Contents +- [Top-Level Symbols](#top-level-symbols) +- [Module Manipulation](#module-manipulation) +- [Expression Construction](#expression-construction) +- [Deprecations](#️-deprecations-renames-and-moves) + + + +### Icon Legend +- ⛔️ Not yet supported, but listed here for completion. +- ❌ removed +- 🌱 new/experimental/proposed; not listed in WASM spec + + + +## Top-Level Symbols +Import `binaryen` as a namespace: +```ts +import * as binaryen from "binaryen.ts"; +``` +or import ES module components individually: +```ts +import {type Type, type ExpressionRef, i32} from "binaryen.ts"; +``` + + +### TypeScript Types +- `Type`: a WASM type; the type of the constants named `i32`, `i64`, etc. +- `HeapType`: a WASM heap type created in a `TypeBuilder` +- `PackedType`: an allowed type of a struct or array field; one of three constants: `notPacked`, `i8`, `i16` +- `ExpressionRef`: an expression, e.g. the type of `i32.const()` +- module component ref types: + - `TagRef` + - `GlobalRef` + - ~~`MemoryRef`~~ ⛔️ + - `TableRef` + - `FunctionRef` + - `DataSegmentRef` + - `ElementSegmentRef` + - ~~`ImportRef`~~ ⛔️ + - `ExportRef` + + +### Constants +- `unreachable`: type of an unreachable instruction (stack effect *[t\*] -> [t\*]*) +- `none`: void type (stack effect *[t\*] -> []*); not to be confused with WASM’s heap type called *none* +- `auto`: special type used in `Module#x.block()` exclusively; automatically detects a block’s result type based on its contents +> +- `i32`: 32-bit integer +- `i64`: 64-bit integer +- `f32`: 32-bit float +- `f64`: 64-bit float +- `v128`: 128-bit vector (SIMD) +> +- `anyref`: *(ref null any)* +- `eqref`: *(ref null eq)* +- `i31ref`: *(ref null i31)* +- `structref`: *(ref null struct)* +- `arrayref`: *(ref null array)* +- `funcref`: *(ref null func)* +- ~~`exnref`~~: ⛔️ reserved for *(ref null exn)* +- `externref`: *(ref null extern)* +- `nullref`: *(ref null none)* +- `nullfuncref`: *(ref null nofunc)* +- ~~`nullexnref`~~: ⛔️ reserved for *(ref null noexn)* +- `nullexternref`: *(ref null noextern)* +- `stringref`: 🌱 planned for *(ref null string)* +> +- `notPacked` (`PackedType`): unaltered type in the struct/array field +- `i8` (`PackedType`): 8-bit integer +- `i16` (`PackedType`): 16-bit integer + + +### Enums +- `ExpressionId`: an enumeration of values returned by `getExpressionId()` + - a slight misnomer, as these are not unique IDs per expression, but different IDs for the “kinds” of expression +- `SideEffect`: an enumeration of values returend by `getSideEffects()` +- `ExternalKind`: an enumeration of kinds of exports; serves as type of the `Module.Export#kind` field +- `MemoryOrder`: an enumeration of values used in atomic expression methods + + +### Global Bindings +Functions (see generated docs for descriptions): +- `emitText(expr: ExpressionRef): string` +- `readBinary(data: Uint8Array): Module` +- `readBinaryWithFeatures(data: Uint8Array, features: Feature): Module` +- `parseText(text: string): Module` +- `exit(status: number): void` +- `createType(types: readonly Type[]): Type` +- `expandType(typ: Type): Type[]` +- `getTypeFromHeapType(heapType: HeapType, nullable: boolean): Type` +- `getHeapType(typ: Type): HeapType` +- `getExpressionId(expr: ExpressionRef): ExpressionId` +- `getExpressionType(expr: ExpressionRef): Type` +- `getExpressionInfo(expr: ExpressionRef): Expression` +- `getSideEffects(expr: ExpressionRef, mod: Module): SideEffect` +- `copyExpression(expr: ExpressionRef, mod: Module): ExpressionRef` + +Objects: +- `settings`: global settings manager; see `SettingsService` docs + + + +## Module Manipulation +- Properties of `Module` as a namespace: + - `new Module.Tag(ref: TagRef)`: an object containing information about a **Tag** + - `new Module.Global(ref: GlobalRef)`: an object containing information about a **Global** + - `new Module.Memory(mod: Module, name: string)`: an object containing information about a **Memory** + - `new Module.Table(ref: TableRef)`: an object containing information about a **Table** + - `new Module.Function(ref: FunctionRef)`: an object containing information about a **Function** + - `new Module.DataSegment(mod: Module, ref: DataSegmentRef)`: an object containing information about a **Data Segment** + - `new Module.ElementSegment(ref: ElementSegmentRef)`: an object containing information about an **Element Segment** + - `new Module.Import()`: an object containing information about an **Import** (🌱 empty for now) + - `new Module.Export(ref: ExportRef)`: an object containing information about an **Export** + +- Properties of `Module` instances (see full list of methods in generated docs): + - `Module#x`: [create expressions](#expression-construction) + - `Module#tags`: **Tag** manipulation + - `Module#globals`: **Global** manipulation + - `Module#memories`: **Memory** manipulation + - `Module#tables`: **Table** manipulation + - `Module#functions`: **Function** manipulation + - `Module#dataSegments`: **Data Segment** manipulation + - `Module#elementSegments`: **Element Segment** manipulation + - `Module#imports`: **Import** manipulation + - `Module#exports`: **Export** manipulation + + + +## Expression Construction +### Parametric Instructions +### Control Instructions +- `Module#x.block()` +- `Module#x.if()` + +### Variable Instructions +- `Module#x.local.get()` +- `Module#x.local.set()` +- `Module#x.local.tee()` +- `Module#x.global.get()` +- `Module#x.global.set()` + +### Table Instructions +### Memory Instructions +### Reference Instructions +### Aggregate Instructions +### Numeric Instructions +### Vector Instructions +### Atomic Instructions +### String Instructions + + + +## ⚠️ Deprecations, Renames, and Moves +### Enums and Types +Enum names have been singularized. +- `ExpressionIds` → `ExpressionId` +- `SideEffects` → `SideEffect` +- `ExternalKinds` → `ExternalKind` +- `Features` → `Feature` +- `Operations` → `Operation` + +`*Info` types have been merged with their respective classes in the `Module` namespace. +- `TagInfo` → `Module.Tag` +- `GlobalInfo` → `Module.Global` +- `MemoryInfo` → `Module.Memory` +- `TableInfo` → `Module.Table` +- `FunctionInfo` → `Module.Function` +- `ElementSegmentInfo` → `Module.ElementSegment` +- `ExportInfo` → `Module.Export` + +`ExpressionInfo` and related types are now classes without the `Info` suffix: +- `ExpressionInfo` → `Expression` +- `BlockInfo` → `Block` +- `LoopInfo` → `Loop` +- `IfInfo` → `If` +- etc. + +~~`MemorySegmentInfo`~~ ❌ has been removed. + + +### Modules +Module components previously at the top level have been moved under the `Module` namespace. +- `Function` → `Module.Function` +- `Table` → `Module.Table` + +Most `get*Info()` functions have been replaced by their corresponding class constructors. +- `getTagInfo(tag)` → `new Module.Tag(tag)`; +- `getGlobalInfo(global)` → `new Module.Global(global)` +- `getTableInfo(table)` → `new Module.Table(table)` +- `getFunctionInfo(func)` → `new Module.Function(func)` +- `getElementSegmentInfo(segment)` → `new Module.ElementSegment(segment)` +- `getExportInfo(xport)` → `new Module.Export(xport)` +> +- `Module#getMemoryInfo(name)` has not changed. +- `Module#getDataSegmentInfo(name)` has not changed. +- global `getExpressionInfo(expr)` has not changed. +- global ~~`getMemorySegmentInfo()`~~ ❌ has been removed. + +Most of the `Module` class’s instance methods relating to module component manipulation have been moved. +- `Module#addTag()` → `Module#tags.add()` +- `Module#setGlobal()` → `Module#globals.set()` +- `Module#removeTable()` → `Module#tables.remove()` +- etc. Generally, the pattern is as follows (where `Thing` and `things` are component types (globals, tables, functions, etc.)): + - `Module#addThing()` → `Module#things.add()` + - `Module#getThing()` → `Module#things.get()` + - `Module#getThingByIndex()` → `Module#things.getByIndex()` + - `Module#getNumThings()` → `Module#things.count()` + - `Module#removeThing()` → `Module#things.remove()` + - `Module#addThingImport()` → `Module#imports.addThing()` + - `Module#addThingExport()` → `Module#exports.addThing()` + +Some of `Module`’s instance methods have been converted into getters/setters: +- `Module#getStart()` → `Module#start` +- `Module#setStart()` → `Module#start` +- `Module#getFeatures()` → `Module#features` +- `Module#setFeatures()` → `Module#features` + +`Module#copyExpression(expr)` has been moved to the global function `copyExpression(expr, mod)` where it lives alongside `getExpressionInfo` et al. + + +### Settings +All optimization pass settings have been moved to the global `settings` object. + +- The functions starting with `get`/`set` with zero/one argument have been converted to getters/setters respectively. + - `{get,set}OptimizeLevel()` → `settings.optimizeLevel` + - `{get,set}ShrinkLevel()` → `settings.shrinkLevel` + - `{get,set}DebugInfo()` → `settings.debugInfo` + - `{get,set}TrapsNeverHappen()` → `settings.trapsNeverHappen` + - `{get,set}ClosedWorld()` → `settings.closedWorld` + - `{get,set}LowMemoryUnused()` → `settings.lowMemoryUnused` + - `{get,set}ZeroFilledMemory()` → `settings.zeroFilledMemory` + - `{get,set}FastMath()` → `settings.fastMath` + - `{get,set}GenerateStackIR()` → `settings.generateStackIR` + - `{get,set}OptimizeStackIR()` → `settings.optimizeStackIR` + - `{get,set}AlwaysInlineMaxSize()` → `settings.alwaysInlineMaxSize` + - `{get,set}FlexibleInlineMaxSize()` → `settings.flexibleInlineMaxSize` + - `{get,set}OneCallerInlineMaxSize()` → `settings.oneCallerInlineMaxSize` + - `{get,set}AllowInliningFunctionsWithLoops()` → `settings.allowInliningFunctionsWithLoops` +- Other functions have only been moved. + - `getPassArgument()` → `settings.getPassArgument()` + - `setPassArgument()` → `settings.setPassArgument()` + - `clearPassArguments()` → `settings.clearPassArguments()` + - `hasPassToSkip()` → `settings.hasPassToSkip()` + - `addPassToSkip()` → `settings.addPassToSkip()` + - `clearPassesToSkip()` → `settings.clearPassesToSkip()` From ce27f429c9d95dbda6ac8ebc222372dab3f27abb Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 01:38:14 -0400 Subject: [PATCH 060/247] build: fix gitignore --- .gitignore | 10 ++-------- ts/.gitignore | 5 +++++ 2 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 ts/.gitignore diff --git a/.gitignore b/.gitignore index f866caa990f..825a446c7fa 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,6 @@ Makefile TAGS tags -# dependency directories -node_modules/ - # autogenerated during the build /src/passes/WasmIntrinsics.cpp @@ -49,15 +46,12 @@ CMakeUserPresets.json # files commonly related to building out-of-tree /build/ -# compiling TypeScript -/ts/dist/ - # macOS .DS_Store # files related to VSCode -/.history -/.vscode +.history/ +.vscode/ # Generated by VSCode CMake extension /Testing diff --git a/ts/.gitignore b/ts/.gitignore new file mode 100644 index 00000000000..ac42bb1260d --- /dev/null +++ b/ts/.gitignore @@ -0,0 +1,5 @@ +# dependency directories +node_modules/ + +# compiling TypeScript +dist/ From e6839a1d675c6c2ff51891a9baf822677a4615cd Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 01:56:30 -0400 Subject: [PATCH 061/247] feat: create expression-creator object --- ts/src/classes/expression/Block.ts | 23 +++--- ts/src/classes/expression/Drop.ts | 31 ++++++++ ts/src/classes/expression/LocalGet.ts | 11 ++- ts/src/classes/expression/LocalSet.ts | 19 +++-- .../classes/expression/expression-creators.ts | 72 +++++++++++++++++++ ts/src/classes/expression/index.ts | 3 + ts/src/classes/module/Module.ts | 25 ++----- 7 files changed, 135 insertions(+), 49 deletions(-) create mode 100644 ts/src/classes/expression/Drop.ts create mode 100644 ts/src/classes/expression/expression-creators.ts diff --git a/ts/src/classes/expression/Block.ts b/ts/src/classes/expression/Block.ts index 50d877b8e08..1ec69a12337 100644 --- a/ts/src/classes/expression/Block.ts +++ b/ts/src/classes/expression/Block.ts @@ -22,6 +22,17 @@ import { export class Block extends Expression { + static block = function (this: Module, name: string | null | undefined, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenBlock"]( + this.ptr, + name ? strToStack(name) : 0, + i32sToStack(children), + children.length, + resultType, + )); + }; + + constructor(expr: ExpressionRef) { super(ExpressionId.Block, expr); } @@ -39,15 +50,3 @@ export class Block extends Expression { insertChildAt() {} removeChildAt() {} } - - - -export function block(this: Module, name: string, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenBlock"]( - this.ptr, - strToStack(name), - i32sToStack(children), - children.length, - resultType, - )); -} diff --git a/ts/src/classes/expression/Drop.ts b/ts/src/classes/expression/Drop.ts new file mode 100644 index 00000000000..c5ad76564ba --- /dev/null +++ b/ts/src/classes/expression/Drop.ts @@ -0,0 +1,31 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import type { + Module, +} from "../module/Module.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Drop extends Expression { + static drop = function (this: Module, value: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenDrop"](this.ptr, value); + }; + + + constructor(expr: ExpressionRef) { + super(ExpressionId.Drop, expr); + } + + + // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters + getValue() {} + setValue() {} +} diff --git a/ts/src/classes/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts index a1a31e5a27f..86d5817a24e 100644 --- a/ts/src/classes/expression/LocalGet.ts +++ b/ts/src/classes/expression/LocalGet.ts @@ -16,6 +16,11 @@ import { export class LocalGet extends Expression { + static localGet = function (this: Module, index: number, typ: Type): ExpressionRef { + return BinaryenObj["_BinaryenLocalGet"](this.ptr, index, typ); + }; + + constructor(expr: ExpressionRef) { super(ExpressionId.LocalGet, expr); } @@ -25,9 +30,3 @@ export class LocalGet extends Expression { getIndex() {} setIndex() {} } - - - -export function localGet(this: Module, index: number, type: Type): ExpressionRef { - return BinaryenObj["_BinaryenLocalGet"](this.ptr, index, type); -} diff --git a/ts/src/classes/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts index f3540791f88..d35a1082e6a 100644 --- a/ts/src/classes/expression/LocalSet.ts +++ b/ts/src/classes/expression/LocalSet.ts @@ -16,6 +16,15 @@ import { export class LocalSet extends Expression { + static localSet = function (this: Module, index: number, value: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenLocalSet"](this.ptr, index, value); + }; + + static localTee = function (this: Module, index: number, value: ExpressionRef, typ: Type): ExpressionRef { + return BinaryenObj["_BinaryenLocalTee"](this.ptr, index, value, typ); + }; + + constructor(expr: ExpressionRef) { super(ExpressionId.LocalSet, expr); } @@ -28,13 +37,3 @@ export class LocalSet extends Expression { getValue() {} setValue() {} } - - - -export function localSet(this: Module, index: number, value: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenLocalSet"](this.ptr, index, value); -} - -export function localTee(this: Module, index: number, value: ExpressionRef, type: Type): ExpressionRef { - return BinaryenObj["_BinaryenLocalTee"](this.ptr, index, value, type); -} diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-creators.ts new file mode 100644 index 00000000000..f028545cee6 --- /dev/null +++ b/ts/src/classes/expression/expression-creators.ts @@ -0,0 +1,72 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; +import type { + Module, +} from "../module/Module.ts"; +import { + Block, +} from "./Block.ts"; +import { + Drop, +} from "./Drop.ts"; +import { + LocalGet, +} from "./LocalGet.ts"; +import { + LocalSet, +} from "./LocalSet.ts"; + + + +function parametric(mod: Module) { + return { + /** Creates a no-operation `(nop)` instruction. */ + nop: () => BinaryenObj["_BinaryenNop"](mod.ptr), + /** Creates an unreachable instruction that will always trap. */ + unreachable: () => BinaryenObj["_BinaryenUnreachable"](mod.ptr), + /** Creates a `(drop)` of a value. */ + drop: Drop.drop.bind(mod), + } as const; +} + + + +function control(mod: Module) { + return { + /** Creates a `(block)`. */ + block: Block.block.bind(mod), + } as const; +} + + + +function variables(mod: Module) { + return { + local: { + /** + * Creates a `(local.get)` for the local at the specified index. + * Note that we must specify the type here as we may not have created the local being accessed yet. + */ + get: LocalGet.localGet.bind(mod), + /** Creates a `(local.set)` for the local at the specified index. */ + set: LocalSet.localSet.bind(mod), + /** + * Creates a `(local.tee)` for the local at the specified index. + * Note that we must specify the type here as we may not have created the local being accessed yet. + */ + tee: LocalSet.localTee.bind(mod), + }, + } as const; +} + + + +/** Methods for creating expressions in a WASM module. */ +export function expressionCreator(mod: Module) { + return { + ...parametric(mod), + ...control(mod), + ...variables(mod), + } as const; +} diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 4b29792653a..589a6b0a710 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -1,5 +1,8 @@ export {Expression} from "./Expression.ts"; +// ## Parametric ## // +export {Drop} from "./Drop.ts"; + // ## Control ## // export {Block} from "./Block.ts"; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index f89884070c4..331f6ffc21c 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -29,15 +29,8 @@ import { strToStack, } from "../../utils.ts"; import { - block, -} from "../expression/Block.ts"; -import { - localGet, -} from "../expression/LocalGet.ts"; -import { - localSet, - localTee, -} from "../expression/LocalSet.ts"; + expressionCreator, +} from "../expression/expression-creators.ts"; import * as DATA_SEGMENT from "./DataSegment.ts"; import * as ELEMENT_SEGMENT from "./ElementSegment.ts"; import * as EXPORT from "./Export.ts"; @@ -130,18 +123,8 @@ export enum Feature { export class Module { readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); - // ## Expression Creation ## // - // ### Control Instructions ### // - block = block; - - // ### Variable Instructions ### // - get local() { - return { - get: localGet.bind(this), - set: localSet.bind(this), - tee: localTee.bind(this), - }; - } + /** This module’s expression creator. */ + readonly x = expressionCreator(this); // “x” for “expression” // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html From 53e30f1f236f57b8a501281a9d5a1026522d3e60 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 03:14:07 -0400 Subject: [PATCH 062/247] fix: convert `{g,s}et*` methods to accessors --- ts/src/classes/expression/Const.ts | 57 +++++++------------ ts/src/classes/expression/Expression.ts | 15 +++-- ts/src/classes/module/Function.ts | 44 +++++++-------- ts/src/classes/module/Table.ts | 73 ++++++------------------- 4 files changed, 64 insertions(+), 125 deletions(-) diff --git a/ts/src/classes/expression/Const.ts b/ts/src/classes/expression/Const.ts index a1766db5a18..74f9063789e 100644 --- a/ts/src/classes/expression/Const.ts +++ b/ts/src/classes/expression/Const.ts @@ -28,51 +28,32 @@ export class Const extends Expression { } get value(): number | number[] { - const this_type = this.getType(); - switch (this.getType()) { - case i32: { return this.getValueI32(); } - case i64: { return this.getValueI64(); } - case f32: { return this.getValueF32(); } - case f64: { return this.getValueF64(); } - case v128: { return this.getValueV128(); } + const this_type = this.type; + switch (this_type) { + case i32: { return this.valueI32; } + case i64: { return this.valueI64; } + case f32: { return this.valueF32; } + case f64: { return this.valueF64; } + case v128: { return this.valueV128; } } throw new Error(`Unexpected type: ${ this_type }.`); } - // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters - getValueI32(): number { - return BinaryenObj["_BinaryenConstGetValueI32"](this[THIS_PTR]); - } - - setValueI32(value: number): void { - BinaryenObj["_BinaryenConstSetValueI32"](this[THIS_PTR], value); - } - - getValueI64(): number { - return BinaryenObj["_BinaryenConstGetValueI64"](this[THIS_PTR]); - } - - setValueI64(value: number): void { - BinaryenObj["_BinaryenConstSetValueI64"](this[THIS_PTR], BigInt(value)); - } - - getValueF32(): number { - return BinaryenObj["_BinaryenConstGetValueF32"](this[THIS_PTR]); - } + /* eslint-disable @stylistic/brace-style */ + get valueI32(): number { return BinaryenObj["_BinaryenConstGetValueI32"](this[THIS_PTR]); } + set valueI32(value: number) { BinaryenObj["_BinaryenConstSetValueI32"](this[THIS_PTR], value); } - setValueF32(value: number): void { - BinaryenObj["_BinaryenConstSetValueF32"](this[THIS_PTR], value); - } + get valueI64(): number { return BinaryenObj["_BinaryenConstGetValueI64"](this[THIS_PTR]); } + set valueI64(value: number) { BinaryenObj["_BinaryenConstSetValueI64"](this[THIS_PTR], BigInt(value)); } - getValueF64(): number { - return BinaryenObj["_BinaryenConstGetValueF64"](this[THIS_PTR]); - } + get valueF32(): number { return BinaryenObj["_BinaryenConstGetValueF32"](this[THIS_PTR]); } + set valueF32(value: number) { BinaryenObj["_BinaryenConstSetValueF32"](this[THIS_PTR], value); } - setValueF64(value: number): void { - BinaryenObj["_BinaryenConstSetValueF64"](this[THIS_PTR], value); - } + get valueF64(): number { return BinaryenObj["_BinaryenConstGetValueF64"](this[THIS_PTR]); } + set valueF64(value: number) { BinaryenObj["_BinaryenConstSetValueF64"](this[THIS_PTR], value); } + /* eslint-enable @stylistic/brace-style */ - getValueV128(): number[] { + get valueV128(): number[] { const value: number[] = []; preserveStack(() => { const tempBuffer = stackAlloc(16); @@ -84,7 +65,7 @@ export class Const extends Expression { return value; } - setValueV128(value: readonly number[]): void { + set valueV128(value: readonly number[]) { preserveStack(() => { const tempBuffer = stackAlloc(16); for (let i = 0; i < 16; ++i) { diff --git a/ts/src/classes/expression/Expression.ts b/ts/src/classes/expression/Expression.ts index 1a43bd2146e..2d71660a715 100644 --- a/ts/src/classes/expression/Expression.ts +++ b/ts/src/classes/expression/Expression.ts @@ -36,23 +36,22 @@ export class Expression { this.#id = exprId; } - valueOf(): ExpressionRef { - return this[THIS_PTR]; - } - - // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters - getId(): ExpressionId { + get id(): ExpressionId { return this.#id; } - getType(): Type { + get type(): Type { return getExpressionType(this[THIS_PTR]); } - setType(typ: Type): void { + set type(typ: Type) { BinaryenObj["_BinaryenExpressionSetType"](this[THIS_PTR], typ); } + valueOf(): ExpressionRef { + return this[THIS_PTR]; + } + finalize(): void { BinaryenObj["_BinaryenExpressionFinalize"](this[THIS_PTR]); } diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index aefc184293f..a807326a1d1 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -37,37 +37,45 @@ class BinaryenFunction { } - valueOf(): FunctionRef { - return this[THIS_PTR]; - } - - // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters - getName(): string { + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenFunctionGetName"](this[THIS_PTR])); } - getType(): Type { + get type(): Type { return BinaryenObj["_BinaryenFunctionGetType"](this[THIS_PTR]); } - getParams(): Type { + get params(): Type { return BinaryenObj["_BinaryenFunctionGetParams"](this[THIS_PTR]); } - getResults(): Type { + get results(): Type { return BinaryenObj["_BinaryenFunctionGetResults"](this[THIS_PTR]); } - getNumVars(): number { + get numVars(): number { return BinaryenObj["_BinaryenFunctionGetNumVars"](this[THIS_PTR]); } - getVar(index: number): Type { - return BinaryenObj["_BinaryenFunctionGetVar"](this[THIS_PTR], index); + get numLocals(): number { + return BinaryenObj["_BinaryenFunctionGetNumLocals"](this[THIS_PTR]); } - getNumLocals(): number { - return BinaryenObj["_BinaryenFunctionGetNumLocals"](this[THIS_PTR]); + get body(): ExpressionRef { + return BinaryenObj["_BinaryenFunctionGetBody"](this[THIS_PTR]); + } + + set body(bodyExpr: ExpressionRef) { + BinaryenObj["_BinaryenFunctionSetBody"](this[THIS_PTR], bodyExpr); + } + + + valueOf(): FunctionRef { + return this[THIS_PTR]; + } + + getVar(index: number): Type { + return BinaryenObj["_BinaryenFunctionGetVar"](this[THIS_PTR], index); } hasLocalName(index: number): boolean { @@ -83,14 +91,6 @@ class BinaryenFunction { BinaryenObj["_BinaryenFunctionSetLocalName"](this[THIS_PTR], index, strToStack(name)); }); } - - getBody(): ExpressionRef { - return BinaryenObj["_BinaryenFunctionGetBody"](this[THIS_PTR]); - } - - setBody(bodyExpr: ExpressionRef): void { - BinaryenObj["_BinaryenFunctionSetBody"](this[THIS_PTR], bodyExpr); - } } export {BinaryenFunction as Function}; diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index a7e3c27b001..47d29e7447c 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -35,39 +35,26 @@ export class Table { } - valueOf(): TableRef { - return this[THIS_PTR]; - } + /* eslint-disable @stylistic/brace-style */ + /** The name of this table */ + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetName"](this[THIS_PTR])); } + set name(name: string) { preserveStack(() => { BinaryenObj["_BinaryenTableSetName"](this[THIS_PTR], strToStack(name)); }); } - // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters - /** - * @return the name of this table - */ - getName(): string { - return UTF8ToString(BinaryenObj["_BinaryenTableGetName"](this[THIS_PTR])); - } + /** The initial number of pages of this table. */ + get initial(): number { return BinaryenObj["_BinaryenTableGetInitial"](this[THIS_PTR]); } + set initial(initial: number) { BinaryenObj["_BinaryenTableSetInitial"](this[THIS_PTR], initial); } - /** - * @param name the new name for the this table - */ - setName(name: string): void { - preserveStack(() => { - BinaryenObj["_BinaryenTableSetName"](this[THIS_PTR], strToStack(name)); - }); - } + /** The maximum number of pages of this table. */ + get max(): number { return BinaryenObj["_BinaryenTableGetMax"](this[THIS_PTR]); } + set max(max: number) { BinaryenObj["_BinaryenTableSetMax"](this[THIS_PTR], max); } - /** - * @return the initial number of pages of the `Table` - */ - getInitial(): number { - return BinaryenObj["_BinaryenTableGetInitial"](this[THIS_PTR]); - } + /** The type of this table. */ + get type(): Type { return BinaryenObj["_BinaryenTableGetType"](this[THIS_PTR]); } + set type(tableType: Type) { BinaryenObj["_BinaryenTableSetType"](this[THIS_PTR], tableType); } + /* eslint-enable @stylistic/brace-style */ - /** - * @param initial the new initial number of pages for this table - */ - setInitial(initial: number): void { - BinaryenObj["_BinaryenTableSetInitial"](this[THIS_PTR], initial); + valueOf(): TableRef { + return this[THIS_PTR]; } /** @@ -76,34 +63,6 @@ export class Table { hasMax(): boolean { return Boolean(BinaryenObj["_BinaryenTableHasMax"](this[THIS_PTR])); } - - /** - * @return the maximum number of pages of this table - */ - getMax(): number { - return BinaryenObj["_BinaryenTableGetMax"](this[THIS_PTR]); - } - - /** - * @param max the maximum number of pages of this table - */ - setMax(max: number): void { - BinaryenObj["_BinaryenTableSetMax"](this[THIS_PTR], max); - } - - /** - * @return the type of this table - */ - getType(): Type { - return BinaryenObj["_BinaryenTableGetType"](this[THIS_PTR]); - } - - /** - * @param tableType the new type for this table - */ - setType(tableType: Type): void { - BinaryenObj["_BinaryenTableSetType"](this[THIS_PTR], tableType); - } } From 2509b623beab0397cdfcb63c3cf866b2f6789f89 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 03:17:42 -0400 Subject: [PATCH 063/247] feat: impl Expression methods --- ts/src/classes/expression/Block.ts | 62 ++++++++++++++++++++++----- ts/src/classes/expression/Drop.ts | 13 ++++-- ts/src/classes/expression/LocalGet.ts | 13 ++++-- ts/src/classes/expression/LocalSet.ts | 20 ++++++--- ts/src/utils.ts | 3 +- 5 files changed, 86 insertions(+), 25 deletions(-) diff --git a/ts/src/classes/expression/Block.ts b/ts/src/classes/expression/Block.ts index 1ec69a12337..2b4f6cf8c02 100644 --- a/ts/src/classes/expression/Block.ts +++ b/ts/src/classes/expression/Block.ts @@ -1,5 +1,6 @@ import { BinaryenObj, + UTF8ToString, } from "../../-pre.ts"; import { ExpressionId, @@ -8,8 +9,11 @@ import { none, } from "../../constants.ts"; import { + THIS_PTR, i32sToStack, + getAllNested, preserveStack, + setAllNested, strToStack, } from "../../utils.ts"; import type { @@ -38,15 +42,51 @@ export class Block extends Expression { } - // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters - getName() {} - setName() {} - getNumChildren() {} - getChildren() {} - setChildren() {} - getChildAt() {} - setChildAt() {} - appendChild() {} - insertChildAt() {} - removeChildAt() {} + get name(): string | null { + const name = BinaryenObj["_BinaryenBlockGetName"](this[THIS_PTR]); + return name ? UTF8ToString(name) : null; + } + + set name(name: string) { + preserveStack(() => BinaryenObj["_BinaryenBlockSetName"](this[THIS_PTR], strToStack(name))); + } + + get numChildren(): number { + return BinaryenObj["_BinaryenBlockGetNumChildren"](this[THIS_PTR]); + } + + get children() { + return getAllNested(this[THIS_PTR], BinaryenObj["_BinaryenBlockGetNumChildren"], BinaryenObj["_BinaryenBlockGetChildAt"]); + } + + set children(children: readonly ExpressionRef[]) { + setAllNested( + this[THIS_PTR], + children, + BinaryenObj["_BinaryenBlockGetNumChildren"], + BinaryenObj["_BinaryenBlockSetChildAt"], + BinaryenObj["_BinaryenBlockAppendChild"], + BinaryenObj["_BinaryenBlockRemoveChildAt"], + ); + } + + getChildAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenBlockGetChildAt"](this[THIS_PTR], index); + } + + setChildAt(index: number, childExpr: ExpressionRef): void { + BinaryenObj["_BinaryenBlockSetChildAt"](this[THIS_PTR], index, childExpr); + } + + appendChild(childExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenBlockAppendChild"](this[THIS_PTR], childExpr); + } + + insertChildAt(index: number, childExpr: ExpressionRef): void { + BinaryenObj["_BinaryenBlockInsertChildAt"](this[THIS_PTR], index, childExpr); + } + + removeChildAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenBlockRemoveChildAt"](this[THIS_PTR], index); + } } diff --git a/ts/src/classes/expression/Drop.ts b/ts/src/classes/expression/Drop.ts index c5ad76564ba..4f0a288e5f8 100644 --- a/ts/src/classes/expression/Drop.ts +++ b/ts/src/classes/expression/Drop.ts @@ -5,6 +5,9 @@ import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; +import { + THIS_PTR, +} from "../../utils.ts"; import type { Module, } from "../module/Module.ts"; @@ -25,7 +28,11 @@ export class Drop extends Expression { } - // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters - getValue() {} - setValue() {} + get value(): ExpressionRef { + return BinaryenObj["_BinaryenDropGetValue"](this[THIS_PTR]); + } + + set value(valueExpr: ExpressionRef) { + BinaryenObj["_BinaryenDropSetValue"](this[THIS_PTR], valueExpr); + } } diff --git a/ts/src/classes/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts index 86d5817a24e..d8450ba8772 100644 --- a/ts/src/classes/expression/LocalGet.ts +++ b/ts/src/classes/expression/LocalGet.ts @@ -6,6 +6,9 @@ import { type ExpressionRef, type Type, } from "../../constants.ts"; +import { + THIS_PTR, +} from "../../utils.ts"; import type { Module, } from "../module/Module.ts"; @@ -26,7 +29,11 @@ export class LocalGet extends Expression { } - // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters - getIndex() {} - setIndex() {} + get index(): number { + return BinaryenObj["_BinaryenLocalGetGetIndex"](this[THIS_PTR]); + } + + set index(index: number) { + BinaryenObj["_BinaryenLocalGetSetIndex"](this[THIS_PTR], index); + } } diff --git a/ts/src/classes/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts index d35a1082e6a..2a7a5778eca 100644 --- a/ts/src/classes/expression/LocalSet.ts +++ b/ts/src/classes/expression/LocalSet.ts @@ -6,6 +6,9 @@ import { type ExpressionRef, type Type, } from "../../constants.ts"; +import { + THIS_PTR, +} from "../../utils.ts"; import type { Module, } from "../module/Module.ts"; @@ -30,10 +33,15 @@ export class LocalSet extends Expression { } - // FIXME: post.js has converted all methods starting with `get` to getters and `set` to setters - getIndex() {} - setIndex() {} - isTee() {} - getValue() {} - setValue() {} + /* eslint-disable @stylistic/brace-style */ + get index(): number { return BinaryenObj["_BinaryenLocalSetGetIndex"](this[THIS_PTR]); } + set index(index: number) { BinaryenObj["_BinaryenLocalSetSetIndex"](this[THIS_PTR], index); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenLocalSetGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenLocalSetSetValue"](this[THIS_PTR], valueExpr); } + /* eslint-enable @stylistic/brace-style */ + + get isTee(): boolean { + return Boolean(BinaryenObj["_BinaryenLocalSetIsTee"](this[THIS_PTR])); + } } diff --git a/ts/src/utils.ts b/ts/src/utils.ts index 61e8f99aae9..eedf3cea43a 100644 --- a/ts/src/utils.ts +++ b/ts/src/utils.ts @@ -101,8 +101,7 @@ export function getAllNested( * @param appendFn [description] * @param removeFn [description] */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -function setAllNested( +export function setAllNested( ref: T, values: readonly U[], numFn: (ref: T) => number, From 2acce9a5274cc02bbee52b24ee182443db4a8509 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 03:29:30 -0400 Subject: [PATCH 064/247] feat: add Select --- ts/src/classes/expression/Select.ts | 41 +++++++++++++++++++ .../classes/expression/expression-creators.ts | 11 ++--- ts/src/classes/expression/index.ts | 1 + 3 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 ts/src/classes/expression/Select.ts diff --git a/ts/src/classes/expression/Select.ts b/ts/src/classes/expression/Select.ts new file mode 100644 index 00000000000..b1cb493d72c --- /dev/null +++ b/ts/src/classes/expression/Select.ts @@ -0,0 +1,41 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + THIS_PTR, +} from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Select extends Expression { + static select = function (this: Module, ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenSelect"](this.ptr, ifTrue, ifFalse); + }; + + + constructor(expr: ExpressionRef) { + super(ExpressionId.Select, expr); + } + + + /* eslint-disable @stylistic/brace-style */ + get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetIfTrue"](this[THIS_PTR]); } + set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetIfTrue"](this[THIS_PTR], ifTrueExpr); } + + get ifFalse(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetIfFalse"](this[THIS_PTR]); } + set ifFalse(ifFalseExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetIfFalse"](this[THIS_PTR], ifFalseExpr); } + + get condition(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetCondition"](this[THIS_PTR]); } + set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetCondition"](this[THIS_PTR], condExpr); } + /* eslint-enable @stylistic/brace-style */ +} diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-creators.ts index f028545cee6..83c15628da2 100644 --- a/ts/src/classes/expression/expression-creators.ts +++ b/ts/src/classes/expression/expression-creators.ts @@ -6,16 +6,11 @@ import type { } from "../module/Module.ts"; import { Block, -} from "./Block.ts"; -import { Drop, -} from "./Drop.ts"; -import { LocalGet, -} from "./LocalGet.ts"; -import { LocalSet, -} from "./LocalSet.ts"; + Select, +} from "./index.ts"; @@ -27,6 +22,8 @@ function parametric(mod: Module) { unreachable: () => BinaryenObj["_BinaryenUnreachable"](mod.ptr), /** Creates a `(drop)` of a value. */ drop: Drop.drop.bind(mod), + /** Creates a `(select)` of one of two values. */ + select: Select.select.bind(mod), } as const; } diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 589a6b0a710..4a8389bd93f 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -2,6 +2,7 @@ export {Expression} from "./Expression.ts"; // ## Parametric ## // export {Drop} from "./Drop.ts"; +export {Select} from "./Select.ts"; // ## Control ## // export {Block} from "./Block.ts"; From 8dcf0c8f47ace92be1b1135d1f087de7cbe814c1 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 03:37:54 -0400 Subject: [PATCH 065/247] lint: allow single-line braces --- ts/eslint.config.js | 2 +- ts/src/classes/expression/Const.ts | 2 -- ts/src/classes/expression/LocalSet.ts | 2 -- ts/src/classes/expression/Select.ts | 2 -- ts/src/classes/module/Module.ts | 4 ---- ts/src/classes/module/Table.ts | 2 -- ts/src/services/SettingsService.ts | 2 -- 7 files changed, 1 insertion(+), 15 deletions(-) diff --git a/ts/eslint.config.js b/ts/eslint.config.js index 78aba9f151f..72fad528144 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -48,7 +48,7 @@ export default [ "@stylistic/array-bracket-spacing": "error", "@stylistic/array-element-newline": ["error", "consistent"], "arrow-body-style": "error", - "@stylistic/brace-style": "error", + "@stylistic/brace-style": ["error", "1tbs", {allowSingleLine: true}], "@stylistic/computed-property-spacing": "error", curly: "error", "@stylistic/function-call-argument-newline": ["error", "consistent"], diff --git a/ts/src/classes/expression/Const.ts b/ts/src/classes/expression/Const.ts index 74f9063789e..8d7dd13fc48 100644 --- a/ts/src/classes/expression/Const.ts +++ b/ts/src/classes/expression/Const.ts @@ -39,7 +39,6 @@ export class Const extends Expression { throw new Error(`Unexpected type: ${ this_type }.`); } - /* eslint-disable @stylistic/brace-style */ get valueI32(): number { return BinaryenObj["_BinaryenConstGetValueI32"](this[THIS_PTR]); } set valueI32(value: number) { BinaryenObj["_BinaryenConstSetValueI32"](this[THIS_PTR], value); } @@ -51,7 +50,6 @@ export class Const extends Expression { get valueF64(): number { return BinaryenObj["_BinaryenConstGetValueF64"](this[THIS_PTR]); } set valueF64(value: number) { BinaryenObj["_BinaryenConstSetValueF64"](this[THIS_PTR], value); } - /* eslint-enable @stylistic/brace-style */ get valueV128(): number[] { const value: number[] = []; diff --git a/ts/src/classes/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts index 2a7a5778eca..a6143150330 100644 --- a/ts/src/classes/expression/LocalSet.ts +++ b/ts/src/classes/expression/LocalSet.ts @@ -33,13 +33,11 @@ export class LocalSet extends Expression { } - /* eslint-disable @stylistic/brace-style */ get index(): number { return BinaryenObj["_BinaryenLocalSetGetIndex"](this[THIS_PTR]); } set index(index: number) { BinaryenObj["_BinaryenLocalSetSetIndex"](this[THIS_PTR], index); } get value(): ExpressionRef { return BinaryenObj["_BinaryenLocalSetGetValue"](this[THIS_PTR]); } set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenLocalSetSetValue"](this[THIS_PTR], valueExpr); } - /* eslint-enable @stylistic/brace-style */ get isTee(): boolean { return Boolean(BinaryenObj["_BinaryenLocalSetIsTee"](this[THIS_PTR])); diff --git a/ts/src/classes/expression/Select.ts b/ts/src/classes/expression/Select.ts index b1cb493d72c..d8cee37422e 100644 --- a/ts/src/classes/expression/Select.ts +++ b/ts/src/classes/expression/Select.ts @@ -28,7 +28,6 @@ export class Select extends Expression { } - /* eslint-disable @stylistic/brace-style */ get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetIfTrue"](this[THIS_PTR]); } set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetIfTrue"](this[THIS_PTR], ifTrueExpr); } @@ -37,5 +36,4 @@ export class Select extends Expression { get condition(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetCondition"](this[THIS_PTR]); } set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetCondition"](this[THIS_PTR], condExpr); } - /* eslint-enable @stylistic/brace-style */ } diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 331f6ffc21c..1bf7526ddce 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -138,12 +138,10 @@ export class Module { readonly imports = new IMPORT.ModuleImports(this); readonly exports = new EXPORT.ModuleExports(this); - /* eslint-disable @stylistic/brace-style */ /** @deprecated Use `this.start` instead. */ @replacedBy("`this.start`") getStart() { return this.start; } /** @deprecated Use `this.start` instead. */ @replacedBy("`this.start`") setStart(start: FunctionRef) { this.start = start; } /** @deprecated Use `this.features` instead. */ @replacedBy("`this.features`") getFeatures() { return this.features; } /** @deprecated Use `this.features` instead. */ @replacedBy("`this.features`") setFeatures(features: Feature) { return this.features = features; } - /* eslint-enable @stylistic/brace-style */ /** The start function. */ get start(): FunctionRef { @@ -166,7 +164,6 @@ export class Module { BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); } - /* eslint-disable @stylistic/brace-style */ /** @deprecated Use `this.tags.add` instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } /** @deprecated Use `this.tags.get` instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } /** @deprecated Use `this.tags.remove` instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } @@ -219,7 +216,6 @@ export class Module { /** @deprecated Use `this.exports.getByIndex` instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } /** @deprecated Use `this.exports.count` instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } /** @deprecated Use `this.exports.remove` instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } - /* eslint-enable @stylistic/brace-style */ getMemoryInfo(name: string): MEMORY.Memory { return new MEMORY.Memory(this, name); diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 47d29e7447c..e71288a8c01 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -35,7 +35,6 @@ export class Table { } - /* eslint-disable @stylistic/brace-style */ /** The name of this table */ get name(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetName"](this[THIS_PTR])); } set name(name: string) { preserveStack(() => { BinaryenObj["_BinaryenTableSetName"](this[THIS_PTR], strToStack(name)); }); } @@ -51,7 +50,6 @@ export class Table { /** The type of this table. */ get type(): Type { return BinaryenObj["_BinaryenTableGetType"](this[THIS_PTR]); } set type(tableType: Type) { BinaryenObj["_BinaryenTableSetType"](this[THIS_PTR], tableType); } - /* eslint-enable @stylistic/brace-style */ valueOf(): TableRef { return this[THIS_PTR]; diff --git a/ts/src/services/SettingsService.ts b/ts/src/services/SettingsService.ts index fe67564a4c9..3484bb3fc80 100644 --- a/ts/src/services/SettingsService.ts +++ b/ts/src/services/SettingsService.ts @@ -10,7 +10,6 @@ import { class SettingsService { - /* eslint-disable @stylistic/brace-style */ /** The currently set optimize level. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ get optimizeLevel(): number { return BinaryenObj["_BinaryenGetOptimizeLevel"](); } set optimizeLevel(level: number) { BinaryenObj["_BinaryenSetOptimizeLevel"](level); } @@ -66,7 +65,6 @@ class SettingsService { /** Are functions with loops allowed to be inlined? */ get allowInliningFunctionsWithLoops(): boolean { return Boolean(BinaryenObj["_BinaryenGetAllowInliningFunctionsWithLoops"]()); } set allowInliningFunctionsWithLoops(enabled: boolean) { BinaryenObj["_BinaryenSetAllowInliningFunctionsWithLoops"](enabled); } - /* eslint-enable @stylistic/brace-style */ /** Gets the value of the specified arbitrary pass argument. */ From f82ea93482694248e4ea3b882c33039526caa28f Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 03:47:34 -0400 Subject: [PATCH 066/247] feat: add Loop --- ts/src/classes/expression/Loop.ts | 45 +++++++++++++++++++ .../classes/expression/expression-creators.ts | 3 ++ ts/src/classes/expression/index.ts | 1 + 3 files changed, 49 insertions(+) create mode 100644 ts/src/classes/expression/Loop.ts diff --git a/ts/src/classes/expression/Loop.ts b/ts/src/classes/expression/Loop.ts new file mode 100644 index 00000000000..43a8f47ce97 --- /dev/null +++ b/ts/src/classes/expression/Loop.ts @@ -0,0 +1,45 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Loop extends Expression { + static loop = function (this: Module, label: string, body: ExpressionRef): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenLoop"](this.ptr, strToStack(label), body)); + }; + + + constructor(expr: ExpressionRef) { + super(ExpressionId.Loop, expr); + } + + + get name(): string | null { + const name = BinaryenObj["_BinaryenLoopGetName"](this[THIS_PTR]); + return name ? UTF8ToString(name) : null; + } + + set name(name: string) { + preserveStack(() => BinaryenObj["_BinaryenLoopSetName"](this[THIS_PTR], strToStack(name))); + } + + get body(): ExpressionRef { return BinaryenObj["_BinaryenLoopGetBody"](this[THIS_PTR]); } + set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenLoopSetBody"](this[THIS_PTR], bodyExpr); } +} diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-creators.ts index 83c15628da2..d7cba2af0c0 100644 --- a/ts/src/classes/expression/expression-creators.ts +++ b/ts/src/classes/expression/expression-creators.ts @@ -9,6 +9,7 @@ import { Drop, LocalGet, LocalSet, + Loop, Select, } from "./index.ts"; @@ -33,6 +34,8 @@ function control(mod: Module) { return { /** Creates a `(block)`. */ block: Block.block.bind(mod), + /** Creates a loop. */ + loop: Loop.loop.bind(mod), } as const; } diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 4a8389bd93f..6b9d8631cad 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -6,6 +6,7 @@ export {Select} from "./Select.ts"; // ## Control ## // export {Block} from "./Block.ts"; +export {Loop} from "./Loop.ts"; // ## Variable ## // export {LocalGet} from "./LocalGet.ts"; From 18579c4c6531141e86cf4be5148c04a1cdb09f8a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 04:22:31 -0400 Subject: [PATCH 067/247] feat: add Break --- ts/src/classes/expression/Break.ts | 52 +++++++++++++++++++ .../classes/expression/expression-creators.ts | 5 ++ ts/src/classes/expression/index.ts | 1 + 3 files changed, 58 insertions(+) create mode 100644 ts/src/classes/expression/Break.ts diff --git a/ts/src/classes/expression/Break.ts b/ts/src/classes/expression/Break.ts new file mode 100644 index 00000000000..43c1e529907 --- /dev/null +++ b/ts/src/classes/expression/Break.ts @@ -0,0 +1,52 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Break extends Expression { + static br = function (this: Module, label: string, condition?: ExpressionRef, value?: ExpressionRef): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenBreak"](this.ptr, strToStack(label), condition!, value!)); + }; + + static br_if = function (this: Module, label: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenBreak"](this.ptr, strToStack(label), condition, value!)); + }; + + + constructor(expr: ExpressionRef) { + super(ExpressionId.Loop, expr); + } + + + get name(): string | null { + const name = BinaryenObj["_BinaryenBreakGetName"](this[THIS_PTR]); + return name ? UTF8ToString(name) : null; + } + + set name(name: string) { + preserveStack(() => BinaryenObj["_BinaryenBreakSetName"](this[THIS_PTR], strToStack(name))); + } + + get condition(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetCondition"](this[THIS_PTR]); } + set condition(condExpr: ExpressionRef) {BinaryenObj["_BinaryenBreakSetCondition"](this[THIS_PTR], condExpr);} + + get value(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenBreakSetValue"](this[THIS_PTR], valueExpr); } +} diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-creators.ts index d7cba2af0c0..4e35eda23a4 100644 --- a/ts/src/classes/expression/expression-creators.ts +++ b/ts/src/classes/expression/expression-creators.ts @@ -6,6 +6,7 @@ import type { } from "../module/Module.ts"; import { Block, + Break, Drop, LocalGet, LocalSet, @@ -36,6 +37,10 @@ function control(mod: Module) { block: Block.block.bind(mod), /** Creates a loop. */ loop: Loop.loop.bind(mod), + /** Creates an unconditional branch `(br)` to a label. */ + br: Break.br.bind(mod), + /** Creates a conditional branch `(br_if)` to a label. */ + br_if: Break.br_if.bind(mod), } as const; } diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 6b9d8631cad..ac41477da37 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -7,6 +7,7 @@ export {Select} from "./Select.ts"; // ## Control ## // export {Block} from "./Block.ts"; export {Loop} from "./Loop.ts"; +export {Break} from "./Break.ts"; // ## Variable ## // export {LocalGet} from "./LocalGet.ts"; From f925265cc4a5335fee396dba990c634a85bf3af7 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 05:00:20 -0400 Subject: [PATCH 068/247] refactor: re-parameterize static methods --- ts/src/classes/expression/Block.ts | 6 ++--- ts/src/classes/expression/Break.ts | 12 +++++----- ts/src/classes/expression/Drop.ts | 6 ++--- ts/src/classes/expression/LocalGet.ts | 6 ++--- ts/src/classes/expression/LocalSet.ts | 12 +++++----- ts/src/classes/expression/Loop.ts | 6 ++--- ts/src/classes/expression/Select.ts | 6 ++--- .../classes/expression/expression-creators.ts | 24 ++++++++++++------- 8 files changed, 42 insertions(+), 36 deletions(-) diff --git a/ts/src/classes/expression/Block.ts b/ts/src/classes/expression/Block.ts index 2b4f6cf8c02..6b69e9a02b6 100644 --- a/ts/src/classes/expression/Block.ts +++ b/ts/src/classes/expression/Block.ts @@ -26,15 +26,15 @@ import { export class Block extends Expression { - static block = function (this: Module, name: string | null | undefined, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef { + static block(mod: Module, name: string | null | undefined, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef { return preserveStack(() => BinaryenObj["_BinaryenBlock"]( - this.ptr, + mod.ptr, name ? strToStack(name) : 0, i32sToStack(children), children.length, resultType, )); - }; + } constructor(expr: ExpressionRef) { diff --git a/ts/src/classes/expression/Break.ts b/ts/src/classes/expression/Break.ts index 43c1e529907..92d5739e209 100644 --- a/ts/src/classes/expression/Break.ts +++ b/ts/src/classes/expression/Break.ts @@ -21,13 +21,13 @@ import { export class Break extends Expression { - static br = function (this: Module, label: string, condition?: ExpressionRef, value?: ExpressionRef): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenBreak"](this.ptr, strToStack(label), condition!, value!)); - }; + static br(mod: Module, label: string, condition?: ExpressionRef, value?: ExpressionRef): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition!, value!)); + } - static br_if = function (this: Module, label: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenBreak"](this.ptr, strToStack(label), condition, value!)); - }; + static br_if(mod: Module, label: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition, value!)); + } constructor(expr: ExpressionRef) { diff --git a/ts/src/classes/expression/Drop.ts b/ts/src/classes/expression/Drop.ts index 4f0a288e5f8..fe7185771cf 100644 --- a/ts/src/classes/expression/Drop.ts +++ b/ts/src/classes/expression/Drop.ts @@ -18,9 +18,9 @@ import { export class Drop extends Expression { - static drop = function (this: Module, value: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenDrop"](this.ptr, value); - }; + static drop(mod: Module, value: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenDrop"](mod.ptr, value); + } constructor(expr: ExpressionRef) { diff --git a/ts/src/classes/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts index d8450ba8772..5a09238abbd 100644 --- a/ts/src/classes/expression/LocalGet.ts +++ b/ts/src/classes/expression/LocalGet.ts @@ -19,9 +19,9 @@ import { export class LocalGet extends Expression { - static localGet = function (this: Module, index: number, typ: Type): ExpressionRef { - return BinaryenObj["_BinaryenLocalGet"](this.ptr, index, typ); - }; + static localGet(mod: Module, index: number, typ: Type): ExpressionRef { + return BinaryenObj["_BinaryenLocalGet"](mod.ptr, index, typ); + } constructor(expr: ExpressionRef) { diff --git a/ts/src/classes/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts index a6143150330..0ba257807b4 100644 --- a/ts/src/classes/expression/LocalSet.ts +++ b/ts/src/classes/expression/LocalSet.ts @@ -19,13 +19,13 @@ import { export class LocalSet extends Expression { - static localSet = function (this: Module, index: number, value: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenLocalSet"](this.ptr, index, value); - }; + static localSet(mod: Module, index: number, value: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenLocalSet"](mod.ptr, index, value); + } - static localTee = function (this: Module, index: number, value: ExpressionRef, typ: Type): ExpressionRef { - return BinaryenObj["_BinaryenLocalTee"](this.ptr, index, value, typ); - }; + static localTee(mod: Module, index: number, value: ExpressionRef, typ: Type): ExpressionRef { + return BinaryenObj["_BinaryenLocalTee"](mod.ptr, index, value, typ); + } constructor(expr: ExpressionRef) { diff --git a/ts/src/classes/expression/Loop.ts b/ts/src/classes/expression/Loop.ts index 43a8f47ce97..a835fe25b56 100644 --- a/ts/src/classes/expression/Loop.ts +++ b/ts/src/classes/expression/Loop.ts @@ -21,9 +21,9 @@ import { export class Loop extends Expression { - static loop = function (this: Module, label: string, body: ExpressionRef): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenLoop"](this.ptr, strToStack(label), body)); - }; + static loop(mod: Module, label: string, body: ExpressionRef): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenLoop"](mod.ptr, strToStack(label), body)); + } constructor(expr: ExpressionRef) { diff --git a/ts/src/classes/expression/Select.ts b/ts/src/classes/expression/Select.ts index d8cee37422e..0cb55965f89 100644 --- a/ts/src/classes/expression/Select.ts +++ b/ts/src/classes/expression/Select.ts @@ -18,9 +18,9 @@ import { export class Select extends Expression { - static select = function (this: Module, ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenSelect"](this.ptr, ifTrue, ifFalse); - }; + static select(mod: Module, ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenSelect"](mod.ptr, ifTrue, ifFalse); + } constructor(expr: ExpressionRef) { diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-creators.ts index 4e35eda23a4..6ca26c3fd32 100644 --- a/ts/src/classes/expression/expression-creators.ts +++ b/ts/src/classes/expression/expression-creators.ts @@ -16,6 +16,12 @@ import { +function extractParam(a: First, fn: (a: First, ...rest: Rest) => Return): (...rest: Rest) => Return { + return (...args) => fn(a, ...args); +} + + + function parametric(mod: Module) { return { /** Creates a no-operation `(nop)` instruction. */ @@ -23,9 +29,9 @@ function parametric(mod: Module) { /** Creates an unreachable instruction that will always trap. */ unreachable: () => BinaryenObj["_BinaryenUnreachable"](mod.ptr), /** Creates a `(drop)` of a value. */ - drop: Drop.drop.bind(mod), + drop: extractParam(mod, Drop.drop), /** Creates a `(select)` of one of two values. */ - select: Select.select.bind(mod), + select: extractParam(mod, Select.select), } as const; } @@ -34,13 +40,13 @@ function parametric(mod: Module) { function control(mod: Module) { return { /** Creates a `(block)`. */ - block: Block.block.bind(mod), + block: extractParam(mod, Block.block), /** Creates a loop. */ - loop: Loop.loop.bind(mod), + loop: extractParam(mod, Loop.loop), /** Creates an unconditional branch `(br)` to a label. */ - br: Break.br.bind(mod), + br: extractParam(mod, Break.br), /** Creates a conditional branch `(br_if)` to a label. */ - br_if: Break.br_if.bind(mod), + br_if: extractParam(mod, Break.br_if), } as const; } @@ -53,14 +59,14 @@ function variables(mod: Module) { * Creates a `(local.get)` for the local at the specified index. * Note that we must specify the type here as we may not have created the local being accessed yet. */ - get: LocalGet.localGet.bind(mod), + get: extractParam(mod, LocalGet.localGet), /** Creates a `(local.set)` for the local at the specified index. */ - set: LocalSet.localSet.bind(mod), + set: extractParam(mod, LocalSet.localSet), /** * Creates a `(local.tee)` for the local at the specified index. * Note that we must specify the type here as we may not have created the local being accessed yet. */ - tee: LocalSet.localTee.bind(mod), + tee: extractParam(mod, LocalSet.localTee), }, } as const; } From e861696a65f3b7d91bcc193539e84e399f243775 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 10:39:17 -0400 Subject: [PATCH 069/247] docs: update instrs --- ts/API.md | 24 +++++++++++++------ ts/src/classes/expression/Block.ts | 2 +- ts/src/classes/expression/Loop.ts | 4 ++-- .../classes/expression/expression-creators.ts | 7 ++++-- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/ts/API.md b/ts/API.md index a30e64b6a43..d3e363b013e 100644 --- a/ts/API.md +++ b/ts/API.md @@ -133,17 +133,27 @@ Objects: ## Expression Construction +Each of these methods returns an `ExpressionRef`. + ### Parametric Instructions +- `Module#x.nop()` +- `Module#x.unreachable()` +- `Module#x.drop(value: ExpressionRef)` +- `Module#x.select(ifTrue: ExpressionRef, ifFalse: ExpressionRef)` + ### Control Instructions -- `Module#x.block()` -- `Module#x.if()` +- `Module#x.block(name: string | null, children: readonly ExpressionRef[], resultType?: Type)` +- `Module#x.loop(name: string, body: ExpressionRef)` +- TODO: `Module#x.if()` +- `Module#x.br(label: string, condition?: ExpressionRef, value?: ExpressionRef)` +- `Module#x.br_if(label: string, condition: ExpressionRef, value?: ExpressionRef)` ### Variable Instructions -- `Module#x.local.get()` -- `Module#x.local.set()` -- `Module#x.local.tee()` -- `Module#x.global.get()` -- `Module#x.global.set()` +- `Module#x.local.get(index: number, typ: Type)` +- `Module#x.local.set(index: number, value: ExpressionRef)` +- `Module#x.local.tee(index: number, value: ExpressionRef, typ: Type)` +- TODO: `Module#x.global.get()` +- TODO: `Module#x.global.set()` ### Table Instructions ### Memory Instructions diff --git a/ts/src/classes/expression/Block.ts b/ts/src/classes/expression/Block.ts index 6b69e9a02b6..71a03612db5 100644 --- a/ts/src/classes/expression/Block.ts +++ b/ts/src/classes/expression/Block.ts @@ -26,7 +26,7 @@ import { export class Block extends Expression { - static block(mod: Module, name: string | null | undefined, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef { + static block(mod: Module, name: string | null, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef { return preserveStack(() => BinaryenObj["_BinaryenBlock"]( mod.ptr, name ? strToStack(name) : 0, diff --git a/ts/src/classes/expression/Loop.ts b/ts/src/classes/expression/Loop.ts index a835fe25b56..41348d14ff9 100644 --- a/ts/src/classes/expression/Loop.ts +++ b/ts/src/classes/expression/Loop.ts @@ -21,8 +21,8 @@ import { export class Loop extends Expression { - static loop(mod: Module, label: string, body: ExpressionRef): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenLoop"](mod.ptr, strToStack(label), body)); + static loop(mod: Module, name: string, body: ExpressionRef): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenLoop"](mod.ptr, strToStack(name), body)); } diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-creators.ts index 6ca26c3fd32..f19c1e4f32d 100644 --- a/ts/src/classes/expression/expression-creators.ts +++ b/ts/src/classes/expression/expression-creators.ts @@ -1,6 +1,9 @@ import { BinaryenObj, } from "../../-pre.ts"; +import type { + ExpressionRef, +} from "../../constants.ts"; import type { Module, } from "../module/Module.ts"; @@ -25,9 +28,9 @@ function extractParam(a: First, fn: (a: F function parametric(mod: Module) { return { /** Creates a no-operation `(nop)` instruction. */ - nop: () => BinaryenObj["_BinaryenNop"](mod.ptr), + nop: (): ExpressionRef => BinaryenObj["_BinaryenNop"](mod.ptr), /** Creates an unreachable instruction that will always trap. */ - unreachable: () => BinaryenObj["_BinaryenUnreachable"](mod.ptr), + unreachable: (): ExpressionRef => BinaryenObj["_BinaryenUnreachable"](mod.ptr), /** Creates a `(drop)` of a value. */ drop: extractParam(mod, Drop.drop), /** Creates a `(select)` of one of two values. */ From 8aab97e0131bb9e22cabd38d968889636b4f8b2e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 10:42:25 -0400 Subject: [PATCH 070/247] build: install typedoc --- ts/package-lock.json | 212 +++++++++++++++++++++++++++++++++++++++++-- ts/package.json | 1 + 2 files changed, 207 insertions(+), 6 deletions(-) diff --git a/ts/package-lock.json b/ts/package-lock.json index cf4a8f494e2..ac7b1d5853f 100644 --- a/ts/package-lock.json +++ b/ts/package-lock.json @@ -13,6 +13,7 @@ "@stylistic/eslint-plugin": "^5.10.0", "eslint": "^10.2.1", "globals": "^17.5.0", + "typedoc": "^0.28.19", "typescript": "~6.0.0", "typescript-eslint": "^8.59.1" }, @@ -148,6 +149,20 @@ "node": "^20.19.0 || ^22.13.0 || >=24" } }, + "node_modules/@gerrit0/mini-shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz", + "integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/engine-oniguruma": "^3.23.0", + "@shikijs/langs": "^3.23.0", + "@shikijs/themes": "^3.23.0", + "@shikijs/types": "^3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, "node_modules/@humanfs/core": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", @@ -214,6 +229,55 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, "node_modules/@stylistic/eslint-plugin": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", @@ -249,6 +313,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -256,6 +330,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.59.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.1.tgz", @@ -539,6 +620,13 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/balanced-match": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", @@ -602,6 +690,19 @@ "dev": true, "license": "MIT" }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -616,9 +717,9 @@ } }, "node_modules/eslint": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.2.1.tgz", - "integrity": "sha512-wiyGaKsDgqXvF40P8mDwiUp/KQjE1FdrIEJsM8PZ3XCiniTMXS3OHWWUe5FI5agoCnr8x4xPrTDZuxsBlNHl+Q==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.3.0.tgz", + "integrity": "sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==", "dev": true, "license": "MIT", "dependencies": { @@ -902,9 +1003,9 @@ } }, "node_modules/globals": { - "version": "17.5.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.5.0.tgz", - "integrity": "sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==", + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", "dev": true, "license": "MIT", "engines": { @@ -1009,6 +1110,16 @@ "node": ">= 0.8.0" } }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -1025,6 +1136,38 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, "node_modules/minimatch": { "version": "10.2.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", @@ -1158,6 +1301,16 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", @@ -1237,6 +1390,30 @@ "node": ">= 0.8.0" } }, + "node_modules/typedoc": { + "version": "0.28.19", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.19.tgz", + "integrity": "sha512-wKh+lhdmMFivMlc6vRRcMGXeGEHGU2g8a2CkPTJjJlwRf1iXbimWIPcFolCqe4E0d/FRtGszpIrsp3WLpDB8Pw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@gerrit0/mini-shiki": "^3.23.0", + "lunr": "^2.3.9", + "markdown-it": "^14.1.1", + "minimatch": "^10.2.5", + "yaml": "^2.8.3" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 18", + "pnpm": ">= 10" + }, + "peerDependencies": { + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x" + } + }, "node_modules/typescript": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", @@ -1275,6 +1452,13 @@ "typescript": ">=4.8.4 <6.1.0" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -1311,6 +1495,22 @@ "node": ">=0.10.0" } }, + "node_modules/yaml": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz", + "integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/ts/package.json b/ts/package.json index 5f1c06de865..65e6a135a86 100644 --- a/ts/package.json +++ b/ts/package.json @@ -31,6 +31,7 @@ "@stylistic/eslint-plugin": "^5.10.0", "eslint": "^10.2.1", "globals": "^17.5.0", + "typedoc": "^0.28.19", "typescript": "~6.0.0", "typescript-eslint": "^8.59.1" }, From 860a80ee062ceb566c63023f82a49b039d23e8b1 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 13:45:55 -0400 Subject: [PATCH 071/247] build: generate docs --- ts/.gitignore | 3 +++ ts/eslint.config.js | 4 ++-- ts/package.json | 5 +++-- ts/typedoc.config.js | 7 +++++++ 4 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 ts/typedoc.config.js diff --git a/ts/.gitignore b/ts/.gitignore index ac42bb1260d..57f5fce8900 100644 --- a/ts/.gitignore +++ b/ts/.gitignore @@ -3,3 +3,6 @@ node_modules/ # compiling TypeScript dist/ + +# generating documentation +docs/out/ diff --git a/ts/eslint.config.js b/ts/eslint.config.js index 72fad528144..7bc8336389c 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -6,12 +6,12 @@ import tseslint from "typescript-eslint"; export default [ - {ignores: ["./dist/"]}, + {ignores: ["./dist/", "./docs/out/"]}, eslint.configs.recommended, // https://github.com/eslint/eslint/blob/v10.2.1/packages/js/src/configs/eslint-recommended.js { name: "All", // all JS and TS files - files: ["./eslint.config.js", "./src/**/*.{js,ts}"], + files: ["./{eslint,typedoc}.config.js", "./src/**/*.{js,ts}"], languageOptions: {globals: {...globals.node}}, linterOptions: {reportUnusedDisableDirectives: "error"}, plugins: {"@stylistic": stylistic}, diff --git a/ts/package.json b/ts/package.json index 65e6a135a86..3ee3ad78138 100644 --- a/ts/package.json +++ b/ts/package.json @@ -16,9 +16,10 @@ "type": "module", "main": "./dist/binaryen.js", "scripts": { - "compile": "rm -r ./dist/ && tsc", + "compile": "rm -rf ./dist/ && tsc", "lint": "eslint ./", - "build": "npm run compile && npm run lint" + "docs": "rm -rf ./docs/out/ && typedoc", + "build": "npm run compile && npm run lint && npm run docs" }, "files": [ "package.json", diff --git a/ts/typedoc.config.js b/ts/typedoc.config.js new file mode 100644 index 00000000000..f71f97e562f --- /dev/null +++ b/ts/typedoc.config.js @@ -0,0 +1,7 @@ +export default { + name: "Binaryen.TS", + entryPoints: ["./src/binaryen.ts"], + projectDocuments: ["./API.md"], + useFirstParagraphOfCommentAsSummary: true, + out: "./docs/out/", +}; From 6d1e873f34e36d75c665e9005bcab7d26ef63be8 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 13:45:55 -0400 Subject: [PATCH 072/247] docs: improve doc linking --- ts/src/-deprecations.ts | 108 ++++++++++++------------ ts/src/binaryen.ts | 16 +++- ts/src/classes/TypeBuilder.ts | 2 +- ts/src/classes/expression/Expression.ts | 3 +- ts/src/classes/module/DataSegment.ts | 7 +- ts/src/classes/module/ElementSegment.ts | 7 +- ts/src/classes/module/Export.ts | 7 +- ts/src/classes/module/Function.ts | 7 +- ts/src/classes/module/Global.ts | 7 +- ts/src/classes/module/Import.ts | 7 +- ts/src/classes/module/Memory.ts | 9 +- ts/src/classes/module/Module.ts | 18 ++-- ts/src/classes/module/Table.ts | 7 +- ts/src/classes/module/Tag.ts | 7 +- ts/src/constants.ts | 7 ++ ts/src/services/SettingsService.ts | 2 +- 16 files changed, 132 insertions(+), 89 deletions(-) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index e5434cec11c..68586a37efb 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -29,73 +29,73 @@ import { -/** @deprecated The `ExpressionIds` enum has been renamed to `ExpressionId`. */ +/** @deprecated The `ExpressionIds` enum has been renamed to {@link ExpressionId}. */ export const ExpressionIds = ExpressionId; -/** @deprecated The `SideEffects` enum has been renamed to `SideEffect`. */ +/** @deprecated The `SideEffects` enum has been renamed to {@link SideEffect}. */ export const SideEffects = SideEffect; -/** @deprecated The `ExternalKinds` enum has been renamed to `ExternalKind`. */ +/** @deprecated The `ExternalKinds` enum has been renamed to {@link ExternalKind}. */ export const ExternalKinds = ExternalKind; -/** @deprecated The `Features` enum has been renamed to `Feature`. */ +/** @deprecated The `Features` enum has been renamed to {@link Feature}. */ export const Features = Feature; -/** @deprecated The `Operations` enum has been renamed to `Operation`. */ +/** @deprecated The `Operations` enum has been renamed to {@link Operation}. */ export const Operations = Operation; -/** @deprecated The `TagInfo` object type is now called `Module.Tag`. */ +/** @deprecated The `TagInfo` object type is now called {@link Module.Tag}. */ export type TagInfo = Module.Tag; -/** @deprecated The `GlobalInfo` object type is now called `Module.Global`. */ +/** @deprecated The `GlobalInfo` object type is now called {@link Module.Global}. */ export type GlobalInfo = Module.Global; -/** @deprecated The `MemoryInfo` object type is now called `Module.Memory`*/ +/** @deprecated The `MemoryInfo` object type is now called {@link Module.Memory}*/ export type MemoryInfo = Module.Memory; -/** @deprecated The `TableInfo` object type is now called `Module.Table`. */ +/** @deprecated The `TableInfo` object type is now called {@link Module.Table}. */ export type TableInfo = Module.Table; -/** @deprecated The `FunctionInfo` object type is now called `Module.Function`. */ +/** @deprecated The `FunctionInfo` object type is now called {@link Module.Function}. */ export type FunctionInfo = Module.Function; // type `DataSegmentInfo` never existed -/** @deprecated The `ElementSegmentInfo` object type is now called `Module.ElementSegment`. */ +/** @deprecated The `ElementSegmentInfo` object type is now called {@link Module.ElementSegment}. */ export type ElementSegmentInfo = Module.ElementSegment; // type `ImportInfo` never existed -/** @deprecated The `ExportInfo` object type is now called `Module.Export`. */ +/** @deprecated The `ExportInfo` object type is now called {@link Module.Export}. */ export type ExportInfo = Module.Export; -/** @deprecated The `Function` class now lives under the `Module` namespace. Use `Module.Function`. */ +/** @deprecated The `Function` class now lives under the `Module` namespace. Use {@link Module.Function}. */ export const Function = Module.Function; -/** @deprecated The `Table` class now lives under the `Module` namespace. Use `Module.Table`. */ +/** @deprecated The `Table` class now lives under the `Module` namespace. Use {@link Module.Table}. */ export const Table = Module.Table; -/** @deprecated Use `new Module.Tag(tagref)` instead. */ +/** @deprecated Use {@link Module.Tag | `new Module.Tag(tagref)`} instead. */ export function getTagInfo(tag: TagRef) { consoleWarn("Global function `getTagInfo` is deprecated; use `new Module.Tag(tagref)` instead."); return new Module.Tag(tag); } -/** @deprecated Use `new Module.Global(globalref)` instead. */ +/** @deprecated Use {@link Module.Global | `new Module.Global(globalref)`} instead. */ export function getGlobalInfo(global: GlobalRef) { consoleWarn("Global function `getGlobalInfo` is deprecated; use `new Module.Global(globalref)` instead."); return new Module.Global(global); } // function `getMemoryInfo` always existed in `Module` -/** @deprecated Use `new Module.Table(tableref)` instead. */ +/** @deprecated Use {@link Module.Table | `new Module.Table(tableref)`} instead. */ export function getTableInfo(table: TableRef) { consoleWarn("Global function `getTableInfo` is deprecated; use `new Module.Table(tableref)` instead."); return new Module.Table(table); } -/** @deprecated Use `new Module.Function(funcref)` instead. */ +/** @deprecated Use {@link Module.Function | `new Module.Function(funcref)`} instead. */ export function getFunctionInfo(func: FunctionRef) { consoleWarn("Global function `getFunctionInfo` is deprecated; use `new Module.Function(funcref)` instead."); return new Module.Function(func); } // function `getDataSegmentInfo` always existed in `Module` -/** @deprecated Use `new Module.ElementSegment(segmentref)` instead. */ +/** @deprecated Use {@link Module.ElementSegment | `new Module.ElementSegment(segmentref)`} instead. */ export function getElementSegmentInfo(segment: ElementSegmentRef) { consoleWarn("Global function `getElementSegmentInfo` is deprecated; use `new Module.ElementSegment(segmentref)` instead."); return new Module.ElementSegment(segment); } // no function `getImportInfo` ever existed -/** @deprecated Use `new Module.Export(exportref)` instead. */ +/** @deprecated Use {@link Module.Export | `new Module.Export(exportref)`} instead. */ export function getExportInfo(xport: ExportRef) { consoleWarn("Global function `getExportInfo` is deprecated; use `new Module.Export(exportref)` instead."); return new Module.Export(xport); @@ -103,142 +103,142 @@ export function getExportInfo(xport: ExportRef) { -/** @deprecated Use `settings.optimizeLevel` instead. */ +/** @deprecated Use {@link settings.optimizeLevel} instead. */ export function getOptimizeLevel() { consoleWarn("Global function `getOptimizeLevel` is deprecated; use `settings.optimizeLevel` instead."); return settings.optimizeLevel; } -/** @deprecated Use `settings.optimizeLevel = level` instead. */ +/** @deprecated Use {@link settings.optimizeLevel} instead. */ export function setOptimizeLevel(level: number) { consoleWarn("Global function `setOptimizeLevel` is deprecated; use `settings.optimizeLevel = level` instead."); settings.optimizeLevel = level; } -/** @deprecated Use `settings.shrinkLevel` instead. */ +/** @deprecated Use {@link settings.shrinkLevel} instead. */ export function getShrinkLevel() { consoleWarn("Global function `getShrinkLevel` is deprecated; use `settings.shrinkLevel` instead."); return settings.shrinkLevel; } -/** @deprecated Use `settings.shrinkLevel = level` instead. */ +/** @deprecated Use {@link settings.shrinkLevel} instead. */ export function setShrinkLevel(level: number) { consoleWarn("Global function `setShrinkLevel` is deprecated; use `settings.shrinkLevel = level` instead."); settings.shrinkLevel = level; } -/** @deprecated Use `settings.debugInfo` instead. */ +/** @deprecated Use {@link settings.debugInfo} instead. */ export function getDebugInfo(): boolean { consoleWarn("Global function `getDebugInfo` is deprecated; use `settings.debugInfo` instead."); return settings.debugInfo; } -/** @deprecated Use `settings.debugInfo = enabled` instead. */ +/** @deprecated Use {@link settings.debugInfo} instead. */ export function setDebugInfo(enabled: boolean) { consoleWarn("Global function `setDebugInfo` is deprecated; use `settings.debugInfo = enabled` instead."); settings.debugInfo = enabled; } -/** @deprecated Use `settings.trapsNeverHappen` instead. */ +/** @deprecated Use {@link settings.trapsNeverHappen} instead. */ export function getTrapsNeverHappen(): boolean { consoleWarn("Global function `getTrapsNeverHappen` is deprecated; use `settings.trapsNeverHappen` instead."); return settings.trapsNeverHappen; } -/** @deprecated Use `settings.trapsNeverHappen = enabled` instead. */ +/** @deprecated Use {@link settings.trapsNeverHappen} instead. */ export function setTrapsNeverHappen(enabled: boolean) { consoleWarn("Global function `setTrapsNeverHappen` is deprecated; use `settings.trapsNeverHappen = enabled` instead."); settings.trapsNeverHappen = enabled; } -/** @deprecated Use `settings.closedWorld` instead. */ +/** @deprecated Use {@link settings.closedWorld} instead. */ export function getClosedWorld() { consoleWarn("Global function `getClosedWorld` is deprecated; use `settings.closedWorld` instead."); return settings.closedWorld; } -/** @deprecated Use `settings.closedWorld = enabled` instead. */ +/** @deprecated Use {@link settings.closedWorld} instead. */ export function setClosedWorld(enabled: boolean) { consoleWarn("Global function `setClosedWorld` is deprecated; use `settings.closedWorld = enabled` instead."); settings.closedWorld = enabled; } -/** @deprecated Use `settings.lowMemoryUnused` instead. */ +/** @deprecated Use {@link settings.lowMemoryUnused} instead. */ export function getLowMemoryUnused() { consoleWarn("Global function `getLowMemoryUnused` is deprecated; use `settings.lowMemoryUnused` instead."); return settings.lowMemoryUnused; } -/** @deprecated Use `settings.lowMemoryUnused = enabled` instead. */ +/** @deprecated Use {@link settings.lowMemoryUnused} instead. */ export function setLowMemoryUnused(enabled: boolean) { consoleWarn("Global function `setLowMemoryUnused` is deprecated; use `settings.lowMemoryUnused = enabled` instead."); settings.lowMemoryUnused = enabled; } -/** @deprecated Use `settings.zeroFilledMemory` instead. */ +/** @deprecated Use {@link settings.zeroFilledMemory} instead. */ export function getZeroFilledMemory() { consoleWarn("Global function `getZeroFilledMemory` is deprecated; use `settings.zeroFilledMemory` instead."); return settings.zeroFilledMemory; } -/** @deprecated Use `settings.zeroFilledMemory = enabled` instead. */ +/** @deprecated Use {@link settings.zeroFilledMemory} instead. */ export function setZeroFilledMemory(enabled: boolean) { consoleWarn("Global function `setZeroFilledMemory` is deprecated; use `settings.zeroFilledMemory = enabled` instead."); settings.zeroFilledMemory = enabled; } -/** @deprecated Use `settings.fastMath` instead. */ +/** @deprecated Use {@link settings.fastMath} instead. */ export function getFastMath() { consoleWarn("Global function `getFastMath` is deprecated; use `settings.fastMath` instead."); return settings.fastMath; } -/** @deprecated Use `settings.fastMath = enabled` instead. */ +/** @deprecated Use {@link settings.fastMath} instead. */ export function setFastMath(enabled: boolean) { consoleWarn("Global function `setFastMath` is deprecated; use `settings.fastMath = enabled` instead."); settings.fastMath = enabled; } -/** @deprecated Use `settings.generateStackIR` instead. */ +/** @deprecated Use {@link settings.generateStackIR} instead. */ export function getGenerateStackIR() { consoleWarn("Global function `getGenerateStackIR` is deprecated; use `settings.generateStackIR` instead."); return settings.generateStackIR; } -/** @deprecated Use `settings.generateStackIR = enabled` instead. */ +/** @deprecated Use {@link settings.generateStackIR} instead. */ export function setGenerateStackIR(enabled: boolean) { consoleWarn("Global function `setGenerateStackIR` is deprecated; use `settings.generateStackIR = enabled` instead."); settings.generateStackIR = enabled; } -/** @deprecated Use `settings.optimizeStackIR` instead. */ +/** @deprecated Use {@link settings.optimizeStackIR} instead. */ export function getOptimizeStackIR() { consoleWarn("Global function `getOptimizeStackIR` is deprecated; use `settings.optimizeStackIR` instead."); return settings.optimizeStackIR; } -/** @deprecated Use `settings.optimizeStackIR = enabled` instead. */ +/** @deprecated Use {@link settings.optimizeStackIR} instead. */ export function setOptimizeStackIR(enabled: boolean) { consoleWarn("Global function `setOptimizeStackIR` is deprecated; use `settings.optimizeStackIR = enabled` instead."); settings.optimizeStackIR = enabled; } -/** @deprecated Use `settings.alwaysInlineMaxSize` instead. */ +/** @deprecated Use {@link settings.alwaysInlineMaxSize} instead. */ export function getAlwaysInlineMaxSize() { consoleWarn("Global function `getAlwaysInlineMaxSize` is deprecated; use `settings.alwaysInlineMaxSize` instead."); return settings.alwaysInlineMaxSize; } -/** @deprecated Use `settings.alwaysInlineMaxSize = size` instead. */ +/** @deprecated Use {@link settings.alwaysInlineMaxSize} instead. */ export function setAlwaysInlineMaxSize(size: number) { consoleWarn("Global function `setAlwaysInlineMaxSize` is deprecated; use `settings.alwaysInlineMaxSize = size` instead."); settings.alwaysInlineMaxSize = size; } -/** @deprecated Use `settings.flexibleInlineMaxSize` instead. */ +/** @deprecated Use {@link settings.flexibleInlineMaxSize} instead. */ export function getFlexibleInlineMaxSize() { consoleWarn("Global function `getFlexibleInlineMaxSize` is deprecated; use `settings.flexibleInlineMaxSize` instead."); return settings.flexibleInlineMaxSize; } -/** @deprecated Use `settings.flexibleInlineMaxSize = size` instead. */ +/** @deprecated Use {@link settings.flexibleInlineMaxSize} instead. */ export function setFlexibleInlineMaxSize(size: number) { consoleWarn("Global function `setFlexibleInlineMaxSize` is deprecated; use `settings.flexibleInlineMaxSize = size` instead."); settings.flexibleInlineMaxSize = size; } -/** @deprecated Use `settings.oneCallerInlineMaxSize` instead. */ +/** @deprecated Use {@link settings.oneCallerInlineMaxSize} instead. */ export function getOneCallerInlineMaxSize() { consoleWarn("Global function `getOneCallerInlineMaxSize` is deprecated; use `settings.oneCallerInlineMaxSize` instead."); return settings.oneCallerInlineMaxSize; } -/** @deprecated Use `settings.oneCallerInlineMaxSize = size` instead. */ +/** @deprecated Use {@link settings.oneCallerInlineMaxSize} instead. */ export function setOneCallerInlineMaxSize(size: number) { consoleWarn("Global function `setOneCallerInlineMaxSize` is deprecated; use `settings.oneCallerInlineMaxSize = size` instead."); settings.oneCallerInlineMaxSize = size; } -/** @deprecated Use `settings.allowInliningFunctionsWithLoops` instead. */ +/** @deprecated Use {@link settings.allowInliningFunctionsWithLoops} instead. */ export function getAllowInliningFunctionsWithLoops() { consoleWarn("Global function `getAllowInliningFunctionsWithLoops` is deprecated; use `settings.allowInliningFunctionsWithLoops` instead."); return settings.allowInliningFunctionsWithLoops; } -/** @deprecated Use `settings.allowInliningFunctionsWithLoops = enabled` instead. */ +/** @deprecated Use {@link settings.allowInliningFunctionsWithLoops} instead. */ export function setAllowInliningFunctionsWithLoops(enabled: boolean) { consoleWarn("Global function `setAllowInliningFunctionsWithLoops` is deprecated; use `settings.allowInliningFunctionsWithLoops = enabled` instead."); settings.allowInliningFunctionsWithLoops = enabled; @@ -246,32 +246,32 @@ export function setAllowInliningFunctionsWithLoops(enabled: boolean) { -/** @deprecated Use `settings.getPassArgument(key)` instead. */ +/** @deprecated Use {@link settings.getPassArgument} instead. */ export function getPassArgument(key: string) { consoleWarn("Global function `getPassArgument` is deprecated; use `settings.getPassArgument(key)` instead."); return settings.getPassArgument(key); } -/** @deprecated Use `settings.setPassArgument(key, value)` instead. */ +/** @deprecated Use {@link settings.setPassArgument} instead. */ export function setPassArgument(key: string, value?: string) { consoleWarn("Global function `setPassArgument` is deprecated; use `settings.setPassArgument(key, value)` instead."); return settings.setPassArgument(key, value); } -/** @deprecated Use `settings.clearPassArguments()` instead. */ +/** @deprecated Use {@link settings.clearPassArguments} instead. */ export function clearPassArguments() { consoleWarn("Global function `clearPassArguments` is deprecated; use `settings.clearPassArguments()` instead."); return settings.clearPassArguments(); } -/** @deprecated Use `settings.hasPassToSkip(pass)` instead. */ +/** @deprecated Use {@link settings.hasPassToSkip} instead. */ export function hasPassToSkip(pass: string) { consoleWarn("Global function `hasPassToSkip` is deprecated; use `settings.hasPassToSkip(pass)` instead."); return settings.hasPassToSkip(pass); } -/** @deprecated Use `settings.addPassToSkip(pass)` instead. */ +/** @deprecated Use {@link settings.addPassToSkip} instead. */ export function addPassToSkip(pass: string) { consoleWarn("Global function `addPassToSkip` is deprecated; use `settings.addPassToSkip(pass)` instead."); return settings.addPassToSkip(pass); } -/** @deprecated Use `settings.clearPassesToSkip()` instead. */ +/** @deprecated Use {@link settings.clearPassesToSkip} instead. */ export function clearPassesToSkip() { consoleWarn("Global function `clearPassesToSkip` is deprecated; use `settings.clearPassesToSkip()` instead."); return settings.clearPassesToSkip(); diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 02e40fc3ddf..8bb988ff89b 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1,15 +1,25 @@ +/** @module binaryen.ts */ export * from "./constants.ts"; export * from "./globals.ts"; export { Feature, Module, } from "./classes/module/Module.ts"; -export {TypeBuilder} from "./classes/TypeBuilder.ts"; +export type {Tag, ModuleTags} from "./classes/module/Tag.ts"; +export type {Global, ModuleGlobals} from "./classes/module/Global.ts"; +export type {Memory, ModuleMemories, MemorySegment} from "./classes/module/Memory.ts"; +export type {Table, ModuleTables} from "./classes/module/Table.ts"; +export type {Function as BinaryenFunction, ModuleFunctions} from "./classes/module/Function.ts"; +export type {DataSegment, ModuleDataSegments} from "./classes/module/DataSegment.ts"; +export type {ElementSegment, ModuleElementSegments} from "./classes/module/ElementSegment.ts"; +export type {Import, ModuleImports} from "./classes/module/Import.ts"; +export type {Export, ModuleExports} from "./classes/module/Export.ts"; +export * from "./classes/expression/index.ts"; +export {TypeBuilder, type Field} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, ExpressionRunnerFlag, } from "./classes/ExpressionRunner.ts"; export {Relooper} from "./classes/Relooper.ts"; -export {settings} from "./services/SettingsService.ts"; -export * from "./classes/expression/index.ts"; +export {type SettingsService, settings} from "./services/SettingsService.ts"; export * from "./-deprecations.ts"; diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index e74ea9887fa..e051cbb4619 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -16,7 +16,7 @@ import { -type Field = { +export type Field = { /** The type of the struct field. */ type: Type, /** The field’s packed type. */ diff --git a/ts/src/classes/expression/Expression.ts b/ts/src/classes/expression/Expression.ts index 2d71660a715..d41353fa9eb 100644 --- a/ts/src/classes/expression/Expression.ts +++ b/ts/src/classes/expression/Expression.ts @@ -16,7 +16,6 @@ import { -/** Base class of all expression wrappers. */ export class Expression { protected readonly [THIS_PTR]: ExpressionRef; @@ -26,7 +25,7 @@ export class Expression { /** * Construct a new Expression object given an ID and reference. * - * Without an ID, you can still call `binaryen.getExpressionInfo(expr)`, + * Without an ID, you can still call {@link getExpressionInfo | `getExpressionInfo(expr)`}, * which will compute the ID and construct an Expression object from there. * @param exprId the expression “kind” id * @param expr the expression reference diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index 71240e72101..c40c0238939 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -18,7 +18,10 @@ import type { -/** Information about a data segment in a WASM module. */ +/** + * Information about a data segment in a WASM module. + * @see {@link ModuleDataSegments} + */ export class DataSegment { readonly name: string; readonly offset?: number; @@ -46,7 +49,7 @@ export class DataSegment { -/** Methods for manipulating data segments in a WASM module. */ +/** Methods for manipulating {@link DataSegment | data segments} in a WASM module. */ export class ModuleDataSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index aac32bb3783..f6a606e16dd 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -17,7 +17,10 @@ import type { -/** Information about an element segment in a WASM module. */ +/** + * Information about an element segment in a WASM module. + * @see {@link ModuleElementSegments} + */ export class ElementSegment { readonly name: string; readonly table: string; @@ -42,7 +45,7 @@ export class ElementSegment { -/** Methods for manipulating element segments in a WASM module. */ +/** Methods for manipulating {@link ElementSegment | element segments} in a WASM module. */ export class ModuleElementSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index e3e46be1443..e7050260248 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -16,7 +16,10 @@ import type { -/** Information about an export in a WASM module. */ +/** + * Information about an export in a WASM module. + * @see {@link ModuleExports} + */ export class Export { readonly kind: ExternalKind; readonly name: string; @@ -32,7 +35,7 @@ export class Export { -/** Methods for manipulating exports in a WASM module. */ +/** Methods for manipulating {@link Export | exports} in a WASM module. */ export class ModuleExports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index a807326a1d1..d55a17e2e64 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -20,7 +20,10 @@ import type { -/** Information about a function in a WASM module. */ +/** + * Information about a function in a WASM module. + * @see {@link ModuleFunctions} + */ class BinaryenFunction { private readonly [THIS_PTR]: FunctionRef; @@ -96,7 +99,7 @@ export {BinaryenFunction as Function}; -/** Methods for manipulating functions in a WASM module. */ +/** Methods for manipulating {@link BinaryenFunction | functions} in a WASM module. */ export class ModuleFunctions { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Global.ts b/ts/src/classes/module/Global.ts index 0527c019b63..6bcb25237d8 100644 --- a/ts/src/classes/module/Global.ts +++ b/ts/src/classes/module/Global.ts @@ -17,7 +17,10 @@ import type { -/** Information about a global in a WASM module. */ +/** + * Information about a global in a WASM module. + * @see {@link ModuleGlobals} + */ export class Global { readonly name: string; readonly module: string; @@ -39,7 +42,7 @@ export class Global { -/** Methods for manipulating globals in a WASM module. */ +/** Methods for manipulating {@link Global | globals} in a WASM module. */ export class ModuleGlobals { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index 98a9104cb45..f7b10394db4 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -14,14 +14,17 @@ import type { -/** Information about an import in a WASM module. */ +/** + * Information about an import in a WASM module. + * @see {@link ModuleImports} + */ export class Import { constructor() {} } -/** Methods for manipulating imports in a WASM module. */ +/** Methods for manipulating {@link Import | imports} in a WASM module. */ export class ModuleImports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index 7cfe57300c5..30b872a463a 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -20,7 +20,7 @@ import type { /** Similar to a `DataSegment` but with some minor differences. */ -interface MemorySegment { +export interface MemorySegment { name?: string; offset: ExpressionRef; data: Uint8Array; @@ -29,7 +29,10 @@ interface MemorySegment { -/** Information about a memory in a WASM module. */ +/** + * Information about a memory in a WASM module. + * @see {@link ModuleMemories} + */ export class Memory { readonly module: string; readonly base: string; @@ -53,7 +56,7 @@ export class Memory { -/** Methods for manipulating memories in a WASM module. */ +/** Methods for manipulating {@link Memory | memories} in a WASM module. */ export class ModuleMemories { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 1bf7526ddce..1f7728e7acc 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -110,15 +110,15 @@ export enum Feature { * Each instance of `Module` is: * - a WASM module with module manipulation methods (`.emitText()`, `.validate()`, etc.). * - an individual namespace containing mixins, each with its own component manipulation methods (`.tags.add()`, `.globals.get()`, etc): - * - {@link TAG.ModuleTags|tags} - * - {@link GLOBAL.ModuleGlobals|globals} - * - {@link MEMORY.ModuleMemories|memories} - * - {@link TABLE.ModuleTables|tables} - * - {@link FUNCTION.ModuleFunctions|functions} - * - {@link DATA_SEGMENT.ModuleDataSegments|dataSegments} - * - {@link ELEMENT_SEGMENT.ModuleElementSegments|elementSegments} - * - {@link IMPORT.ModuleImports|imports} - * - {@link EXPORT.ModuleExports|exports} + * - {@link TAG.ModuleTags | tags} + * - {@link GLOBAL.ModuleGlobals | globals} + * - {@link MEMORY.ModuleMemories | memories} + * - {@link TABLE.ModuleTables | tables} + * - {@link FUNCTION.ModuleFunctions | functions} + * - {@link DATA_SEGMENT.ModuleDataSegments | dataSegments} + * - {@link ELEMENT_SEGMENT.ModuleElementSegments | elementSegments} + * - {@link IMPORT.ModuleImports | imports} + * - {@link EXPORT.ModuleExports | exports} */ export class Module { readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index e71288a8c01..c72da5256aa 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -20,7 +20,10 @@ import type { -/** Information about a table in a WASM module. */ +/** + * Information about a table in a WASM module. + * @see {@link ModuleTables} + */ export class Table { private readonly [THIS_PTR]: TableRef; @@ -65,7 +68,7 @@ export class Table { -/** Methods for manipulating tables in a WASM module. */ +/** Methods for manipulating {@link Table | tables} in a WASM module. */ export class ModuleTables { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Tag.ts b/ts/src/classes/module/Tag.ts index 2944246699e..0754606fe7a 100644 --- a/ts/src/classes/module/Tag.ts +++ b/ts/src/classes/module/Tag.ts @@ -16,7 +16,10 @@ import type { -/** Information about a tag in a WASM module. */ +/** + * Information about a tag in a WASM module. + * @see {@link ModuleTags} + */ export class Tag { readonly name: string; readonly module: string; @@ -36,7 +39,7 @@ export class Tag { -/** Methods for manipulating tags in a WASM module. */ +/** Methods for manipulating {@link Tag | tags} in a WASM module. */ export class ModuleTags { constructor(private readonly mod: Module) {} diff --git a/ts/src/constants.ts b/ts/src/constants.ts index cd2323192a8..e2c4fa8a6dd 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -17,14 +17,21 @@ export type PackedType = number; export type ExpressionRef = number; // ### Module Components ### // +/** Reference to a {@link Tag}. */ export type TagRef = number; +/** Reference to a {@link Global}. */ export type GlobalRef = number; // no `MemoryRef` +/** Reference to a {@link Table}. */ export type TableRef = number; +/** Reference to a {@link BinaryenFunction}. */ export type FunctionRef = number; +/** Reference to a {@link DataSegment}. */ export type DataSegmentRef = number; +/** Reference to an {@link ElementSegment}. */ export type ElementSegmentRef = number; // no `ImportRef` +/** Reference to an {@link Export}. */ export type ExportRef = number; // ### Binaryen Tools ### // diff --git a/ts/src/services/SettingsService.ts b/ts/src/services/SettingsService.ts index 3484bb3fc80..990decbd87f 100644 --- a/ts/src/services/SettingsService.ts +++ b/ts/src/services/SettingsService.ts @@ -9,7 +9,7 @@ import { -class SettingsService { +export class SettingsService { /** The currently set optimize level. 0, 1, 2 correspond to -O0, -O1, -O2, etc. */ get optimizeLevel(): number { return BinaryenObj["_BinaryenGetOptimizeLevel"](); } set optimizeLevel(level: number) { BinaryenObj["_BinaryenSetOptimizeLevel"](level); } From 74cfdf9fbd5956ec412a1220fd3de21800570d5a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 14:45:11 -0400 Subject: [PATCH 073/247] refactor: cleanup unused types --- ts/API.md | 1 - ts/src/-deprecations.ts | 5 ----- ts/src/classes/ExpressionRunner.ts | 3 +-- ts/src/classes/Relooper.ts | 5 ++++- ts/src/classes/TypeBuilder.ts | 1 + ts/src/constants.ts | 5 ----- 6 files changed, 6 insertions(+), 14 deletions(-) diff --git a/ts/API.md b/ts/API.md index d3e363b013e..02888bc4493 100644 --- a/ts/API.md +++ b/ts/API.md @@ -173,7 +173,6 @@ Enum names have been singularized. - `SideEffects` → `SideEffect` - `ExternalKinds` → `ExternalKind` - `Features` → `Feature` -- `Operations` → `Operation` `*Info` types have been merged with their respective classes in the `Module` namespace. - `TagInfo` → `Module.Tag` diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 68586a37efb..5ecb2fe6323 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -13,9 +13,6 @@ import { type TableRef, type TagRef, } from "./constants.ts"; -import { - Operation, -} from "./classes/expression/Operation.ts"; import { Feature, Module, @@ -37,8 +34,6 @@ export const SideEffects = SideEffect; export const ExternalKinds = ExternalKind; /** @deprecated The `Features` enum has been renamed to {@link Feature}. */ export const Features = Feature; -/** @deprecated The `Operations` enum has been renamed to {@link Operation}. */ -export const Operations = Operation; diff --git a/ts/src/classes/ExpressionRunner.ts b/ts/src/classes/ExpressionRunner.ts index 371c4ebf8fe..a1c605fb64a 100644 --- a/ts/src/classes/ExpressionRunner.ts +++ b/ts/src/classes/ExpressionRunner.ts @@ -3,7 +3,6 @@ import { } from "../-pre.ts"; import type { ExpressionRef, - ExpressionRunnerRef, } from "../constants.ts"; import { preserveStack, @@ -27,7 +26,7 @@ export class ExpressionRunner { static Flags = ExpressionRunnerFlag; - readonly #ptr: ExpressionRunnerRef; + readonly #ptr: number; constructor(mod: Module, flags: ExpressionRunnerFlag, maxDepth: number, maxLoopIterations: number) { this.#ptr = BinaryenObj["_ExpressionRunnerCreate"](mod.ptr, flags, maxDepth, maxLoopIterations); diff --git a/ts/src/classes/Relooper.ts b/ts/src/classes/Relooper.ts index 48d1caeb6f9..4a3d72ce458 100644 --- a/ts/src/classes/Relooper.ts +++ b/ts/src/classes/Relooper.ts @@ -3,7 +3,6 @@ import { } from "../-pre.ts"; import type { ExpressionRef, - RelooperBlockRef, } from "../constants.ts"; import { i32sToStack, @@ -15,6 +14,10 @@ import type { +export type RelooperBlockRef = number; + + + export class Relooper { readonly #ptr: number; diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index e051cbb4619..cd85834abe8 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -16,6 +16,7 @@ import { +/** A field in a struct/array. */ export type Field = { /** The type of the struct field. */ type: Type, diff --git a/ts/src/constants.ts b/ts/src/constants.ts index e2c4fa8a6dd..1b7433ad142 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -34,11 +34,6 @@ export type ElementSegmentRef = number; /** Reference to an {@link Export}. */ export type ExportRef = number; -// ### Binaryen Tools ### // -export type TypeBuilderRef = number; -export type ExpressionRunnerRef = number; -export type RelooperBlockRef = number; - // ## Expression Types ## // From f99d9f00b66db704c25f5b31fdc5702569aeaa04 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 16:05:23 -0400 Subject: [PATCH 074/247] refactor: aggregate Expression classes --- ts/API.md | 31 +++++++++++++++++++++++++----- ts/src/-deprecations.ts | 28 +++++++++++++++++++++++---- ts/src/binaryen.ts | 2 +- ts/src/classes/expression/index.ts | 11 +++++++++++ ts/src/classes/module/Module.ts | 6 ++++++ 5 files changed, 68 insertions(+), 10 deletions(-) diff --git a/ts/API.md b/ts/API.md index 02888bc4493..d5282e1bdf4 100644 --- a/ts/API.md +++ b/ts/API.md @@ -166,6 +166,27 @@ Each of these methods returns an `ExpressionRef`. +## Expression Manipulation +Expression info classes all live under the global `X` namespace. (“X” for “Expression”). +They can be used to inspect and manipulate expressions. +See generated docs for fields, methods, and descriptions of each. + +- `X.Expression` (root class) +- parametric instructions + - `X.Drop` + - `X.Select` +- control instructions + - `X.Block` + - `X.Loop` + - `X.Break` +- variable instructions + - `X.LocalGet` + - `X.LocalSet` +- numeric instructions + - `X.Const` + + + ## ⚠️ Deprecations, Renames, and Moves ### Enums and Types Enum names have been singularized. @@ -183,11 +204,11 @@ Enum names have been singularized. - `ElementSegmentInfo` → `Module.ElementSegment` - `ExportInfo` → `Module.Export` -`ExpressionInfo` and related types are now classes without the `Info` suffix: -- `ExpressionInfo` → `Expression` -- `BlockInfo` → `Block` -- `LoopInfo` → `Loop` -- `IfInfo` → `If` +`ExpressionInfo` and related types are now classes in the `X` namespace: +- `ExpressionInfo` → `X.Expression` +- `BlockInfo` → `X.Block` +- `LoopInfo` → `X.Loop` +- `IfInfo` → `X.If` - etc. ~~`MemorySegmentInfo`~~ ❌ has been removed. diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 5ecb2fe6323..9e0df94386c 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -2,6 +2,11 @@ +import type * as X from "./classes/expression/index.ts"; +import { + Feature, + Module, +} from "./classes/module/Module.ts"; import { type ElementSegmentRef, type ExportRef, @@ -13,10 +18,6 @@ import { type TableRef, type TagRef, } from "./constants.ts"; -import { - Feature, - Module, -} from "./classes/module/Module.ts"; import { consoleWarn, } from "./lib.ts"; @@ -55,6 +56,25 @@ export type ElementSegmentInfo = Module.ElementSegment; export type ExportInfo = Module.Export; +/** @deprecated The `ExpressionInfo` object type is now called {@link X.Expression}. */ +export type ExpressionInfo = X.Expression; +/** @deprecated The `DropInfo` object type is now called {@link X.Drop}. */ +export type DropInfo = X.Drop; +/** @deprecated The `SelectInfo` object type is now called {@link X.Select}. */ +export type SelectInfo = X.Select; +/** @deprecated The `BlockInfo` object type is now called {@link X.Block}. */ +export type BlockInfo = X.Block; +/** @deprecated The `LoopInfo` object type is now called {@link X.Loop}. */ +export type LoopInfo = X.Loop; +/** @deprecated The `BreakInfo` object type is now called {@link X.Break}. */ +export type BreakInfo = X.Break; +/** @deprecated The `LocalGetInfo` object type is now called {@link X.LocalGet}. */ +export type LocalGetInfo = X.LocalGet; +/** @deprecated The `LocalSetInfo` object type is now called {@link X.LocalSet}. */ +export type LocalSetInfo = X.LocalSet; +/** @deprecated The `ConstInfo` object type is now called {@link X.Const}. */ +export type ConstInfo = X.Const; + /** @deprecated The `Function` class now lives under the `Module` namespace. Use {@link Module.Function}. */ export const Function = Module.Function; /** @deprecated The `Table` class now lives under the `Module` namespace. Use {@link Module.Table}. */ diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 8bb988ff89b..31de15f52e7 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -14,7 +14,7 @@ export type {DataSegment, ModuleDataSegments} from "./classes/module/DataSegment export type {ElementSegment, ModuleElementSegments} from "./classes/module/ElementSegment.ts"; export type {Import, ModuleImports} from "./classes/module/Import.ts"; export type {Export, ModuleExports} from "./classes/module/Export.ts"; -export * from "./classes/expression/index.ts"; +export * as X from "./classes/expression/index.ts"; export {TypeBuilder, type Field} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index ac41477da37..54b0515769c 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -1,3 +1,14 @@ +/** + * A collection of classes related to WASM expression manipulation. + * + * The {@link Expression} class is the root class in the hierarchy; + * all other classes in this module extend it and describe specific kinds of expressions. + * Each expression type corresponds to an {@link ExpressionId}. + * @module + */ + + + export {Expression} from "./Expression.ts"; // ## Parametric ## // diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 1f7728e7acc..ae713a73af8 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -383,6 +383,12 @@ export class Module { +/** + * A collection of types and classes related to WASM module manipulation. + * + * Each class represents a component of a WASM module, + * and its corresponding type is included for documentation. + */ // eslint-disable-next-line no-redeclare export namespace Module { export type Tag = TAG.Tag; From 518d2956a45744a445ecfcdc2fb7fa0b46dfe9e8 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 22:21:58 -0400 Subject: [PATCH 075/247] renamed: API.md -> docs/API-Overview.md --- ts/{API.md => docs/API-Overview.md} | 2 +- ts/typedoc.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename ts/{API.md => docs/API-Overview.md} (99%) diff --git a/ts/API.md b/ts/docs/API-Overview.md similarity index 99% rename from ts/API.md rename to ts/docs/API-Overview.md index d5282e1bdf4..cef35b12c7d 100644 --- a/ts/API.md +++ b/ts/docs/API-Overview.md @@ -1,4 +1,4 @@ -# API Documentation +# API Overview Please note that the Binaryen API is evolving fast. Definitions and documentation provided by the C++ codebase don’t always immediately find their way here into TypeScript. If you rely on Binaryen.TS and spot an issue, please consider sending a PR our way. Thank you! diff --git a/ts/typedoc.config.js b/ts/typedoc.config.js index f71f97e562f..356b3de9433 100644 --- a/ts/typedoc.config.js +++ b/ts/typedoc.config.js @@ -1,7 +1,7 @@ export default { name: "Binaryen.TS", entryPoints: ["./src/binaryen.ts"], - projectDocuments: ["./API.md"], + projectDocuments: ["./docs/API-Overview.md"], useFirstParagraphOfCommentAsSummary: true, out: "./docs/out/", }; From ed3027536645ba24448c60f159bbb073052238a8 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 21:40:30 -0400 Subject: [PATCH 076/247] refactor: replace `extractParam` with `Function#bind` --- .../classes/expression/expression-creators.ts | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-creators.ts index f19c1e4f32d..a1e4529a285 100644 --- a/ts/src/classes/expression/expression-creators.ts +++ b/ts/src/classes/expression/expression-creators.ts @@ -19,12 +19,6 @@ import { -function extractParam(a: First, fn: (a: First, ...rest: Rest) => Return): (...rest: Rest) => Return { - return (...args) => fn(a, ...args); -} - - - function parametric(mod: Module) { return { /** Creates a no-operation `(nop)` instruction. */ @@ -32,9 +26,9 @@ function parametric(mod: Module) { /** Creates an unreachable instruction that will always trap. */ unreachable: (): ExpressionRef => BinaryenObj["_BinaryenUnreachable"](mod.ptr), /** Creates a `(drop)` of a value. */ - drop: extractParam(mod, Drop.drop), + drop: Drop.drop.bind(null, mod), /** Creates a `(select)` of one of two values. */ - select: extractParam(mod, Select.select), + select: Select.select.bind(null, mod), } as const; } @@ -43,33 +37,33 @@ function parametric(mod: Module) { function control(mod: Module) { return { /** Creates a `(block)`. */ - block: extractParam(mod, Block.block), + block: Block.block.bind(null, mod), /** Creates a loop. */ - loop: extractParam(mod, Loop.loop), + loop: Loop.loop.bind(null, mod), /** Creates an unconditional branch `(br)` to a label. */ - br: extractParam(mod, Break.br), + br: Break.br.bind(null, mod), /** Creates a conditional branch `(br_if)` to a label. */ - br_if: extractParam(mod, Break.br_if), + br_if: Break.br_if.bind(null, mod), } as const; } -function variables(mod: Module) { +function variable(mod: Module) { return { local: { /** * Creates a `(local.get)` for the local at the specified index. * Note that we must specify the type here as we may not have created the local being accessed yet. */ - get: extractParam(mod, LocalGet.localGet), + get: LocalGet.localGet.bind(null, mod), /** Creates a `(local.set)` for the local at the specified index. */ - set: extractParam(mod, LocalSet.localSet), + set: LocalSet.localSet.bind(null, mod), /** * Creates a `(local.tee)` for the local at the specified index. * Note that we must specify the type here as we may not have created the local being accessed yet. */ - tee: extractParam(mod, LocalSet.localTee), + tee: LocalSet.localTee.bind(null, mod), }, } as const; } @@ -81,6 +75,6 @@ export function expressionCreator(mod: Module) { return { ...parametric(mod), ...control(mod), - ...variables(mod), + ...variable(mod), } as const; } From 87ac5868f0ea9d3637bdd250792567896c7c2700 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 22:30:20 -0400 Subject: [PATCH 077/247] docs: move doccomments to original functions and inherit them --- ts/docs/API-Overview.md | 4 ++-- ts/src/classes/expression/Block.ts | 1 + ts/src/classes/expression/Break.ts | 2 ++ ts/src/classes/expression/Drop.ts | 1 + ts/src/classes/expression/LocalGet.ts | 4 ++++ ts/src/classes/expression/LocalSet.ts | 5 ++++ ts/src/classes/expression/Loop.ts | 1 + ts/src/classes/expression/Select.ts | 1 + .../classes/expression/expression-creators.ts | 24 +++++++------------ ts/src/classes/module/Module.ts | 20 ++++++++++++---- 10 files changed, 41 insertions(+), 22 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index cef35b12c7d..d059943663b 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -119,7 +119,7 @@ Objects: - `new Module.Export(ref: ExportRef)`: an object containing information about an **Export** - Properties of `Module` instances (see full list of methods in generated docs): - - `Module#x`: [create expressions](#expression-construction) + - `Module#x`: [create expressions](#expression-construction) (“x” for “expression”) - `Module#tags`: **Tag** manipulation - `Module#globals`: **Global** manipulation - `Module#memories`: **Memory** manipulation @@ -167,7 +167,7 @@ Each of these methods returns an `ExpressionRef`. ## Expression Manipulation -Expression info classes all live under the global `X` namespace. (“X” for “Expression”). +Expression info classes all live under the global `X` namespace (“X” for “Expression”). They can be used to inspect and manipulate expressions. See generated docs for fields, methods, and descriptions of each. diff --git a/ts/src/classes/expression/Block.ts b/ts/src/classes/expression/Block.ts index 71a03612db5..78c8e861250 100644 --- a/ts/src/classes/expression/Block.ts +++ b/ts/src/classes/expression/Block.ts @@ -26,6 +26,7 @@ import { export class Block extends Expression { + /** Creates a `(block)`. */ static block(mod: Module, name: string | null, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef { return preserveStack(() => BinaryenObj["_BinaryenBlock"]( mod.ptr, diff --git a/ts/src/classes/expression/Break.ts b/ts/src/classes/expression/Break.ts index 92d5739e209..46662b74b2c 100644 --- a/ts/src/classes/expression/Break.ts +++ b/ts/src/classes/expression/Break.ts @@ -21,10 +21,12 @@ import { export class Break extends Expression { + /** Creates an unconditional branch `(br)` to a label. */ static br(mod: Module, label: string, condition?: ExpressionRef, value?: ExpressionRef): ExpressionRef { return preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition!, value!)); } + /** Creates a conditional branch `(br_if)` to a label. */ static br_if(mod: Module, label: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef { return preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition, value!)); } diff --git a/ts/src/classes/expression/Drop.ts b/ts/src/classes/expression/Drop.ts index fe7185771cf..8085a314b76 100644 --- a/ts/src/classes/expression/Drop.ts +++ b/ts/src/classes/expression/Drop.ts @@ -18,6 +18,7 @@ import { export class Drop extends Expression { + /** Creates a `(drop)` of a value. */ static drop(mod: Module, value: ExpressionRef): ExpressionRef { return BinaryenObj["_BinaryenDrop"](mod.ptr, value); } diff --git a/ts/src/classes/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts index 5a09238abbd..5420e92abf9 100644 --- a/ts/src/classes/expression/LocalGet.ts +++ b/ts/src/classes/expression/LocalGet.ts @@ -19,6 +19,10 @@ import { export class LocalGet extends Expression { + /** + * Creates a `(local.get)` for the local at the specified index. + * Note that we must specify the type here as we may not have created the local being accessed yet. + */ static localGet(mod: Module, index: number, typ: Type): ExpressionRef { return BinaryenObj["_BinaryenLocalGet"](mod.ptr, index, typ); } diff --git a/ts/src/classes/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts index 0ba257807b4..aa8ea908f83 100644 --- a/ts/src/classes/expression/LocalSet.ts +++ b/ts/src/classes/expression/LocalSet.ts @@ -19,10 +19,15 @@ import { export class LocalSet extends Expression { + /** Creates a `(local.set)` for the local at the specified index. */ static localSet(mod: Module, index: number, value: ExpressionRef): ExpressionRef { return BinaryenObj["_BinaryenLocalSet"](mod.ptr, index, value); } + /** + * Creates a `(local.tee)` for the local at the specified index. + * Note that we must specify the type here as we may not have created the local being accessed yet. + */ static localTee(mod: Module, index: number, value: ExpressionRef, typ: Type): ExpressionRef { return BinaryenObj["_BinaryenLocalTee"](mod.ptr, index, value, typ); } diff --git a/ts/src/classes/expression/Loop.ts b/ts/src/classes/expression/Loop.ts index 41348d14ff9..2784ec4c0a5 100644 --- a/ts/src/classes/expression/Loop.ts +++ b/ts/src/classes/expression/Loop.ts @@ -21,6 +21,7 @@ import { export class Loop extends Expression { + /** Creates a `(loop)`. */ static loop(mod: Module, name: string, body: ExpressionRef): ExpressionRef { return preserveStack(() => BinaryenObj["_BinaryenLoop"](mod.ptr, strToStack(name), body)); } diff --git a/ts/src/classes/expression/Select.ts b/ts/src/classes/expression/Select.ts index 0cb55965f89..8e6e532ecb8 100644 --- a/ts/src/classes/expression/Select.ts +++ b/ts/src/classes/expression/Select.ts @@ -18,6 +18,7 @@ import { export class Select extends Expression { + /** Creates a `(select)` of one of two values. */ static select(mod: Module, ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef { return BinaryenObj["_BinaryenSelect"](mod.ptr, ifTrue, ifFalse); } diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-creators.ts index a1e4529a285..9410e16b414 100644 --- a/ts/src/classes/expression/expression-creators.ts +++ b/ts/src/classes/expression/expression-creators.ts @@ -25,9 +25,9 @@ function parametric(mod: Module) { nop: (): ExpressionRef => BinaryenObj["_BinaryenNop"](mod.ptr), /** Creates an unreachable instruction that will always trap. */ unreachable: (): ExpressionRef => BinaryenObj["_BinaryenUnreachable"](mod.ptr), - /** Creates a `(drop)` of a value. */ + /** @inheritDoc X.Drop.drop */ drop: Drop.drop.bind(null, mod), - /** Creates a `(select)` of one of two values. */ + /** @inheritDoc X.Select.select */ select: Select.select.bind(null, mod), } as const; } @@ -36,13 +36,13 @@ function parametric(mod: Module) { function control(mod: Module) { return { - /** Creates a `(block)`. */ + /** @inheritdoc X.Block.block */ block: Block.block.bind(null, mod), - /** Creates a loop. */ + /** @inheritdoc X.Loop.loop */ loop: Loop.loop.bind(null, mod), - /** Creates an unconditional branch `(br)` to a label. */ + /** @inheritdoc X.Break.br */ br: Break.br.bind(null, mod), - /** Creates a conditional branch `(br_if)` to a label. */ + /** @inheritdoc X.Break.br_if */ br_if: Break.br_if.bind(null, mod), } as const; } @@ -52,17 +52,11 @@ function control(mod: Module) { function variable(mod: Module) { return { local: { - /** - * Creates a `(local.get)` for the local at the specified index. - * Note that we must specify the type here as we may not have created the local being accessed yet. - */ + /** @inheritDoc X.LocalGet.localGet */ get: LocalGet.localGet.bind(null, mod), - /** Creates a `(local.set)` for the local at the specified index. */ + /** @inheritDoc X.LocalSet.localSet */ set: LocalSet.localSet.bind(null, mod), - /** - * Creates a `(local.tee)` for the local at the specified index. - * Note that we must specify the type here as we may not have created the local being accessed yet. - */ + /** @inheritDoc X.LocalSet.localTee */ tee: LocalSet.localTee.bind(null, mod), }, } as const; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index ae713a73af8..9cc327afe98 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -107,9 +107,9 @@ export enum Feature { * - {@link Import} * - {@link Export} * - * Each instance of `Module` is: - * - a WASM module with module manipulation methods (`.emitText()`, `.validate()`, etc.). - * - an individual namespace containing mixins, each with its own component manipulation methods (`.tags.add()`, `.globals.get()`, etc): + * Each instance of `Module`: + * - is a WASM module with module manipulation methods (`.emitText()`, `.validate()`, etc.). + * - is an individual namespace containing mixins, each with its own component manipulation methods (`.tags.add()`, `.globals.get()`, etc): * - {@link TAG.ModuleTags | tags} * - {@link GLOBAL.ModuleGlobals | globals} * - {@link MEMORY.ModuleMemories | memories} @@ -119,12 +119,22 @@ export enum Feature { * - {@link ELEMENT_SEGMENT.ModuleElementSegments | elementSegments} * - {@link IMPORT.ModuleImports | imports} * - {@link EXPORT.ModuleExports | exports} + * - has a property `.x`, a namespace for creating expressions in the module (`.x.nop()`, `.x.i32.add()`, etc.) */ export class Module { readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); - /** This module’s expression creator. */ - readonly x = expressionCreator(this); // “x” for “expression” + /** + * This module’s expression creator. + * + * N.B.: For convenience, developers may want to destructure the module to free `x`: + * ```ts + * const mod = new Module(); + * const {x} = mod; + * x.i32.add(); + * ``` + */ + readonly x = expressionCreator(this); // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html From 70557cf793cca63de11cbd13c4bfc70422bafb14 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 22:49:15 -0400 Subject: [PATCH 078/247] renamed: src/-pre{ => .d}.ts --- ts/src/{-pre.ts => -pre.d.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ts/src/{-pre.ts => -pre.d.ts} (100%) diff --git a/ts/src/-pre.ts b/ts/src/-pre.d.ts similarity index 100% rename from ts/src/-pre.ts rename to ts/src/-pre.d.ts From 3a4143a030d4ff9d07b40028fa0c00b5e6c57e55 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 2 May 2026 23:10:40 -0400 Subject: [PATCH 079/247] docs: add Contributing section --- ts/README.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/ts/README.md b/ts/README.md index e447ba426cd..b2968ebc162 100644 --- a/ts/README.md +++ b/ts/README.md @@ -32,3 +32,56 @@ const instance = new WebAssembly.Instance(compiled, {}); console.log(instance.exports.add(41, 1)); // 42 ``` + +## How to Contribute +Make sure you have Git and Node (and NPM) installed on your machine, and have already cloned the **WebAssembly/binaryen** repo. + +From the repo’s root: +```zsh +$ cd ./ts/ +$ npm ci +$ npm run build +``` + +File Inventory: +- `README.md`: *you are here* + +- `{.editorconfig,.gitignore}`: standard repo files + +- `package{,-lock}.json`: Node package & npm registry details + +- `node_modules/` *(gitignored)*: npm dependencies + +- `tsconfig.json`: TypeScript configuration + +- `eslint.config.js`: JS/TS coding style conventions + +- `typedoc.config.js`: documentation generator configuration + +- `src/`: human-written source code + + - `binaryen.ts`: the entrypoint; exports everything available to consumers + + - `-pre.d.ts`: artifacts provided by Emscripten + + - `{lib,utils}.ts`: internal tools + + - `{constants,globals}.ts`: top-level exported globals + + - `-deprecations.ts`: everything deprecated, all in one place + + - `classes/`: all the modular code + + - `{TypeBuilder,ExpressionRunner,Relooper}.ts`: Binaryen tools + + - `module/`: Module and related classes + + - `expression/`: Expression info classes, and source for WASM expression generation + + - `services/`: namespace-like, stateless classes + +- `dist/` *(gitignored)*: output of **tsc**; this gets published to npm for consumers + +- `docs/`: documentation + + - `out/` *(gitignored)*: output of **typedoc**; gitignored From 6d87d3f5d80e4aae884a7bdb581e63c2a81c7252 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 03:16:30 -0400 Subject: [PATCH 080/247] docs: fix Module namespace --- ts/src/-deprecations.ts | 1 + ts/src/classes/module/DataSegment.ts | 4 +- ts/src/classes/module/ElementSegment.ts | 4 +- ts/src/classes/module/Export.ts | 4 +- ts/src/classes/module/Function.ts | 4 +- ts/src/classes/module/Global.ts | 4 +- ts/src/classes/module/Import.ts | 4 +- ts/src/classes/module/Memory.ts | 4 +- ts/src/classes/module/Module.ts | 57 +++++++++++++------------ ts/src/classes/module/Table.ts | 4 +- ts/src/classes/module/Tag.ts | 4 +- 11 files changed, 57 insertions(+), 37 deletions(-) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 9e0df94386c..5a275c92f49 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -56,6 +56,7 @@ export type ElementSegmentInfo = Module.ElementSegment; export type ExportInfo = Module.Export; + /** @deprecated The `ExpressionInfo` object type is now called {@link X.Expression}. */ export type ExpressionInfo = X.Expression; /** @deprecated The `DropInfo` object type is now called {@link X.Drop}. */ diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index c40c0238939..bc7c2317397 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -49,7 +49,9 @@ export class DataSegment { -/** Methods for manipulating {@link DataSegment | data segments} in a WASM module. */ +/** + * Methods for manipulating {@link DataSegment | data segments} in a WASM module. + */ export class ModuleDataSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index f6a606e16dd..a903361285f 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -45,7 +45,9 @@ export class ElementSegment { -/** Methods for manipulating {@link ElementSegment | element segments} in a WASM module. */ +/** + * Methods for manipulating {@link ElementSegment | element segments} in a WASM module. + */ export class ModuleElementSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index e7050260248..ba53cb46acf 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -35,7 +35,9 @@ export class Export { -/** Methods for manipulating {@link Export | exports} in a WASM module. */ +/** + * Methods for manipulating {@link Export | exports} in a WASM module. + */ export class ModuleExports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index d55a17e2e64..1faeafb402d 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -99,7 +99,9 @@ export {BinaryenFunction as Function}; -/** Methods for manipulating {@link BinaryenFunction | functions} in a WASM module. */ +/** + * Methods for manipulating {@link BinaryenFunction | functions} in a WASM module. + */ export class ModuleFunctions { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Global.ts b/ts/src/classes/module/Global.ts index 6bcb25237d8..9a8da7e2547 100644 --- a/ts/src/classes/module/Global.ts +++ b/ts/src/classes/module/Global.ts @@ -42,7 +42,9 @@ export class Global { -/** Methods for manipulating {@link Global | globals} in a WASM module. */ +/** + * Methods for manipulating {@link Global | globals} in a WASM module. + */ export class ModuleGlobals { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index f7b10394db4..c75bcb349a5 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -24,7 +24,9 @@ export class Import { -/** Methods for manipulating {@link Import | imports} in a WASM module. */ +/** + * Methods for manipulating {@link Import | imports} in a WASM module. + */ export class ModuleImports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index 30b872a463a..9ba6ee6379e 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -56,7 +56,9 @@ export class Memory { -/** Methods for manipulating {@link Memory | memories} in a WASM module. */ +/** + * Methods for manipulating {@link Memory | memories} in a WASM module. + */ export class ModuleMemories { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 9cc327afe98..6bc2dcebaed 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -97,31 +97,42 @@ export enum Feature { * `Module` itself is: * - an instantiable class (via `new Module()`) * - a namespace containing the following members, which themselves are classes (see related documentation): - * - {@link Tag} - * - {@link Global} - * - {@link Memory} - * - {@link Table} - * - {@link Function} - * - {@link DataSegment} - * - {@link ElementSegment} - * - {@link Import} - * - {@link Export} + * - {@link Module.Tag} + * - {@link Module.Global} + * - {@link Module.Memory} + * - {@link Module.Table} + * - {@link Module.Function} + * - {@link Module.DataSegment} + * - {@link Module.ElementSegment} + * - {@link Module.Import} + * - {@link Module.Export} * * Each instance of `Module`: * - is a WASM module with module manipulation methods (`.emitText()`, `.validate()`, etc.). * - is an individual namespace containing mixins, each with its own component manipulation methods (`.tags.add()`, `.globals.get()`, etc): - * - {@link TAG.ModuleTags | tags} - * - {@link GLOBAL.ModuleGlobals | globals} - * - {@link MEMORY.ModuleMemories | memories} - * - {@link TABLE.ModuleTables | tables} - * - {@link FUNCTION.ModuleFunctions | functions} - * - {@link DATA_SEGMENT.ModuleDataSegments | dataSegments} - * - {@link ELEMENT_SEGMENT.ModuleElementSegments | elementSegments} - * - {@link IMPORT.ModuleImports | imports} - * - {@link EXPORT.ModuleExports | exports} + * - {@link Module#tags} + * - {@link Module#globals} + * - {@link Module#memories} + * - {@link Module#tables} + * - {@link Module#functions} + * - {@link Module#dataSegments} + * - {@link Module#elementSegments} + * - {@link Module#imports} + * - {@link Module#exports} * - has a property `.x`, a namespace for creating expressions in the module (`.x.nop()`, `.x.i32.add()`, etc.) */ export class Module { + static readonly Tag = TAG.Tag; + static readonly Global = GLOBAL.Global; + static readonly Memory = MEMORY.Memory; + static readonly Table = TABLE.Table; + static readonly Function = FUNCTION.Function; + static readonly DataSegment = DATA_SEGMENT.DataSegment; + static readonly ElementSegment = ELEMENT_SEGMENT.ElementSegment; + static readonly Import = IMPORT.Import; + static readonly Export = EXPORT.Export; + + readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); /** @@ -410,14 +421,4 @@ export namespace Module { export type ElementSegment = ELEMENT_SEGMENT.ElementSegment; export type Import = IMPORT.Import; export type Export = EXPORT.Export; - - export const Tag = TAG.Tag; - export const Global = GLOBAL.Global; - export const Memory = MEMORY.Memory; - export const Table = TABLE.Table; - export const Function = FUNCTION.Function; - export const DataSegment = DATA_SEGMENT.DataSegment; - export const ElementSegment = ELEMENT_SEGMENT.ElementSegment; - export const Import = IMPORT.Import; - export const Export = EXPORT.Export; } diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index c72da5256aa..48747859b82 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -68,7 +68,9 @@ export class Table { -/** Methods for manipulating {@link Table | tables} in a WASM module. */ +/** + * Methods for manipulating {@link Table | tables} in a WASM module. + */ export class ModuleTables { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Tag.ts b/ts/src/classes/module/Tag.ts index 0754606fe7a..eef70b1d6b0 100644 --- a/ts/src/classes/module/Tag.ts +++ b/ts/src/classes/module/Tag.ts @@ -39,7 +39,9 @@ export class Tag { -/** Methods for manipulating {@link Tag | tags} in a WASM module. */ +/** + * Methods for manipulating {@link Tag | tags} in a WASM module. + */ export class ModuleTags { constructor(private readonly mod: Module) {} From fe8369e9a0a8d8c360d470b7d9f60ed6c3364a29 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 03:17:47 -0400 Subject: [PATCH 081/247] lint: inline internal object types --- ts/src/binaryen.ts | 4 ++-- ts/src/classes/TypeBuilder.ts | 7 +++++-- ts/src/classes/module/Memory.ts | 17 ++++++++++------- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 31de15f52e7..3085fc3171b 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -7,7 +7,7 @@ export { } from "./classes/module/Module.ts"; export type {Tag, ModuleTags} from "./classes/module/Tag.ts"; export type {Global, ModuleGlobals} from "./classes/module/Global.ts"; -export type {Memory, ModuleMemories, MemorySegment} from "./classes/module/Memory.ts"; +export type {Memory, ModuleMemories} from "./classes/module/Memory.ts"; export type {Table, ModuleTables} from "./classes/module/Table.ts"; export type {Function as BinaryenFunction, ModuleFunctions} from "./classes/module/Function.ts"; export type {DataSegment, ModuleDataSegments} from "./classes/module/DataSegment.ts"; @@ -15,7 +15,7 @@ export type {ElementSegment, ModuleElementSegments} from "./classes/module/Eleme export type {Import, ModuleImports} from "./classes/module/Import.ts"; export type {Export, ModuleExports} from "./classes/module/Export.ts"; export * as X from "./classes/expression/index.ts"; -export {TypeBuilder, type Field} from "./classes/TypeBuilder.ts"; +export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, ExpressionRunnerFlag, diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index cd85834abe8..40169d768e6 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -16,8 +16,11 @@ import { -/** A field in a struct/array. */ -export type Field = { +/** + * A field in a struct/array. + * @inline + */ +type Field = { /** The type of the struct field. */ type: Type, /** The field’s packed type. */ diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index 9ba6ee6379e..50f5e1b4ef7 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -19,13 +19,16 @@ import type { -/** Similar to a `DataSegment` but with some minor differences. */ -export interface MemorySegment { - name?: string; - offset: ExpressionRef; - data: Uint8Array; - passive: boolean; -} +/** + * Similar to a {@link DataSegment} but with some minor differences. + * @inline + */ +type MemorySegment = { + name?: string, + offset: ExpressionRef, + data: Uint8Array, + passive: boolean, +}; From 12acf6e27c709b4c9ef85b1ddc4066d823ddf0f2 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 03:47:39 -0400 Subject: [PATCH 082/247] docs: fix `@return` -> `@returns` --- ts/src/classes/Relooper.ts | 2 +- ts/src/classes/TypeBuilder.ts | 10 +++++----- ts/src/classes/module/Table.ts | 2 +- ts/src/globals.ts | 10 +++++----- ts/src/lib.ts | 2 +- ts/src/utils.ts | 10 +++++----- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/ts/src/classes/Relooper.ts b/ts/src/classes/Relooper.ts index 4a3d72ce458..78a4a87a41c 100644 --- a/ts/src/classes/Relooper.ts +++ b/ts/src/classes/Relooper.ts @@ -33,7 +33,7 @@ export class Relooper { /** * Adds a new block to the CFG, containing the provided code as its body. * @param code the block expression - * @return a reference to the block + * @returns a reference to the block */ addBlock(code: ExpressionRef): RelooperBlockRef { return BinaryenObj["_RelooperAddBlock"](this.#ptr, code); diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index 40169d768e6..6b11d699191 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -47,7 +47,7 @@ export class TypeBuilder { } /** - * @return the number of types in the builder + * @returns the number of types in the builder */ getSize(): number { return BinaryenObj["_TypeBuilderGetSize"](this.#ptr); @@ -104,7 +104,7 @@ export class TypeBuilder { /** * Retrieve a heap type from the builder, before disposal. * @param index index of the type to get - * @return the heap type at the given index + * @returns the heap type at the given index */ getTempHeapType(index: number): HeapType { return BinaryenObj["_TypeBuilderGetTempHeapType"](this.#ptr, index); @@ -113,7 +113,7 @@ export class TypeBuilder { /** * Retrieve a tuple type. * @param types types in the tuple - * @return the tuple type + * @returns the tuple type */ getTempTupleType(types: readonly Type[]): Type { return preserveStack(() => BinaryenObj["_TypeBuilderGetTempTupleType"](this.#ptr, i32sToStack(types), types.length)); @@ -123,7 +123,7 @@ export class TypeBuilder { * Generate a refence type from the given temporary heap type. * @param heapType the heap type in the type builder to use * @param nullable is the reference type nullable? - * @return the reference type + * @returns the reference type */ getTempRefType(heapType: HeapType, nullable: boolean): Type { return BinaryenObj["_TypeBuilderGetTempRefType"](this.#ptr, heapType, nullable); @@ -157,7 +157,7 @@ export class TypeBuilder { /** * Resolve any and all recursive types in the TypeBuilder and return their finalized forms. - * @return list of finalized heap types in the builder + * @returns list of finalized heap types in the builder */ buildAndDispose(): HeapType[] { return preserveStack(() => { diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 48747859b82..65a6a4433f8 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -59,7 +59,7 @@ export class Table { } /** - * @return does this table have a maximum number of pages? + * @returns does this table have a maximum number of pages? */ hasMax(): boolean { return Boolean(BinaryenObj["_BinaryenTableHasMax"](this[THIS_PTR])); diff --git a/ts/src/globals.ts b/ts/src/globals.ts index e043649a7e6..3be6d3d3bb9 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -50,7 +50,7 @@ function wrapModule(ptr: number): Module { * fatal error, we throw a JS exception (which JS can handle) rather than * abort the entire process (which would not be a friendly behavior). * @param func the function to call - * @return the return value of the given function + * @returns the return value of the given function */ function handleFatalError(func: () => T): T { try { @@ -137,7 +137,7 @@ export function exit(status: number): void { /** * Creates a multi-value type from an array of types. * @param types the array of types - * @return a tuple type containing the array’s components + * @returns a tuple type containing the array’s components */ export function createType(types: readonly Type[]): Type { return preserveStack(() => BinaryenObj["_BinaryenTypeCreate"](i32sToStack(types), types.length)); @@ -146,7 +146,7 @@ export function createType(types: readonly Type[]): Type { /** * Expands a multi-value type to an array of types. * @param typ the tuple type - * @return an array containing the tuple’s components + * @returns an array containing the tuple’s components */ export function expandType(typ: Type): Type[] { return preserveStack(() => { @@ -165,7 +165,7 @@ export function expandType(typ: Type): Type[] { * Gets the type from a heap type generated by TypeBuilder. * @param heapType the heap type from which to get the type * @param nullable whether the return type should be nullable - * @return given `ht`: `(ref null? ht)` + * @returns given `ht`: `(ref null? ht)` */ export function getTypeFromHeapType(heapType: HeapType, nullable: boolean): Type { return BinaryenObj["_BinaryenTypeFromHeapType"](heapType, nullable); @@ -174,7 +174,7 @@ export function getTypeFromHeapType(heapType: HeapType, nullable: boolean): Type /** * Gets the heap type of a type. * @param typ the type from which to get the heap type - * @return given `(ref null? ht)`: `ht` + * @returns given `(ref null? ht)`: `ht` */ export function getHeapType(typ: Type): HeapType { return BinaryenObj["_BinaryenTypeGetHeapType"](typ); diff --git a/ts/src/lib.ts b/ts/src/lib.ts index 021c5c280a2..7af0cee5832 100644 --- a/ts/src/lib.ts +++ b/ts/src/lib.ts @@ -21,7 +21,7 @@ export function consoleWarn(...args: any[]): void { * } * * @param replacement the name or signature of the new method replacing the deprecated one - * @return a method decorator + * @returns a method decorator */ export function replacedBy(replacement: string = ""): ( method: (this: This, ...args: Params) => Return, diff --git a/ts/src/utils.ts b/ts/src/utils.ts index eedf3cea43a..4fddd052e5f 100644 --- a/ts/src/utils.ts +++ b/ts/src/utils.ts @@ -28,7 +28,7 @@ export const THIS_PTR: unique symbol = Symbol(); /** * Exports friendly API methods. * @param func [description] - * @return [description] + * @returns [description] */ export function preserveStack(func: () => T): T { try { @@ -42,7 +42,7 @@ export function preserveStack(func: () => T): T { /** * [description] * @param str [description] - * @return [description] + * @returns [description] */ export function strToStack(str?: string): number { return str ? stringToUTF8OnStack(str) : 0; @@ -51,7 +51,7 @@ export function strToStack(str?: string): number { /** * [description] * @param i32s [description] - * @return [description] + * @returns [description] */ export function i32sToStack(i32s: readonly number[]): number { const ret = stackAlloc(i32s.length << 2); @@ -62,7 +62,7 @@ export function i32sToStack(i32s: readonly number[]): number { /** * [description] * @param i8s [description] - * @return [description] + * @returns [description] */ export function i8sToStack(i8s: readonly number[]): number { const ret = stackAlloc(i8s.length); @@ -77,7 +77,7 @@ export function i8sToStack(i8s: readonly number[]): number { * @param ref [description] * @param numFn [description] * @param getFn [description] - * @return [description] + * @returns [description] */ export function getAllNested( ref: T, From b2ec5fdb7a69ff540bb0a96add3dc718f33761bf Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 04:58:18 -0400 Subject: [PATCH 083/247] docs: add ExpressionCreator docs --- .../classes/expression/expression-creators.ts | 18 +++++++++++++++++- ts/src/classes/expression/index.ts | 9 +++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-creators.ts index 9410e16b414..0fb384470c7 100644 --- a/ts/src/classes/expression/expression-creators.ts +++ b/ts/src/classes/expression/expression-creators.ts @@ -31,6 +31,8 @@ function parametric(mod: Module) { select: Select.select.bind(null, mod), } as const; } +/** @useDeclaredType */ +export type ExpressionCreatorParametric = ReturnType; @@ -46,6 +48,8 @@ function control(mod: Module) { br_if: Break.br_if.bind(null, mod), } as const; } +/** @useDeclaredType */ +export type ExpressionCreatorControl = ReturnType; @@ -61,11 +65,23 @@ function variable(mod: Module) { }, } as const; } +/** @useDeclaredType */ +export type ExpressionCreatorVariable = ReturnType; +/** + * @expandType ExpressionCreatorParametric + * @expandType ExpressionCreatorControl + * @expandType ExpressionCreatorVariable + */ +export type ExpressionCreator = ( + & ExpressionCreatorParametric + & ExpressionCreatorControl + & ExpressionCreatorVariable +); /** Methods for creating expressions in a WASM module. */ -export function expressionCreator(mod: Module) { +export function expressionCreator(mod: Module): ExpressionCreator { return { ...parametric(mod), ...control(mod), diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 54b0515769c..f03dc64ca70 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -26,3 +26,12 @@ export {LocalSet} from "./LocalSet.ts"; // ## Numeric & Vector ## // export {Const} from "./Const.ts"; + + + +export type { + ExpressionCreator, + ExpressionCreatorParametric, + ExpressionCreatorControl, + ExpressionCreatorVariable, +} from "./expression-creators.ts"; From 979a3942e14db9e6d966ed1ecd053d31719ba464 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 05:04:01 -0400 Subject: [PATCH 084/247] style: rename "expression creator" -> "expression builder" --- ts/docs/API-Overview.md | 4 ++-- ...ion-creators.ts => expression-builders.ts} | 24 +++++++++---------- ts/src/classes/expression/index.ts | 10 ++++---- ts/src/classes/module/Module.ts | 8 +++---- 4 files changed, 23 insertions(+), 23 deletions(-) rename ts/src/classes/expression/{expression-creators.ts => expression-builders.ts} (75%) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index d059943663b..e60c0de5fdb 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -119,7 +119,7 @@ Objects: - `new Module.Export(ref: ExportRef)`: an object containing information about an **Export** - Properties of `Module` instances (see full list of methods in generated docs): - - `Module#x`: [create expressions](#expression-construction) (“x” for “expression”) + - `Module#x`: [build expressions](#expression-building) (“x” for “expression”) - `Module#tags`: **Tag** manipulation - `Module#globals`: **Global** manipulation - `Module#memories`: **Memory** manipulation @@ -132,7 +132,7 @@ Objects: -## Expression Construction +## Expression Building Each of these methods returns an `ExpressionRef`. ### Parametric Instructions diff --git a/ts/src/classes/expression/expression-creators.ts b/ts/src/classes/expression/expression-builders.ts similarity index 75% rename from ts/src/classes/expression/expression-creators.ts rename to ts/src/classes/expression/expression-builders.ts index 0fb384470c7..98f1418a825 100644 --- a/ts/src/classes/expression/expression-creators.ts +++ b/ts/src/classes/expression/expression-builders.ts @@ -1,6 +1,6 @@ import { BinaryenObj, -} from "../../-pre.ts"; +} from "../../-pre"; import type { ExpressionRef, } from "../../constants.ts"; @@ -32,7 +32,7 @@ function parametric(mod: Module) { } as const; } /** @useDeclaredType */ -export type ExpressionCreatorParametric = ReturnType; +export type ExpressionBuilderParametric = ReturnType; @@ -49,7 +49,7 @@ function control(mod: Module) { } as const; } /** @useDeclaredType */ -export type ExpressionCreatorControl = ReturnType; +export type ExpressionBuilderControl = ReturnType; @@ -66,22 +66,22 @@ function variable(mod: Module) { } as const; } /** @useDeclaredType */ -export type ExpressionCreatorVariable = ReturnType; +export type ExpressionBuilderVariable = ReturnType; /** - * @expandType ExpressionCreatorParametric - * @expandType ExpressionCreatorControl - * @expandType ExpressionCreatorVariable + * @expandType ExpressionBuilderParametric + * @expandType ExpressionBuilderControl + * @expandType ExpressionBuilderVariable */ -export type ExpressionCreator = ( - & ExpressionCreatorParametric - & ExpressionCreatorControl - & ExpressionCreatorVariable +export type ExpressionBuilder = ( + & ExpressionBuilderParametric + & ExpressionBuilderControl + & ExpressionBuilderVariable ); /** Methods for creating expressions in a WASM module. */ -export function expressionCreator(mod: Module): ExpressionCreator { +export function expressionBuilder(mod: Module): ExpressionBuilder { return { ...parametric(mod), ...control(mod), diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index f03dc64ca70..d810abe160e 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -30,8 +30,8 @@ export {Const} from "./Const.ts"; export type { - ExpressionCreator, - ExpressionCreatorParametric, - ExpressionCreatorControl, - ExpressionCreatorVariable, -} from "./expression-creators.ts"; + ExpressionBuilder, + ExpressionBuilderParametric, + ExpressionBuilderControl, + ExpressionBuilderVariable, +} from "./expression-builders.ts"; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 6bc2dcebaed..adbc0e8c8d1 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -29,8 +29,8 @@ import { strToStack, } from "../../utils.ts"; import { - expressionCreator, -} from "../expression/expression-creators.ts"; + expressionBuilder, +} from "../expression/expression-builders.ts"; import * as DATA_SEGMENT from "./DataSegment.ts"; import * as ELEMENT_SEGMENT from "./ElementSegment.ts"; import * as EXPORT from "./Export.ts"; @@ -136,7 +136,7 @@ export class Module { readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); /** - * This module’s expression creator. + * This module’s expression builder. * * N.B.: For convenience, developers may want to destructure the module to free `x`: * ```ts @@ -145,7 +145,7 @@ export class Module { * x.i32.add(); * ``` */ - readonly x = expressionCreator(this); + readonly x = expressionBuilder(this); // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html From 760b667c13e436ef6479f1787bbe1ec840b7295f Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 05:33:55 -0400 Subject: [PATCH 085/247] docs: fix deprecation links --- ts/src/classes/ExpressionRunner.ts | 2 +- ts/src/classes/module/Module.ts | 114 ++++++++++++++--------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/ts/src/classes/ExpressionRunner.ts b/ts/src/classes/ExpressionRunner.ts index a1c605fb64a..473c82bd33c 100644 --- a/ts/src/classes/ExpressionRunner.ts +++ b/ts/src/classes/ExpressionRunner.ts @@ -22,7 +22,7 @@ export enum ExpressionRunnerFlag { export class ExpressionRunner { - /** @deprecated Static field `ExpressionRunner.Flags` is now a standalone enum `ExpressionRunnerFlag`. */ + /** @deprecated Static field `ExpressionRunner.Flags` is now a standalone enum {@link ExpressionRunnerFlag}. */ static Flags = ExpressionRunnerFlag; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index adbc0e8c8d1..56621df9db6 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -159,10 +159,10 @@ export class Module { readonly imports = new IMPORT.ModuleImports(this); readonly exports = new EXPORT.ModuleExports(this); - /** @deprecated Use `this.start` instead. */ @replacedBy("`this.start`") getStart() { return this.start; } - /** @deprecated Use `this.start` instead. */ @replacedBy("`this.start`") setStart(start: FunctionRef) { this.start = start; } - /** @deprecated Use `this.features` instead. */ @replacedBy("`this.features`") getFeatures() { return this.features; } - /** @deprecated Use `this.features` instead. */ @replacedBy("`this.features`") setFeatures(features: Feature) { return this.features = features; } + /** @deprecated Use {@link Module#start | `this.start`} instead. */ @replacedBy("`this.start`") getStart() { return this.start; } + /** @deprecated Use {@link Module#start | `this.start`} instead. */ @replacedBy("`this.start`") setStart(start: FunctionRef) { this.start = start; } + /** @deprecated Use {@link Module#features | `this.features`} instead. */ @replacedBy("`this.features`") getFeatures() { return this.features; } + /** @deprecated Use {@link Module#features | `this.features`} instead. */ @replacedBy("`this.features`") setFeatures(features: Feature) { return this.features = features; } /** The start function. */ get start(): FunctionRef { @@ -185,58 +185,58 @@ export class Module { BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); } - /** @deprecated Use `this.tags.add` instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } - /** @deprecated Use `this.tags.get` instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } - /** @deprecated Use `this.tags.remove` instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } - - /** @deprecated Use `this.globals.add` instead. */ @replacedBy("`this.globals.add`") addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef) { return this.globals.add(name, type, mutable, init); } - /** @deprecated Use `this.globals.get` instead. */ @replacedBy("`this.globals.get`") getGlobal(name: string) { return this.globals.get(name); } - /** @deprecated Use `this.globals.getByIndex` instead. */ @replacedBy("`this.globals.getByIndex`") getGlobalByIndex(index: number) { return this.globals.getByIndex(index); } - /** @deprecated Use `this.globals.count` instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } - /** @deprecated Use `this.globals.remove` instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } - - /** @deprecated Use `this.memories.set` instead. */ @replacedBy("`this.memories.set`") setMemory(initial: number, maximum: number, exportName: string, segments?: readonly any[], shared?: boolean, memory64?: boolean, internalName?: string) { return this.memories.set(initial, maximum, exportName, segments, shared, memory64, internalName); } - /** @deprecated Use `this.memories.has` instead. */ @replacedBy("`this.memories.has`") hasMemory() { return this.memories.has(); } - - /** @deprecated Use `this.tables.add` instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } - /** @deprecated Use `this.tables.get` instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } - /** @deprecated Use `this.tables.getByIndex` instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } - /** @deprecated Use `this.tables.getSegments` instead. */ @replacedBy("`this.tables.getSegments`") getTableSegments(table: TableRef) { return this.tables.getSegments(table); } - /** @deprecated Use `this.tables.count` instead. */ @replacedBy("`this.tables.count`") getNumTables() { return this.tables.count(); } - /** @deprecated Use `this.tables.remove` instead. */ @replacedBy("`this.tables.remove`") removeTable(name: string) { return this.tables.remove(name); } - - /** @deprecated Use `this.functions.add` instead. */ @replacedBy("`this.functions.add`") addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef) { return this.functions.add(name, params, results, varTypes, body); } - /** @deprecated Use `this.functions.get` instead. */ @replacedBy("`this.functions.get`") getFunction(name: string) { return this.functions.get(name); } - /** @deprecated Use `this.functions.getByIndex` instead. */ @replacedBy("`this.functions.getByIndex`") getFunctionByIndex(index: number) { return this.functions.getByIndex(index); } - /** @deprecated Use `this.functions.count` instead. */ @replacedBy("`this.functions.count`") getNumFunctions() { return this.functions.count(); } - /** @deprecated Use `this.functions.remove` instead. */ @replacedBy("`this.functions.remove`") removeFunction(name: string) { return this.functions.remove(name); } - - /** @deprecated Use `this.dataSegments.get` instead. */ @replacedBy("`this.dataSegments.get`") getDataSegment(name: string) { return this.dataSegments.get(name); } - /** @deprecated Use `this.dataSegments.getByIndex` instead. */ @replacedBy("`this.dataSegments.getByIndex`") getDataSegmentByIndex(index: number) { return this.dataSegments.getByIndex(index); } - /** @deprecated Use `this.dataSegments.count` instead. */ @replacedBy("`this.dataSegments.count`") getNumDataSegments() { return this.dataSegments.count(); } - - /** @deprecated Use `this.elementSegments.addActive` instead. */ @replacedBy("`this.elementSegments.addActive`") addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef) { return this.elementSegments.addActive(table, name, funcNames, offset); } - /** @deprecated Use `this.elementSegments.addPassive` instead. */ @replacedBy("`this.elementSegments.addPassive`") addPassiveElementSegment(name: string, funcNames: readonly string[]) { return this.elementSegments.addPassive(name, funcNames); } - /** @deprecated Use `this.elementSegments.get` instead. */ @replacedBy("`this.elementSegments.get`") getElementSegment(name: string) { return this.elementSegments.get(name); } - /** @deprecated Use `this.elementSegments.getByIndex` instead. */ @replacedBy("`this.elementSegments.getByIndex`") getElementSegmentByIndex(index: number) { return this.elementSegments.getByIndex(index); } - /** @deprecated Use `this.elementSegments.count` instead. */ @replacedBy("`this.elementSegments.count`") getNumElementSegments() { return this.elementSegments.count(); } - /** @deprecated Use `this.elementSegments.remove` instead. */ @replacedBy("`this.elementSegments.remove`") removeElementSegment(name: string) { return this.elementSegments.remove(name); } - - /** @deprecated Use `this.imports.addTag` instead. */ @replacedBy("`this.imports.addTag`") addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addTag(internalName, externalModuleName, externalBaseName, params, results); } - /** @deprecated Use `this.imports.addGlobal` instead. */ @replacedBy("`this.imports.addGlobal`") addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean) { return this.imports.addGlobal(internalName, externalModuleName, externalBaseName, globalType, mutable); } - /** @deprecated Use `this.imports.addMemory` instead. */ @replacedBy("`this.imports.addMemory`") addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean) { return this.imports.addMemory(internalName, externalModuleName, externalBaseName, shared); } - /** @deprecated Use `this.imports.addTable` instead. */ @replacedBy("`this.imports.addTable`") addTableImport(internalName: string, externalModuleName: string, externalBaseName: string) { return this.imports.addTable(internalName, externalModuleName, externalBaseName); } - /** @deprecated Use `this.imports.addFunction` instead. */ @replacedBy("`this.imports.addFunction`") addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addFunction(internalName, externalModuleName, externalBaseName, params, results); } - - /** @deprecated Use `this.exports.addTag` instead. */ @replacedBy("`this.exports.addTag`") addTagExport(internalName: string, externalName: string) { return this.exports.addTag(internalName, externalName); } - /** @deprecated Use `this.exports.addGlobal` instead. */ @replacedBy("`this.exports.addGlobal`") addGlobalExport(internalName: string, externalName: string) { return this.exports.addGlobal(internalName, externalName); } - /** @deprecated Use `this.exports.addMemory` instead. */ @replacedBy("`this.exports.addMemory`") addMemoryExport(internalName: string, externalName: string) { return this.exports.addMemory(internalName, externalName); } - /** @deprecated Use `this.exports.addTable` instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } - /** @deprecated Use `this.exports.addFunction` instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } - /** @deprecated Use `this.exports.get` instead. */ @replacedBy("`this.exports.get`") getExport(externalName: string) { return this.exports.get(externalName); } - /** @deprecated Use `this.exports.getByIndex` instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } - /** @deprecated Use `this.exports.count` instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } - /** @deprecated Use `this.exports.remove` instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } + /** @deprecated Use {@link ModuleTags#add | `this.tags.add`} instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } + /** @deprecated Use {@link ModuleTags#add | `this.tags.get`} instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } + /** @deprecated Use {@link ModuleTags#add | `this.tags.remove`} instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } + + /** @deprecated Use {@link ModuleGlobals#add | `this.globals.add`} instead. */ @replacedBy("`this.globals.add`") addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef) { return this.globals.add(name, type, mutable, init); } + /** @deprecated Use {@link ModuleGlobals#get | `this.globals.get`} instead. */ @replacedBy("`this.globals.get`") getGlobal(name: string) { return this.globals.get(name); } + /** @deprecated Use {@link ModuleGlobals#getByIndex | `this.globals.getByIndex`} instead. */ @replacedBy("`this.globals.getByIndex`") getGlobalByIndex(index: number) { return this.globals.getByIndex(index); } + /** @deprecated Use {@link ModuleGlobals#count | `this.globals.count`} instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } + /** @deprecated Use {@link ModuleGlobals#remove | `this.globals.remove`} instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } + + /** @deprecated Use {@link ModuleMemories#set | `this.memories.set`} instead. */ @replacedBy("`this.memories.set`") setMemory(initial: number, maximum: number, exportName: string, segments?: readonly any[], shared?: boolean, memory64?: boolean, internalName?: string) { return this.memories.set(initial, maximum, exportName, segments, shared, memory64, internalName); } + /** @deprecated Use {@link ModuleMemories#has | `this.memories.has`} instead. */ @replacedBy("`this.memories.has`") hasMemory() { return this.memories.has(); } + + /** @deprecated Use {@link ModuleTables#add | `this.tables.add`} instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } + /** @deprecated Use {@link ModuleTables#get | `this.tables.get`} instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } + /** @deprecated Use {@link ModuleTables#getByIndex | `this.tables.getByIndex`} instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } + /** @deprecated Use {@link ModuleTables#getSegments | `this.tables.getSegments`} instead. */ @replacedBy("`this.tables.getSegments`") getTableSegments(table: TableRef) { return this.tables.getSegments(table); } + /** @deprecated Use {@link ModuleTables#count | `this.tables.count`} instead. */ @replacedBy("`this.tables.count`") getNumTables() { return this.tables.count(); } + /** @deprecated Use {@link ModuleTables#remove | `this.tables.remove`} instead. */ @replacedBy("`this.tables.remove`") removeTable(name: string) { return this.tables.remove(name); } + + /** @deprecated Use {@link ModuleFunctions#add | `this.functions.add`} instead. */ @replacedBy("`this.functions.add`") addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef) { return this.functions.add(name, params, results, varTypes, body); } + /** @deprecated Use {@link ModuleFunctions#get | `this.functions.get`} instead. */ @replacedBy("`this.functions.get`") getFunction(name: string) { return this.functions.get(name); } + /** @deprecated Use {@link ModuleFunctions#getByIndex | `this.functions.getByIndex`} instead. */ @replacedBy("`this.functions.getByIndex`") getFunctionByIndex(index: number) { return this.functions.getByIndex(index); } + /** @deprecated Use {@link ModuleFunctions#count | `this.functions.count`} instead. */ @replacedBy("`this.functions.count`") getNumFunctions() { return this.functions.count(); } + /** @deprecated Use {@link ModuleFunctions#remove | `this.functions.remove`} instead. */ @replacedBy("`this.functions.remove`") removeFunction(name: string) { return this.functions.remove(name); } + + /** @deprecated Use {@link ModuleDataSegments#get | `this.dataSegments.get`} instead. */ @replacedBy("`this.dataSegments.get`") getDataSegment(name: string) { return this.dataSegments.get(name); } + /** @deprecated Use {@link ModuleDataSegments#getByIndex | `this.dataSegments.getByIndex`} instead. */ @replacedBy("`this.dataSegments.getByIndex`") getDataSegmentByIndex(index: number) { return this.dataSegments.getByIndex(index); } + /** @deprecated Use {@link ModuleDataSegments#count | `this.dataSegments.count`} instead. */ @replacedBy("`this.dataSegments.count`") getNumDataSegments() { return this.dataSegments.count(); } + + /** @deprecated Use {@link ModuleElementSegments#addActive | `this.elementSegments.addActive`} instead. */ @replacedBy("`this.elementSegments.addActive`") addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef) { return this.elementSegments.addActive(table, name, funcNames, offset); } + /** @deprecated Use {@link ModuleElementSegments#addPassive | `this.elementSegments.addPassive`} instead. */ @replacedBy("`this.elementSegments.addPassive`") addPassiveElementSegment(name: string, funcNames: readonly string[]) { return this.elementSegments.addPassive(name, funcNames); } + /** @deprecated Use {@link ModuleElementSegments#get | `this.elementSegments.get`} instead. */ @replacedBy("`this.elementSegments.get`") getElementSegment(name: string) { return this.elementSegments.get(name); } + /** @deprecated Use {@link ModuleElementSegments#getByIndex | `this.elementSegments.getByIndex`} instead. */ @replacedBy("`this.elementSegments.getByIndex`") getElementSegmentByIndex(index: number) { return this.elementSegments.getByIndex(index); } + /** @deprecated Use {@link ModuleElementSegments#count | `this.elementSegments.count`} instead. */ @replacedBy("`this.elementSegments.count`") getNumElementSegments() { return this.elementSegments.count(); } + /** @deprecated Use {@link ModuleElementSegments#remove | `this.elementSegments.remove`} instead. */ @replacedBy("`this.elementSegments.remove`") removeElementSegment(name: string) { return this.elementSegments.remove(name); } + + /** @deprecated Use {@link ModuleImports#addTag | `this.imports.addTag`} instead. */ @replacedBy("`this.imports.addTag`") addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addTag(internalName, externalModuleName, externalBaseName, params, results); } + /** @deprecated Use {@link ModuleImports#addGlobal | `this.imports.addGlobal`} instead. */ @replacedBy("`this.imports.addGlobal`") addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean) { return this.imports.addGlobal(internalName, externalModuleName, externalBaseName, globalType, mutable); } + /** @deprecated Use {@link ModuleImports#addMemory | `this.imports.addMemory`} instead. */ @replacedBy("`this.imports.addMemory`") addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean) { return this.imports.addMemory(internalName, externalModuleName, externalBaseName, shared); } + /** @deprecated Use {@link ModuleImports#addTable | `this.imports.addTable`} instead. */ @replacedBy("`this.imports.addTable`") addTableImport(internalName: string, externalModuleName: string, externalBaseName: string) { return this.imports.addTable(internalName, externalModuleName, externalBaseName); } + /** @deprecated Use {@link ModuleImports#addFunction | `this.imports.addFunction`} instead. */ @replacedBy("`this.imports.addFunction`") addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addFunction(internalName, externalModuleName, externalBaseName, params, results); } + + /** @deprecated Use {@link ModuleExports#get | `this.exports.get`} instead. */ @replacedBy("`this.exports.get`") getExport(externalName: string) { return this.exports.get(externalName); } + /** @deprecated Use {@link ModuleExports#getByIndex | `this.exports.getByIndex`} instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } + /** @deprecated Use {@link ModuleExports#count | `this.exports.count`} instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } + /** @deprecated Use {@link ModuleExports#remove | `this.exports.remove`} instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } + /** @deprecated Use {@link ModuleExports#addTag | `this.exports.addTag`} instead. */ @replacedBy("`this.exports.addTag`") addTagExport(internalName: string, externalName: string) { return this.exports.addTag(internalName, externalName); } + /** @deprecated Use {@link ModuleExports#addGlobal | `this.exports.addGlobal`} instead. */ @replacedBy("`this.exports.addGlobal`") addGlobalExport(internalName: string, externalName: string) { return this.exports.addGlobal(internalName, externalName); } + /** @deprecated Use {@link ModuleExports#addMemory | `this.exports.addMemory`} instead. */ @replacedBy("`this.exports.addMemory`") addMemoryExport(internalName: string, externalName: string) { return this.exports.addMemory(internalName, externalName); } + /** @deprecated Use {@link ModuleExports#addTable | `this.exports.addTable`} instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } + /** @deprecated Use {@link ModuleExports#addFunction | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } getMemoryInfo(name: string): MEMORY.Memory { return new MEMORY.Memory(this, name); @@ -395,7 +395,7 @@ export class Module { BinaryenObj["_BinaryenModuleUpdateMaps"](this.ptr); } - /** @deprecated Use global `copyExpression(expr, this)` instead. */ + /** @deprecated Use {@link copyExpression | `copyExpression(expr, this)`} instead. */ @replacedBy("global `copyExpression(expr, this)`") copyExpression(expr: ExpressionRef) { return copyExpression(expr, this); From 6ad70a59b98e10fd3ad76d7b86495b3ad9399ad0 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 05:35:59 -0400 Subject: [PATCH 086/247] style: add some css --- ts/docs/styles.css | 4 ++++ ts/typedoc.config.js | 1 + 2 files changed, 5 insertions(+) create mode 100644 ts/docs/styles.css diff --git a/ts/docs/styles.css b/ts/docs/styles.css new file mode 100644 index 00000000000..d6c18b9a1ec --- /dev/null +++ b/ts/docs/styles.css @@ -0,0 +1,4 @@ +.deprecated { + --color-text: gray; + color: var(--color-text); +} diff --git a/ts/typedoc.config.js b/ts/typedoc.config.js index 356b3de9433..bee06b650d4 100644 --- a/ts/typedoc.config.js +++ b/ts/typedoc.config.js @@ -4,4 +4,5 @@ export default { projectDocuments: ["./docs/API-Overview.md"], useFirstParagraphOfCommentAsSummary: true, out: "./docs/out/", + customCss: "./docs/styles.css", }; From 5bf504decd1947093269fab019d8d1e5f500d60c Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 05:40:29 -0400 Subject: [PATCH 087/247] docs: fix API TOC --- ts/docs/API-Overview.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index e60c0de5fdb..f2b42a3e2ed 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -6,7 +6,8 @@ If you rely on Binaryen.TS and spot an issue, please consider sending a PR our w ### Contents - [Top-Level Symbols](#top-level-symbols) - [Module Manipulation](#module-manipulation) -- [Expression Construction](#expression-construction) +- [Expression Building](#expression-building) +- [Expression Manipulation](#expression-manipulation) - [Deprecations](#️-deprecations-renames-and-moves) From ba3a64c95d2afc600e8cdf3882cc70d937ede74a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 16:19:02 -0400 Subject: [PATCH 088/247] build: install @types/node & tsx --- ts/package-lock.json | 563 ++++++++++++++++++++++++++++++++++++++++++- ts/package.json | 4 +- 2 files changed, 565 insertions(+), 2 deletions(-) diff --git a/ts/package-lock.json b/ts/package-lock.json index ac7b1d5853f..742cbd41210 100644 --- a/ts/package-lock.json +++ b/ts/package-lock.json @@ -11,14 +11,458 @@ "devDependencies": { "@eslint/js": "^10.0.1", "@stylistic/eslint-plugin": "^5.10.0", + "@types/node": "^24.12.2", "eslint": "^10.2.1", "globals": "^17.5.0", + "tsx": "^4.21.0", "typedoc": "^0.28.19", "typescript": "~6.0.0", "typescript-eslint": "^8.59.1" }, "engines": { - "node": "^22.6 || ^24" + "node": "^24.12" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -330,6 +774,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "24.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", + "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -703,6 +1157,48 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -989,6 +1485,34 @@ "dev": true, "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -1311,6 +1835,16 @@ "node": ">=6" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", @@ -1377,6 +1911,26 @@ "typescript": ">=4.8.4" } }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -1459,6 +2013,13 @@ "dev": true, "license": "MIT" }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/ts/package.json b/ts/package.json index 3ee3ad78138..dbf0def7e78 100644 --- a/ts/package.json +++ b/ts/package.json @@ -30,13 +30,15 @@ "devDependencies": { "@eslint/js": "^10.0.1", "@stylistic/eslint-plugin": "^5.10.0", + "@types/node": "^24.12.2", "eslint": "^10.2.1", "globals": "^17.5.0", + "tsx": "^4.21.0", "typedoc": "^0.28.19", "typescript": "~6.0.0", "typescript-eslint": "^8.59.1" }, "engines": { - "node": "^22.6 || ^24" + "node": "^24.12" } } From 4930f74d515600d84306ecfa82514007c54faa07 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 17:54:43 -0400 Subject: [PATCH 089/247] Revert "renamed: src/-pre{ => .d}.ts" This reverts commit 70557cf793cca63de11cbd13c4bfc70422bafb14. --- ts/src/{-pre.d.ts => -pre.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ts/src/{-pre.d.ts => -pre.ts} (100%) diff --git a/ts/src/-pre.d.ts b/ts/src/-pre.ts similarity index 100% rename from ts/src/-pre.d.ts rename to ts/src/-pre.ts From 80fd8d4217189fa52ff14ede0677dd224df9433b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 17:50:53 -0400 Subject: [PATCH 090/247] test: setup tests --- ts/eslint.config.js | 6 +++--- ts/package.json | 3 ++- ts/test/demo.test.ts | 24 ++++++++++++++++++++++++ ts/test/tsconfig.json | 12 ++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 ts/test/demo.test.ts create mode 100644 ts/test/tsconfig.json diff --git a/ts/eslint.config.js b/ts/eslint.config.js index 7bc8336389c..428846ea037 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -11,7 +11,7 @@ export default [ eslint.configs.recommended, // https://github.com/eslint/eslint/blob/v10.2.1/packages/js/src/configs/eslint-recommended.js { name: "All", // all JS and TS files - files: ["./{eslint,typedoc}.config.js", "./src/**/*.{js,ts}"], + files: ["./{eslint,typedoc}.config.js", "./{src,test}/**/*.{js,ts}"], languageOptions: {globals: {...globals.node}}, linterOptions: {reportUnusedDisableDirectives: "error"}, plugins: {"@stylistic": stylistic}, @@ -118,11 +118,11 @@ export default [ }, { name: "TypeScript Only", // rules that break on JS files, and rules that need TSConfig to work - files: ["./src/**/*.ts"], + files: ["./{src,test}/**/*.ts"], languageOptions: { globals: {...globals.node}, parser: tseslint.parser, - parserOptions: {project: ["./tsconfig.json"]}, + parserOptions: {project: ["./tsconfig.json", "./test/tsconfig.json"]}, }, plugins: {"@typescript-eslint": tseslint.plugin}, diff --git a/ts/package.json b/ts/package.json index dbf0def7e78..c500a7c6003 100644 --- a/ts/package.json +++ b/ts/package.json @@ -19,7 +19,8 @@ "compile": "rm -rf ./dist/ && tsc", "lint": "eslint ./", "docs": "rm -rf ./docs/out/ && typedoc", - "build": "npm run compile && npm run lint && npm run docs" + "test": "tsx --test --test-isolation=none -- './test/**/*.test.ts'", + "build": "npm run compile && npm run lint && npm run docs && npm run test" }, "files": [ "package.json", diff --git a/ts/test/demo.test.ts b/ts/test/demo.test.ts new file mode 100644 index 00000000000..d02a8cdde0c --- /dev/null +++ b/ts/test/demo.test.ts @@ -0,0 +1,24 @@ +import * as assert from "node:assert"; +import { + suite, + test, +} from "node:test"; + + + +suite("Demo", () => { + test("basic assertions.", () => { + assert.ok(true, "expected value to be truthy."); + assert.strictEqual(2 ** 7, 128, "expected values to be value-equal."); + + const arr = ["f64", "i32"]; + assert.strictEqual(arr, arr.sort(), "expected values to be reference-equal."); + assert.notStrictEqual(arr, ["f64", "i32"], "expected values not to be reference-equal."); + assert.deepStrictEqual(arr, ["f64", "i32"], "expected values to be recursively deep equal."); + assert.notDeepStrictEqual(arr, ["i32", "f64"], "arrays are not deep-equal when item order differs."); + + const obj = {i: 32, f: 64}; + assert.deepStrictEqual(obj, {f: 64, i: 32}, "deep-equal objects need not have the same property order."); + assert.partialDeepStrictEqual(obj, {i: 32}, "expected the left to contain all properties & values in the right."); + }); +}); diff --git a/ts/test/tsconfig.json b/ts/test/tsconfig.json new file mode 100644 index 00000000000..3437380bf30 --- /dev/null +++ b/ts/test/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + // Modules + "rootDir": "../", + "types": ["node"], + + // Emit + "noEmit": true, + }, + "include": ["./"], +} From b258669d02b94cc7d4dcb4dadec615421d4b79a2 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 18:42:38 -0400 Subject: [PATCH 091/247] feat: stub some missing instructions --- .../classes/expression/expression-builders.ts | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/ts/src/classes/expression/expression-builders.ts b/ts/src/classes/expression/expression-builders.ts index 98f1418a825..05687d0927d 100644 --- a/ts/src/classes/expression/expression-builders.ts +++ b/ts/src/classes/expression/expression-builders.ts @@ -19,6 +19,11 @@ import { +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + function parametric(mod: Module) { return { /** Creates a no-operation `(nop)` instruction. */ @@ -42,10 +47,52 @@ function control(mod: Module) { block: Block.block.bind(null, mod), /** @inheritdoc X.Loop.loop */ loop: Loop.loop.bind(null, mod), + if: STUB, /** @inheritdoc X.Break.br */ br: Break.br.bind(null, mod), /** @inheritdoc X.Break.br_if */ br_if: Break.br_if.bind(null, mod), + br_table: STUB, + br_on_null: STUB, + br_on_non_null: STUB, + br_on_cast: STUB, + br_on_cast_fail: STUB, + call: STUB, + call_ref: STUB, + call_indirect: STUB, + return: STUB, + return_call: STUB, + return_call_ref: STUB, + return_call_indirect: STUB, + throw: STUB, + throw_ref: STUB, + try_table: STUB, + // TODO: catch + // TODO: catch_ref + // TODO: catch_all + // TODO: catch_all_ref + + /** @deprecated Use {@link ExpressionBuilderControl#br} instead. */ + // @ts-expect-error + break(...args) { return this.br(...args); }, + /** @deprecated Use {@link ExpressionBuilderControl#br_table} instead. */ + // @ts-expect-error + switch(...args) { return this.br_table(...args); }, + /** @deprecated Use {@link ExpressionBuilderControl#call_indirect} instead. */ + // @ts-expect-error + callIndirect(...args) { return this.call_indirect(...args); }, + /** @deprecated Use {@link ExpressionBuilderControl#return_call} instead. */ + // @ts-expect-error + returnCall(...args) { return this.return_call(...args); }, + /** @deprecated Use {@link ExpressionBuilderControl#return_call_indirect} instead. */ + // @ts-expect-error + returnCallIndirect(...args) { return this.return_call_indirect(...args); }, + /** @deprecated Use {@link ExpressionBuilderControl#throw_ref} instead. */ + // @ts-expect-error + rethrow(...args) { return this.throw_ref(...args); }, + /** @deprecated Use {@link ExpressionBuilderControl#try_table} instead. */ + // @ts-expect-error + try(...args) { return this.try_table(...args); }, } as const; } /** @useDeclaredType */ @@ -63,6 +110,10 @@ function variable(mod: Module) { /** @inheritDoc X.LocalSet.localTee */ tee: LocalSet.localTee.bind(null, mod), }, + global: { + get: STUB, + set: STUB, + }, } as const; } /** @useDeclaredType */ From 0d0d584c82acec7bf1bb67438d01b985e8d6e913 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 20:12:18 -0400 Subject: [PATCH 092/247] refactor: split up expression builders --- ts/src/binaryen.ts | 1 + .../control.ts} | 74 +------------------ .../expression-builders/expressionBuilder.ts | 48 ++++++++++++ ts/src/classes/expression-builders/global.ts | 22 ++++++ ts/src/classes/expression-builders/index.ts | 5 ++ ts/src/classes/expression-builders/local.ts | 25 +++++++ .../classes/expression-builders/parametric.ts | 33 +++++++++ ts/src/classes/expression/index.ts | 9 --- ts/src/classes/module/Module.ts | 2 +- 9 files changed, 139 insertions(+), 80 deletions(-) rename ts/src/classes/{expression/expression-builders.ts => expression-builders/control.ts} (54%) create mode 100644 ts/src/classes/expression-builders/expressionBuilder.ts create mode 100644 ts/src/classes/expression-builders/global.ts create mode 100644 ts/src/classes/expression-builders/index.ts create mode 100644 ts/src/classes/expression-builders/local.ts create mode 100644 ts/src/classes/expression-builders/parametric.ts diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 3085fc3171b..b5fd2287899 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -15,6 +15,7 @@ export type {ElementSegment, ModuleElementSegments} from "./classes/module/Eleme export type {Import, ModuleImports} from "./classes/module/Import.ts"; export type {Export, ModuleExports} from "./classes/module/Export.ts"; export * as X from "./classes/expression/index.ts"; +export * as ExpressionBuilder from "./classes/expression-builders/index.ts"; export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, diff --git a/ts/src/classes/expression/expression-builders.ts b/ts/src/classes/expression-builders/control.ts similarity index 54% rename from ts/src/classes/expression/expression-builders.ts rename to ts/src/classes/expression-builders/control.ts index 05687d0927d..a8c117bdc83 100644 --- a/ts/src/classes/expression/expression-builders.ts +++ b/ts/src/classes/expression-builders/control.ts @@ -1,21 +1,11 @@ -import { - BinaryenObj, -} from "../../-pre"; -import type { - ExpressionRef, -} from "../../constants.ts"; import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; import { Block, Break, - Drop, - LocalGet, - LocalSet, Loop, - Select, -} from "./index.ts"; +} from "../../classes/expression/index.ts"; @@ -24,24 +14,7 @@ const STUB = (..._args: readonly number[]): number => 0; -function parametric(mod: Module) { - return { - /** Creates a no-operation `(nop)` instruction. */ - nop: (): ExpressionRef => BinaryenObj["_BinaryenNop"](mod.ptr), - /** Creates an unreachable instruction that will always trap. */ - unreachable: (): ExpressionRef => BinaryenObj["_BinaryenUnreachable"](mod.ptr), - /** @inheritDoc X.Drop.drop */ - drop: Drop.drop.bind(null, mod), - /** @inheritDoc X.Select.select */ - select: Select.select.bind(null, mod), - } as const; -} -/** @useDeclaredType */ -export type ExpressionBuilderParametric = ReturnType; - - - -function control(mod: Module) { +export function control(mod: Module) { return { /** @inheritdoc X.Block.block */ block: Block.block.bind(null, mod), @@ -95,47 +68,8 @@ function control(mod: Module) { try(...args) { return this.try_table(...args); }, } as const; } -/** @useDeclaredType */ -export type ExpressionBuilderControl = ReturnType; -function variable(mod: Module) { - return { - local: { - /** @inheritDoc X.LocalGet.localGet */ - get: LocalGet.localGet.bind(null, mod), - /** @inheritDoc X.LocalSet.localSet */ - set: LocalSet.localSet.bind(null, mod), - /** @inheritDoc X.LocalSet.localTee */ - tee: LocalSet.localTee.bind(null, mod), - }, - global: { - get: STUB, - set: STUB, - }, - } as const; -} /** @useDeclaredType */ -export type ExpressionBuilderVariable = ReturnType; - - - -/** - * @expandType ExpressionBuilderParametric - * @expandType ExpressionBuilderControl - * @expandType ExpressionBuilderVariable - */ -export type ExpressionBuilder = ( - & ExpressionBuilderParametric - & ExpressionBuilderControl - & ExpressionBuilderVariable -); -/** Methods for creating expressions in a WASM module. */ -export function expressionBuilder(mod: Module): ExpressionBuilder { - return { - ...parametric(mod), - ...control(mod), - ...variable(mod), - } as const; -} +export type ExpressionBuilderControl = ReturnType; diff --git a/ts/src/classes/expression-builders/expressionBuilder.ts b/ts/src/classes/expression-builders/expressionBuilder.ts new file mode 100644 index 00000000000..3ab92d70476 --- /dev/null +++ b/ts/src/classes/expression-builders/expressionBuilder.ts @@ -0,0 +1,48 @@ +import type { + Module, +} from "../../classes/module/Module.ts"; +import { + type ExpressionBuilderControl, + control, +} from "./control.ts"; +import { + type ExpressionBuilderGlobal, + global, +} from "./global.ts"; +import { + type ExpressionBuilderLocal, + local, +} from "./local.ts"; +import { + type ExpressionBuilderParametric, + parametric, +} from "./parametric.ts"; + + + +/** + * @expandType ExpressionBuilderParametric + * @expandType ExpressionBuilderControl + * @expandType ExpressionBuilderLocal + * @expandType ExpressionBuilderGlobal + */ +export type ExpressionBuilder = ( + & ExpressionBuilderParametric + & ExpressionBuilderControl + & { + local: ExpressionBuilderLocal, + global: ExpressionBuilderGlobal, + } +); + + + +/** Methods for building expressions in a WASM module. */ +export function expressionBuilder(mod: Module) { + return { + ...parametric(mod), + ...control(mod), + local: local(mod), + global: global(mod), + } as const; +} diff --git a/ts/src/classes/expression-builders/global.ts b/ts/src/classes/expression-builders/global.ts new file mode 100644 index 00000000000..4462ea0c85c --- /dev/null +++ b/ts/src/classes/expression-builders/global.ts @@ -0,0 +1,22 @@ +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +export function global(_mod: Module) { + return { + get: STUB, + set: STUB, + } as const; +} + + + +/** @useDeclaredType */ +export type ExpressionBuilderGlobal = ReturnType; diff --git a/ts/src/classes/expression-builders/index.ts b/ts/src/classes/expression-builders/index.ts new file mode 100644 index 00000000000..b7db750a2aa --- /dev/null +++ b/ts/src/classes/expression-builders/index.ts @@ -0,0 +1,5 @@ +export type {ExpressionBuilderParametric} from "./parametric.ts"; +export type {ExpressionBuilderControl} from "./control.ts"; +export type {ExpressionBuilderLocal} from "./local.ts"; +export type {ExpressionBuilderGlobal} from "./global.ts"; +export type {ExpressionBuilder} from "./expressionBuilder.ts"; diff --git a/ts/src/classes/expression-builders/local.ts b/ts/src/classes/expression-builders/local.ts new file mode 100644 index 00000000000..7f8b192397f --- /dev/null +++ b/ts/src/classes/expression-builders/local.ts @@ -0,0 +1,25 @@ +import type { + Module, +} from "../../classes/module/Module.ts"; +import { + LocalGet, + LocalSet, +} from "../../classes/expression/index.ts"; + + + +export function local(mod: Module) { + return { + /** @inheritDoc X.LocalGet.localGet */ + get: LocalGet.localGet.bind(null, mod), + /** @inheritDoc X.LocalSet.localSet */ + set: LocalSet.localSet.bind(null, mod), + /** @inheritDoc X.LocalSet.localTee */ + tee: LocalSet.localTee.bind(null, mod), + } as const; +} + + + +/** @useDeclaredType */ +export type ExpressionBuilderLocal = ReturnType; diff --git a/ts/src/classes/expression-builders/parametric.ts b/ts/src/classes/expression-builders/parametric.ts new file mode 100644 index 00000000000..3292c784756 --- /dev/null +++ b/ts/src/classes/expression-builders/parametric.ts @@ -0,0 +1,33 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; +import type { + Module, +} from "../../classes/module/Module.ts"; +import { + Drop, + Select, +} from "../../classes/expression/index.ts"; +import type { + ExpressionRef, +} from "../../constants.ts"; + + + +export function parametric(mod: Module) { + return { + /** Creates a no-operation `(nop)` instruction. */ + nop: (): ExpressionRef => BinaryenObj["_BinaryenNop"](mod.ptr), + /** Creates an unreachable instruction that will always trap. */ + unreachable: (): ExpressionRef => BinaryenObj["_BinaryenUnreachable"](mod.ptr), + /** @inheritDoc X.Drop.drop */ + drop: Drop.drop.bind(null, mod), + /** @inheritDoc X.Select.select */ + select: Select.select.bind(null, mod), + } as const; +} + + + +/** @useDeclaredType */ +export type ExpressionBuilderParametric = ReturnType; diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index d810abe160e..54b0515769c 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -26,12 +26,3 @@ export {LocalSet} from "./LocalSet.ts"; // ## Numeric & Vector ## // export {Const} from "./Const.ts"; - - - -export type { - ExpressionBuilder, - ExpressionBuilderParametric, - ExpressionBuilderControl, - ExpressionBuilderVariable, -} from "./expression-builders.ts"; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 56621df9db6..225efcf46fd 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -30,7 +30,7 @@ import { } from "../../utils.ts"; import { expressionBuilder, -} from "../expression/expression-builders.ts"; +} from "../../classes/expression-builders/expressionBuilder.ts"; import * as DATA_SEGMENT from "./DataSegment.ts"; import * as ELEMENT_SEGMENT from "./ElementSegment.ts"; import * as EXPORT from "./Export.ts"; From d86a1fe153f9e336ecd7848f3705e307cdd6c015 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 21:35:06 -0400 Subject: [PATCH 093/247] docs: simplify ExpressionBuilder --- ts/src/binaryen.ts | 2 +- ts/src/classes/expression-builders/control.ts | 20 ++++++-------- .../expression-builders/expressionBuilder.ts | 26 ++++--------------- ts/src/classes/expression-builders/global.ts | 6 +---- ts/src/classes/expression-builders/index.ts | 5 ---- ts/src/classes/expression-builders/local.ts | 6 +---- .../classes/expression-builders/parametric.ts | 6 +---- ts/src/classes/module/Module.ts | 11 ++++++-- 8 files changed, 26 insertions(+), 56 deletions(-) delete mode 100644 ts/src/classes/expression-builders/index.ts diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index b5fd2287899..b605d043d9d 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -15,7 +15,7 @@ export type {ElementSegment, ModuleElementSegments} from "./classes/module/Eleme export type {Import, ModuleImports} from "./classes/module/Import.ts"; export type {Export, ModuleExports} from "./classes/module/Export.ts"; export * as X from "./classes/expression/index.ts"; -export * as ExpressionBuilder from "./classes/expression-builders/index.ts"; +export type {ExpressionBuilder} from "./classes/expression-builders/expressionBuilder.ts"; export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, diff --git a/ts/src/classes/expression-builders/control.ts b/ts/src/classes/expression-builders/control.ts index a8c117bdc83..1d98c162ae0 100644 --- a/ts/src/classes/expression-builders/control.ts +++ b/ts/src/classes/expression-builders/control.ts @@ -14,6 +14,7 @@ const STUB = (..._args: readonly number[]): number => 0; +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ export function control(mod: Module) { return { /** @inheritdoc X.Block.block */ @@ -45,31 +46,26 @@ export function control(mod: Module) { // TODO: catch_all // TODO: catch_all_ref - /** @deprecated Use {@link ExpressionBuilderControl#br} instead. */ + /** @deprecated Use {@link ExpressionBuilder#br} instead. */ // @ts-expect-error break(...args) { return this.br(...args); }, - /** @deprecated Use {@link ExpressionBuilderControl#br_table} instead. */ + /** @deprecated Use {@link ExpressionBuilder#br_table} instead. */ // @ts-expect-error switch(...args) { return this.br_table(...args); }, - /** @deprecated Use {@link ExpressionBuilderControl#call_indirect} instead. */ + /** @deprecated Use {@link ExpressionBuilder#call_indirect} instead. */ // @ts-expect-error callIndirect(...args) { return this.call_indirect(...args); }, - /** @deprecated Use {@link ExpressionBuilderControl#return_call} instead. */ + /** @deprecated Use {@link ExpressionBuilder#return_call} instead. */ // @ts-expect-error returnCall(...args) { return this.return_call(...args); }, - /** @deprecated Use {@link ExpressionBuilderControl#return_call_indirect} instead. */ + /** @deprecated Use {@link ExpressionBuilder#return_call_indirect} instead. */ // @ts-expect-error returnCallIndirect(...args) { return this.return_call_indirect(...args); }, - /** @deprecated Use {@link ExpressionBuilderControl#throw_ref} instead. */ + /** @deprecated Use {@link ExpressionBuilder#throw_ref} instead. */ // @ts-expect-error rethrow(...args) { return this.throw_ref(...args); }, - /** @deprecated Use {@link ExpressionBuilderControl#try_table} instead. */ + /** @deprecated Use {@link ExpressionBuilder#try_table} instead. */ // @ts-expect-error try(...args) { return this.try_table(...args); }, } as const; } - - - -/** @useDeclaredType */ -export type ExpressionBuilderControl = ReturnType; diff --git a/ts/src/classes/expression-builders/expressionBuilder.ts b/ts/src/classes/expression-builders/expressionBuilder.ts index 3ab92d70476..8b96adb5752 100644 --- a/ts/src/classes/expression-builders/expressionBuilder.ts +++ b/ts/src/classes/expression-builders/expressionBuilder.ts @@ -2,41 +2,20 @@ import type { Module, } from "../../classes/module/Module.ts"; import { - type ExpressionBuilderControl, control, } from "./control.ts"; import { - type ExpressionBuilderGlobal, global, } from "./global.ts"; import { - type ExpressionBuilderLocal, local, } from "./local.ts"; import { - type ExpressionBuilderParametric, parametric, } from "./parametric.ts"; -/** - * @expandType ExpressionBuilderParametric - * @expandType ExpressionBuilderControl - * @expandType ExpressionBuilderLocal - * @expandType ExpressionBuilderGlobal - */ -export type ExpressionBuilder = ( - & ExpressionBuilderParametric - & ExpressionBuilderControl - & { - local: ExpressionBuilderLocal, - global: ExpressionBuilderGlobal, - } -); - - - /** Methods for building expressions in a WASM module. */ export function expressionBuilder(mod: Module) { return { @@ -46,3 +25,8 @@ export function expressionBuilder(mod: Module) { global: global(mod), } as const; } + + + +/** @useDeclaredType */ +export type ExpressionBuilder = ReturnType; diff --git a/ts/src/classes/expression-builders/global.ts b/ts/src/classes/expression-builders/global.ts index 4462ea0c85c..0e5aa882125 100644 --- a/ts/src/classes/expression-builders/global.ts +++ b/ts/src/classes/expression-builders/global.ts @@ -9,14 +9,10 @@ const STUB = (..._args: readonly number[]): number => 0; +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#variable-instructions */ export function global(_mod: Module) { return { get: STUB, set: STUB, } as const; } - - - -/** @useDeclaredType */ -export type ExpressionBuilderGlobal = ReturnType; diff --git a/ts/src/classes/expression-builders/index.ts b/ts/src/classes/expression-builders/index.ts deleted file mode 100644 index b7db750a2aa..00000000000 --- a/ts/src/classes/expression-builders/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type {ExpressionBuilderParametric} from "./parametric.ts"; -export type {ExpressionBuilderControl} from "./control.ts"; -export type {ExpressionBuilderLocal} from "./local.ts"; -export type {ExpressionBuilderGlobal} from "./global.ts"; -export type {ExpressionBuilder} from "./expressionBuilder.ts"; diff --git a/ts/src/classes/expression-builders/local.ts b/ts/src/classes/expression-builders/local.ts index 7f8b192397f..e49202b164e 100644 --- a/ts/src/classes/expression-builders/local.ts +++ b/ts/src/classes/expression-builders/local.ts @@ -8,6 +8,7 @@ import { +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#variable-instructions */ export function local(mod: Module) { return { /** @inheritDoc X.LocalGet.localGet */ @@ -18,8 +19,3 @@ export function local(mod: Module) { tee: LocalSet.localTee.bind(null, mod), } as const; } - - - -/** @useDeclaredType */ -export type ExpressionBuilderLocal = ReturnType; diff --git a/ts/src/classes/expression-builders/parametric.ts b/ts/src/classes/expression-builders/parametric.ts index 3292c784756..70598253eec 100644 --- a/ts/src/classes/expression-builders/parametric.ts +++ b/ts/src/classes/expression-builders/parametric.ts @@ -14,6 +14,7 @@ import type { +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#parametric-instructions */ export function parametric(mod: Module) { return { /** Creates a no-operation `(nop)` instruction. */ @@ -26,8 +27,3 @@ export function parametric(mod: Module) { select: Select.select.bind(null, mod), } as const; } - - - -/** @useDeclaredType */ -export type ExpressionBuilderParametric = ReturnType; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 225efcf46fd..ff82c5ad9de 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -29,6 +29,7 @@ import { strToStack, } from "../../utils.ts"; import { + type ExpressionBuilder, expressionBuilder, } from "../../classes/expression-builders/expressionBuilder.ts"; import * as DATA_SEGMENT from "./DataSegment.ts"; @@ -142,10 +143,16 @@ export class Module { * ```ts * const mod = new Module(); * const {x} = mod; - * x.i32.add(); + * x.drop(x.i32.add(x.i32.const(3), x.i32.const(5))); * ``` + * or to free its properties: + * ```ts + * const {i32, drop} = mod.x; + * drop(i32.add(i32.const(3), i32.const(5))); + * ``` + * @see {@link ExpressionBuilder} */ - readonly x = expressionBuilder(this); + readonly x: ExpressionBuilder = expressionBuilder(this); // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html From ae6921a40cc9a58e891c08fd874bfbcc0e8ac6ba Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 22:39:07 -0400 Subject: [PATCH 094/247] docs: API Overview: rewrite Expression Building sections --- ts/docs/API-Overview.md | 66 ++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index f2b42a3e2ed..58c5cf95fa8 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -134,36 +134,32 @@ Objects: ## Expression Building -Each of these methods returns an `ExpressionRef`. - -### Parametric Instructions -- `Module#x.nop()` -- `Module#x.unreachable()` -- `Module#x.drop(value: ExpressionRef)` -- `Module#x.select(ifTrue: ExpressionRef, ifFalse: ExpressionRef)` - -### Control Instructions -- `Module#x.block(name: string | null, children: readonly ExpressionRef[], resultType?: Type)` -- `Module#x.loop(name: string, body: ExpressionRef)` -- TODO: `Module#x.if()` -- `Module#x.br(label: string, condition?: ExpressionRef, value?: ExpressionRef)` -- `Module#x.br_if(label: string, condition: ExpressionRef, value?: ExpressionRef)` - -### Variable Instructions -- `Module#x.local.get(index: number, typ: Type)` -- `Module#x.local.set(index: number, value: ExpressionRef)` -- `Module#x.local.tee(index: number, value: ExpressionRef, typ: Type)` -- TODO: `Module#x.global.get()` -- TODO: `Module#x.global.set()` - -### Table Instructions -### Memory Instructions -### Reference Instructions -### Aggregate Instructions -### Numeric Instructions -### Vector Instructions -### Atomic Instructions -### String Instructions +Each of these functions is bound to `Module#x` (of type `ExpressionBuilder`) and returns an `ExpressionRef`. +See the generated **ExpressionBuilder** docs for all available functions and details. + +- Parametric Instructions + - `.nop()` + - `.unreachable()` + - `.drop()` + - `.select()` +- Control Instructions + - conditionals, blocks, loops, and breaking (“branching”) + - `.if()` + - `.block()` + - `.loop()` + - `.br()`, `.br_if()`, `.br_table()` + - `.br_on_null()`, `.br_on_non_null()`, `.br_on_cast()`, `.br_on_cast_fail()` + - function calls, returns, throws, and catching + - `.call()`, `.call_ref()`, `.call_indirect()` + - `.return()`, `.return_call()`, `.return_call_ref()`, `.return_call_indirect()` + - `.throw()`, `.throw_ref()`, `.try_table()` + - ~~`.catch()`, `.catch_ref()`, `.catch_all()`, `.catch_all_ref()`~~; ⛔️ not yet supported +- local and global variables + - `.local.get()` + - `.local.set()` + - `.local.tee()` + - `.global.get()` + - `.global.set()` @@ -255,6 +251,16 @@ Some of `Module`’s instance methods have been converted into getters/setters: `Module#copyExpression(expr)` has been moved to the global function `copyExpression(expr, mod)` where it lives alongside `getExpressionInfo` et al. +### Expression Builders +- `ExpressionBuilder#break()` → `ExpressionBuilder#br()` +- `ExpressionBuilder#switch()` → `ExpressionBuilder#br_table()` +- `ExpressionBuilder#callIndirect()` → `ExpressionBuilder#call_indirect()` +- `ExpressionBuilder#returnCall()` → `ExpressionBuilder#return_call()` +- `ExpressionBuilder#returnCallIndirect()` → `ExpressionBuilder#return_call_indirect()` +- `ExpressionBuilder#rethrow()` → `ExpressionBuilder#throw_ref()` +- `ExpressionBuilder#try()` → `ExpressionBuilder#try_table()` + + ### Settings All optimization pass settings have been moved to the global `settings` object. From fe20adc03d3779f8c161e8c1bb7550fa47f0f8f2 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 3 May 2026 23:01:32 -0400 Subject: [PATCH 095/247] feat: stub more expression builders --- ts/docs/API-Overview.md | 23 ++++++++++ ts/src/classes/expression-builders/array.ts | 35 ++++++++++++++ .../expression-builders/expressionBuilder.ts | 46 +++++++++++++++++++ ts/src/classes/expression-builders/i31.ts | 18 ++++++++ ts/src/classes/expression-builders/memory.ts | 33 +++++++++++++ ts/src/classes/expression-builders/ref.ts | 23 ++++++++++ ts/src/classes/expression-builders/struct.ts | 27 +++++++++++ ts/src/classes/expression-builders/table.ts | 23 ++++++++++ 8 files changed, 228 insertions(+) create mode 100644 ts/src/classes/expression-builders/array.ts create mode 100644 ts/src/classes/expression-builders/i31.ts create mode 100644 ts/src/classes/expression-builders/memory.ts create mode 100644 ts/src/classes/expression-builders/ref.ts create mode 100644 ts/src/classes/expression-builders/struct.ts create mode 100644 ts/src/classes/expression-builders/table.ts diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 58c5cf95fa8..81886b47fb8 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -137,6 +137,8 @@ Objects: Each of these functions is bound to `Module#x` (of type `ExpressionBuilder`) and returns an `ExpressionRef`. See the generated **ExpressionBuilder** docs for all available functions and details. +Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`”. + - Parametric Instructions - `.nop()` - `.unreachable()` @@ -160,6 +162,25 @@ See the generated **ExpressionBuilder** docs for all available functions and det - `.local.tee()` - `.global.get()` - `.global.set()` +- tables and memories + - `.table.get()`, `.table.set()`, `.table.size()`, `.table.grow()` + - `.memory.size()`, `.memory.grow()`, `.memory.fill()`, `.memory.copy()`, `.memory.init()`, + - `.elem.drop()`, `.data.drop()` +- references + - `.ref.func()`, `.ref.null()`, `.ref.is_null()`, `.ref.as_non_null()`, `.ref.eq()`, `.ref.test()`, `.ref.cast()` + - `.ref.i31()`, `i31.get_{s,u}()` + - ~~`.extern.convert_any()`, `.any.convert_extern()`~~; ⛔️ not yet supported +- structs and arrays + - `.struct.new()`, `.struct.new_default()` + - `.struct.get()`, `.struct.get_{s,u}()` + - `.struct.set()` + - `.array.new()`, `.array.new_default()`, `.array.new_fixed()`, `.array.new_data()`, `.array.new_elem()` + - `.array.get()`, `.array.get_{s,u}()` + - `.array.set()` + - `.array.len()` + - `.array.fill()` + - `.array.copy()` + - `.array.init_data()`, `.array.init_elem()` @@ -260,6 +281,8 @@ Some of `Module`’s instance methods have been converted into getters/setters: - `ExpressionBuilder#rethrow()` → `ExpressionBuilder#throw_ref()` - `ExpressionBuilder#try()` → `ExpressionBuilder#try_table()` +`.{struct,array}.get()` no longer take the `isSigned` argument. For packed signed/unsigned types, use `.{struct,array}.get_{s,u}()` respectively. + ### Settings All optimization pass settings have been moved to the global `settings` object. diff --git a/ts/src/classes/expression-builders/array.ts b/ts/src/classes/expression-builders/array.ts new file mode 100644 index 00000000000..bff8b3c2583 --- /dev/null +++ b/ts/src/classes/expression-builders/array.ts @@ -0,0 +1,35 @@ +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +export function array(_mod: Module) { + return { + new: STUB, + new_default: STUB, + new_fixed: STUB, + new_data: STUB, + new_elem: STUB, + /** + * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. + * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. + */ + get: (_ref: number, _index: number, _type: number, deprecated_isSigned?: boolean) => deprecated_isSigned === undefined + ? STUB + : deprecated_isSigned ? /* get_s */ STUB : /* get_u */ STUB, + get_s: STUB, + get_u: STUB, + set: STUB, + len: STUB, + fill: STUB, + copy: STUB, + init_data: STUB, + init_elem: STUB, + } as const; +} diff --git a/ts/src/classes/expression-builders/expressionBuilder.ts b/ts/src/classes/expression-builders/expressionBuilder.ts index 8b96adb5752..8cd8dd67eff 100644 --- a/ts/src/classes/expression-builders/expressionBuilder.ts +++ b/ts/src/classes/expression-builders/expressionBuilder.ts @@ -1,28 +1,74 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + array, +} from "./array.ts"; import { control, } from "./control.ts"; import { global, } from "./global.ts"; +import { + i31, +} from "./i31.ts"; import { local, } from "./local.ts"; +import { + memory, +} from "./memory.ts"; import { parametric, } from "./parametric.ts"; +import { + ref, +} from "./ref.ts"; +import { + struct, +} from "./struct.ts"; +import { + table, +} from "./table.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + /** Methods for building expressions in a WASM module. */ export function expressionBuilder(mod: Module) { + /* + * Each property of this returned object should be either: + * + * - a spread function call (`...parametric(mod)`), which “splats” its properties into the top level, or + * - a property with a function call value (`local: local(mod)`), which sets the object to a property for nesting, or + * - a property set to a singleton object (`elem: {drop: () => {...}}`). + * + * To keep things clean and concise, stick with the above convention. + * If any object literal has more than one property, move it out into a separate function. + */ return { ...parametric(mod), ...control(mod), local: local(mod), global: global(mod), + table: table(mod), + elem: {drop: STUB}, + memory: memory(mod), + data: {drop: STUB}, + ref: ref(mod), + struct: struct(mod), + array: array(mod), + i31: i31(mod), + // TODO: extern + // TODO: any } as const; } diff --git a/ts/src/classes/expression-builders/i31.ts b/ts/src/classes/expression-builders/i31.ts new file mode 100644 index 00000000000..cddb2ffc06f --- /dev/null +++ b/ts/src/classes/expression-builders/i31.ts @@ -0,0 +1,18 @@ +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#aggregate-instructions */ +export function i31(_mod: Module) { + return { + get_s: STUB, + get_u: STUB, + } as const; +} diff --git a/ts/src/classes/expression-builders/memory.ts b/ts/src/classes/expression-builders/memory.ts new file mode 100644 index 00000000000..1dc65246484 --- /dev/null +++ b/ts/src/classes/expression-builders/memory.ts @@ -0,0 +1,33 @@ +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +function memoryAtomic(_mod: Module) { + return { + notify: STUB, + wait32: STUB, + wait64: STUB, + } as const; +} + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions */ +export function memory(mod: Module) { + return { + size: STUB, + grow: STUB, + fill: STUB, + copy: STUB, + init: STUB, + /** @experimental */ + atomic: memoryAtomic(mod), + } as const; +} diff --git a/ts/src/classes/expression-builders/ref.ts b/ts/src/classes/expression-builders/ref.ts new file mode 100644 index 00000000000..1782b242262 --- /dev/null +++ b/ts/src/classes/expression-builders/ref.ts @@ -0,0 +1,23 @@ +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +export function ref(_mod: Module) { + return { + func: STUB, + null: STUB, + is_null: STUB, + as_non_null: STUB, + eq: STUB, + test: STUB, + cast: STUB, + i31: STUB, + } as const; +} diff --git a/ts/src/classes/expression-builders/struct.ts b/ts/src/classes/expression-builders/struct.ts new file mode 100644 index 00000000000..ac5fe0f0a9e --- /dev/null +++ b/ts/src/classes/expression-builders/struct.ts @@ -0,0 +1,27 @@ +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +export function struct(_mod: Module) { + return { + new: STUB, + new_default: STUB, + /** + * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. + * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. + */ + get: (_index: number, _ref: number, _type: number, deprecated_isSigned?: boolean) => deprecated_isSigned === undefined + ? STUB + : deprecated_isSigned ? /* get_s */ STUB : /* get_u */ STUB, + get_s: STUB, + get_u: STUB, + set: STUB, + } as const; +} diff --git a/ts/src/classes/expression-builders/table.ts b/ts/src/classes/expression-builders/table.ts new file mode 100644 index 00000000000..b738743d2ff --- /dev/null +++ b/ts/src/classes/expression-builders/table.ts @@ -0,0 +1,23 @@ +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#table-instructions */ +export function table(_mod: Module) { + return { + get: STUB, + set: STUB, + size: STUB, + grow: STUB, + // TODO: fill + // TODO: copy + // TODO: init + } as const; +} From 0f794d637919d11bca6f150c4e5570a35f2d7965 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 01:25:02 -0400 Subject: [PATCH 096/247] feat: stub numerics --- ts/docs/API-Overview.md | 101 ++++++++++++++---- .../expression-builders/expressionBuilder.ts | 20 ++++ ts/src/classes/expression-builders/f32.ts | 64 +++++++++++ ts/src/classes/expression-builders/f64.ts | 64 +++++++++++ ts/src/classes/expression-builders/i32.ts | 89 +++++++++++++++ ts/src/classes/expression-builders/i64.ts | 93 ++++++++++++++++ ts/src/classes/expression-builders/tuple.ts | 17 +++ ts/src/classes/expression/Operation.ts | 61 ++++++----- ts/src/classes/module/ElementSegment.ts | 2 +- 9 files changed, 464 insertions(+), 47 deletions(-) create mode 100644 ts/src/classes/expression-builders/f32.ts create mode 100644 ts/src/classes/expression-builders/f64.ts create mode 100644 ts/src/classes/expression-builders/i32.ts create mode 100644 ts/src/classes/expression-builders/i64.ts create mode 100644 ts/src/classes/expression-builders/tuple.ts diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 81886b47fb8..5d8ecf97df0 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -144,18 +144,17 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.unreachable()` - `.drop()` - `.select()` -- Control Instructions - - conditionals, blocks, loops, and breaking (“branching”) - - `.if()` - - `.block()` - - `.loop()` - - `.br()`, `.br_if()`, `.br_table()` - - `.br_on_null()`, `.br_on_non_null()`, `.br_on_cast()`, `.br_on_cast_fail()` - - function calls, returns, throws, and catching - - `.call()`, `.call_ref()`, `.call_indirect()` - - `.return()`, `.return_call()`, `.return_call_ref()`, `.return_call_indirect()` - - `.throw()`, `.throw_ref()`, `.try_table()` - - ~~`.catch()`, `.catch_ref()`, `.catch_all()`, `.catch_all_ref()`~~; ⛔️ not yet supported +- conditionals, blocks, loops, and breaking (“branching”) + - `.if()` + - `.block()` + - `.loop()` + - `.br()`, `.br_if()`, `.br_table()` + - `.br_on_null()`, `.br_on_non_null()`, `.br_on_cast()`, `.br_on_cast_fail()` +- function calls, returns, throws, and catching + - `.call()`, `.call_ref()`, `.call_indirect()` + - `.return()`, `.return_call()`, `.return_call_ref()`, `.return_call_indirect()` + - `.throw()`, `.throw_ref()`, `.try_table()` + - ~~`.catch()`, `.catch_ref()`, `.catch_all()`, `.catch_all_ref()`~~; ⛔️ not yet supported - local and global variables - `.local.get()` - `.local.set()` @@ -181,6 +180,31 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.array.fill()` - `.array.copy()` - `.array.init_data()`, `.array.init_elem()` +- integers + - `.{i32,i64}.const` + - `.{i31,i32}.clz`, `.{i32,i64}.ctz`, `.{i32,i64}.popcnt` + - `.{i32,i64}.extend8_s`, `.{i32,i64}.extend16_s`, `.i64.extend32_s` + - `.{i31,i32}.add`, `.{i32,i64}.sub`, `.{i32,i64}.mul`, `.{i31,i32}.div_{s,u}`, `.{i32,i64}.rem_{s,u}` + - `.{i31,i32}.and`, `.{i32,i64}.or`, `.{i32,i64}.xor`, `.{i31,i32}.shl`, `.{i31,i32}.shr{s,u}`, `.{i32,i64}.rotl`, `.{i32,i64}.rotr` + - `.{i32,i64}.eqz` + - `.{i32,i64}.eq`, `.{i32,i64}.ne` + - `.{i32,i64}.lt_{s,u}`, `.{i32,i64}.gt_{s,u}`, `.{i32,i64}.le_{s,u}`, `.{i32,i64}.ge_{s,u}` + - `.i32.wrap_i64()`, `.i64.extend_i32_{s,u}()` + - `.i32.trunc_f32_{s,u}()`, `.i32.trunc_f64_{s,u}()` + - `.i64.trunc_f32_{s,u}()`, `.i64.trunc_f64_{s,u}()` + - `.i32.trunc_sat_f32_{s,u}()`, `.i32.trunc_sat_f64_{s,u}()` + - `.i64.trunc_sat_f32_{s,u}()`, `.i64.trunc_sat_f64_{s,u}()` + - `.i32.reinterpret_f32()`, `.i64.reinterpret_f64()` +- floats + - `.{f32,f64}.const` + - `.{f32,f64}.abs`, `.{f32,f64}.neg`, `.{f32,f64}.sqrt`, `.{f32,f64}.ceil`, `.{f32,f64}.floor`, `.{f32,f64}.trunc`, `.{f32,f64}.nearest` + - `.{f32,f64}.add`, `.{f32,f64}.sub`, `.{f32,f64}.mul`, `.{f32,f64}.div`, `.{f32,f64}.min`, `.{f32,f64}.max`, `.{f32,f64}.copysign` + - `.{f32,f64}.eq`, `.{f32,f64}.lt`, `.{f32,f64}.gt`, `.{f32,f64}.le`, `.{f32,f64}.ge` + - `.{f32,f64}.convert_i32_s`, `.{f32,f64}.convert_i32_u`, `.{f32,f64}.convert_i64_s`, `.{f32,f64}.convert_i64_u` + - `.f32.demote_f64`, `.f64.promote_f32` +- tuples 🌱 (Binaryen-specific) + - `.tuple.make()` + - `.tuple.extract()` @@ -273,16 +297,55 @@ Some of `Module`’s instance methods have been converted into getters/setters: ### Expression Builders -- `ExpressionBuilder#break()` → `ExpressionBuilder#br()` -- `ExpressionBuilder#switch()` → `ExpressionBuilder#br_table()` -- `ExpressionBuilder#callIndirect()` → `ExpressionBuilder#call_indirect()` -- `ExpressionBuilder#returnCall()` → `ExpressionBuilder#return_call()` -- `ExpressionBuilder#returnCallIndirect()` → `ExpressionBuilder#return_call_indirect()` -- `ExpressionBuilder#rethrow()` → `ExpressionBuilder#throw_ref()` -- `ExpressionBuilder#try()` → `ExpressionBuilder#try_table()` +Note: To improve readability, assume all methods written in this section are bound to an Expression Builder (an object returned by `Module#x`). + +- `.break()` → `.br()` +- `.switch()` → `.br_table()` +- `.callIndirect()` → `.call_indirect()` +- `.returnCall()` → `.return_call()` +- `.returnCallIndirect()` → `.return_call_indirect()` +- `.rethrow()` → `.throw_ref()` +- `.try()` → `.try_table()` `.{struct,array}.get()` no longer take the `isSigned` argument. For packed signed/unsigned types, use `.{struct,array}.get_{s,u}()` respectively. +- `.i32.wrap()` → `.i32.wrap_i64()` +- `.i32.trunc_s.f32()` → `.i32.trunc_f32_s()` +- `.i32.trunc_s.f64()` → `.i32.trunc_f64_s()` +- `.i32.trunc_u.f32()` → `.i32.trunc_f32_u()` +- `.i32.trunc_u.f64()` → `.i32.trunc_f64_u()` +- `.i32.trunc_s_sat.f32()` → `.i32.trunc_sat_f32_s()` +- `.i32.trunc_s_sat.f64()` → `.i32.trunc_sat_f64_s()` +- `.i32.trunc_u_sat.f32()` → `.i32.trunc_sat_f32_u()` +- `.i32.trunc_u_sat.f64()` → `.i32.trunc_sat_f64_u()` +- `.reinterpret()` → `.reinterpret_f32()` + +- `.i64.extend_s()` → `.i64.extend_i32_s()` +- `.i64.extend_u()` → `.i64.extend_i32_u()` +- `.i64.trunc_s.f32()` → `.i64.trunc_f32_s()` +- `.i64.trunc_s.f64()` → `.i64.trunc_f64_s()` +- `.i64.trunc_u.f32()` → `.i64.trunc_f32_u()` +- `.i64.trunc_u.f64()` → `.i64.trunc_f64_u()` +- `.i64.trunc_s_sat.f32()` → `.i64.trunc_sat_f32_s()` +- `.i64.trunc_s_sat.f64()` → `.i64.trunc_sat_f64_s()` +- `.i64.trunc_u_sat.f32()` → `.i64.trunc_sat_f32_u()` +- `.i64.trunc_u_sat.f64()` → `.i64.trunc_sat_f64_u()` +- `.reinterpret()` → `.reinterpret_f64()` + +- `.f32.convert_s.i32()` → `.f32.convert_i32_s()` +- `.f32.convert_s.i64()` → `.f32.convert_i64_s()` +- `.f32.convert_u.i32()` → `.f32.convert_i32_u()` +- `.f32.convert_u.i64()` → `.f32.convert_i64_u()` +- `.f32.reinterpret()` → `.f32.reinterpret_i32()` +- `.f32.demote()` → `.f32.demote_f64()` + +- `.f64.convert_s.i32()` → `.f64.convert_i32_s()` +- `.f64.convert_s.i64()` → `.f64.convert_i64_s()` +- `.f64.convert_u.i32()` → `.f64.convert_i32_u()` +- `.f64.convert_u.i64()` → `.f64.convert_i64_u()` +- `.f64.reinterpret()` → `.f64.reinterpret_i64()` +- `.f64.promote()` → `.f64.promote_f32()` + ### Settings All optimization pass settings have been moved to the global `settings` object. diff --git a/ts/src/classes/expression-builders/expressionBuilder.ts b/ts/src/classes/expression-builders/expressionBuilder.ts index 8cd8dd67eff..8980c4f25d8 100644 --- a/ts/src/classes/expression-builders/expressionBuilder.ts +++ b/ts/src/classes/expression-builders/expressionBuilder.ts @@ -7,12 +7,24 @@ import { import { control, } from "./control.ts"; +import { + f32, +} from "./f32.ts"; +import { + f64, +} from "./f64.ts"; import { global, } from "./global.ts"; import { i31, } from "./i31.ts"; +import { + i32, +} from "./i32.ts"; +import { + i64, +} from "./i64.ts"; import { local, } from "./local.ts"; @@ -31,6 +43,9 @@ import { import { table, } from "./table.ts"; +import { + tuple, +} from "./tuple.ts"; @@ -69,6 +84,11 @@ export function expressionBuilder(mod: Module) { i31: i31(mod), // TODO: extern // TODO: any + i32: i32(mod), + i64: i64(mod), + f32: f32(mod), + f64: f64(mod), + tuple: tuple(mod), } as const; } diff --git a/ts/src/classes/expression-builders/f32.ts b/ts/src/classes/expression-builders/f32.ts new file mode 100644 index 00000000000..9763e38ada6 --- /dev/null +++ b/ts/src/classes/expression-builders/f32.ts @@ -0,0 +1,64 @@ +import { + consoleWarn, +} from "../../lib.ts"; +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ +export function f32(_mod: Module) { + return { + const: STUB, + + abs: STUB, + neg: STUB, + sqrt: STUB, + ceil: STUB, + floor: STUB, + trunc: STUB, + nearest: STUB, + + add: STUB, + sub: STUB, + mul: STUB, + div: STUB, + min: STUB, + max: STUB, + copysign: STUB, + + eq: STUB, + ne: STUB, + lt: STUB, + gt: STUB, + le: STUB, + ge: STUB, + + convert_i32_s: STUB, + convert_i32_u: STUB, + convert_i64_s: STUB, + convert_i64_u: STUB, + reinterpret_i32: STUB, + + demote_f64: STUB, + + convert_s: { + /** @deprecated Use `.convert_i32_s()` instead. */ i32: STUB, + /** @deprecated Use `.convert_i64_s()` instead. */ i64: STUB, + }, + convert_u: { + /** @deprecated Use `.convert_i32_u()` instead. */ i32: STUB, + /** @deprecated Use `.convert_i64_u()` instead. */ i64: STUB, + }, + // @ts-expect-error + /** @deprecated Use `.reinterpret_i32()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_i32()` instead."); return this.reinterpret_i32(...args); }, + // @ts-expect-error + /** @deprecated Use `.demote_f64()` instead. */ demote(...args) { consoleWarn("`.demote()` is deprecated; use `.demote_f64()` instead."); return this.demote_f64(...args); }, + } as const; +} diff --git a/ts/src/classes/expression-builders/f64.ts b/ts/src/classes/expression-builders/f64.ts new file mode 100644 index 00000000000..5cbb5454f80 --- /dev/null +++ b/ts/src/classes/expression-builders/f64.ts @@ -0,0 +1,64 @@ +import { + consoleWarn, +} from "../../lib.ts"; +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ +export function f64(_mod: Module) { + return { + const: STUB, + + abs: STUB, + neg: STUB, + sqrt: STUB, + ceil: STUB, + floor: STUB, + trunc: STUB, + nearest: STUB, + + add: STUB, + sub: STUB, + mul: STUB, + div: STUB, + min: STUB, + max: STUB, + copysign: STUB, + + eq: STUB, + ne: STUB, + lt: STUB, + gt: STUB, + le: STUB, + ge: STUB, + + convert_i32_s: STUB, + convert_i32_u: STUB, + convert_i64_s: STUB, + convert_i64_u: STUB, + reinterpret_f64: STUB, + + prmote_f32: STUB, + + convert_s: { + /** @deprecated Use `.convert_i32_s()` instead. */ i32: STUB, + /** @deprecated Use `.convert_i64_s()` instead. */ i64: STUB, + }, + convert_u: { + /** @deprecated Use `.convert_i32_u()` instead. */ i32: STUB, + /** @deprecated Use `.convert_i64_u()` instead. */ i64: STUB, + }, + // @ts-expect-error + /** @deprecated Use `.reinterpret_i64()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_i64()` instead."); return this.reinterpret_i64(...args); }, + // @ts-expect-error + /** @deprecated Use `.promote_f32()` instead. */ promote(...args) { consoleWarn("`.promote()` is deprecated; use `.promote_f32()` instead."); return this.promote_f32(...args); }, + } as const; +} diff --git a/ts/src/classes/expression-builders/i32.ts b/ts/src/classes/expression-builders/i32.ts new file mode 100644 index 00000000000..6c223846523 --- /dev/null +++ b/ts/src/classes/expression-builders/i32.ts @@ -0,0 +1,89 @@ +import { + consoleWarn, +} from "../../lib.ts"; +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ +export function i32(_mod: Module) { + return { + const: STUB, + + clz: STUB, + ctz: STUB, + popcnt: STUB, + extend8_s: STUB, + extend16_s: STUB, + + add: STUB, + sub: STUB, + mul: STUB, + div_s: STUB, + div_u: STUB, + rem_s: STUB, + rem_u: STUB, + + and: STUB, + or: STUB, + xor: STUB, + shl: STUB, + shr_s: STUB, + shr_u: STUB, + rotl: STUB, + rotr: STUB, + + eqz: STUB, + + eq: STUB, + ne: STUB, + lt_s: STUB, + lt_u: STUB, + gt_s: STUB, + gt_u: STUB, + le_s: STUB, + le_u: STUB, + ge_s: STUB, + ge_u: STUB, + + wrap_i64: STUB, + + trunc_f32_s: STUB, + trunc_f32_u: STUB, + trunc_f64_s: STUB, + trunc_f64_u: STUB, + trunc_sat_f32_s: STUB, + trunc_sat_f32_u: STUB, + trunc_sat_f64_s: STUB, + trunc_sat_f64_u: STUB, + reinterpret_f32: STUB, + + // @ts-expect-error + /** @deprecated Use `.wrap_i64()` instead. */ wrap(...args) { consoleWarn("`.wrap()` is deprecated; use `.wrap_i64()` instead."); return this.wrap_i64(...args); }, + trunc_s: { + /** @deprecated Use `.trunc_f32_s()` instead. */ f32: STUB, + /** @deprecated Use `.trunc_f64_s()` instead. */ f64: STUB, + }, + trunc_u: { + /** @deprecated Use `.trunc_f32_u()` instead. */ f32: STUB, + /** @deprecated Use `.trunc_f64_u()` instead. */ f64: STUB, + }, + trunc_s_sat: { + /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: STUB, + /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: STUB, + }, + trunc_u_sat: { + /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: STUB, + /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: STUB, + }, + // @ts-expect-error + /** @deprecated Use `.reinterpret_f32()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_f32()` instead."); return this.reinterpret_f32(...args); }, + } as const; +} diff --git a/ts/src/classes/expression-builders/i64.ts b/ts/src/classes/expression-builders/i64.ts new file mode 100644 index 00000000000..3091e2160de --- /dev/null +++ b/ts/src/classes/expression-builders/i64.ts @@ -0,0 +1,93 @@ +import { + consoleWarn, +} from "../../lib.ts"; +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ +export function i64(_mod: Module) { + return { + const: STUB, + + clz: STUB, + ctz: STUB, + popcnt: STUB, + extend8_s: STUB, + extend16_s: STUB, + extend32_s: STUB, + + add: STUB, + sub: STUB, + mul: STUB, + div_s: STUB, + div_u: STUB, + rem_s: STUB, + rem_u: STUB, + + and: STUB, + or: STUB, + xor: STUB, + shl: STUB, + shr_s: STUB, + shr_u: STUB, + rotl: STUB, + rotr: STUB, + + eqz: STUB, + + eq: STUB, + ne: STUB, + lt_s: STUB, + lt_u: STUB, + gt_s: STUB, + gt_u: STUB, + le_s: STUB, + le_u: STUB, + ge_s: STUB, + ge_u: STUB, + + extend_i32_s: STUB, + extend_i32_u: STUB, + + trunc_f32_s: STUB, + trunc_f32_u: STUB, + trunc_f64_s: STUB, + trunc_f64_u: STUB, + trunc_sat_f32_s: STUB, + trunc_sat_f32_u: STUB, + trunc_sat_f64_s: STUB, + trunc_sat_f64_u: STUB, + reinterpret_f64: STUB, + + // @ts-expect-error + /** @deprecated Use `.extend_i32_s()` instead. */ extend_s(...args) { consoleWarn("`.extend_s()` is deprecated; use `.extend_i32_s()` instead."); return this.extend_i32_s(...args); }, + // @ts-expect-error + /** @deprecated Use `.extend_i32_u()` instead. */ extend_u(...args) { consoleWarn("`.extend_u()` is deprecated; use `.extend_i32_u()` instead."); return this.extend_i32_u(...args); }, + trunc_s: { + /** @deprecated Use `.trunc_f32_s()` instead. */ f32: STUB, + /** @deprecated Use `.trunc_f64_s()` instead. */ f64: STUB, + }, + trunc_u: { + /** @deprecated Use `.trunc_f32_u()` instead. */ f32: STUB, + /** @deprecated Use `.trunc_f64_u()` instead. */ f64: STUB, + }, + trunc_s_sat: { + /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: STUB, + /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: STUB, + }, + trunc_u_sat: { + /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: STUB, + /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: STUB, + }, + // @ts-expect-error + /** @deprecated Use `.reinterpret_f64()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_f64()` instead."); return this.reinterpret_f64(...args); }, + } as const; +} diff --git a/ts/src/classes/expression-builders/tuple.ts b/ts/src/classes/expression-builders/tuple.ts new file mode 100644 index 00000000000..9897c056dee --- /dev/null +++ b/ts/src/classes/expression-builders/tuple.ts @@ -0,0 +1,17 @@ +import type { + Module, +} from "../module/Module.ts"; + + + +/** Placeholder. */ +const STUB = (..._args: readonly number[]): number => 0; + + + +export function tuple(_mod: Module) { + return { + make: STUB, + extract: STUB, + } as const; +} diff --git a/ts/src/classes/expression/Operation.ts b/ts/src/classes/expression/Operation.ts index 03ada68805e..f87748e0f95 100644 --- a/ts/src/classes/expression/Operation.ts +++ b/ts/src/classes/expression/Operation.ts @@ -45,6 +45,19 @@ export enum Operation { RefAsExternConvertAny = BinaryenObj["_BinaryenRefAsExternConvertAny"](), // ### Integer Operations ### // + // #### unop #### // + ClzInt32 = BinaryenObj["_BinaryenClzInt32"](), + ClzInt64 = BinaryenObj["_BinaryenClzInt64"](), + CtzInt32 = BinaryenObj["_BinaryenCtzInt32"](), + CtzInt64 = BinaryenObj["_BinaryenCtzInt64"](), + PopcntInt32 = BinaryenObj["_BinaryenPopcntInt32"](), + PopcntInt64 = BinaryenObj["_BinaryenPopcntInt64"](), + ExtendS8Int32 = BinaryenObj["_BinaryenExtendS8Int32"](), + ExtendS8Int64 = BinaryenObj["_BinaryenExtendS8Int64"](), + ExtendS16Int32 = BinaryenObj["_BinaryenExtendS16Int32"](), + ExtendS16Int64 = BinaryenObj["_BinaryenExtendS16Int64"](), + ExtendS32Int64 = BinaryenObj["_BinaryenExtendS32Int64"](), + // #### binop #### // AddInt32 = BinaryenObj["_BinaryenAddInt32"](), AddInt64 = BinaryenObj["_BinaryenAddInt64"](), SubInt32 = BinaryenObj["_BinaryenSubInt32"](), @@ -75,14 +88,10 @@ export enum Operation { RotLInt64 = BinaryenObj["_BinaryenRotLInt64"](), RotRInt32 = BinaryenObj["_BinaryenRotRInt32"](), RotRInt64 = BinaryenObj["_BinaryenRotRInt64"](), - ClzInt32 = BinaryenObj["_BinaryenClzInt32"](), - ClzInt64 = BinaryenObj["_BinaryenClzInt64"](), - CtzInt32 = BinaryenObj["_BinaryenCtzInt32"](), - CtzInt64 = BinaryenObj["_BinaryenCtzInt64"](), - PopcntInt32 = BinaryenObj["_BinaryenPopcntInt32"](), - PopcntInt64 = BinaryenObj["_BinaryenPopcntInt64"](), + // #### testop #### // EqZInt32 = BinaryenObj["_BinaryenEqZInt32"](), EqZInt64 = BinaryenObj["_BinaryenEqZInt64"](), + // #### relop #### // EqInt32 = BinaryenObj["_BinaryenEqInt32"](), EqInt64 = BinaryenObj["_BinaryenEqInt64"](), NeInt32 = BinaryenObj["_BinaryenNeInt32"](), @@ -103,27 +112,9 @@ export enum Operation { GeSInt64 = BinaryenObj["_BinaryenGeSInt64"](), GeUInt32 = BinaryenObj["_BinaryenGeUInt32"](), GeUInt64 = BinaryenObj["_BinaryenGeUInt64"](), - ExtendS8Int32 = BinaryenObj["_BinaryenExtendS8Int32"](), - ExtendS8Int64 = BinaryenObj["_BinaryenExtendS8Int64"](), - ExtendS16Int32 = BinaryenObj["_BinaryenExtendS16Int32"](), - ExtendS16Int64 = BinaryenObj["_BinaryenExtendS16Int64"](), - ExtendS32Int64 = BinaryenObj["_BinaryenExtendS32Int64"](), // ### Floating-Point Operations ### // - AddFloat32 = BinaryenObj["_BinaryenAddFloat32"](), - AddFloat64 = BinaryenObj["_BinaryenAddFloat64"](), - SubFloat32 = BinaryenObj["_BinaryenSubFloat32"](), - SubFloat64 = BinaryenObj["_BinaryenSubFloat64"](), - MulFloat32 = BinaryenObj["_BinaryenMulFloat32"](), - MulFloat64 = BinaryenObj["_BinaryenMulFloat64"](), - DivFloat32 = BinaryenObj["_BinaryenDivFloat32"](), - DivFloat64 = BinaryenObj["_BinaryenDivFloat64"](), - MinFloat32 = BinaryenObj["_BinaryenMinFloat32"](), - MinFloat64 = BinaryenObj["_BinaryenMinFloat64"](), - MaxFloat32 = BinaryenObj["_BinaryenMaxFloat32"](), - MaxFloat64 = BinaryenObj["_BinaryenMaxFloat64"](), - CopySignFloat32 = BinaryenObj["_BinaryenCopySignFloat32"](), - CopySignFloat64 = BinaryenObj["_BinaryenCopySignFloat64"](), + // #### unop #### // AbsFloat32 = BinaryenObj["_BinaryenAbsFloat32"](), AbsFloat64 = BinaryenObj["_BinaryenAbsFloat64"](), NegFloat32 = BinaryenObj["_BinaryenNegFloat32"](), @@ -138,6 +129,22 @@ export enum Operation { TruncFloat64 = BinaryenObj["_BinaryenTruncFloat64"](), NearestFloat32 = BinaryenObj["_BinaryenNearestFloat32"](), NearestFloat64 = BinaryenObj["_BinaryenNearestFloat64"](), + // #### binop #### // + AddFloat32 = BinaryenObj["_BinaryenAddFloat32"](), + AddFloat64 = BinaryenObj["_BinaryenAddFloat64"](), + SubFloat32 = BinaryenObj["_BinaryenSubFloat32"](), + SubFloat64 = BinaryenObj["_BinaryenSubFloat64"](), + MulFloat32 = BinaryenObj["_BinaryenMulFloat32"](), + MulFloat64 = BinaryenObj["_BinaryenMulFloat64"](), + DivFloat32 = BinaryenObj["_BinaryenDivFloat32"](), + DivFloat64 = BinaryenObj["_BinaryenDivFloat64"](), + MinFloat32 = BinaryenObj["_BinaryenMinFloat32"](), + MinFloat64 = BinaryenObj["_BinaryenMinFloat64"](), + MaxFloat32 = BinaryenObj["_BinaryenMaxFloat32"](), + MaxFloat64 = BinaryenObj["_BinaryenMaxFloat64"](), + CopySignFloat32 = BinaryenObj["_BinaryenCopySignFloat32"](), + CopySignFloat64 = BinaryenObj["_BinaryenCopySignFloat64"](), + // #### relop #### // EqFloat32 = BinaryenObj["_BinaryenEqFloat32"](), EqFloat64 = BinaryenObj["_BinaryenEqFloat64"](), NeFloat32 = BinaryenObj["_BinaryenNeFloat32"](), @@ -171,8 +178,6 @@ export enum Operation { TruncSatUFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt64"](), TruncSatUFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt32"](), TruncSatUFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt64"](), - PromoteFloat32 = BinaryenObj["_BinaryenPromoteFloat32"](), - DemoteFloat64 = BinaryenObj["_BinaryenDemoteFloat64"](), ConvertSInt32ToFloat32 = BinaryenObj["_BinaryenConvertSInt32ToFloat32"](), ConvertSInt32ToFloat64 = BinaryenObj["_BinaryenConvertSInt32ToFloat64"](), ConvertSInt64ToFloat32 = BinaryenObj["_BinaryenConvertSInt64ToFloat32"](), @@ -185,6 +190,8 @@ export enum Operation { ReinterpretInt64 = BinaryenObj["_BinaryenReinterpretInt64"](), ReinterpretFloat32 = BinaryenObj["_BinaryenReinterpretFloat32"](), ReinterpretFloat64 = BinaryenObj["_BinaryenReinterpretFloat64"](), + PromoteFloat32 = BinaryenObj["_BinaryenPromoteFloat32"](), + DemoteFloat64 = BinaryenObj["_BinaryenDemoteFloat64"](), // ### Vector Operations ### // // #### vvunop #### // diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index a903361285f..f175241a5fb 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -52,7 +52,7 @@ export class ModuleElementSegments { constructor(private readonly mod: Module) {} /** Adds an active element segment. */ - addActive(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef): ElementSegmentRef { + addActive(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef = this.mod.x.i32.const(0)): ElementSegmentRef { return preserveStack(() => BinaryenObj["_BinaryenAddActiveElementSegment"]( this.mod.ptr, strToStack(table), From f049ff545037e93f739272bafb739da1a6a21425 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 01:25:29 -0400 Subject: [PATCH 097/247] docs: console warn on control deprecations --- ts/src/classes/expression-builders/control.ts | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/ts/src/classes/expression-builders/control.ts b/ts/src/classes/expression-builders/control.ts index 1d98c162ae0..cf9ad28e064 100644 --- a/ts/src/classes/expression-builders/control.ts +++ b/ts/src/classes/expression-builders/control.ts @@ -1,3 +1,6 @@ +import { + consoleWarn, +} from "../../lib.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -46,26 +49,19 @@ export function control(mod: Module) { // TODO: catch_all // TODO: catch_all_ref - /** @deprecated Use {@link ExpressionBuilder#br} instead. */ // @ts-expect-error - break(...args) { return this.br(...args); }, - /** @deprecated Use {@link ExpressionBuilder#br_table} instead. */ + /** @deprecated Use {@link ExpressionBuilder#br} instead. */ break(...args) { consoleWarn("`.break()` is deprecated; use `.br()` instead."); return this.br(...args); }, // @ts-expect-error - switch(...args) { return this.br_table(...args); }, - /** @deprecated Use {@link ExpressionBuilder#call_indirect} instead. */ + /** @deprecated Use {@link ExpressionBuilder#br_table} instead. */ switch(...args) { consoleWarn("`.switch()` is deprecated; use `.br_table()` instead."); return this.br_table(...args); }, // @ts-expect-error - callIndirect(...args) { return this.call_indirect(...args); }, - /** @deprecated Use {@link ExpressionBuilder#return_call} instead. */ + /** @deprecated Use {@link ExpressionBuilder#call_indirect} instead. */ callIndirect(...args) { consoleWarn("`.callIndirect()` is deprecated; use `.call_indirect()` instead."); return this.call_indirect(...args); }, // @ts-expect-error - returnCall(...args) { return this.return_call(...args); }, - /** @deprecated Use {@link ExpressionBuilder#return_call_indirect} instead. */ + /** @deprecated Use {@link ExpressionBuilder#return_call} instead. */ returnCall(...args) { consoleWarn("`.returnCall()` is deprecated; use `.return_call()` instead."); return this.return_call(...args); }, // @ts-expect-error - returnCallIndirect(...args) { return this.return_call_indirect(...args); }, - /** @deprecated Use {@link ExpressionBuilder#throw_ref} instead. */ + /** @deprecated Use {@link ExpressionBuilder#return_call_indirect} instead. */ returnCallIndirect(...args) { consoleWarn("`.returnCallIndirect()` is deprecated; use `.return_call_indirect()` instead."); return this.return_call_indirect(...args); }, // @ts-expect-error - rethrow(...args) { return this.throw_ref(...args); }, - /** @deprecated Use {@link ExpressionBuilder#try_table} instead. */ + /** @deprecated Use {@link ExpressionBuilder#throw_ref} instead. */ rethrow(...args) { consoleWarn("`.rethrow()` is deprecated; use `.throw_ref()` instead."); return this.throw_ref(...args); }, // @ts-expect-error - try(...args) { return this.try_table(...args); }, + /** @deprecated Use {@link ExpressionBuilder#try_table} instead. */ try(...args) { consoleWarn("`.try()` is deprecated; use `.try_table()` instead."); return this.try_table(...args); }, } as const; } From 385a6a773d108fcd35a778f3d6dcd4641b72aa51 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 01:27:33 -0400 Subject: [PATCH 098/247] feat: add `Module#pop` --- ts/docs/API-Overview.md | 7 +++++++ ts/src/classes/module/Module.ts | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 5d8ecf97df0..3151979e485 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -295,6 +295,13 @@ Some of `Module`’s instance methods have been converted into getters/setters: `Module#copyExpression(expr)` has been moved to the global function `copyExpression(expr, mod)` where it lives alongside `getExpressionInfo` et al. +All “type” properties (`.i32`, `.i64`, etc) on `Module` previously served as namespaces containing functions for building expressions. +(E.g., `Module#i32.add()` produced an `(i32.add)` WASM instruction.) +These have all migrated to `Module#x`, an [Expression Builder](#expression-building). +These properties also each contained its own `.pop()` method, which didn’t build a WASM expression, +but was a pseudo-instruction enabling Binaryen to reason about multiple values on the stack. +They have been combined into one method on Module, `Module#pop(t: Type)`, where `t` is one of the corresponding type namespaces. + ### Expression Builders Note: To improve readability, assume all methods written in this section are bound to an Expression Builder (an object returned by `Module#x`). diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index ff82c5ad9de..6d58141416a 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -12,7 +12,19 @@ import { type HeapType, type TableRef, type Type, + i32, + i64, + f32, + f64, + v128, + anyref, + eqref, + i31ref, + structref, + arrayref, funcref, + externref, + stringref, } from "../../constants.ts"; import { copyExpression, @@ -154,6 +166,29 @@ export class Module { */ readonly x: ExpressionBuilder = expressionBuilder(this); + /** Pseudo-instruction enabling Binaryen to reason about multiple values on the stack. */ + pop(typ: Type): ExpressionRef { + if ([ + i32, + i64, + f32, + f64, + v128, + anyref, + eqref, + i31ref, + structref, + arrayref, + funcref, + externref, + stringref, + ].includes(typ)) { + return BinaryenObj["_BinaryenPop"](this.ptr, typ); + } else { + throw new Error(`Unexpected type ${ typ }.`); + } + } + // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html readonly tags = new TAG.ModuleTags(this); From c3b7586c9df079ead38ed116d8abf1602b157738 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 01:34:38 -0400 Subject: [PATCH 099/247] docs: mark inner objects deprecated --- ts/src/classes/expression-builders/f32.ts | 2 ++ ts/src/classes/expression-builders/f64.ts | 2 ++ ts/src/classes/expression-builders/i32.ts | 4 ++++ ts/src/classes/expression-builders/i64.ts | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/ts/src/classes/expression-builders/f32.ts b/ts/src/classes/expression-builders/f32.ts index 9763e38ada6..c6fb405bef4 100644 --- a/ts/src/classes/expression-builders/f32.ts +++ b/ts/src/classes/expression-builders/f32.ts @@ -48,10 +48,12 @@ export function f32(_mod: Module) { demote_f64: STUB, + /** @deprecated */ convert_s: { /** @deprecated Use `.convert_i32_s()` instead. */ i32: STUB, /** @deprecated Use `.convert_i64_s()` instead. */ i64: STUB, }, + /** @deprecated */ convert_u: { /** @deprecated Use `.convert_i32_u()` instead. */ i32: STUB, /** @deprecated Use `.convert_i64_u()` instead. */ i64: STUB, diff --git a/ts/src/classes/expression-builders/f64.ts b/ts/src/classes/expression-builders/f64.ts index 5cbb5454f80..8b7b182f61e 100644 --- a/ts/src/classes/expression-builders/f64.ts +++ b/ts/src/classes/expression-builders/f64.ts @@ -48,10 +48,12 @@ export function f64(_mod: Module) { prmote_f32: STUB, + /** @deprecated */ convert_s: { /** @deprecated Use `.convert_i32_s()` instead. */ i32: STUB, /** @deprecated Use `.convert_i64_s()` instead. */ i64: STUB, }, + /** @deprecated */ convert_u: { /** @deprecated Use `.convert_i32_u()` instead. */ i32: STUB, /** @deprecated Use `.convert_i64_u()` instead. */ i64: STUB, diff --git a/ts/src/classes/expression-builders/i32.ts b/ts/src/classes/expression-builders/i32.ts index 6c223846523..0e224ec3f3f 100644 --- a/ts/src/classes/expression-builders/i32.ts +++ b/ts/src/classes/expression-builders/i32.ts @@ -67,18 +67,22 @@ export function i32(_mod: Module) { // @ts-expect-error /** @deprecated Use `.wrap_i64()` instead. */ wrap(...args) { consoleWarn("`.wrap()` is deprecated; use `.wrap_i64()` instead."); return this.wrap_i64(...args); }, + /** @deprecated */ trunc_s: { /** @deprecated Use `.trunc_f32_s()` instead. */ f32: STUB, /** @deprecated Use `.trunc_f64_s()` instead. */ f64: STUB, }, + /** @deprecated */ trunc_u: { /** @deprecated Use `.trunc_f32_u()` instead. */ f32: STUB, /** @deprecated Use `.trunc_f64_u()` instead. */ f64: STUB, }, + /** @deprecated */ trunc_s_sat: { /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: STUB, /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: STUB, }, + /** @deprecated */ trunc_u_sat: { /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: STUB, /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: STUB, diff --git a/ts/src/classes/expression-builders/i64.ts b/ts/src/classes/expression-builders/i64.ts index 3091e2160de..21f0eb1cc4b 100644 --- a/ts/src/classes/expression-builders/i64.ts +++ b/ts/src/classes/expression-builders/i64.ts @@ -71,18 +71,22 @@ export function i64(_mod: Module) { /** @deprecated Use `.extend_i32_s()` instead. */ extend_s(...args) { consoleWarn("`.extend_s()` is deprecated; use `.extend_i32_s()` instead."); return this.extend_i32_s(...args); }, // @ts-expect-error /** @deprecated Use `.extend_i32_u()` instead. */ extend_u(...args) { consoleWarn("`.extend_u()` is deprecated; use `.extend_i32_u()` instead."); return this.extend_i32_u(...args); }, + /** @deprecated */ trunc_s: { /** @deprecated Use `.trunc_f32_s()` instead. */ f32: STUB, /** @deprecated Use `.trunc_f64_s()` instead. */ f64: STUB, }, + /** @deprecated */ trunc_u: { /** @deprecated Use `.trunc_f32_u()` instead. */ f32: STUB, /** @deprecated Use `.trunc_f64_u()` instead. */ f64: STUB, }, + /** @deprecated */ trunc_s_sat: { /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: STUB, /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: STUB, }, + /** @deprecated */ trunc_u_sat: { /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: STUB, /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: STUB, From 87b0726e76d39c3921ae5c6245d890c088f76f64 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 01:39:24 -0400 Subject: [PATCH 100/247] docs: fix numeric deprecation styling --- ts/docs/API-Overview.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 3151979e485..e94d2dc4de6 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -316,6 +316,7 @@ Note: To improve readability, assume all methods written in this section are bou `.{struct,array}.get()` no longer take the `isSigned` argument. For packed signed/unsigned types, use `.{struct,array}.get_{s,u}()` respectively. +Many numeric methods have been renamed: - `.i32.wrap()` → `.i32.wrap_i64()` - `.i32.trunc_s.f32()` → `.i32.trunc_f32_s()` - `.i32.trunc_s.f64()` → `.i32.trunc_f64_s()` @@ -326,7 +327,7 @@ Note: To improve readability, assume all methods written in this section are bou - `.i32.trunc_u_sat.f32()` → `.i32.trunc_sat_f32_u()` - `.i32.trunc_u_sat.f64()` → `.i32.trunc_sat_f64_u()` - `.reinterpret()` → `.reinterpret_f32()` - +> - `.i64.extend_s()` → `.i64.extend_i32_s()` - `.i64.extend_u()` → `.i64.extend_i32_u()` - `.i64.trunc_s.f32()` → `.i64.trunc_f32_s()` @@ -338,14 +339,14 @@ Note: To improve readability, assume all methods written in this section are bou - `.i64.trunc_u_sat.f32()` → `.i64.trunc_sat_f32_u()` - `.i64.trunc_u_sat.f64()` → `.i64.trunc_sat_f64_u()` - `.reinterpret()` → `.reinterpret_f64()` - +> - `.f32.convert_s.i32()` → `.f32.convert_i32_s()` - `.f32.convert_s.i64()` → `.f32.convert_i64_s()` - `.f32.convert_u.i32()` → `.f32.convert_i32_u()` - `.f32.convert_u.i64()` → `.f32.convert_i64_u()` - `.f32.reinterpret()` → `.f32.reinterpret_i32()` - `.f32.demote()` → `.f32.demote_f64()` - +> - `.f64.convert_s.i32()` → `.f64.convert_i32_s()` - `.f64.convert_s.i64()` → `.f64.convert_i64_s()` - `.f64.convert_u.i32()` → `.f64.convert_i32_u()` From 744ec90d5cab5f3600f3c42911bed83feb8660e4 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 13:33:39 -0400 Subject: [PATCH 101/247] lint: rename `Module#{x => wasm}` --- ts/README.md | 19 +++++++++++-------- ts/docs/API-Overview.md | 10 +++++----- .../expression-builders/expressionBuilder.ts | 6 +++++- ts/src/classes/module/ElementSegment.ts | 2 +- ts/src/classes/module/Module.ts | 15 +++++++-------- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/ts/README.md b/ts/README.md index b2968ebc162..7add7523c50 100644 --- a/ts/README.md +++ b/ts/README.md @@ -10,16 +10,17 @@ import * as binaryen from "binaryen.ts"; const mod: binaryen.Module = new binaryen.Module(); -mod.addFunction("add", binaryen.createType([binaryen.i32, binaryen.i32]), binaryen.i32, [binaryen.i32], (() => { - const param0: binaryen.ExpressionRef = mod.local.get(0, binaryen.i32); - const param1: binaryen.ExpressionRef = mod.local.get(1, binaryen.i32); - const result: binaryen.ExpressionRef = mod.i32.add(param0, param1); - return mod.block(null, [ - mod.local.set(2, result), - mod.local.get(2, binaryen.i32), +mod.functions.add("add", binaryen.createType([binaryen.i32, binaryen.i32]), binaryen.i32, [binaryen.i32], (() => { + const {block, local, i32} = mod.wasm; + const param0: binaryen.ExpressionRef = local.get(0, binaryen.i32); + const param1: binaryen.ExpressionRef = local.get(1, binaryen.i32); + const result: binaryen.ExpressionRef = i32.add(param0, param1); + return block(null, [ + local.set(2, result), + local.get(2, binaryen.i32), ], binaryen.i32); })()); -mod.addFunctionExport("add", "add"); +mod.exports.addFunction("add", "add"); mod.optimize(); if (!mod.validate()) { throw new Error("Invalid WebAssembly module."); @@ -78,6 +79,8 @@ File Inventory: - `expression/`: Expression info classes, and source for WASM expression generation + - `expression-builders/`: internal functions for ultimately construting an `ExpressionBuilder` object + - `services/`: namespace-like, stateless classes - `dist/` *(gitignored)*: output of **tsc**; this gets published to npm for consumers diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index e94d2dc4de6..57565ea94f8 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -50,7 +50,7 @@ import {type Type, type ExpressionRef, i32} from "binaryen.ts"; ### Constants - `unreachable`: type of an unreachable instruction (stack effect *[t\*] -> [t\*]*) - `none`: void type (stack effect *[t\*] -> []*); not to be confused with WASM’s heap type called *none* -- `auto`: special type used in `Module#x.block()` exclusively; automatically detects a block’s result type based on its contents +- `auto`: special type used in [`ExpressionBuilder#block()`](#expression-building) exclusively; automatically detects a block’s result type based on its contents > - `i32`: 32-bit integer - `i64`: 64-bit integer @@ -120,7 +120,7 @@ Objects: - `new Module.Export(ref: ExportRef)`: an object containing information about an **Export** - Properties of `Module` instances (see full list of methods in generated docs): - - `Module#x`: [build expressions](#expression-building) (“x” for “expression”) + - `Module#wasm`: [build WASM expressions](#expression-building) - `Module#tags`: **Tag** manipulation - `Module#globals`: **Global** manipulation - `Module#memories`: **Memory** manipulation @@ -134,7 +134,7 @@ Objects: ## Expression Building -Each of these functions is bound to `Module#x` (of type `ExpressionBuilder`) and returns an `ExpressionRef`. +Each of these functions is bound to `Module#wasm` (of type `ExpressionBuilder`) and returns an `ExpressionRef`. See the generated **ExpressionBuilder** docs for all available functions and details. Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`”. @@ -297,14 +297,14 @@ Some of `Module`’s instance methods have been converted into getters/setters: All “type” properties (`.i32`, `.i64`, etc) on `Module` previously served as namespaces containing functions for building expressions. (E.g., `Module#i32.add()` produced an `(i32.add)` WASM instruction.) -These have all migrated to `Module#x`, an [Expression Builder](#expression-building). +These have all migrated to `Module#wasm`, an [Expression Builder](#expression-building). These properties also each contained its own `.pop()` method, which didn’t build a WASM expression, but was a pseudo-instruction enabling Binaryen to reason about multiple values on the stack. They have been combined into one method on Module, `Module#pop(t: Type)`, where `t` is one of the corresponding type namespaces. ### Expression Builders -Note: To improve readability, assume all methods written in this section are bound to an Expression Builder (an object returned by `Module#x`). +Note: To improve readability, assume all methods written in this section are bound to an Expression Builder (an object returned by `Module#wasm`). - `.break()` → `.br()` - `.switch()` → `.br_table()` diff --git a/ts/src/classes/expression-builders/expressionBuilder.ts b/ts/src/classes/expression-builders/expressionBuilder.ts index 8980c4f25d8..0becf3430d0 100644 --- a/ts/src/classes/expression-builders/expressionBuilder.ts +++ b/ts/src/classes/expression-builders/expressionBuilder.ts @@ -94,5 +94,9 @@ export function expressionBuilder(mod: Module) { -/** @useDeclaredType */ +/** + * An namespace of functions for building WASM expressions. + * @see https://webassembly.github.io/spec/core/syntax/instructions.html + * @useDeclaredType + */ export type ExpressionBuilder = ReturnType; diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index f175241a5fb..4ed711561ae 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -52,7 +52,7 @@ export class ModuleElementSegments { constructor(private readonly mod: Module) {} /** Adds an active element segment. */ - addActive(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef = this.mod.x.i32.const(0)): ElementSegmentRef { + addActive(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef = this.mod.wasm.i32.const(0)): ElementSegmentRef { return preserveStack(() => BinaryenObj["_BinaryenAddActiveElementSegment"]( this.mod.ptr, strToStack(table), diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 6d58141416a..a8c97f35f73 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -132,7 +132,7 @@ export enum Feature { * - {@link Module#elementSegments} * - {@link Module#imports} * - {@link Module#exports} - * - has a property `.x`, a namespace for creating expressions in the module (`.x.nop()`, `.x.i32.add()`, etc.) + * - has a property `.wasm`, a namespace for creating expressions in the module (`.wasm.nop()`, `.wasm.i32.add()`, etc.) */ export class Module { static readonly Tag = TAG.Tag; @@ -149,22 +149,21 @@ export class Module { readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); /** - * This module’s expression builder. + * This module’s {@link ExpressionBuilder | WASM expression builder}. * - * N.B.: For convenience, developers may want to destructure the module to free `x`: + * N.B.: For convenience, developers may want to destructure the module to free `wasm`: * ```ts * const mod = new Module(); - * const {x} = mod; - * x.drop(x.i32.add(x.i32.const(3), x.i32.const(5))); + * const {wasm} = mod; + * wasm.drop(wasm.i32.add(wasm.i32.const(3), wasm.i32.const(5))); * ``` * or to free its properties: * ```ts - * const {i32, drop} = mod.x; + * const {i32, drop} = mod.wasm; * drop(i32.add(i32.const(3), i32.const(5))); * ``` - * @see {@link ExpressionBuilder} */ - readonly x: ExpressionBuilder = expressionBuilder(this); + readonly wasm: ExpressionBuilder = expressionBuilder(this); /** Pseudo-instruction enabling Binaryen to reason about multiple values on the stack. */ pop(typ: Type): ExpressionRef { From 822103d57471d5ee189965f04e7743285d8cd334 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 14:52:18 -0400 Subject: [PATCH 102/247] lint: rename namespace `X => EXPR` --- ts/docs/API-Overview.md | 30 +++++++-------- ts/src/-deprecations.ts | 38 +++++++++---------- ts/src/binaryen.ts | 2 +- ts/src/classes/expression-builders/control.ts | 8 ++-- ts/src/classes/expression-builders/local.ts | 6 +-- .../classes/expression-builders/parametric.ts | 4 +- 6 files changed, 44 insertions(+), 44 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 57565ea94f8..f1cd3721fc3 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -209,23 +209,23 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” ## Expression Manipulation -Expression info classes all live under the global `X` namespace (“X” for “Expression”). +Expression info classes all live under the global `EXPR` namespace. They can be used to inspect and manipulate expressions. See generated docs for fields, methods, and descriptions of each. -- `X.Expression` (root class) +- `EXPR.Expression` (root class) - parametric instructions - - `X.Drop` - - `X.Select` + - `EXPR.Drop` + - `EXPR.Select` - control instructions - - `X.Block` - - `X.Loop` - - `X.Break` + - `EXPR.Block` + - `EXPR.Loop` + - `EXPR.Break` - variable instructions - - `X.LocalGet` - - `X.LocalSet` + - `EXPR.LocalGet` + - `EXPR.LocalSet` - numeric instructions - - `X.Const` + - `EXPR.Const` @@ -246,11 +246,11 @@ Enum names have been singularized. - `ElementSegmentInfo` → `Module.ElementSegment` - `ExportInfo` → `Module.Export` -`ExpressionInfo` and related types are now classes in the `X` namespace: -- `ExpressionInfo` → `X.Expression` -- `BlockInfo` → `X.Block` -- `LoopInfo` → `X.Loop` -- `IfInfo` → `X.If` +`ExpressionInfo` and related types are now classes in the `EXPR` namespace: +- `ExpressionInfo` → `EXPR.Expression` +- `BlockInfo` → `EXPR.Block` +- `LoopInfo` → `EXPR.Loop` +- `IfInfo` → `EXPR.If` - etc. ~~`MemorySegmentInfo`~~ ❌ has been removed. diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 5a275c92f49..aa139e72743 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -2,7 +2,7 @@ -import type * as X from "./classes/expression/index.ts"; +import type * as EXPR from "./classes/expression/index.ts"; import { Feature, Module, @@ -57,24 +57,24 @@ export type ExportInfo = Module.Export; -/** @deprecated The `ExpressionInfo` object type is now called {@link X.Expression}. */ -export type ExpressionInfo = X.Expression; -/** @deprecated The `DropInfo` object type is now called {@link X.Drop}. */ -export type DropInfo = X.Drop; -/** @deprecated The `SelectInfo` object type is now called {@link X.Select}. */ -export type SelectInfo = X.Select; -/** @deprecated The `BlockInfo` object type is now called {@link X.Block}. */ -export type BlockInfo = X.Block; -/** @deprecated The `LoopInfo` object type is now called {@link X.Loop}. */ -export type LoopInfo = X.Loop; -/** @deprecated The `BreakInfo` object type is now called {@link X.Break}. */ -export type BreakInfo = X.Break; -/** @deprecated The `LocalGetInfo` object type is now called {@link X.LocalGet}. */ -export type LocalGetInfo = X.LocalGet; -/** @deprecated The `LocalSetInfo` object type is now called {@link X.LocalSet}. */ -export type LocalSetInfo = X.LocalSet; -/** @deprecated The `ConstInfo` object type is now called {@link X.Const}. */ -export type ConstInfo = X.Const; +/** @deprecated The `ExpressionInfo` object type is now called {@link EXPR.Expression}. */ +export type ExpressionInfo = EXPR.Expression; +/** @deprecated The `DropInfo` object type is now called {@link EXPR.Drop}. */ +export type DropInfo = EXPR.Drop; +/** @deprecated The `SelectInfo` object type is now called {@link EXPR.Select}. */ +export type SelectInfo = EXPR.Select; +/** @deprecated The `BlockInfo` object type is now called {@link EXPR.Block}. */ +export type BlockInfo = EXPR.Block; +/** @deprecated The `LoopInfo` object type is now called {@link EXPR.Loop}. */ +export type LoopInfo = EXPR.Loop; +/** @deprecated The `BreakInfo` object type is now called {@link EXPR.Break}. */ +export type BreakInfo = EXPR.Break; +/** @deprecated The `LocalGetInfo` object type is now called {@link EXPR.LocalGet}. */ +export type LocalGetInfo = EXPR.LocalGet; +/** @deprecated The `LocalSetInfo` object type is now called {@link EXPR.LocalSet}. */ +export type LocalSetInfo = EXPR.LocalSet; +/** @deprecated The `ConstInfo` object type is now called {@link EXPR.Const}. */ +export type ConstInfo = EXPR.Const; /** @deprecated The `Function` class now lives under the `Module` namespace. Use {@link Module.Function}. */ export const Function = Module.Function; diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index b605d043d9d..5f9454913d4 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -14,7 +14,7 @@ export type {DataSegment, ModuleDataSegments} from "./classes/module/DataSegment export type {ElementSegment, ModuleElementSegments} from "./classes/module/ElementSegment.ts"; export type {Import, ModuleImports} from "./classes/module/Import.ts"; export type {Export, ModuleExports} from "./classes/module/Export.ts"; -export * as X from "./classes/expression/index.ts"; +export * as EXPR from "./classes/expression/index.ts"; export type {ExpressionBuilder} from "./classes/expression-builders/expressionBuilder.ts"; export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { diff --git a/ts/src/classes/expression-builders/control.ts b/ts/src/classes/expression-builders/control.ts index cf9ad28e064..4fbd8a97ff5 100644 --- a/ts/src/classes/expression-builders/control.ts +++ b/ts/src/classes/expression-builders/control.ts @@ -20,14 +20,14 @@ const STUB = (..._args: readonly number[]): number => 0; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ export function control(mod: Module) { return { - /** @inheritdoc X.Block.block */ + /** @inheritdoc EXPR.Block.block */ block: Block.block.bind(null, mod), - /** @inheritdoc X.Loop.loop */ + /** @inheritdoc EXPR.Loop.loop */ loop: Loop.loop.bind(null, mod), if: STUB, - /** @inheritdoc X.Break.br */ + /** @inheritdoc EXPR.Break.br */ br: Break.br.bind(null, mod), - /** @inheritdoc X.Break.br_if */ + /** @inheritdoc EXPR.Break.br_if */ br_if: Break.br_if.bind(null, mod), br_table: STUB, br_on_null: STUB, diff --git a/ts/src/classes/expression-builders/local.ts b/ts/src/classes/expression-builders/local.ts index e49202b164e..5403089fe0b 100644 --- a/ts/src/classes/expression-builders/local.ts +++ b/ts/src/classes/expression-builders/local.ts @@ -11,11 +11,11 @@ import { /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#variable-instructions */ export function local(mod: Module) { return { - /** @inheritDoc X.LocalGet.localGet */ + /** @inheritDoc EXPR.LocalGet.localGet */ get: LocalGet.localGet.bind(null, mod), - /** @inheritDoc X.LocalSet.localSet */ + /** @inheritDoc EXPR.LocalSet.localSet */ set: LocalSet.localSet.bind(null, mod), - /** @inheritDoc X.LocalSet.localTee */ + /** @inheritDoc EXPR.LocalSet.localTee */ tee: LocalSet.localTee.bind(null, mod), } as const; } diff --git a/ts/src/classes/expression-builders/parametric.ts b/ts/src/classes/expression-builders/parametric.ts index 70598253eec..67d2ac0ae94 100644 --- a/ts/src/classes/expression-builders/parametric.ts +++ b/ts/src/classes/expression-builders/parametric.ts @@ -21,9 +21,9 @@ export function parametric(mod: Module) { nop: (): ExpressionRef => BinaryenObj["_BinaryenNop"](mod.ptr), /** Creates an unreachable instruction that will always trap. */ unreachable: (): ExpressionRef => BinaryenObj["_BinaryenUnreachable"](mod.ptr), - /** @inheritDoc X.Drop.drop */ + /** @inheritDoc EXPR.Drop.drop */ drop: Drop.drop.bind(null, mod), - /** @inheritDoc X.Select.select */ + /** @inheritDoc EXPR.Select.select */ select: Select.select.bind(null, mod), } as const; } From 1150d839e3730c87f4bb7fe412442e19f084bf2f Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 13:42:30 -0400 Subject: [PATCH 103/247] docs: fix numeric ops --- ts/docs/API-Overview.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index f1cd3721fc3..8e6e30554dc 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -181,14 +181,14 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.array.copy()` - `.array.init_data()`, `.array.init_elem()` - integers - - `.{i32,i64}.const` - - `.{i31,i32}.clz`, `.{i32,i64}.ctz`, `.{i32,i64}.popcnt` - - `.{i32,i64}.extend8_s`, `.{i32,i64}.extend16_s`, `.i64.extend32_s` - - `.{i31,i32}.add`, `.{i32,i64}.sub`, `.{i32,i64}.mul`, `.{i31,i32}.div_{s,u}`, `.{i32,i64}.rem_{s,u}` - - `.{i31,i32}.and`, `.{i32,i64}.or`, `.{i32,i64}.xor`, `.{i31,i32}.shl`, `.{i31,i32}.shr{s,u}`, `.{i32,i64}.rotl`, `.{i32,i64}.rotr` - - `.{i32,i64}.eqz` - - `.{i32,i64}.eq`, `.{i32,i64}.ne` - - `.{i32,i64}.lt_{s,u}`, `.{i32,i64}.gt_{s,u}`, `.{i32,i64}.le_{s,u}`, `.{i32,i64}.ge_{s,u}` + - `.{i32,i64}.const()` + - `.{i31,i32}.clz()`, `.{i32,i64}.ctz()`, `.{i32,i64}.popcnt()` + - `.{i32,i64}.extend8_s()`, `.{i32,i64}.extend16_s()`, `.i64.extend32_s()` + - `.{i31,i32}.add()`, `.{i32,i64}.sub()`, `.{i32,i64}.mul()`, `.{i31,i32}.div_{s,u}()`, `.{i32,i64}.rem_{s,u}()` + - `.{i31,i32}.and()`, `.{i32,i64}.or()`, `.{i32,i64}.xor()`, `.{i31,i32}.shl()`, `.{i31,i32}.shr{s,u}()`, `.{i32,i64}.rotl()`, `.{i32,i64}.rotr()` + - `.{i32,i64}.eqz()` + - `.{i32,i64}.eq()`, `.{i32,i64}.ne()` + - `.{i32,i64}.lt_{s,u}()`, `.{i32,i64}.gt_{s,u}()`, `.{i32,i64}.le_{s,u}()`, `.{i32,i64}.ge_{s,u}()` - `.i32.wrap_i64()`, `.i64.extend_i32_{s,u}()` - `.i32.trunc_f32_{s,u}()`, `.i32.trunc_f64_{s,u}()` - `.i64.trunc_f32_{s,u}()`, `.i64.trunc_f64_{s,u}()` @@ -196,12 +196,12 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.i64.trunc_sat_f32_{s,u}()`, `.i64.trunc_sat_f64_{s,u}()` - `.i32.reinterpret_f32()`, `.i64.reinterpret_f64()` - floats - - `.{f32,f64}.const` - - `.{f32,f64}.abs`, `.{f32,f64}.neg`, `.{f32,f64}.sqrt`, `.{f32,f64}.ceil`, `.{f32,f64}.floor`, `.{f32,f64}.trunc`, `.{f32,f64}.nearest` - - `.{f32,f64}.add`, `.{f32,f64}.sub`, `.{f32,f64}.mul`, `.{f32,f64}.div`, `.{f32,f64}.min`, `.{f32,f64}.max`, `.{f32,f64}.copysign` - - `.{f32,f64}.eq`, `.{f32,f64}.lt`, `.{f32,f64}.gt`, `.{f32,f64}.le`, `.{f32,f64}.ge` - - `.{f32,f64}.convert_i32_s`, `.{f32,f64}.convert_i32_u`, `.{f32,f64}.convert_i64_s`, `.{f32,f64}.convert_i64_u` - - `.f32.demote_f64`, `.f64.promote_f32` + - `.{f32,f64}.const()` + - `.{f32,f64}.abs()`, `.{f32,f64}.neg()`, `.{f32,f64}.sqrt()`, `.{f32,f64}.ceil()`, `.{f32,f64}.floor()`, `.{f32,f64}.trunc()`, `.{f32,f64}.nearest()` + - `.{f32,f64}.add()`, `.{f32,f64}.sub()`, `.{f32,f64}.mul()`, `.{f32,f64}.div()`, `.{f32,f64}.min()`, `.{f32,f64}.max()`, `.{f32,f64}.copysign()` + - `.{f32,f64}.eq()`, `.{f32,f64}.lt()`, `.{f32,f64}.gt()`, `.{f32,f64}.le()`, `.{f32,f64}.ge()` + - `.{f32,f64}.convert_i32_s()`, `.{f32,f64}.convert_i32_u()`, `.{f32,f64}.convert_i64_s()`, `.{f32,f64}.convert_i64_u()` + - `.f32.demote_f64()`, `.f64.promote_f32()` - tuples 🌱 (Binaryen-specific) - `.tuple.make()` - `.tuple.extract()` @@ -303,7 +303,7 @@ but was a pseudo-instruction enabling Binaryen to reason about multiple values o They have been combined into one method on Module, `Module#pop(t: Type)`, where `t` is one of the corresponding type namespaces. -### Expression Builders +### Expression Builder Methods Note: To improve readability, assume all methods written in this section are bound to an Expression Builder (an object returned by `Module#wasm`). - `.break()` → `.br()` From 87cb5ad977c3d3b0752f3e21a274b2589a101167 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 14:39:44 -0400 Subject: [PATCH 104/247] docs: update Contribute section --- ts/README.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/ts/README.md b/ts/README.md index 7add7523c50..83837f7fac1 100644 --- a/ts/README.md +++ b/ts/README.md @@ -35,7 +35,9 @@ console.log(instance.exports.add(41, 1)); // 42 ``` ## How to Contribute -Make sure you have Git and Node (and NPM) installed on your machine, and have already cloned the **WebAssembly/binaryen** repo. +Contributions are welcome! +Make sure you have [Git](https://git-scm.com/) and [Node (and NPM)](https://nodejs.org/) installed on your machine, +and have already cloned the **WebAssembly/binaryen** repo. From the repo’s root: ```zsh @@ -44,10 +46,77 @@ $ npm ci $ npm run build ``` -File Inventory: +### Pipeline +#### Develop in TypeScript +The core of this project is written in [TS](https://www.typescriptlang.org/), best paired with a powerful editor and some nice extensions. +```zsh +$ npm run compile # emits javascript output to ./dist/ +``` +Don’t put anything important in `./dist/`, as it gets deleted and rebuilt each time. + +Before committing, ensure only the best code quality by running [ESLint](https://eslint.org/). +```zsh +$ npm run lint # reports linter errors & warnings +$ npm run lint -- --fix # tries to auto-fix problems (some may need manual fixing) +``` + +Use [Conventional Commits](https://www.conventionalcommits.org/) commit message format. +Messages should be in the present tense / command tense. +```zsh +$ git commit -m "feat: add a new feature" +$ git commit -m "feat!: add a new breaking feature" # API consumers need to know about these +$ git commit -m "fix: fix a bug" +$ git commit -m "refactor: reorganize code" +$ git commit -m "lint: fix a coding style issue" +$ git commit -m "docs: update documentation" +$ git commit -m "test: add/update tests" +$ git commit -m "build: make a change related to the package build system" +``` + +#### Read the Docs +Generated documentation is built with [TypeDoc](https://typedoc.org/), a tool that parses comments in the TS source files and produces beautiful HTML. + +After developing and updating doc-comments, regenerate docs and view them in your browser. +```zsh +$ npm run docs # builds a static site to ./docs/out/ +$ open ./docs/out/index.html +``` +Don’t put anything important in `./docs/out/`, as it gets deleted and rebuilt each time. + +TODO: Docs will be hosted publicly online somewhere soon. + +#### Run Tests +The test suite is empty for now, but you can still run it. +Node v24+ required. +```zsh +$ npm run test +``` + +#### Bundle +TypeScript only compiles the source files to `./dist/`. +After that we need a bundler to optimize and minify it into one giant JS file, +which will then get processed with Emscripten’s build so that it can be used by consumers. +This will look a lot like AssemblyScript’s build process. + +TODO: more details + +#### Build and Push +Before pushing, rebuild the entire project to catch any errors. +```zsh +$ npm run build + +# if all goes well… + +$ git push +``` + +#### Publish +TODO: this section + +### File Inventory - `README.md`: *you are here* -- `{.editorconfig,.gitignore}`: standard repo files +- `.editorconfig`, `.gitignore`: standard repo files - `package{,-lock}.json`: Node package & npm registry details @@ -63,7 +132,7 @@ File Inventory: - `binaryen.ts`: the entrypoint; exports everything available to consumers - - `-pre.d.ts`: artifacts provided by Emscripten + - `-pre.ts`: artifacts provided by Emscripten - `{lib,utils}.ts`: internal tools @@ -87,4 +156,4 @@ File Inventory: - `docs/`: documentation - - `out/` *(gitignored)*: output of **typedoc**; gitignored + - `out/` *(gitignored)*: output of **typedoc**; this will probably be hosted online From 4acba0c26e47762247f95c159c2f9a770e9e00b4 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 15:15:18 -0400 Subject: [PATCH 105/247] refactor: move expressionBuilder to services --- ts/README.md | 2 -- ts/src/binaryen.ts | 2 +- ts/src/classes/module/Module.ts | 8 ++++---- .../expression-builder}/array.ts | 2 +- .../expression-builder}/control.ts | 0 .../expression-builder}/expressionBuilder.ts | 3 --- .../expression-builder}/f32.ts | 2 +- .../expression-builder}/f64.ts | 2 +- .../expression-builder}/global.ts | 2 +- .../expression-builder}/i31.ts | 2 +- .../expression-builder}/i32.ts | 2 +- .../expression-builder}/i64.ts | 2 +- .../expression-builder}/local.ts | 0 .../expression-builder}/memory.ts | 2 +- .../expression-builder}/parametric.ts | 0 .../expression-builder}/ref.ts | 2 +- .../expression-builder}/struct.ts | 2 +- .../expression-builder}/table.ts | 2 +- .../expression-builder}/tuple.ts | 2 +- 19 files changed, 17 insertions(+), 22 deletions(-) rename ts/src/{classes/expression-builders => services/expression-builder}/array.ts (94%) rename ts/src/{classes/expression-builders => services/expression-builder}/control.ts (100%) rename ts/src/{classes/expression-builders => services/expression-builder}/expressionBuilder.ts (99%) rename ts/src/{classes/expression-builders => services/expression-builder}/f32.ts (97%) rename ts/src/{classes/expression-builders => services/expression-builder}/f64.ts (97%) rename ts/src/{classes/expression-builders => services/expression-builder}/global.ts (87%) rename ts/src/{classes/expression-builders => services/expression-builder}/i31.ts (87%) rename ts/src/{classes/expression-builders => services/expression-builder}/i32.ts (98%) rename ts/src/{classes/expression-builders => services/expression-builder}/i64.ts (98%) rename ts/src/{classes/expression-builders => services/expression-builder}/local.ts (100%) rename ts/src/{classes/expression-builders => services/expression-builder}/memory.ts (92%) rename ts/src/{classes/expression-builders => services/expression-builder}/parametric.ts (100%) rename ts/src/{classes/expression-builders => services/expression-builder}/ref.ts (87%) rename ts/src/{classes/expression-builders => services/expression-builder}/struct.ts (93%) rename ts/src/{classes/expression-builders => services/expression-builder}/table.ts (89%) rename ts/src/{classes/expression-builders => services/expression-builder}/tuple.ts (82%) diff --git a/ts/README.md b/ts/README.md index 83837f7fac1..17fc73aa1d0 100644 --- a/ts/README.md +++ b/ts/README.md @@ -148,8 +148,6 @@ TODO: this section - `expression/`: Expression info classes, and source for WASM expression generation - - `expression-builders/`: internal functions for ultimately construting an `ExpressionBuilder` object - - `services/`: namespace-like, stateless classes - `dist/` *(gitignored)*: output of **tsc**; this gets published to npm for consumers diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 5f9454913d4..cf0d3b00e06 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -15,7 +15,7 @@ export type {ElementSegment, ModuleElementSegments} from "./classes/module/Eleme export type {Import, ModuleImports} from "./classes/module/Import.ts"; export type {Export, ModuleExports} from "./classes/module/Export.ts"; export * as EXPR from "./classes/expression/index.ts"; -export type {ExpressionBuilder} from "./classes/expression-builders/expressionBuilder.ts"; +export type {ExpressionBuilder} from "./services/expression-builder/expressionBuilder.ts"; export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index a8c97f35f73..904e0de0137 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -32,6 +32,10 @@ import { import { replacedBy, } from "../../lib.ts"; +import { + type ExpressionBuilder, + expressionBuilder, +} from "../../services/expression-builder/expressionBuilder.ts"; import { HEAPU8, HEAPU32, @@ -40,10 +44,6 @@ import { preserveStack, strToStack, } from "../../utils.ts"; -import { - type ExpressionBuilder, - expressionBuilder, -} from "../../classes/expression-builders/expressionBuilder.ts"; import * as DATA_SEGMENT from "./DataSegment.ts"; import * as ELEMENT_SEGMENT from "./ElementSegment.ts"; import * as EXPORT from "./Export.ts"; diff --git a/ts/src/classes/expression-builders/array.ts b/ts/src/services/expression-builder/array.ts similarity index 94% rename from ts/src/classes/expression-builders/array.ts rename to ts/src/services/expression-builder/array.ts index bff8b3c2583..83389550370 100644 --- a/ts/src/classes/expression-builders/array.ts +++ b/ts/src/services/expression-builder/array.ts @@ -1,6 +1,6 @@ import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/control.ts b/ts/src/services/expression-builder/control.ts similarity index 100% rename from ts/src/classes/expression-builders/control.ts rename to ts/src/services/expression-builder/control.ts diff --git a/ts/src/classes/expression-builders/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts similarity index 99% rename from ts/src/classes/expression-builders/expressionBuilder.ts rename to ts/src/services/expression-builder/expressionBuilder.ts index 0becf3430d0..3dfa6630f8a 100644 --- a/ts/src/classes/expression-builders/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -54,9 +54,6 @@ const STUB = (..._args: readonly number[]): number => 0; - - - /** Methods for building expressions in a WASM module. */ export function expressionBuilder(mod: Module) { /* diff --git a/ts/src/classes/expression-builders/f32.ts b/ts/src/services/expression-builder/f32.ts similarity index 97% rename from ts/src/classes/expression-builders/f32.ts rename to ts/src/services/expression-builder/f32.ts index c6fb405bef4..bf333fcc9f6 100644 --- a/ts/src/classes/expression-builders/f32.ts +++ b/ts/src/services/expression-builder/f32.ts @@ -3,7 +3,7 @@ import { } from "../../lib.ts"; import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/f64.ts b/ts/src/services/expression-builder/f64.ts similarity index 97% rename from ts/src/classes/expression-builders/f64.ts rename to ts/src/services/expression-builder/f64.ts index 8b7b182f61e..c4b8d694440 100644 --- a/ts/src/classes/expression-builders/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -3,7 +3,7 @@ import { } from "../../lib.ts"; import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/global.ts b/ts/src/services/expression-builder/global.ts similarity index 87% rename from ts/src/classes/expression-builders/global.ts rename to ts/src/services/expression-builder/global.ts index 0e5aa882125..9dda851c166 100644 --- a/ts/src/classes/expression-builders/global.ts +++ b/ts/src/services/expression-builder/global.ts @@ -1,6 +1,6 @@ import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/i31.ts b/ts/src/services/expression-builder/i31.ts similarity index 87% rename from ts/src/classes/expression-builders/i31.ts rename to ts/src/services/expression-builder/i31.ts index cddb2ffc06f..7c7462c0e02 100644 --- a/ts/src/classes/expression-builders/i31.ts +++ b/ts/src/services/expression-builder/i31.ts @@ -1,6 +1,6 @@ import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/i32.ts b/ts/src/services/expression-builder/i32.ts similarity index 98% rename from ts/src/classes/expression-builders/i32.ts rename to ts/src/services/expression-builder/i32.ts index 0e224ec3f3f..d44164127ea 100644 --- a/ts/src/classes/expression-builders/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -3,7 +3,7 @@ import { } from "../../lib.ts"; import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/i64.ts b/ts/src/services/expression-builder/i64.ts similarity index 98% rename from ts/src/classes/expression-builders/i64.ts rename to ts/src/services/expression-builder/i64.ts index 21f0eb1cc4b..ec84bc1539e 100644 --- a/ts/src/classes/expression-builders/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -3,7 +3,7 @@ import { } from "../../lib.ts"; import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/local.ts b/ts/src/services/expression-builder/local.ts similarity index 100% rename from ts/src/classes/expression-builders/local.ts rename to ts/src/services/expression-builder/local.ts diff --git a/ts/src/classes/expression-builders/memory.ts b/ts/src/services/expression-builder/memory.ts similarity index 92% rename from ts/src/classes/expression-builders/memory.ts rename to ts/src/services/expression-builder/memory.ts index 1dc65246484..ea6604fbf71 100644 --- a/ts/src/classes/expression-builders/memory.ts +++ b/ts/src/services/expression-builder/memory.ts @@ -1,6 +1,6 @@ import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/parametric.ts b/ts/src/services/expression-builder/parametric.ts similarity index 100% rename from ts/src/classes/expression-builders/parametric.ts rename to ts/src/services/expression-builder/parametric.ts diff --git a/ts/src/classes/expression-builders/ref.ts b/ts/src/services/expression-builder/ref.ts similarity index 87% rename from ts/src/classes/expression-builders/ref.ts rename to ts/src/services/expression-builder/ref.ts index 1782b242262..18ef7bb8d02 100644 --- a/ts/src/classes/expression-builders/ref.ts +++ b/ts/src/services/expression-builder/ref.ts @@ -1,6 +1,6 @@ import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/struct.ts b/ts/src/services/expression-builder/struct.ts similarity index 93% rename from ts/src/classes/expression-builders/struct.ts rename to ts/src/services/expression-builder/struct.ts index ac5fe0f0a9e..b9bcf4733be 100644 --- a/ts/src/classes/expression-builders/struct.ts +++ b/ts/src/services/expression-builder/struct.ts @@ -1,6 +1,6 @@ import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/table.ts b/ts/src/services/expression-builder/table.ts similarity index 89% rename from ts/src/classes/expression-builders/table.ts rename to ts/src/services/expression-builder/table.ts index b738743d2ff..d7bf7c273a6 100644 --- a/ts/src/classes/expression-builders/table.ts +++ b/ts/src/services/expression-builder/table.ts @@ -1,6 +1,6 @@ import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; diff --git a/ts/src/classes/expression-builders/tuple.ts b/ts/src/services/expression-builder/tuple.ts similarity index 82% rename from ts/src/classes/expression-builders/tuple.ts rename to ts/src/services/expression-builder/tuple.ts index 9897c056dee..9a0ecb749db 100644 --- a/ts/src/classes/expression-builders/tuple.ts +++ b/ts/src/services/expression-builder/tuple.ts @@ -1,6 +1,6 @@ import type { Module, -} from "../module/Module.ts"; +} from "../../classes/module/Module.ts"; From b61d699872046802198f4ab894dd7bea940f50ab Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 17:08:45 -0400 Subject: [PATCH 106/247] fix: disable nojekyll --- ts/typedoc.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/ts/typedoc.config.js b/ts/typedoc.config.js index bee06b650d4..fe82125dff5 100644 --- a/ts/typedoc.config.js +++ b/ts/typedoc.config.js @@ -4,5 +4,6 @@ export default { projectDocuments: ["./docs/API-Overview.md"], useFirstParagraphOfCommentAsSummary: true, out: "./docs/out/", + githubPages: false, // when `false`, does not generate a `.nojekyll` file to prevent GitHub Pages from using Jekyll customCss: "./docs/styles.css", }; From 843c9a9865ce968c1790153a037706f325f4d3b3 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 17:43:30 -0400 Subject: [PATCH 107/247] docs: API Overview: add Module methods --- ts/docs/API-Overview.md | 71 +++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 8e6e30554dc..c12f91d9476 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -108,28 +108,51 @@ Objects: ## Module Manipulation -- Properties of `Module` as a namespace: - - `new Module.Tag(ref: TagRef)`: an object containing information about a **Tag** - - `new Module.Global(ref: GlobalRef)`: an object containing information about a **Global** - - `new Module.Memory(mod: Module, name: string)`: an object containing information about a **Memory** - - `new Module.Table(ref: TableRef)`: an object containing information about a **Table** - - `new Module.Function(ref: FunctionRef)`: an object containing information about a **Function** - - `new Module.DataSegment(mod: Module, ref: DataSegmentRef)`: an object containing information about a **Data Segment** - - `new Module.ElementSegment(ref: ElementSegmentRef)`: an object containing information about an **Element Segment** - - `new Module.Import()`: an object containing information about an **Import** (🌱 empty for now) - - `new Module.Export(ref: ExportRef)`: an object containing information about an **Export** - -- Properties of `Module` instances (see full list of methods in generated docs): - - `Module#wasm`: [build WASM expressions](#expression-building) - - `Module#tags`: **Tag** manipulation - - `Module#globals`: **Global** manipulation - - `Module#memories`: **Memory** manipulation - - `Module#tables`: **Table** manipulation - - `Module#functions`: **Function** manipulation - - `Module#dataSegments`: **Data Segment** manipulation - - `Module#elementSegments`: **Element Segment** manipulation - - `Module#imports`: **Import** manipulation - - `Module#exports`: **Export** manipulation +Properties of `Module` as a namespace: +- `new Module.Tag(ref: TagRef)`: an object containing information about a **Tag** +- `new Module.Global(ref: GlobalRef)`: an object containing information about a **Global** +- `new Module.Memory(mod: Module, name: string)`: an object containing information about a **Memory** +- `new Module.Table(ref: TableRef)`: an object containing information about a **Table** +- `new Module.Function(ref: FunctionRef)`: an object containing information about a **Function** +- `new Module.DataSegment(mod: Module, ref: DataSegmentRef)`: an object containing information about a **Data Segment** +- `new Module.ElementSegment(ref: ElementSegmentRef)`: an object containing information about an **Element Segment** +- `new Module.Import()`: an object containing information about an **Import** (🌱 empty for now) +- `new Module.Export(ref: ExportRef)`: an object containing information about an **Export** + +Properties of `Module` instances (see full list of methods in generated docs): +- `Module#wasm`: [build WASM expressions](#expression-building) +- `Module#tags`: **Tag** manipulation +- `Module#globals`: **Global** manipulation +- `Module#memories`: **Memory** manipulation +- `Module#tables`: **Table** manipulation +- `Module#functions`: **Function** manipulation +- `Module#dataSegments`: **Data Segment** manipulation +- `Module#elementSegments`: **Element Segment** manipulation +- `Module#imports`: **Import** manipulation +- `Module#exports`: **Export** manipulation + +Module methods (see signatures and descriptions in generated docs): +- Emission & Execution + - `.emitText()` + - `.emitStackIR()` + - `.emitAsmjs()` + - `.emitBinary()` + - `.interpret()` + - `.dispose()` +- Validation & Optimization + - `.validate()` + - `.optimize()` + - `.optimizeFunction()` + - `.runPasses()` + - `.runPassesOnFunction()` +- Debugging + - `.addDebugInfoFileName()` + - `.getDebugInfoFileName()` + - `.setDebugLocation()` + - `.setTypeName()` + - `.setFieldName()` + - `.addCustomSection()` + - `.updateMaps()` @@ -326,7 +349,7 @@ Many numeric methods have been renamed: - `.i32.trunc_s_sat.f64()` → `.i32.trunc_sat_f64_s()` - `.i32.trunc_u_sat.f32()` → `.i32.trunc_sat_f32_u()` - `.i32.trunc_u_sat.f64()` → `.i32.trunc_sat_f64_u()` -- `.reinterpret()` → `.reinterpret_f32()` +- `.i32.reinterpret()` → `.i32.reinterpret_f32()` > - `.i64.extend_s()` → `.i64.extend_i32_s()` - `.i64.extend_u()` → `.i64.extend_i32_u()` @@ -338,7 +361,7 @@ Many numeric methods have been renamed: - `.i64.trunc_s_sat.f64()` → `.i64.trunc_sat_f64_s()` - `.i64.trunc_u_sat.f32()` → `.i64.trunc_sat_f32_u()` - `.i64.trunc_u_sat.f64()` → `.i64.trunc_sat_f64_u()` -- `.reinterpret()` → `.reinterpret_f64()` +- `.i64.reinterpret()` → `.i64.reinterpret_f64()` > - `.f32.convert_s.i32()` → `.f32.convert_i32_s()` - `.f32.convert_s.i64()` → `.f32.convert_i64_s()` From fddc61048733dff3bee68375d00633c175495568 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 17:44:53 -0400 Subject: [PATCH 108/247] build: tsc tests in script --- ts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/package.json b/ts/package.json index c500a7c6003..b6dc56ddba5 100644 --- a/ts/package.json +++ b/ts/package.json @@ -16,7 +16,7 @@ "type": "module", "main": "./dist/binaryen.js", "scripts": { - "compile": "rm -rf ./dist/ && tsc", + "compile": "rm -rf ./dist/ && tsc && tsc --project ./test/tsconfig.json", "lint": "eslint ./", "docs": "rm -rf ./docs/out/ && typedoc", "test": "tsx --test --test-isolation=none -- './test/**/*.test.ts'", From cff03936ccb61b7b2d8e2a4bcff33ad3da1e6fac Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 17:50:25 -0400 Subject: [PATCH 109/247] refactor: move BinaryenFunction run-once getters to fields --- ts/src/classes/module/Function.ts | 36 +++++++++++-------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index 1faeafb402d..f7d44ad8ef3 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -29,6 +29,12 @@ class BinaryenFunction { readonly module: string; readonly base: string; + readonly name: string; + readonly type: Type; + readonly params: Type; + readonly results: Type; + readonly numVars: number; + readonly numLocals: number; readonly vars: readonly Type[]; @@ -36,34 +42,16 @@ class BinaryenFunction { this[THIS_PTR] = func; this.module = UTF8ToString(BinaryenObj["_BinaryenFunctionImportGetModule"](this[THIS_PTR])); this.base = UTF8ToString(BinaryenObj["_BinaryenFunctionImportGetBase"](this[THIS_PTR])); + this.name = UTF8ToString(BinaryenObj["_BinaryenFunctionGetName"](this[THIS_PTR])); + this.type = BinaryenObj["_BinaryenFunctionGetType"](this[THIS_PTR]); + this.params = BinaryenObj["_BinaryenFunctionGetParams"](this[THIS_PTR]); + this.results = BinaryenObj["_BinaryenFunctionGetResults"](this[THIS_PTR]); + this.numVars = BinaryenObj["_BinaryenFunctionGetNumVars"](this[THIS_PTR]); + this.numLocals = BinaryenObj["_BinaryenFunctionGetNumLocals"](this[THIS_PTR]); this.vars = getAllNested(func, BinaryenObj["_BinaryenFunctionGetNumVars"], BinaryenObj["_BinaryenFunctionGetVar"]); } - get name(): string { - return UTF8ToString(BinaryenObj["_BinaryenFunctionGetName"](this[THIS_PTR])); - } - - get type(): Type { - return BinaryenObj["_BinaryenFunctionGetType"](this[THIS_PTR]); - } - - get params(): Type { - return BinaryenObj["_BinaryenFunctionGetParams"](this[THIS_PTR]); - } - - get results(): Type { - return BinaryenObj["_BinaryenFunctionGetResults"](this[THIS_PTR]); - } - - get numVars(): number { - return BinaryenObj["_BinaryenFunctionGetNumVars"](this[THIS_PTR]); - } - - get numLocals(): number { - return BinaryenObj["_BinaryenFunctionGetNumLocals"](this[THIS_PTR]); - } - get body(): ExpressionRef { return BinaryenObj["_BinaryenFunctionGetBody"](this[THIS_PTR]); } From 395c0ad47ad4ce4702c33c82aa9a88043e6e19db Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 18:33:39 -0400 Subject: [PATCH 110/247] fix: import/export order --- ts/src/binaryen.ts | 6 +++--- ts/src/globals.ts | 2 +- ts/src/services/expression-builder/control.ts | 6 +++--- ts/src/services/expression-builder/local.ts | 6 +++--- ts/src/services/expression-builder/parametric.ts | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index cf0d3b00e06..dcf786f6455 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -1,6 +1,9 @@ /** @module binaryen.ts */ export * from "./constants.ts"; export * from "./globals.ts"; +export {type SettingsService, settings} from "./services/SettingsService.ts"; +export * as EXPR from "./classes/expression/index.ts"; +export type {ExpressionBuilder} from "./services/expression-builder/expressionBuilder.ts"; export { Feature, Module, @@ -14,13 +17,10 @@ export type {DataSegment, ModuleDataSegments} from "./classes/module/DataSegment export type {ElementSegment, ModuleElementSegments} from "./classes/module/ElementSegment.ts"; export type {Import, ModuleImports} from "./classes/module/Import.ts"; export type {Export, ModuleExports} from "./classes/module/Export.ts"; -export * as EXPR from "./classes/expression/index.ts"; -export type {ExpressionBuilder} from "./services/expression-builder/expressionBuilder.ts"; export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, ExpressionRunnerFlag, } from "./classes/ExpressionRunner.ts"; export {Relooper} from "./classes/Relooper.ts"; -export {type SettingsService, settings} from "./services/SettingsService.ts"; export * from "./-deprecations.ts"; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 3be6d3d3bb9..d90df2f42d6 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -17,7 +17,7 @@ import { } from "./classes/module/Module.ts"; import { Expression, -} from "./classes/expression/Expression.ts"; +} from "./classes/expression/index.ts"; import type { ExpressionId, ExpressionRef, diff --git a/ts/src/services/expression-builder/control.ts b/ts/src/services/expression-builder/control.ts index 4fbd8a97ff5..88c4d5f0cbf 100644 --- a/ts/src/services/expression-builder/control.ts +++ b/ts/src/services/expression-builder/control.ts @@ -1,14 +1,14 @@ import { consoleWarn, } from "../../lib.ts"; -import type { - Module, -} from "../../classes/module/Module.ts"; import { Block, Break, Loop, } from "../../classes/expression/index.ts"; +import type { + Module, +} from "../../classes/module/Module.ts"; diff --git a/ts/src/services/expression-builder/local.ts b/ts/src/services/expression-builder/local.ts index 5403089fe0b..d77e9c955df 100644 --- a/ts/src/services/expression-builder/local.ts +++ b/ts/src/services/expression-builder/local.ts @@ -1,10 +1,10 @@ -import type { - Module, -} from "../../classes/module/Module.ts"; import { LocalGet, LocalSet, } from "../../classes/expression/index.ts"; +import type { + Module, +} from "../../classes/module/Module.ts"; diff --git a/ts/src/services/expression-builder/parametric.ts b/ts/src/services/expression-builder/parametric.ts index 67d2ac0ae94..58500cab28d 100644 --- a/ts/src/services/expression-builder/parametric.ts +++ b/ts/src/services/expression-builder/parametric.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../../-pre.ts"; -import type { - Module, -} from "../../classes/module/Module.ts"; import { Drop, Select, } from "../../classes/expression/index.ts"; +import type { + Module, +} from "../../classes/module/Module.ts"; import type { ExpressionRef, } from "../../constants.ts"; From 848fc1e0e83cd2c9e76d3e31b6d1ecf907efe526 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 19:08:19 -0400 Subject: [PATCH 111/247] fix: `getExpressionInfo()` returns specific expression type --- ts/src/globals.ts | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/ts/src/globals.ts b/ts/src/globals.ts index d90df2f42d6..017e35d5f8c 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -15,15 +15,13 @@ import { type Feature, Module, } from "./classes/module/Module.ts"; +import * as EXPR from "./classes/expression/index.ts"; import { - Expression, -} from "./classes/expression/index.ts"; -import type { ExpressionId, - ExpressionRef, - HeapType, - SideEffect, - Type, + type ExpressionRef, + type HeapType, + type SideEffect, + type Type, } from "./constants.ts"; import { HEAP8, @@ -34,6 +32,19 @@ import { +const EXPRESSION_TYPE_REGISTRY: ReadonlyMap EXPR.Expression> = new Map EXPR.Expression>([ + [ExpressionId.Drop, EXPR.Drop], + [ExpressionId.Select, EXPR.Select], + [ExpressionId.Block, EXPR.Block], + [ExpressionId.Loop, EXPR.Loop], + [ExpressionId.Break, EXPR.Break], + [ExpressionId.LocalGet, EXPR.LocalGet], + [ExpressionId.LocalSet, EXPR.LocalSet], + [ExpressionId.Const, EXPR.Const], +]); + + + /** * Private utility to create a Module from a given pointer. * Users don’t have access to this. @@ -195,8 +206,10 @@ export function getExpressionType(expr: ExpressionRef): Type { * Additional properties depend on the expression’s ID * and are usually equivalent to the respective parameters when creating such an expression. */ -export function getExpressionInfo(expr: ExpressionRef): Expression { - return new Expression(getExpressionId(expr), expr); +export function getExpressionInfo(expr: ExpressionRef): EXPR.Expression { + const id = getExpressionId(expr); + const specificExpression = EXPRESSION_TYPE_REGISTRY.get(id); + return specificExpression ? new specificExpression(expr) : new EXPR.Expression(id, expr); } /** Gets the side effects of the specified expression. */ From d5d458c637e6ebaccebfc1e9cab79c2f79e345ae Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 20:35:46 -0400 Subject: [PATCH 112/247] refactor: move static classes into MOD namespace --- ts/docs/API-Overview.md | 56 +++++------ ts/src/-deprecations.ts | 74 +++++++------- ts/src/binaryen.ts | 10 +- ts/src/classes/expression/index.ts | 2 +- ts/src/classes/module/Module.ts | 149 ++++++++++------------------- ts/src/classes/module/index.ts | 19 ++++ ts/src/constants.ts | 14 +-- 7 files changed, 145 insertions(+), 179 deletions(-) create mode 100644 ts/src/classes/module/index.ts diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index c12f91d9476..2f75dcebbd0 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -81,7 +81,7 @@ import {type Type, type ExpressionRef, i32} from "binaryen.ts"; - `ExpressionId`: an enumeration of values returned by `getExpressionId()` - a slight misnomer, as these are not unique IDs per expression, but different IDs for the “kinds” of expression - `SideEffect`: an enumeration of values returend by `getSideEffects()` -- `ExternalKind`: an enumeration of kinds of exports; serves as type of the `Module.Export#kind` field +- `ExternalKind`: an enumeration of kinds of exports; serves as type of the `MOD.Export#kind` field - `MemoryOrder`: an enumeration of values used in atomic expression methods @@ -108,16 +108,16 @@ Objects: ## Module Manipulation -Properties of `Module` as a namespace: -- `new Module.Tag(ref: TagRef)`: an object containing information about a **Tag** -- `new Module.Global(ref: GlobalRef)`: an object containing information about a **Global** -- `new Module.Memory(mod: Module, name: string)`: an object containing information about a **Memory** -- `new Module.Table(ref: TableRef)`: an object containing information about a **Table** -- `new Module.Function(ref: FunctionRef)`: an object containing information about a **Function** -- `new Module.DataSegment(mod: Module, ref: DataSegmentRef)`: an object containing information about a **Data Segment** -- `new Module.ElementSegment(ref: ElementSegmentRef)`: an object containing information about an **Element Segment** -- `new Module.Import()`: an object containing information about an **Import** (🌱 empty for now) -- `new Module.Export(ref: ExportRef)`: an object containing information about an **Export** +Classes in the `MOD` namespace: +- `new MOD.Tag(ref: TagRef)`: an object containing information about a **Tag** +- `new MOD.Global(ref: GlobalRef)`: an object containing information about a **Global** +- `new MOD.Memory(mod: Module, name: string)`: an object containing information about a **Memory** +- `new MOD.Table(ref: TableRef)`: an object containing information about a **Table** +- `new MOD.Function(ref: FunctionRef)`: an object containing information about a **Function** +- `new MOD.DataSegment(mod: Module, ref: DataSegmentRef)`: an object containing information about a **Data Segment** +- `new MOD.ElementSegment(ref: ElementSegmentRef)`: an object containing information about an **Element Segment** +- `new MOD.Import()`: an object containing information about an **Import** (🌱 empty for now) +- `new MOD.Export(ref: ExportRef)`: an object containing information about an **Export** Properties of `Module` instances (see full list of methods in generated docs): - `Module#wasm`: [build WASM expressions](#expression-building) @@ -260,14 +260,14 @@ Enum names have been singularized. - `ExternalKinds` → `ExternalKind` - `Features` → `Feature` -`*Info` types have been merged with their respective classes in the `Module` namespace. -- `TagInfo` → `Module.Tag` -- `GlobalInfo` → `Module.Global` -- `MemoryInfo` → `Module.Memory` -- `TableInfo` → `Module.Table` -- `FunctionInfo` → `Module.Function` -- `ElementSegmentInfo` → `Module.ElementSegment` -- `ExportInfo` → `Module.Export` +`*Info` types have been merged with their respective classes in the `MOD` namespace. +- `TagInfo` → `MOD.Tag` +- `GlobalInfo` → `MOD.Global` +- `MemoryInfo` → `MOD.Memory` +- `TableInfo` → `MOD.Table` +- `FunctionInfo` → `MOD.Function` +- `ElementSegmentInfo` → `MOD.ElementSegment` +- `ExportInfo` → `MOD.Export` `ExpressionInfo` and related types are now classes in the `EXPR` namespace: - `ExpressionInfo` → `EXPR.Expression` @@ -280,17 +280,17 @@ Enum names have been singularized. ### Modules -Module components previously at the top level have been moved under the `Module` namespace. -- `Function` → `Module.Function` -- `Table` → `Module.Table` +Module components previously at the top level have been moved under the `MOD` namespace. +- `Function` → `MOD.Function` +- `Table` → `MOD.Table` Most `get*Info()` functions have been replaced by their corresponding class constructors. -- `getTagInfo(tag)` → `new Module.Tag(tag)`; -- `getGlobalInfo(global)` → `new Module.Global(global)` -- `getTableInfo(table)` → `new Module.Table(table)` -- `getFunctionInfo(func)` → `new Module.Function(func)` -- `getElementSegmentInfo(segment)` → `new Module.ElementSegment(segment)` -- `getExportInfo(xport)` → `new Module.Export(xport)` +- `getTagInfo(tag)` → `new MOD.Tag(tag)`; +- `getGlobalInfo(global)` → `new MOD.Global(global)` +- `getTableInfo(table)` → `new MOD.Table(table)` +- `getFunctionInfo(func)` → `new MOD.Function(func)` +- `getElementSegmentInfo(segment)` → `new MOD.ElementSegment(segment)` +- `getExportInfo(xport)` → `new MOD.Export(xport)` > - `Module#getMemoryInfo(name)` has not changed. - `Module#getDataSegmentInfo(name)` has not changed. diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index aa139e72743..05ef9fcb59a 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -3,9 +3,9 @@ import type * as EXPR from "./classes/expression/index.ts"; +import * as MOD from "./classes/module/index.ts"; import { Feature, - Module, } from "./classes/module/Module.ts"; import { type ElementSegmentRef, @@ -38,22 +38,22 @@ export const Features = Feature; -/** @deprecated The `TagInfo` object type is now called {@link Module.Tag}. */ -export type TagInfo = Module.Tag; -/** @deprecated The `GlobalInfo` object type is now called {@link Module.Global}. */ -export type GlobalInfo = Module.Global; -/** @deprecated The `MemoryInfo` object type is now called {@link Module.Memory}*/ -export type MemoryInfo = Module.Memory; -/** @deprecated The `TableInfo` object type is now called {@link Module.Table}. */ -export type TableInfo = Module.Table; -/** @deprecated The `FunctionInfo` object type is now called {@link Module.Function}. */ -export type FunctionInfo = Module.Function; +/** @deprecated The `TagInfo` object type is now called {@link MOD.Tag}. */ +export type TagInfo = MOD.Tag; +/** @deprecated The `GlobalInfo` object type is now called {@link MOD.Global}. */ +export type GlobalInfo = MOD.Global; +/** @deprecated The `MemoryInfo` object type is now called {@link MOD.Memory}*/ +export type MemoryInfo = MOD.Memory; +/** @deprecated The `TableInfo` object type is now called {@link MOD.Table}. */ +export type TableInfo = MOD.Table; +/** @deprecated The `FunctionInfo` object type is now called {@link MOD.Function}. */ +export type FunctionInfo = MOD.Function; // type `DataSegmentInfo` never existed -/** @deprecated The `ElementSegmentInfo` object type is now called {@link Module.ElementSegment}. */ -export type ElementSegmentInfo = Module.ElementSegment; +/** @deprecated The `ElementSegmentInfo` object type is now called {@link MOD.ElementSegment}. */ +export type ElementSegmentInfo = MOD.ElementSegment; // type `ImportInfo` never existed -/** @deprecated The `ExportInfo` object type is now called {@link Module.Export}. */ -export type ExportInfo = Module.Export; +/** @deprecated The `ExportInfo` object type is now called {@link MOD.Export}. */ +export type ExportInfo = MOD.Export; @@ -76,45 +76,45 @@ export type LocalSetInfo = EXPR.LocalSet; /** @deprecated The `ConstInfo` object type is now called {@link EXPR.Const}. */ export type ConstInfo = EXPR.Const; -/** @deprecated The `Function` class now lives under the `Module` namespace. Use {@link Module.Function}. */ -export const Function = Module.Function; -/** @deprecated The `Table` class now lives under the `Module` namespace. Use {@link Module.Table}. */ -export const Table = Module.Table; +/** @deprecated The `Function` class now lives under the `MOD` namespace. Use {@link MOD.Function}. */ +export const Function = MOD.Function; +/** @deprecated The `Table` class now lives under the `MOD` namespace. Use {@link MOD.Table}. */ +export const Table = MOD.Table; -/** @deprecated Use {@link Module.Tag | `new Module.Tag(tagref)`} instead. */ +/** @deprecated Use {@link MOD.Tag | `new MOD.Tag(tagref)`} instead. */ export function getTagInfo(tag: TagRef) { - consoleWarn("Global function `getTagInfo` is deprecated; use `new Module.Tag(tagref)` instead."); - return new Module.Tag(tag); + consoleWarn("Global function `getTagInfo` is deprecated; use `new MOD.Tag(tagref)` instead."); + return new MOD.Tag(tag); } -/** @deprecated Use {@link Module.Global | `new Module.Global(globalref)`} instead. */ +/** @deprecated Use {@link MOD.Global | `new MOD.Global(globalref)`} instead. */ export function getGlobalInfo(global: GlobalRef) { - consoleWarn("Global function `getGlobalInfo` is deprecated; use `new Module.Global(globalref)` instead."); - return new Module.Global(global); + consoleWarn("Global function `getGlobalInfo` is deprecated; use `new MOD.Global(globalref)` instead."); + return new MOD.Global(global); } // function `getMemoryInfo` always existed in `Module` -/** @deprecated Use {@link Module.Table | `new Module.Table(tableref)`} instead. */ +/** @deprecated Use {@link MOD.Table | `new MOD.Table(tableref)`} instead. */ export function getTableInfo(table: TableRef) { - consoleWarn("Global function `getTableInfo` is deprecated; use `new Module.Table(tableref)` instead."); - return new Module.Table(table); + consoleWarn("Global function `getTableInfo` is deprecated; use `new MOD.Table(tableref)` instead."); + return new MOD.Table(table); } -/** @deprecated Use {@link Module.Function | `new Module.Function(funcref)`} instead. */ +/** @deprecated Use {@link MOD.Function | `new MOD.Function(funcref)`} instead. */ export function getFunctionInfo(func: FunctionRef) { - consoleWarn("Global function `getFunctionInfo` is deprecated; use `new Module.Function(funcref)` instead."); - return new Module.Function(func); + consoleWarn("Global function `getFunctionInfo` is deprecated; use `new MOD.Function(funcref)` instead."); + return new MOD.Function(func); } // function `getDataSegmentInfo` always existed in `Module` -/** @deprecated Use {@link Module.ElementSegment | `new Module.ElementSegment(segmentref)`} instead. */ +/** @deprecated Use {@link MOD.ElementSegment | `new MOD.ElementSegment(segmentref)`} instead. */ export function getElementSegmentInfo(segment: ElementSegmentRef) { - consoleWarn("Global function `getElementSegmentInfo` is deprecated; use `new Module.ElementSegment(segmentref)` instead."); - return new Module.ElementSegment(segment); + consoleWarn("Global function `getElementSegmentInfo` is deprecated; use `new MOD.ElementSegment(segmentref)` instead."); + return new MOD.ElementSegment(segment); } // no function `getImportInfo` ever existed -/** @deprecated Use {@link Module.Export | `new Module.Export(exportref)`} instead. */ +/** @deprecated Use {@link MOD.Export | `new MOD.Export(exportref)`} instead. */ export function getExportInfo(xport: ExportRef) { - consoleWarn("Global function `getExportInfo` is deprecated; use `new Module.Export(exportref)` instead."); - return new Module.Export(xport); + consoleWarn("Global function `getExportInfo` is deprecated; use `new MOD.Export(exportref)` instead."); + return new MOD.Export(xport); } diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index dcf786f6455..2334e25c47a 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -8,15 +8,7 @@ export { Feature, Module, } from "./classes/module/Module.ts"; -export type {Tag, ModuleTags} from "./classes/module/Tag.ts"; -export type {Global, ModuleGlobals} from "./classes/module/Global.ts"; -export type {Memory, ModuleMemories} from "./classes/module/Memory.ts"; -export type {Table, ModuleTables} from "./classes/module/Table.ts"; -export type {Function as BinaryenFunction, ModuleFunctions} from "./classes/module/Function.ts"; -export type {DataSegment, ModuleDataSegments} from "./classes/module/DataSegment.ts"; -export type {ElementSegment, ModuleElementSegments} from "./classes/module/ElementSegment.ts"; -export type {Import, ModuleImports} from "./classes/module/Import.ts"; -export type {Export, ModuleExports} from "./classes/module/Export.ts"; +export * as MOD from "./classes/module/index.ts"; export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 54b0515769c..b76135653d7 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -4,7 +4,7 @@ * The {@link Expression} class is the root class in the hierarchy; * all other classes in this module extend it and describe specific kinds of expressions. * Each expression type corresponds to an {@link ExpressionId}. - * @module + * @module EXPR */ diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 904e0de0137..75fa224459f 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -107,19 +107,6 @@ export enum Feature { /** * A WASM module. * - * `Module` itself is: - * - an instantiable class (via `new Module()`) - * - a namespace containing the following members, which themselves are classes (see related documentation): - * - {@link Module.Tag} - * - {@link Module.Global} - * - {@link Module.Memory} - * - {@link Module.Table} - * - {@link Module.Function} - * - {@link Module.DataSegment} - * - {@link Module.ElementSegment} - * - {@link Module.Import} - * - {@link Module.Export} - * * Each instance of `Module`: * - is a WASM module with module manipulation methods (`.emitText()`, `.validate()`, etc.). * - is an individual namespace containing mixins, each with its own component manipulation methods (`.tags.add()`, `.globals.get()`, etc): @@ -135,17 +122,6 @@ export enum Feature { * - has a property `.wasm`, a namespace for creating expressions in the module (`.wasm.nop()`, `.wasm.i32.add()`, etc.) */ export class Module { - static readonly Tag = TAG.Tag; - static readonly Global = GLOBAL.Global; - static readonly Memory = MEMORY.Memory; - static readonly Table = TABLE.Table; - static readonly Function = FUNCTION.Function; - static readonly DataSegment = DATA_SEGMENT.DataSegment; - static readonly ElementSegment = ELEMENT_SEGMENT.ElementSegment; - static readonly Import = IMPORT.Import; - static readonly Export = EXPORT.Export; - - readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); /** @@ -226,58 +202,58 @@ export class Module { BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); } - /** @deprecated Use {@link ModuleTags#add | `this.tags.add`} instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } - /** @deprecated Use {@link ModuleTags#add | `this.tags.get`} instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } - /** @deprecated Use {@link ModuleTags#add | `this.tags.remove`} instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } - - /** @deprecated Use {@link ModuleGlobals#add | `this.globals.add`} instead. */ @replacedBy("`this.globals.add`") addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef) { return this.globals.add(name, type, mutable, init); } - /** @deprecated Use {@link ModuleGlobals#get | `this.globals.get`} instead. */ @replacedBy("`this.globals.get`") getGlobal(name: string) { return this.globals.get(name); } - /** @deprecated Use {@link ModuleGlobals#getByIndex | `this.globals.getByIndex`} instead. */ @replacedBy("`this.globals.getByIndex`") getGlobalByIndex(index: number) { return this.globals.getByIndex(index); } - /** @deprecated Use {@link ModuleGlobals#count | `this.globals.count`} instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } - /** @deprecated Use {@link ModuleGlobals#remove | `this.globals.remove`} instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } - - /** @deprecated Use {@link ModuleMemories#set | `this.memories.set`} instead. */ @replacedBy("`this.memories.set`") setMemory(initial: number, maximum: number, exportName: string, segments?: readonly any[], shared?: boolean, memory64?: boolean, internalName?: string) { return this.memories.set(initial, maximum, exportName, segments, shared, memory64, internalName); } - /** @deprecated Use {@link ModuleMemories#has | `this.memories.has`} instead. */ @replacedBy("`this.memories.has`") hasMemory() { return this.memories.has(); } - - /** @deprecated Use {@link ModuleTables#add | `this.tables.add`} instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } - /** @deprecated Use {@link ModuleTables#get | `this.tables.get`} instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } - /** @deprecated Use {@link ModuleTables#getByIndex | `this.tables.getByIndex`} instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } - /** @deprecated Use {@link ModuleTables#getSegments | `this.tables.getSegments`} instead. */ @replacedBy("`this.tables.getSegments`") getTableSegments(table: TableRef) { return this.tables.getSegments(table); } - /** @deprecated Use {@link ModuleTables#count | `this.tables.count`} instead. */ @replacedBy("`this.tables.count`") getNumTables() { return this.tables.count(); } - /** @deprecated Use {@link ModuleTables#remove | `this.tables.remove`} instead. */ @replacedBy("`this.tables.remove`") removeTable(name: string) { return this.tables.remove(name); } - - /** @deprecated Use {@link ModuleFunctions#add | `this.functions.add`} instead. */ @replacedBy("`this.functions.add`") addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef) { return this.functions.add(name, params, results, varTypes, body); } - /** @deprecated Use {@link ModuleFunctions#get | `this.functions.get`} instead. */ @replacedBy("`this.functions.get`") getFunction(name: string) { return this.functions.get(name); } - /** @deprecated Use {@link ModuleFunctions#getByIndex | `this.functions.getByIndex`} instead. */ @replacedBy("`this.functions.getByIndex`") getFunctionByIndex(index: number) { return this.functions.getByIndex(index); } - /** @deprecated Use {@link ModuleFunctions#count | `this.functions.count`} instead. */ @replacedBy("`this.functions.count`") getNumFunctions() { return this.functions.count(); } - /** @deprecated Use {@link ModuleFunctions#remove | `this.functions.remove`} instead. */ @replacedBy("`this.functions.remove`") removeFunction(name: string) { return this.functions.remove(name); } - - /** @deprecated Use {@link ModuleDataSegments#get | `this.dataSegments.get`} instead. */ @replacedBy("`this.dataSegments.get`") getDataSegment(name: string) { return this.dataSegments.get(name); } - /** @deprecated Use {@link ModuleDataSegments#getByIndex | `this.dataSegments.getByIndex`} instead. */ @replacedBy("`this.dataSegments.getByIndex`") getDataSegmentByIndex(index: number) { return this.dataSegments.getByIndex(index); } - /** @deprecated Use {@link ModuleDataSegments#count | `this.dataSegments.count`} instead. */ @replacedBy("`this.dataSegments.count`") getNumDataSegments() { return this.dataSegments.count(); } - - /** @deprecated Use {@link ModuleElementSegments#addActive | `this.elementSegments.addActive`} instead. */ @replacedBy("`this.elementSegments.addActive`") addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef) { return this.elementSegments.addActive(table, name, funcNames, offset); } - /** @deprecated Use {@link ModuleElementSegments#addPassive | `this.elementSegments.addPassive`} instead. */ @replacedBy("`this.elementSegments.addPassive`") addPassiveElementSegment(name: string, funcNames: readonly string[]) { return this.elementSegments.addPassive(name, funcNames); } - /** @deprecated Use {@link ModuleElementSegments#get | `this.elementSegments.get`} instead. */ @replacedBy("`this.elementSegments.get`") getElementSegment(name: string) { return this.elementSegments.get(name); } - /** @deprecated Use {@link ModuleElementSegments#getByIndex | `this.elementSegments.getByIndex`} instead. */ @replacedBy("`this.elementSegments.getByIndex`") getElementSegmentByIndex(index: number) { return this.elementSegments.getByIndex(index); } - /** @deprecated Use {@link ModuleElementSegments#count | `this.elementSegments.count`} instead. */ @replacedBy("`this.elementSegments.count`") getNumElementSegments() { return this.elementSegments.count(); } - /** @deprecated Use {@link ModuleElementSegments#remove | `this.elementSegments.remove`} instead. */ @replacedBy("`this.elementSegments.remove`") removeElementSegment(name: string) { return this.elementSegments.remove(name); } - - /** @deprecated Use {@link ModuleImports#addTag | `this.imports.addTag`} instead. */ @replacedBy("`this.imports.addTag`") addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addTag(internalName, externalModuleName, externalBaseName, params, results); } - /** @deprecated Use {@link ModuleImports#addGlobal | `this.imports.addGlobal`} instead. */ @replacedBy("`this.imports.addGlobal`") addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean) { return this.imports.addGlobal(internalName, externalModuleName, externalBaseName, globalType, mutable); } - /** @deprecated Use {@link ModuleImports#addMemory | `this.imports.addMemory`} instead. */ @replacedBy("`this.imports.addMemory`") addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean) { return this.imports.addMemory(internalName, externalModuleName, externalBaseName, shared); } - /** @deprecated Use {@link ModuleImports#addTable | `this.imports.addTable`} instead. */ @replacedBy("`this.imports.addTable`") addTableImport(internalName: string, externalModuleName: string, externalBaseName: string) { return this.imports.addTable(internalName, externalModuleName, externalBaseName); } - /** @deprecated Use {@link ModuleImports#addFunction | `this.imports.addFunction`} instead. */ @replacedBy("`this.imports.addFunction`") addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addFunction(internalName, externalModuleName, externalBaseName, params, results); } - - /** @deprecated Use {@link ModuleExports#get | `this.exports.get`} instead. */ @replacedBy("`this.exports.get`") getExport(externalName: string) { return this.exports.get(externalName); } - /** @deprecated Use {@link ModuleExports#getByIndex | `this.exports.getByIndex`} instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } - /** @deprecated Use {@link ModuleExports#count | `this.exports.count`} instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } - /** @deprecated Use {@link ModuleExports#remove | `this.exports.remove`} instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } - /** @deprecated Use {@link ModuleExports#addTag | `this.exports.addTag`} instead. */ @replacedBy("`this.exports.addTag`") addTagExport(internalName: string, externalName: string) { return this.exports.addTag(internalName, externalName); } - /** @deprecated Use {@link ModuleExports#addGlobal | `this.exports.addGlobal`} instead. */ @replacedBy("`this.exports.addGlobal`") addGlobalExport(internalName: string, externalName: string) { return this.exports.addGlobal(internalName, externalName); } - /** @deprecated Use {@link ModuleExports#addMemory | `this.exports.addMemory`} instead. */ @replacedBy("`this.exports.addMemory`") addMemoryExport(internalName: string, externalName: string) { return this.exports.addMemory(internalName, externalName); } - /** @deprecated Use {@link ModuleExports#addTable | `this.exports.addTable`} instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } - /** @deprecated Use {@link ModuleExports#addFunction | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } + /** @deprecated Use {@link MOD.ModuleTags#add | `this.tags.add`} instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } + /** @deprecated Use {@link MOD.ModuleTags#add | `this.tags.get`} instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } + /** @deprecated Use {@link MOD.ModuleTags#add | `this.tags.remove`} instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } + + /** @deprecated Use {@link MOD.ModuleGlobals#add | `this.globals.add`} instead. */ @replacedBy("`this.globals.add`") addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef) { return this.globals.add(name, type, mutable, init); } + /** @deprecated Use {@link MOD.ModuleGlobals#get | `this.globals.get`} instead. */ @replacedBy("`this.globals.get`") getGlobal(name: string) { return this.globals.get(name); } + /** @deprecated Use {@link MOD.ModuleGlobals#getByIndex | `this.globals.getByIndex`} instead. */ @replacedBy("`this.globals.getByIndex`") getGlobalByIndex(index: number) { return this.globals.getByIndex(index); } + /** @deprecated Use {@link MOD.ModuleGlobals#count | `this.globals.count`} instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } + /** @deprecated Use {@link MOD.ModuleGlobals#remove | `this.globals.remove`} instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } + + /** @deprecated Use {@link MOD.ModuleMemories#set | `this.memories.set`} instead. */ @replacedBy("`this.memories.set`") setMemory(initial: number, maximum: number, exportName: string, segments?: readonly any[], shared?: boolean, memory64?: boolean, internalName?: string) { return this.memories.set(initial, maximum, exportName, segments, shared, memory64, internalName); } + /** @deprecated Use {@link MOD.ModuleMemories#has | `this.memories.has`} instead. */ @replacedBy("`this.memories.has`") hasMemory() { return this.memories.has(); } + + /** @deprecated Use {@link MOD.ModuleTables#add | `this.tables.add`} instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } + /** @deprecated Use {@link MOD.ModuleTables#get | `this.tables.get`} instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } + /** @deprecated Use {@link MOD.ModuleTables#getByIndex | `this.tables.getByIndex`} instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } + /** @deprecated Use {@link MOD.ModuleTables#getSegments | `this.tables.getSegments`} instead. */ @replacedBy("`this.tables.getSegments`") getTableSegments(table: TableRef) { return this.tables.getSegments(table); } + /** @deprecated Use {@link MOD.ModuleTables#count | `this.tables.count`} instead. */ @replacedBy("`this.tables.count`") getNumTables() { return this.tables.count(); } + /** @deprecated Use {@link MOD.ModuleTables#remove | `this.tables.remove`} instead. */ @replacedBy("`this.tables.remove`") removeTable(name: string) { return this.tables.remove(name); } + + /** @deprecated Use {@link MOD.ModuleFunctions#add | `this.functions.add`} instead. */ @replacedBy("`this.functions.add`") addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef) { return this.functions.add(name, params, results, varTypes, body); } + /** @deprecated Use {@link MOD.ModuleFunctions#get | `this.functions.get`} instead. */ @replacedBy("`this.functions.get`") getFunction(name: string) { return this.functions.get(name); } + /** @deprecated Use {@link MOD.ModuleFunctions#getByIndex | `this.functions.getByIndex`} instead. */ @replacedBy("`this.functions.getByIndex`") getFunctionByIndex(index: number) { return this.functions.getByIndex(index); } + /** @deprecated Use {@link MOD.ModuleFunctions#count | `this.functions.count`} instead. */ @replacedBy("`this.functions.count`") getNumFunctions() { return this.functions.count(); } + /** @deprecated Use {@link MOD.ModuleFunctions#remove | `this.functions.remove`} instead. */ @replacedBy("`this.functions.remove`") removeFunction(name: string) { return this.functions.remove(name); } + + /** @deprecated Use {@link MOD.ModuleDataSegments#get | `this.dataSegments.get`} instead. */ @replacedBy("`this.dataSegments.get`") getDataSegment(name: string) { return this.dataSegments.get(name); } + /** @deprecated Use {@link MOD.ModuleDataSegments#getByIndex | `this.dataSegments.getByIndex`} instead. */ @replacedBy("`this.dataSegments.getByIndex`") getDataSegmentByIndex(index: number) { return this.dataSegments.getByIndex(index); } + /** @deprecated Use {@link MOD.ModuleDataSegments#count | `this.dataSegments.count`} instead. */ @replacedBy("`this.dataSegments.count`") getNumDataSegments() { return this.dataSegments.count(); } + + /** @deprecated Use {@link MOD.ModuleElementSegments#addActive | `this.elementSegments.addActive`} instead. */ @replacedBy("`this.elementSegments.addActive`") addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef) { return this.elementSegments.addActive(table, name, funcNames, offset); } + /** @deprecated Use {@link MOD.ModuleElementSegments#addPassive | `this.elementSegments.addPassive`} instead. */ @replacedBy("`this.elementSegments.addPassive`") addPassiveElementSegment(name: string, funcNames: readonly string[]) { return this.elementSegments.addPassive(name, funcNames); } + /** @deprecated Use {@link MOD.ModuleElementSegments#get | `this.elementSegments.get`} instead. */ @replacedBy("`this.elementSegments.get`") getElementSegment(name: string) { return this.elementSegments.get(name); } + /** @deprecated Use {@link MOD.ModuleElementSegments#getByIndex | `this.elementSegments.getByIndex`} instead. */ @replacedBy("`this.elementSegments.getByIndex`") getElementSegmentByIndex(index: number) { return this.elementSegments.getByIndex(index); } + /** @deprecated Use {@link MOD.ModuleElementSegments#count | `this.elementSegments.count`} instead. */ @replacedBy("`this.elementSegments.count`") getNumElementSegments() { return this.elementSegments.count(); } + /** @deprecated Use {@link MOD.ModuleElementSegments#remove | `this.elementSegments.remove`} instead. */ @replacedBy("`this.elementSegments.remove`") removeElementSegment(name: string) { return this.elementSegments.remove(name); } + + /** @deprecated Use {@link MOD.ModuleImports#addTag | `this.imports.addTag`} instead. */ @replacedBy("`this.imports.addTag`") addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addTag(internalName, externalModuleName, externalBaseName, params, results); } + /** @deprecated Use {@link MOD.ModuleImports#addGlobal | `this.imports.addGlobal`} instead. */ @replacedBy("`this.imports.addGlobal`") addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean) { return this.imports.addGlobal(internalName, externalModuleName, externalBaseName, globalType, mutable); } + /** @deprecated Use {@link MOD.ModuleImports#addMemory | `this.imports.addMemory`} instead. */ @replacedBy("`this.imports.addMemory`") addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean) { return this.imports.addMemory(internalName, externalModuleName, externalBaseName, shared); } + /** @deprecated Use {@link MOD.ModuleImports#addTable | `this.imports.addTable`} instead. */ @replacedBy("`this.imports.addTable`") addTableImport(internalName: string, externalModuleName: string, externalBaseName: string) { return this.imports.addTable(internalName, externalModuleName, externalBaseName); } + /** @deprecated Use {@link MOD.ModuleImports#addFunction | `this.imports.addFunction`} instead. */ @replacedBy("`this.imports.addFunction`") addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addFunction(internalName, externalModuleName, externalBaseName, params, results); } + + /** @deprecated Use {@link MOD.ModuleExports#get | `this.exports.get`} instead. */ @replacedBy("`this.exports.get`") getExport(externalName: string) { return this.exports.get(externalName); } + /** @deprecated Use {@link MOD.ModuleExports#getByIndex | `this.exports.getByIndex`} instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } + /** @deprecated Use {@link MOD.ModuleExports#count | `this.exports.count`} instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } + /** @deprecated Use {@link MOD.ModuleExports#remove | `this.exports.remove`} instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } + /** @deprecated Use {@link MOD.ModuleExports#addTag | `this.exports.addTag`} instead. */ @replacedBy("`this.exports.addTag`") addTagExport(internalName: string, externalName: string) { return this.exports.addTag(internalName, externalName); } + /** @deprecated Use {@link MOD.ModuleExports#addGlobal | `this.exports.addGlobal`} instead. */ @replacedBy("`this.exports.addGlobal`") addGlobalExport(internalName: string, externalName: string) { return this.exports.addGlobal(internalName, externalName); } + /** @deprecated Use {@link MOD.ModuleExports#addMemory | `this.exports.addMemory`} instead. */ @replacedBy("`this.exports.addMemory`") addMemoryExport(internalName: string, externalName: string) { return this.exports.addMemory(internalName, externalName); } + /** @deprecated Use {@link MOD.ModuleExports#addTable | `this.exports.addTable`} instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } + /** @deprecated Use {@link MOD.ModuleExports#addFunction | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } getMemoryInfo(name: string): MEMORY.Memory { return new MEMORY.Memory(this, name); @@ -442,24 +418,3 @@ export class Module { return copyExpression(expr, this); } } - - - -/** - * A collection of types and classes related to WASM module manipulation. - * - * Each class represents a component of a WASM module, - * and its corresponding type is included for documentation. - */ -// eslint-disable-next-line no-redeclare -export namespace Module { - export type Tag = TAG.Tag; - export type Global = GLOBAL.Global; - export type Memory = MEMORY.Memory; - export type Table = TABLE.Table; - export type Function = FUNCTION.Function; - export type DataSegment = DATA_SEGMENT.DataSegment; - export type ElementSegment = ELEMENT_SEGMENT.ElementSegment; - export type Import = IMPORT.Import; - export type Export = EXPORT.Export; -} diff --git a/ts/src/classes/module/index.ts b/ts/src/classes/module/index.ts new file mode 100644 index 00000000000..9e4af733522 --- /dev/null +++ b/ts/src/classes/module/index.ts @@ -0,0 +1,19 @@ +/** + * A collection of types and classes related to WASM module manipulation. + * + * Each class represents a component of a WASM module. + * Additional interfaces for module manipulation are included. + * @module MOD + */ + + + +export {Tag, type ModuleTags} from "./Tag.ts"; +export {Global, type ModuleGlobals} from "./Global.ts"; +export {Memory, type ModuleMemories} from "./Memory.ts"; +export {Table, type ModuleTables} from "./Table.ts"; +export {Function, type ModuleFunctions} from "./Function.ts"; +export {DataSegment, type ModuleDataSegments} from "./DataSegment.ts"; +export {ElementSegment, type ModuleElementSegments} from "./ElementSegment.ts"; +export {Import, type ModuleImports} from "./Import.ts"; +export {Export, type ModuleExports} from "./Export.ts"; diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 1b7433ad142..03db6b28b19 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -17,21 +17,21 @@ export type PackedType = number; export type ExpressionRef = number; // ### Module Components ### // -/** Reference to a {@link Tag}. */ +/** Reference to a {@link MOD.Tag}. */ export type TagRef = number; -/** Reference to a {@link Global}. */ +/** Reference to a {@link MOD.Global}. */ export type GlobalRef = number; // no `MemoryRef` -/** Reference to a {@link Table}. */ +/** Reference to a {@link MOD.Table}. */ export type TableRef = number; -/** Reference to a {@link BinaryenFunction}. */ +/** Reference to a {@link MOD.Function}. */ export type FunctionRef = number; -/** Reference to a {@link DataSegment}. */ +/** Reference to a {@link MOD.DataSegment}. */ export type DataSegmentRef = number; -/** Reference to an {@link ElementSegment}. */ +/** Reference to an {@link MOD.ElementSegment}. */ export type ElementSegmentRef = number; // no `ImportRef` -/** Reference to an {@link Export}. */ +/** Reference to an {@link MOD.Export}. */ export type ExportRef = number; From 19595b2506db563b5fe06db383d44159bd6d1b9e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 20:52:17 -0400 Subject: [PATCH 113/247] refactor: order of ExpressionIds --- ts/docs/API-Overview.md | 8 ++++---- ts/src/classes/expression/Break.ts | 2 +- ts/src/constants.ts | 8 ++++---- ts/src/services/expression-builder/expressionBuilder.ts | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 2f75dcebbd0..3bb26d92eb8 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -168,9 +168,9 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.drop()` - `.select()` - conditionals, blocks, loops, and breaking (“branching”) - - `.if()` - `.block()` - `.loop()` + - `.if()` - `.br()`, `.br_if()`, `.br_table()` - `.br_on_null()`, `.br_on_non_null()`, `.br_on_cast()`, `.br_on_cast_fail()` - function calls, returns, throws, and catching @@ -192,6 +192,9 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.ref.func()`, `.ref.null()`, `.ref.is_null()`, `.ref.as_non_null()`, `.ref.eq()`, `.ref.test()`, `.ref.cast()` - `.ref.i31()`, `i31.get_{s,u}()` - ~~`.extern.convert_any()`, `.any.convert_extern()`~~; ⛔️ not yet supported +- tuples 🌱 (Binaryen-specific) + - `.tuple.make()` + - `.tuple.extract()` - structs and arrays - `.struct.new()`, `.struct.new_default()` - `.struct.get()`, `.struct.get_{s,u}()` @@ -225,9 +228,6 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.{f32,f64}.eq()`, `.{f32,f64}.lt()`, `.{f32,f64}.gt()`, `.{f32,f64}.le()`, `.{f32,f64}.ge()` - `.{f32,f64}.convert_i32_s()`, `.{f32,f64}.convert_i32_u()`, `.{f32,f64}.convert_i64_s()`, `.{f32,f64}.convert_i64_u()` - `.f32.demote_f64()`, `.f64.promote_f32()` -- tuples 🌱 (Binaryen-specific) - - `.tuple.make()` - - `.tuple.extract()` diff --git a/ts/src/classes/expression/Break.ts b/ts/src/classes/expression/Break.ts index 46662b74b2c..596c6e95021 100644 --- a/ts/src/classes/expression/Break.ts +++ b/ts/src/classes/expression/Break.ts @@ -33,7 +33,7 @@ export class Break extends Expression { constructor(expr: ExpressionRef) { - super(ExpressionId.Loop, expr); + super(ExpressionId.Break, expr); } diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 03db6b28b19..8b0c96b6041 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -106,8 +106,6 @@ export enum ExpressionId { // ### Binaryen-Only Instruction Ids ### // Invalid = BinaryenObj["_BinaryenInvalidId"](), Pop = BinaryenObj["_BinaryenPopId"](), - TupleMake = BinaryenObj["_BinaryenTupleMakeId"](), - TupleExtract = BinaryenObj["_BinaryenTupleExtractId"](), // ### Parametric Instruction Ids ### // Nop = BinaryenObj["_BinaryenNopId"](), @@ -162,8 +160,12 @@ export enum ExpressionId { RefEq = BinaryenObj["_BinaryenRefEqId"](), RefTest = BinaryenObj["_BinaryenRefTestId"](), RefCast = BinaryenObj["_BinaryenRefCastId"](), + RefI31 = BinaryenObj["_BinaryenRefI31Id"](), + I31Get = BinaryenObj["_BinaryenI31GetId"](), // ### Aggregate Instruction Ids ### // + TupleMake = BinaryenObj["_BinaryenTupleMakeId"](), + TupleExtract = BinaryenObj["_BinaryenTupleExtractId"](), StructNew = BinaryenObj["_BinaryenStructNewId"](), StructGet = BinaryenObj["_BinaryenStructGetId"](), StructSet = BinaryenObj["_BinaryenStructSetId"](), @@ -178,8 +180,6 @@ export enum ExpressionId { ArrayCopy = BinaryenObj["_BinaryenArrayCopyId"](), ArrayInitData = BinaryenObj["_BinaryenArrayInitDataId"](), ArrayInitElem = BinaryenObj["_BinaryenArrayInitElemId"](), - RefI31 = BinaryenObj["_BinaryenRefI31Id"](), - I31Get = BinaryenObj["_BinaryenI31GetId"](), // ### Numeric & Vector Instruction Ids ### // Const = BinaryenObj["_BinaryenConstId"](), diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index 3dfa6630f8a..9018b1a4a3e 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -76,6 +76,7 @@ export function expressionBuilder(mod: Module) { memory: memory(mod), data: {drop: STUB}, ref: ref(mod), + tuple: tuple(mod), struct: struct(mod), array: array(mod), i31: i31(mod), @@ -85,7 +86,6 @@ export function expressionBuilder(mod: Module) { i64: i64(mod), f32: f32(mod), f64: f64(mod), - tuple: tuple(mod), } as const; } From 8e3c6067c94ee6fb77cbed49f635c7588dca3fae Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 21:53:48 -0400 Subject: [PATCH 114/247] feat: impl deprecated instrs --- ts/src/services/expression-builder/array.ts | 10 +++++--- ts/src/services/expression-builder/f32.ts | 14 +++++++---- ts/src/services/expression-builder/f64.ts | 14 +++++++---- ts/src/services/expression-builder/i32.ts | 26 +++++++++++++------- ts/src/services/expression-builder/i64.ts | 26 +++++++++++++------- ts/src/services/expression-builder/struct.ts | 10 +++++--- 6 files changed, 66 insertions(+), 34 deletions(-) diff --git a/ts/src/services/expression-builder/array.ts b/ts/src/services/expression-builder/array.ts index 83389550370..02ad9f93c6d 100644 --- a/ts/src/services/expression-builder/array.ts +++ b/ts/src/services/expression-builder/array.ts @@ -20,9 +20,13 @@ export function array(_mod: Module) { * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. */ - get: (_ref: number, _index: number, _type: number, deprecated_isSigned?: boolean) => deprecated_isSigned === undefined - ? STUB - : deprecated_isSigned ? /* get_s */ STUB : /* get_u */ STUB, + get: function (index: number, ref: number, type: number, deprecated_isSigned?: boolean) { + return deprecated_isSigned === undefined + ? STUB(index, ref, type) + : deprecated_isSigned + ? this.get_s(index, ref, type) + : this.get_u(index, ref, type); + }, get_s: STUB, get_u: STUB, set: STUB, diff --git a/ts/src/services/expression-builder/f32.ts b/ts/src/services/expression-builder/f32.ts index bf333fcc9f6..804048dece0 100644 --- a/ts/src/services/expression-builder/f32.ts +++ b/ts/src/services/expression-builder/f32.ts @@ -13,7 +13,7 @@ const STUB = (..._args: readonly number[]): number => 0; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ -export function f32(_mod: Module) { +export function f32(mod: Module) { return { const: STUB, @@ -50,13 +50,17 @@ export function f32(_mod: Module) { /** @deprecated */ convert_s: { - /** @deprecated Use `.convert_i32_s()` instead. */ i32: STUB, - /** @deprecated Use `.convert_i64_s()` instead. */ i64: STUB, + // @ts-expect-error + /** @deprecated Use `.convert_i32_s()` instead. */ i32: (...args) => { consoleWarn("`.convert_s.i32()` is deprecated; use `.convert_i32_s()` instead."); return f32(mod).convert_i32_s(...args); }, + // @ts-expect-error + /** @deprecated Use `.convert_i64_s()` instead. */ i64: (...args) => { consoleWarn("`.convert_s.i64()` is deprecated; use `.convert_i64_s()` instead."); return f32(mod).convert_i64_s(...args); }, }, /** @deprecated */ convert_u: { - /** @deprecated Use `.convert_i32_u()` instead. */ i32: STUB, - /** @deprecated Use `.convert_i64_u()` instead. */ i64: STUB, + // @ts-expect-error + /** @deprecated Use `.convert_i32_u()` instead. */ i32: (...args) => { consoleWarn("`.convert_u.i32()` is deprecated; use `.convert_i32_u()` instead."); return f32(mod).convert_i32_u(...args); }, + // @ts-expect-error + /** @deprecated Use `.convert_i64_u()` instead. */ i64: (...args) => { consoleWarn("`.convert_u.i64()` is deprecated; use `.convert_i64_u()` instead."); return f32(mod).convert_i64_u(...args); }, }, // @ts-expect-error /** @deprecated Use `.reinterpret_i32()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_i32()` instead."); return this.reinterpret_i32(...args); }, diff --git a/ts/src/services/expression-builder/f64.ts b/ts/src/services/expression-builder/f64.ts index c4b8d694440..d2f2a4b0db6 100644 --- a/ts/src/services/expression-builder/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -13,7 +13,7 @@ const STUB = (..._args: readonly number[]): number => 0; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ -export function f64(_mod: Module) { +export function f64(mod: Module) { return { const: STUB, @@ -50,13 +50,17 @@ export function f64(_mod: Module) { /** @deprecated */ convert_s: { - /** @deprecated Use `.convert_i32_s()` instead. */ i32: STUB, - /** @deprecated Use `.convert_i64_s()` instead. */ i64: STUB, + // @ts-expect-error + /** @deprecated Use `.convert_i32_s()` instead. */ i32: (...args) => { consoleWarn("`.convert_s.i32()` is deprecated; use `.convert_i32_s()` instead."); return f64(mod).convert_i32_s(...args); }, + // @ts-expect-error + /** @deprecated Use `.convert_i64_s()` instead. */ i64: (...args) => { consoleWarn("`.convert_s.i64()` is deprecated; use `.convert_i64_s()` instead."); return f64(mod).convert_i64_s(...args); }, }, /** @deprecated */ convert_u: { - /** @deprecated Use `.convert_i32_u()` instead. */ i32: STUB, - /** @deprecated Use `.convert_i64_u()` instead. */ i64: STUB, + // @ts-expect-error + /** @deprecated Use `.convert_i32_u()` instead. */ i32: (...args) => { consoleWarn("`.convert_u.i32()` is deprecated; use `.convert_i32_u()` instead."); return f64(mod).convert_i32_u(...args); }, + // @ts-expect-error + /** @deprecated Use `.convert_i64_u()` instead. */ i64: (...args) => { consoleWarn("`.convert_u.i64()` is deprecated; use `.convert_i64_u()` instead."); return f64(mod).convert_i64_u(...args); }, }, // @ts-expect-error /** @deprecated Use `.reinterpret_i64()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_i64()` instead."); return this.reinterpret_i64(...args); }, diff --git a/ts/src/services/expression-builder/i32.ts b/ts/src/services/expression-builder/i32.ts index d44164127ea..a1324274fb4 100644 --- a/ts/src/services/expression-builder/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -13,7 +13,7 @@ const STUB = (..._args: readonly number[]): number => 0; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ -export function i32(_mod: Module) { +export function i32(mod: Module) { return { const: STUB, @@ -69,23 +69,31 @@ export function i32(_mod: Module) { /** @deprecated Use `.wrap_i64()` instead. */ wrap(...args) { consoleWarn("`.wrap()` is deprecated; use `.wrap_i64()` instead."); return this.wrap_i64(...args); }, /** @deprecated */ trunc_s: { - /** @deprecated Use `.trunc_f32_s()` instead. */ f32: STUB, - /** @deprecated Use `.trunc_f64_s()` instead. */ f64: STUB, + // @ts-expect-error + /** @deprecated Use `.trunc_f32_s()` instead. */ f32: (...args) => { consoleWarn("`.trunc_s.f32()` is deprecated; use `.trunc_f32_s()` instead."); return i32(mod).trunc_f32_s(...args); }, + // @ts-expect-error + /** @deprecated Use `.trunc_f64_s()` instead. */ f64: (...args) => { consoleWarn("`.trunc_s.f64()` is deprecated; use `.trunc_f64_s()` instead."); return i32(mod).trunc_f64_s(...args); }, }, /** @deprecated */ trunc_u: { - /** @deprecated Use `.trunc_f32_u()` instead. */ f32: STUB, - /** @deprecated Use `.trunc_f64_u()` instead. */ f64: STUB, + // @ts-expect-error + /** @deprecated Use `.trunc_f32_u()` instead. */ f32: (...args) => { consoleWarn("`.trunc_u.f32()` is deprecated; use `.trunc_f32_u()` instead."); return i32(mod).trunc_f32_u(...args); }, + // @ts-expect-error + /** @deprecated Use `.trunc_f64_u()` instead. */ f64: (...args) => { consoleWarn("`.trunc_u.f64()` is deprecated; use `.trunc_f64_u()` instead."); return i32(mod).trunc_f64_u(...args); }, }, /** @deprecated */ trunc_s_sat: { - /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: STUB, - /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: STUB, + // @ts-expect-error + /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: (...args) => { consoleWarn("`.trunc_s_sat.f32()` is deprecated; use `.trunc_sat_f32_s()` instead."); return i32(mod).trunc_sat_f32_s(...args); }, + // @ts-expect-error + /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: (...args) => { consoleWarn("`.trunc_s_sat.f64()` is deprecated; use `.trunc_sat_f64_s()` instead."); return i32(mod).trunc_sat_f64_s(...args); }, }, /** @deprecated */ trunc_u_sat: { - /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: STUB, - /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: STUB, + // @ts-expect-error + /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: (...args) => { consoleWarn("`.trunc_u_sat.f32()` is deprecated; use `.trunc_sat_f32_u()` instead."); return i32(mod).trunc_sat_f32_u(...args); }, + // @ts-expect-error + /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: (...args) => { consoleWarn("`.trunc_u_sat.f64()` is deprecated; use `.trunc_sat_f64_u()` instead."); return i32(mod).trunc_sat_f64_u(...args); }, }, // @ts-expect-error /** @deprecated Use `.reinterpret_f32()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_f32()` instead."); return this.reinterpret_f32(...args); }, diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index ec84bc1539e..6d8b3f84ade 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -13,7 +13,7 @@ const STUB = (..._args: readonly number[]): number => 0; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ -export function i64(_mod: Module) { +export function i64(mod: Module) { return { const: STUB, @@ -73,23 +73,31 @@ export function i64(_mod: Module) { /** @deprecated Use `.extend_i32_u()` instead. */ extend_u(...args) { consoleWarn("`.extend_u()` is deprecated; use `.extend_i32_u()` instead."); return this.extend_i32_u(...args); }, /** @deprecated */ trunc_s: { - /** @deprecated Use `.trunc_f32_s()` instead. */ f32: STUB, - /** @deprecated Use `.trunc_f64_s()` instead. */ f64: STUB, + // @ts-expect-error + /** @deprecated Use `.trunc_f32_s()` instead. */ f32: (...args) => { consoleWarn("`.trunc_s.f32()` is deprecated; use `.trunc_f32_s()` instead."); return i64(mod).trunc_f32_s(...args); }, + // @ts-expect-error + /** @deprecated Use `.trunc_f64_s()` instead. */ f64: (...args) => { consoleWarn("`.trunc_s.f64()` is deprecated; use `.trunc_f64_s()` instead."); return i64(mod).trunc_f64_s(...args); }, }, /** @deprecated */ trunc_u: { - /** @deprecated Use `.trunc_f32_u()` instead. */ f32: STUB, - /** @deprecated Use `.trunc_f64_u()` instead. */ f64: STUB, + // @ts-expect-error + /** @deprecated Use `.trunc_f32_u()` instead. */ f32: (...args) => { consoleWarn("`.trunc_u.f32()` is deprecated; use `.trunc_f32_u()` instead."); return i64(mod).trunc_f32_u(...args); }, + // @ts-expect-error + /** @deprecated Use `.trunc_f64_u()` instead. */ f64: (...args) => { consoleWarn("`.trunc_u.f64()` is deprecated; use `.trunc_f64_u()` instead."); return i64(mod).trunc_f64_u(...args); }, }, /** @deprecated */ trunc_s_sat: { - /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: STUB, - /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: STUB, + // @ts-expect-error + /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: (...args) => { consoleWarn("`.trunc_s_sat.f32()` is deprecated; use `.trunc_sat_f32_s()` instead."); return i64(mod).trunc_sat_f32_s(...args); }, + // @ts-expect-error + /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: (...args) => { consoleWarn("`.trunc_s_sat.f64()` is deprecated; use `.trunc_sat_f64_s()` instead."); return i64(mod).trunc_sat_f64_s(...args); }, }, /** @deprecated */ trunc_u_sat: { - /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: STUB, - /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: STUB, + // @ts-expect-error + /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: (...args) => { consoleWarn("`.trunc_u_sat.f32()` is deprecated; use `.trunc_sat_f32_u()` instead."); return i64(mod).trunc_sat_f32_u(...args); }, + // @ts-expect-error + /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: (...args) => { consoleWarn("`.trunc_u_sat.f64()` is deprecated; use `.trunc_sat_f64_u()` instead."); return i64(mod).trunc_sat_f64_u(...args); }, }, // @ts-expect-error /** @deprecated Use `.reinterpret_f64()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_f64()` instead."); return this.reinterpret_f64(...args); }, diff --git a/ts/src/services/expression-builder/struct.ts b/ts/src/services/expression-builder/struct.ts index b9bcf4733be..5a645d6cc0a 100644 --- a/ts/src/services/expression-builder/struct.ts +++ b/ts/src/services/expression-builder/struct.ts @@ -17,9 +17,13 @@ export function struct(_mod: Module) { * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. */ - get: (_index: number, _ref: number, _type: number, deprecated_isSigned?: boolean) => deprecated_isSigned === undefined - ? STUB - : deprecated_isSigned ? /* get_s */ STUB : /* get_u */ STUB, + get: function (index: number, ref: number, type: number, deprecated_isSigned?: boolean) { + return deprecated_isSigned === undefined + ? STUB(index, ref, type) + : deprecated_isSigned + ? this.get_s(index, ref, type) + : this.get_u(index, ref, type); + }, get_s: STUB, get_u: STUB, set: STUB, From 2f2e4c4769d8d48b6d3265f7f645a571bc62d0d4 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 22:26:08 -0400 Subject: [PATCH 115/247] feat: add control classes --- ts/src/classes/expression/BrOn.ts | 15 +++++++++++++++ ts/src/classes/expression/Call.ts | 15 +++++++++++++++ ts/src/classes/expression/CallIndirect.ts | 15 +++++++++++++++ ts/src/classes/expression/CallRef.ts | 15 +++++++++++++++ ts/src/classes/expression/If.ts | 15 +++++++++++++++ ts/src/classes/expression/Rethrow.ts | 15 +++++++++++++++ ts/src/classes/expression/Return.ts | 15 +++++++++++++++ ts/src/classes/expression/Switch.ts | 15 +++++++++++++++ ts/src/classes/expression/Throw.ts | 15 +++++++++++++++ ts/src/classes/expression/Try.ts | 15 +++++++++++++++ ts/src/classes/expression/index.ts | 10 ++++++++++ ts/src/globals.ts | 17 +++++++++++++++++ 12 files changed, 177 insertions(+) create mode 100644 ts/src/classes/expression/BrOn.ts create mode 100644 ts/src/classes/expression/Call.ts create mode 100644 ts/src/classes/expression/CallIndirect.ts create mode 100644 ts/src/classes/expression/CallRef.ts create mode 100644 ts/src/classes/expression/If.ts create mode 100644 ts/src/classes/expression/Rethrow.ts create mode 100644 ts/src/classes/expression/Return.ts create mode 100644 ts/src/classes/expression/Switch.ts create mode 100644 ts/src/classes/expression/Throw.ts create mode 100644 ts/src/classes/expression/Try.ts diff --git a/ts/src/classes/expression/BrOn.ts b/ts/src/classes/expression/BrOn.ts new file mode 100644 index 00000000000..c7464a77a5f --- /dev/null +++ b/ts/src/classes/expression/BrOn.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class BrOn extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.BrOn, expr); + } +} diff --git a/ts/src/classes/expression/Call.ts b/ts/src/classes/expression/Call.ts new file mode 100644 index 00000000000..141da4ff199 --- /dev/null +++ b/ts/src/classes/expression/Call.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Call extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Call, expr); + } +} diff --git a/ts/src/classes/expression/CallIndirect.ts b/ts/src/classes/expression/CallIndirect.ts new file mode 100644 index 00000000000..a0dbb98c941 --- /dev/null +++ b/ts/src/classes/expression/CallIndirect.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class CallIndirect extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.CallIndirect, expr); + } +} diff --git a/ts/src/classes/expression/CallRef.ts b/ts/src/classes/expression/CallRef.ts new file mode 100644 index 00000000000..bf8d6777a7e --- /dev/null +++ b/ts/src/classes/expression/CallRef.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class CallRef extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.CallRef, expr); + } +} diff --git a/ts/src/classes/expression/If.ts b/ts/src/classes/expression/If.ts new file mode 100644 index 00000000000..4e60acf31a1 --- /dev/null +++ b/ts/src/classes/expression/If.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class If extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.If, expr); + } +} diff --git a/ts/src/classes/expression/Rethrow.ts b/ts/src/classes/expression/Rethrow.ts new file mode 100644 index 00000000000..9ee3f991ed6 --- /dev/null +++ b/ts/src/classes/expression/Rethrow.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Rethrow extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Rethrow, expr); + } +} diff --git a/ts/src/classes/expression/Return.ts b/ts/src/classes/expression/Return.ts new file mode 100644 index 00000000000..d0eee26f99d --- /dev/null +++ b/ts/src/classes/expression/Return.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Return extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Return, expr); + } +} diff --git a/ts/src/classes/expression/Switch.ts b/ts/src/classes/expression/Switch.ts new file mode 100644 index 00000000000..8f26a12d844 --- /dev/null +++ b/ts/src/classes/expression/Switch.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Switch extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Switch, expr); + } +} diff --git a/ts/src/classes/expression/Throw.ts b/ts/src/classes/expression/Throw.ts new file mode 100644 index 00000000000..deaf1267866 --- /dev/null +++ b/ts/src/classes/expression/Throw.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Throw extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Throw, expr); + } +} diff --git a/ts/src/classes/expression/Try.ts b/ts/src/classes/expression/Try.ts new file mode 100644 index 00000000000..6690da7fe70 --- /dev/null +++ b/ts/src/classes/expression/Try.ts @@ -0,0 +1,15 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Try extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Try, expr); + } +} diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index b76135653d7..3efff9bd697 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -18,7 +18,17 @@ export {Select} from "./Select.ts"; // ## Control ## // export {Block} from "./Block.ts"; export {Loop} from "./Loop.ts"; +export {If} from "./If.ts"; export {Break} from "./Break.ts"; +export {Switch} from "./Switch.ts"; +export {BrOn} from "./BrOn.ts"; +export {Call} from "./Call.ts"; +export {CallRef} from "./CallRef.ts"; +export {CallIndirect} from "./CallIndirect.ts"; +export {Return} from "./Return.ts"; +export {Throw} from "./Throw.ts"; +export {Rethrow} from "./Rethrow.ts"; +export {Try} from "./Try.ts"; // ## Variable ## // export {LocalGet} from "./LocalGet.ts"; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 017e35d5f8c..d1efe088dda 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -33,13 +33,30 @@ import { const EXPRESSION_TYPE_REGISTRY: ReadonlyMap EXPR.Expression> = new Map EXPR.Expression>([ + // Parametric Instructions [ExpressionId.Drop, EXPR.Drop], [ExpressionId.Select, EXPR.Select], + + // Control Instructions [ExpressionId.Block, EXPR.Block], [ExpressionId.Loop, EXPR.Loop], + [ExpressionId.If, EXPR.If], [ExpressionId.Break, EXPR.Break], + [ExpressionId.Switch, EXPR.Switch], + [ExpressionId.BrOn, EXPR.BrOn], + [ExpressionId.Call, EXPR.Call], + [ExpressionId.CallRef, EXPR.CallRef], + [ExpressionId.CallIndirect, EXPR.CallIndirect], + [ExpressionId.Return, EXPR.Return], + [ExpressionId.Throw, EXPR.Throw], + [ExpressionId.Rethrow, EXPR.Rethrow], + [ExpressionId.Try, EXPR.Try], + + // Variable Instructions [ExpressionId.LocalGet, EXPR.LocalGet], [ExpressionId.LocalSet, EXPR.LocalSet], + + // Numeric & Vector Instructions [ExpressionId.Const, EXPR.Const], ]); From 22e4cb49d5c21c66d18477a0e434aef21c4b2dc7 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 4 May 2026 22:52:22 -0400 Subject: [PATCH 116/247] perf: use tail calls in `preserveStack` --- ts/src/classes/module/ElementSegment.ts | 4 +--- ts/src/classes/module/Export.ts | 4 +--- ts/src/classes/module/Function.ts | 4 +--- ts/src/classes/module/Global.ts | 4 +--- ts/src/classes/module/Import.ts | 16 +++++++--------- ts/src/classes/module/Module.ts | 20 +++++--------------- ts/src/classes/module/Table.ts | 4 +--- ts/src/classes/module/Tag.ts | 4 +--- ts/src/services/SettingsService.ts | 8 ++------ 9 files changed, 20 insertions(+), 48 deletions(-) diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index 4ed711561ae..1b430e5ac31 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -90,8 +90,6 @@ export class ModuleElementSegments { /** Removes an element segment by name. */ remove(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveElementSegment"](this.mod.ptr, strToStack(name)); - }); + preserveStack(() => BinaryenObj["_BinaryenRemoveElementSegment"](this.mod.ptr, strToStack(name))); } } diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index ba53cb46acf..db23f730257 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -58,9 +58,7 @@ export class ModuleExports { /** Removes an export, by external name. */ remove(externalName: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveExport"](this.mod.ptr, strToStack(externalName)); - }); + preserveStack(() => BinaryenObj["_BinaryenRemoveExport"](this.mod.ptr, strToStack(externalName))); } /** Adds a tag export. */ diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index f7d44ad8ef3..06ae076ac0a 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -123,8 +123,6 @@ export class ModuleFunctions { /** Removes a function by name. */ remove(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveFunction"](this.mod.ptr, strToStack(name)); - }); + preserveStack(() => BinaryenObj["_BinaryenRemoveFunction"](this.mod.ptr, strToStack(name))); } } diff --git a/ts/src/classes/module/Global.ts b/ts/src/classes/module/Global.ts index 9a8da7e2547..6064f5aa44c 100644 --- a/ts/src/classes/module/Global.ts +++ b/ts/src/classes/module/Global.ts @@ -70,8 +70,6 @@ export class ModuleGlobals { /** Removes a global by name. */ remove(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveGlobal"](this.mod.ptr, strToStack(name)); - }); + preserveStack(() => BinaryenObj["_BinaryenRemoveGlobal"](this.mod.ptr, strToStack(name))); } } diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index c75bcb349a5..3d94909c58a 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -56,14 +56,12 @@ export class ModuleImports { } #addComponent(binaryenFuncName: string, internalName: string, externalModuleName: string, externalBaseName: string, ...rest: any[]): void { - return preserveStack(() => { - BinaryenObj[binaryenFuncName]( - this.mod.ptr, - strToStack(internalName), - strToStack(externalModuleName), - strToStack(externalBaseName), - ...rest, - ); - }); + preserveStack(() => BinaryenObj[binaryenFuncName]( + this.mod.ptr, + strToStack(internalName), + strToStack(externalModuleName), + strToStack(externalBaseName), + ...rest, + )); } } diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 75fa224459f..4010e972a3c 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -354,9 +354,7 @@ export class Module { /** Runs the specified passes on the module. */ runPasses(passes: readonly string[]): void { - return preserveStack(() => { - BinaryenObj["_BinaryenModuleRunPasses"](this.ptr, i32sToStack(passes.map(strToStack)), passes.length); - }); + preserveStack(() => BinaryenObj["_BinaryenModuleRunPasses"](this.ptr, i32sToStack(passes.map(strToStack)), passes.length)); } /** Runs the specified passes on a single function. */ @@ -364,9 +362,7 @@ export class Module { if (typeof func === "string") { func = this.functions.get(func); } - return preserveStack(() => { - BinaryenObj["_BinaryenFunctionRunPasses"](func, this.ptr, i32sToStack(passes.map(strToStack)), passes.length); - }); + preserveStack(() => BinaryenObj["_BinaryenFunctionRunPasses"](func, this.ptr, i32sToStack(passes.map(strToStack)), passes.length)); } // ### Debugging ### // @@ -388,23 +384,17 @@ export class Module { // ### Other ### // /** [description] */ setTypeName(heapType: HeapType, name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenModuleSetTypeName"](this.ptr, heapType, strToStack(name)); - }); + preserveStack(() => BinaryenObj["_BinaryenModuleSetTypeName"](this.ptr, heapType, strToStack(name))); } /** [description] */ setFieldName(heapType: HeapType, index: number, name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenModuleSetFieldName"](this.ptr, heapType, index, strToStack(name)); - }); + preserveStack(() => BinaryenObj["_BinaryenModuleSetFieldName"](this.ptr, heapType, index, strToStack(name))); } /** Adds a custom section to the binary. */ addCustomSection(name: string, contents: Uint8Array): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddCustomSection"](this.ptr, strToStack(name), i8sToStack([...contents]), contents.length); - }); + preserveStack(() => BinaryenObj["_BinaryenAddCustomSection"](this.ptr, strToStack(name), i8sToStack([...contents]), contents.length)); } /** [description] */ diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 65a6a4433f8..029933d2034 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -111,8 +111,6 @@ export class ModuleTables { /** Removes a table by name. */ remove(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveTable"](this.mod.ptr, strToStack(name)); - }); + preserveStack(() => BinaryenObj["_BinaryenRemoveTable"](this.mod.ptr, strToStack(name))); } } diff --git a/ts/src/classes/module/Tag.ts b/ts/src/classes/module/Tag.ts index eef70b1d6b0..07e6aec067c 100644 --- a/ts/src/classes/module/Tag.ts +++ b/ts/src/classes/module/Tag.ts @@ -57,8 +57,6 @@ export class ModuleTags { /** Removes a tag by name. */ remove(name: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenRemoveTag"](this.mod.ptr, strToStack(name)); - }); + preserveStack(() => BinaryenObj["_BinaryenRemoveTag"](this.mod.ptr, strToStack(name))); } } diff --git a/ts/src/services/SettingsService.ts b/ts/src/services/SettingsService.ts index 990decbd87f..dd7a67bffc2 100644 --- a/ts/src/services/SettingsService.ts +++ b/ts/src/services/SettingsService.ts @@ -80,9 +80,7 @@ export class SettingsService { * Removes the respective argument if `value` is `undefined` or an empty string. */ setPassArgument(key: string, value?: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenSetPassArgument"](strToStack(key), strToStack(value)); - }); + preserveStack(() => BinaryenObj["_BinaryenSetPassArgument"](strToStack(key), strToStack(value))); } /** Clears all arbitrary pass arguments. */ @@ -97,9 +95,7 @@ export class SettingsService { /** Add a pass to the set of passes to skip. */ addPassToSkip(pass: string): void { - return preserveStack(() => { - BinaryenObj["_BinaryenAddPassToSkip"](strToStack(pass)); - }); + preserveStack(() => BinaryenObj["_BinaryenAddPassToSkip"](strToStack(pass))); } /** Clears the set of passes to skip. */ From 37ffd498a35e8f3daa83026e753e100d9055c6e1 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 00:04:14 -0400 Subject: [PATCH 117/247] feat: add control class instance methods --- ts/src/classes/expression/BrOn.ts | 23 ++++ ts/src/classes/expression/Call.ts | 60 +++++++++++ ts/src/classes/expression/CallIndirect.ts | 70 +++++++++++++ ts/src/classes/expression/CallRef.ts | 32 ++++++ ts/src/classes/expression/If.ts | 16 +++ ts/src/classes/expression/Rethrow.ts | 19 ++++ ts/src/classes/expression/Return.ts | 10 ++ ts/src/classes/expression/Select.ts | 6 +- ts/src/classes/expression/Switch.ts | 69 ++++++++++++ ts/src/classes/expression/Throw.ts | 57 ++++++++++ ts/src/classes/expression/Try.ts | 122 ++++++++++++++++++++++ ts/src/classes/module/Table.ts | 2 +- 12 files changed, 482 insertions(+), 4 deletions(-) diff --git a/ts/src/classes/expression/BrOn.ts b/ts/src/classes/expression/BrOn.ts index c7464a77a5f..fdc229a9824 100644 --- a/ts/src/classes/expression/BrOn.ts +++ b/ts/src/classes/expression/BrOn.ts @@ -1,7 +1,17 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, + type Type, } from "../../constants.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +22,17 @@ export class BrOn extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.BrOn, expr); } + + + get op(): number { return BinaryenObj["_BinaryenBrOnGetOp"](this[THIS_PTR]); } + set op(op: number) { BinaryenObj["_BinaryenBrOnSetOp"](this[THIS_PTR], op); } + + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenBrOnGetName"](this[THIS_PTR])); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenBrOnSetName"](this[THIS_PTR], strToStack(name))); } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenBrOnGetRef"](this[THIS_PTR]); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenBrOnSetRef"](this[THIS_PTR], ref); } + + get castType(): Type { return BinaryenObj["_BinaryenBrOnGetCastType"](this[THIS_PTR]); } + set castType(castType: Type) { BinaryenObj["_BinaryenBrOnSetCastType"](this[THIS_PTR], castType); } } diff --git a/ts/src/classes/expression/Call.ts b/ts/src/classes/expression/Call.ts index 141da4ff199..82f00d0884b 100644 --- a/ts/src/classes/expression/Call.ts +++ b/ts/src/classes/expression/Call.ts @@ -1,7 +1,18 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; +import { + THIS_PTR, + getAllNested, + preserveStack, + setAllNested, + strToStack, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +23,53 @@ export class Call extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.Call, expr); } + + + get target(): string { return UTF8ToString(BinaryenObj["_BinaryenCallGetTarget"](this[THIS_PTR])); } + set target(targetName: string) { preserveStack(() => BinaryenObj["_BinaryenCallSetTarget"](this[THIS_PTR], strToStack(targetName))); } + + get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIsReturn"](this[THIS_PTR])); } + set return(isReturn: boolean) { BinaryenObj["_BinaryenCallSetReturn"](this[THIS_PTR], isReturn); } + + get numOperands(): number { return BinaryenObj["_BinaryenCallGetNumOperands"](this[THIS_PTR]); } + + get operands(): ExpressionRef[] { + return getAllNested( + this[THIS_PTR], + BinaryenObj["_BinaryenCallGetNumOperands"], + BinaryenObj["_BinaryenCallGetOperandAt"], + ); + } + + set operands(operands: readonly ExpressionRef[]) { + setAllNested( + this[THIS_PTR], + operands, + BinaryenObj["_BinaryenCallGetNumOperands"], + BinaryenObj["_BinaryenCallSetOperandAt"], + BinaryenObj["_BinaryenCallAppendOperand"], + BinaryenObj["_BinaryenCallRemoveOperandAt"], + ); + } + + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallGetOperandAt"](this[THIS_PTR], index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallSetOperandAt"](this[THIS_PTR], index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenCallAppendOperand"](this[THIS_PTR], operandExpr); + } + + insertOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallInsertOperandAt"](this[THIS_PTR], index, operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallRemoveOperandAt"](this[THIS_PTR], index); + } } diff --git a/ts/src/classes/expression/CallIndirect.ts b/ts/src/classes/expression/CallIndirect.ts index a0dbb98c941..04c1f5752b6 100644 --- a/ts/src/classes/expression/CallIndirect.ts +++ b/ts/src/classes/expression/CallIndirect.ts @@ -1,7 +1,19 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, + type Type, } from "../../constants.ts"; +import { + THIS_PTR, + getAllNested, + preserveStack, + setAllNested, + strToStack, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +24,62 @@ export class CallIndirect extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.CallIndirect, expr); } + + + get target(): ExpressionRef { return BinaryenObj["_BinaryenCallIndirectGetTarget"](this[THIS_PTR]); } + set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallIndirectSetTarget"](this[THIS_PTR], targetExpr); } + + get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIndirectIsReturn"](this[THIS_PTR])); } + set return(isReturn: boolean) { BinaryenObj["_BinaryenCallIndirectSetReturn"](this[THIS_PTR], isReturn); } + + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenCallIndirectGetTable"](this[THIS_PTR])); } + set table(table: string) { preserveStack(() => BinaryenObj["_BinaryenCallIndirectSetTable"](this[THIS_PTR], strToStack(table))); } + + get params(): Type {return BinaryenObj["_BinaryenCallIndirectGetParams"](this[THIS_PTR]);} + set params(params: Type) { BinaryenObj["_BinaryenCallIndirectSetParams"](this[THIS_PTR], params); } + + get results(): Type { return BinaryenObj["_BinaryenCallIndirectGetResults"](this[THIS_PTR]); } + set results(results: Type) { BinaryenObj["_BinaryenCallIndirectSetResults"](this[THIS_PTR], results); } + + get numOperands(): number { return BinaryenObj["_BinaryenCallIndirectGetNumOperands"](this[THIS_PTR]); } + + get operands(): ExpressionRef[] { + return getAllNested( + this[THIS_PTR], + BinaryenObj["_BinaryenCallIndirectGetNumOperands"], + BinaryenObj["_BinaryenCallIndirectGetOperandAt"], + ); + } + + set operands(operands: readonly ExpressionRef[]) { + setAllNested( + this[THIS_PTR], + operands, + BinaryenObj["_BinaryenCallIndirectGetNumOperands"], + BinaryenObj["_BinaryenCallIndirectSetOperandAt"], + BinaryenObj["_BinaryenCallIndirectAppendOperand"], + BinaryenObj["_BinaryenCallIndirectRemoveOperandAt"], + ); + } + + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallIndirectGetOperandAt"](this[THIS_PTR], index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallIndirectSetOperandAt"](this[THIS_PTR], index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenCallIndirectAppendOperand"](this[THIS_PTR], operandExpr); + } + + insertOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallIndirectInsertOperandAt"](this[THIS_PTR], index, operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallIndirectRemoveOperandAt"](this[THIS_PTR], index); + } } diff --git a/ts/src/classes/expression/CallRef.ts b/ts/src/classes/expression/CallRef.ts index bf8d6777a7e..ae5363951c2 100644 --- a/ts/src/classes/expression/CallRef.ts +++ b/ts/src/classes/expression/CallRef.ts @@ -1,7 +1,13 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; +import { + THIS_PTR, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +18,30 @@ export class CallRef extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.CallRef, expr); } + + + get target(): ExpressionRef { return BinaryenObj["_BinaryenCallRefGetTarget"](this[THIS_PTR]); } + set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallRefSetTarget"](this[THIS_PTR], targetExpr); } + + get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallRefIsReturn"](this[THIS_PTR])); } + set return(isReturn: boolean) { BinaryenObj["_BinaryenCallRefSetReturn"](this[THIS_PTR], isReturn); } + + get numOperands(): number { return BinaryenObj["_BinaryenCallRefGetNumOperands"](this[THIS_PTR]); } + + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallRefGetOperandAt"](this[THIS_PTR], index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallRefSetOperandAt"](this[THIS_PTR], index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenCallRefAppendOperand"](this[THIS_PTR], operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallRefRemoveOperandAt"](this[THIS_PTR], index); + } } diff --git a/ts/src/classes/expression/If.ts b/ts/src/classes/expression/If.ts index 4e60acf31a1..2e827c75f16 100644 --- a/ts/src/classes/expression/If.ts +++ b/ts/src/classes/expression/If.ts @@ -1,7 +1,13 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; +import { + THIS_PTR, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +18,14 @@ export class If extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.If, expr); } + + + get condition(): ExpressionRef { return BinaryenObj["_BinaryenIfGetCondition"](this[THIS_PTR]); } + set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetCondition"](condExpr); } + + get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfTrue"](this[THIS_PTR]); } + set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfTrue"](this[THIS_PTR], ifTrueExpr); } + + get ifFalse(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfFalse"](this[THIS_PTR]); } + set ifFalse(ifFalseExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfFalse"](this[THIS_PTR], ifFalseExpr); } } diff --git a/ts/src/classes/expression/Rethrow.ts b/ts/src/classes/expression/Rethrow.ts index 9ee3f991ed6..0a534bd67c9 100644 --- a/ts/src/classes/expression/Rethrow.ts +++ b/ts/src/classes/expression/Rethrow.ts @@ -1,7 +1,16 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +21,14 @@ export class Rethrow extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.Rethrow, expr); } + + + get target(): string | null { + const target = BinaryenObj["_BinaryenRethrowGetTarget"](this[THIS_PTR]); + return target ? UTF8ToString(target) : null; + } + + set target(target: string) { + preserveStack(() => BinaryenObj["_BinaryenRethrowSetTarget"](this[THIS_PTR], strToStack(target))); + } } diff --git a/ts/src/classes/expression/Return.ts b/ts/src/classes/expression/Return.ts index d0eee26f99d..727eac9749d 100644 --- a/ts/src/classes/expression/Return.ts +++ b/ts/src/classes/expression/Return.ts @@ -1,7 +1,13 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; +import { + THIS_PTR, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +18,8 @@ export class Return extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.Return, expr); } + + + get value(): ExpressionRef { return BinaryenObj["_BinaryenReturnGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenReturnSetValue"](this[THIS_PTR], valueExpr); } } diff --git a/ts/src/classes/expression/Select.ts b/ts/src/classes/expression/Select.ts index 8e6e532ecb8..8d07d2711f8 100644 --- a/ts/src/classes/expression/Select.ts +++ b/ts/src/classes/expression/Select.ts @@ -29,12 +29,12 @@ export class Select extends Expression { } + get condition(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetCondition"](this[THIS_PTR]); } + set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetCondition"](this[THIS_PTR], condExpr); } + get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetIfTrue"](this[THIS_PTR]); } set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetIfTrue"](this[THIS_PTR], ifTrueExpr); } get ifFalse(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetIfFalse"](this[THIS_PTR]); } set ifFalse(ifFalseExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetIfFalse"](this[THIS_PTR], ifFalseExpr); } - - get condition(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetCondition"](this[THIS_PTR]); } - set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetCondition"](this[THIS_PTR], condExpr); } } diff --git a/ts/src/classes/expression/Switch.ts b/ts/src/classes/expression/Switch.ts index 8f26a12d844..2bfd1406878 100644 --- a/ts/src/classes/expression/Switch.ts +++ b/ts/src/classes/expression/Switch.ts @@ -1,7 +1,18 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; +import { + THIS_PTR, + getAllNested, + preserveStack, + setAllNested, + strToStack, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +23,62 @@ export class Switch extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.Switch, expr); } + + + get condition(): ExpressionRef { return BinaryenObj["_BinaryenSwitchGetCondition"](this[THIS_PTR]); } + set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSwitchSetCondition"](condExpr); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenSwitchGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenSwitchSetValue"](valueExpr); } + + get numNames(): number { return BinaryenObj["_BinaryenSwitchGetNumNames"](this[THIS_PTR]); } + + get names(): string[] { + return getAllNested( + this[THIS_PTR], + BinaryenObj["_BinaryenSwitchGetNumNames"], + BinaryenObj["_BinaryenSwitchGetNameAt"], + ).map((p) => UTF8ToString(p)); + } + + set names(names: readonly string[]) { + preserveStack(() => setAllNested( + this[THIS_PTR], + names.map(strToStack), + BinaryenObj["_BinaryenSwitchGetNumNames"], + BinaryenObj["_BinaryenSwitchSetNameAt"], + BinaryenObj["_BinaryenSwitchAppendName"], + BinaryenObj["_BinaryenSwitchRemoveNameAt"], + )); + } + + get defaultName(): string | null { + const name = BinaryenObj["_BinaryenSwitchGetDefaultName"](this[THIS_PTR]); + return name ? UTF8ToString(name) : null; + } + + set defaultName(defaultName: string) { + preserveStack(() => BinaryenObj["_BinaryenSwitchSetDefaultName"](this[THIS_PTR], strToStack(defaultName))); + } + + + getNameAt(index: number): string { + return UTF8ToString(BinaryenObj["_BinaryenSwitchGetNameAt"](this[THIS_PTR], index)); + } + + setNameAt(index: number, name: string): void { + preserveStack(() => BinaryenObj["_BinaryenSwitchSetNameAt"](this[THIS_PTR], index, strToStack(name))); + } + + appendName(name: string): void { + preserveStack(() => BinaryenObj["_BinaryenSwitchAppendName"](this[THIS_PTR], strToStack(name))); + } + + insertNameAt(index: number, name: string): void { + preserveStack(() => BinaryenObj["_BinaryenSwitchInsertNameAt"](this[THIS_PTR], index, strToStack(name))); + } + + removeNameAt(index: number): string { + return UTF8ToString(BinaryenObj["_BinaryenSwitchRemoveNameAt"](this[THIS_PTR], index)); + } } diff --git a/ts/src/classes/expression/Throw.ts b/ts/src/classes/expression/Throw.ts index deaf1267866..d3f5ab1a3ef 100644 --- a/ts/src/classes/expression/Throw.ts +++ b/ts/src/classes/expression/Throw.ts @@ -1,7 +1,18 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; +import { + THIS_PTR, + getAllNested, + preserveStack, + setAllNested, + strToStack, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +23,50 @@ export class Throw extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.Throw, expr); } + + + getTag(): string { return UTF8ToString(BinaryenObj["_BinaryenThrowGetTag"](this[THIS_PTR])); } + setTag(tagName: string) { preserveStack(() => BinaryenObj["_BinaryenThrowSetTag"](this[THIS_PTR], strToStack(tagName))); } + + getNumOperands(): number { return BinaryenObj["_BinaryenThrowGetNumOperands"](this[THIS_PTR]); } + + getOperands(): ExpressionRef[] { + return getAllNested( + this[THIS_PTR], + BinaryenObj["_BinaryenThrowGetNumOperands"], + BinaryenObj["_BinaryenThrowGetOperandAt"], + ); + } + + setOperands(operands: readonly ExpressionRef[]) { + setAllNested( + this[THIS_PTR], + operands, + BinaryenObj["_BinaryenThrowGetNumOperands"], + BinaryenObj["_BinaryenThrowSetOperandAt"], + BinaryenObj["_BinaryenThrowAppendOperand"], + BinaryenObj["_BinaryenThrowRemoveOperandAt"], + ); + } + + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenThrowGetOperandAt"](this[THIS_PTR], index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenThrowSetOperandAt"](this[THIS_PTR], index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenThrowAppendOperand"](this[THIS_PTR], operandExpr); + } + + insertOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenThrowInsertOperandAt"](this[THIS_PTR], index, operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenThrowRemoveOperandAt"](this[THIS_PTR], index); + } } diff --git a/ts/src/classes/expression/Try.ts b/ts/src/classes/expression/Try.ts index 6690da7fe70..1f10cc77c66 100644 --- a/ts/src/classes/expression/Try.ts +++ b/ts/src/classes/expression/Try.ts @@ -1,7 +1,18 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; +import { + THIS_PTR, + getAllNested, + preserveStack, + strToStack, + setAllNested, +} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; @@ -12,4 +23,115 @@ export class Try extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.Try, expr); } + + + get body(): ExpressionRef { return BinaryenObj["_BinaryenTryGetBody"](this[THIS_PTR]); } + set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenTrySetBody"](this[THIS_PTR], bodyExpr); } + + get numCatchTags(): number { return BinaryenObj["_BinaryenTryGetNumCatchTags"](this[THIS_PTR]); } + + get numCatchBodies(): number { return BinaryenObj["_BinaryenTryGetNumCatchBodies"](this[THIS_PTR]); } + + get delegate(): boolean { return Boolean(BinaryenObj["_BinaryenTryIsDelegate"](this[THIS_PTR])); } + + get name(): string | null { + const name = BinaryenObj["_BinaryenTryGetName"](this[THIS_PTR]); + return name ? UTF8ToString(name) : null; + } + + set name(name: string) { + preserveStack(() => BinaryenObj["_BinaryenTrySetName"](this[THIS_PTR], strToStack(name))); + } + + get catchTags(): string[] { + return getAllNested( + this[THIS_PTR], + BinaryenObj["_BinaryenTryGetNumCatchTags"], + BinaryenObj["_BinaryenTryGetCatchTagAt"], + ).map((p) => UTF8ToString(p)); + } + + set catchTags(catchTags: readonly string[]) { + preserveStack(() => setAllNested( + this[THIS_PTR], + catchTags.map(strToStack), + BinaryenObj["_BinaryenTryGetNumCatchTags"], + BinaryenObj["_BinaryenTrySetCatchTagAt"], + BinaryenObj["_BinaryenTryAppendCatchTag"], + BinaryenObj["_BinaryenTryRemoveCatchTagAt"], + )); + } + + get catchBodies(): ExpressionRef[] { + return getAllNested( + this[THIS_PTR], + BinaryenObj["_BinaryenTryGetNumCatchBodies"], + BinaryenObj["_BinaryenTryGetCatchBodyAt"], + ); + } + + set catchBodies(catchBodies: readonly ExpressionRef[]) { + setAllNested( + this[THIS_PTR], + catchBodies, + BinaryenObj["_BinaryenTryGetNumCatchBodies"], + BinaryenObj["_BinaryenTrySetCatchBodyAt"], + BinaryenObj["_BinaryenTryAppendCatchBody"], + BinaryenObj["_BinaryenTryRemoveCatchBodyAt"], + ); + } + + get delegateTarget(): string | null { + const name = BinaryenObj["_BinaryenTryGetDelegateTarget"](this[THIS_PTR]); + return name ? UTF8ToString(name) : null; + } + + set delegateTarget(name: string) { + preserveStack(() => BinaryenObj["_BinaryenTrySetDelegateTarget"](this[THIS_PTR], strToStack(name))); + } + + + getCatchTagAt(index: number): string { + return UTF8ToString(BinaryenObj["_BinaryenTryGetCatchTagAt"](this[THIS_PTR], index)); + } + + setCatchTagAt(index: number, catchTag: string): void { + preserveStack(() => BinaryenObj["_BinaryenTrySetCatchTagAt"](this[THIS_PTR], index, strToStack(catchTag))); + } + + appendCatchTag(catchTag: string): void { + preserveStack(() => BinaryenObj["_BinaryenTryAppendCatchTag"](this[THIS_PTR], strToStack(catchTag))); + } + + insertCatchTagAt(index: number, catchTag: string): void { + preserveStack(() => BinaryenObj["_BinaryenTryInsertCatchTagAt"](this[THIS_PTR], index, strToStack(catchTag))); + } + + removeCatchTagAt(index: number): string { + return UTF8ToString(BinaryenObj["_BinaryenTryRemoveCatchTagAt"](this[THIS_PTR], index)); + } + + getCatchBodyAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenTryGetCatchBodyAt"](this[THIS_PTR], index); + } + + setCatchBodyAt(index: number, catchExpr: ExpressionRef): void { + BinaryenObj["_BinaryenTrySetCatchBodyAt"](this[THIS_PTR], index, catchExpr); + } + + appendCatchBody(catchExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenTryAppendCatchBody"](this[THIS_PTR], catchExpr); + } + + insertCatchBodyAt(index: number, catchExpr: ExpressionRef): void { + BinaryenObj["_BinaryenTryInsertCatchBodyAt"](this[THIS_PTR], index, catchExpr); + } + + removeCatchBodyAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenTryRemoveCatchBodyAt"](this[THIS_PTR], index); + } + + hasCatchAll(): boolean { + return Boolean(BinaryenObj["_BinaryenTryHasCatchAll"](this[THIS_PTR])); + } } diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 029933d2034..189d3975823 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -40,7 +40,7 @@ export class Table { /** The name of this table */ get name(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetName"](this[THIS_PTR])); } - set name(name: string) { preserveStack(() => { BinaryenObj["_BinaryenTableSetName"](this[THIS_PTR], strToStack(name)); }); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableSetName"](this[THIS_PTR], strToStack(name))); } /** The initial number of pages of this table. */ get initial(): number { return BinaryenObj["_BinaryenTableGetInitial"](this[THIS_PTR]); } From dd6112d019fc240f1f6ae9d361c1b6ed17c91f17 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 18:10:50 -0400 Subject: [PATCH 118/247] Revert "refactor: move static classes into MOD namespace" This reverts commit d5d458c637e6ebaccebfc1e9cab79c2f79e345ae. --- ts/docs/API-Overview.md | 56 ++++----- ts/src/-deprecations.ts | 74 ++++++------ ts/src/binaryen.ts | 10 +- ts/src/classes/module/DataSegment.ts | 2 +- ts/src/classes/module/ElementSegment.ts | 2 +- ts/src/classes/module/Export.ts | 2 +- ts/src/classes/module/Function.ts | 2 +- ts/src/classes/module/Global.ts | 2 +- ts/src/classes/module/Import.ts | 2 +- ts/src/classes/module/Memory.ts | 2 +- ts/src/classes/module/Module.ts | 149 +++++++++++++++--------- ts/src/classes/module/Table.ts | 2 +- ts/src/classes/module/Tag.ts | 2 +- ts/src/classes/module/index.ts | 19 --- ts/src/constants.ts | 14 +-- 15 files changed, 187 insertions(+), 153 deletions(-) delete mode 100644 ts/src/classes/module/index.ts diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 3bb26d92eb8..6e6cf244bee 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -81,7 +81,7 @@ import {type Type, type ExpressionRef, i32} from "binaryen.ts"; - `ExpressionId`: an enumeration of values returned by `getExpressionId()` - a slight misnomer, as these are not unique IDs per expression, but different IDs for the “kinds” of expression - `SideEffect`: an enumeration of values returend by `getSideEffects()` -- `ExternalKind`: an enumeration of kinds of exports; serves as type of the `MOD.Export#kind` field +- `ExternalKind`: an enumeration of kinds of exports; serves as type of the `Module.Export#kind` field - `MemoryOrder`: an enumeration of values used in atomic expression methods @@ -108,16 +108,16 @@ Objects: ## Module Manipulation -Classes in the `MOD` namespace: -- `new MOD.Tag(ref: TagRef)`: an object containing information about a **Tag** -- `new MOD.Global(ref: GlobalRef)`: an object containing information about a **Global** -- `new MOD.Memory(mod: Module, name: string)`: an object containing information about a **Memory** -- `new MOD.Table(ref: TableRef)`: an object containing information about a **Table** -- `new MOD.Function(ref: FunctionRef)`: an object containing information about a **Function** -- `new MOD.DataSegment(mod: Module, ref: DataSegmentRef)`: an object containing information about a **Data Segment** -- `new MOD.ElementSegment(ref: ElementSegmentRef)`: an object containing information about an **Element Segment** -- `new MOD.Import()`: an object containing information about an **Import** (🌱 empty for now) -- `new MOD.Export(ref: ExportRef)`: an object containing information about an **Export** +Properties of `Module` as a namespace: +- `new Module.Tag(ref: TagRef)`: an object containing information about a **Tag** +- `new Module.Global(ref: GlobalRef)`: an object containing information about a **Global** +- `new Module.Memory(mod: Module, name: string)`: an object containing information about a **Memory** +- `new Module.Table(ref: TableRef)`: an object containing information about a **Table** +- `new Module.Function(ref: FunctionRef)`: an object containing information about a **Function** +- `new Module.DataSegment(mod: Module, ref: DataSegmentRef)`: an object containing information about a **Data Segment** +- `new Module.ElementSegment(ref: ElementSegmentRef)`: an object containing information about an **Element Segment** +- `new Module.Import()`: an object containing information about an **Import** (🌱 empty for now) +- `new Module.Export(ref: ExportRef)`: an object containing information about an **Export** Properties of `Module` instances (see full list of methods in generated docs): - `Module#wasm`: [build WASM expressions](#expression-building) @@ -260,14 +260,14 @@ Enum names have been singularized. - `ExternalKinds` → `ExternalKind` - `Features` → `Feature` -`*Info` types have been merged with their respective classes in the `MOD` namespace. -- `TagInfo` → `MOD.Tag` -- `GlobalInfo` → `MOD.Global` -- `MemoryInfo` → `MOD.Memory` -- `TableInfo` → `MOD.Table` -- `FunctionInfo` → `MOD.Function` -- `ElementSegmentInfo` → `MOD.ElementSegment` -- `ExportInfo` → `MOD.Export` +`*Info` types have been merged with their respective classes in the `Module` namespace. +- `TagInfo` → `Module.Tag` +- `GlobalInfo` → `Module.Global` +- `MemoryInfo` → `Module.Memory` +- `TableInfo` → `Module.Table` +- `FunctionInfo` → `Module.Function` +- `ElementSegmentInfo` → `Module.ElementSegment` +- `ExportInfo` → `Module.Export` `ExpressionInfo` and related types are now classes in the `EXPR` namespace: - `ExpressionInfo` → `EXPR.Expression` @@ -280,17 +280,17 @@ Enum names have been singularized. ### Modules -Module components previously at the top level have been moved under the `MOD` namespace. -- `Function` → `MOD.Function` -- `Table` → `MOD.Table` +Module components previously at the top level have been moved under the `Module` namespace. +- `Function` → `Module.Function` +- `Table` → `Module.Table` Most `get*Info()` functions have been replaced by their corresponding class constructors. -- `getTagInfo(tag)` → `new MOD.Tag(tag)`; -- `getGlobalInfo(global)` → `new MOD.Global(global)` -- `getTableInfo(table)` → `new MOD.Table(table)` -- `getFunctionInfo(func)` → `new MOD.Function(func)` -- `getElementSegmentInfo(segment)` → `new MOD.ElementSegment(segment)` -- `getExportInfo(xport)` → `new MOD.Export(xport)` +- `getTagInfo(tag)` → `new Module.Tag(tag)`; +- `getGlobalInfo(global)` → `new Module.Global(global)` +- `getTableInfo(table)` → `new Module.Table(table)` +- `getFunctionInfo(func)` → `new Module.Function(func)` +- `getElementSegmentInfo(segment)` → `new Module.ElementSegment(segment)` +- `getExportInfo(xport)` → `new Module.Export(xport)` > - `Module#getMemoryInfo(name)` has not changed. - `Module#getDataSegmentInfo(name)` has not changed. diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 05ef9fcb59a..aa139e72743 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -3,9 +3,9 @@ import type * as EXPR from "./classes/expression/index.ts"; -import * as MOD from "./classes/module/index.ts"; import { Feature, + Module, } from "./classes/module/Module.ts"; import { type ElementSegmentRef, @@ -38,22 +38,22 @@ export const Features = Feature; -/** @deprecated The `TagInfo` object type is now called {@link MOD.Tag}. */ -export type TagInfo = MOD.Tag; -/** @deprecated The `GlobalInfo` object type is now called {@link MOD.Global}. */ -export type GlobalInfo = MOD.Global; -/** @deprecated The `MemoryInfo` object type is now called {@link MOD.Memory}*/ -export type MemoryInfo = MOD.Memory; -/** @deprecated The `TableInfo` object type is now called {@link MOD.Table}. */ -export type TableInfo = MOD.Table; -/** @deprecated The `FunctionInfo` object type is now called {@link MOD.Function}. */ -export type FunctionInfo = MOD.Function; +/** @deprecated The `TagInfo` object type is now called {@link Module.Tag}. */ +export type TagInfo = Module.Tag; +/** @deprecated The `GlobalInfo` object type is now called {@link Module.Global}. */ +export type GlobalInfo = Module.Global; +/** @deprecated The `MemoryInfo` object type is now called {@link Module.Memory}*/ +export type MemoryInfo = Module.Memory; +/** @deprecated The `TableInfo` object type is now called {@link Module.Table}. */ +export type TableInfo = Module.Table; +/** @deprecated The `FunctionInfo` object type is now called {@link Module.Function}. */ +export type FunctionInfo = Module.Function; // type `DataSegmentInfo` never existed -/** @deprecated The `ElementSegmentInfo` object type is now called {@link MOD.ElementSegment}. */ -export type ElementSegmentInfo = MOD.ElementSegment; +/** @deprecated The `ElementSegmentInfo` object type is now called {@link Module.ElementSegment}. */ +export type ElementSegmentInfo = Module.ElementSegment; // type `ImportInfo` never existed -/** @deprecated The `ExportInfo` object type is now called {@link MOD.Export}. */ -export type ExportInfo = MOD.Export; +/** @deprecated The `ExportInfo` object type is now called {@link Module.Export}. */ +export type ExportInfo = Module.Export; @@ -76,45 +76,45 @@ export type LocalSetInfo = EXPR.LocalSet; /** @deprecated The `ConstInfo` object type is now called {@link EXPR.Const}. */ export type ConstInfo = EXPR.Const; -/** @deprecated The `Function` class now lives under the `MOD` namespace. Use {@link MOD.Function}. */ -export const Function = MOD.Function; -/** @deprecated The `Table` class now lives under the `MOD` namespace. Use {@link MOD.Table}. */ -export const Table = MOD.Table; +/** @deprecated The `Function` class now lives under the `Module` namespace. Use {@link Module.Function}. */ +export const Function = Module.Function; +/** @deprecated The `Table` class now lives under the `Module` namespace. Use {@link Module.Table}. */ +export const Table = Module.Table; -/** @deprecated Use {@link MOD.Tag | `new MOD.Tag(tagref)`} instead. */ +/** @deprecated Use {@link Module.Tag | `new Module.Tag(tagref)`} instead. */ export function getTagInfo(tag: TagRef) { - consoleWarn("Global function `getTagInfo` is deprecated; use `new MOD.Tag(tagref)` instead."); - return new MOD.Tag(tag); + consoleWarn("Global function `getTagInfo` is deprecated; use `new Module.Tag(tagref)` instead."); + return new Module.Tag(tag); } -/** @deprecated Use {@link MOD.Global | `new MOD.Global(globalref)`} instead. */ +/** @deprecated Use {@link Module.Global | `new Module.Global(globalref)`} instead. */ export function getGlobalInfo(global: GlobalRef) { - consoleWarn("Global function `getGlobalInfo` is deprecated; use `new MOD.Global(globalref)` instead."); - return new MOD.Global(global); + consoleWarn("Global function `getGlobalInfo` is deprecated; use `new Module.Global(globalref)` instead."); + return new Module.Global(global); } // function `getMemoryInfo` always existed in `Module` -/** @deprecated Use {@link MOD.Table | `new MOD.Table(tableref)`} instead. */ +/** @deprecated Use {@link Module.Table | `new Module.Table(tableref)`} instead. */ export function getTableInfo(table: TableRef) { - consoleWarn("Global function `getTableInfo` is deprecated; use `new MOD.Table(tableref)` instead."); - return new MOD.Table(table); + consoleWarn("Global function `getTableInfo` is deprecated; use `new Module.Table(tableref)` instead."); + return new Module.Table(table); } -/** @deprecated Use {@link MOD.Function | `new MOD.Function(funcref)`} instead. */ +/** @deprecated Use {@link Module.Function | `new Module.Function(funcref)`} instead. */ export function getFunctionInfo(func: FunctionRef) { - consoleWarn("Global function `getFunctionInfo` is deprecated; use `new MOD.Function(funcref)` instead."); - return new MOD.Function(func); + consoleWarn("Global function `getFunctionInfo` is deprecated; use `new Module.Function(funcref)` instead."); + return new Module.Function(func); } // function `getDataSegmentInfo` always existed in `Module` -/** @deprecated Use {@link MOD.ElementSegment | `new MOD.ElementSegment(segmentref)`} instead. */ +/** @deprecated Use {@link Module.ElementSegment | `new Module.ElementSegment(segmentref)`} instead. */ export function getElementSegmentInfo(segment: ElementSegmentRef) { - consoleWarn("Global function `getElementSegmentInfo` is deprecated; use `new MOD.ElementSegment(segmentref)` instead."); - return new MOD.ElementSegment(segment); + consoleWarn("Global function `getElementSegmentInfo` is deprecated; use `new Module.ElementSegment(segmentref)` instead."); + return new Module.ElementSegment(segment); } // no function `getImportInfo` ever existed -/** @deprecated Use {@link MOD.Export | `new MOD.Export(exportref)`} instead. */ +/** @deprecated Use {@link Module.Export | `new Module.Export(exportref)`} instead. */ export function getExportInfo(xport: ExportRef) { - consoleWarn("Global function `getExportInfo` is deprecated; use `new MOD.Export(exportref)` instead."); - return new MOD.Export(xport); + consoleWarn("Global function `getExportInfo` is deprecated; use `new Module.Export(exportref)` instead."); + return new Module.Export(xport); } diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index 2334e25c47a..b877720ccfd 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -8,7 +8,15 @@ export { Feature, Module, } from "./classes/module/Module.ts"; -export * as MOD from "./classes/module/index.ts"; +export {Tag, type ModuleTags} from "./classes/module/Tag.ts"; +export {Global, type ModuleGlobals} from "./classes/module/Global.ts"; +export {Memory, type ModuleMemories} from "./classes/module/Memory.ts"; +export {Table, type ModuleTables} from "./classes/module/Table.ts"; +export {Function, type ModuleFunctions} from "./classes/module/Function.ts"; +export {DataSegment, type ModuleDataSegments} from "./classes/module/DataSegment.ts"; +export {ElementSegment, type ModuleElementSegments} from "./classes/module/ElementSegment.ts"; +export {Import, type ModuleImports} from "./classes/module/Import.ts"; +export {Export, type ModuleExports} from "./classes/module/Export.ts"; export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index bc7c2317397..a2ec3ae7c4c 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -50,7 +50,7 @@ export class DataSegment { /** - * Methods for manipulating {@link DataSegment | data segments} in a WASM module. + * Methods for manipulating {@link Module.DataSegment | data segments} in a WASM module. */ export class ModuleDataSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index 4ed711561ae..6e7c1999a70 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -46,7 +46,7 @@ export class ElementSegment { /** - * Methods for manipulating {@link ElementSegment | element segments} in a WASM module. + * Methods for manipulating {@link Module.ElementSegment | element segments} in a WASM module. */ export class ModuleElementSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index ba53cb46acf..b40c3bb48c6 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -36,7 +36,7 @@ export class Export { /** - * Methods for manipulating {@link Export | exports} in a WASM module. + * Methods for manipulating {@link Module.Export | exports} in a WASM module. */ export class ModuleExports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index f7d44ad8ef3..8d2a9f35b51 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -88,7 +88,7 @@ export {BinaryenFunction as Function}; /** - * Methods for manipulating {@link BinaryenFunction | functions} in a WASM module. + * Methods for manipulating {@link Module.Function | functions} in a WASM module. */ export class ModuleFunctions { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Global.ts b/ts/src/classes/module/Global.ts index 9a8da7e2547..b3ce49a8307 100644 --- a/ts/src/classes/module/Global.ts +++ b/ts/src/classes/module/Global.ts @@ -43,7 +43,7 @@ export class Global { /** - * Methods for manipulating {@link Global | globals} in a WASM module. + * Methods for manipulating {@link Module.Global | globals} in a WASM module. */ export class ModuleGlobals { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index c75bcb349a5..692f0ce8483 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -25,7 +25,7 @@ export class Import { /** - * Methods for manipulating {@link Import | imports} in a WASM module. + * Methods for manipulating {@link Module.Import | imports} in a WASM module. */ export class ModuleImports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index 50f5e1b4ef7..d1df08d6eaf 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -60,7 +60,7 @@ export class Memory { /** - * Methods for manipulating {@link Memory | memories} in a WASM module. + * Methods for manipulating {@link Module.Memory | memories} in a WASM module. */ export class ModuleMemories { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 75fa224459f..904e0de0137 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -107,6 +107,19 @@ export enum Feature { /** * A WASM module. * + * `Module` itself is: + * - an instantiable class (via `new Module()`) + * - a namespace containing the following members, which themselves are classes (see related documentation): + * - {@link Module.Tag} + * - {@link Module.Global} + * - {@link Module.Memory} + * - {@link Module.Table} + * - {@link Module.Function} + * - {@link Module.DataSegment} + * - {@link Module.ElementSegment} + * - {@link Module.Import} + * - {@link Module.Export} + * * Each instance of `Module`: * - is a WASM module with module manipulation methods (`.emitText()`, `.validate()`, etc.). * - is an individual namespace containing mixins, each with its own component manipulation methods (`.tags.add()`, `.globals.get()`, etc): @@ -122,6 +135,17 @@ export enum Feature { * - has a property `.wasm`, a namespace for creating expressions in the module (`.wasm.nop()`, `.wasm.i32.add()`, etc.) */ export class Module { + static readonly Tag = TAG.Tag; + static readonly Global = GLOBAL.Global; + static readonly Memory = MEMORY.Memory; + static readonly Table = TABLE.Table; + static readonly Function = FUNCTION.Function; + static readonly DataSegment = DATA_SEGMENT.DataSegment; + static readonly ElementSegment = ELEMENT_SEGMENT.ElementSegment; + static readonly Import = IMPORT.Import; + static readonly Export = EXPORT.Export; + + readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); /** @@ -202,58 +226,58 @@ export class Module { BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); } - /** @deprecated Use {@link MOD.ModuleTags#add | `this.tags.add`} instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } - /** @deprecated Use {@link MOD.ModuleTags#add | `this.tags.get`} instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } - /** @deprecated Use {@link MOD.ModuleTags#add | `this.tags.remove`} instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } - - /** @deprecated Use {@link MOD.ModuleGlobals#add | `this.globals.add`} instead. */ @replacedBy("`this.globals.add`") addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef) { return this.globals.add(name, type, mutable, init); } - /** @deprecated Use {@link MOD.ModuleGlobals#get | `this.globals.get`} instead. */ @replacedBy("`this.globals.get`") getGlobal(name: string) { return this.globals.get(name); } - /** @deprecated Use {@link MOD.ModuleGlobals#getByIndex | `this.globals.getByIndex`} instead. */ @replacedBy("`this.globals.getByIndex`") getGlobalByIndex(index: number) { return this.globals.getByIndex(index); } - /** @deprecated Use {@link MOD.ModuleGlobals#count | `this.globals.count`} instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } - /** @deprecated Use {@link MOD.ModuleGlobals#remove | `this.globals.remove`} instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } - - /** @deprecated Use {@link MOD.ModuleMemories#set | `this.memories.set`} instead. */ @replacedBy("`this.memories.set`") setMemory(initial: number, maximum: number, exportName: string, segments?: readonly any[], shared?: boolean, memory64?: boolean, internalName?: string) { return this.memories.set(initial, maximum, exportName, segments, shared, memory64, internalName); } - /** @deprecated Use {@link MOD.ModuleMemories#has | `this.memories.has`} instead. */ @replacedBy("`this.memories.has`") hasMemory() { return this.memories.has(); } - - /** @deprecated Use {@link MOD.ModuleTables#add | `this.tables.add`} instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } - /** @deprecated Use {@link MOD.ModuleTables#get | `this.tables.get`} instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } - /** @deprecated Use {@link MOD.ModuleTables#getByIndex | `this.tables.getByIndex`} instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } - /** @deprecated Use {@link MOD.ModuleTables#getSegments | `this.tables.getSegments`} instead. */ @replacedBy("`this.tables.getSegments`") getTableSegments(table: TableRef) { return this.tables.getSegments(table); } - /** @deprecated Use {@link MOD.ModuleTables#count | `this.tables.count`} instead. */ @replacedBy("`this.tables.count`") getNumTables() { return this.tables.count(); } - /** @deprecated Use {@link MOD.ModuleTables#remove | `this.tables.remove`} instead. */ @replacedBy("`this.tables.remove`") removeTable(name: string) { return this.tables.remove(name); } - - /** @deprecated Use {@link MOD.ModuleFunctions#add | `this.functions.add`} instead. */ @replacedBy("`this.functions.add`") addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef) { return this.functions.add(name, params, results, varTypes, body); } - /** @deprecated Use {@link MOD.ModuleFunctions#get | `this.functions.get`} instead. */ @replacedBy("`this.functions.get`") getFunction(name: string) { return this.functions.get(name); } - /** @deprecated Use {@link MOD.ModuleFunctions#getByIndex | `this.functions.getByIndex`} instead. */ @replacedBy("`this.functions.getByIndex`") getFunctionByIndex(index: number) { return this.functions.getByIndex(index); } - /** @deprecated Use {@link MOD.ModuleFunctions#count | `this.functions.count`} instead. */ @replacedBy("`this.functions.count`") getNumFunctions() { return this.functions.count(); } - /** @deprecated Use {@link MOD.ModuleFunctions#remove | `this.functions.remove`} instead. */ @replacedBy("`this.functions.remove`") removeFunction(name: string) { return this.functions.remove(name); } - - /** @deprecated Use {@link MOD.ModuleDataSegments#get | `this.dataSegments.get`} instead. */ @replacedBy("`this.dataSegments.get`") getDataSegment(name: string) { return this.dataSegments.get(name); } - /** @deprecated Use {@link MOD.ModuleDataSegments#getByIndex | `this.dataSegments.getByIndex`} instead. */ @replacedBy("`this.dataSegments.getByIndex`") getDataSegmentByIndex(index: number) { return this.dataSegments.getByIndex(index); } - /** @deprecated Use {@link MOD.ModuleDataSegments#count | `this.dataSegments.count`} instead. */ @replacedBy("`this.dataSegments.count`") getNumDataSegments() { return this.dataSegments.count(); } - - /** @deprecated Use {@link MOD.ModuleElementSegments#addActive | `this.elementSegments.addActive`} instead. */ @replacedBy("`this.elementSegments.addActive`") addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef) { return this.elementSegments.addActive(table, name, funcNames, offset); } - /** @deprecated Use {@link MOD.ModuleElementSegments#addPassive | `this.elementSegments.addPassive`} instead. */ @replacedBy("`this.elementSegments.addPassive`") addPassiveElementSegment(name: string, funcNames: readonly string[]) { return this.elementSegments.addPassive(name, funcNames); } - /** @deprecated Use {@link MOD.ModuleElementSegments#get | `this.elementSegments.get`} instead. */ @replacedBy("`this.elementSegments.get`") getElementSegment(name: string) { return this.elementSegments.get(name); } - /** @deprecated Use {@link MOD.ModuleElementSegments#getByIndex | `this.elementSegments.getByIndex`} instead. */ @replacedBy("`this.elementSegments.getByIndex`") getElementSegmentByIndex(index: number) { return this.elementSegments.getByIndex(index); } - /** @deprecated Use {@link MOD.ModuleElementSegments#count | `this.elementSegments.count`} instead. */ @replacedBy("`this.elementSegments.count`") getNumElementSegments() { return this.elementSegments.count(); } - /** @deprecated Use {@link MOD.ModuleElementSegments#remove | `this.elementSegments.remove`} instead. */ @replacedBy("`this.elementSegments.remove`") removeElementSegment(name: string) { return this.elementSegments.remove(name); } - - /** @deprecated Use {@link MOD.ModuleImports#addTag | `this.imports.addTag`} instead. */ @replacedBy("`this.imports.addTag`") addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addTag(internalName, externalModuleName, externalBaseName, params, results); } - /** @deprecated Use {@link MOD.ModuleImports#addGlobal | `this.imports.addGlobal`} instead. */ @replacedBy("`this.imports.addGlobal`") addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean) { return this.imports.addGlobal(internalName, externalModuleName, externalBaseName, globalType, mutable); } - /** @deprecated Use {@link MOD.ModuleImports#addMemory | `this.imports.addMemory`} instead. */ @replacedBy("`this.imports.addMemory`") addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean) { return this.imports.addMemory(internalName, externalModuleName, externalBaseName, shared); } - /** @deprecated Use {@link MOD.ModuleImports#addTable | `this.imports.addTable`} instead. */ @replacedBy("`this.imports.addTable`") addTableImport(internalName: string, externalModuleName: string, externalBaseName: string) { return this.imports.addTable(internalName, externalModuleName, externalBaseName); } - /** @deprecated Use {@link MOD.ModuleImports#addFunction | `this.imports.addFunction`} instead. */ @replacedBy("`this.imports.addFunction`") addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addFunction(internalName, externalModuleName, externalBaseName, params, results); } - - /** @deprecated Use {@link MOD.ModuleExports#get | `this.exports.get`} instead. */ @replacedBy("`this.exports.get`") getExport(externalName: string) { return this.exports.get(externalName); } - /** @deprecated Use {@link MOD.ModuleExports#getByIndex | `this.exports.getByIndex`} instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } - /** @deprecated Use {@link MOD.ModuleExports#count | `this.exports.count`} instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } - /** @deprecated Use {@link MOD.ModuleExports#remove | `this.exports.remove`} instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } - /** @deprecated Use {@link MOD.ModuleExports#addTag | `this.exports.addTag`} instead. */ @replacedBy("`this.exports.addTag`") addTagExport(internalName: string, externalName: string) { return this.exports.addTag(internalName, externalName); } - /** @deprecated Use {@link MOD.ModuleExports#addGlobal | `this.exports.addGlobal`} instead. */ @replacedBy("`this.exports.addGlobal`") addGlobalExport(internalName: string, externalName: string) { return this.exports.addGlobal(internalName, externalName); } - /** @deprecated Use {@link MOD.ModuleExports#addMemory | `this.exports.addMemory`} instead. */ @replacedBy("`this.exports.addMemory`") addMemoryExport(internalName: string, externalName: string) { return this.exports.addMemory(internalName, externalName); } - /** @deprecated Use {@link MOD.ModuleExports#addTable | `this.exports.addTable`} instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } - /** @deprecated Use {@link MOD.ModuleExports#addFunction | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } + /** @deprecated Use {@link ModuleTags#add | `this.tags.add`} instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } + /** @deprecated Use {@link ModuleTags#add | `this.tags.get`} instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } + /** @deprecated Use {@link ModuleTags#add | `this.tags.remove`} instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } + + /** @deprecated Use {@link ModuleGlobals#add | `this.globals.add`} instead. */ @replacedBy("`this.globals.add`") addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef) { return this.globals.add(name, type, mutable, init); } + /** @deprecated Use {@link ModuleGlobals#get | `this.globals.get`} instead. */ @replacedBy("`this.globals.get`") getGlobal(name: string) { return this.globals.get(name); } + /** @deprecated Use {@link ModuleGlobals#getByIndex | `this.globals.getByIndex`} instead. */ @replacedBy("`this.globals.getByIndex`") getGlobalByIndex(index: number) { return this.globals.getByIndex(index); } + /** @deprecated Use {@link ModuleGlobals#count | `this.globals.count`} instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } + /** @deprecated Use {@link ModuleGlobals#remove | `this.globals.remove`} instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } + + /** @deprecated Use {@link ModuleMemories#set | `this.memories.set`} instead. */ @replacedBy("`this.memories.set`") setMemory(initial: number, maximum: number, exportName: string, segments?: readonly any[], shared?: boolean, memory64?: boolean, internalName?: string) { return this.memories.set(initial, maximum, exportName, segments, shared, memory64, internalName); } + /** @deprecated Use {@link ModuleMemories#has | `this.memories.has`} instead. */ @replacedBy("`this.memories.has`") hasMemory() { return this.memories.has(); } + + /** @deprecated Use {@link ModuleTables#add | `this.tables.add`} instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } + /** @deprecated Use {@link ModuleTables#get | `this.tables.get`} instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } + /** @deprecated Use {@link ModuleTables#getByIndex | `this.tables.getByIndex`} instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } + /** @deprecated Use {@link ModuleTables#getSegments | `this.tables.getSegments`} instead. */ @replacedBy("`this.tables.getSegments`") getTableSegments(table: TableRef) { return this.tables.getSegments(table); } + /** @deprecated Use {@link ModuleTables#count | `this.tables.count`} instead. */ @replacedBy("`this.tables.count`") getNumTables() { return this.tables.count(); } + /** @deprecated Use {@link ModuleTables#remove | `this.tables.remove`} instead. */ @replacedBy("`this.tables.remove`") removeTable(name: string) { return this.tables.remove(name); } + + /** @deprecated Use {@link ModuleFunctions#add | `this.functions.add`} instead. */ @replacedBy("`this.functions.add`") addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef) { return this.functions.add(name, params, results, varTypes, body); } + /** @deprecated Use {@link ModuleFunctions#get | `this.functions.get`} instead. */ @replacedBy("`this.functions.get`") getFunction(name: string) { return this.functions.get(name); } + /** @deprecated Use {@link ModuleFunctions#getByIndex | `this.functions.getByIndex`} instead. */ @replacedBy("`this.functions.getByIndex`") getFunctionByIndex(index: number) { return this.functions.getByIndex(index); } + /** @deprecated Use {@link ModuleFunctions#count | `this.functions.count`} instead. */ @replacedBy("`this.functions.count`") getNumFunctions() { return this.functions.count(); } + /** @deprecated Use {@link ModuleFunctions#remove | `this.functions.remove`} instead. */ @replacedBy("`this.functions.remove`") removeFunction(name: string) { return this.functions.remove(name); } + + /** @deprecated Use {@link ModuleDataSegments#get | `this.dataSegments.get`} instead. */ @replacedBy("`this.dataSegments.get`") getDataSegment(name: string) { return this.dataSegments.get(name); } + /** @deprecated Use {@link ModuleDataSegments#getByIndex | `this.dataSegments.getByIndex`} instead. */ @replacedBy("`this.dataSegments.getByIndex`") getDataSegmentByIndex(index: number) { return this.dataSegments.getByIndex(index); } + /** @deprecated Use {@link ModuleDataSegments#count | `this.dataSegments.count`} instead. */ @replacedBy("`this.dataSegments.count`") getNumDataSegments() { return this.dataSegments.count(); } + + /** @deprecated Use {@link ModuleElementSegments#addActive | `this.elementSegments.addActive`} instead. */ @replacedBy("`this.elementSegments.addActive`") addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef) { return this.elementSegments.addActive(table, name, funcNames, offset); } + /** @deprecated Use {@link ModuleElementSegments#addPassive | `this.elementSegments.addPassive`} instead. */ @replacedBy("`this.elementSegments.addPassive`") addPassiveElementSegment(name: string, funcNames: readonly string[]) { return this.elementSegments.addPassive(name, funcNames); } + /** @deprecated Use {@link ModuleElementSegments#get | `this.elementSegments.get`} instead. */ @replacedBy("`this.elementSegments.get`") getElementSegment(name: string) { return this.elementSegments.get(name); } + /** @deprecated Use {@link ModuleElementSegments#getByIndex | `this.elementSegments.getByIndex`} instead. */ @replacedBy("`this.elementSegments.getByIndex`") getElementSegmentByIndex(index: number) { return this.elementSegments.getByIndex(index); } + /** @deprecated Use {@link ModuleElementSegments#count | `this.elementSegments.count`} instead. */ @replacedBy("`this.elementSegments.count`") getNumElementSegments() { return this.elementSegments.count(); } + /** @deprecated Use {@link ModuleElementSegments#remove | `this.elementSegments.remove`} instead. */ @replacedBy("`this.elementSegments.remove`") removeElementSegment(name: string) { return this.elementSegments.remove(name); } + + /** @deprecated Use {@link ModuleImports#addTag | `this.imports.addTag`} instead. */ @replacedBy("`this.imports.addTag`") addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addTag(internalName, externalModuleName, externalBaseName, params, results); } + /** @deprecated Use {@link ModuleImports#addGlobal | `this.imports.addGlobal`} instead. */ @replacedBy("`this.imports.addGlobal`") addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean) { return this.imports.addGlobal(internalName, externalModuleName, externalBaseName, globalType, mutable); } + /** @deprecated Use {@link ModuleImports#addMemory | `this.imports.addMemory`} instead. */ @replacedBy("`this.imports.addMemory`") addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean) { return this.imports.addMemory(internalName, externalModuleName, externalBaseName, shared); } + /** @deprecated Use {@link ModuleImports#addTable | `this.imports.addTable`} instead. */ @replacedBy("`this.imports.addTable`") addTableImport(internalName: string, externalModuleName: string, externalBaseName: string) { return this.imports.addTable(internalName, externalModuleName, externalBaseName); } + /** @deprecated Use {@link ModuleImports#addFunction | `this.imports.addFunction`} instead. */ @replacedBy("`this.imports.addFunction`") addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addFunction(internalName, externalModuleName, externalBaseName, params, results); } + + /** @deprecated Use {@link ModuleExports#get | `this.exports.get`} instead. */ @replacedBy("`this.exports.get`") getExport(externalName: string) { return this.exports.get(externalName); } + /** @deprecated Use {@link ModuleExports#getByIndex | `this.exports.getByIndex`} instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } + /** @deprecated Use {@link ModuleExports#count | `this.exports.count`} instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } + /** @deprecated Use {@link ModuleExports#remove | `this.exports.remove`} instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } + /** @deprecated Use {@link ModuleExports#addTag | `this.exports.addTag`} instead. */ @replacedBy("`this.exports.addTag`") addTagExport(internalName: string, externalName: string) { return this.exports.addTag(internalName, externalName); } + /** @deprecated Use {@link ModuleExports#addGlobal | `this.exports.addGlobal`} instead. */ @replacedBy("`this.exports.addGlobal`") addGlobalExport(internalName: string, externalName: string) { return this.exports.addGlobal(internalName, externalName); } + /** @deprecated Use {@link ModuleExports#addMemory | `this.exports.addMemory`} instead. */ @replacedBy("`this.exports.addMemory`") addMemoryExport(internalName: string, externalName: string) { return this.exports.addMemory(internalName, externalName); } + /** @deprecated Use {@link ModuleExports#addTable | `this.exports.addTable`} instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } + /** @deprecated Use {@link ModuleExports#addFunction | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } getMemoryInfo(name: string): MEMORY.Memory { return new MEMORY.Memory(this, name); @@ -418,3 +442,24 @@ export class Module { return copyExpression(expr, this); } } + + + +/** + * A collection of types and classes related to WASM module manipulation. + * + * Each class represents a component of a WASM module, + * and its corresponding type is included for documentation. + */ +// eslint-disable-next-line no-redeclare +export namespace Module { + export type Tag = TAG.Tag; + export type Global = GLOBAL.Global; + export type Memory = MEMORY.Memory; + export type Table = TABLE.Table; + export type Function = FUNCTION.Function; + export type DataSegment = DATA_SEGMENT.DataSegment; + export type ElementSegment = ELEMENT_SEGMENT.ElementSegment; + export type Import = IMPORT.Import; + export type Export = EXPORT.Export; +} diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 65a6a4433f8..c1301283206 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -69,7 +69,7 @@ export class Table { /** - * Methods for manipulating {@link Table | tables} in a WASM module. + * Methods for manipulating {@link Module.Table | tables} in a WASM module. */ export class ModuleTables { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Tag.ts b/ts/src/classes/module/Tag.ts index eef70b1d6b0..32ee807d672 100644 --- a/ts/src/classes/module/Tag.ts +++ b/ts/src/classes/module/Tag.ts @@ -40,7 +40,7 @@ export class Tag { /** - * Methods for manipulating {@link Tag | tags} in a WASM module. + * Methods for manipulating {@link Module.Tag | tags} in a WASM module. */ export class ModuleTags { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/index.ts b/ts/src/classes/module/index.ts deleted file mode 100644 index 9e4af733522..00000000000 --- a/ts/src/classes/module/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * A collection of types and classes related to WASM module manipulation. - * - * Each class represents a component of a WASM module. - * Additional interfaces for module manipulation are included. - * @module MOD - */ - - - -export {Tag, type ModuleTags} from "./Tag.ts"; -export {Global, type ModuleGlobals} from "./Global.ts"; -export {Memory, type ModuleMemories} from "./Memory.ts"; -export {Table, type ModuleTables} from "./Table.ts"; -export {Function, type ModuleFunctions} from "./Function.ts"; -export {DataSegment, type ModuleDataSegments} from "./DataSegment.ts"; -export {ElementSegment, type ModuleElementSegments} from "./ElementSegment.ts"; -export {Import, type ModuleImports} from "./Import.ts"; -export {Export, type ModuleExports} from "./Export.ts"; diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 8b0c96b6041..e8988b7ad6d 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -17,21 +17,21 @@ export type PackedType = number; export type ExpressionRef = number; // ### Module Components ### // -/** Reference to a {@link MOD.Tag}. */ +/** Reference to a {@link Module.Tag}. */ export type TagRef = number; -/** Reference to a {@link MOD.Global}. */ +/** Reference to a {@link Module.Global}. */ export type GlobalRef = number; // no `MemoryRef` -/** Reference to a {@link MOD.Table}. */ +/** Reference to a {@link Module.Table}. */ export type TableRef = number; -/** Reference to a {@link MOD.Function}. */ +/** Reference to a {@link Module.Function}. */ export type FunctionRef = number; -/** Reference to a {@link MOD.DataSegment}. */ +/** Reference to a {@link Module.DataSegment}. */ export type DataSegmentRef = number; -/** Reference to an {@link MOD.ElementSegment}. */ +/** Reference to an {@link Module.ElementSegment}. */ export type ElementSegmentRef = number; // no `ImportRef` -/** Reference to an {@link MOD.Export}. */ +/** Reference to an {@link Module.Export}. */ export type ExportRef = number; From 12bf373b37ea07d6a13cbc4190bd5c624fdd7c6d Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 18:25:50 -0400 Subject: [PATCH 119/247] docs: inline `Module*s` interfaces --- ts/src/binaryen.ts | 18 ++-- ts/src/classes/module/DataSegment.ts | 4 +- ts/src/classes/module/ElementSegment.ts | 4 +- ts/src/classes/module/Export.ts | 4 +- ts/src/classes/module/Function.ts | 4 +- ts/src/classes/module/Global.ts | 4 +- ts/src/classes/module/Import.ts | 4 +- ts/src/classes/module/Memory.ts | 6 +- ts/src/classes/module/Module.ts | 104 ++++++++++++------------ ts/src/classes/module/Table.ts | 4 +- ts/src/classes/module/Tag.ts | 4 +- 11 files changed, 80 insertions(+), 80 deletions(-) diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index b877720ccfd..cd70250c08c 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -8,15 +8,15 @@ export { Feature, Module, } from "./classes/module/Module.ts"; -export {Tag, type ModuleTags} from "./classes/module/Tag.ts"; -export {Global, type ModuleGlobals} from "./classes/module/Global.ts"; -export {Memory, type ModuleMemories} from "./classes/module/Memory.ts"; -export {Table, type ModuleTables} from "./classes/module/Table.ts"; -export {Function, type ModuleFunctions} from "./classes/module/Function.ts"; -export {DataSegment, type ModuleDataSegments} from "./classes/module/DataSegment.ts"; -export {ElementSegment, type ModuleElementSegments} from "./classes/module/ElementSegment.ts"; -export {Import, type ModuleImports} from "./classes/module/Import.ts"; -export {Export, type ModuleExports} from "./classes/module/Export.ts"; +export {Tag} from "./classes/module/Tag.ts"; +export {Global} from "./classes/module/Global.ts"; +export {Memory} from "./classes/module/Memory.ts"; +export {Table} from "./classes/module/Table.ts"; +export {Function} from "./classes/module/Function.ts"; +export {DataSegment} from "./classes/module/DataSegment.ts"; +export {ElementSegment} from "./classes/module/ElementSegment.ts"; +export {Import} from "./classes/module/Import.ts"; +export {Export} from "./classes/module/Export.ts"; export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index a2ec3ae7c4c..4ddbd6a63c6 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -20,7 +20,6 @@ import type { /** * Information about a data segment in a WASM module. - * @see {@link ModuleDataSegments} */ export class DataSegment { readonly name: string; @@ -50,7 +49,8 @@ export class DataSegment { /** - * Methods for manipulating {@link Module.DataSegment | data segments} in a WASM module. + * Methods for manipulating data segments in a WASM module. + * @inline */ export class ModuleDataSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index 6e7c1999a70..655feb44c07 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -19,7 +19,6 @@ import type { /** * Information about an element segment in a WASM module. - * @see {@link ModuleElementSegments} */ export class ElementSegment { readonly name: string; @@ -46,7 +45,8 @@ export class ElementSegment { /** - * Methods for manipulating {@link Module.ElementSegment | element segments} in a WASM module. + * Methods for manipulating element segments in a WASM module. + * @inline */ export class ModuleElementSegments { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index b40c3bb48c6..fdfe51d7334 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -18,7 +18,6 @@ import type { /** * Information about an export in a WASM module. - * @see {@link ModuleExports} */ export class Export { readonly kind: ExternalKind; @@ -36,7 +35,8 @@ export class Export { /** - * Methods for manipulating {@link Module.Export | exports} in a WASM module. + * Methods for manipulating exports in a WASM module. + * @inline */ export class ModuleExports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index 8d2a9f35b51..9d1e20cede5 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -22,7 +22,6 @@ import type { /** * Information about a function in a WASM module. - * @see {@link ModuleFunctions} */ class BinaryenFunction { private readonly [THIS_PTR]: FunctionRef; @@ -88,7 +87,8 @@ export {BinaryenFunction as Function}; /** - * Methods for manipulating {@link Module.Function | functions} in a WASM module. + * Methods for manipulating functions in a WASM module. + * @inline */ export class ModuleFunctions { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Global.ts b/ts/src/classes/module/Global.ts index b3ce49a8307..3ced8f84ff0 100644 --- a/ts/src/classes/module/Global.ts +++ b/ts/src/classes/module/Global.ts @@ -19,7 +19,6 @@ import type { /** * Information about a global in a WASM module. - * @see {@link ModuleGlobals} */ export class Global { readonly name: string; @@ -43,7 +42,8 @@ export class Global { /** - * Methods for manipulating {@link Module.Global | globals} in a WASM module. + * Methods for manipulating globals in a WASM module. + * @inline */ export class ModuleGlobals { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index 692f0ce8483..5c0ff6d3b0a 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -16,7 +16,6 @@ import type { /** * Information about an import in a WASM module. - * @see {@link ModuleImports} */ export class Import { constructor() {} @@ -25,7 +24,8 @@ export class Import { /** - * Methods for manipulating {@link Module.Import | imports} in a WASM module. + * Methods for manipulating imports in a WASM module. + * @inline */ export class ModuleImports { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index d1df08d6eaf..384cafc9d60 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -20,7 +20,7 @@ import type { /** - * Similar to a {@link DataSegment} but with some minor differences. + * Similar to a {@link Module.DataSegment} but with some minor differences. * @inline */ type MemorySegment = { @@ -34,7 +34,6 @@ type MemorySegment = { /** * Information about a memory in a WASM module. - * @see {@link ModuleMemories} */ export class Memory { readonly module: string; @@ -60,7 +59,8 @@ export class Memory { /** - * Methods for manipulating {@link Module.Memory | memories} in a WASM module. + * Methods for manipulating memories in a WASM module. + * @inline */ export class ModuleMemories { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 904e0de0137..80f7af45c4d 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -226,58 +226,58 @@ export class Module { BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); } - /** @deprecated Use {@link ModuleTags#add | `this.tags.add`} instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } - /** @deprecated Use {@link ModuleTags#add | `this.tags.get`} instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } - /** @deprecated Use {@link ModuleTags#add | `this.tags.remove`} instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } - - /** @deprecated Use {@link ModuleGlobals#add | `this.globals.add`} instead. */ @replacedBy("`this.globals.add`") addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef) { return this.globals.add(name, type, mutable, init); } - /** @deprecated Use {@link ModuleGlobals#get | `this.globals.get`} instead. */ @replacedBy("`this.globals.get`") getGlobal(name: string) { return this.globals.get(name); } - /** @deprecated Use {@link ModuleGlobals#getByIndex | `this.globals.getByIndex`} instead. */ @replacedBy("`this.globals.getByIndex`") getGlobalByIndex(index: number) { return this.globals.getByIndex(index); } - /** @deprecated Use {@link ModuleGlobals#count | `this.globals.count`} instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } - /** @deprecated Use {@link ModuleGlobals#remove | `this.globals.remove`} instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } - - /** @deprecated Use {@link ModuleMemories#set | `this.memories.set`} instead. */ @replacedBy("`this.memories.set`") setMemory(initial: number, maximum: number, exportName: string, segments?: readonly any[], shared?: boolean, memory64?: boolean, internalName?: string) { return this.memories.set(initial, maximum, exportName, segments, shared, memory64, internalName); } - /** @deprecated Use {@link ModuleMemories#has | `this.memories.has`} instead. */ @replacedBy("`this.memories.has`") hasMemory() { return this.memories.has(); } - - /** @deprecated Use {@link ModuleTables#add | `this.tables.add`} instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } - /** @deprecated Use {@link ModuleTables#get | `this.tables.get`} instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } - /** @deprecated Use {@link ModuleTables#getByIndex | `this.tables.getByIndex`} instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } - /** @deprecated Use {@link ModuleTables#getSegments | `this.tables.getSegments`} instead. */ @replacedBy("`this.tables.getSegments`") getTableSegments(table: TableRef) { return this.tables.getSegments(table); } - /** @deprecated Use {@link ModuleTables#count | `this.tables.count`} instead. */ @replacedBy("`this.tables.count`") getNumTables() { return this.tables.count(); } - /** @deprecated Use {@link ModuleTables#remove | `this.tables.remove`} instead. */ @replacedBy("`this.tables.remove`") removeTable(name: string) { return this.tables.remove(name); } - - /** @deprecated Use {@link ModuleFunctions#add | `this.functions.add`} instead. */ @replacedBy("`this.functions.add`") addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef) { return this.functions.add(name, params, results, varTypes, body); } - /** @deprecated Use {@link ModuleFunctions#get | `this.functions.get`} instead. */ @replacedBy("`this.functions.get`") getFunction(name: string) { return this.functions.get(name); } - /** @deprecated Use {@link ModuleFunctions#getByIndex | `this.functions.getByIndex`} instead. */ @replacedBy("`this.functions.getByIndex`") getFunctionByIndex(index: number) { return this.functions.getByIndex(index); } - /** @deprecated Use {@link ModuleFunctions#count | `this.functions.count`} instead. */ @replacedBy("`this.functions.count`") getNumFunctions() { return this.functions.count(); } - /** @deprecated Use {@link ModuleFunctions#remove | `this.functions.remove`} instead. */ @replacedBy("`this.functions.remove`") removeFunction(name: string) { return this.functions.remove(name); } - - /** @deprecated Use {@link ModuleDataSegments#get | `this.dataSegments.get`} instead. */ @replacedBy("`this.dataSegments.get`") getDataSegment(name: string) { return this.dataSegments.get(name); } - /** @deprecated Use {@link ModuleDataSegments#getByIndex | `this.dataSegments.getByIndex`} instead. */ @replacedBy("`this.dataSegments.getByIndex`") getDataSegmentByIndex(index: number) { return this.dataSegments.getByIndex(index); } - /** @deprecated Use {@link ModuleDataSegments#count | `this.dataSegments.count`} instead. */ @replacedBy("`this.dataSegments.count`") getNumDataSegments() { return this.dataSegments.count(); } - - /** @deprecated Use {@link ModuleElementSegments#addActive | `this.elementSegments.addActive`} instead. */ @replacedBy("`this.elementSegments.addActive`") addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef) { return this.elementSegments.addActive(table, name, funcNames, offset); } - /** @deprecated Use {@link ModuleElementSegments#addPassive | `this.elementSegments.addPassive`} instead. */ @replacedBy("`this.elementSegments.addPassive`") addPassiveElementSegment(name: string, funcNames: readonly string[]) { return this.elementSegments.addPassive(name, funcNames); } - /** @deprecated Use {@link ModuleElementSegments#get | `this.elementSegments.get`} instead. */ @replacedBy("`this.elementSegments.get`") getElementSegment(name: string) { return this.elementSegments.get(name); } - /** @deprecated Use {@link ModuleElementSegments#getByIndex | `this.elementSegments.getByIndex`} instead. */ @replacedBy("`this.elementSegments.getByIndex`") getElementSegmentByIndex(index: number) { return this.elementSegments.getByIndex(index); } - /** @deprecated Use {@link ModuleElementSegments#count | `this.elementSegments.count`} instead. */ @replacedBy("`this.elementSegments.count`") getNumElementSegments() { return this.elementSegments.count(); } - /** @deprecated Use {@link ModuleElementSegments#remove | `this.elementSegments.remove`} instead. */ @replacedBy("`this.elementSegments.remove`") removeElementSegment(name: string) { return this.elementSegments.remove(name); } - - /** @deprecated Use {@link ModuleImports#addTag | `this.imports.addTag`} instead. */ @replacedBy("`this.imports.addTag`") addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addTag(internalName, externalModuleName, externalBaseName, params, results); } - /** @deprecated Use {@link ModuleImports#addGlobal | `this.imports.addGlobal`} instead. */ @replacedBy("`this.imports.addGlobal`") addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean) { return this.imports.addGlobal(internalName, externalModuleName, externalBaseName, globalType, mutable); } - /** @deprecated Use {@link ModuleImports#addMemory | `this.imports.addMemory`} instead. */ @replacedBy("`this.imports.addMemory`") addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean) { return this.imports.addMemory(internalName, externalModuleName, externalBaseName, shared); } - /** @deprecated Use {@link ModuleImports#addTable | `this.imports.addTable`} instead. */ @replacedBy("`this.imports.addTable`") addTableImport(internalName: string, externalModuleName: string, externalBaseName: string) { return this.imports.addTable(internalName, externalModuleName, externalBaseName); } - /** @deprecated Use {@link ModuleImports#addFunction | `this.imports.addFunction`} instead. */ @replacedBy("`this.imports.addFunction`") addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addFunction(internalName, externalModuleName, externalBaseName, params, results); } - - /** @deprecated Use {@link ModuleExports#get | `this.exports.get`} instead. */ @replacedBy("`this.exports.get`") getExport(externalName: string) { return this.exports.get(externalName); } - /** @deprecated Use {@link ModuleExports#getByIndex | `this.exports.getByIndex`} instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } - /** @deprecated Use {@link ModuleExports#count | `this.exports.count`} instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } - /** @deprecated Use {@link ModuleExports#remove | `this.exports.remove`} instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } - /** @deprecated Use {@link ModuleExports#addTag | `this.exports.addTag`} instead. */ @replacedBy("`this.exports.addTag`") addTagExport(internalName: string, externalName: string) { return this.exports.addTag(internalName, externalName); } - /** @deprecated Use {@link ModuleExports#addGlobal | `this.exports.addGlobal`} instead. */ @replacedBy("`this.exports.addGlobal`") addGlobalExport(internalName: string, externalName: string) { return this.exports.addGlobal(internalName, externalName); } - /** @deprecated Use {@link ModuleExports#addMemory | `this.exports.addMemory`} instead. */ @replacedBy("`this.exports.addMemory`") addMemoryExport(internalName: string, externalName: string) { return this.exports.addMemory(internalName, externalName); } - /** @deprecated Use {@link ModuleExports#addTable | `this.exports.addTable`} instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } - /** @deprecated Use {@link ModuleExports#addFunction | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } + /** @deprecated Use {@link Module#tags | `this.tags.add`} instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } + /** @deprecated Use {@link Module#tags | `this.tags.get`} instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } + /** @deprecated Use {@link Module#tags | `this.tags.remove`} instead. */ @replacedBy("`this.tags.remove`") removeTag(name: string) { return this.tags.remove(name); } + + /** @deprecated Use {@link Module#globals | `this.globals.add`} instead. */ @replacedBy("`this.globals.add`") addGlobal(name: string, type: Type, mutable: boolean, init: ExpressionRef) { return this.globals.add(name, type, mutable, init); } + /** @deprecated Use {@link Module#globals | `this.globals.get`} instead. */ @replacedBy("`this.globals.get`") getGlobal(name: string) { return this.globals.get(name); } + /** @deprecated Use {@link Module#globals | `this.globals.getByIndex`} instead. */ @replacedBy("`this.globals.getByIndex`") getGlobalByIndex(index: number) { return this.globals.getByIndex(index); } + /** @deprecated Use {@link Module#globals | `this.globals.count`} instead. */ @replacedBy("`this.globals.count`") getNumGlobals() { return this.globals.count(); } + /** @deprecated Use {@link Module#globals | `this.globals.remove`} instead. */ @replacedBy("`this.globals.remove`") removeGlobal(name: string) { return this.globals.remove(name); } + + /** @deprecated Use {@link Module#memories | `this.memories.set`} instead. */ @replacedBy("`this.memories.set`") setMemory(initial: number, maximum: number, exportName: string, segments?: readonly any[], shared?: boolean, memory64?: boolean, internalName?: string) { return this.memories.set(initial, maximum, exportName, segments, shared, memory64, internalName); } + /** @deprecated Use {@link Module#memories | `this.memories.has`} instead. */ @replacedBy("`this.memories.has`") hasMemory() { return this.memories.has(); } + + /** @deprecated Use {@link Module#tables | `this.tables.add`} instead. */ @replacedBy("`this.tables.add`") addTable(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef) { return this.tables.add(name, initial, maximum, type, init); } + /** @deprecated Use {@link Module#tables | `this.tables.get`} instead. */ @replacedBy("`this.tables.get`") getTable(name: string) { return this.tables.get(name); } + /** @deprecated Use {@link Module#tables | `this.tables.getByIndex`} instead. */ @replacedBy("`this.tables.getByIndex`") getTableByIndex(index: number) { return this.tables.getByIndex(index); } + /** @deprecated Use {@link Module#tables | `this.tables.getSegments`} instead. */ @replacedBy("`this.tables.getSegments`") getTableSegments(table: TableRef) { return this.tables.getSegments(table); } + /** @deprecated Use {@link Module#tables | `this.tables.count`} instead. */ @replacedBy("`this.tables.count`") getNumTables() { return this.tables.count(); } + /** @deprecated Use {@link Module#tables | `this.tables.remove`} instead. */ @replacedBy("`this.tables.remove`") removeTable(name: string) { return this.tables.remove(name); } + + /** @deprecated Use {@link Module#functions | `this.functions.add`} instead. */ @replacedBy("`this.functions.add`") addFunction(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef) { return this.functions.add(name, params, results, varTypes, body); } + /** @deprecated Use {@link Module#functions | `this.functions.get`} instead. */ @replacedBy("`this.functions.get`") getFunction(name: string) { return this.functions.get(name); } + /** @deprecated Use {@link Module#functions | `this.functions.getByIndex`} instead. */ @replacedBy("`this.functions.getByIndex`") getFunctionByIndex(index: number) { return this.functions.getByIndex(index); } + /** @deprecated Use {@link Module#functions | `this.functions.count`} instead. */ @replacedBy("`this.functions.count`") getNumFunctions() { return this.functions.count(); } + /** @deprecated Use {@link Module#functions | `this.functions.remove`} instead. */ @replacedBy("`this.functions.remove`") removeFunction(name: string) { return this.functions.remove(name); } + + /** @deprecated Use {@link Module#dataSegments | `this.dataSegments.get`} instead. */ @replacedBy("`this.dataSegments.get`") getDataSegment(name: string) { return this.dataSegments.get(name); } + /** @deprecated Use {@link Module#dataSegments | `this.dataSegments.getByIndex`} instead. */ @replacedBy("`this.dataSegments.getByIndex`") getDataSegmentByIndex(index: number) { return this.dataSegments.getByIndex(index); } + /** @deprecated Use {@link Module#dataSegments | `this.dataSegments.count`} instead. */ @replacedBy("`this.dataSegments.count`") getNumDataSegments() { return this.dataSegments.count(); } + + /** @deprecated Use {@link Module#elementSegments | `this.elementSegments.addActive`} instead. */ @replacedBy("`this.elementSegments.addActive`") addActiveElementSegment(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef) { return this.elementSegments.addActive(table, name, funcNames, offset); } + /** @deprecated Use {@link Module#elementSegments | `this.elementSegments.addPassive`} instead. */ @replacedBy("`this.elementSegments.addPassive`") addPassiveElementSegment(name: string, funcNames: readonly string[]) { return this.elementSegments.addPassive(name, funcNames); } + /** @deprecated Use {@link Module#elementSegments | `this.elementSegments.get`} instead. */ @replacedBy("`this.elementSegments.get`") getElementSegment(name: string) { return this.elementSegments.get(name); } + /** @deprecated Use {@link Module#elementSegments | `this.elementSegments.getByIndex`} instead. */ @replacedBy("`this.elementSegments.getByIndex`") getElementSegmentByIndex(index: number) { return this.elementSegments.getByIndex(index); } + /** @deprecated Use {@link Module#elementSegments | `this.elementSegments.count`} instead. */ @replacedBy("`this.elementSegments.count`") getNumElementSegments() { return this.elementSegments.count(); } + /** @deprecated Use {@link Module#elementSegments | `this.elementSegments.remove`} instead. */ @replacedBy("`this.elementSegments.remove`") removeElementSegment(name: string) { return this.elementSegments.remove(name); } + + /** @deprecated Use {@link Module#imports | `this.imports.addTag`} instead. */ @replacedBy("`this.imports.addTag`") addTagImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addTag(internalName, externalModuleName, externalBaseName, params, results); } + /** @deprecated Use {@link Module#imports | `this.imports.addGlobal`} instead. */ @replacedBy("`this.imports.addGlobal`") addGlobalImport(internalName: string, externalModuleName: string, externalBaseName: string, globalType: Type, mutable: boolean) { return this.imports.addGlobal(internalName, externalModuleName, externalBaseName, globalType, mutable); } + /** @deprecated Use {@link Module#imports | `this.imports.addMemory`} instead. */ @replacedBy("`this.imports.addMemory`") addMemoryImport(internalName: string, externalModuleName: string, externalBaseName: string, shared: boolean) { return this.imports.addMemory(internalName, externalModuleName, externalBaseName, shared); } + /** @deprecated Use {@link Module#imports | `this.imports.addTable`} instead. */ @replacedBy("`this.imports.addTable`") addTableImport(internalName: string, externalModuleName: string, externalBaseName: string) { return this.imports.addTable(internalName, externalModuleName, externalBaseName); } + /** @deprecated Use {@link Module#imports | `this.imports.addFunction`} instead. */ @replacedBy("`this.imports.addFunction`") addFunctionImport(internalName: string, externalModuleName: string, externalBaseName: string, params: Type, results: Type) { return this.imports.addFunction(internalName, externalModuleName, externalBaseName, params, results); } + + /** @deprecated Use {@link Module#exports | `this.exports.get`} instead. */ @replacedBy("`this.exports.get`") getExport(externalName: string) { return this.exports.get(externalName); } + /** @deprecated Use {@link Module#exports | `this.exports.getByIndex`} instead. */ @replacedBy("`this.exports.getByIndex`") getExportByIndex(index: number) { return this.exports.getByIndex(index); } + /** @deprecated Use {@link Module#exports | `this.exports.count`} instead. */ @replacedBy("`this.exports.count`") getNumExports() { return this.exports.count(); } + /** @deprecated Use {@link Module#exports | `this.exports.remove`} instead. */ @replacedBy("`this.exports.remove`") removeExport(externalName: string) { return this.exports.remove(externalName); } + /** @deprecated Use {@link Module#exports | `this.exports.addTag`} instead. */ @replacedBy("`this.exports.addTag`") addTagExport(internalName: string, externalName: string) { return this.exports.addTag(internalName, externalName); } + /** @deprecated Use {@link Module#exports | `this.exports.addGlobal`} instead. */ @replacedBy("`this.exports.addGlobal`") addGlobalExport(internalName: string, externalName: string) { return this.exports.addGlobal(internalName, externalName); } + /** @deprecated Use {@link Module#exports | `this.exports.addMemory`} instead. */ @replacedBy("`this.exports.addMemory`") addMemoryExport(internalName: string, externalName: string) { return this.exports.addMemory(internalName, externalName); } + /** @deprecated Use {@link Module#exports | `this.exports.addTable`} instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } + /** @deprecated Use {@link Module#exports | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } getMemoryInfo(name: string): MEMORY.Memory { return new MEMORY.Memory(this, name); diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index c1301283206..f79d942b0d5 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -22,7 +22,6 @@ import type { /** * Information about a table in a WASM module. - * @see {@link ModuleTables} */ export class Table { private readonly [THIS_PTR]: TableRef; @@ -69,7 +68,8 @@ export class Table { /** - * Methods for manipulating {@link Module.Table | tables} in a WASM module. + * Methods for manipulating tables in a WASM module. + * @inline */ export class ModuleTables { constructor(private readonly mod: Module) {} diff --git a/ts/src/classes/module/Tag.ts b/ts/src/classes/module/Tag.ts index 32ee807d672..81b12a3f53a 100644 --- a/ts/src/classes/module/Tag.ts +++ b/ts/src/classes/module/Tag.ts @@ -18,7 +18,6 @@ import type { /** * Information about a tag in a WASM module. - * @see {@link ModuleTags} */ export class Tag { readonly name: string; @@ -40,7 +39,8 @@ export class Tag { /** - * Methods for manipulating {@link Module.Tag | tags} in a WASM module. + * Methods for manipulating tags in a WASM module. + * @inline */ export class ModuleTags { constructor(private readonly mod: Module) {} From 5272c250d949470ef230e5f000f4f728d23e33ef Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 18:46:18 -0400 Subject: [PATCH 120/247] docs: nest Module static components --- ts/src/binaryen.ts | 9 --------- ts/src/classes/module/Module.ts | 18 +++++++++--------- ts/typedoc.config.js | 12 ++++++++++++ 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index cd70250c08c..c22e6fd76b8 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -8,15 +8,6 @@ export { Feature, Module, } from "./classes/module/Module.ts"; -export {Tag} from "./classes/module/Tag.ts"; -export {Global} from "./classes/module/Global.ts"; -export {Memory} from "./classes/module/Memory.ts"; -export {Table} from "./classes/module/Table.ts"; -export {Function} from "./classes/module/Function.ts"; -export {DataSegment} from "./classes/module/DataSegment.ts"; -export {ElementSegment} from "./classes/module/ElementSegment.ts"; -export {Import} from "./classes/module/Import.ts"; -export {Export} from "./classes/module/Export.ts"; export {TypeBuilder} from "./classes/TypeBuilder.ts"; export { ExpressionRunner, diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 80f7af45c4d..68254ec8dcc 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -135,15 +135,15 @@ export enum Feature { * - has a property `.wasm`, a namespace for creating expressions in the module (`.wasm.nop()`, `.wasm.i32.add()`, etc.) */ export class Module { - static readonly Tag = TAG.Tag; - static readonly Global = GLOBAL.Global; - static readonly Memory = MEMORY.Memory; - static readonly Table = TABLE.Table; - static readonly Function = FUNCTION.Function; - static readonly DataSegment = DATA_SEGMENT.DataSegment; - static readonly ElementSegment = ELEMENT_SEGMENT.ElementSegment; - static readonly Import = IMPORT.Import; - static readonly Export = EXPORT.Export; + /** @class */ static readonly Tag = TAG.Tag; + /** @class */ static readonly Global = GLOBAL.Global; + /** @class */ static readonly Memory = MEMORY.Memory; + /** @class */ static readonly Table = TABLE.Table; + /** @class */ static readonly Function = FUNCTION.Function; + /** @class */ static readonly DataSegment = DATA_SEGMENT.DataSegment; + /** @class */ static readonly ElementSegment = ELEMENT_SEGMENT.ElementSegment; + /** @class */ static readonly Import = IMPORT.Import; + /** @class */ static readonly Export = EXPORT.Export; readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); diff --git a/ts/typedoc.config.js b/ts/typedoc.config.js index bee06b650d4..57be56491c1 100644 --- a/ts/typedoc.config.js +++ b/ts/typedoc.config.js @@ -5,4 +5,16 @@ export default { useFirstParagraphOfCommentAsSummary: true, out: "./docs/out/", customCss: "./docs/styles.css", + + intentionallyNotExported: [ + "Tag", + "Global", + "Memory", + "Table", + "BinaryenFunction", + "DataSegment", + "ElementSegment", + "Import", + "Export", + ], }; From 327a8e43eba5ecfdccfa3685da13446a97412762 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 18:51:16 -0400 Subject: [PATCH 121/247] lint: rename imports --- ts/src/classes/module/Module.ts | 107 ++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 68254ec8dcc..c433fbf3a0d 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -44,15 +44,42 @@ import { preserveStack, strToStack, } from "../../utils.ts"; -import * as DATA_SEGMENT from "./DataSegment.ts"; -import * as ELEMENT_SEGMENT from "./ElementSegment.ts"; -import * as EXPORT from "./Export.ts"; -import * as FUNCTION from "./Function.ts"; -import * as GLOBAL from "./Global.ts"; -import * as IMPORT from "./Import.ts"; -import * as MEMORY from "./Memory.ts"; -import * as TABLE from "./Table.ts"; -import * as TAG from "./Tag.ts"; +import { + DataSegment as DataSegment_, + ModuleDataSegments, +} from "./DataSegment.ts"; +import { + ElementSegment as ElementSegment_, + ModuleElementSegments, +} from "./ElementSegment.ts"; +import { + Export as Export_, + ModuleExports, +} from "./Export.ts"; +import { + Function as Function_, + ModuleFunctions, +} from "./Function.ts"; +import { + Global as Global_, + ModuleGlobals, +} from "./Global.ts"; +import { + Import as Import_, + ModuleImports, +} from "./Import.ts"; +import { + Memory as Memory_, + ModuleMemories, +} from "./Memory.ts"; +import { + ModuleTables, + Table as Table_, +} from "./Table.ts"; +import { + ModuleTags, + Tag as Tag_, +} from "./Tag.ts"; @@ -135,15 +162,15 @@ export enum Feature { * - has a property `.wasm`, a namespace for creating expressions in the module (`.wasm.nop()`, `.wasm.i32.add()`, etc.) */ export class Module { - /** @class */ static readonly Tag = TAG.Tag; - /** @class */ static readonly Global = GLOBAL.Global; - /** @class */ static readonly Memory = MEMORY.Memory; - /** @class */ static readonly Table = TABLE.Table; - /** @class */ static readonly Function = FUNCTION.Function; - /** @class */ static readonly DataSegment = DATA_SEGMENT.DataSegment; - /** @class */ static readonly ElementSegment = ELEMENT_SEGMENT.ElementSegment; - /** @class */ static readonly Import = IMPORT.Import; - /** @class */ static readonly Export = EXPORT.Export; + /** @class */ static readonly Tag = Tag_; + /** @class */ static readonly Global = Global_; + /** @class */ static readonly Memory = Memory_; + /** @class */ static readonly Table = Table_; + /** @class */ static readonly Function = Function_; + /** @class */ static readonly DataSegment = DataSegment_; + /** @class */ static readonly ElementSegment = ElementSegment_; + /** @class */ static readonly Import = Import_; + /** @class */ static readonly Export = Export_; readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); @@ -190,15 +217,15 @@ export class Module { // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html - readonly tags = new TAG.ModuleTags(this); - readonly globals = new GLOBAL.ModuleGlobals(this); - readonly memories = new MEMORY.ModuleMemories(this); - readonly tables = new TABLE.ModuleTables(this); - readonly functions = new FUNCTION.ModuleFunctions(this); - readonly dataSegments = new DATA_SEGMENT.ModuleDataSegments(this); - readonly elementSegments = new ELEMENT_SEGMENT.ModuleElementSegments(this); - readonly imports = new IMPORT.ModuleImports(this); - readonly exports = new EXPORT.ModuleExports(this); + readonly tags = new ModuleTags(this); + readonly globals = new ModuleGlobals(this); + readonly memories = new ModuleMemories(this); + readonly tables = new ModuleTables(this); + readonly functions = new ModuleFunctions(this); + readonly dataSegments = new ModuleDataSegments(this); + readonly elementSegments = new ModuleElementSegments(this); + readonly imports = new ModuleImports(this); + readonly exports = new ModuleExports(this); /** @deprecated Use {@link Module#start | `this.start`} instead. */ @replacedBy("`this.start`") getStart() { return this.start; } /** @deprecated Use {@link Module#start | `this.start`} instead. */ @replacedBy("`this.start`") setStart(start: FunctionRef) { this.start = start; } @@ -279,12 +306,12 @@ export class Module { /** @deprecated Use {@link Module#exports | `this.exports.addTable`} instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } /** @deprecated Use {@link Module#exports | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } - getMemoryInfo(name: string): MEMORY.Memory { - return new MEMORY.Memory(this, name); + getMemoryInfo(name: string): Memory_ { + return new Memory_(this, name); } - getDataSegmentInfo(segment: DataSegmentRef): DATA_SEGMENT.DataSegment { - return new DATA_SEGMENT.DataSegment(this, segment); + getDataSegmentInfo(segment: DataSegmentRef): DataSegment_ { + return new DataSegment_(this, segment); } // ## Binaryen Operations ## // @@ -453,13 +480,13 @@ export class Module { */ // eslint-disable-next-line no-redeclare export namespace Module { - export type Tag = TAG.Tag; - export type Global = GLOBAL.Global; - export type Memory = MEMORY.Memory; - export type Table = TABLE.Table; - export type Function = FUNCTION.Function; - export type DataSegment = DATA_SEGMENT.DataSegment; - export type ElementSegment = ELEMENT_SEGMENT.ElementSegment; - export type Import = IMPORT.Import; - export type Export = EXPORT.Export; + export type Tag = Tag_; + export type Global = Global_; + export type Memory = Memory_; + export type Table = Table_; + export type Function = Function_; + export type DataSegment = DataSegment_; + export type ElementSegment = ElementSegment_; + export type Import = Import_; + export type Export = Export_; } From 5ecad8befaa639c53380a0ed2a16d410368b5edf Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 18:51:54 -0400 Subject: [PATCH 122/247] docs: fix `@inheritDoc` --- ts/src/services/expression-builder/control.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ts/src/services/expression-builder/control.ts b/ts/src/services/expression-builder/control.ts index 88c4d5f0cbf..727fdabd9f3 100644 --- a/ts/src/services/expression-builder/control.ts +++ b/ts/src/services/expression-builder/control.ts @@ -20,14 +20,14 @@ const STUB = (..._args: readonly number[]): number => 0; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ export function control(mod: Module) { return { - /** @inheritdoc EXPR.Block.block */ + /** @inheritDoc EXPR.Block.block */ block: Block.block.bind(null, mod), - /** @inheritdoc EXPR.Loop.loop */ + /** @inheritDoc EXPR.Loop.loop */ loop: Loop.loop.bind(null, mod), if: STUB, - /** @inheritdoc EXPR.Break.br */ + /** @inheritDoc EXPR.Break.br */ br: Break.br.bind(null, mod), - /** @inheritdoc EXPR.Break.br_if */ + /** @inheritDoc EXPR.Break.br_if */ br_if: Break.br_if.bind(null, mod), br_table: STUB, br_on_null: STUB, From 2f6665b66ecdcecc9a732942425b17a5ebc78666 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 18:58:55 -0400 Subject: [PATCH 123/247] lint: rename namespace `EXPR` -> `expressions` --- ts/docs/API-Overview.md | 30 +++++++-------- ts/src/-deprecations.ts | 38 +++++++++---------- ts/src/binaryen.ts | 2 +- ts/src/classes/expression/index.ts | 2 +- ts/src/globals.ts | 24 ++++++------ ts/src/services/expression-builder/control.ts | 22 +++++------ ts/src/services/expression-builder/local.ts | 17 ++++----- .../services/expression-builder/parametric.ts | 13 +++---- 8 files changed, 69 insertions(+), 79 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 6e6cf244bee..b05c1c28874 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -232,23 +232,23 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” ## Expression Manipulation -Expression info classes all live under the global `EXPR` namespace. +Expression info classes all live under the global `expressions` namespace. They can be used to inspect and manipulate expressions. See generated docs for fields, methods, and descriptions of each. -- `EXPR.Expression` (root class) +- `expressions.Expression` (root class) - parametric instructions - - `EXPR.Drop` - - `EXPR.Select` + - `expressions.Drop` + - `expressions.Select` - control instructions - - `EXPR.Block` - - `EXPR.Loop` - - `EXPR.Break` + - `expressions.Block` + - `expressions.Loop` + - `expressions.Break` - variable instructions - - `EXPR.LocalGet` - - `EXPR.LocalSet` + - `expressions.LocalGet` + - `expressions.LocalSet` - numeric instructions - - `EXPR.Const` + - `expressions.Const` @@ -269,11 +269,11 @@ Enum names have been singularized. - `ElementSegmentInfo` → `Module.ElementSegment` - `ExportInfo` → `Module.Export` -`ExpressionInfo` and related types are now classes in the `EXPR` namespace: -- `ExpressionInfo` → `EXPR.Expression` -- `BlockInfo` → `EXPR.Block` -- `LoopInfo` → `EXPR.Loop` -- `IfInfo` → `EXPR.If` +`ExpressionInfo` and related types are now classes in the `expressions` namespace: +- `ExpressionInfo` → `expressions.Expression` +- `BlockInfo` → `expressions.Block` +- `LoopInfo` → `expressions.Loop` +- `IfInfo` → `expressions.If` - etc. ~~`MemorySegmentInfo`~~ ❌ has been removed. diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index aa139e72743..ec778c6f469 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -2,7 +2,7 @@ -import type * as EXPR from "./classes/expression/index.ts"; +import type * as expressions from "./classes/expression/index.ts"; import { Feature, Module, @@ -57,24 +57,24 @@ export type ExportInfo = Module.Export; -/** @deprecated The `ExpressionInfo` object type is now called {@link EXPR.Expression}. */ -export type ExpressionInfo = EXPR.Expression; -/** @deprecated The `DropInfo` object type is now called {@link EXPR.Drop}. */ -export type DropInfo = EXPR.Drop; -/** @deprecated The `SelectInfo` object type is now called {@link EXPR.Select}. */ -export type SelectInfo = EXPR.Select; -/** @deprecated The `BlockInfo` object type is now called {@link EXPR.Block}. */ -export type BlockInfo = EXPR.Block; -/** @deprecated The `LoopInfo` object type is now called {@link EXPR.Loop}. */ -export type LoopInfo = EXPR.Loop; -/** @deprecated The `BreakInfo` object type is now called {@link EXPR.Break}. */ -export type BreakInfo = EXPR.Break; -/** @deprecated The `LocalGetInfo` object type is now called {@link EXPR.LocalGet}. */ -export type LocalGetInfo = EXPR.LocalGet; -/** @deprecated The `LocalSetInfo` object type is now called {@link EXPR.LocalSet}. */ -export type LocalSetInfo = EXPR.LocalSet; -/** @deprecated The `ConstInfo` object type is now called {@link EXPR.Const}. */ -export type ConstInfo = EXPR.Const; +/** @deprecated The `ExpressionInfo` object type is now called {@link expressions.Expression}. */ +export type ExpressionInfo = expressions.Expression; +/** @deprecated The `DropInfo` object type is now called {@link expressions.Drop}. */ +export type DropInfo = expressions.Drop; +/** @deprecated The `SelectInfo` object type is now called {@link expressions.Select}. */ +export type SelectInfo = expressions.Select; +/** @deprecated The `BlockInfo` object type is now called {@link expressions.Block}. */ +export type BlockInfo = expressions.Block; +/** @deprecated The `LoopInfo` object type is now called {@link expressions.Loop}. */ +export type LoopInfo = expressions.Loop; +/** @deprecated The `BreakInfo` object type is now called {@link expressions.Break}. */ +export type BreakInfo = expressions.Break; +/** @deprecated The `LocalGetInfo` object type is now called {@link expressions.LocalGet}. */ +export type LocalGetInfo = expressions.LocalGet; +/** @deprecated The `LocalSetInfo` object type is now called {@link expressions.LocalSet}. */ +export type LocalSetInfo = expressions.LocalSet; +/** @deprecated The `ConstInfo` object type is now called {@link expressions.Const}. */ +export type ConstInfo = expressions.Const; /** @deprecated The `Function` class now lives under the `Module` namespace. Use {@link Module.Function}. */ export const Function = Module.Function; diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index c22e6fd76b8..c2238f29e34 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -2,7 +2,7 @@ export * from "./constants.ts"; export * from "./globals.ts"; export {type SettingsService, settings} from "./services/SettingsService.ts"; -export * as EXPR from "./classes/expression/index.ts"; +export * as expressions from "./classes/expression/index.ts"; export type {ExpressionBuilder} from "./services/expression-builder/expressionBuilder.ts"; export { Feature, diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index b76135653d7..8a3911fa810 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -4,7 +4,7 @@ * The {@link Expression} class is the root class in the hierarchy; * all other classes in this module extend it and describe specific kinds of expressions. * Each expression type corresponds to an {@link ExpressionId}. - * @module EXPR + * @module expressions */ diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 017e35d5f8c..dd0f331b5f1 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -15,7 +15,7 @@ import { type Feature, Module, } from "./classes/module/Module.ts"; -import * as EXPR from "./classes/expression/index.ts"; +import * as expressions from "./classes/expression/index.ts"; import { ExpressionId, type ExpressionRef, @@ -32,15 +32,15 @@ import { -const EXPRESSION_TYPE_REGISTRY: ReadonlyMap EXPR.Expression> = new Map EXPR.Expression>([ - [ExpressionId.Drop, EXPR.Drop], - [ExpressionId.Select, EXPR.Select], - [ExpressionId.Block, EXPR.Block], - [ExpressionId.Loop, EXPR.Loop], - [ExpressionId.Break, EXPR.Break], - [ExpressionId.LocalGet, EXPR.LocalGet], - [ExpressionId.LocalSet, EXPR.LocalSet], - [ExpressionId.Const, EXPR.Const], +const EXPRESSION_TYPE_REGISTRY: ReadonlyMap expressions.Expression> = new Map expressions.Expression>([ + [ExpressionId.Drop, expressions.Drop], + [ExpressionId.Select, expressions.Select], + [ExpressionId.Block, expressions.Block], + [ExpressionId.Loop, expressions.Loop], + [ExpressionId.Break, expressions.Break], + [ExpressionId.LocalGet, expressions.LocalGet], + [ExpressionId.LocalSet, expressions.LocalSet], + [ExpressionId.Const, expressions.Const], ]); @@ -206,10 +206,10 @@ export function getExpressionType(expr: ExpressionRef): Type { * Additional properties depend on the expression’s ID * and are usually equivalent to the respective parameters when creating such an expression. */ -export function getExpressionInfo(expr: ExpressionRef): EXPR.Expression { +export function getExpressionInfo(expr: ExpressionRef): expressions.Expression { const id = getExpressionId(expr); const specificExpression = EXPRESSION_TYPE_REGISTRY.get(id); - return specificExpression ? new specificExpression(expr) : new EXPR.Expression(id, expr); + return specificExpression ? new specificExpression(expr) : new expressions.Expression(id, expr); } /** Gets the side effects of the specified expression. */ diff --git a/ts/src/services/expression-builder/control.ts b/ts/src/services/expression-builder/control.ts index 727fdabd9f3..0932595b785 100644 --- a/ts/src/services/expression-builder/control.ts +++ b/ts/src/services/expression-builder/control.ts @@ -1,11 +1,7 @@ import { consoleWarn, } from "../../lib.ts"; -import { - Block, - Break, - Loop, -} from "../../classes/expression/index.ts"; +import * as expressions from "../../classes/expression/index.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -20,15 +16,15 @@ const STUB = (..._args: readonly number[]): number => 0; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ export function control(mod: Module) { return { - /** @inheritDoc EXPR.Block.block */ - block: Block.block.bind(null, mod), - /** @inheritDoc EXPR.Loop.loop */ - loop: Loop.loop.bind(null, mod), + /** @inheritDoc expressions.Block.block */ + block: expressions.Block.block.bind(null, mod), + /** @inheritDoc expressions.Loop.loop */ + loop: expressions.Loop.loop.bind(null, mod), if: STUB, - /** @inheritDoc EXPR.Break.br */ - br: Break.br.bind(null, mod), - /** @inheritDoc EXPR.Break.br_if */ - br_if: Break.br_if.bind(null, mod), + /** @inheritDoc expressions.Break.br */ + br: expressions.Break.br.bind(null, mod), + /** @inheritDoc expressions.Break.br_if */ + br_if: expressions.Break.br_if.bind(null, mod), br_table: STUB, br_on_null: STUB, br_on_non_null: STUB, diff --git a/ts/src/services/expression-builder/local.ts b/ts/src/services/expression-builder/local.ts index d77e9c955df..011b38b3793 100644 --- a/ts/src/services/expression-builder/local.ts +++ b/ts/src/services/expression-builder/local.ts @@ -1,7 +1,4 @@ -import { - LocalGet, - LocalSet, -} from "../../classes/expression/index.ts"; +import * as expressions from "../../classes/expression/index.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -11,11 +8,11 @@ import type { /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#variable-instructions */ export function local(mod: Module) { return { - /** @inheritDoc EXPR.LocalGet.localGet */ - get: LocalGet.localGet.bind(null, mod), - /** @inheritDoc EXPR.LocalSet.localSet */ - set: LocalSet.localSet.bind(null, mod), - /** @inheritDoc EXPR.LocalSet.localTee */ - tee: LocalSet.localTee.bind(null, mod), + /** @inheritDoc expressions.LocalGet.localGet */ + get: expressions.LocalGet.localGet.bind(null, mod), + /** @inheritDoc expressions.LocalSet.localSet */ + set: expressions.LocalSet.localSet.bind(null, mod), + /** @inheritDoc expressions.LocalSet.localTee */ + tee: expressions.LocalSet.localTee.bind(null, mod), } as const; } diff --git a/ts/src/services/expression-builder/parametric.ts b/ts/src/services/expression-builder/parametric.ts index 58500cab28d..883f09620d5 100644 --- a/ts/src/services/expression-builder/parametric.ts +++ b/ts/src/services/expression-builder/parametric.ts @@ -1,10 +1,7 @@ import { BinaryenObj, } from "../../-pre.ts"; -import { - Drop, - Select, -} from "../../classes/expression/index.ts"; +import * as expressions from "../../classes/expression/index.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -21,9 +18,9 @@ export function parametric(mod: Module) { nop: (): ExpressionRef => BinaryenObj["_BinaryenNop"](mod.ptr), /** Creates an unreachable instruction that will always trap. */ unreachable: (): ExpressionRef => BinaryenObj["_BinaryenUnreachable"](mod.ptr), - /** @inheritDoc EXPR.Drop.drop */ - drop: Drop.drop.bind(null, mod), - /** @inheritDoc EXPR.Select.select */ - select: Select.select.bind(null, mod), + /** @inheritDoc expressions.Drop.drop */ + drop: expressions.Drop.drop.bind(null, mod), + /** @inheritDoc expressions.Select.select */ + select: expressions.Select.select.bind(null, mod), } as const; } From 2ed7331bc03530adaa6097449415d7e0e396b445 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 19:14:44 -0400 Subject: [PATCH 124/247] refactor: move {getSideEffects,copyExpression} to Module --- ts/docs/API-Overview.md | 2 +- ts/src/-deprecations.ts | 9 +++++++++ ts/src/classes/module/Module.ts | 20 +++++++++++--------- ts/src/globals.ts | 11 ----------- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index b05c1c28874..fc30fb69428 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -316,7 +316,7 @@ Some of `Module`’s instance methods have been converted into getters/setters: - `Module#getFeatures()` → `Module#features` - `Module#setFeatures()` → `Module#features` -`Module#copyExpression(expr)` has been moved to the global function `copyExpression(expr, mod)` where it lives alongside `getExpressionInfo` et al. +Global `getSideEffects(expr, mod)` has been moved to `Module#getSideEffects()` where it lives alongside `Module#copyExpression()`. All “type” properties (`.i32`, `.i64`, etc) on `Module` previously served as namespaces containing functions for building expressions. (E.g., `Module#i32.add()` produced an `(i32.add)` WASM instruction.) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index ec778c6f469..c4b8571bc62 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -11,6 +11,7 @@ import { type ElementSegmentRef, type ExportRef, ExpressionId, + type ExpressionRef, ExternalKind, type FunctionRef, type GlobalRef, @@ -83,6 +84,14 @@ export const Table = Module.Table; +/** @deprecated Use {@link Module#getSideEffects} instead. */ +export function getSideEffects(expr: ExpressionRef, mod: Module) { + consoleWarn("Global function `getSideEffects(expr, mod)` is deprecated; use `mod.getSideEffects(expr)` instead."); + return mod.getSideEffects(expr); +} + + + /** @deprecated Use {@link Module.Tag | `new Module.Tag(tagref)`} instead. */ export function getTagInfo(tag: TagRef) { consoleWarn("Global function `getTagInfo` is deprecated; use `new Module.Tag(tagref)` instead."); diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index c433fbf3a0d..c13d5cce4e3 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -10,6 +10,7 @@ import { type ExpressionRef, type FunctionRef, type HeapType, + type SideEffect, type TableRef, type Type, i32, @@ -26,9 +27,6 @@ import { externref, stringref, } from "../../constants.ts"; -import { - copyExpression, -} from "../../globals.ts"; import { replacedBy, } from "../../lib.ts"; @@ -215,6 +213,16 @@ export class Module { } } + /** Gets the side effects of the specified expression. */ + getSideEffects(expr: ExpressionRef): SideEffect { + return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, this.ptr); + } + + /** Creates a deep copy of an expression. */ + copyExpression(expr: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenExpressionCopy"](expr, this.ptr); + } + // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html readonly tags = new ModuleTags(this); @@ -462,12 +470,6 @@ export class Module { updateMaps(): void { BinaryenObj["_BinaryenModuleUpdateMaps"](this.ptr); } - - /** @deprecated Use {@link copyExpression | `copyExpression(expr, this)`} instead. */ - @replacedBy("global `copyExpression(expr, this)`") - copyExpression(expr: ExpressionRef) { - return copyExpression(expr, this); - } } diff --git a/ts/src/globals.ts b/ts/src/globals.ts index dd0f331b5f1..5717039498f 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -20,7 +20,6 @@ import { ExpressionId, type ExpressionRef, type HeapType, - type SideEffect, type Type, } from "./constants.ts"; import { @@ -211,13 +210,3 @@ export function getExpressionInfo(expr: ExpressionRef): expressions.Expression { const specificExpression = EXPRESSION_TYPE_REGISTRY.get(id); return specificExpression ? new specificExpression(expr) : new expressions.Expression(id, expr); } - -/** Gets the side effects of the specified expression. */ -export function getSideEffects(expr: ExpressionRef, mod: Module): SideEffect { - return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, mod.ptr); -} - -/** Creates a deep copy of an expression. */ -export function copyExpression(expr: ExpressionRef, mod: Module): ExpressionRef { - return BinaryenObj["_BinaryenExpressionCopy"](expr, mod.ptr); -} From e232247a3f72ebf028f20babea7b09a231c6ac92 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 19:28:39 -0400 Subject: [PATCH 125/247] docs: categorize Module methods --- ts/src/classes/module/Module.ts | 119 ++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 28 deletions(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index c13d5cce4e3..759d2f2fea9 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -171,8 +171,10 @@ export class Module { /** @class */ static readonly Export = Export_; + /** @internal */ readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); + // ## Expression Manipulation ## // /** * This module’s {@link ExpressionBuilder | WASM expression builder}. * @@ -187,10 +189,14 @@ export class Module { * const {i32, drop} = mod.wasm; * drop(i32.add(i32.const(3), i32.const(5))); * ``` + * @category Expression Manipulation */ readonly wasm: ExpressionBuilder = expressionBuilder(this); - /** Pseudo-instruction enabling Binaryen to reason about multiple values on the stack. */ + /** + * Pseudo-instruction enabling Binaryen to reason about multiple values on the stack. + * @category Expression Manipulation + */ pop(typ: Type): ExpressionRef { if ([ i32, @@ -213,34 +219,43 @@ export class Module { } } - /** Gets the side effects of the specified expression. */ + /** + * Gets the side effects of the specified expression. + * @category Expression Manipulation + */ getSideEffects(expr: ExpressionRef): SideEffect { return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, this.ptr); } - /** Creates a deep copy of an expression. */ + /** + * Creates a deep copy of an expression. + * @category Expression Manipulation + */ copyExpression(expr: ExpressionRef): ExpressionRef { return BinaryenObj["_BinaryenExpressionCopy"](expr, this.ptr); } // ## Module Component Operations ## // // see https://webassembly.github.io/spec/core/syntax/modules.html - readonly tags = new ModuleTags(this); - readonly globals = new ModuleGlobals(this); - readonly memories = new ModuleMemories(this); - readonly tables = new ModuleTables(this); - readonly functions = new ModuleFunctions(this); - readonly dataSegments = new ModuleDataSegments(this); - readonly elementSegments = new ModuleElementSegments(this); - readonly imports = new ModuleImports(this); - readonly exports = new ModuleExports(this); + /** @category Module Component Operations */ readonly tags = new ModuleTags(this); + /** @category Module Component Operations */ readonly globals = new ModuleGlobals(this); + /** @category Module Component Operations */ readonly memories = new ModuleMemories(this); + /** @category Module Component Operations */ readonly tables = new ModuleTables(this); + /** @category Module Component Operations */ readonly functions = new ModuleFunctions(this); + /** @category Module Component Operations */ readonly dataSegments = new ModuleDataSegments(this); + /** @category Module Component Operations */ readonly elementSegments = new ModuleElementSegments(this); + /** @category Module Component Operations */ readonly imports = new ModuleImports(this); + /** @category Module Component Operations */ readonly exports = new ModuleExports(this); /** @deprecated Use {@link Module#start | `this.start`} instead. */ @replacedBy("`this.start`") getStart() { return this.start; } /** @deprecated Use {@link Module#start | `this.start`} instead. */ @replacedBy("`this.start`") setStart(start: FunctionRef) { this.start = start; } /** @deprecated Use {@link Module#features | `this.features`} instead. */ @replacedBy("`this.features`") getFeatures() { return this.features; } /** @deprecated Use {@link Module#features | `this.features`} instead. */ @replacedBy("`this.features`") setFeatures(features: Feature) { return this.features = features; } - /** The start function. */ + /** + * The start function. + * @category Module Component Operations + */ get start(): FunctionRef { return BinaryenObj["_BinaryenGetStart"](this.ptr); } @@ -252,6 +267,7 @@ export class Module { /** * The WebAssembly features enabled for this module. * Features are a bitmask of `Feature` enum members. + * @category Module Component Operations */ get features(): Feature { return BinaryenObj["_BinaryenModuleGetFeatures"](this.ptr); @@ -314,17 +330,22 @@ export class Module { /** @deprecated Use {@link Module#exports | `this.exports.addTable`} instead. */ @replacedBy("`this.exports.addTable`") addTableExport(internalName: string, externalName: string) { return this.exports.addTable(internalName, externalName); } /** @deprecated Use {@link Module#exports | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } + /** @category Module Component Operations */ getMemoryInfo(name: string): Memory_ { return new Memory_(this, name); } + /** @category Module Component Operations */ getDataSegmentInfo(segment: DataSegmentRef): DataSegment_ { return new DataSegment_(this, segment); } // ## Binaryen Operations ## // // ### Emission & Execution ### // - /** Returns the module in Binaryen’s s-expression text format (not official stack-style text format). */ + /** + * Returns the module in Binaryen’s s-expression text format (not official stack-style text format). + * @category Emission & Execution + */ emitText(): string { const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteText"](this.ptr); const text = UTF8ToString(textPtr); @@ -334,7 +355,10 @@ export class Module { return text; } - /** Returns the module in official stack-style text format. */ + /** + * Returns the module in official stack-style text format. + * @category Emission & Execution + */ emitStackIR(): string { const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteStackIR"](this.ptr); const text = UTF8ToString(textPtr); @@ -344,7 +368,10 @@ export class Module { return text; } - /** Returns the [asm.js](http://asmjs.org/) representation of the module. */ + /** + * Returns the [asm.js](http://asmjs.org/) representation of the module. + * @category Emission & Execution + */ emitAsmjs(): string { let returned = ""; const saved = out; @@ -356,9 +383,15 @@ export class Module { return returned; } - /** Returns the module in binary format. */ + /** + * Returns the module in binary format. + * @category Emission & Execution + */ emitBinary(): Uint8Array; - /** Returns the module in binary format with a given source map. */ + /** + * Returns the module in binary format with a given source map. + * @category Emission & Execution + */ emitBinary(sourceMapUrl: string): {binary: Uint8Array, sourceMap: string}; emitBinary(sourceMapUrl?: string): Uint8Array | {binary: Uint8Array, sourceMap: string} { return preserveStack(() => { @@ -382,28 +415,43 @@ export class Module { }); } - /** Runs the module in the interpreter, calling the start function. */ + /** + * Runs the module in the interpreter, calling the start function. + * @category Emission & Execution + */ interpret(): void { BinaryenObj["_BinaryenModuleInterpret"](this.ptr); } - /** Releases the resources held by the module once it isn't needed anymore. */ + /** + * Releases the resources held by the module once it isn't needed anymore. + * @category Emission & Execution + */ dispose(): void { BinaryenObj["_BinaryenModuleDispose"](this.ptr); } // ### Validation & Optimization ### // - /** Validates the module. Returns `true` if valid, otherwise prints validation errors and returns `false`. */ + /** + * Validates the module. Returns `true` if valid, otherwise prints validation errors and returns `false`. + * @category Validation & Optimization + */ validate(): number { return BinaryenObj["_BinaryenModuleValidate"](this.ptr); } - /** Optimizes the module using the default optimization passes. */ + /** + * Optimizes the module using the default optimization passes. + * @category Validation & Optimization + */ optimize(): void { BinaryenObj["_BinaryenModuleOptimize"](this.ptr); } - /** Optimizes a single function using the default optimization passes. */ + /** + * Optimizes a single function using the default optimization passes. + * @category Validation & Optimization + */ optimizeFunction(func: FunctionRef | string): void { if (typeof func === "string") { func = this.functions.get(func); @@ -411,14 +459,20 @@ export class Module { BinaryenObj["_BinaryenFunctionOptimize"](func, this.ptr); } - /** Runs the specified passes on the module. */ + /** + * Runs the specified passes on the module. + * @category Validation & Optimization + */ runPasses(passes: readonly string[]): void { return preserveStack(() => { BinaryenObj["_BinaryenModuleRunPasses"](this.ptr, i32sToStack(passes.map(strToStack)), passes.length); }); } - /** Runs the specified passes on a single function. */ + /** + * Runs the specified passes on a single function. + * @category Validation & Optimization + */ runPassesOnFunction(func: string | FunctionRef, passes: readonly string[]): void { if (typeof func === "string") { func = this.functions.get(func); @@ -429,17 +483,26 @@ export class Module { } // ### Debugging ### // - /** Adds a debug info file name to the module and returns its index. */ + /** + * Adds a debug info file name to the module and returns its index. + * @category Debugging + */ addDebugInfoFileName(filename: string): number { return preserveStack(() => BinaryenObj["_BinaryenModuleAddDebugInfoFileName"](this.ptr, strToStack(filename))); } - /** Gets the name of the debug info file at the specified index. */ + /** + * Gets the name of the debug info file at the specified index. + * @category Debugging + */ getDebugInfoFileName(index: number): string { return UTF8ToString(BinaryenObj["_BinaryenModuleGetDebugInfoFileName"](this.ptr, index)); } - /** Sets the debug location of the specified `ExpressionRef` within the specified `FunctionRef`. */ + /** + * Sets the debug location of the specified `ExpressionRef` within the specified `FunctionRef`. + * @category Debugging + */ setDebugLocation(func: FunctionRef, expr: ExpressionRef, fileIndex: number, lineNumber: number, columnNumber: number): void { BinaryenObj["_BinaryenFunctionSetDebugLocation"](func, expr, fileIndex, lineNumber, columnNumber); } From fbcffe0d81bdb9c4dacc83703d47a3909ff1d602 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 19:29:10 -0400 Subject: [PATCH 126/247] build: add "module" to tsconfig --- ts/test/tsconfig.json | 1 + ts/tsconfig.json | 1 + 2 files changed, 2 insertions(+) diff --git a/ts/test/tsconfig.json b/ts/test/tsconfig.json index 3437380bf30..ac7d15ce09e 100644 --- a/ts/test/tsconfig.json +++ b/ts/test/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "compilerOptions": { // Modules + "module": "nodenext", "rootDir": "../", "types": ["node"], diff --git a/ts/tsconfig.json b/ts/tsconfig.json index ec6584661eb..ffcee485644 100644 --- a/ts/tsconfig.json +++ b/ts/tsconfig.json @@ -8,6 +8,7 @@ "noPropertyAccessFromIndexSignature": true, // Modules + "module": "esnext", "rewriteRelativeImportExtensions": true, "rootDir": "./src/", From d0864dabc79768c39fd85af877f558aba42af13b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 22:50:03 -0400 Subject: [PATCH 127/247] feat: add control class static methods --- ts/src/classes/expression/BrOn.ts | 33 ++++++++++++ ts/src/classes/expression/Call.ts | 15 ++++++ ts/src/classes/expression/CallIndirect.ts | 10 ++++ ts/src/classes/expression/CallRef.ts | 12 +++++ ts/src/classes/expression/If.ts | 9 ++++ ts/src/classes/expression/Rethrow.ts | 9 ++++ ts/src/classes/expression/Return.ts | 28 ++++++++++ ts/src/classes/expression/Switch.ts | 17 ++++++ ts/src/classes/expression/Throw.ts | 10 ++++ ts/src/classes/expression/Try.ts | 26 +++++++++ ts/src/services/expression-builder/control.ts | 53 +++++++++++-------- 11 files changed, 201 insertions(+), 21 deletions(-) diff --git a/ts/src/classes/expression/BrOn.ts b/ts/src/classes/expression/BrOn.ts index fdc229a9824..d785015c62a 100644 --- a/ts/src/classes/expression/BrOn.ts +++ b/ts/src/classes/expression/BrOn.ts @@ -6,19 +6,52 @@ import { ExpressionId, type ExpressionRef, type Type, + unreachable, } from "../../constants.ts"; import { THIS_PTR, preserveStack, strToStack, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; +import { + Operation, +} from "./Operation.ts"; export class BrOn extends Expression { + static #brOn(mod: Module, op: Operation, label: string, value: ExpressionRef, castType: Type): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenBrOn"](mod.ptr, op, strToStack(label), value, castType)); + } + + /** Branches if the reference operand is null. */ + static brOnNull(mod: Module, label: string, value: ExpressionRef): ExpressionRef { + return this.#brOn(mod, Operation.BrOnNull, label, value, unreachable); + } + + /** Branches if the reference operand is not null. */ + static brOnNonNull(mod: Module, label: string, value: ExpressionRef): ExpressionRef { + return this.#brOn(mod, Operation.BrOnNonNull, label, value, unreachable); + } + + /** Branches if the reference operand is successfully downcast to the given type. */ + static brOnCast(mod: Module, label: string, value: ExpressionRef, castType: Type): ExpressionRef { + return this.#brOn(mod, Operation.BrOnCast, label, value, castType); + } + + /** Branches if the reference operand fails to downcast to the given type. */ + static brOnCastFail(mod: Module, label: string, value: ExpressionRef, castType: Type): ExpressionRef { + return this.#brOn(mod, Operation.BrOnCastFail, label, value, castType); + } + + + constructor(expr: ExpressionRef) { super(ExpressionId.BrOn, expr); } diff --git a/ts/src/classes/expression/Call.ts b/ts/src/classes/expression/Call.ts index 82f00d0884b..432f499d9fc 100644 --- a/ts/src/classes/expression/Call.ts +++ b/ts/src/classes/expression/Call.ts @@ -5,14 +5,19 @@ import { import { ExpressionId, type ExpressionRef, + type Type, } from "../../constants.ts"; import { THIS_PTR, getAllNested, + i32sToStack, preserveStack, setAllNested, strToStack, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -20,6 +25,16 @@ import { export class Call extends Expression { + /** + * Creates a call to a function. + * Note that we must specify the return type here as we may not have created the function being called yet. + */ + // NOTE: the `override` keyword is needed here to override JavaScript’s intrinsic `Function#call` method + static override call(mod: Module, name: string, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenCall"](mod.ptr, strToStack(name), i32sToStack(operands), operands.length, resultsType)); + } + + constructor(expr: ExpressionRef) { super(ExpressionId.Call, expr); } diff --git a/ts/src/classes/expression/CallIndirect.ts b/ts/src/classes/expression/CallIndirect.ts index 04c1f5752b6..7194c73dc34 100644 --- a/ts/src/classes/expression/CallIndirect.ts +++ b/ts/src/classes/expression/CallIndirect.ts @@ -10,10 +10,14 @@ import { import { THIS_PTR, getAllNested, + i32sToStack, preserveStack, setAllNested, strToStack, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -21,6 +25,12 @@ import { export class CallIndirect extends Expression { + /** Similar to `call_ref`, but indexes into a table to find the function to call. */ + static callIndirect(mod: Module, table: string, target: ExpressionRef, operands: readonly ExpressionRef[], paramsType: Type, resultsType: Type): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenCallIndirect"](mod.ptr, strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)); + } + + constructor(expr: ExpressionRef) { super(ExpressionId.CallIndirect, expr); } diff --git a/ts/src/classes/expression/CallRef.ts b/ts/src/classes/expression/CallRef.ts index ae5363951c2..3536e98eb06 100644 --- a/ts/src/classes/expression/CallRef.ts +++ b/ts/src/classes/expression/CallRef.ts @@ -4,10 +4,16 @@ import { import { ExpressionId, type ExpressionRef, + type Type, } from "../../constants.ts"; import { THIS_PTR, + i32sToStack, + preserveStack, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -15,6 +21,12 @@ import { export class CallRef extends Expression { + /** Similar to `call`, but takes a function reference operand instead of a name as the called value. */ + static callRef(mod: Module, target: ExpressionRef, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenCallRef"](mod.ptr, target, i32sToStack(operands), operands.length, resultsType)); + } + + constructor(expr: ExpressionRef) { super(ExpressionId.CallRef, expr); } diff --git a/ts/src/classes/expression/If.ts b/ts/src/classes/expression/If.ts index 2e827c75f16..e1e1f5efbb7 100644 --- a/ts/src/classes/expression/If.ts +++ b/ts/src/classes/expression/If.ts @@ -8,6 +8,9 @@ import { import { THIS_PTR, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -15,6 +18,12 @@ import { export class If extends Expression { + /** Creates an ‘if’ or ‘if/else’ combination. */ + static if(mod: Module, ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenIf"](mod.ptr, ifTrue, ifFalse); + } + + constructor(expr: ExpressionRef) { super(ExpressionId.If, expr); } diff --git a/ts/src/classes/expression/Rethrow.ts b/ts/src/classes/expression/Rethrow.ts index 0a534bd67c9..881e5b158a4 100644 --- a/ts/src/classes/expression/Rethrow.ts +++ b/ts/src/classes/expression/Rethrow.ts @@ -11,6 +11,9 @@ import { preserveStack, strToStack, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -18,6 +21,12 @@ import { export class Rethrow extends Expression { + /** Reraise an exception. */ + static throwRef(mod: Module, target: string): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenRethrow"](mod.ptr, strToStack(target))); + } + + constructor(expr: ExpressionRef) { super(ExpressionId.Rethrow, expr); } diff --git a/ts/src/classes/expression/Return.ts b/ts/src/classes/expression/Return.ts index 727eac9749d..b9cc16214e6 100644 --- a/ts/src/classes/expression/Return.ts +++ b/ts/src/classes/expression/Return.ts @@ -4,10 +4,17 @@ import { import { ExpressionId, type ExpressionRef, + type Type, } from "../../constants.ts"; import { THIS_PTR, + i32sToStack, + preserveStack, + strToStack, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -15,6 +22,27 @@ import { export class Return extends Expression { + /** Unconditional branch to the body of the current function. */ + static return(mod: Module, value: ExpressionRef): ExpressionRef { + return BinaryenObj["_BinaryenReturn"](mod.ptr, value); + } + + /** Tail-call variant of `call`. */ + static returnCall(mod: Module, name: string, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenReturnCall"](mod.ptr, strToStack(name), i32sToStack(operands), operands.length, resultsType)); + } + + /** Tail-call variant of `call_ref`. */ + static returnCallRef(mod: Module, target: ExpressionRef, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenReturnCallRef"](mod.ptr, target, i32sToStack(operands), operands.length, resultsType)); + } + + /** Tail-call variant of `call_indirect`. */ + static returnCallIndirect(mod: Module, table: string, target: ExpressionRef, operands: readonly ExpressionRef[], paramsType: Type, resultsType: Type): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenReturnCallIndirect"](mod.ptr, strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)); + } + + constructor(expr: ExpressionRef) { super(ExpressionId.Return, expr); } diff --git a/ts/src/classes/expression/Switch.ts b/ts/src/classes/expression/Switch.ts index 2bfd1406878..c0b4ca556eb 100644 --- a/ts/src/classes/expression/Switch.ts +++ b/ts/src/classes/expression/Switch.ts @@ -9,10 +9,14 @@ import { import { THIS_PTR, getAllNested, + i32sToStack, preserveStack, setAllNested, strToStack, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -20,6 +24,19 @@ import { export class Switch extends Expression { + /** Creates a switch. */ + static brTable(mod: Module, labels: readonly string[], defaultLabel: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenSwitch"]( + mod.ptr, + i32sToStack(labels.map(strToStack)), + labels.length, + strToStack(defaultLabel), + condition, + value!, + )); + } + + constructor(expr: ExpressionRef) { super(ExpressionId.Switch, expr); } diff --git a/ts/src/classes/expression/Throw.ts b/ts/src/classes/expression/Throw.ts index d3f5ab1a3ef..ed4ecccbbe1 100644 --- a/ts/src/classes/expression/Throw.ts +++ b/ts/src/classes/expression/Throw.ts @@ -9,10 +9,14 @@ import { import { THIS_PTR, getAllNested, + i32sToStack, preserveStack, setAllNested, strToStack, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -20,6 +24,12 @@ import { export class Throw extends Expression { + /** Raise an exception. */ + static throw(mod: Module, tag: string, operands: readonly ExpressionRef[]): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenThrow"](mod.ptr, strToStack(tag), i32sToStack(operands), operands.length)); + } + + constructor(expr: ExpressionRef) { super(ExpressionId.Throw, expr); } diff --git a/ts/src/classes/expression/Try.ts b/ts/src/classes/expression/Try.ts index 1f10cc77c66..7024cbdbc7d 100644 --- a/ts/src/classes/expression/Try.ts +++ b/ts/src/classes/expression/Try.ts @@ -9,10 +9,14 @@ import { import { THIS_PTR, getAllNested, + i32sToStack, preserveStack, strToStack, setAllNested, } from "../../utils.ts"; +import type { + Module, +} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -20,6 +24,28 @@ import { export class Try extends Expression { + /** Installs an exception handler that handles exceptions as specified by its catch clauses. */ + static tryTable( + mod: Module, + name: string, + body: ExpressionRef, + catchTags: readonly string[], + catchBodies: readonly ExpressionRef[], + delegateTarget: string, + ): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenTry"]( + mod.ptr, + strToStack(name), + body, + i32sToStack(catchTags.map(strToStack)), + catchTags.length, + i32sToStack(catchBodies), + catchBodies.length, + strToStack(delegateTarget), + )); + } + + constructor(expr: ExpressionRef) { super(ExpressionId.Try, expr); } diff --git a/ts/src/services/expression-builder/control.ts b/ts/src/services/expression-builder/control.ts index 0932595b785..c02f8d510e0 100644 --- a/ts/src/services/expression-builder/control.ts +++ b/ts/src/services/expression-builder/control.ts @@ -8,11 +8,6 @@ import type { -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; - - - /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ export function control(mod: Module) { return { @@ -20,26 +15,42 @@ export function control(mod: Module) { block: expressions.Block.block.bind(null, mod), /** @inheritDoc expressions.Loop.loop */ loop: expressions.Loop.loop.bind(null, mod), - if: STUB, + /** @inheritDoc expressions.If.if */ + if: expressions.If.if.bind(null, mod), /** @inheritDoc expressions.Break.br */ br: expressions.Break.br.bind(null, mod), /** @inheritDoc expressions.Break.br_if */ br_if: expressions.Break.br_if.bind(null, mod), - br_table: STUB, - br_on_null: STUB, - br_on_non_null: STUB, - br_on_cast: STUB, - br_on_cast_fail: STUB, - call: STUB, - call_ref: STUB, - call_indirect: STUB, - return: STUB, - return_call: STUB, - return_call_ref: STUB, - return_call_indirect: STUB, - throw: STUB, - throw_ref: STUB, - try_table: STUB, + /** @inheritDoc expressions.Switch.brTable */ + br_table: expressions.Switch.brTable.bind(null, mod), + /** @inheritDoc expressions.BrOn.brOnNull */ + br_on_null: expressions.BrOn.brOnNull.bind(null, mod), + /** @inheritDoc expressions.BrOn.brOnNonNull */ + br_on_non_null: expressions.BrOn.brOnNonNull.bind(null, mod), + /** @inheritDoc expressions.BrOn.brOnCast */ + br_on_cast: expressions.BrOn.brOnCast.bind(null, mod), + /** @inheritDoc expressions.BrOn.brOnCastFail */ + br_on_cast_fail: expressions.BrOn.brOnCastFail.bind(null, mod), + /** @inheritDoc expressions.Call.call */ + call: expressions.Call.call.bind(null, mod), + /** @inheritDoc expressions.CallRef.callRef */ + call_ref: expressions.CallRef.callRef.bind(null, mod), + /** @inheritDoc expressions.CallIndirect.callIndirect */ + call_indirect: expressions.CallIndirect.callIndirect.bind(null, mod), + /** @inheritDoc expressions.Return.return */ + return: expressions.Return.return.bind(null, mod), + /** @inheritDoc expressions.Return.returnCall */ + return_call: expressions.Return.returnCall.bind(null, mod), + /** @inheritDoc expressions.Return.returnCallRef */ + return_call_ref: expressions.Return.returnCallRef.bind(null, mod), + /** @inheritDoc expressions.Return.returnCallIndirect */ + return_call_indirect: expressions.Return.returnCallIndirect.bind(null, mod), + /** @inheritDoc expressions.Throw.throw */ + throw: expressions.Throw.throw.bind(null, mod), + /** @inheritDoc expressions.Rethrow.throwRef */ + throw_ref: expressions.Rethrow.throwRef.bind(null, mod), + /** @inheritDoc expressions.Try.tryTable */ + try_table: expressions.Try.tryTable.bind(null, mod), // TODO: catch // TODO: catch_ref // TODO: catch_all From b67e08d00a7e55a23d7740aaa7142379990f2077 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 22:57:38 -0400 Subject: [PATCH 128/247] refactor: move parametric instrs from classes --- ts/src/classes/expression/Drop.ts | 9 ------- ts/src/classes/expression/Select.ts | 9 ------- .../services/expression-builder/parametric.ts | 24 +++++++++++++------ 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/ts/src/classes/expression/Drop.ts b/ts/src/classes/expression/Drop.ts index 8085a314b76..17bb44a4607 100644 --- a/ts/src/classes/expression/Drop.ts +++ b/ts/src/classes/expression/Drop.ts @@ -8,9 +8,6 @@ import { import { THIS_PTR, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -18,12 +15,6 @@ import { export class Drop extends Expression { - /** Creates a `(drop)` of a value. */ - static drop(mod: Module, value: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenDrop"](mod.ptr, value); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Drop, expr); } diff --git a/ts/src/classes/expression/Select.ts b/ts/src/classes/expression/Select.ts index 8d07d2711f8..e83c21780af 100644 --- a/ts/src/classes/expression/Select.ts +++ b/ts/src/classes/expression/Select.ts @@ -8,9 +8,6 @@ import { import { THIS_PTR, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -18,12 +15,6 @@ import { export class Select extends Expression { - /** Creates a `(select)` of one of two values. */ - static select(mod: Module, ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenSelect"](mod.ptr, ifTrue, ifFalse); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Select, expr); } diff --git a/ts/src/services/expression-builder/parametric.ts b/ts/src/services/expression-builder/parametric.ts index 883f09620d5..a07ff7f664d 100644 --- a/ts/src/services/expression-builder/parametric.ts +++ b/ts/src/services/expression-builder/parametric.ts @@ -1,7 +1,6 @@ import { BinaryenObj, } from "../../-pre.ts"; -import * as expressions from "../../classes/expression/index.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -15,12 +14,23 @@ import type { export function parametric(mod: Module) { return { /** Creates a no-operation `(nop)` instruction. */ - nop: (): ExpressionRef => BinaryenObj["_BinaryenNop"](mod.ptr), + nop: (): ExpressionRef => ( + BinaryenObj["_BinaryenNop"](mod.ptr) + ), + /** Creates an unreachable instruction that will always trap. */ - unreachable: (): ExpressionRef => BinaryenObj["_BinaryenUnreachable"](mod.ptr), - /** @inheritDoc expressions.Drop.drop */ - drop: expressions.Drop.drop.bind(null, mod), - /** @inheritDoc expressions.Select.select */ - select: expressions.Select.select.bind(null, mod), + unreachable: (): ExpressionRef => ( + BinaryenObj["_BinaryenUnreachable"](mod.ptr) + ), + + /** Creates a `(drop)` of a value. */ + drop: (value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenDrop"](mod.ptr, value) + ), + + /** Creates a `(select)` of one of two values. */ + select: (ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenSelect"](mod.ptr, ifTrue, ifFalse) + ), } as const; } From 6da3bea7429e4281cb52d2cdf54b1a06246b8cea Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 23:42:15 -0400 Subject: [PATCH 129/247] refactor: move control instrs from classes --- ts/src/classes/expression/Block.ts | 18 -- ts/src/classes/expression/BrOn.ts | 33 --- ts/src/classes/expression/Break.ts | 14 -- ts/src/classes/expression/Call.ts | 15 -- ts/src/classes/expression/CallIndirect.ts | 10 - ts/src/classes/expression/CallRef.ts | 12 - ts/src/classes/expression/If.ts | 9 - ts/src/classes/expression/Loop.ts | 9 - ts/src/classes/expression/Rethrow.ts | 9 - ts/src/classes/expression/Return.ts | 28 --- ts/src/classes/expression/Switch.ts | 17 -- ts/src/classes/expression/Throw.ts | 10 - ts/src/classes/expression/Try.ts | 26 -- ts/src/services/expression-builder/control.ts | 224 ++++++++++++++---- .../expression-builder/expressionBuilder.ts | 10 +- 15 files changed, 186 insertions(+), 258 deletions(-) diff --git a/ts/src/classes/expression/Block.ts b/ts/src/classes/expression/Block.ts index 78c8e861250..b39f0bf3c94 100644 --- a/ts/src/classes/expression/Block.ts +++ b/ts/src/classes/expression/Block.ts @@ -5,20 +5,14 @@ import { import { ExpressionId, type ExpressionRef, - type Type, - none, } from "../../constants.ts"; import { THIS_PTR, - i32sToStack, getAllNested, preserveStack, setAllNested, strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -26,18 +20,6 @@ import { export class Block extends Expression { - /** Creates a `(block)`. */ - static block(mod: Module, name: string | null, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenBlock"]( - mod.ptr, - name ? strToStack(name) : 0, - i32sToStack(children), - children.length, - resultType, - )); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Block, expr); } diff --git a/ts/src/classes/expression/BrOn.ts b/ts/src/classes/expression/BrOn.ts index d785015c62a..fdc229a9824 100644 --- a/ts/src/classes/expression/BrOn.ts +++ b/ts/src/classes/expression/BrOn.ts @@ -6,52 +6,19 @@ import { ExpressionId, type ExpressionRef, type Type, - unreachable, } from "../../constants.ts"; import { THIS_PTR, preserveStack, strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; -import { - Operation, -} from "./Operation.ts"; export class BrOn extends Expression { - static #brOn(mod: Module, op: Operation, label: string, value: ExpressionRef, castType: Type): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenBrOn"](mod.ptr, op, strToStack(label), value, castType)); - } - - /** Branches if the reference operand is null. */ - static brOnNull(mod: Module, label: string, value: ExpressionRef): ExpressionRef { - return this.#brOn(mod, Operation.BrOnNull, label, value, unreachable); - } - - /** Branches if the reference operand is not null. */ - static brOnNonNull(mod: Module, label: string, value: ExpressionRef): ExpressionRef { - return this.#brOn(mod, Operation.BrOnNonNull, label, value, unreachable); - } - - /** Branches if the reference operand is successfully downcast to the given type. */ - static brOnCast(mod: Module, label: string, value: ExpressionRef, castType: Type): ExpressionRef { - return this.#brOn(mod, Operation.BrOnCast, label, value, castType); - } - - /** Branches if the reference operand fails to downcast to the given type. */ - static brOnCastFail(mod: Module, label: string, value: ExpressionRef, castType: Type): ExpressionRef { - return this.#brOn(mod, Operation.BrOnCastFail, label, value, castType); - } - - - constructor(expr: ExpressionRef) { super(ExpressionId.BrOn, expr); } diff --git a/ts/src/classes/expression/Break.ts b/ts/src/classes/expression/Break.ts index 596c6e95021..8babad0aef6 100644 --- a/ts/src/classes/expression/Break.ts +++ b/ts/src/classes/expression/Break.ts @@ -11,9 +11,6 @@ import { preserveStack, strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -21,17 +18,6 @@ import { export class Break extends Expression { - /** Creates an unconditional branch `(br)` to a label. */ - static br(mod: Module, label: string, condition?: ExpressionRef, value?: ExpressionRef): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition!, value!)); - } - - /** Creates a conditional branch `(br_if)` to a label. */ - static br_if(mod: Module, label: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition, value!)); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Break, expr); } diff --git a/ts/src/classes/expression/Call.ts b/ts/src/classes/expression/Call.ts index 432f499d9fc..82f00d0884b 100644 --- a/ts/src/classes/expression/Call.ts +++ b/ts/src/classes/expression/Call.ts @@ -5,19 +5,14 @@ import { import { ExpressionId, type ExpressionRef, - type Type, } from "../../constants.ts"; import { THIS_PTR, getAllNested, - i32sToStack, preserveStack, setAllNested, strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -25,16 +20,6 @@ import { export class Call extends Expression { - /** - * Creates a call to a function. - * Note that we must specify the return type here as we may not have created the function being called yet. - */ - // NOTE: the `override` keyword is needed here to override JavaScript’s intrinsic `Function#call` method - static override call(mod: Module, name: string, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenCall"](mod.ptr, strToStack(name), i32sToStack(operands), operands.length, resultsType)); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Call, expr); } diff --git a/ts/src/classes/expression/CallIndirect.ts b/ts/src/classes/expression/CallIndirect.ts index 7194c73dc34..04c1f5752b6 100644 --- a/ts/src/classes/expression/CallIndirect.ts +++ b/ts/src/classes/expression/CallIndirect.ts @@ -10,14 +10,10 @@ import { import { THIS_PTR, getAllNested, - i32sToStack, preserveStack, setAllNested, strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -25,12 +21,6 @@ import { export class CallIndirect extends Expression { - /** Similar to `call_ref`, but indexes into a table to find the function to call. */ - static callIndirect(mod: Module, table: string, target: ExpressionRef, operands: readonly ExpressionRef[], paramsType: Type, resultsType: Type): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenCallIndirect"](mod.ptr, strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.CallIndirect, expr); } diff --git a/ts/src/classes/expression/CallRef.ts b/ts/src/classes/expression/CallRef.ts index 3536e98eb06..ae5363951c2 100644 --- a/ts/src/classes/expression/CallRef.ts +++ b/ts/src/classes/expression/CallRef.ts @@ -4,16 +4,10 @@ import { import { ExpressionId, type ExpressionRef, - type Type, } from "../../constants.ts"; import { THIS_PTR, - i32sToStack, - preserveStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -21,12 +15,6 @@ import { export class CallRef extends Expression { - /** Similar to `call`, but takes a function reference operand instead of a name as the called value. */ - static callRef(mod: Module, target: ExpressionRef, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenCallRef"](mod.ptr, target, i32sToStack(operands), operands.length, resultsType)); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.CallRef, expr); } diff --git a/ts/src/classes/expression/If.ts b/ts/src/classes/expression/If.ts index e1e1f5efbb7..2e827c75f16 100644 --- a/ts/src/classes/expression/If.ts +++ b/ts/src/classes/expression/If.ts @@ -8,9 +8,6 @@ import { import { THIS_PTR, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -18,12 +15,6 @@ import { export class If extends Expression { - /** Creates an ‘if’ or ‘if/else’ combination. */ - static if(mod: Module, ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenIf"](mod.ptr, ifTrue, ifFalse); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.If, expr); } diff --git a/ts/src/classes/expression/Loop.ts b/ts/src/classes/expression/Loop.ts index 2784ec4c0a5..c5fc6de4e7a 100644 --- a/ts/src/classes/expression/Loop.ts +++ b/ts/src/classes/expression/Loop.ts @@ -11,9 +11,6 @@ import { preserveStack, strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -21,12 +18,6 @@ import { export class Loop extends Expression { - /** Creates a `(loop)`. */ - static loop(mod: Module, name: string, body: ExpressionRef): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenLoop"](mod.ptr, strToStack(name), body)); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Loop, expr); } diff --git a/ts/src/classes/expression/Rethrow.ts b/ts/src/classes/expression/Rethrow.ts index 881e5b158a4..0a534bd67c9 100644 --- a/ts/src/classes/expression/Rethrow.ts +++ b/ts/src/classes/expression/Rethrow.ts @@ -11,9 +11,6 @@ import { preserveStack, strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -21,12 +18,6 @@ import { export class Rethrow extends Expression { - /** Reraise an exception. */ - static throwRef(mod: Module, target: string): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenRethrow"](mod.ptr, strToStack(target))); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Rethrow, expr); } diff --git a/ts/src/classes/expression/Return.ts b/ts/src/classes/expression/Return.ts index b9cc16214e6..727eac9749d 100644 --- a/ts/src/classes/expression/Return.ts +++ b/ts/src/classes/expression/Return.ts @@ -4,17 +4,10 @@ import { import { ExpressionId, type ExpressionRef, - type Type, } from "../../constants.ts"; import { THIS_PTR, - i32sToStack, - preserveStack, - strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -22,27 +15,6 @@ import { export class Return extends Expression { - /** Unconditional branch to the body of the current function. */ - static return(mod: Module, value: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenReturn"](mod.ptr, value); - } - - /** Tail-call variant of `call`. */ - static returnCall(mod: Module, name: string, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenReturnCall"](mod.ptr, strToStack(name), i32sToStack(operands), operands.length, resultsType)); - } - - /** Tail-call variant of `call_ref`. */ - static returnCallRef(mod: Module, target: ExpressionRef, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenReturnCallRef"](mod.ptr, target, i32sToStack(operands), operands.length, resultsType)); - } - - /** Tail-call variant of `call_indirect`. */ - static returnCallIndirect(mod: Module, table: string, target: ExpressionRef, operands: readonly ExpressionRef[], paramsType: Type, resultsType: Type): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenReturnCallIndirect"](mod.ptr, strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Return, expr); } diff --git a/ts/src/classes/expression/Switch.ts b/ts/src/classes/expression/Switch.ts index c0b4ca556eb..2bfd1406878 100644 --- a/ts/src/classes/expression/Switch.ts +++ b/ts/src/classes/expression/Switch.ts @@ -9,14 +9,10 @@ import { import { THIS_PTR, getAllNested, - i32sToStack, preserveStack, setAllNested, strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -24,19 +20,6 @@ import { export class Switch extends Expression { - /** Creates a switch. */ - static brTable(mod: Module, labels: readonly string[], defaultLabel: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenSwitch"]( - mod.ptr, - i32sToStack(labels.map(strToStack)), - labels.length, - strToStack(defaultLabel), - condition, - value!, - )); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Switch, expr); } diff --git a/ts/src/classes/expression/Throw.ts b/ts/src/classes/expression/Throw.ts index ed4ecccbbe1..d3f5ab1a3ef 100644 --- a/ts/src/classes/expression/Throw.ts +++ b/ts/src/classes/expression/Throw.ts @@ -9,14 +9,10 @@ import { import { THIS_PTR, getAllNested, - i32sToStack, preserveStack, setAllNested, strToStack, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -24,12 +20,6 @@ import { export class Throw extends Expression { - /** Raise an exception. */ - static throw(mod: Module, tag: string, operands: readonly ExpressionRef[]): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenThrow"](mod.ptr, strToStack(tag), i32sToStack(operands), operands.length)); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Throw, expr); } diff --git a/ts/src/classes/expression/Try.ts b/ts/src/classes/expression/Try.ts index 7024cbdbc7d..1f10cc77c66 100644 --- a/ts/src/classes/expression/Try.ts +++ b/ts/src/classes/expression/Try.ts @@ -9,14 +9,10 @@ import { import { THIS_PTR, getAllNested, - i32sToStack, preserveStack, strToStack, setAllNested, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -24,28 +20,6 @@ import { export class Try extends Expression { - /** Installs an exception handler that handles exceptions as specified by its catch clauses. */ - static tryTable( - mod: Module, - name: string, - body: ExpressionRef, - catchTags: readonly string[], - catchBodies: readonly ExpressionRef[], - delegateTarget: string, - ): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenTry"]( - mod.ptr, - strToStack(name), - body, - i32sToStack(catchTags.map(strToStack)), - catchTags.length, - i32sToStack(catchBodies), - catchBodies.length, - strToStack(delegateTarget), - )); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.Try, expr); } diff --git a/ts/src/services/expression-builder/control.ts b/ts/src/services/expression-builder/control.ts index c02f8d510e0..4aee6da6ffb 100644 --- a/ts/src/services/expression-builder/control.ts +++ b/ts/src/services/expression-builder/control.ts @@ -1,71 +1,203 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import { consoleWarn, } from "../../lib.ts"; -import * as expressions from "../../classes/expression/index.ts"; +import { + Operation, +} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; +import { + type ExpressionRef, + type Type, + none, + unreachable, +} from "../../constants.ts"; +import { + i32sToStack, + preserveStack, + strToStack, +} from "../../utils.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ -export function control(mod: Module) { +export function blocks(mod: Module) { return { - /** @inheritDoc expressions.Block.block */ - block: expressions.Block.block.bind(null, mod), - /** @inheritDoc expressions.Loop.loop */ - loop: expressions.Loop.loop.bind(null, mod), - /** @inheritDoc expressions.If.if */ - if: expressions.If.if.bind(null, mod), - /** @inheritDoc expressions.Break.br */ - br: expressions.Break.br.bind(null, mod), - /** @inheritDoc expressions.Break.br_if */ - br_if: expressions.Break.br_if.bind(null, mod), - /** @inheritDoc expressions.Switch.brTable */ - br_table: expressions.Switch.brTable.bind(null, mod), - /** @inheritDoc expressions.BrOn.brOnNull */ - br_on_null: expressions.BrOn.brOnNull.bind(null, mod), - /** @inheritDoc expressions.BrOn.brOnNonNull */ - br_on_non_null: expressions.BrOn.brOnNonNull.bind(null, mod), - /** @inheritDoc expressions.BrOn.brOnCast */ - br_on_cast: expressions.BrOn.brOnCast.bind(null, mod), - /** @inheritDoc expressions.BrOn.brOnCastFail */ - br_on_cast_fail: expressions.BrOn.brOnCastFail.bind(null, mod), - /** @inheritDoc expressions.Call.call */ - call: expressions.Call.call.bind(null, mod), - /** @inheritDoc expressions.CallRef.callRef */ - call_ref: expressions.CallRef.callRef.bind(null, mod), - /** @inheritDoc expressions.CallIndirect.callIndirect */ - call_indirect: expressions.CallIndirect.callIndirect.bind(null, mod), - /** @inheritDoc expressions.Return.return */ - return: expressions.Return.return.bind(null, mod), - /** @inheritDoc expressions.Return.returnCall */ - return_call: expressions.Return.returnCall.bind(null, mod), - /** @inheritDoc expressions.Return.returnCallRef */ - return_call_ref: expressions.Return.returnCallRef.bind(null, mod), - /** @inheritDoc expressions.Return.returnCallIndirect */ - return_call_indirect: expressions.Return.returnCallIndirect.bind(null, mod), - /** @inheritDoc expressions.Throw.throw */ - throw: expressions.Throw.throw.bind(null, mod), - /** @inheritDoc expressions.Rethrow.throwRef */ - throw_ref: expressions.Rethrow.throwRef.bind(null, mod), - /** @inheritDoc expressions.Try.tryTable */ - try_table: expressions.Try.tryTable.bind(null, mod), - // TODO: catch - // TODO: catch_ref - // TODO: catch_all - // TODO: catch_all_ref + /** Creates a `(block)`. */ + block: (name: string | null, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenBlock"]( + mod.ptr, + name ? strToStack(name) : 0, + i32sToStack(children), + children.length, + resultType, + )) + ), + + /** Creates a `(loop)`. */ + loop: (name: string, body: ExpressionRef): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenLoop"](mod.ptr, strToStack(name), body)) + ), + + /** Creates an ‘if’ or ‘if/else’ combination. */ + if: (ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenIf"](mod.ptr, ifTrue, ifFalse) + ), + } as const; +} + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ +export function breaks(mod: Module) { + function brOn(op: Operation, label: string, value: ExpressionRef, castType: Type): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenBrOn"](mod.ptr, op, strToStack(label), value, castType)); + } + + return { + /** Creates an unconditional branch `(br)` to a label. */ + br: (label: string, condition?: ExpressionRef, value?: ExpressionRef): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition!, value!)) + ), + + /** Creates a conditional branch `(br_if)` to a label. */ + br_if: (label: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition, value!)) + ), + + /** Creates a switch. */ + br_table: (labels: readonly string[], defaultLabel: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenSwitch"]( + mod.ptr, + i32sToStack(labels.map(strToStack)), + labels.length, + strToStack(defaultLabel), + condition, + value!, + )) + ), + + /** Branches if the reference operand is null. */ + br_on_null: (label: string, value: ExpressionRef): ExpressionRef => ( + brOn(Operation.BrOnNull, label, value, unreachable) + ), + + /** Branches if the reference operand is not null. */ + br_on_non_null: (label: string, value: ExpressionRef): ExpressionRef => ( + brOn(Operation.BrOnNonNull, label, value, unreachable) + ), + + /** Branches if the reference operand is successfully downcast to the given type. */ + br_on_cast: (label: string, value: ExpressionRef, castType: Type): ExpressionRef => ( + brOn(Operation.BrOnCast, label, value, castType) + ), + + /** Branches if the reference operand fails to downcast to the given type. */ + br_on_cast_fail: (label: string, value: ExpressionRef, castType: Type): ExpressionRef => ( + brOn(Operation.BrOnCastFail, label, value, castType) + ), // @ts-expect-error /** @deprecated Use {@link ExpressionBuilder#br} instead. */ break(...args) { consoleWarn("`.break()` is deprecated; use `.br()` instead."); return this.br(...args); }, // @ts-expect-error /** @deprecated Use {@link ExpressionBuilder#br_table} instead. */ switch(...args) { consoleWarn("`.switch()` is deprecated; use `.br_table()` instead."); return this.br_table(...args); }, + } as const; +} + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ +export function calls(mod: Module) { + return { + /** + * Creates a call to a function. + * Note that we must specify the return type here as we may not have created the function being called yet. + */ + call: (name: string, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenCall"](mod.ptr, strToStack(name), i32sToStack(operands), operands.length, resultsType)) + ), + + /** Similar to `call`, but takes a function reference operand instead of a name as the called value. */ + call_ref: (target: ExpressionRef, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenCallRef"](mod.ptr, target, i32sToStack(operands), operands.length, resultsType)) + ), + + /** Similar to `call_ref`, but indexes into a table to find the function to call. */ + call_indirect: (table: string, target: ExpressionRef, operands: readonly ExpressionRef[], paramsType: Type, resultsType: Type): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenCallIndirect"](mod.ptr, strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)) + ), + + /** Unconditional branch to the body of the current function. */ + return: (value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenReturn"](mod.ptr, value) + ), + + /** Tail-call variant of `call`. */ + return_call: (name: string, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenReturnCall"](mod.ptr, strToStack(name), i32sToStack(operands), operands.length, resultsType)) + ), + + /** Tail-call variant of `call_ref`. */ + return_call_ref: (target: ExpressionRef, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenReturnCallRef"](mod.ptr, target, i32sToStack(operands), operands.length, resultsType)) + ), + + /** Tail-call variant of `call_indirect`. */ + return_call_indirect: (table: string, target: ExpressionRef, operands: readonly ExpressionRef[], paramsType: Type, resultsType: Type): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenReturnCallIndirect"](mod.ptr, strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)) + ), + // @ts-expect-error /** @deprecated Use {@link ExpressionBuilder#call_indirect} instead. */ callIndirect(...args) { consoleWarn("`.callIndirect()` is deprecated; use `.call_indirect()` instead."); return this.call_indirect(...args); }, // @ts-expect-error /** @deprecated Use {@link ExpressionBuilder#return_call} instead. */ returnCall(...args) { consoleWarn("`.returnCall()` is deprecated; use `.return_call()` instead."); return this.return_call(...args); }, // @ts-expect-error /** @deprecated Use {@link ExpressionBuilder#return_call_indirect} instead. */ returnCallIndirect(...args) { consoleWarn("`.returnCallIndirect()` is deprecated; use `.return_call_indirect()` instead."); return this.return_call_indirect(...args); }, + } as const; +} + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ +export function throws(mod: Module) { + return { + /** Raise an exception. */ + throw: (tag: string, operands: readonly ExpressionRef[]): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenThrow"](mod.ptr, strToStack(tag), i32sToStack(operands), operands.length)) + ), + + /** Reraise an exception. */ + throw_ref: (target: string): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenRethrow"](mod.ptr, strToStack(target))) + ), + + /** Installs an exception handler that handles exceptions as specified by its catch clauses. */ + try_table: ( + name: string, + body: ExpressionRef, + catchTags: readonly string[], + catchBodies: readonly ExpressionRef[], + delegateTarget: string, + ): ExpressionRef => preserveStack(() => BinaryenObj["_BinaryenTry"]( + mod.ptr, + strToStack(name), + body, + i32sToStack(catchTags.map(strToStack)), + catchTags.length, + i32sToStack(catchBodies), + catchBodies.length, + strToStack(delegateTarget), + )), + + // TODO: catch + // TODO: catch_ref + // TODO: catch_all + // TODO: catch_all_ref + // @ts-expect-error /** @deprecated Use {@link ExpressionBuilder#throw_ref} instead. */ rethrow(...args) { consoleWarn("`.rethrow()` is deprecated; use `.throw_ref()` instead."); return this.throw_ref(...args); }, // @ts-expect-error diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index 9018b1a4a3e..e5a56012640 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -5,7 +5,10 @@ import { array, } from "./array.ts"; import { - control, + blocks, + breaks, + calls, + throws, } from "./control.ts"; import { f32, @@ -68,7 +71,10 @@ export function expressionBuilder(mod: Module) { */ return { ...parametric(mod), - ...control(mod), + ...blocks(mod), + ...breaks(mod), + ...calls(mod), + ...throws(mod), local: local(mod), global: global(mod), table: table(mod), From 869412f5b9ee9843d08a4e4e1bf1737420068d10 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 5 May 2026 23:52:00 -0400 Subject: [PATCH 130/247] refactor: move local instrs from classes --- ts/src/classes/expression/LocalGet.ts | 13 -------- ts/src/classes/expression/LocalSet.ts | 18 ----------- ts/src/services/expression-builder/local.ts | 34 ++++++++++++++++----- 3 files changed, 27 insertions(+), 38 deletions(-) diff --git a/ts/src/classes/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts index 5420e92abf9..ee1062b1b0e 100644 --- a/ts/src/classes/expression/LocalGet.ts +++ b/ts/src/classes/expression/LocalGet.ts @@ -4,14 +4,10 @@ import { import { ExpressionId, type ExpressionRef, - type Type, } from "../../constants.ts"; import { THIS_PTR, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -19,15 +15,6 @@ import { export class LocalGet extends Expression { - /** - * Creates a `(local.get)` for the local at the specified index. - * Note that we must specify the type here as we may not have created the local being accessed yet. - */ - static localGet(mod: Module, index: number, typ: Type): ExpressionRef { - return BinaryenObj["_BinaryenLocalGet"](mod.ptr, index, typ); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.LocalGet, expr); } diff --git a/ts/src/classes/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts index aa8ea908f83..fade41f72a0 100644 --- a/ts/src/classes/expression/LocalSet.ts +++ b/ts/src/classes/expression/LocalSet.ts @@ -4,14 +4,10 @@ import { import { ExpressionId, type ExpressionRef, - type Type, } from "../../constants.ts"; import { THIS_PTR, } from "../../utils.ts"; -import type { - Module, -} from "../module/Module.ts"; import { Expression, } from "./Expression.ts"; @@ -19,20 +15,6 @@ import { export class LocalSet extends Expression { - /** Creates a `(local.set)` for the local at the specified index. */ - static localSet(mod: Module, index: number, value: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenLocalSet"](mod.ptr, index, value); - } - - /** - * Creates a `(local.tee)` for the local at the specified index. - * Note that we must specify the type here as we may not have created the local being accessed yet. - */ - static localTee(mod: Module, index: number, value: ExpressionRef, typ: Type): ExpressionRef { - return BinaryenObj["_BinaryenLocalTee"](mod.ptr, index, value, typ); - } - - constructor(expr: ExpressionRef) { super(ExpressionId.LocalSet, expr); } diff --git a/ts/src/services/expression-builder/local.ts b/ts/src/services/expression-builder/local.ts index 011b38b3793..28ad5be0df8 100644 --- a/ts/src/services/expression-builder/local.ts +++ b/ts/src/services/expression-builder/local.ts @@ -1,18 +1,38 @@ -import * as expressions from "../../classes/expression/index.ts"; +import { + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; +import type { + ExpressionRef, + Type, +} from "../../constants.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#variable-instructions */ export function local(mod: Module) { return { - /** @inheritDoc expressions.LocalGet.localGet */ - get: expressions.LocalGet.localGet.bind(null, mod), - /** @inheritDoc expressions.LocalSet.localSet */ - set: expressions.LocalSet.localSet.bind(null, mod), - /** @inheritDoc expressions.LocalSet.localTee */ - tee: expressions.LocalSet.localTee.bind(null, mod), + /** + * Creates a `(local.get)` for the local at the specified index. + * Note that we must specify the type here as we may not have created the local being accessed yet. + */ + get: (index: number, typ: Type): ExpressionRef => ( + BinaryenObj["_BinaryenLocalGet"](mod.ptr, index, typ) + ), + + /** Creates a `(local.set)` for the local at the specified index. */ + set: (index: number, value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenLocalSet"](mod.ptr, index, value) + ), + + /** + * Creates a `(local.tee)` for the local at the specified index. + * Note that we must specify the type here as we may not have created the local being accessed yet. + */ + tee: (index: number, value: ExpressionRef, typ: Type): ExpressionRef => ( + BinaryenObj["_BinaryenLocalTee"](mod.ptr, index, value, typ) + ), } as const; } From 0b6e8df0059990352f6f11195fe32c6f0eda2727 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 6 May 2026 00:08:31 -0400 Subject: [PATCH 131/247] feat: add global instrs --- .../expression-builder/expressionBuilder.ts | 10 ++++---- ts/src/services/expression-builder/global.ts | 18 -------------- .../{local.ts => variable.ts} | 24 +++++++++++++++++++ 3 files changed, 28 insertions(+), 24 deletions(-) delete mode 100644 ts/src/services/expression-builder/global.ts rename ts/src/services/expression-builder/{local.ts => variable.ts} (59%) diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index e5a56012640..c04bd75186f 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -16,9 +16,6 @@ import { import { f64, } from "./f64.ts"; -import { - global, -} from "./global.ts"; import { i31, } from "./i31.ts"; @@ -28,9 +25,6 @@ import { import { i64, } from "./i64.ts"; -import { - local, -} from "./local.ts"; import { memory, } from "./memory.ts"; @@ -49,6 +43,10 @@ import { import { tuple, } from "./tuple.ts"; +import { + global, + local, +} from "./variable.ts"; diff --git a/ts/src/services/expression-builder/global.ts b/ts/src/services/expression-builder/global.ts deleted file mode 100644 index 9dda851c166..00000000000 --- a/ts/src/services/expression-builder/global.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { - Module, -} from "../../classes/module/Module.ts"; - - - -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; - - - -/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#variable-instructions */ -export function global(_mod: Module) { - return { - get: STUB, - set: STUB, - } as const; -} diff --git a/ts/src/services/expression-builder/local.ts b/ts/src/services/expression-builder/variable.ts similarity index 59% rename from ts/src/services/expression-builder/local.ts rename to ts/src/services/expression-builder/variable.ts index 28ad5be0df8..538ace2f13c 100644 --- a/ts/src/services/expression-builder/local.ts +++ b/ts/src/services/expression-builder/variable.ts @@ -8,6 +8,10 @@ import type { ExpressionRef, Type, } from "../../constants.ts"; +import { + preserveStack, + strToStack, +} from "../../utils.ts"; @@ -36,3 +40,23 @@ export function local(mod: Module) { ), } as const; } + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#variable-instructions */ +export function global(mod: Module) { + return { + /** + * Creates a `(global.get)` for the global with the specified name. + * Note that we must specify the type here as we may not have created the global being accessed yet. + */ + get: (name: string, typ: Type): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenGlobalGet"](mod.ptr, strToStack(name), typ)) + ), + + /** Creates a `(global.set)` for the global with the specified name. */ + set: (name: string, value: ExpressionRef): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenGlobalSet"](mod.ptr, strToStack(name), value)) + ), + } as const; +} From 9714ee30c6bb4bb40157318901c34063ede87b51 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 6 May 2026 00:17:23 -0400 Subject: [PATCH 132/247] feat: add table instrs --- ts/src/services/expression-builder/table.ts | 40 ++++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/ts/src/services/expression-builder/table.ts b/ts/src/services/expression-builder/table.ts index d7bf7c273a6..f98601b528a 100644 --- a/ts/src/services/expression-builder/table.ts +++ b/ts/src/services/expression-builder/table.ts @@ -1,21 +1,43 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; +import type { + ExpressionRef, + Type, +} from "../../constants.ts"; +import { + preserveStack, + strToStack, +} from "../../utils.ts"; + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#table-instructions */ +export function table(mod: Module) { + return { + /** Load an element in a table. */ + get: (name: string, index: number, typ: Type): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenTableGet"](mod.ptr, strToStack(name), index, typ)) + ), -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; + /** Store an element in a table. */ + set: (name: string, index: number, value: ExpressionRef): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenTableSet"](mod.ptr, strToStack(name), index, value)) + ), + /** Returns the current size of a table. */ + size: (name: string): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenTableSize"](mod.ptr, strToStack(name))) + ), + /** Grows table by a given delta and returns the previous size, or -1 if not enough space can be allocated. */ + grow: (name: string, value: ExpressionRef, delta: ExpressionRef): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenTableGrow"](mod.ptr, strToStack(name), value, delta)) + ), -/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#table-instructions */ -export function table(_mod: Module) { - return { - get: STUB, - set: STUB, - size: STUB, - grow: STUB, // TODO: fill // TODO: copy // TODO: init From 615a791d68787fce61bf420c5d05166d9122fd36 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 6 May 2026 00:53:31 -0400 Subject: [PATCH 133/247] feat: add memory instrs --- ts/src/services/expression-builder/memory.ts | 72 ++++++++++++++++---- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/ts/src/services/expression-builder/memory.ts b/ts/src/services/expression-builder/memory.ts index ea6604fbf71..ffc19599d02 100644 --- a/ts/src/services/expression-builder/memory.ts +++ b/ts/src/services/expression-builder/memory.ts @@ -1,19 +1,42 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; +import { + type ExpressionRef, + type Type, + i32, + i64, +} from "../../constants.ts"; +import { + preserveStack, + strToStack, +} from "../../utils.ts"; -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; +function atomic(mod: Module) { + function wait(typ: Type, ptr: ExpressionRef, expected: ExpressionRef, timeout: ExpressionRef, name: string): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenAtomicWait"](mod.ptr, ptr, expected, timeout, typ, strToStack(name))); + } + return { + /** @experimental */ + notify: (ptr: ExpressionRef, notifyCount: ExpressionRef, name: string): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenAtomicNotify"](mod.ptr, ptr, notifyCount, strToStack(name))) + ), + /** @experimental */ + wait32: (ptr: ExpressionRef, expected: ExpressionRef, timeout: ExpressionRef, name: string): ExpressionRef => ( + wait(i32, ptr, expected, timeout, name) + ), -function memoryAtomic(_mod: Module) { - return { - notify: STUB, - wait32: STUB, - wait64: STUB, + /** @experimental */ + wait64: (ptr: ExpressionRef, expected: ExpressionRef, timeout: ExpressionRef, name: string): ExpressionRef => ( + wait(i64, ptr, expected, timeout, name) + ), } as const; } @@ -22,12 +45,35 @@ function memoryAtomic(_mod: Module) { /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions */ export function memory(mod: Module) { return { - size: STUB, - grow: STUB, - fill: STUB, - copy: STUB, - init: STUB, + /** Returns the current size of a memory. */ + size: (name: string, memory64: boolean = false): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenMemorySize"](mod.ptr, strToStack(name), memory64)) + ), + + /** Grows memory by a given delta and returns the previous size, or -1 if not enough space can be allocated. */ + grow: (delta: ExpressionRef, name: string, memory64: boolean = false): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenMemoryGrow"](mod.ptr, delta, strToStack(name), memory64)) + ), + + /** Sets all values in a region of memory to a given byte. */ + fill: (dest: ExpressionRef, value: ExpressionRef, size: ExpressionRef, name: string): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenMemoryFill"](mod.ptr, dest, value, size, strToStack(name))) + ), + + /** + * Copies data from a source memory region to a possibly overlapping destination region in another or the same memory. + * The first index denotes the destination. + */ + copy: (dest: ExpressionRef, source: ExpressionRef, size: ExpressionRef, destMemory: string, sourceMemory: string): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenMemoryCopy"](mod.ptr, dest, source, size, strToStack(destMemory), strToStack(sourceMemory))) + ), + + /** Copies data from a passive data segment into a memory. */ + init: (segment: string, dest: ExpressionRef, offset: ExpressionRef, size: ExpressionRef, name: string): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenMemoryInit"](mod.ptr, strToStack(segment), dest, offset, size, strToStack(name))) + ), + /** @experimental */ - atomic: memoryAtomic(mod), + atomic: atomic(mod), } as const; } From f264f214bba64adcc8421fa2627eb48a104424f1 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 6 May 2026 14:20:44 -0400 Subject: [PATCH 134/247] feat: impl ref & i31 instrs --- .../expression-builder/expressionBuilder.ts | 6 +- ts/src/services/expression-builder/i31.ts | 18 ----- ts/src/services/expression-builder/ref.ts | 79 ++++++++++++++++--- 3 files changed, 70 insertions(+), 33 deletions(-) delete mode 100644 ts/src/services/expression-builder/i31.ts diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index c04bd75186f..61f06a33430 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -16,9 +16,6 @@ import { import { f64, } from "./f64.ts"; -import { - i31, -} from "./i31.ts"; import { i32, } from "./i32.ts"; @@ -32,6 +29,7 @@ import { parametric, } from "./parametric.ts"; import { + i31, ref, } from "./ref.ts"; import { @@ -80,10 +78,10 @@ export function expressionBuilder(mod: Module) { memory: memory(mod), data: {drop: STUB}, ref: ref(mod), + i31: i31(mod), tuple: tuple(mod), struct: struct(mod), array: array(mod), - i31: i31(mod), // TODO: extern // TODO: any i32: i32(mod), diff --git a/ts/src/services/expression-builder/i31.ts b/ts/src/services/expression-builder/i31.ts deleted file mode 100644 index 7c7462c0e02..00000000000 --- a/ts/src/services/expression-builder/i31.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { - Module, -} from "../../classes/module/Module.ts"; - - - -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; - - - -/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#aggregate-instructions */ -export function i31(_mod: Module) { - return { - get_s: STUB, - get_u: STUB, - } as const; -} diff --git a/ts/src/services/expression-builder/ref.ts b/ts/src/services/expression-builder/ref.ts index 18ef7bb8d02..de7f0e8fd94 100644 --- a/ts/src/services/expression-builder/ref.ts +++ b/ts/src/services/expression-builder/ref.ts @@ -1,23 +1,80 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; +import { + Operation, +} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; +import type { + ExpressionRef, + Type, +} from "../../constants.ts"; +import { + preserveStack, + strToStack, +} from "../../utils.ts"; + + + +export function ref(mod: Module) { + return { + /** Produces a reference to a given function. */ + func: (name: string, type: Type) => ( + preserveStack(() => BinaryenObj["_BinaryenRefFunc"](mod.ptr, strToStack(name), type)) + ), + + /** Produces a null reference. */ + null: (typ: Type): ExpressionRef => ( + BinaryenObj["_BinaryenRefNull"](mod.ptr, typ) + ), + /** Checks for null. */ + is_null: (value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenRefIsNull"](mod.ptr, value) + ), + /** Converts a nullible reference to a non-null one, or traps. */ + as_non_null: (value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenRefAs"](mod.ptr, Operation.RefAsNonNull, value) + ), -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; + /** Compares two references. */ + eq: (left: ExpressionRef, right: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenRefEq"](mod.ptr, left, right) + ), + /** Tests the dynamic type of a reference, and returns boolean. */ + test: (value: ExpressionRef, castType: Type): ExpressionRef => ( + BinaryenObj["_BinaryenRefTest"](mod.ptr, value, castType) + ), + /** Tests the dynamic type of a reference, and performs a downcast or traps. */ + cast: (value: ExpressionRef, castType: Type): ExpressionRef => ( + BinaryenObj["_BinaryenRefCast"](mod.ptr, value, castType) + ), -export function ref(_mod: Module) { + /** Converts type i32 to an unboxed scalar. */ + i31: (value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenRefI31"](mod.ptr, value) + ), + } as const; +} + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#aggregate-instructions */ +export function i31(mod: Module) { return { - func: STUB, - null: STUB, - is_null: STUB, - as_non_null: STUB, - eq: STUB, - test: STUB, - cast: STUB, - i31: STUB, + /** Converts an unboxed scalar to type i32, signed. */ + get_s: (value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenI31Get"](mod.ptr, value, true) + ), + + /** Converts an unboxed scalar to type i32, unsigned. */ + get_u: (value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenI31Get"](mod.ptr, value, false) + ), } as const; } From 42e77058fa47d1dcf3e7b7b79d4458ee0d0cadb2 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 6 May 2026 15:07:24 -0400 Subject: [PATCH 135/247] feat: impl tuple, struct, array instrs --- ts/src/services/expression-builder/array.ts | 122 +++++++++++++++---- ts/src/services/expression-builder/struct.ts | 54 ++++++-- ts/src/services/expression-builder/tuple.ts | 32 +++-- 3 files changed, 168 insertions(+), 40 deletions(-) diff --git a/ts/src/services/expression-builder/array.ts b/ts/src/services/expression-builder/array.ts index 02ad9f93c6d..b9727d5162c 100644 --- a/ts/src/services/expression-builder/array.ts +++ b/ts/src/services/expression-builder/array.ts @@ -1,39 +1,119 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; +import type { + ExpressionRef, + HeapType, + Type, +} from "../../constants.ts"; +import { + i32sToStack, + preserveStack, + strToStack, +} from "../../utils.ts"; + +export function array(mod: Module) { + return { + /** Allocates a new array and initializes it with the given operand (repeated). */ + new: (heapType: HeapType, size: ExpressionRef, operand: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenArrayNew"](mod.ptr, heapType, size, operand) + ), -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; + /** Allocates a new array and initializes it with a default value (repeated). */ + new_default: (heapType: HeapType, size: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenArrayNew"](mod.ptr, heapType, size, 0) + ), + /** Allocates a new array with the given operands and a statically fixed size. */ + new_fixed: (heapType: HeapType, operands: readonly ExpressionRef[]): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenArrayNewFixed"](mod.ptr, heapType, i32sToStack(operands), operands.length)) + ), + /** Allocates a new array and initializes it from a data segment. */ + new_data: (heapType: HeapType, name: string, offset: ExpressionRef, size: ExpressionRef): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenArrayNewData"](mod.ptr, heapType, strToStack(name), offset, size)) + ), + + /** Allocates a new array and initializes it from an element segment. */ + new_elem: (heapType: HeapType, name: string, offset: ExpressionRef, size: ExpressionRef): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenArrayNewElem"](mod.ptr, heapType, strToStack(name), offset, size)) + ), -export function array(_mod: Module) { - return { - new: STUB, - new_default: STUB, - new_fixed: STUB, - new_data: STUB, - new_elem: STUB, /** + * Gets an array entry with an unpacked type at an index. + * * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. */ - get: function (index: number, ref: number, type: number, deprecated_isSigned?: boolean) { + get: function (ref: number, index: number, type: number, deprecated_isSigned?: boolean) { return deprecated_isSigned === undefined - ? STUB(index, ref, type) + ? BinaryenObj["_BinaryenArrayGet"](mod.ptr, ref, index, type) : deprecated_isSigned - ? this.get_s(index, ref, type) - : this.get_u(index, ref, type); + ? this.get_s(ref, index, type) + : this.get_u(ref, index, type); }, - get_s: STUB, - get_u: STUB, - set: STUB, - len: STUB, - fill: STUB, - copy: STUB, - init_data: STUB, - init_elem: STUB, + + /** Gets an array entry with a signed packed type at an index. */ + get_s: (ref: ExpressionRef, index: ExpressionRef, type: Type): ExpressionRef => ( + BinaryenObj["_BinaryenArrayGet"](mod.ptr, ref, index, type, true) + ), + + /** Gets an array entry with an unsigned packed type at an index. */ + get_u: (ref: ExpressionRef, index: ExpressionRef, type: Type): ExpressionRef => ( + BinaryenObj["_BinaryenArrayGet"](mod.ptr, ref, index, type, false) + ), + + /** Sets an array entry at an index. */ + set: (ref: ExpressionRef, index: ExpressionRef, value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenArraySet"](mod.ptr, ref, index, value) + ), + + /** Produces the length of an array. */ + len: (ref: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenArrayLen"](mod.ptr, ref) + ), + + /** Fills a specified slice of an array with the given value. */ + fill: (ref: ExpressionRef, index: ExpressionRef, value: ExpressionRef, size: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenArrayFill"](mod.ptr, ref, index, value, size) + ), + + /** Copies elements to a specified slice of an array from a given array. */ + copy: ( + destRef: ExpressionRef, + destIndex: ExpressionRef, + srcRef: ExpressionRef, + srcIndex: ExpressionRef, + length: ExpressionRef, + ): ExpressionRef => ( + BinaryenObj["_BinaryenArrayCopy"](mod.ptr, destRef, destIndex, srcRef, srcIndex, length) + ), + + /** Copies elements to a specified slice of an array from a given data segment. */ + init_data: ( + name: string, + ref: ExpressionRef, + index: ExpressionRef, + offset: ExpressionRef, + size: ExpressionRef, + ): ExpressionRef => ( + BinaryenObj["_BinaryenArrayInitData"](mod.ptr, strToStack(name), ref, index, offset, size) + ), + + /** Copies elements to a specified slice of an array from a given element segment. */ + init_elem: ( + name: string, + ref: ExpressionRef, + index: ExpressionRef, + offset: ExpressionRef, + size: ExpressionRef, + ): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenArrayInitElem"](mod.ptr, strToStack(name), ref, index, offset, size)) + ), } as const; } diff --git a/ts/src/services/expression-builder/struct.ts b/ts/src/services/expression-builder/struct.ts index 5a645d6cc0a..1caf3287ba3 100644 --- a/ts/src/services/expression-builder/struct.ts +++ b/ts/src/services/expression-builder/struct.ts @@ -1,31 +1,63 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; +import type { + ExpressionRef, + HeapType, + Type, +} from "../../constants.ts"; +import { + i32sToStack, + preserveStack, +} from "../../utils.ts"; -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; - +export function struct(mod: Module) { + return { + /** + * Allocates a new struct and initializes it with the given operands. + * Passing in an empty array for `operands` returns `(struct.new_default)`. + */ + new: (operands: readonly ExpressionRef[], heapType: HeapType): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenStructNew"](mod.ptr, i32sToStack(operands), operands.length, heapType)) + ), + /** Allocate a new struct and initializes it with default values. */ + new_default: (heapType: HeapType): ExpressionRef => ( + BinaryenObj["_BinaryenStructNew"](mod.ptr, 0, 0, heapType) + ), -export function struct(_mod: Module) { - return { - new: STUB, - new_default: STUB, /** + * Gets a struct entry with an unpacked type at an index. + * * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. */ get: function (index: number, ref: number, type: number, deprecated_isSigned?: boolean) { return deprecated_isSigned === undefined - ? STUB(index, ref, type) + ? BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type) : deprecated_isSigned ? this.get_s(index, ref, type) : this.get_u(index, ref, type); }, - get_s: STUB, - get_u: STUB, - set: STUB, + + /** Gets a struct entry with a signed packed type at an index. */ + get_s: (index: number, ref: ExpressionRef, type: Type): ExpressionRef => ( + BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type, true) + ), + + /** Gets a struct entry with an unsigned packed type at an index. */ + get_u: (index: number, ref: ExpressionRef, type: Type): ExpressionRef => ( + BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type, false) + ), + + /** Sets a struct entry at an index. */ + set: (index: number, ref: ExpressionRef, value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenStructSet"](mod.ptr, index, ref, value) + ), } as const; } diff --git a/ts/src/services/expression-builder/tuple.ts b/ts/src/services/expression-builder/tuple.ts index 9a0ecb749db..e0979592420 100644 --- a/ts/src/services/expression-builder/tuple.ts +++ b/ts/src/services/expression-builder/tuple.ts @@ -1,17 +1,33 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; +import type { + ExpressionRef, +} from "../../constants.ts"; +import { + i32sToStack, + preserveStack, +} from "../../utils.ts"; -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; - - - -export function tuple(_mod: Module) { +export function tuple(mod: Module) { return { - make: STUB, - extract: STUB, + /** + * A Binaryen-specific operation that combines values into a virtual tuple. + * A virtual tuple is simply a set of locals treated together as one unit, + * not an actual object stored in the heap. + */ + make: (elements: readonly ExpressionRef[]): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenTupleMake"](mod.ptr, i32sToStack(elements), elements.length)) + ), + + /** Extracts a value from a Binaryen virtual tuple. */ + extract: (tupl: ExpressionRef, index: number): ExpressionRef => ( + BinaryenObj["_BinaryenTupleExtract"](mod.ptr, tupl, index) + ), } as const; } From 69a2e7c16eea6240051c969a474ebd96388818e4 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 6 May 2026 15:12:10 -0400 Subject: [PATCH 136/247] refactor: reorganize reference & aggregate instr files --- .../{array.ts => aggregate.ts} | 72 ++++++++++++++++++- .../expression-builder/expressionBuilder.ts | 16 ++--- .../{ref.ts => reference.ts} | 1 + ts/src/services/expression-builder/struct.ts | 63 ---------------- ts/src/services/expression-builder/tuple.ts | 33 --------- 5 files changed, 78 insertions(+), 107 deletions(-) rename ts/src/services/expression-builder/{array.ts => aggregate.ts} (62%) rename ts/src/services/expression-builder/{ref.ts => reference.ts} (95%) delete mode 100644 ts/src/services/expression-builder/struct.ts delete mode 100644 ts/src/services/expression-builder/tuple.ts diff --git a/ts/src/services/expression-builder/array.ts b/ts/src/services/expression-builder/aggregate.ts similarity index 62% rename from ts/src/services/expression-builder/array.ts rename to ts/src/services/expression-builder/aggregate.ts index b9727d5162c..dc44e2f6006 100644 --- a/ts/src/services/expression-builder/array.ts +++ b/ts/src/services/expression-builder/aggregate.ts @@ -5,8 +5,8 @@ import type { Module, } from "../../classes/module/Module.ts"; import type { - ExpressionRef, HeapType, + ExpressionRef, Type, } from "../../constants.ts"; import { @@ -17,6 +17,76 @@ import { +export function tuple(mod: Module) { + return { + /** + * A Binaryen-specific operation that combines values into a virtual tuple. + * A virtual tuple is simply a set of locals treated together as one unit, + * not an actual object stored in the heap. + */ + make: (elements: readonly ExpressionRef[]): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenTupleMake"](mod.ptr, i32sToStack(elements), elements.length)) + ), + + /** Extracts a value from a Binaryen virtual tuple. */ + extract: (tupl: ExpressionRef, index: number): ExpressionRef => ( + BinaryenObj["_BinaryenTupleExtract"](mod.ptr, tupl, index) + ), + } as const; +} + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#aggregate-instructions */ +export function struct(mod: Module) { + return { + /** + * Allocates a new struct and initializes it with the given operands. + * Passing in an empty array for `operands` returns `(struct.new_default)`. + */ + new: (operands: readonly ExpressionRef[], heapType: HeapType): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenStructNew"](mod.ptr, i32sToStack(operands), operands.length, heapType)) + ), + + /** Allocate a new struct and initializes it with default values. */ + new_default: (heapType: HeapType): ExpressionRef => ( + BinaryenObj["_BinaryenStructNew"](mod.ptr, 0, 0, heapType) + ), + + /** + * Gets a struct entry with an unpacked type at an index. + * + * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. + * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. + */ + get: function (index: number, ref: number, type: number, deprecated_isSigned?: boolean) { + return deprecated_isSigned === undefined + ? BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type) + : deprecated_isSigned + ? this.get_s(index, ref, type) + : this.get_u(index, ref, type); + }, + + /** Gets a struct entry with a signed packed type at an index. */ + get_s: (index: number, ref: ExpressionRef, type: Type): ExpressionRef => ( + BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type, true) + ), + + /** Gets a struct entry with an unsigned packed type at an index. */ + get_u: (index: number, ref: ExpressionRef, type: Type): ExpressionRef => ( + BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type, false) + ), + + /** Sets a struct entry at an index. */ + set: (index: number, ref: ExpressionRef, value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenStructSet"](mod.ptr, index, ref, value) + ), + } as const; +} + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#aggregate-instructions */ export function array(mod: Module) { return { /** Allocates a new array and initializes it with the given operand (repeated). */ diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index 61f06a33430..7b42ac84839 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -3,7 +3,9 @@ import type { } from "../../classes/module/Module.ts"; import { array, -} from "./array.ts"; + struct, + tuple, +} from "./aggregate.ts"; import { blocks, breaks, @@ -31,16 +33,10 @@ import { import { i31, ref, -} from "./ref.ts"; -import { - struct, -} from "./struct.ts"; +} from "./reference.ts"; import { table, } from "./table.ts"; -import { - tuple, -} from "./tuple.ts"; import { global, local, @@ -79,11 +75,11 @@ export function expressionBuilder(mod: Module) { data: {drop: STUB}, ref: ref(mod), i31: i31(mod), + // TODO: extern + // TODO: any tuple: tuple(mod), struct: struct(mod), array: array(mod), - // TODO: extern - // TODO: any i32: i32(mod), i64: i64(mod), f32: f32(mod), diff --git a/ts/src/services/expression-builder/ref.ts b/ts/src/services/expression-builder/reference.ts similarity index 95% rename from ts/src/services/expression-builder/ref.ts rename to ts/src/services/expression-builder/reference.ts index de7f0e8fd94..57f4d60e3af 100644 --- a/ts/src/services/expression-builder/ref.ts +++ b/ts/src/services/expression-builder/reference.ts @@ -18,6 +18,7 @@ import { +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#reference-instructions */ export function ref(mod: Module) { return { /** Produces a reference to a given function. */ diff --git a/ts/src/services/expression-builder/struct.ts b/ts/src/services/expression-builder/struct.ts deleted file mode 100644 index 1caf3287ba3..00000000000 --- a/ts/src/services/expression-builder/struct.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; -import type { - Module, -} from "../../classes/module/Module.ts"; -import type { - ExpressionRef, - HeapType, - Type, -} from "../../constants.ts"; -import { - i32sToStack, - preserveStack, -} from "../../utils.ts"; - - - -export function struct(mod: Module) { - return { - /** - * Allocates a new struct and initializes it with the given operands. - * Passing in an empty array for `operands` returns `(struct.new_default)`. - */ - new: (operands: readonly ExpressionRef[], heapType: HeapType): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenStructNew"](mod.ptr, i32sToStack(operands), operands.length, heapType)) - ), - - /** Allocate a new struct and initializes it with default values. */ - new_default: (heapType: HeapType): ExpressionRef => ( - BinaryenObj["_BinaryenStructNew"](mod.ptr, 0, 0, heapType) - ), - - /** - * Gets a struct entry with an unpacked type at an index. - * - * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. - * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. - */ - get: function (index: number, ref: number, type: number, deprecated_isSigned?: boolean) { - return deprecated_isSigned === undefined - ? BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type) - : deprecated_isSigned - ? this.get_s(index, ref, type) - : this.get_u(index, ref, type); - }, - - /** Gets a struct entry with a signed packed type at an index. */ - get_s: (index: number, ref: ExpressionRef, type: Type): ExpressionRef => ( - BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type, true) - ), - - /** Gets a struct entry with an unsigned packed type at an index. */ - get_u: (index: number, ref: ExpressionRef, type: Type): ExpressionRef => ( - BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type, false) - ), - - /** Sets a struct entry at an index. */ - set: (index: number, ref: ExpressionRef, value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenStructSet"](mod.ptr, index, ref, value) - ), - } as const; -} diff --git a/ts/src/services/expression-builder/tuple.ts b/ts/src/services/expression-builder/tuple.ts deleted file mode 100644 index e0979592420..00000000000 --- a/ts/src/services/expression-builder/tuple.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; -import type { - Module, -} from "../../classes/module/Module.ts"; -import type { - ExpressionRef, -} from "../../constants.ts"; -import { - i32sToStack, - preserveStack, -} from "../../utils.ts"; - - - -export function tuple(mod: Module) { - return { - /** - * A Binaryen-specific operation that combines values into a virtual tuple. - * A virtual tuple is simply a set of locals treated together as one unit, - * not an actual object stored in the heap. - */ - make: (elements: readonly ExpressionRef[]): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenTupleMake"](mod.ptr, i32sToStack(elements), elements.length)) - ), - - /** Extracts a value from a Binaryen virtual tuple. */ - extract: (tupl: ExpressionRef, index: number): ExpressionRef => ( - BinaryenObj["_BinaryenTupleExtract"](mod.ptr, tupl, index) - ), - } as const; -} From a939d84368c705f2556758459db862bdf06e1868 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 6 May 2026 23:30:50 -0400 Subject: [PATCH 137/247] build: update -pre.ts with js build --- ts/src/-pre.ts | 28 +++++++++++++++------------- ts/src/types/binaryen_js.d.ts | 22 ++++++++++++++++++++++ ts/tsconfig.json | 3 +++ 3 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 ts/src/types/binaryen_js.d.ts diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index 63a1dc87ac5..875de13f08a 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -1,20 +1,22 @@ // # Preprocess # // -// Artifacts provided by the Emscripten build. +import Binaryen from "binaryen-raw"; -/** The main object provided by Emscripten. This is what gets wrapped. */ -export declare const BinaryenObj: Readonly number>>; +/** The main object provided by Emscripten. This is what gets wrapped. It is not exposed to the consumer. */ +export const BinaryenObj = await Binaryen(); -export declare function _free(ptr: number): void; -export declare function _malloc(ptr: number): number; -export declare function stackSave(): unknown; -export declare function stackRestore(stack: unknown): unknown; -export declare function stackAlloc(length: number): number; -export declare function stringToUTF8OnStack(str: string): number; -export declare function UTF8ToString(n: number): string; -export declare function stringToAscii(text: string, buffer: number): void; -export declare function getExceptionMessage(e: number | Error): [string, string]; // https://emscripten.org/docs/porting/exceptions.html#handling-c-exceptions-from-javascript -export declare function _BinaryenSizeofAllocateAndWriteResult(): number; +export const { + _free, + _malloc, + stackSave, + stackRestore, + stackAlloc, + stringToUTF8OnStack, + UTF8ToString, + stringToAscii, + getExceptionMessage, + _BinaryenSizeofAllocateAndWriteResult, +} = BinaryenObj; diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts new file mode 100644 index 00000000000..4ff239ca9cc --- /dev/null +++ b/ts/src/types/binaryen_js.d.ts @@ -0,0 +1,22 @@ +// Artifacts provided by the Emscripten build, located at `/build/bin/binaryen_js.js`. + + + +declare module "binaryen-raw" { + interface BinaryenObjType { + _free(ptr: number): void; + _malloc(ptr: number): number; + stackSave(): unknown; + stackRestore(stack: unknown): unknown; + stackAlloc(length: number): number; + stringToUTF8OnStack(str: string): number; + UTF8ToString(n: number): string; + stringToAscii(text: string, buffer: number): void; + getExceptionMessage(e: number | Error): [string, string]; // https://emscripten.org/docs/porting/exceptions.html#handling-c-exceptions-from-javascript + _BinaryenSizeofAllocateAndWriteResult(): number; + + [key: string]: (...args: readonly (number | bigint | boolean)[]) => number; + } + + export default function Binaryen(): Promise; +} diff --git a/ts/tsconfig.json b/ts/tsconfig.json index ffcee485644..1d6f8c3075b 100644 --- a/ts/tsconfig.json +++ b/ts/tsconfig.json @@ -9,6 +9,9 @@ // Modules "module": "esnext", + "paths": { + "binaryen-raw": ["./src/types/binaryen_js.d.ts"], + }, "rewriteRelativeImportExtensions": true, "rootDir": "./src/", From 6c773f0fcbd9d0ea813224ae95a0981a6e8029e5 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 00:45:41 -0400 Subject: [PATCH 138/247] build: fix prebuild function refs --- ts/src/-pre.ts | 15 +++++++++------ ts/src/classes/TypeBuilder.ts | 2 +- ts/src/classes/expression/Const.ts | 2 +- ts/src/classes/module/DataSegment.ts | 2 +- ts/src/classes/module/Memory.ts | 2 +- ts/src/classes/module/Module.ts | 9 ++++----- ts/src/globals.ts | 4 ++-- ts/src/types/binaryen_js.d.ts | 17 ++++++++++++++--- ts/src/utils.ts | 10 ++-------- 9 files changed, 35 insertions(+), 28 deletions(-) diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index 875de13f08a..19ef41aeec9 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -11,12 +11,15 @@ export const BinaryenObj = await Binaryen(); export const { _free, _malloc, - stackSave, - stackRestore, - stackAlloc, - stringToUTF8OnStack, + HEAP8, + HEAPU8, + HEAP32, + HEAPU32, UTF8ToString, - stringToAscii, getExceptionMessage, - _BinaryenSizeofAllocateAndWriteResult, + stackAlloc, + stackRestore, + stackSave, + stringToAscii, + stringToUTF8OnStack, } = BinaryenObj; diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index 6b11d699191..50ccb469dae 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -1,5 +1,6 @@ import { BinaryenObj, + HEAPU32, stackAlloc, } from "../-pre.ts"; import type { @@ -8,7 +9,6 @@ import type { Type, } from "../constants.ts"; import { - HEAPU32, i8sToStack, i32sToStack, preserveStack, diff --git a/ts/src/classes/expression/Const.ts b/ts/src/classes/expression/Const.ts index 8d7dd13fc48..1f0084b0852 100644 --- a/ts/src/classes/expression/Const.ts +++ b/ts/src/classes/expression/Const.ts @@ -1,5 +1,6 @@ import { BinaryenObj, + HEAPU8, stackAlloc, } from "../../-pre.ts"; import { @@ -12,7 +13,6 @@ import { v128, } from "../../constants.ts"; import { - HEAPU8, THIS_PTR, preserveStack, } from "../../utils.ts"; diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index 4ddbd6a63c6..5154728ae96 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -2,13 +2,13 @@ import { _free, _malloc, BinaryenObj, + HEAP8, UTF8ToString, } from "../../-pre.ts"; import type { DataSegmentRef, } from "../../constants.ts"; import { - HEAP8, preserveStack, strToStack, } from "../../utils.ts"; diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index 384cafc9d60..741a6f81b7a 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -2,13 +2,13 @@ import { _free, _malloc, BinaryenObj, + HEAP8, UTF8ToString, } from "../../-pre.ts"; import type { ExpressionRef, } from "../../constants.ts"; import { - HEAP8, i32sToStack, preserveStack, strToStack, diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 8039283a016..8ff47b8ad5d 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -1,7 +1,8 @@ import { - _BinaryenSizeofAllocateAndWriteResult, _free, BinaryenObj, + HEAPU8, + HEAPU32, UTF8ToString, stackAlloc, } from "../../-pre.ts"; @@ -35,8 +36,6 @@ import { expressionBuilder, } from "../../services/expression-builder/expressionBuilder.ts"; import { - HEAPU8, - HEAPU32, i8sToStack, i32sToStack, preserveStack, @@ -395,7 +394,7 @@ export class Module { emitBinary(sourceMapUrl: string): {binary: Uint8Array, sourceMap: string}; emitBinary(sourceMapUrl?: string): Uint8Array | {binary: Uint8Array, sourceMap: string} { return preserveStack(() => { - const tempBuffer = stackAlloc(_BinaryenSizeofAllocateAndWriteResult()); + const tempBuffer = stackAlloc(BinaryenObj["_BinaryenSizeofAllocateAndWriteResult"]()); BinaryenObj["_BinaryenModuleAllocateAndWrite"](tempBuffer, this.ptr, strToStack(sourceMapUrl)); const binaryPtr = HEAPU32[tempBuffer >>> 2]; const binaryBytes = HEAPU32[(tempBuffer >>> 2) + 1]; @@ -424,7 +423,7 @@ export class Module { } /** - * Releases the resources held by the module once it isn't needed anymore. + * Releases the resources held by the module once it isn’t needed anymore. * @category Emission & Execution */ dispose(): void { diff --git a/ts/src/globals.ts b/ts/src/globals.ts index dfeb7b7a7e3..087c28f4555 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -6,6 +6,8 @@ import { _free, _malloc, + HEAP8, + HEAPU32, BinaryenObj, getExceptionMessage, stackAlloc, @@ -23,8 +25,6 @@ import { type Type, } from "./constants.ts"; import { - HEAP8, - HEAPU32, i32sToStack, preserveStack, } from "./utils.ts"; diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index 4ff239ca9cc..81e82910be6 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -4,17 +4,28 @@ declare module "binaryen-raw" { interface BinaryenObjType { + // https://github.com/emscripten-core/emscripten/blob/main/src/preamble.js _free(ptr: number): void; _malloc(ptr: number): number; + + // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libcore.js + HEAP8: Int8Array; + HEAPU8: Uint8Array; + HEAP32: Int32Array; + HEAPU32: Uint32Array; stackSave(): unknown; stackRestore(stack: unknown): unknown; stackAlloc(length: number): number; - stringToUTF8OnStack(str: string): number; + + // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libstrings.js UTF8ToString(n: number): string; stringToAscii(text: string, buffer: number): void; - getExceptionMessage(e: number | Error): [string, string]; // https://emscripten.org/docs/porting/exceptions.html#handling-c-exceptions-from-javascript - _BinaryenSizeofAllocateAndWriteResult(): number; + stringToUTF8OnStack(str: string): number; + + // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libexceptions.js + getExceptionMessage(e: number | Error): [string, string]; + // C-defined functions [key: string]: (...args: readonly (number | bigint | boolean)[]) => number; } diff --git a/ts/src/utils.ts b/ts/src/utils.ts index 4fddd052e5f..7be6ace2da7 100644 --- a/ts/src/utils.ts +++ b/ts/src/utils.ts @@ -4,7 +4,8 @@ import { - BinaryenObj, + HEAP8, + HEAP32, stackAlloc, stackRestore, stackSave, @@ -13,13 +14,6 @@ import { -export const HEAP8: Int8Array = BinaryenObj["HEAP8"] as any; -export const HEAPU8: Uint8Array = BinaryenObj["HEAPU8"] as any; -export const HEAP32: Int32Array = BinaryenObj["HEAP32"] as any; -export const HEAPU32: Uint32Array = BinaryenObj["HEAPU32"] as any; - - - /** Private symbol used to store the underlying C-API pointer of a wrapped object. */ export const THIS_PTR: unique symbol = Symbol(); From dadea1f3aa8be783951de6723e7b984cb0a4c3d2 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 01:56:45 -0400 Subject: [PATCH 139/247] feat: finish numerics ops --- ts/src/classes/module/Module.ts | 12 -- ts/src/services/expression-builder/f32.ts | 77 ++++++----- ts/src/services/expression-builder/f64.ts | 77 ++++++----- ts/src/services/expression-builder/i32.ts | 103 +++++++------- ts/src/services/expression-builder/i64.ts | 129 +++++++++++------- .../services/expression-builder/numerics.ts | 41 ++++++ 6 files changed, 263 insertions(+), 176 deletions(-) create mode 100644 ts/src/services/expression-builder/numerics.ts diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 8ff47b8ad5d..feb53a45439 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -85,18 +85,6 @@ declare let out: any; -/** - * The size of a single literal in memory as used in Const creation, - * which is a little different: we don’t want users to need to make - * their own Literals, as the C API handles them by value, which means - * we would leak them. Instead, Const creation is fused together with - * an intermediate stack allocation of this size to pass the value. - */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const SIZE_OF_LITERAL = BinaryenObj["_BinaryenSizeofLiteral"](); - - - export enum Feature { MVP = BinaryenObj["_BinaryenFeatureMVP"](), Atomics = BinaryenObj["_BinaryenFeatureAtomics"](), diff --git a/ts/src/services/expression-builder/f32.ts b/ts/src/services/expression-builder/f32.ts index 804048dece0..3563df38e82 100644 --- a/ts/src/services/expression-builder/f32.ts +++ b/ts/src/services/expression-builder/f32.ts @@ -1,52 +1,65 @@ import { consoleWarn, } from "../../lib.ts"; +import { + Operation, +} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; - - - -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; +import type { + ExpressionRef, +} from "../../constants.ts"; +import { + binaryFn, + constant, + unaryFn, +} from "./numerics.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ export function f32(mod: Module) { return { - const: STUB, + /** Return a static constant f32. */ + const: (value: number): ExpressionRef => ( + constant(mod, "_BinaryenLiteralFloat32", value) + ), + + const_bits: (value: number): ExpressionRef => ( + constant(mod, "_BinaryenLiteralFloat32Bits", value) + ), - abs: STUB, - neg: STUB, - sqrt: STUB, - ceil: STUB, - floor: STUB, - trunc: STUB, - nearest: STUB, + abs: unaryFn(mod, Operation.AbsFloat32), + neg: unaryFn(mod, Operation.NegFloat32), + sqrt: unaryFn(mod, Operation.SqrtFloat32), + ceil: unaryFn(mod, Operation.CeilFloat32), + floor: unaryFn(mod, Operation.FloorFloat32), + trunc: unaryFn(mod, Operation.TruncFloat32), + nearest: unaryFn(mod, Operation.NearestFloat32), - add: STUB, - sub: STUB, - mul: STUB, - div: STUB, - min: STUB, - max: STUB, - copysign: STUB, + add: binaryFn(mod, Operation.AddFloat32), + sub: binaryFn(mod, Operation.SubFloat32), + mul: binaryFn(mod, Operation.MulFloat32), + div: binaryFn(mod, Operation.DivFloat32), + min: binaryFn(mod, Operation.MinFloat32), + max: binaryFn(mod, Operation.MaxFloat32), + copysign: binaryFn(mod, Operation.CopySignFloat32), - eq: STUB, - ne: STUB, - lt: STUB, - gt: STUB, - le: STUB, - ge: STUB, + eq: binaryFn(mod, Operation.EqFloat32), + ne: binaryFn(mod, Operation.NeFloat32), + lt: binaryFn(mod, Operation.LtFloat32), + gt: binaryFn(mod, Operation.GtFloat32), + le: binaryFn(mod, Operation.LeFloat32), + ge: binaryFn(mod, Operation.GeFloat32), - convert_i32_s: STUB, - convert_i32_u: STUB, - convert_i64_s: STUB, - convert_i64_u: STUB, - reinterpret_i32: STUB, + convert_i32_s: unaryFn(mod, Operation.ConvertSInt32ToFloat32), + convert_i32_u: unaryFn(mod, Operation.ConvertUInt32ToFloat32), + convert_i64_s: unaryFn(mod, Operation.ConvertSInt64ToFloat32), + convert_i64_u: unaryFn(mod, Operation.ConvertUInt64ToFloat32), + reinterpret_i32: unaryFn(mod, Operation.ReinterpretInt32), - demote_f64: STUB, + demote_f64: unaryFn(mod, Operation.DemoteFloat64), /** @deprecated */ convert_s: { diff --git a/ts/src/services/expression-builder/f64.ts b/ts/src/services/expression-builder/f64.ts index d2f2a4b0db6..475131e77ec 100644 --- a/ts/src/services/expression-builder/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -1,52 +1,65 @@ import { consoleWarn, } from "../../lib.ts"; +import { + Operation, +} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; - - - -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; +import type { + ExpressionRef, +} from "../../constants.ts"; +import { + binaryFn, + constant, + unaryFn, +} from "./numerics.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ export function f64(mod: Module) { return { - const: STUB, + /** Return a static constant f64. */ + const: (value: number): ExpressionRef => ( + constant(mod, "_BinaryenLiteralFloat64", value) + ), + + const_bits: (value: number | bigint): ExpressionRef => ( + constant(mod, "_BinaryenLiteralFloat64Bits", BigInt(value)) + ), - abs: STUB, - neg: STUB, - sqrt: STUB, - ceil: STUB, - floor: STUB, - trunc: STUB, - nearest: STUB, + abs: unaryFn(mod, Operation.AbsFloat64), + neg: unaryFn(mod, Operation.NegFloat64), + sqrt: unaryFn(mod, Operation.SqrtFloat64), + ceil: unaryFn(mod, Operation.CeilFloat64), + floor: unaryFn(mod, Operation.FloorFloat64), + trunc: unaryFn(mod, Operation.TruncFloat64), + nearest: unaryFn(mod, Operation.NearestFloat64), - add: STUB, - sub: STUB, - mul: STUB, - div: STUB, - min: STUB, - max: STUB, - copysign: STUB, + add: binaryFn(mod, Operation.AddFloat64), + sub: binaryFn(mod, Operation.SubFloat64), + mul: binaryFn(mod, Operation.MulFloat64), + div: binaryFn(mod, Operation.DivFloat64), + min: binaryFn(mod, Operation.MinFloat64), + max: binaryFn(mod, Operation.MaxFloat64), + copysign: binaryFn(mod, Operation.CopySignFloat64), - eq: STUB, - ne: STUB, - lt: STUB, - gt: STUB, - le: STUB, - ge: STUB, + eq: binaryFn(mod, Operation.EqFloat64), + ne: binaryFn(mod, Operation.NeFloat64), + lt: binaryFn(mod, Operation.LtFloat64), + gt: binaryFn(mod, Operation.GtFloat64), + le: binaryFn(mod, Operation.LeFloat64), + ge: binaryFn(mod, Operation.GeFloat64), - convert_i32_s: STUB, - convert_i32_u: STUB, - convert_i64_s: STUB, - convert_i64_u: STUB, - reinterpret_f64: STUB, + convert_i32_s: unaryFn(mod, Operation.ConvertSInt32ToFloat64), + convert_i32_u: unaryFn(mod, Operation.ConvertUInt32ToFloat64), + convert_i64_s: unaryFn(mod, Operation.ConvertSInt64ToFloat64), + convert_i64_u: unaryFn(mod, Operation.ConvertUInt64ToFloat64), + reinterpret_f64: unaryFn(mod, Operation.ReinterpretInt64), - prmote_f32: STUB, + promote_f32: unaryFn(mod, Operation.PromoteFloat32), /** @deprecated */ convert_s: { diff --git a/ts/src/services/expression-builder/i32.ts b/ts/src/services/expression-builder/i32.ts index a1324274fb4..0bec510b35b 100644 --- a/ts/src/services/expression-builder/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -1,69 +1,78 @@ import { consoleWarn, } from "../../lib.ts"; +import { + Operation, +} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; - - - -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; +import type { + ExpressionRef, +} from "../../constants.ts"; +import { + binaryFn, + constant, + unaryFn, +} from "./numerics.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ export function i32(mod: Module) { return { - const: STUB, + /** Return a static constant i32. */ + const: (value: number): ExpressionRef => ( + constant(mod, "_BinaryenLiteralInt32", value) + ), - clz: STUB, - ctz: STUB, - popcnt: STUB, - extend8_s: STUB, - extend16_s: STUB, + clz: unaryFn(mod, Operation.ClzInt32), + ctz: unaryFn(mod, Operation.CtzInt32), + popcnt: unaryFn(mod, Operation.PopcntInt32), + extend8_s: unaryFn(mod, Operation.ExtendS8Int32), + extend16_s: unaryFn(mod, Operation.ExtendS16Int32), - add: STUB, - sub: STUB, - mul: STUB, - div_s: STUB, - div_u: STUB, - rem_s: STUB, - rem_u: STUB, + add: binaryFn(mod, Operation.AddInt32), + sub: binaryFn(mod, Operation.SubInt32), + mul: binaryFn(mod, Operation.MulInt32), + div_s: binaryFn(mod, Operation.DivSInt32), + div_u: binaryFn(mod, Operation.DivUInt32), + rem_s: binaryFn(mod, Operation.RemSInt32), + rem_u: binaryFn(mod, Operation.RemUInt32), - and: STUB, - or: STUB, - xor: STUB, - shl: STUB, - shr_s: STUB, - shr_u: STUB, - rotl: STUB, - rotr: STUB, + and: binaryFn(mod, Operation.AndInt32), + or: binaryFn(mod, Operation.OrInt32), + xor: binaryFn(mod, Operation.XorInt32), + shl: binaryFn(mod, Operation.ShlInt32), + shr_s: binaryFn(mod, Operation.ShrSInt32), + shr_u: binaryFn(mod, Operation.ShrUInt32), + rotl: binaryFn(mod, Operation.RotLInt32), + rotr: binaryFn(mod, Operation.RotRInt32), - eqz: STUB, + eqz: unaryFn(mod, Operation.EqZInt32), - eq: STUB, - ne: STUB, - lt_s: STUB, - lt_u: STUB, - gt_s: STUB, - gt_u: STUB, - le_s: STUB, - le_u: STUB, - ge_s: STUB, - ge_u: STUB, + eq: binaryFn(mod, Operation.EqInt32), + ne: binaryFn(mod, Operation.NeInt32), + lt_s: binaryFn(mod, Operation.LtSInt32), + lt_u: binaryFn(mod, Operation.LtUInt32), + gt_s: binaryFn(mod, Operation.GtSInt32), + gt_u: binaryFn(mod, Operation.GtUInt32), + le_s: binaryFn(mod, Operation.LeSInt32), + le_u: binaryFn(mod, Operation.LeUInt32), + ge_s: binaryFn(mod, Operation.GeSInt32), + ge_u: binaryFn(mod, Operation.GeUInt32), - wrap_i64: STUB, + wrap_i64: unaryFn(mod, Operation.WrapInt64), - trunc_f32_s: STUB, - trunc_f32_u: STUB, - trunc_f64_s: STUB, - trunc_f64_u: STUB, - trunc_sat_f32_s: STUB, - trunc_sat_f32_u: STUB, - trunc_sat_f64_s: STUB, - trunc_sat_f64_u: STUB, - reinterpret_f32: STUB, + trunc_f32_s: unaryFn(mod, Operation.TruncSFloat32ToInt32), + trunc_f32_u: unaryFn(mod, Operation.TruncUFloat32ToInt32), + trunc_f64_s: unaryFn(mod, Operation.TruncSFloat64ToInt32), + trunc_f64_u: unaryFn(mod, Operation.TruncUFloat64ToInt32), + trunc_sat_f32_s: unaryFn(mod, Operation.TruncSatSFloat32ToInt32), + trunc_sat_f32_u: unaryFn(mod, Operation.TruncSatUFloat32ToInt32), + trunc_sat_f64_s: unaryFn(mod, Operation.TruncSatSFloat64ToInt32), + trunc_sat_f64_u: unaryFn(mod, Operation.TruncSatUFloat64ToInt32), + reinterpret_f32: unaryFn(mod, Operation.ReinterpretFloat32), // @ts-expect-error /** @deprecated Use `.wrap_i64()` instead. */ wrap(...args) { consoleWarn("`.wrap()` is deprecated; use `.wrap_i64()` instead."); return this.wrap_i64(...args); }, diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index 297c53c178a..e82e505b364 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -1,76 +1,99 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import { consoleWarn, } from "../../lib.ts"; +import { + Operation, +} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; - - - -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; +import type { + ExpressionRef, +} from "../../constants.ts"; +import { + binaryFn, + constant, + unaryFn, +} from "./numerics.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ export function i64(mod: Module) { return { - const: STUB, + /** Return a static constant i64. */ + const: (value: number | bigint): ExpressionRef => ( + constant(mod, "_BinaryenLiteralInt64", BigInt(value)) + ), + + clz: unaryFn(mod, Operation.ClzInt64), + ctz: unaryFn(mod, Operation.CtzInt64), + popcnt: unaryFn(mod, Operation.PopcntInt64), + extend8_s: unaryFn(mod, Operation.ExtendS8Int64), + extend16_s: unaryFn(mod, Operation.ExtendS16Int64), + extend32_s: unaryFn(mod, Operation.ExtendS32Int64), + + add: binaryFn(mod, Operation.AddInt64), + sub: binaryFn(mod, Operation.SubInt64), + mul: binaryFn(mod, Operation.MulInt64), + div_s: binaryFn(mod, Operation.DivSInt64), + div_u: binaryFn(mod, Operation.DivUInt64), + rem_s: binaryFn(mod, Operation.RemSInt64), + rem_u: binaryFn(mod, Operation.RemUInt64), + + add128: (leftLow: ExpressionRef, leftHigh: ExpressionRef, rightLow: ExpressionRef, rightHigh: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenWideIntAddSub"](mod.ptr, Operation.AddInt128, leftLow, leftHigh, rightLow, rightHigh) + ), - clz: STUB, - ctz: STUB, - popcnt: STUB, - extend8_s: STUB, - extend16_s: STUB, - extend32_s: STUB, + sub128: (leftLow: ExpressionRef, leftHigh: ExpressionRef, rightLow: ExpressionRef, rightHigh: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenWideIntAddSub"](mod.ptr, Operation.SubInt128, leftLow, leftHigh, rightLow, rightHigh) + ), - add: STUB, - sub: STUB, - mul: STUB, - div_s: STUB, - div_u: STUB, - rem_s: STUB, - rem_u: STUB, + mul_wide_s: (left: ExpressionRef, right: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenWideIntMul"](mod.ptr, Operation.MulWideSInt64, left, right) + ), - add128: STUB, - sub128: STUB, - mul_wide_s: STUB, - mul_wide_u: STUB, + mul_wide_u: (left: ExpressionRef, right: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenWideIntMul"](mod.ptr, Operation.MulWideUInt64, left, right) + ), - and: STUB, - or: STUB, - xor: STUB, - shl: STUB, - shr_s: STUB, - shr_u: STUB, - rotl: STUB, - rotr: STUB, + and: binaryFn(mod, Operation.AndInt64), + or: binaryFn(mod, Operation.OrInt64), + xor: binaryFn(mod, Operation.XorInt64), + shl: binaryFn(mod, Operation.ShlInt64), + shr_s: binaryFn(mod, Operation.ShrSInt64), + shr_u: binaryFn(mod, Operation.ShrUInt64), + rotl: binaryFn(mod, Operation.RotLInt64), + rotr: binaryFn(mod, Operation.RotRInt64), - eqz: STUB, + eqz: unaryFn(mod, Operation.EqZInt64), - eq: STUB, - ne: STUB, - lt_s: STUB, - lt_u: STUB, - gt_s: STUB, - gt_u: STUB, - le_s: STUB, - le_u: STUB, - ge_s: STUB, - ge_u: STUB, + eq: binaryFn(mod, Operation.EqInt64), + ne: binaryFn(mod, Operation.NeInt64), + lt_s: binaryFn(mod, Operation.LtSInt64), + lt_u: binaryFn(mod, Operation.LtUInt64), + gt_s: binaryFn(mod, Operation.GtSInt64), + gt_u: binaryFn(mod, Operation.GtUInt64), + le_s: binaryFn(mod, Operation.LeSInt64), + le_u: binaryFn(mod, Operation.LeUInt64), + ge_s: binaryFn(mod, Operation.GeSInt64), + ge_u: binaryFn(mod, Operation.GeUInt64), - extend_i32_s: STUB, - extend_i32_u: STUB, + extend_i32_s: unaryFn(mod, Operation.ExtendSInt32), + extend_i32_u: unaryFn(mod, Operation.ExtendUInt32), - trunc_f32_s: STUB, - trunc_f32_u: STUB, - trunc_f64_s: STUB, - trunc_f64_u: STUB, - trunc_sat_f32_s: STUB, - trunc_sat_f32_u: STUB, - trunc_sat_f64_s: STUB, - trunc_sat_f64_u: STUB, - reinterpret_f64: STUB, + trunc_f32_s: unaryFn(mod, Operation.TruncSFloat32ToInt64), + trunc_f32_u: unaryFn(mod, Operation.TruncUFloat32ToInt64), + trunc_f64_s: unaryFn(mod, Operation.TruncSFloat64ToInt64), + trunc_f64_u: unaryFn(mod, Operation.TruncUFloat64ToInt64), + trunc_sat_f32_s: unaryFn(mod, Operation.TruncSatSFloat32ToInt64), + trunc_sat_f32_u: unaryFn(mod, Operation.TruncSatUFloat32ToInt64), + trunc_sat_f64_s: unaryFn(mod, Operation.TruncSatSFloat64ToInt64), + trunc_sat_f64_u: unaryFn(mod, Operation.TruncSatUFloat64ToInt64), + reinterpret_f64: unaryFn(mod, Operation.ReinterpretFloat64), // @ts-expect-error /** @deprecated Use `.extend_i32_s()` instead. */ extend_s(...args) { consoleWarn("`.extend_s()` is deprecated; use `.extend_i32_s()` instead."); return this.extend_i32_s(...args); }, diff --git a/ts/src/services/expression-builder/numerics.ts b/ts/src/services/expression-builder/numerics.ts new file mode 100644 index 00000000000..6d6a1f08314 --- /dev/null +++ b/ts/src/services/expression-builder/numerics.ts @@ -0,0 +1,41 @@ +import { + BinaryenObj, + stackAlloc, +} from "../../-pre.ts"; +import type { + Operation, +} from "../../classes/expression/Operation.ts"; +import type { + Module, +} from "../../classes/module/Module.ts"; +import type { + ExpressionRef, +} from "../../constants.ts"; +import { + preserveStack, +} from "../../utils.ts"; + + + +/** + * The size of a single literal in memory as used in Const creation, + * which is a little different: we don’t want users to need to make + * their own Literals, as the C API handles them by value, which means + * we would leak them. Instead, Const creation is fused together with + * an intermediate stack allocation of this size to pass the value. + */ +const SIZE_OF_LITERAL = BinaryenObj["_BinaryenSizeofLiteral"](); + + + +export function constant(mod: Module, binFuncName: string, value: number | bigint): ExpressionRef { + return preserveStack(() => BinaryenObj["_BinaryenConst"](mod.ptr, BinaryenObj[binFuncName](stackAlloc(SIZE_OF_LITERAL), value))); +} + +export function unaryFn(mod: Module, op: Operation): (value: ExpressionRef) => ExpressionRef { + return (value) => BinaryenObj["_BinaryenUnary"](mod.ptr, op, value); +} + +export function binaryFn(mod: Module, op: Operation): (left: ExpressionRef, right: ExpressionRef) => ExpressionRef { + return (left, right) => BinaryenObj["_BinaryenBinary"](mod.ptr, op, left, right); +} From 3a3120882103d40af69ed8b33511b8107804609d Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 02:41:57 -0400 Subject: [PATCH 140/247] feat: impl `data.drop`, todo `elem.drop` --- .../expression-builder/expressionBuilder.ts | 14 +++++--------- ts/src/services/expression-builder/memory.ts | 12 ++++++++++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index 7b42ac84839..62cb48acbc3 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -25,6 +25,7 @@ import { i64, } from "./i64.ts"; import { + data, memory, } from "./memory.ts"; import { @@ -44,11 +45,6 @@ import { -/** Placeholder. */ -const STUB = (..._args: readonly number[]): number => 0; - - - /** Methods for building expressions in a WASM module. */ export function expressionBuilder(mod: Module) { /* @@ -70,13 +66,13 @@ export function expressionBuilder(mod: Module) { local: local(mod), global: global(mod), table: table(mod), - elem: {drop: STUB}, + // TODO: elem.drop memory: memory(mod), - data: {drop: STUB}, + data: data(mod), ref: ref(mod), i31: i31(mod), - // TODO: extern - // TODO: any + // TODO: extern.convert_any + // TODO: any.convert_extern tuple: tuple(mod), struct: struct(mod), array: array(mod), diff --git a/ts/src/services/expression-builder/memory.ts b/ts/src/services/expression-builder/memory.ts index ffc19599d02..93f0352f382 100644 --- a/ts/src/services/expression-builder/memory.ts +++ b/ts/src/services/expression-builder/memory.ts @@ -77,3 +77,15 @@ export function memory(mod: Module) { atomic: atomic(mod), } as const; } + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions */ +export function data(mod: Module) { + return { + /** Prevents further use of a passive data segment. */ + drop: (segment: string): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenDataDrop"](mod.ptr, strToStack(segment))) + ), + } as const; +} From 51a22e46b155d97da2f9d87cb9cda6eb9ca2d59c Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 03:45:34 -0400 Subject: [PATCH 141/247] feat: impl numeric memory ops --- ts/docs/API-Overview.md | 3 +++ ts/src/services/expression-builder/f32.ts | 15 ++++++++--- ts/src/services/expression-builder/f64.ts | 15 ++++++++--- ts/src/services/expression-builder/i32.ts | 22 +++++++++++++--- ts/src/services/expression-builder/i64.ts | 25 ++++++++++++++++--- .../services/expression-builder/numerics.ts | 10 ++++++++ 6 files changed, 78 insertions(+), 12 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index da31cb1bbc5..c0b8abaeb24 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -207,6 +207,8 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.array.copy()` - `.array.init_data()`, `.array.init_elem()` - integers + - `.{i32,i64}.load()`, `.{i32,i64}.load8_{s,u}()`, `.{i32,i64}.load16_{s,u}()`, `.i64.load32_{s,u}()` + - `.{i32,i64}.store()`, `.{i32,i64}.store8()`, `.{i32,i64}.store16()`, `.i64.store32()` - `.{i32,i64}.const()` - `.{i31,i32}.clz()`, `.{i32,i64}.ctz()`, `.{i32,i64}.popcnt()` - `.{i32,i64}.extend8_s()`, `.{i32,i64}.extend16_s()`, `.i64.extend32_s()` @@ -223,6 +225,7 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.i32.reinterpret_f32()`, `.i64.reinterpret_f64()` - 🌱 WideInt proposal: `.add128()`, `.sub128()`, `.mul_wide_{s,u}()` - floats + - `.{f32,f64}.load()`, `.{f32,f64}.store()` - `.{f32,f64}.const()` - `.{f32,f64}.abs()`, `.{f32,f64}.neg()`, `.{f32,f64}.sqrt()`, `.{f32,f64}.ceil()`, `.{f32,f64}.floor()`, `.{f32,f64}.trunc()`, `.{f32,f64}.nearest()` - `.{f32,f64}.add()`, `.{f32,f64}.sub()`, `.{f32,f64}.mul()`, `.{f32,f64}.div()`, `.{f32,f64}.min()`, `.{f32,f64}.max()`, `.{f32,f64}.copysign()` diff --git a/ts/src/services/expression-builder/f32.ts b/ts/src/services/expression-builder/f32.ts index 3563df38e82..aea5392c2f0 100644 --- a/ts/src/services/expression-builder/f32.ts +++ b/ts/src/services/expression-builder/f32.ts @@ -7,20 +7,29 @@ import { import type { Module, } from "../../classes/module/Module.ts"; -import type { - ExpressionRef, +import { + type ExpressionRef, + f32 as f32_t, } from "../../constants.ts"; import { binaryFn, constant, + loadFn, + storeFn, unaryFn, } from "./numerics.ts"; -/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ +/** + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions + */ export function f32(mod: Module) { return { + load: loadFn(mod, f32_t, 4, true), + store: storeFn(mod, f32_t, 4), + /** Return a static constant f32. */ const: (value: number): ExpressionRef => ( constant(mod, "_BinaryenLiteralFloat32", value) diff --git a/ts/src/services/expression-builder/f64.ts b/ts/src/services/expression-builder/f64.ts index 475131e77ec..ff4c7bcacf0 100644 --- a/ts/src/services/expression-builder/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -7,20 +7,29 @@ import { import type { Module, } from "../../classes/module/Module.ts"; -import type { - ExpressionRef, +import { + type ExpressionRef, + f64 as f64_t, } from "../../constants.ts"; import { binaryFn, constant, + loadFn, + storeFn, unaryFn, } from "./numerics.ts"; -/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ +/** + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions + */ export function f64(mod: Module) { return { + load: loadFn(mod, f64_t, 8, true), + store: storeFn(mod, f64_t, 8), + /** Return a static constant f64. */ const: (value: number): ExpressionRef => ( constant(mod, "_BinaryenLiteralFloat64", value) diff --git a/ts/src/services/expression-builder/i32.ts b/ts/src/services/expression-builder/i32.ts index 0bec510b35b..42902577365 100644 --- a/ts/src/services/expression-builder/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -7,20 +7,36 @@ import { import type { Module, } from "../../classes/module/Module.ts"; -import type { - ExpressionRef, +import { + type ExpressionRef, + i32 as i32_t, } from "../../constants.ts"; import { binaryFn, constant, + loadFn, + storeFn, unaryFn, } from "./numerics.ts"; -/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ +/** + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions + */ export function i32(mod: Module) { return { + load: loadFn(mod, i32_t, 4, true), + load8_s: loadFn(mod, i32_t, 1, true), + load8_u: loadFn(mod, i32_t, 1, false), + load16_s: loadFn(mod, i32_t, 2, true), + load16_u: loadFn(mod, i32_t, 2, false), + + store: storeFn(mod, i32_t, 4), + store8: storeFn(mod, i32_t, 1), + store16: storeFn(mod, i32_t, 2), + /** Return a static constant i32. */ const: (value: number): ExpressionRef => ( constant(mod, "_BinaryenLiteralInt32", value) diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index e82e505b364..8cf752b9b65 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -10,20 +10,39 @@ import { import type { Module, } from "../../classes/module/Module.ts"; -import type { - ExpressionRef, +import { + type ExpressionRef, + i64 as i64_t, } from "../../constants.ts"; import { binaryFn, constant, + loadFn, + storeFn, unaryFn, } from "./numerics.ts"; -/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions */ +/** + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions + */ export function i64(mod: Module) { return { + load: loadFn(mod, i64_t, 8, true), + load8_s: loadFn(mod, i64_t, 1, true), + load8_u: loadFn(mod, i64_t, 1, false), + load16_s: loadFn(mod, i64_t, 2, true), + load16_u: loadFn(mod, i64_t, 2, false), + load32_s: loadFn(mod, i64_t, 4, true), + load32_u: loadFn(mod, i64_t, 4, false), + + store: storeFn(mod, i64_t, 8), + store8: storeFn(mod, i64_t, 1), + store16: storeFn(mod, i64_t, 2), + store32: storeFn(mod, i64_t, 4), + /** Return a static constant i64. */ const: (value: number | bigint): ExpressionRef => ( constant(mod, "_BinaryenLiteralInt64", BigInt(value)) diff --git a/ts/src/services/expression-builder/numerics.ts b/ts/src/services/expression-builder/numerics.ts index 6d6a1f08314..b6f9f60db64 100644 --- a/ts/src/services/expression-builder/numerics.ts +++ b/ts/src/services/expression-builder/numerics.ts @@ -10,9 +10,11 @@ import type { } from "../../classes/module/Module.ts"; import type { ExpressionRef, + Type, } from "../../constants.ts"; import { preserveStack, + strToStack, } from "../../utils.ts"; @@ -39,3 +41,11 @@ export function unaryFn(mod: Module, op: Operation): (value: ExpressionRef) => E export function binaryFn(mod: Module, op: Operation): (left: ExpressionRef, right: ExpressionRef) => ExpressionRef { return (left, right) => BinaryenObj["_BinaryenBinary"](mod.ptr, op, left, right); } + +export function loadFn(mod: Module, typ: Type, bytes: number, isSigned: boolean): (offset: number, align: number, ptr: ExpressionRef, name: string) => ExpressionRef { + return (offset, align, ptr, name) => preserveStack(() => BinaryenObj["_BinaryenLoad"](mod.ptr, bytes, isSigned, offset, align, typ, ptr, strToStack(name))); +} + +export function storeFn(mod: Module, typ: Type, bytes: number): (offset: number, align: number, ptr: ExpressionRef, value: ExpressionRef, name: string) => ExpressionRef { + return (offset, align, ptr, value, name) => preserveStack(() => BinaryenObj["_BinaryenLoad"](mod.ptr, bytes, offset, align, ptr, value, typ, strToStack(name))); +} From b2b72981ff995f226bdc6781a32f389900796c5a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 10:21:58 -0400 Subject: [PATCH 142/247] renamed: src/utils.ts -> src/-utils.ts --- ts/src/{utils.ts => -utils.ts} | 0 ts/src/classes/ExpressionRunner.ts | 8 ++++---- ts/src/classes/Relooper.ts | 8 ++++---- ts/src/classes/TypeBuilder.ts | 10 +++++----- ts/src/classes/expression/Block.ts | 10 +++++----- ts/src/classes/expression/BrOn.ts | 10 +++++----- ts/src/classes/expression/Break.ts | 10 +++++----- ts/src/classes/expression/Call.ts | 10 +++++----- ts/src/classes/expression/CallIndirect.ts | 12 ++++++------ ts/src/classes/expression/CallRef.ts | 6 +++--- ts/src/classes/expression/Const.ts | 8 ++++---- ts/src/classes/expression/Drop.ts | 6 +++--- ts/src/classes/expression/Expression.ts | 6 +++--- ts/src/classes/expression/If.ts | 6 +++--- ts/src/classes/expression/LocalGet.ts | 6 +++--- ts/src/classes/expression/LocalSet.ts | 6 +++--- ts/src/classes/expression/Loop.ts | 10 +++++----- ts/src/classes/expression/Rethrow.ts | 10 +++++----- ts/src/classes/expression/Return.ts | 6 +++--- ts/src/classes/expression/Select.ts | 6 +++--- ts/src/classes/expression/Switch.ts | 10 +++++----- ts/src/classes/expression/Throw.ts | 10 +++++----- ts/src/classes/expression/Try.ts | 10 +++++----- ts/src/classes/module/DataSegment.ts | 8 ++++---- ts/src/classes/module/ElementSegment.ts | 10 +++++----- ts/src/classes/module/Export.ts | 8 ++++---- ts/src/classes/module/Function.ts | 12 ++++++------ ts/src/classes/module/Global.ts | 8 ++++---- ts/src/classes/module/Import.ts | 8 ++++---- ts/src/classes/module/Memory.ts | 8 ++++---- ts/src/classes/module/Module.ts | 12 ++++++------ ts/src/classes/module/Table.ts | 10 +++++----- ts/src/classes/module/Tag.ts | 8 ++++---- ts/src/globals.ts | 8 ++++---- ts/src/services/SettingsService.ts | 2 +- ts/src/services/expression-builder/aggregate.ts | 10 +++++----- ts/src/services/expression-builder/control.ts | 10 +++++----- ts/src/services/expression-builder/memory.ts | 8 ++++---- ts/src/services/expression-builder/numerics.ts | 8 ++++---- ts/src/services/expression-builder/reference.ts | 8 ++++---- ts/src/services/expression-builder/table.ts | 8 ++++---- ts/src/services/expression-builder/variable.ts | 8 ++++---- 42 files changed, 173 insertions(+), 173 deletions(-) rename ts/src/{utils.ts => -utils.ts} (100%) diff --git a/ts/src/utils.ts b/ts/src/-utils.ts similarity index 100% rename from ts/src/utils.ts rename to ts/src/-utils.ts diff --git a/ts/src/classes/ExpressionRunner.ts b/ts/src/classes/ExpressionRunner.ts index 473c82bd33c..422c15362a4 100644 --- a/ts/src/classes/ExpressionRunner.ts +++ b/ts/src/classes/ExpressionRunner.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../-pre.ts"; -import type { - ExpressionRef, -} from "../constants.ts"; import { preserveStack, strToStack, -} from "../utils.ts"; +} from "../-utils.ts"; +import type { + ExpressionRef, +} from "../constants.ts"; import type { Module, } from "./module/Module.ts"; diff --git a/ts/src/classes/Relooper.ts b/ts/src/classes/Relooper.ts index 78a4a87a41c..111c01ea8ea 100644 --- a/ts/src/classes/Relooper.ts +++ b/ts/src/classes/Relooper.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../-pre.ts"; -import type { - ExpressionRef, -} from "../constants.ts"; import { i32sToStack, preserveStack, -} from "../utils.ts"; +} from "../-utils.ts"; +import type { + ExpressionRef, +} from "../constants.ts"; import type { Module, } from "./module/Module.ts"; diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index 50ccb469dae..d6ea02c82c9 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -3,16 +3,16 @@ import { HEAPU32, stackAlloc, } from "../-pre.ts"; +import { + i8sToStack, + i32sToStack, + preserveStack, +} from "../-utils.ts"; import type { HeapType, PackedType, Type, } from "../constants.ts"; -import { - i8sToStack, - i32sToStack, - preserveStack, -} from "../utils.ts"; diff --git a/ts/src/classes/expression/Block.ts b/ts/src/classes/expression/Block.ts index b39f0bf3c94..97c15da86f6 100644 --- a/ts/src/classes/expression/Block.ts +++ b/ts/src/classes/expression/Block.ts @@ -2,17 +2,17 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; import { THIS_PTR, getAllNested, preserveStack, setAllNested, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/BrOn.ts b/ts/src/classes/expression/BrOn.ts index fdc229a9824..9bfc568af56 100644 --- a/ts/src/classes/expression/BrOn.ts +++ b/ts/src/classes/expression/BrOn.ts @@ -2,16 +2,16 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, type Type, } from "../../constants.ts"; -import { - THIS_PTR, - preserveStack, - strToStack, -} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Break.ts b/ts/src/classes/expression/Break.ts index 8babad0aef6..141e6377c63 100644 --- a/ts/src/classes/expression/Break.ts +++ b/ts/src/classes/expression/Break.ts @@ -2,15 +2,15 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; import { THIS_PTR, preserveStack, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Call.ts b/ts/src/classes/expression/Call.ts index 82f00d0884b..b5517ff8ee8 100644 --- a/ts/src/classes/expression/Call.ts +++ b/ts/src/classes/expression/Call.ts @@ -2,17 +2,17 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; import { THIS_PTR, getAllNested, preserveStack, setAllNested, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/CallIndirect.ts b/ts/src/classes/expression/CallIndirect.ts index 04c1f5752b6..d04ab50cee9 100644 --- a/ts/src/classes/expression/CallIndirect.ts +++ b/ts/src/classes/expression/CallIndirect.ts @@ -2,18 +2,18 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import { - ExpressionId, - type ExpressionRef, - type Type, -} from "../../constants.ts"; import { THIS_PTR, getAllNested, preserveStack, setAllNested, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, + type Type, +} from "../../constants.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/CallRef.ts b/ts/src/classes/expression/CallRef.ts index ae5363951c2..89654372085 100644 --- a/ts/src/classes/expression/CallRef.ts +++ b/ts/src/classes/expression/CallRef.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + THIS_PTR, +} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; -import { - THIS_PTR, -} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Const.ts b/ts/src/classes/expression/Const.ts index 1f0084b0852..9f9b1937889 100644 --- a/ts/src/classes/expression/Const.ts +++ b/ts/src/classes/expression/Const.ts @@ -3,6 +3,10 @@ import { HEAPU8, stackAlloc, } from "../../-pre.ts"; +import { + THIS_PTR, + preserveStack, +} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, @@ -12,10 +16,6 @@ import { f64, v128, } from "../../constants.ts"; -import { - THIS_PTR, - preserveStack, -} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Drop.ts b/ts/src/classes/expression/Drop.ts index 17bb44a4607..3d217f44dfb 100644 --- a/ts/src/classes/expression/Drop.ts +++ b/ts/src/classes/expression/Drop.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + THIS_PTR, +} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; -import { - THIS_PTR, -} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Expression.ts b/ts/src/classes/expression/Expression.ts index d41353fa9eb..f0e2e1c0549 100644 --- a/ts/src/classes/expression/Expression.ts +++ b/ts/src/classes/expression/Expression.ts @@ -1,6 +1,9 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + THIS_PTR, +} from "../../-utils.ts"; import type { ExpressionId, ExpressionRef, @@ -10,9 +13,6 @@ import { emitText, getExpressionType, } from "../../globals.ts"; -import { - THIS_PTR, -} from "../../utils.ts"; diff --git a/ts/src/classes/expression/If.ts b/ts/src/classes/expression/If.ts index 2e827c75f16..d7a4e2daf46 100644 --- a/ts/src/classes/expression/If.ts +++ b/ts/src/classes/expression/If.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + THIS_PTR, +} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; -import { - THIS_PTR, -} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts index ee1062b1b0e..6cfa9e599ed 100644 --- a/ts/src/classes/expression/LocalGet.ts +++ b/ts/src/classes/expression/LocalGet.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + THIS_PTR, +} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; -import { - THIS_PTR, -} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts index fade41f72a0..cb5f7fd59a5 100644 --- a/ts/src/classes/expression/LocalSet.ts +++ b/ts/src/classes/expression/LocalSet.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + THIS_PTR, +} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; -import { - THIS_PTR, -} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Loop.ts b/ts/src/classes/expression/Loop.ts index c5fc6de4e7a..c2d28400e6d 100644 --- a/ts/src/classes/expression/Loop.ts +++ b/ts/src/classes/expression/Loop.ts @@ -2,15 +2,15 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; import { THIS_PTR, preserveStack, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Rethrow.ts b/ts/src/classes/expression/Rethrow.ts index 0a534bd67c9..107eed8135d 100644 --- a/ts/src/classes/expression/Rethrow.ts +++ b/ts/src/classes/expression/Rethrow.ts @@ -2,15 +2,15 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; import { THIS_PTR, preserveStack, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Return.ts b/ts/src/classes/expression/Return.ts index 727eac9749d..bb1b0b50728 100644 --- a/ts/src/classes/expression/Return.ts +++ b/ts/src/classes/expression/Return.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + THIS_PTR, +} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; -import { - THIS_PTR, -} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Select.ts b/ts/src/classes/expression/Select.ts index e83c21780af..23698f6cece 100644 --- a/ts/src/classes/expression/Select.ts +++ b/ts/src/classes/expression/Select.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + THIS_PTR, +} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, } from "../../constants.ts"; -import { - THIS_PTR, -} from "../../utils.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Switch.ts b/ts/src/classes/expression/Switch.ts index 2bfd1406878..ed4e9a775a0 100644 --- a/ts/src/classes/expression/Switch.ts +++ b/ts/src/classes/expression/Switch.ts @@ -2,17 +2,17 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; import { THIS_PTR, getAllNested, preserveStack, setAllNested, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Throw.ts b/ts/src/classes/expression/Throw.ts index d3f5ab1a3ef..4493f72649c 100644 --- a/ts/src/classes/expression/Throw.ts +++ b/ts/src/classes/expression/Throw.ts @@ -2,17 +2,17 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; import { THIS_PTR, getAllNested, preserveStack, setAllNested, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/expression/Try.ts b/ts/src/classes/expression/Try.ts index 1f10cc77c66..05e85d032f7 100644 --- a/ts/src/classes/expression/Try.ts +++ b/ts/src/classes/expression/Try.ts @@ -2,17 +2,17 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; import { THIS_PTR, getAllNested, preserveStack, strToStack, setAllNested, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index 5154728ae96..107e8a305f5 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -5,13 +5,13 @@ import { HEAP8, UTF8ToString, } from "../../-pre.ts"; -import type { - DataSegmentRef, -} from "../../constants.ts"; import { preserveStack, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import type { + DataSegmentRef, +} from "../../constants.ts"; import type { Module, } from "./Module.ts"; diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index 20ad16f00e9..e9d7d5a2e47 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -2,15 +2,15 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import type { - ExpressionRef, - ElementSegmentRef, -} from "../../constants.ts"; import { i32sToStack, preserveStack, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import type { + ExpressionRef, + ElementSegmentRef, +} from "../../constants.ts"; import type { Module, } from "./Module.ts"; diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index 86f36b38f7a..0b6cb392127 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -2,14 +2,14 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../../-utils.ts"; import type { ExportRef, ExternalKind, } from "../../constants.ts"; -import { - preserveStack, - strToStack, -} from "../../utils.ts"; import type { Module, } from "./Module.ts"; diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index 5e98f27d5e5..01efa184934 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -2,18 +2,18 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; -import type { - ExpressionRef, - FunctionRef, - Type, -} from "../../constants.ts"; import { THIS_PTR, getAllNested, i32sToStack, preserveStack, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import type { + ExpressionRef, + FunctionRef, + Type, +} from "../../constants.ts"; import type { Module, } from "./Module.ts"; diff --git a/ts/src/classes/module/Global.ts b/ts/src/classes/module/Global.ts index e93cd2f4e15..ba24de61931 100644 --- a/ts/src/classes/module/Global.ts +++ b/ts/src/classes/module/Global.ts @@ -2,15 +2,15 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../../-utils.ts"; import type { ExpressionRef, GlobalRef, Type, } from "../../constants.ts"; -import { - preserveStack, - strToStack, -} from "../../utils.ts"; import type { Module, } from "./Module.ts"; diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index 8543356dfd0..79830a34e4c 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -1,13 +1,13 @@ import { BinaryenObj, } from "../../-pre.ts"; -import type { - Type, -} from "../../constants.ts"; import { preserveStack, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import type { + Type, +} from "../../constants.ts"; import type { Module, } from "./Module.ts"; diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index 741a6f81b7a..9e3b058dc38 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -5,14 +5,14 @@ import { HEAP8, UTF8ToString, } from "../../-pre.ts"; -import type { - ExpressionRef, -} from "../../constants.ts"; import { i32sToStack, preserveStack, strToStack, -} from "../../utils.ts"; +} from "../../-utils.ts"; +import type { + ExpressionRef, +} from "../../constants.ts"; import type { Module, } from "./Module.ts"; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index feb53a45439..ec0e6c02cf9 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -6,6 +6,12 @@ import { UTF8ToString, stackAlloc, } from "../../-pre.ts"; +import { + i8sToStack, + i32sToStack, + preserveStack, + strToStack, +} from "../../-utils.ts"; import { type DataSegmentRef, type ExpressionRef, @@ -35,12 +41,6 @@ import { type ExpressionBuilder, expressionBuilder, } from "../../services/expression-builder/expressionBuilder.ts"; -import { - i8sToStack, - i32sToStack, - preserveStack, - strToStack, -} from "../../utils.ts"; import { DataSegment as DataSegment_, ModuleDataSegments, diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 6ad8e56b73a..c7119e1c6d7 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -2,6 +2,11 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../-utils.ts"; import { type ElementSegmentRef, type ExpressionRef, @@ -9,11 +14,6 @@ import { type Type, funcref, } from "../../constants.ts"; -import { - THIS_PTR, - preserveStack, - strToStack, -} from "../../utils.ts"; import type { Module, } from "./Module.ts"; diff --git a/ts/src/classes/module/Tag.ts b/ts/src/classes/module/Tag.ts index 90cbec2133e..b1a4c340e23 100644 --- a/ts/src/classes/module/Tag.ts +++ b/ts/src/classes/module/Tag.ts @@ -2,14 +2,14 @@ import { BinaryenObj, UTF8ToString, } from "../../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../../-utils.ts"; import type { TagRef, Type, } from "../../constants.ts"; -import { - preserveStack, - strToStack, -} from "../../utils.ts"; import type { Module, } from "./Module.ts"; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 087c28f4555..a0f6f270569 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -13,6 +13,10 @@ import { stackAlloc, stringToAscii, } from "./-pre.ts"; +import { + i32sToStack, + preserveStack, +} from "./-utils.ts"; import { type Feature, Module, @@ -24,10 +28,6 @@ import { type HeapType, type Type, } from "./constants.ts"; -import { - i32sToStack, - preserveStack, -} from "./utils.ts"; diff --git a/ts/src/services/SettingsService.ts b/ts/src/services/SettingsService.ts index dd7a67bffc2..c54aec9b323 100644 --- a/ts/src/services/SettingsService.ts +++ b/ts/src/services/SettingsService.ts @@ -5,7 +5,7 @@ import { import { preserveStack, strToStack, -} from "../utils.ts"; +} from "../-utils.ts"; diff --git a/ts/src/services/expression-builder/aggregate.ts b/ts/src/services/expression-builder/aggregate.ts index dc44e2f6006..e498a391a50 100644 --- a/ts/src/services/expression-builder/aggregate.ts +++ b/ts/src/services/expression-builder/aggregate.ts @@ -1,6 +1,11 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + i32sToStack, + preserveStack, + strToStack, +} from "../../-utils.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -9,11 +14,6 @@ import type { ExpressionRef, Type, } from "../../constants.ts"; -import { - i32sToStack, - preserveStack, - strToStack, -} from "../../utils.ts"; diff --git a/ts/src/services/expression-builder/control.ts b/ts/src/services/expression-builder/control.ts index 4aee6da6ffb..79b75994ef6 100644 --- a/ts/src/services/expression-builder/control.ts +++ b/ts/src/services/expression-builder/control.ts @@ -1,6 +1,11 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + i32sToStack, + preserveStack, + strToStack, +} from "../../-utils.ts"; import { consoleWarn, } from "../../lib.ts"; @@ -16,11 +21,6 @@ import { none, unreachable, } from "../../constants.ts"; -import { - i32sToStack, - preserveStack, - strToStack, -} from "../../utils.ts"; diff --git a/ts/src/services/expression-builder/memory.ts b/ts/src/services/expression-builder/memory.ts index 93f0352f382..12e6ea797ae 100644 --- a/ts/src/services/expression-builder/memory.ts +++ b/ts/src/services/expression-builder/memory.ts @@ -1,6 +1,10 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../../-utils.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -10,10 +14,6 @@ import { i32, i64, } from "../../constants.ts"; -import { - preserveStack, - strToStack, -} from "../../utils.ts"; diff --git a/ts/src/services/expression-builder/numerics.ts b/ts/src/services/expression-builder/numerics.ts index b6f9f60db64..8ae17fc586b 100644 --- a/ts/src/services/expression-builder/numerics.ts +++ b/ts/src/services/expression-builder/numerics.ts @@ -2,6 +2,10 @@ import { BinaryenObj, stackAlloc, } from "../../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../../-utils.ts"; import type { Operation, } from "../../classes/expression/Operation.ts"; @@ -12,10 +16,6 @@ import type { ExpressionRef, Type, } from "../../constants.ts"; -import { - preserveStack, - strToStack, -} from "../../utils.ts"; diff --git a/ts/src/services/expression-builder/reference.ts b/ts/src/services/expression-builder/reference.ts index 57f4d60e3af..23bba3043c4 100644 --- a/ts/src/services/expression-builder/reference.ts +++ b/ts/src/services/expression-builder/reference.ts @@ -1,6 +1,10 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../../-utils.ts"; import { Operation, } from "../../classes/expression/Operation.ts"; @@ -11,10 +15,6 @@ import type { ExpressionRef, Type, } from "../../constants.ts"; -import { - preserveStack, - strToStack, -} from "../../utils.ts"; diff --git a/ts/src/services/expression-builder/table.ts b/ts/src/services/expression-builder/table.ts index f98601b528a..3d31c21b7c9 100644 --- a/ts/src/services/expression-builder/table.ts +++ b/ts/src/services/expression-builder/table.ts @@ -1,6 +1,10 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../../-utils.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -8,10 +12,6 @@ import type { ExpressionRef, Type, } from "../../constants.ts"; -import { - preserveStack, - strToStack, -} from "../../utils.ts"; diff --git a/ts/src/services/expression-builder/variable.ts b/ts/src/services/expression-builder/variable.ts index 538ace2f13c..21dda50d737 100644 --- a/ts/src/services/expression-builder/variable.ts +++ b/ts/src/services/expression-builder/variable.ts @@ -1,6 +1,10 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../../-utils.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -8,10 +12,6 @@ import type { ExpressionRef, Type, } from "../../constants.ts"; -import { - preserveStack, - strToStack, -} from "../../utils.ts"; From 54644b3592f4a521b5161f3c591f1425ce018aee Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 10:23:00 -0400 Subject: [PATCH 143/247] renamed: src/services/expression-builder/numerics.ts -> src/services/expression-builder/-utils.ts --- ts/src/services/expression-builder/{numerics.ts => -utils.ts} | 2 +- ts/src/services/expression-builder/f32.ts | 2 +- ts/src/services/expression-builder/f64.ts | 2 +- ts/src/services/expression-builder/i32.ts | 2 +- ts/src/services/expression-builder/i64.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename ts/src/services/expression-builder/{numerics.ts => -utils.ts} (95%) diff --git a/ts/src/services/expression-builder/numerics.ts b/ts/src/services/expression-builder/-utils.ts similarity index 95% rename from ts/src/services/expression-builder/numerics.ts rename to ts/src/services/expression-builder/-utils.ts index 8ae17fc586b..f806d6d6d22 100644 --- a/ts/src/services/expression-builder/numerics.ts +++ b/ts/src/services/expression-builder/-utils.ts @@ -47,5 +47,5 @@ export function loadFn(mod: Module, typ: Type, bytes: number, isSigned: boolean) } export function storeFn(mod: Module, typ: Type, bytes: number): (offset: number, align: number, ptr: ExpressionRef, value: ExpressionRef, name: string) => ExpressionRef { - return (offset, align, ptr, value, name) => preserveStack(() => BinaryenObj["_BinaryenLoad"](mod.ptr, bytes, offset, align, ptr, value, typ, strToStack(name))); + return (offset, align, ptr, value, name) => preserveStack(() => BinaryenObj["_BinaryenStore"](mod.ptr, bytes, offset, align, ptr, value, typ, strToStack(name))); } diff --git a/ts/src/services/expression-builder/f32.ts b/ts/src/services/expression-builder/f32.ts index aea5392c2f0..ae8d020fc28 100644 --- a/ts/src/services/expression-builder/f32.ts +++ b/ts/src/services/expression-builder/f32.ts @@ -17,7 +17,7 @@ import { loadFn, storeFn, unaryFn, -} from "./numerics.ts"; +} from "./-utils.ts"; diff --git a/ts/src/services/expression-builder/f64.ts b/ts/src/services/expression-builder/f64.ts index ff4c7bcacf0..f8d15169532 100644 --- a/ts/src/services/expression-builder/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -17,7 +17,7 @@ import { loadFn, storeFn, unaryFn, -} from "./numerics.ts"; +} from "./-utils.ts"; diff --git a/ts/src/services/expression-builder/i32.ts b/ts/src/services/expression-builder/i32.ts index 42902577365..1910dcf4012 100644 --- a/ts/src/services/expression-builder/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -17,7 +17,7 @@ import { loadFn, storeFn, unaryFn, -} from "./numerics.ts"; +} from "./-utils.ts"; diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index 8cf752b9b65..cca8782434d 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -20,7 +20,7 @@ import { loadFn, storeFn, unaryFn, -} from "./numerics.ts"; +} from "./-utils.ts"; From 93160c3325837fe476f1351c308e18612b480ea1 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 10:31:04 -0400 Subject: [PATCH 144/247] renamed: src/classes/expression/Operation.ts -> src/services/expression-builder/Operation.ts --- ts/src/services/expression-builder/-utils.ts | 6 +++--- .../expression => services/expression-builder}/Operation.ts | 0 ts/src/services/expression-builder/control.ts | 6 +++--- ts/src/services/expression-builder/f32.ts | 6 +++--- ts/src/services/expression-builder/f64.ts | 6 +++--- ts/src/services/expression-builder/i32.ts | 6 +++--- ts/src/services/expression-builder/i64.ts | 6 +++--- ts/src/services/expression-builder/reference.ts | 6 +++--- 8 files changed, 21 insertions(+), 21 deletions(-) rename ts/src/{classes/expression => services/expression-builder}/Operation.ts (100%) diff --git a/ts/src/services/expression-builder/-utils.ts b/ts/src/services/expression-builder/-utils.ts index f806d6d6d22..b26f6b48dba 100644 --- a/ts/src/services/expression-builder/-utils.ts +++ b/ts/src/services/expression-builder/-utils.ts @@ -6,9 +6,6 @@ import { preserveStack, strToStack, } from "../../-utils.ts"; -import type { - Operation, -} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -16,6 +13,9 @@ import type { ExpressionRef, Type, } from "../../constants.ts"; +import type { + Operation, +} from "./Operation.ts"; diff --git a/ts/src/classes/expression/Operation.ts b/ts/src/services/expression-builder/Operation.ts similarity index 100% rename from ts/src/classes/expression/Operation.ts rename to ts/src/services/expression-builder/Operation.ts diff --git a/ts/src/services/expression-builder/control.ts b/ts/src/services/expression-builder/control.ts index 79b75994ef6..0702b03380a 100644 --- a/ts/src/services/expression-builder/control.ts +++ b/ts/src/services/expression-builder/control.ts @@ -9,9 +9,6 @@ import { import { consoleWarn, } from "../../lib.ts"; -import { - Operation, -} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -21,6 +18,9 @@ import { none, unreachable, } from "../../constants.ts"; +import { + Operation, +} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/f32.ts b/ts/src/services/expression-builder/f32.ts index ae8d020fc28..31fb3d3d1bd 100644 --- a/ts/src/services/expression-builder/f32.ts +++ b/ts/src/services/expression-builder/f32.ts @@ -1,9 +1,6 @@ import { consoleWarn, } from "../../lib.ts"; -import { - Operation, -} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -18,6 +15,9 @@ import { storeFn, unaryFn, } from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/f64.ts b/ts/src/services/expression-builder/f64.ts index f8d15169532..574686b4ec5 100644 --- a/ts/src/services/expression-builder/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -1,9 +1,6 @@ import { consoleWarn, } from "../../lib.ts"; -import { - Operation, -} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -18,6 +15,9 @@ import { storeFn, unaryFn, } from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/i32.ts b/ts/src/services/expression-builder/i32.ts index 1910dcf4012..9f554d56e4d 100644 --- a/ts/src/services/expression-builder/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -1,9 +1,6 @@ import { consoleWarn, } from "../../lib.ts"; -import { - Operation, -} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -18,6 +15,9 @@ import { storeFn, unaryFn, } from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index cca8782434d..6e42e9b648c 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -4,9 +4,6 @@ import { import { consoleWarn, } from "../../lib.ts"; -import { - Operation, -} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -21,6 +18,9 @@ import { storeFn, unaryFn, } from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/reference.ts b/ts/src/services/expression-builder/reference.ts index 23bba3043c4..ddf736f6c23 100644 --- a/ts/src/services/expression-builder/reference.ts +++ b/ts/src/services/expression-builder/reference.ts @@ -5,9 +5,6 @@ import { preserveStack, strToStack, } from "../../-utils.ts"; -import { - Operation, -} from "../../classes/expression/Operation.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -15,6 +12,9 @@ import type { ExpressionRef, Type, } from "../../constants.ts"; +import { + Operation, +} from "./Operation.ts"; From d29f0d401439f746bd96fcf82b112758175ee2a0 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 10:56:41 -0400 Subject: [PATCH 145/247] feat: add v128 memory ops --- ts/docs/API-Overview.md | 8 +++ ts/src/services/expression-builder/-utils.ts | 8 +++ .../services/expression-builder/Operation.ts | 8 +-- .../expression-builder/expressionBuilder.ts | 4 ++ ts/src/services/expression-builder/v128.ts | 49 +++++++++++++++++++ 5 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 ts/src/services/expression-builder/v128.ts diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index c0b8abaeb24..8214a7411ae 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -232,6 +232,14 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.{f32,f64}.eq()`, `.{f32,f64}.lt()`, `.{f32,f64}.gt()`, `.{f32,f64}.le()`, `.{f32,f64}.ge()` - `.{f32,f64}.convert_i32_s()`, `.{f32,f64}.convert_i32_u()`, `.{f32,f64}.convert_i64_s()`, `.{f32,f64}.convert_i64_u()` - `.f32.demote_f64()`, `.f64.promote_f32()` +- vectors + - `.v128.load()` + - `.v128.load{8x8,16x4,32x2}_{s,u}()` + - `.v128.load{8,16,32,64}_splat()` + - `.v128.load{32,64}_zero()` + - `.v128.load{8,16,32,64}_lane()` + - `.v128.store()` + - `.v128.store{8,16,32,64}_lane()` diff --git a/ts/src/services/expression-builder/-utils.ts b/ts/src/services/expression-builder/-utils.ts index b26f6b48dba..8a5c31863ca 100644 --- a/ts/src/services/expression-builder/-utils.ts +++ b/ts/src/services/expression-builder/-utils.ts @@ -49,3 +49,11 @@ export function loadFn(mod: Module, typ: Type, bytes: number, isSigned: boolean) export function storeFn(mod: Module, typ: Type, bytes: number): (offset: number, align: number, ptr: ExpressionRef, value: ExpressionRef, name: string) => ExpressionRef { return (offset, align, ptr, value, name) => preserveStack(() => BinaryenObj["_BinaryenStore"](mod.ptr, bytes, offset, align, ptr, value, typ, strToStack(name))); } + +export function simdLoadFn(mod: Module, op: Operation): (offset: number, align: number, ptr: ExpressionRef, name: string) => ExpressionRef { + return (offset, align, ptr, name) => preserveStack(() => BinaryenObj["_BinaryenSIMDLoad"](mod.ptr, op, offset, align, ptr, strToStack(name))); +} + +export function simdLoadStoreLaneFn(mod: Module, op: Operation): (offset: number, align: number, index: number, ptr: ExpressionRef, vec: ExpressionRef, name: string) => ExpressionRef { + return (offset, align, index, ptr, vec, name) => preserveStack(() => BinaryenObj["_BinaryenSIMDLoadStoreLane"](mod.ptr, op, offset, align, index, ptr, vec, strToStack(name))); +} diff --git a/ts/src/services/expression-builder/Operation.ts b/ts/src/services/expression-builder/Operation.ts index ac5403e524d..61c3e0af0d8 100644 --- a/ts/src/services/expression-builder/Operation.ts +++ b/ts/src/services/expression-builder/Operation.ts @@ -16,10 +16,6 @@ export enum Operation { BrOnCastFail = BinaryenObj["_BinaryenBrOnCastFail"](), // ### Memory Operations ### // - Load8LaneVec128 = BinaryenObj["_BinaryenLoad8LaneVec128"](), - Load16LaneVec128 = BinaryenObj["_BinaryenLoad16LaneVec128"](), - Load32LaneVec128 = BinaryenObj["_BinaryenLoad32LaneVec128"](), - Load64LaneVec128 = BinaryenObj["_BinaryenLoad64LaneVec128"](), Load8x8SVec128 = BinaryenObj["_BinaryenLoad8x8SVec128"](), Load8x8UVec128 = BinaryenObj["_BinaryenLoad8x8UVec128"](), Load16x4SVec128 = BinaryenObj["_BinaryenLoad16x4SVec128"](), @@ -32,6 +28,10 @@ export enum Operation { Load64SplatVec128 = BinaryenObj["_BinaryenLoad64SplatVec128"](), Load32ZeroVec128 = BinaryenObj["_BinaryenLoad32ZeroVec128"](), Load64ZeroVec128 = BinaryenObj["_BinaryenLoad64ZeroVec128"](), + Load8LaneVec128 = BinaryenObj["_BinaryenLoad8LaneVec128"](), + Load16LaneVec128 = BinaryenObj["_BinaryenLoad16LaneVec128"](), + Load32LaneVec128 = BinaryenObj["_BinaryenLoad32LaneVec128"](), + Load64LaneVec128 = BinaryenObj["_BinaryenLoad64LaneVec128"](), Store8LaneVec128 = BinaryenObj["_BinaryenStore8LaneVec128"](), Store16LaneVec128 = BinaryenObj["_BinaryenStore16LaneVec128"](), Store32LaneVec128 = BinaryenObj["_BinaryenStore32LaneVec128"](), diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index 62cb48acbc3..3bb68e77e07 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -38,6 +38,9 @@ import { import { table, } from "./table.ts"; +import { + v128, +} from "./v128.ts"; import { global, local, @@ -80,6 +83,7 @@ export function expressionBuilder(mod: Module) { i64: i64(mod), f32: f32(mod), f64: f64(mod), + v128: v128(mod), } as const; } diff --git a/ts/src/services/expression-builder/v128.ts b/ts/src/services/expression-builder/v128.ts new file mode 100644 index 00000000000..6e9a534fa7c --- /dev/null +++ b/ts/src/services/expression-builder/v128.ts @@ -0,0 +1,49 @@ +import type { + Module, +} from "../../classes/module/Module.ts"; +import { + v128 as v128_t, +} from "../../constants.ts"; +import { + loadFn, + simdLoadFn, + simdLoadStoreLaneFn, + storeFn, +} from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; + + + +/** + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions + * @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions + */ +export function v128(mod: Module) { + return { + load: loadFn(mod, v128_t, 16, false), + load8x8_s: simdLoadFn(mod, Operation.Load8x8SVec128), + load8x8_u: simdLoadFn(mod, Operation.Load8x8UVec128), + load16x4_s: simdLoadFn(mod, Operation.Load16x4SVec128), + load16x4_u: simdLoadFn(mod, Operation.Load16x4UVec128), + load32x2_s: simdLoadFn(mod, Operation.Load32x2SVec128), + load32x2_u: simdLoadFn(mod, Operation.Load32x2UVec128), + load8_splat: simdLoadFn(mod, Operation.Load8SplatVec128), + load16_splat: simdLoadFn(mod, Operation.Load16SplatVec128), + load32_splat: simdLoadFn(mod, Operation.Load32SplatVec128), + load64_splat: simdLoadFn(mod, Operation.Load64SplatVec128), + load32_zero: simdLoadFn(mod, Operation.Load32ZeroVec128), + load64_zero: simdLoadFn(mod, Operation.Load64ZeroVec128), + load8_lane: simdLoadStoreLaneFn(mod, Operation.Load8LaneVec128), + load16_lane: simdLoadStoreLaneFn(mod, Operation.Load16LaneVec128), + load32_lane: simdLoadStoreLaneFn(mod, Operation.Load32LaneVec128), + load64_lane: simdLoadStoreLaneFn(mod, Operation.Load64LaneVec128), + + store: storeFn(mod, v128_t, 16), + store8_lane: simdLoadStoreLaneFn(mod, Operation.Store8LaneVec128), + store16_lane: simdLoadStoreLaneFn(mod, Operation.Store16LaneVec128), + store32_lane: simdLoadStoreLaneFn(mod, Operation.Store32LaneVec128), + store64_lane: simdLoadStoreLaneFn(mod, Operation.Store64LaneVec128), + } as const; +} From a52d1aae8080eb015a24fa649d3947ba3ff31eae Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 12:32:31 -0400 Subject: [PATCH 146/247] lint: add eslintRecommended to rules --- ts/eslint.config.js | 6 ++++++ ts/src/-utils.ts | 3 ++- ts/src/classes/module/Module.ts | 1 - ts/src/globals.ts | 2 +- ts/src/types/binaryen_js.d.ts | 4 ++-- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ts/eslint.config.js b/ts/eslint.config.js index 428846ea037..5daa19ed490 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -116,6 +116,10 @@ export default [ "prefer-arrow-callback": ["error", {allowUnboundThis: false}], }, }, + { + ...tseslint.configs.eslintRecommended, // https://github.com/typescript-eslint/typescript-eslint/blob/v8.59.1/packages/eslint-plugin/src/configs/flat/eslint-recommended.ts + files: ["./{src,test}/**/*.ts"], + }, { name: "TypeScript Only", // rules that break on JS files, and rules that need TSConfig to work files: ["./{src,test}/**/*.ts"], @@ -127,6 +131,8 @@ export default [ plugins: {"@typescript-eslint": tseslint.plugin}, rules: { + "@typescript-eslint/ban-ts-comment": ["error", {"ts-expect-error": false}], + /* # Layout & Formatting */ /* ## Operator Style */ "@typescript-eslint/array-type": ["error", { diff --git a/ts/src/-utils.ts b/ts/src/-utils.ts index 7be6ace2da7..37b3a2493dd 100644 --- a/ts/src/-utils.ts +++ b/ts/src/-utils.ts @@ -25,8 +25,9 @@ export const THIS_PTR: unique symbol = Symbol(); * @returns [description] */ export function preserveStack(func: () => T): T { + let stack: number = 0; try { - var stack = stackSave(); + stack = stackSave(); return func(); } finally { stackRestore(stack); diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index ec0e6c02cf9..5395752e0db 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -520,7 +520,6 @@ export class Module { * Each class represents a component of a WASM module, * and its corresponding type is included for documentation. */ -// eslint-disable-next-line no-redeclare export namespace Module { export type Tag = Tag_; export type Global = Global_; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index a0f6f270569..8b7ac3f0a5b 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -89,7 +89,7 @@ function handleFatalError(func: () => T): T { const [_, message] = getExceptionMessage(e); if (message.startsWith("Fatal: ")) { // eslint-disable-next-line preserve-caught-error - throw new Error(message.substr(7).trim()); + throw new Error(message.slice(7).trim()); } } else { const err = e as Error; diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index 81e82910be6..93bd9815930 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -13,8 +13,8 @@ declare module "binaryen-raw" { HEAPU8: Uint8Array; HEAP32: Int32Array; HEAPU32: Uint32Array; - stackSave(): unknown; - stackRestore(stack: unknown): unknown; + stackSave(): number; + stackRestore(stack: number): number; stackAlloc(length: number): number; // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libstrings.js From 18717422281042e1288e491d97df4460d320254e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 12:34:44 -0400 Subject: [PATCH 147/247] fix: impl of `constant` util --- ts/src/services/expression-builder/-utils.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ts/src/services/expression-builder/-utils.ts b/ts/src/services/expression-builder/-utils.ts index 8a5c31863ca..2150d574bd6 100644 --- a/ts/src/services/expression-builder/-utils.ts +++ b/ts/src/services/expression-builder/-utils.ts @@ -31,7 +31,15 @@ const SIZE_OF_LITERAL = BinaryenObj["_BinaryenSizeofLiteral"](); export function constant(mod: Module, binFuncName: string, value: number | bigint): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenConst"](mod.ptr, BinaryenObj[binFuncName](stackAlloc(SIZE_OF_LITERAL), value))); + return preserveStack(() => { + // Weird C stuff happening here… + // `tempLiteral` is a pointer whose reference gets mutated by the call to `binFuncName`. + // Emscripten applies the ‘sret’ convention here, converting `BinaryenObj[binFuncName]` + // (e.g `BinaryenLiteralInt32`) to a function with 2 params. + const tempLiteral = stackAlloc(SIZE_OF_LITERAL); + BinaryenObj[binFuncName](tempLiteral, value); + return BinaryenObj["_BinaryenConst"](mod.ptr, tempLiteral); + }); } export function unaryFn(mod: Module, op: Operation): (value: ExpressionRef) => ExpressionRef { From 7af56c2cd5bbe2cf4432806d9e570555b511007a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 12:35:23 -0400 Subject: [PATCH 148/247] refactor: tighten `constant` util overloads --- ts/src/services/expression-builder/-utils.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ts/src/services/expression-builder/-utils.ts b/ts/src/services/expression-builder/-utils.ts index 2150d574bd6..fe3cab2745e 100644 --- a/ts/src/services/expression-builder/-utils.ts +++ b/ts/src/services/expression-builder/-utils.ts @@ -30,6 +30,25 @@ const SIZE_OF_LITERAL = BinaryenObj["_BinaryenSizeofLiteral"](); +export function constant( + mod: Module, + binFuncName: ( + | "_BinaryenLiteralInt32" + | "_BinaryenLiteralFloat32" + | "_BinaryenLiteralFloat64" + | "_BinaryenLiteralVec128" + | "_BinaryenLiteralFloat32Bits" + ), + value: number, +): ExpressionRef; +export function constant( + mod: Module, + binFuncName: ( + | "_BinaryenLiteralInt64" + | "_BinaryenLiteralFloat64Bits" + ), + value: bigint, +): ExpressionRef; export function constant(mod: Module, binFuncName: string, value: number | bigint): ExpressionRef { return preserveStack(() => { // Weird C stuff happening here… From f8f87b5e394415f288f9ab661e3c8cd06c11f383 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 12:49:35 -0400 Subject: [PATCH 149/247] feat: finish v128 ops --- ts/docs/API-Overview.md | 4 ++++ ts/src/services/expression-builder/v128.ts | 28 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 8214a7411ae..650df23fdb0 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -240,6 +240,10 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.v128.load{8,16,32,64}_lane()` - `.v128.store()` - `.v128.store{8,16,32,64}_lane()` + - `.v128.not()` + - `.v128.and()`, `.v128.andnot()`, `.v128.or()`, `.v128.xor()` + - `.v128.bitselect()` + - `.v128.anytrue()` diff --git a/ts/src/services/expression-builder/v128.ts b/ts/src/services/expression-builder/v128.ts index 6e9a534fa7c..c4b711d9227 100644 --- a/ts/src/services/expression-builder/v128.ts +++ b/ts/src/services/expression-builder/v128.ts @@ -1,14 +1,24 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; +import { + i8sToStack, +} from "../../-utils.ts"; import type { Module, } from "../../classes/module/Module.ts"; import { + type ExpressionRef, v128 as v128_t, } from "../../constants.ts"; import { + binaryFn, + constant, loadFn, simdLoadFn, simdLoadStoreLaneFn, storeFn, + unaryFn, } from "./-utils.ts"; import { Operation, @@ -45,5 +55,23 @@ export function v128(mod: Module) { store16_lane: simdLoadStoreLaneFn(mod, Operation.Store16LaneVec128), store32_lane: simdLoadStoreLaneFn(mod, Operation.Store32LaneVec128), store64_lane: simdLoadStoreLaneFn(mod, Operation.Store64LaneVec128), + + /** Return a static constant v128. */ + const: (i8s: readonly number[]): ExpressionRef => ( + constant(mod, "_BinaryenLiteralVec128", i8sToStack(i8s)) + ), + + not: unaryFn(mod, Operation.NotVec128), + + and: binaryFn(mod, Operation.AndVec128), + andnot: binaryFn(mod, Operation.AndNotVec128), + or: binaryFn(mod, Operation.OrVec128), + xor: binaryFn(mod, Operation.XorVec128), + + bitselect: (left: ExpressionRef, right: ExpressionRef, cond: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenSIMDTernary"](mod.ptr, Operation.BitselectVec128, left, right, cond) + ), + + anytrue: unaryFn(mod, Operation.AnyTrueVec128), } as const; } From b90be954c701df63daca31798cad795dc13acee6 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 21:47:41 -0400 Subject: [PATCH 150/247] feat: stub shape ops --- ts/docs/API-Overview.md | 51 +++++++++++++ .../services/expression-builder/Operation.ts | 10 ++- .../expression-builder/expressionBuilder.ts | 30 ++++---- ts/src/services/expression-builder/f32x4.ts | 48 +++++++++++++ ts/src/services/expression-builder/f64x2.ts | 48 +++++++++++++ ts/src/services/expression-builder/i16x8.ts | 72 +++++++++++++++++++ ts/src/services/expression-builder/i32x4.ts | 71 ++++++++++++++++++ ts/src/services/expression-builder/i64x2.ts | 48 +++++++++++++ ts/src/services/expression-builder/i8x16.ts | 60 ++++++++++++++++ 9 files changed, 423 insertions(+), 15 deletions(-) create mode 100644 ts/src/services/expression-builder/f32x4.ts create mode 100644 ts/src/services/expression-builder/f64x2.ts create mode 100644 ts/src/services/expression-builder/i16x8.ts create mode 100644 ts/src/services/expression-builder/i32x4.ts create mode 100644 ts/src/services/expression-builder/i64x2.ts create mode 100644 ts/src/services/expression-builder/i8x16.ts diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 650df23fdb0..0cbb1cddd68 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -240,10 +240,61 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.v128.load{8,16,32,64}_lane()` - `.v128.store()` - `.v128.store{8,16,32,64}_lane()` + - `.v128.const()` - `.v128.not()` - `.v128.and()`, `.v128.andnot()`, `.v128.or()`, `.v128.xor()` - `.v128.bitselect()` - `.v128.anytrue()` +- SIMD ints + - `.{i8x16,i16x8,i32x4,i64x2}.abs()`, `.{i8x16,i16x8,i32x4,i64x2}.neg()`, `.i8x16.popcnt()` + > + - `.{i8x16,i16x8,i32x4,i64x2}.add()` + - `.{i8x16,i16x8,i32x4,i64x2}.sub()` + - `.{i8x16,i16x8}.add_sat_{s,u}()` + - `.{i8x16,i16x8}.sub_sat_{s,u}()` + - `.{i16x8,i32x4,i64x2}.mul()` + - `.{i8x16,i16x8}.avgr_u()` + - `.i16x8.q15mulr_sat_s()` + - `.i16x8.relaxed_q15mulr_s()` + - `.{i8x16,i16x8,i32x4}.min{s,u}()` + - `.{i8x16,i16x8,i32x4}.max{s,u}()` + > + - `.{i8x16,i16x8,i32x4,i64x2}.relaxed_laneselect()` + - `.{i8x16,i16x8,i32x4,i64x2}.all_true()` + - `.{i8x16,i16x8,i32x4,i64x2}.eq()` + - `.{i8x16,i16x8,i32x4,i64x2}.ne()` + - `.{i8x16,i16x8,i32x4}.lt_{s,u}()`, `.i64x2.lt_s()` + - `.{i8x16,i16x8,i32x4}.gt_{s,u}()`, `.i64x2.gt_s()` + - `.{i8x16,i16x8,i32x4}.le_{s,u}()`, `.i64x2.le_s()` + - `.{i8x16,i16x8,i32x4}.ge_{s,u}()`, `.i64x2.ge_s()` + > + - `.{i8x16,i16x8,i32x4,i64x2}.shl()` + - `.{i8x16,i16x8,i32x4,i64x2}.shr{s,u}()` + - `.{i8x16,i16x8,i32x4,i64x2}.bitmask()` + - `.i8x16.swizzle()`, `.i8x16.relaxed_swizzle()` + - `.i8x16.shuffle()` + > + - `.i16x8.extadd_pairwise_i8x16_{s,u}()`, `.i32x4.extadd_pairwise_i16x8_{s,u}()` + - `.i16x8.extmul_{low,high}_i8x16_{s,u}()`, `.i32x4.extmul_{low,high}_i16x8_{s,u}()`, `.i64x2.extmul_{low,high}_i32x4_{s,u}()` + - `.i32x4.dot_i16x8_s()` + - `.i16x8.relaxed_dot_i8x16_i7x16_s()` + - `.i32x4.relaxed_dot_i8x16_i7x16_add_s()` + - `.i8x16.narrow_i16x8_{s,u}()`, `.i16x8.narrow_i32x4_{s,u}()` + > + - `.i16x8.extend_{low,high}_i8x16_{s,u}()`, `.i32x4.extend_{low,high}_i16x8_{s,u}()`, `.i64x2.extend_{low,high}_i32x4_{s,u}()` + - `.i32x4.trunc_sat_f32x4_{s,u}()`, `.i32x4.trunc_sat_f64x2_{s,u}_zero()` + - `.i32x4.relaxed_trunc_f32x4_{s,u}()`, `.i32x4.relaxed_trunc_f64x2_{s,u}_zero()` +- SIMD floats + - `.{f32x4,f64x2}.abs()`, `.{f32x4,f64x2}.neg()`, `.{f32x4,f64x2}.sqrt()`, `.{f32x4,f64x2}.ceil()`, `.{f32x4,f64x2}.floor()`, `.{f32x4,f64x2}.trunc()`, `.{f32x4,f64x2}.nearest()` + - `.{f32x4,f64x2}.add()`, `.{f32x4,f64x2}.sub()`, `.{f32x4,f64x2}.mul()`, `.{f32x4,f64x2}.div()`, `.{f32x4,f64x2}.min()`, `.{f32x4,f64x2}.max()`, `.{f32x4,f64x2}.pmin()`, `.{f32x4,f64x2}.pmax()`, `.{f32x4,f64x2}.relaxed_min()`, `.{f32x4,f64x2}.relaxed_max()` + - `.{f32x4,f64x2}.relaxed_madd()`, `.{f32x4,f64x2}.relaxed_nmadd()` + - `.{f32x4,f64x2}.eq()`, `.{f32x4,f64x2}.ne()`, `.{f32x4,f64x2}.lt()`, `.{f32x4,f64x2}.gt()`, `.{f32x4,f64x2}.le()`, `.{f32x4,f64x2}.ge()` + - `.f32x4.convert_i32x4_{s,u}()`, `.f64x2.convert_low_i32x4_{s,u}()` + - `.f32x4.demote_f64x2_zero()`, `.f64x2.promote_low_f32x4()` +- SIMD vectors + - `.{i8x16,i16x8,i32x4,i64x2,f32x4,f64x2}.splat()` + - `.{i8x16,i16x8}.extract_lane_{s,u}()`, `.{i32x4,i64x2,f32x4,f64x2}.extract_lane()` + - `.{i8x16,i16x8,i32x4,i64x2,f32x4,f64x2}.replace_lane()` diff --git a/ts/src/services/expression-builder/Operation.ts b/ts/src/services/expression-builder/Operation.ts index fee6b0fb8b0..9c0afb5a29a 100644 --- a/ts/src/services/expression-builder/Operation.ts +++ b/ts/src/services/expression-builder/Operation.ts @@ -318,6 +318,7 @@ export enum Operation { LtUVecI8x16 = BinaryenObj["_BinaryenLtUVecI8x16"](), LtUVecI16x8 = BinaryenObj["_BinaryenLtUVecI16x8"](), LtUVecI32x4 = BinaryenObj["_BinaryenLtUVecI32x4"](), + // LtUVecI64x2 // not supported; see #414 GtSVecI8x16 = BinaryenObj["_BinaryenGtSVecI8x16"](), GtSVecI16x8 = BinaryenObj["_BinaryenGtSVecI16x8"](), GtSVecI32x4 = BinaryenObj["_BinaryenGtSVecI32x4"](), @@ -325,6 +326,7 @@ export enum Operation { GtUVecI8x16 = BinaryenObj["_BinaryenGtUVecI8x16"](), GtUVecI16x8 = BinaryenObj["_BinaryenGtUVecI16x8"](), GtUVecI32x4 = BinaryenObj["_BinaryenGtUVecI32x4"](), + // GtUVecI64x2 // not supported; see #414 LeSVecI8x16 = BinaryenObj["_BinaryenLeSVecI8x16"](), LeSVecI16x8 = BinaryenObj["_BinaryenLeSVecI16x8"](), LeSVecI32x4 = BinaryenObj["_BinaryenLeSVecI32x4"](), @@ -332,6 +334,7 @@ export enum Operation { LeUVecI8x16 = BinaryenObj["_BinaryenLeUVecI8x16"](), LeUVecI16x8 = BinaryenObj["_BinaryenLeUVecI16x8"](), LeUVecI32x4 = BinaryenObj["_BinaryenLeUVecI32x4"](), + // LeUVecI64x2 // not supported; see #414 GeSVecI8x16 = BinaryenObj["_BinaryenGeSVecI8x16"](), GeSVecI16x8 = BinaryenObj["_BinaryenGeSVecI16x8"](), GeSVecI32x4 = BinaryenObj["_BinaryenGeSVecI32x4"](), @@ -339,6 +342,7 @@ export enum Operation { GeUVecI8x16 = BinaryenObj["_BinaryenGeUVecI8x16"](), GeUVecI16x8 = BinaryenObj["_BinaryenGeUVecI16x8"](), GeUVecI32x4 = BinaryenObj["_BinaryenGeUVecI32x4"](), + // GeUVecI64x2 // not supported; see #414 // #### vrelop_f #### // EqVecF32x4 = BinaryenObj["_BinaryenEqVecF32x4"](), EqVecF64x2 = BinaryenObj["_BinaryenEqVecF64x2"](), @@ -391,13 +395,13 @@ export enum Operation { ExtMulHighUVecI16x8 = BinaryenObj["_BinaryenExtMulHighUVecI16x8"](), ExtMulHighUVecI32x4 = BinaryenObj["_BinaryenExtMulHighUVecI32x4"](), ExtMulHighUVecI64x2 = BinaryenObj["_BinaryenExtMulHighUVecI64x2"](), - RelaxedDotI8x16I7x16AddSToVecI32x4 = BinaryenObj["_BinaryenRelaxedDotI8x16I7x16AddSToVecI32x4"](), - RelaxedDotI8x16I7x16SToVecI16x8 = BinaryenObj["_BinaryenRelaxedDotI8x16I7x16SToVecI16x8"](), DotSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenDotSVecI16x8ToVecI32x4"](), + RelaxedDotI8x16I7x16SToVecI16x8 = BinaryenObj["_BinaryenRelaxedDotI8x16I7x16SToVecI16x8"](), + RelaxedDotI8x16I7x16AddSToVecI32x4 = BinaryenObj["_BinaryenRelaxedDotI8x16I7x16AddSToVecI32x4"](), // #### narrow #### // NarrowSVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowSVecI16x8ToVecI8x16"](), - NarrowUVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowUVecI16x8ToVecI8x16"](), NarrowSVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowSVecI32x4ToVecI16x8"](), + NarrowUVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowUVecI16x8ToVecI8x16"](), NarrowUVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowUVecI32x4ToVecI16x8"](), // #### vcvtop #### // ExtendLowSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowSVecI8x16ToVecI16x8"](), diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index 3bb68e77e07..b5dace83f9a 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -12,18 +12,18 @@ import { calls, throws, } from "./control.ts"; -import { - f32, -} from "./f32.ts"; -import { - f64, -} from "./f64.ts"; -import { - i32, -} from "./i32.ts"; -import { - i64, -} from "./i64.ts"; +/* eslint-disable @stylistic/object-curly-newline */ +import {f32} from "./f32.ts"; +import {f32x4} from "./f32x4.ts"; +import {f64} from "./f64.ts"; +import {f64x2} from "./f64x2.ts"; +import {i8x16} from "./i8x16.ts"; +import {i16x8} from "./i16x8.ts"; +import {i32} from "./i32.ts"; +import {i32x4} from "./i32x4.ts"; +import {i64} from "./i64.ts"; +import {i64x2} from "./i64x2.ts"; +/* eslint-enable @stylistic/object-curly-newline */ import { data, memory, @@ -84,6 +84,12 @@ export function expressionBuilder(mod: Module) { f32: f32(mod), f64: f64(mod), v128: v128(mod), + i8x16: i8x16(mod), + i16x8: i16x8(mod), + i32x4: i32x4(mod), + i64x2: i64x2(mod), + f32x4: f32x4(mod), + f64x2: f64x2(mod), } as const; } diff --git a/ts/src/services/expression-builder/f32x4.ts b/ts/src/services/expression-builder/f32x4.ts new file mode 100644 index 00000000000..d6ae4fc2962 --- /dev/null +++ b/ts/src/services/expression-builder/f32x4.ts @@ -0,0 +1,48 @@ +import type { + Module, +} from "../../classes/module/Module.ts"; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ +export function f32x4(_mod: Module) { + return { + abs: null, + neg: null, + sqrt: null, + ceil: null, + floor: null, + trunc: null, + nearest: null, + + add: null, + sub: null, + mul: null, + div: null, + min: null, + max: null, + pmin: null, + pmax: null, + relaxed_min: null, + relaxed_max: null, + + relaxed_madd: null, + relaxed_nmadd: null, + + eq: null, + ne: null, + lt: null, + gt: null, + le: null, + ge: null, + + convert_i32x4_s: null, + convert_i32x4_u: null, + + demote_f64x2_zero: null, + + splat: null, + extract_lane: null, + replace_lane: null, + } as const; +} diff --git a/ts/src/services/expression-builder/f64x2.ts b/ts/src/services/expression-builder/f64x2.ts new file mode 100644 index 00000000000..828723eca1a --- /dev/null +++ b/ts/src/services/expression-builder/f64x2.ts @@ -0,0 +1,48 @@ +import type { + Module, +} from "../../classes/module/Module.ts"; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ +export function f64x2(_mod: Module) { + return { + abs: null, + neg: null, + sqrt: null, + ceil: null, + floor: null, + trunc: null, + nearest: null, + + add: null, + sub: null, + mul: null, + div: null, + min: null, + max: null, + pmin: null, + pmax: null, + relaxed_min: null, + relaxed_max: null, + + relaxed_madd: null, + relaxed_nmadd: null, + + eq: null, + ne: null, + lt: null, + gt: null, + le: null, + ge: null, + + convert_low_i32x4_s: null, + convert_low_i32x4_u: null, + + promote_low_f32x4: null, + + splat: null, + extract_lane: null, + replace_lane: null, + } as const; +} diff --git a/ts/src/services/expression-builder/i16x8.ts b/ts/src/services/expression-builder/i16x8.ts new file mode 100644 index 00000000000..46e30f50ad9 --- /dev/null +++ b/ts/src/services/expression-builder/i16x8.ts @@ -0,0 +1,72 @@ +import type { + Module, +} from "../../classes/module/Module.ts"; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ +export function i16x8(_mod: Module) { + return { + abs: null, + neg: null, + + add: null, + sub: null, + add_sat_s: null, + add_sat_u: null, + sub_sat_s: null, + sub_sat_u: null, + mul: null, + avgr_u: null, + q15mulr_sat_s: null, + relaxed_q15mulr_s: null, + min_s: null, + min_u: null, + max_s: null, + max_u: null, + + relaxed_laneselect: null, + + all_true: null, + + eq: null, + ne: null, + lt_s: null, + lt_u: null, + gt_s: null, + gt_u: null, + le_s: null, + le_u: null, + ge_s: null, + ge_u: null, + + shl: null, + shr_s: null, + shr_u: null, + + bitmask: null, + + extadd_pairwise_i8x16_s: null, + extadd_pairwise_i8x16_u: null, + + extmul_low_i8x16_s: null, + extmul_low_i8x16_u: null, + extmul_high_i8x16_s: null, + extmul_high_i8x16_u: null, + + relaxed_dot_i8x16_i7x16_s: null, + + narrow_i32x4_s: null, + narrow_i32x4_u: null, + + extend_low_i8x16_s: null, + extend_low_i8x16_u: null, + extend_high_i8x16_s: null, + extend_high_i8x16_u: null, + + splat: null, + extract_lane_s: null, + extract_lane_u: null, + replace_lane: null, + } as const; +} diff --git a/ts/src/services/expression-builder/i32x4.ts b/ts/src/services/expression-builder/i32x4.ts new file mode 100644 index 00000000000..7e7e07ff6a1 --- /dev/null +++ b/ts/src/services/expression-builder/i32x4.ts @@ -0,0 +1,71 @@ +import type { + Module, +} from "../../classes/module/Module.ts"; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ +export function i32x4(_mod: Module) { + return { + abs: null, + neg: null, + + add: null, + sub: null, + mul: null, + min_s: null, + min_u: null, + max_s: null, + max_u: null, + + relaxed_laneselect: null, + + all_true: null, + + eq: null, + ne: null, + lt_s: null, + lt_u: null, + gt_s: null, + gt_u: null, + le_s: null, + le_u: null, + ge_s: null, + ge_u: null, + + shl: null, + shr_s: null, + shr_u: null, + + bitmask: null, + + extadd_pairwise_i16x8_s: null, + extadd_pairwise_i16x8_u: null, + + extmul_low_i16x8_s: null, + extmul_low_i16x8_u: null, + extmul_high_i16x8_s: null, + extmul_high_i16x8_u: null, + + dot_i16x8_s: null, + relaxed_dot_i8x16_i7x16_add_s: null, + + extend_low_i16x8_s: null, + extend_low_i16x8_u: null, + extend_high_i16x8_s: null, + extend_high_i16x8_u: null, + + trunc_sat_f32x4_s: null, + trunc_sat_f32x4_u: null, + trunc_sat_f64x2_s_zero: null, + trunc_sat_f64x2_u_zero: null, + relaxed_trunc_f32x4_s: null, + relaxed_trunc_f32x4_u: null, + relaxed_trunc_f64x2_s_zero: null, + relaxed_trunc_f64x2_u_zero: null, + + splat: null, + extract_lane: null, + replace_lane: null, + } as const; +} diff --git a/ts/src/services/expression-builder/i64x2.ts b/ts/src/services/expression-builder/i64x2.ts new file mode 100644 index 00000000000..dcbfd679afb --- /dev/null +++ b/ts/src/services/expression-builder/i64x2.ts @@ -0,0 +1,48 @@ +import type { + Module, +} from "../../classes/module/Module.ts"; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ +export function i64x2(_mod: Module) { + return { + abs: null, + neg: null, + + add: null, + sub: null, + mul: null, + + relaxed_laneselect: null, + + all_true: null, + + eq: null, + ne: null, + lt_s: null, + gt_s: null, + le_s: null, + ge_s: null, + + shl: null, + shr_s: null, + shr_u: null, + + bitmask: null, + + extmul_low_i32x4_s: null, + extmul_low_i32x4_u: null, + extmul_high_i32x4_s: null, + extmul_high_i32x4_u: null, + + extend_low_i32x4_s: null, + extend_low_i32x4_u: null, + extend_high_i32x4_s: null, + extend_high_i32x4_u: null, + + splat: null, + extract_lane: null, + replace_lane: null, + } as const; +} diff --git a/ts/src/services/expression-builder/i8x16.ts b/ts/src/services/expression-builder/i8x16.ts new file mode 100644 index 00000000000..efeb2ee38f1 --- /dev/null +++ b/ts/src/services/expression-builder/i8x16.ts @@ -0,0 +1,60 @@ +import type { + Module, +} from "../../classes/module/Module.ts"; + + + +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ +export function i8x16(_mod: Module) { + return { + abs: null, + neg: null, + popcnt: null, + + add: null, + sub: null, + add_sat_s: null, + add_sat_u: null, + sub_sat_s: null, + sub_sat_u: null, + avgr_u: null, + min_s: null, + min_u: null, + max_s: null, + max_u: null, + + relaxed_laneselect: null, + + all_true: null, + + eq: null, + ne: null, + lt_s: null, + lt_u: null, + gt_s: null, + gt_u: null, + le_s: null, + le_u: null, + ge_s: null, + ge_u: null, + + shl: null, + shr_s: null, + shr_u: null, + + bitmask: null, + + swizzle: null, + relaxed_swizzle: null, + + shuffle: null, + + narrow_i16x8_s: null, + narrow_i16x8_u: null, + + splat: null, + extract_lane_s: null, + extract_lane_u: null, + replace_lane: null, + } as const; +} From 75028c0aa0c0043de46ca5ad8c13a0a9f36d255a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 23:22:02 -0400 Subject: [PATCH 151/247] feat: impl shape ops --- ts/src/services/expression-builder/-utils.ts | 12 ++ ts/src/services/expression-builder/f32x4.ts | 85 +++++++------ ts/src/services/expression-builder/f64x2.ts | 85 +++++++------ ts/src/services/expression-builder/i16x8.ts | 111 +++++++++-------- ts/src/services/expression-builder/i32x4.ts | 109 +++++++++-------- ts/src/services/expression-builder/i64x2.ts | 69 ++++++----- ts/src/services/expression-builder/i8x16.ts | 122 +++++++++++-------- 7 files changed, 339 insertions(+), 254 deletions(-) diff --git a/ts/src/services/expression-builder/-utils.ts b/ts/src/services/expression-builder/-utils.ts index fe3cab2745e..e94c0680588 100644 --- a/ts/src/services/expression-builder/-utils.ts +++ b/ts/src/services/expression-builder/-utils.ts @@ -84,3 +84,15 @@ export function simdLoadFn(mod: Module, op: Operation): (offset: number, align: export function simdLoadStoreLaneFn(mod: Module, op: Operation): (offset: number, align: number, index: number, ptr: ExpressionRef, vec: ExpressionRef, name: string) => ExpressionRef { return (offset, align, index, ptr, vec, name) => preserveStack(() => BinaryenObj["_BinaryenSIMDLoadStoreLane"](mod.ptr, op, offset, align, index, ptr, vec, strToStack(name))); } + +export function simdShiftFn(mod: Module, op: Operation): (vec: ExpressionRef, shift: ExpressionRef) => ExpressionRef { + return (vec, shift) => BinaryenObj["_BinaryenSIMDShift"](mod.ptr, op, vec, shift); +} + +export function simdExtractFn(mod: Module, op: Operation): (vec: ExpressionRef, index: number) => ExpressionRef { + return (vec, index) => BinaryenObj["_BinaryenSIMDExtract"](mod.ptr, op, vec, index); +} + +export function simdReplaceFn(mod: Module, op: Operation): (vec: ExpressionRef, index: number, value: ExpressionRef) => ExpressionRef { + return (vec, index, value) => BinaryenObj["_BinaryenSIMDReplace"](mod.ptr, op, vec, index, value); +} diff --git a/ts/src/services/expression-builder/f32x4.ts b/ts/src/services/expression-builder/f32x4.ts index d6ae4fc2962..7058198b3c3 100644 --- a/ts/src/services/expression-builder/f32x4.ts +++ b/ts/src/services/expression-builder/f32x4.ts @@ -1,48 +1,57 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + binaryFn, + simdExtractFn, + simdReplaceFn, + unaryFn, +} from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ -export function f32x4(_mod: Module) { +export function f32x4(mod: Module) { return { - abs: null, - neg: null, - sqrt: null, - ceil: null, - floor: null, - trunc: null, - nearest: null, - - add: null, - sub: null, - mul: null, - div: null, - min: null, - max: null, - pmin: null, - pmax: null, - relaxed_min: null, - relaxed_max: null, - - relaxed_madd: null, - relaxed_nmadd: null, - - eq: null, - ne: null, - lt: null, - gt: null, - le: null, - ge: null, - - convert_i32x4_s: null, - convert_i32x4_u: null, - - demote_f64x2_zero: null, - - splat: null, - extract_lane: null, - replace_lane: null, + abs: unaryFn(mod, Operation.AbsVecF32x4), + neg: unaryFn(mod, Operation.NegVecF32x4), + sqrt: unaryFn(mod, Operation.SqrtVecF32x4), + ceil: unaryFn(mod, Operation.CeilVecF32x4), + floor: unaryFn(mod, Operation.FloorVecF32x4), + trunc: unaryFn(mod, Operation.TruncVecF32x4), + nearest: unaryFn(mod, Operation.NearestVecF32x4), + + add: binaryFn(mod, Operation.AddVecF32x4), + sub: binaryFn(mod, Operation.SubVecF32x4), + mul: binaryFn(mod, Operation.MulVecF32x4), + div: binaryFn(mod, Operation.DivVecF32x4), + min: binaryFn(mod, Operation.MinVecF32x4), + max: binaryFn(mod, Operation.MaxVecF32x4), + pmin: binaryFn(mod, Operation.PMinVecF32x4), + pmax: binaryFn(mod, Operation.PMaxVecF32x4), + // TODO: relaxed_min + // TODO: relaxed_max + + // TODO: relaxed_madd + // TODO: relaxed_nmadd + + eq: binaryFn(mod, Operation.EqVecF32x4), + ne: binaryFn(mod, Operation.NeVecF32x4), + lt: binaryFn(mod, Operation.LtVecF32x4), + gt: binaryFn(mod, Operation.GtVecF32x4), + le: binaryFn(mod, Operation.LeVecF32x4), + ge: binaryFn(mod, Operation.GeVecF32x4), + + convert_i32x4_s: unaryFn(mod, Operation.ConvertSVecI32x4ToVecF32x4), + convert_i32x4_u: unaryFn(mod, Operation.ConvertUVecI32x4ToVecF32x4), + + demote_f64x2_zero: unaryFn(mod, Operation.DemoteZeroVecF64x2ToVecF32x4), + + splat: unaryFn(mod, Operation.SplatVecF32x4), + extract_lane: simdExtractFn(mod, Operation.ExtractLaneVecF32x4), + replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecF32x4), } as const; } diff --git a/ts/src/services/expression-builder/f64x2.ts b/ts/src/services/expression-builder/f64x2.ts index 828723eca1a..330f546fdd3 100644 --- a/ts/src/services/expression-builder/f64x2.ts +++ b/ts/src/services/expression-builder/f64x2.ts @@ -1,48 +1,57 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + binaryFn, + simdExtractFn, + simdReplaceFn, + unaryFn, +} from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ -export function f64x2(_mod: Module) { +export function f64x2(mod: Module) { return { - abs: null, - neg: null, - sqrt: null, - ceil: null, - floor: null, - trunc: null, - nearest: null, - - add: null, - sub: null, - mul: null, - div: null, - min: null, - max: null, - pmin: null, - pmax: null, - relaxed_min: null, - relaxed_max: null, - - relaxed_madd: null, - relaxed_nmadd: null, - - eq: null, - ne: null, - lt: null, - gt: null, - le: null, - ge: null, - - convert_low_i32x4_s: null, - convert_low_i32x4_u: null, - - promote_low_f32x4: null, - - splat: null, - extract_lane: null, - replace_lane: null, + abs: unaryFn(mod, Operation.AbsVecF64x2), + neg: unaryFn(mod, Operation.NegVecF64x2), + sqrt: unaryFn(mod, Operation.SqrtVecF64x2), + ceil: unaryFn(mod, Operation.CeilVecF64x2), + floor: unaryFn(mod, Operation.FloorVecF64x2), + trunc: unaryFn(mod, Operation.TruncVecF64x2), + nearest: unaryFn(mod, Operation.NearestVecF64x2), + + add: binaryFn(mod, Operation.AddVecF64x2), + sub: binaryFn(mod, Operation.SubVecF64x2), + mul: binaryFn(mod, Operation.MulVecF64x2), + div: binaryFn(mod, Operation.DivVecF64x2), + min: binaryFn(mod, Operation.MinVecF64x2), + max: binaryFn(mod, Operation.MaxVecF64x2), + pmin: binaryFn(mod, Operation.PMinVecF64x2), + pmax: binaryFn(mod, Operation.PMaxVecF64x2), + // TODO: relaxed_min + // TODO: relaxed_max + + // TODO: relaxed_madd + // TODO: relaxed_nmadd + + eq: binaryFn(mod, Operation.EqVecF64x2), + ne: binaryFn(mod, Operation.NeVecF64x2), + lt: binaryFn(mod, Operation.LtVecF64x2), + gt: binaryFn(mod, Operation.GtVecF64x2), + le: binaryFn(mod, Operation.LeVecF64x2), + ge: binaryFn(mod, Operation.GeVecF64x2), + + convert_low_i32x4_s: unaryFn(mod, Operation.ConvertLowSVecI32x4ToVecF64x2), + convert_low_i32x4_u: unaryFn(mod, Operation.ConvertLowUVecI32x4ToVecF64x2), + + promote_low_f32x4: unaryFn(mod, Operation.PromoteLowVecF32x4ToVecF64x2), + + splat: unaryFn(mod, Operation.SplatVecF64x2), + extract_lane: simdExtractFn(mod, Operation.ExtractLaneVecF64x2), + replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecF64x2), } as const; } diff --git a/ts/src/services/expression-builder/i16x8.ts b/ts/src/services/expression-builder/i16x8.ts index 46e30f50ad9..beb31e33dbd 100644 --- a/ts/src/services/expression-builder/i16x8.ts +++ b/ts/src/services/expression-builder/i16x8.ts @@ -1,72 +1,83 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + binaryFn, + simdExtractFn, + simdReplaceFn, + simdShiftFn, + unaryFn, +} from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ -export function i16x8(_mod: Module) { +export function i16x8(mod: Module) { return { - abs: null, - neg: null, + abs: unaryFn(mod, Operation.AbsVecI16x8), + neg: unaryFn(mod, Operation.NegVecI16x8), - add: null, - sub: null, - add_sat_s: null, - add_sat_u: null, - sub_sat_s: null, - sub_sat_u: null, - mul: null, - avgr_u: null, - q15mulr_sat_s: null, - relaxed_q15mulr_s: null, - min_s: null, - min_u: null, - max_s: null, - max_u: null, + add: binaryFn(mod, Operation.AddVecI16x8), + sub: binaryFn(mod, Operation.SubVecI16x8), + add_sat_s: binaryFn(mod, Operation.AddSatSVecI16x8), // TODO: deprecate `add_saturate_s` + add_sat_u: binaryFn(mod, Operation.AddSatUVecI16x8), // TODO: deprecate `add_saturate_u` + sub_sat_s: binaryFn(mod, Operation.SubSatSVecI16x8), // TODO: deprecate `sub_saturate_s` + sub_sat_u: binaryFn(mod, Operation.SubSatUVecI16x8), // TODO: deprecate `sub_saturate_u` + mul: binaryFn(mod, Operation.MulVecI16x8), + avgr_u: binaryFn(mod, Operation.AvgrUVecI16x8), + q15mulr_sat_s: binaryFn(mod, Operation.Q15MulrSatSVecI16x8), + // TODO: relaxed_q15mulr_s + min_s: binaryFn(mod, Operation.MinSVecI16x8), + min_u: binaryFn(mod, Operation.MinUVecI16x8), + max_s: binaryFn(mod, Operation.MaxSVecI16x8), + max_u: binaryFn(mod, Operation.MaxUVecI16x8), - relaxed_laneselect: null, + // TODO: relaxed_laneselect - all_true: null, + all_true: unaryFn(mod, Operation.AllTrueVecI16x8), - eq: null, - ne: null, - lt_s: null, - lt_u: null, - gt_s: null, - gt_u: null, - le_s: null, - le_u: null, - ge_s: null, - ge_u: null, + eq: binaryFn(mod, Operation.EqVecI16x8), + ne: binaryFn(mod, Operation.NeVecI16x8), + lt_s: binaryFn(mod, Operation.LtSVecI16x8), + lt_u: binaryFn(mod, Operation.LtUVecI16x8), + gt_s: binaryFn(mod, Operation.GtSVecI16x8), + gt_u: binaryFn(mod, Operation.GtUVecI16x8), + le_s: binaryFn(mod, Operation.LeSVecI16x8), + le_u: binaryFn(mod, Operation.LeUVecI16x8), + ge_s: binaryFn(mod, Operation.GeSVecI16x8), + ge_u: binaryFn(mod, Operation.GeUVecI16x8), - shl: null, - shr_s: null, - shr_u: null, + shl: simdShiftFn(mod, Operation.ShlVecI16x8), + shr_s: simdShiftFn(mod, Operation.ShrSVecI16x8), + shr_u: simdShiftFn(mod, Operation.ShrUVecI16x8), - bitmask: null, + bitmask: unaryFn(mod, Operation.BitmaskVecI16x8), - extadd_pairwise_i8x16_s: null, - extadd_pairwise_i8x16_u: null, + extadd_pairwise_i8x16_s: unaryFn(mod, Operation.ExtAddPairwiseSVecI8x16ToI16x8), + extadd_pairwise_i8x16_u: unaryFn(mod, Operation.ExtAddPairwiseUVecI8x16ToI16x8), - extmul_low_i8x16_s: null, - extmul_low_i8x16_u: null, - extmul_high_i8x16_s: null, - extmul_high_i8x16_u: null, + // NOTE: operation names correspond to “this” object, not instruction names + extmul_low_i8x16_s: binaryFn(mod, Operation.ExtMulLowSVecI16x8), + extmul_low_i8x16_u: binaryFn(mod, Operation.ExtMulLowUVecI16x8), + extmul_high_i8x16_s: binaryFn(mod, Operation.ExtMulHighSVecI16x8), + extmul_high_i8x16_u: binaryFn(mod, Operation.ExtMulHighUVecI16x8), - relaxed_dot_i8x16_i7x16_s: null, + // TODO: relaxed_dot_i8x16_i7x16_s - narrow_i32x4_s: null, - narrow_i32x4_u: null, + narrow_i32x4_s: binaryFn(mod, Operation.NarrowSVecI32x4ToVecI16x8), + narrow_i32x4_u: binaryFn(mod, Operation.NarrowUVecI32x4ToVecI16x8), - extend_low_i8x16_s: null, - extend_low_i8x16_u: null, - extend_high_i8x16_s: null, - extend_high_i8x16_u: null, + extend_low_i8x16_s: unaryFn(mod, Operation.ExtendLowSVecI8x16ToVecI16x8), + extend_low_i8x16_u: unaryFn(mod, Operation.ExtendLowUVecI8x16ToVecI16x8), + extend_high_i8x16_s: unaryFn(mod, Operation.ExtendHighSVecI8x16ToVecI16x8), + extend_high_i8x16_u: unaryFn(mod, Operation.ExtendHighUVecI8x16ToVecI16x8), - splat: null, - extract_lane_s: null, - extract_lane_u: null, - replace_lane: null, + splat: unaryFn(mod, Operation.SplatVecI16x8), + extract_lane_s: simdExtractFn(mod, Operation.ExtractLaneSVecI16x8), + extract_lane_u: simdExtractFn(mod, Operation.ExtractLaneUVecI16x8), + replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecI16x8), } as const; } diff --git a/ts/src/services/expression-builder/i32x4.ts b/ts/src/services/expression-builder/i32x4.ts index 7e7e07ff6a1..a0793e1d6da 100644 --- a/ts/src/services/expression-builder/i32x4.ts +++ b/ts/src/services/expression-builder/i32x4.ts @@ -1,71 +1,82 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + binaryFn, + simdExtractFn, + simdReplaceFn, + simdShiftFn, + unaryFn, +} from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ -export function i32x4(_mod: Module) { +export function i32x4(mod: Module) { return { - abs: null, - neg: null, + abs: unaryFn(mod, Operation.AbsVecI32x4), + neg: unaryFn(mod, Operation.NegVecI32x4), - add: null, - sub: null, - mul: null, - min_s: null, - min_u: null, - max_s: null, - max_u: null, + add: binaryFn(mod, Operation.AddVecI32x4), + sub: binaryFn(mod, Operation.SubVecI32x4), + mul: binaryFn(mod, Operation.MulVecI32x4), + min_s: binaryFn(mod, Operation.MinSVecI32x4), + min_u: binaryFn(mod, Operation.MinUVecI32x4), + max_s: binaryFn(mod, Operation.MaxSVecI32x4), + max_u: binaryFn(mod, Operation.MaxUVecI32x4), - relaxed_laneselect: null, + // TODO: relaxed_laneselect - all_true: null, + all_true: unaryFn(mod, Operation.AllTrueVecI32x4), - eq: null, - ne: null, - lt_s: null, - lt_u: null, - gt_s: null, - gt_u: null, - le_s: null, - le_u: null, - ge_s: null, - ge_u: null, + eq: binaryFn(mod, Operation.EqVecI32x4), + ne: binaryFn(mod, Operation.NeVecI32x4), + lt_s: binaryFn(mod, Operation.LtSVecI32x4), + lt_u: binaryFn(mod, Operation.LtUVecI32x4), + gt_s: binaryFn(mod, Operation.GtSVecI32x4), + gt_u: binaryFn(mod, Operation.GtUVecI32x4), + le_s: binaryFn(mod, Operation.LeSVecI32x4), + le_u: binaryFn(mod, Operation.LeUVecI32x4), + ge_s: binaryFn(mod, Operation.GeSVecI32x4), + ge_u: binaryFn(mod, Operation.GeUVecI32x4), - shl: null, - shr_s: null, - shr_u: null, + shl: simdShiftFn(mod, Operation.ShlVecI32x4), + shr_s: simdShiftFn(mod, Operation.ShrSVecI32x4), + shr_u: simdShiftFn(mod, Operation.ShrUVecI32x4), - bitmask: null, + bitmask: unaryFn(mod, Operation.BitmaskVecI32x4), - extadd_pairwise_i16x8_s: null, - extadd_pairwise_i16x8_u: null, + extadd_pairwise_i16x8_s: unaryFn(mod, Operation.ExtAddPairwiseSVecI16x8ToI32x4), + extadd_pairwise_i16x8_u: unaryFn(mod, Operation.ExtAddPairwiseUVecI16x8ToI32x4), - extmul_low_i16x8_s: null, - extmul_low_i16x8_u: null, - extmul_high_i16x8_s: null, - extmul_high_i16x8_u: null, + // NOTE: operation names correspond to “this” object, not instruction names + extmul_low_i16x8_s: binaryFn(mod, Operation.ExtMulLowSVecI32x4), + extmul_low_i16x8_u: binaryFn(mod, Operation.ExtMulLowUVecI32x4), + extmul_high_i16x8_s: binaryFn(mod, Operation.ExtMulHighSVecI32x4), + extmul_high_i16x8_u: binaryFn(mod, Operation.ExtMulHighUVecI32x4), - dot_i16x8_s: null, - relaxed_dot_i8x16_i7x16_add_s: null, + dot_i16x8_s: binaryFn(mod, Operation.DotSVecI16x8ToVecI32x4), + // TODO: relaxed_dot_i8x16_i7x16_add_s - extend_low_i16x8_s: null, - extend_low_i16x8_u: null, - extend_high_i16x8_s: null, - extend_high_i16x8_u: null, + extend_low_i16x8_s: unaryFn(mod, Operation.ExtendLowSVecI16x8ToVecI32x4), + extend_low_i16x8_u: unaryFn(mod, Operation.ExtendLowUVecI16x8ToVecI32x4), + extend_high_i16x8_s: unaryFn(mod, Operation.ExtendHighSVecI16x8ToVecI32x4), + extend_high_i16x8_u: unaryFn(mod, Operation.ExtendHighUVecI16x8ToVecI32x4), - trunc_sat_f32x4_s: null, - trunc_sat_f32x4_u: null, - trunc_sat_f64x2_s_zero: null, - trunc_sat_f64x2_u_zero: null, - relaxed_trunc_f32x4_s: null, - relaxed_trunc_f32x4_u: null, - relaxed_trunc_f64x2_s_zero: null, - relaxed_trunc_f64x2_u_zero: null, + trunc_sat_f32x4_s: unaryFn(mod, Operation.TruncSatSVecF32x4ToVecI32x4), + trunc_sat_f32x4_u: unaryFn(mod, Operation.TruncSatUVecF32x4ToVecI32x4), + trunc_sat_f64x2_s_zero: unaryFn(mod, Operation.TruncSatZeroSVecF64x2ToVecI32x4), + trunc_sat_f64x2_u_zero: unaryFn(mod, Operation.TruncSatZeroUVecF64x2ToVecI32x4), + // TODO: relaxed_trunc_f32x4_s + // TODO: relaxed_trunc_f32x4_u + // TODO: relaxed_trunc_f64x2_s_zero + // TODO: relaxed_trunc_f64x2_u_zero - splat: null, - extract_lane: null, - replace_lane: null, + splat: unaryFn(mod, Operation.SplatVecI32x4), + extract_lane: simdExtractFn(mod, Operation.ExtractLaneVecI32x4), + replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecI32x4), } as const; } diff --git a/ts/src/services/expression-builder/i64x2.ts b/ts/src/services/expression-builder/i64x2.ts index dcbfd679afb..1ea3505e57f 100644 --- a/ts/src/services/expression-builder/i64x2.ts +++ b/ts/src/services/expression-builder/i64x2.ts @@ -1,48 +1,59 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + binaryFn, + simdExtractFn, + simdReplaceFn, + simdShiftFn, + unaryFn, +} from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ -export function i64x2(_mod: Module) { +export function i64x2(mod: Module) { return { - abs: null, - neg: null, + abs: unaryFn(mod, Operation.AbsVecI64x2), + neg: unaryFn(mod, Operation.NegVecI64x2), - add: null, - sub: null, - mul: null, + add: binaryFn(mod, Operation.AddVecI64x2), + sub: binaryFn(mod, Operation.SubVecI64x2), + mul: binaryFn(mod, Operation.MulVecI64x2), - relaxed_laneselect: null, + // TODO: relaxed_laneselect - all_true: null, + all_true: unaryFn(mod, Operation.AllTrueVecI64x2), - eq: null, - ne: null, - lt_s: null, - gt_s: null, - le_s: null, - ge_s: null, + eq: binaryFn(mod, Operation.EqVecI64x2), + ne: binaryFn(mod, Operation.NeVecI64x2), + lt_s: binaryFn(mod, Operation.LtSVecI64x2), + gt_s: binaryFn(mod, Operation.GtSVecI64x2), + le_s: binaryFn(mod, Operation.LeSVecI64x2), + ge_s: binaryFn(mod, Operation.GeSVecI64x2), - shl: null, - shr_s: null, - shr_u: null, + shl: simdShiftFn(mod, Operation.ShlVecI64x2), + shr_s: simdShiftFn(mod, Operation.ShrSVecI64x2), + shr_u: simdShiftFn(mod, Operation.ShrUVecI64x2), - bitmask: null, + bitmask: unaryFn(mod, Operation.BitmaskVecI64x2), - extmul_low_i32x4_s: null, - extmul_low_i32x4_u: null, - extmul_high_i32x4_s: null, - extmul_high_i32x4_u: null, + // NOTE: operation names correspond to “this” object, not instruction names + extmul_low_i32x4_s: binaryFn(mod, Operation.ExtMulLowSVecI64x2), + extmul_low_i32x4_u: binaryFn(mod, Operation.ExtMulLowUVecI64x2), + extmul_high_i32x4_s: binaryFn(mod, Operation.ExtMulHighSVecI64x2), + extmul_high_i32x4_u: binaryFn(mod, Operation.ExtMulHighUVecI64x2), - extend_low_i32x4_s: null, - extend_low_i32x4_u: null, - extend_high_i32x4_s: null, - extend_high_i32x4_u: null, + extend_low_i32x4_s: unaryFn(mod, Operation.ExtendLowSVecI32x4ToVecI64x2), + extend_low_i32x4_u: unaryFn(mod, Operation.ExtendLowUVecI32x4ToVecI64x2), + extend_high_i32x4_s: unaryFn(mod, Operation.ExtendHighSVecI32x4ToVecI64x2), + extend_high_i32x4_u: unaryFn(mod, Operation.ExtendHighUVecI32x4ToVecI64x2), - splat: null, - extract_lane: null, - replace_lane: null, + splat: unaryFn(mod, Operation.SplatVecI64x2), + extract_lane: simdExtractFn(mod, Operation.ExtractLaneVecI64x2), + replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecI64x2), } as const; } diff --git a/ts/src/services/expression-builder/i8x16.ts b/ts/src/services/expression-builder/i8x16.ts index efeb2ee38f1..f8fd63e5fa6 100644 --- a/ts/src/services/expression-builder/i8x16.ts +++ b/ts/src/services/expression-builder/i8x16.ts @@ -1,60 +1,82 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; +import { + i8sToStack, + preserveStack, +} from "../../-utils.ts"; import type { Module, } from "../../classes/module/Module.ts"; +import type { + ExpressionRef, +} from "../../constants.ts"; +import { + binaryFn, + simdExtractFn, + simdReplaceFn, + simdShiftFn, + unaryFn, +} from "./-utils.ts"; +import { + Operation, +} from "./Operation.ts"; /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#vector-instructions */ -export function i8x16(_mod: Module) { +export function i8x16(mod: Module) { return { - abs: null, - neg: null, - popcnt: null, - - add: null, - sub: null, - add_sat_s: null, - add_sat_u: null, - sub_sat_s: null, - sub_sat_u: null, - avgr_u: null, - min_s: null, - min_u: null, - max_s: null, - max_u: null, - - relaxed_laneselect: null, - - all_true: null, - - eq: null, - ne: null, - lt_s: null, - lt_u: null, - gt_s: null, - gt_u: null, - le_s: null, - le_u: null, - ge_s: null, - ge_u: null, - - shl: null, - shr_s: null, - shr_u: null, - - bitmask: null, - - swizzle: null, - relaxed_swizzle: null, - - shuffle: null, - - narrow_i16x8_s: null, - narrow_i16x8_u: null, - - splat: null, - extract_lane_s: null, - extract_lane_u: null, - replace_lane: null, + abs: unaryFn(mod, Operation.AbsVecI8x16), + neg: unaryFn(mod, Operation.NegVecI8x16), + popcnt: unaryFn(mod, Operation.PopcntVecI8x16), + + add: binaryFn(mod, Operation.AddVecI8x16), + sub: binaryFn(mod, Operation.SubVecI8x16), + add_sat_s: binaryFn(mod, Operation.AddSatSVecI8x16), // TODO: deprecate `add_saturate_s` + add_sat_u: binaryFn(mod, Operation.AddSatUVecI8x16), // TODO: deprecate `add_saturate_u` + sub_sat_s: binaryFn(mod, Operation.SubSatSVecI8x16), // TODO: deprecate `sub_saturate_s` + sub_sat_u: binaryFn(mod, Operation.SubSatUVecI8x16), // TODO: deprecate `sub_saturate_u` + avgr_u: binaryFn(mod, Operation.AvgrUVecI8x16), + min_s: binaryFn(mod, Operation.MinSVecI8x16), + min_u: binaryFn(mod, Operation.MinUVecI8x16), + max_s: binaryFn(mod, Operation.MaxSVecI8x16), + max_u: binaryFn(mod, Operation.MaxUVecI8x16), + + // TODO: relaxed_laneselect + + all_true: unaryFn(mod, Operation.AllTrueVecI8x16), + + eq: binaryFn(mod, Operation.EqVecI8x16), + ne: binaryFn(mod, Operation.NeVecI8x16), + lt_s: binaryFn(mod, Operation.LtSVecI8x16), + lt_u: binaryFn(mod, Operation.LtUVecI8x16), + gt_s: binaryFn(mod, Operation.GtSVecI8x16), + gt_u: binaryFn(mod, Operation.GtUVecI8x16), + le_s: binaryFn(mod, Operation.LeSVecI8x16), + le_u: binaryFn(mod, Operation.LeUVecI8x16), + ge_s: binaryFn(mod, Operation.GeSVecI8x16), + ge_u: binaryFn(mod, Operation.GeUVecI8x16), + + shl: simdShiftFn(mod, Operation.ShlVecI8x16), + shr_s: simdShiftFn(mod, Operation.ShrSVecI8x16), + shr_u: simdShiftFn(mod, Operation.ShrUVecI8x16), + + bitmask: unaryFn(mod, Operation.BitmaskVecI8x16), + + swizzle: binaryFn(mod, Operation.SwizzleVecI8x16), + // TODO: relaxed_swizzle + + shuffle: (left: ExpressionRef, right: ExpressionRef, mask: readonly number[]): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenSIMDShuffle"](mod.ptr, left, right, i8sToStack(mask))) + ), + + narrow_i16x8_s: binaryFn(mod, Operation.NarrowSVecI16x8ToVecI8x16), + narrow_i16x8_u: binaryFn(mod, Operation.NarrowUVecI16x8ToVecI8x16), + + splat: unaryFn(mod, Operation.SplatVecI8x16), + extract_lane_s: simdExtractFn(mod, Operation.ExtractLaneSVecI8x16), + extract_lane_u: simdExtractFn(mod, Operation.ExtractLaneUVecI8x16), + replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecI8x16), } as const; } From f86c052109344ecba1fa6c773014c24c6e2faf6e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 23:29:54 -0400 Subject: [PATCH 152/247] feat: deprecate `{i8x16,i16x8}.{add,sub}_saturate_{s,u}` --- ts/src/services/expression-builder/i16x8.ts | 20 ++++++++++++++++---- ts/src/services/expression-builder/i8x16.ts | 20 ++++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/ts/src/services/expression-builder/i16x8.ts b/ts/src/services/expression-builder/i16x8.ts index beb31e33dbd..f0fa6477898 100644 --- a/ts/src/services/expression-builder/i16x8.ts +++ b/ts/src/services/expression-builder/i16x8.ts @@ -1,6 +1,9 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + consoleWarn, +} from "../../lib.ts"; import { binaryFn, simdExtractFn, @@ -22,10 +25,10 @@ export function i16x8(mod: Module) { add: binaryFn(mod, Operation.AddVecI16x8), sub: binaryFn(mod, Operation.SubVecI16x8), - add_sat_s: binaryFn(mod, Operation.AddSatSVecI16x8), // TODO: deprecate `add_saturate_s` - add_sat_u: binaryFn(mod, Operation.AddSatUVecI16x8), // TODO: deprecate `add_saturate_u` - sub_sat_s: binaryFn(mod, Operation.SubSatSVecI16x8), // TODO: deprecate `sub_saturate_s` - sub_sat_u: binaryFn(mod, Operation.SubSatUVecI16x8), // TODO: deprecate `sub_saturate_u` + add_sat_s: binaryFn(mod, Operation.AddSatSVecI16x8), + add_sat_u: binaryFn(mod, Operation.AddSatUVecI16x8), + sub_sat_s: binaryFn(mod, Operation.SubSatSVecI16x8), + sub_sat_u: binaryFn(mod, Operation.SubSatUVecI16x8), mul: binaryFn(mod, Operation.MulVecI16x8), avgr_u: binaryFn(mod, Operation.AvgrUVecI16x8), q15mulr_sat_s: binaryFn(mod, Operation.Q15MulrSatSVecI16x8), @@ -79,5 +82,14 @@ export function i16x8(mod: Module) { extract_lane_s: simdExtractFn(mod, Operation.ExtractLaneSVecI16x8), extract_lane_u: simdExtractFn(mod, Operation.ExtractLaneUVecI16x8), replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecI16x8), + + // @ts-expect-error + /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.add_sat_s} instead. */ add_saturate_s(...args) { consoleWarn("`.i16x8.add_saturate_s()` is deprecated; use `.i16x8.add_sat_s()` instead."); return this.add_sat_s(...args); }, + // @ts-expect-error + /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.add_sat_u} instead. */ add_saturate_u(...args) { consoleWarn("`.i16x8.add_saturate_u()` is deprecated; use `.i16x8.add_sat_u()` instead."); return this.add_sat_u(...args); }, + // @ts-expect-error + /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.sub_sat_s} instead. */ sub_saturate_s(...args) { consoleWarn("`.i16x8.sub_saturate_s()` is deprecated; use `.i16x8.sub_sat_s()` instead."); return this.sub_sat_s(...args); }, + // @ts-expect-error + /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.sub_sat_u} instead. */ sub_saturate_u(...args) { consoleWarn("`.i16x8.sub_saturate_u()` is deprecated; use `.i16x8.sub_sat_u()` instead."); return this.sub_sat_u(...args); }, } as const; } diff --git a/ts/src/services/expression-builder/i8x16.ts b/ts/src/services/expression-builder/i8x16.ts index f8fd63e5fa6..c70f2fd7620 100644 --- a/ts/src/services/expression-builder/i8x16.ts +++ b/ts/src/services/expression-builder/i8x16.ts @@ -11,6 +11,9 @@ import type { import type { ExpressionRef, } from "../../constants.ts"; +import { + consoleWarn, +} from "../../lib.ts"; import { binaryFn, simdExtractFn, @@ -33,10 +36,10 @@ export function i8x16(mod: Module) { add: binaryFn(mod, Operation.AddVecI8x16), sub: binaryFn(mod, Operation.SubVecI8x16), - add_sat_s: binaryFn(mod, Operation.AddSatSVecI8x16), // TODO: deprecate `add_saturate_s` - add_sat_u: binaryFn(mod, Operation.AddSatUVecI8x16), // TODO: deprecate `add_saturate_u` - sub_sat_s: binaryFn(mod, Operation.SubSatSVecI8x16), // TODO: deprecate `sub_saturate_s` - sub_sat_u: binaryFn(mod, Operation.SubSatUVecI8x16), // TODO: deprecate `sub_saturate_u` + add_sat_s: binaryFn(mod, Operation.AddSatSVecI8x16), + add_sat_u: binaryFn(mod, Operation.AddSatUVecI8x16), + sub_sat_s: binaryFn(mod, Operation.SubSatSVecI8x16), + sub_sat_u: binaryFn(mod, Operation.SubSatUVecI8x16), avgr_u: binaryFn(mod, Operation.AvgrUVecI8x16), min_s: binaryFn(mod, Operation.MinSVecI8x16), min_u: binaryFn(mod, Operation.MinUVecI8x16), @@ -78,5 +81,14 @@ export function i8x16(mod: Module) { extract_lane_s: simdExtractFn(mod, Operation.ExtractLaneSVecI8x16), extract_lane_u: simdExtractFn(mod, Operation.ExtractLaneUVecI8x16), replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecI8x16), + + // @ts-expect-error + /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.add_sat_s} instead. */ add_saturate_s(...args) { consoleWarn("`.i8x16.add_saturate_s()` is deprecated; use `.i8x16.add_sat_s()` instead."); return this.add_sat_s(...args); }, + // @ts-expect-error + /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.add_sat_u} instead. */ add_saturate_u(...args) { consoleWarn("`.i8x16.add_saturate_u()` is deprecated; use `.i8x16.add_sat_u()` instead."); return this.add_sat_u(...args); }, + // @ts-expect-error + /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.sub_sat_s} instead. */ sub_saturate_s(...args) { consoleWarn("`.i8x16.sub_saturate_s()` is deprecated; use `.i8x16.sub_sat_s()` instead."); return this.sub_sat_s(...args); }, + // @ts-expect-error + /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.sub_sat_u} instead. */ sub_saturate_u(...args) { consoleWarn("`.i8x16.sub_saturate_u()` is deprecated; use `.i8x16.sub_sat_u()` instead."); return this.sub_sat_u(...args); }, } as const; } From 7cc67fa4866a60e94217312e3d9e1817296384db Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 7 May 2026 23:56:18 -0400 Subject: [PATCH 153/247] lint: capitalize MemoryOrder enum members --- ts/src/services/expression-builder/Operation.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ts/src/services/expression-builder/Operation.ts b/ts/src/services/expression-builder/Operation.ts index 9c0afb5a29a..66e14153861 100644 --- a/ts/src/services/expression-builder/Operation.ts +++ b/ts/src/services/expression-builder/Operation.ts @@ -483,7 +483,7 @@ export enum Operation { export enum MemoryOrder { - unordered = BinaryenObj["_BinaryenMemoryOrderUnordered"](), - seqcst = BinaryenObj["_BinaryenMemoryOrderSeqCst"](), - acqrel = BinaryenObj["_BinaryenMemoryOrderAcqRel"](), + Unordered = BinaryenObj["_BinaryenMemoryOrderUnordered"](), + SeqCst = BinaryenObj["_BinaryenMemoryOrderSeqCst"](), + AcqRel = BinaryenObj["_BinaryenMemoryOrderAcqRel"](), } From 929ad1d1a7d7bfb4ddd8467bf208a3a674790b84 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 00:02:37 -0400 Subject: [PATCH 154/247] feat: optional `name` param in load/store ops --- ts/src/services/expression-builder/-utils.ts | 24 +++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/ts/src/services/expression-builder/-utils.ts b/ts/src/services/expression-builder/-utils.ts index e94c0680588..fc50cdb0d89 100644 --- a/ts/src/services/expression-builder/-utils.ts +++ b/ts/src/services/expression-builder/-utils.ts @@ -69,20 +69,28 @@ export function binaryFn(mod: Module, op: Operation): (left: ExpressionRef, righ return (left, right) => BinaryenObj["_BinaryenBinary"](mod.ptr, op, left, right); } -export function loadFn(mod: Module, typ: Type, bytes: number, isSigned: boolean): (offset: number, align: number, ptr: ExpressionRef, name: string) => ExpressionRef { - return (offset, align, ptr, name) => preserveStack(() => BinaryenObj["_BinaryenLoad"](mod.ptr, bytes, isSigned, offset, align, typ, ptr, strToStack(name))); +export function loadFn(mod: Module, typ: Type, bytes: number, isSigned: boolean): (offset: number, align: number, ptr: ExpressionRef, name?: string) => ExpressionRef { + return (offset, align, ptr, name) => ( + preserveStack(() => BinaryenObj["_BinaryenLoad"](mod.ptr, bytes, isSigned, offset, align, typ, ptr, strToStack(name))) + ); } -export function storeFn(mod: Module, typ: Type, bytes: number): (offset: number, align: number, ptr: ExpressionRef, value: ExpressionRef, name: string) => ExpressionRef { - return (offset, align, ptr, value, name) => preserveStack(() => BinaryenObj["_BinaryenStore"](mod.ptr, bytes, offset, align, ptr, value, typ, strToStack(name))); +export function storeFn(mod: Module, typ: Type, bytes: number): (offset: number, align: number, ptr: ExpressionRef, value: ExpressionRef, name?: string) => ExpressionRef { + return (offset, align, ptr, value, name) => ( + preserveStack(() => BinaryenObj["_BinaryenStore"](mod.ptr, bytes, offset, align, ptr, value, typ, strToStack(name))) + ); } -export function simdLoadFn(mod: Module, op: Operation): (offset: number, align: number, ptr: ExpressionRef, name: string) => ExpressionRef { - return (offset, align, ptr, name) => preserveStack(() => BinaryenObj["_BinaryenSIMDLoad"](mod.ptr, op, offset, align, ptr, strToStack(name))); +export function simdLoadFn(mod: Module, op: Operation): (offset: number, align: number, ptr: ExpressionRef, name?: string) => ExpressionRef { + return (offset, align, ptr, name) => ( + preserveStack(() => BinaryenObj["_BinaryenSIMDLoad"](mod.ptr, op, offset, align, ptr, strToStack(name))) + ); } -export function simdLoadStoreLaneFn(mod: Module, op: Operation): (offset: number, align: number, index: number, ptr: ExpressionRef, vec: ExpressionRef, name: string) => ExpressionRef { - return (offset, align, index, ptr, vec, name) => preserveStack(() => BinaryenObj["_BinaryenSIMDLoadStoreLane"](mod.ptr, op, offset, align, index, ptr, vec, strToStack(name))); +export function simdLoadStoreLaneFn(mod: Module, op: Operation): (offset: number, align: number, index: number, ptr: ExpressionRef, vec: ExpressionRef, name?: string) => ExpressionRef { + return (offset, align, index, ptr, vec, name) => ( + preserveStack(() => BinaryenObj["_BinaryenSIMDLoadStoreLane"](mod.ptr, op, offset, align, index, ptr, vec, strToStack(name))) + ); } export function simdShiftFn(mod: Module, op: Operation): (vec: ExpressionRef, shift: ExpressionRef) => ExpressionRef { From b3ee14c2351d69bd6807d52cd3d7d95c75b7a668 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 00:53:51 -0400 Subject: [PATCH 155/247] docs: hide `Module#wasm` type details --- ts/docs/styles.css | 4 ++++ ts/src/classes/module/Module.ts | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ts/docs/styles.css b/ts/docs/styles.css index d6c18b9a1ec..5730302c617 100644 --- a/ts/docs/styles.css +++ b/ts/docs/styles.css @@ -2,3 +2,7 @@ --color-text: gray; color: var(--color-text); } + +#wasm ~ :is(.tsd-signature, .tsd-type-declaration) { + display: none; +} diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 5395752e0db..da3349729ed 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -163,7 +163,9 @@ export class Module { // ## Expression Manipulation ## // /** - * This module’s {@link ExpressionBuilder | WASM expression builder}. + * This module’s WASM expression builder. + * + * See {@link ExpressionBuilder} for its type signature. * * N.B.: For convenience, developers may want to destructure the module to free `wasm`: * ```ts From 60c6506ee44722aca385ae276372a95b3aeca5f6 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 00:54:47 -0400 Subject: [PATCH 156/247] feat: move `MemoryOrder` enum to global --- ts/src/constants.ts | 10 ++++++++++ ts/src/services/expression-builder/Operation.ts | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ts/src/constants.ts b/ts/src/constants.ts index e8988b7ad6d..51ff71b590b 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -242,3 +242,13 @@ export enum ExternalKind { ExternalTable = BinaryenObj["_BinaryenExternalTable"](), ExternalFunction = BinaryenObj["_BinaryenExternalFunction"](), } + +/** + * [description] + * @experimental + */ +export enum MemoryOrder { + Unordered = BinaryenObj["_BinaryenMemoryOrderUnordered"](), + SeqCst = BinaryenObj["_BinaryenMemoryOrderSeqCst"](), + AcqRel = BinaryenObj["_BinaryenMemoryOrderAcqRel"](), +} diff --git a/ts/src/services/expression-builder/Operation.ts b/ts/src/services/expression-builder/Operation.ts index 66e14153861..d96233b2bee 100644 --- a/ts/src/services/expression-builder/Operation.ts +++ b/ts/src/services/expression-builder/Operation.ts @@ -479,11 +479,3 @@ export enum Operation { MulWideSInt64 = BinaryenObj["_BinaryenMulWideSInt64"](), MulWideUInt64 = BinaryenObj["_BinaryenMulWideUInt64"](), } - - - -export enum MemoryOrder { - Unordered = BinaryenObj["_BinaryenMemoryOrderUnordered"](), - SeqCst = BinaryenObj["_BinaryenMemoryOrderSeqCst"](), - AcqRel = BinaryenObj["_BinaryenMemoryOrderAcqRel"](), -} From 2d86c210e5ca66e1e1dd6d669a3a3b5d2f20694a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 00:56:36 -0400 Subject: [PATCH 157/247] feat: add `{i32,i64}.atomic` --- ts/src/services/expression-builder/-utils.ts | 44 ++++++++++++++++++-- ts/src/services/expression-builder/i32.ts | 24 +++++++++++ ts/src/services/expression-builder/i64.ts | 27 ++++++++++++ 3 files changed, 91 insertions(+), 4 deletions(-) diff --git a/ts/src/services/expression-builder/-utils.ts b/ts/src/services/expression-builder/-utils.ts index fc50cdb0d89..a78c5ae801c 100644 --- a/ts/src/services/expression-builder/-utils.ts +++ b/ts/src/services/expression-builder/-utils.ts @@ -9,11 +9,12 @@ import { import type { Module, } from "../../classes/module/Module.ts"; -import type { - ExpressionRef, - Type, +import { + type ExpressionRef, + MemoryOrder, + type Type, } from "../../constants.ts"; -import type { +import { Operation, } from "./Operation.ts"; @@ -104,3 +105,38 @@ export function simdExtractFn(mod: Module, op: Operation): (vec: ExpressionRef, export function simdReplaceFn(mod: Module, op: Operation): (vec: ExpressionRef, index: number, value: ExpressionRef) => ExpressionRef { return (vec, index, value) => BinaryenObj["_BinaryenSIMDReplace"](mod.ptr, op, vec, index, value); } + +export function atomicLoadFn(mod: Module, typ: Type, bytes: number): (offset: number, ptr: ExpressionRef, name?: string, order?: MemoryOrder) => ExpressionRef { + return (offset, ptr, name, order = MemoryOrder.SeqCst) => ( + preserveStack(() => BinaryenObj["_BinaryenAtomicLoad"](mod.ptr, bytes, offset, typ, ptr, strToStack(name), order)) + ); +} + +export function atomicStoreFn(mod: Module, typ: Type, bytes: number): (offset: number, ptr: ExpressionRef, value: ExpressionRef, name?: string, order?: MemoryOrder) => ExpressionRef { + return (offset, ptr, value, name, order = MemoryOrder.SeqCst) => ( + preserveStack(() => BinaryenObj["_BinaryenAtomicStore"](mod.ptr, bytes, offset, ptr, value, typ, strToStack(name), order)) + ); +} + + + +function atomicRmwFn(mod: Module, op: Operation, typ: Type, bytes: number): (offset: number, ptr: ExpressionRef, value: ExpressionRef, name?: string, order?: MemoryOrder) => ExpressionRef { + return (offset, ptr, value, name, order = MemoryOrder.SeqCst) => ( + preserveStack(() => BinaryenObj["_BinaryenAtomicRMW"](mod.ptr, op, bytes, offset, ptr, value, typ, strToStack(name), order)) + ); +} + +export function atomicRmwOps(mod: Module, typ: Type, bytes: number) { + return { + add: atomicRmwFn(mod, Operation.AtomicRMWAdd, typ, bytes), + sub: atomicRmwFn(mod, Operation.AtomicRMWSub, typ, bytes), + and: atomicRmwFn(mod, Operation.AtomicRMWAnd, typ, bytes), + or: atomicRmwFn(mod, Operation.AtomicRMWOr, typ, bytes), + xor: atomicRmwFn(mod, Operation.AtomicRMWXor, typ, bytes), + xchg: atomicRmwFn(mod, Operation.AtomicRMWXchg, typ, bytes), + + cmpxchg: (offset: number, ptr: ExpressionRef, expected: ExpressionRef, replacement: ExpressionRef, name?: string, order: MemoryOrder = MemoryOrder.SeqCst): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenAtomicCmpxchg"](mod.ptr, bytes, offset, ptr, expected, replacement, typ, strToStack(name), order)) + ), + } as const; +} diff --git a/ts/src/services/expression-builder/i32.ts b/ts/src/services/expression-builder/i32.ts index 9f554d56e4d..1ef22803e30 100644 --- a/ts/src/services/expression-builder/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -9,6 +9,9 @@ import { i32 as i32_t, } from "../../constants.ts"; import { + atomicLoadFn, + atomicRmwOps, + atomicStoreFn, binaryFn, constant, loadFn, @@ -21,6 +24,24 @@ import { +function atomic(mod: Module) { + return { + load: atomicLoadFn(mod, i32_t, 4), + load8_u: atomicLoadFn(mod, i32_t, 1), + load16_u: atomicLoadFn(mod, i32_t, 2), + + store: atomicStoreFn(mod, i32_t, 4), + store8: atomicStoreFn(mod, i32_t, 1), + store16: atomicStoreFn(mod, i32_t, 2), + + rmw: atomicRmwOps(mod, i32_t, 4), + rmw8_u: atomicRmwOps(mod, i32_t, 1), + rmw16_u: atomicRmwOps(mod, i32_t, 2), + } as const; +} + + + /** * @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions * @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions @@ -90,6 +111,9 @@ export function i32(mod: Module) { trunc_sat_f64_u: unaryFn(mod, Operation.TruncSatUFloat64ToInt32), reinterpret_f32: unaryFn(mod, Operation.ReinterpretFloat32), + /** @experimental */ + atomic: atomic(mod), + // @ts-expect-error /** @deprecated Use `.wrap_i64()` instead. */ wrap(...args) { consoleWarn("`.wrap()` is deprecated; use `.wrap_i64()` instead."); return this.wrap_i64(...args); }, /** @deprecated */ diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index 6e42e9b648c..cc95a35bae3 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -12,6 +12,9 @@ import { i64 as i64_t, } from "../../constants.ts"; import { + atomicLoadFn, + atomicRmwOps, + atomicStoreFn, binaryFn, constant, loadFn, @@ -24,6 +27,27 @@ import { +function atomic(mod: Module) { + return { + load: atomicLoadFn(mod, i64_t, 8), + load8_u: atomicLoadFn(mod, i64_t, 1), + load16_u: atomicLoadFn(mod, i64_t, 2), + load32_u: atomicLoadFn(mod, i64_t, 4), + + store: atomicStoreFn(mod, i64_t, 8), + store8: atomicStoreFn(mod, i64_t, 1), + store16: atomicStoreFn(mod, i64_t, 2), + store32: atomicStoreFn(mod, i64_t, 4), + + rmw: atomicRmwOps(mod, i64_t, 8), + rmw8_u: atomicRmwOps(mod, i64_t, 1), + rmw16_u: atomicRmwOps(mod, i64_t, 2), + rmw32_u: atomicRmwOps(mod, i64_t, 4), + } as const; +} + + + /** * @see https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions * @see https://webassembly.github.io/spec/core/syntax/instructions.html#numeric-instructions @@ -114,6 +138,9 @@ export function i64(mod: Module) { trunc_sat_f64_u: unaryFn(mod, Operation.TruncSatUFloat64ToInt64), reinterpret_f64: unaryFn(mod, Operation.ReinterpretFloat64), + /** @experimental */ + atomic: atomic(mod), + // @ts-expect-error /** @deprecated Use `.extend_i32_s()` instead. */ extend_s(...args) { consoleWarn("`.extend_s()` is deprecated; use `.extend_i32_s()` instead."); return this.extend_i32_s(...args); }, // @ts-expect-error From b478412be3a1704de3eea6c30ca715450f601622 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 01:28:21 -0400 Subject: [PATCH 158/247] feat: add `atomic.fence` --- ts/src/classes/module/Module.ts | 5 ++++- ts/src/services/expression-builder/expressionBuilder.ts | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index da3349729ed..12963486e91 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -508,7 +508,10 @@ export class Module { preserveStack(() => BinaryenObj["_BinaryenAddCustomSection"](this.ptr, strToStack(name), i8sToStack([...contents]), contents.length)); } - /** [description] */ + /** + * Updates the internal name mapping logic in a module. + * This must be called after renaming module elements. + */ updateMaps(): void { BinaryenObj["_BinaryenModuleUpdateMaps"](this.ptr); } diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index b5dace83f9a..d05952c2d01 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -1,3 +1,6 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -90,6 +93,7 @@ export function expressionBuilder(mod: Module) { i64x2: i64x2(mod), f32x4: f32x4(mod), f64x2: f64x2(mod), + atomic: {fence: () => BinaryenObj["_BinaryenAtomicFence"](mod.ptr)}, } as const; } From 7ee7eb271b4b97ba27be87199ea865826c7c9df4 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 01:38:43 -0400 Subject: [PATCH 159/247] feat: add `Global{Get,Set}` classes --- ts/docs/API-Overview.md | 2 ++ ts/src/classes/expression/GlobalGet.ts | 28 +++++++++++++++++++++++ ts/src/classes/expression/GlobalSet.ts | 31 ++++++++++++++++++++++++++ ts/src/classes/expression/index.ts | 2 ++ ts/src/globals.ts | 2 ++ 5 files changed, 65 insertions(+) create mode 100644 ts/src/classes/expression/GlobalGet.ts create mode 100644 ts/src/classes/expression/GlobalSet.ts diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 0cbb1cddd68..e2f802b7bb9 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -314,6 +314,8 @@ See generated docs for fields, methods, and descriptions of each. - variable instructions - `expressions.LocalGet` - `expressions.LocalSet` + - `expressions.GlobalGet` + - `expressions.GlobalSet` - numeric instructions - `expressions.Const` diff --git a/ts/src/classes/expression/GlobalGet.ts b/ts/src/classes/expression/GlobalGet.ts new file mode 100644 index 00000000000..bd38b3d4542 --- /dev/null +++ b/ts/src/classes/expression/GlobalGet.ts @@ -0,0 +1,28 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class GlobalGet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.GlobalGet, expr); + } + + + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalGetGetName"](this[THIS_PTR])); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalGetSetName"](this[THIS_PTR], strToStack(name))); } +} diff --git a/ts/src/classes/expression/GlobalSet.ts b/ts/src/classes/expression/GlobalSet.ts new file mode 100644 index 00000000000..7002231d354 --- /dev/null +++ b/ts/src/classes/expression/GlobalSet.ts @@ -0,0 +1,31 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class GlobalSet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.GlobalSet, expr); + } + + + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalSetGetName"](this[THIS_PTR])); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalSetSetName"](this[THIS_PTR], strToStack(name))); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenGlobalSetGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenGlobalSetSetValue"](this[THIS_PTR], valueExpr); } +} diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 21a58f9feb2..609c6086d97 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -33,6 +33,8 @@ export {Try} from "./Try.ts"; // ## Variable ## // export {LocalGet} from "./LocalGet.ts"; export {LocalSet} from "./LocalSet.ts"; +export {GlobalGet} from "./GlobalGet.ts"; +export {GlobalSet} from "./GlobalSet.ts"; // ## Numeric & Vector ## // export {Const} from "./Const.ts"; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 8b7ac3f0a5b..4892ff4b5c3 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -54,6 +54,8 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Fri, 8 May 2026 09:53:31 -0400 Subject: [PATCH 160/247] feat: add `Table{Get,Set}` --- ts/src/classes/expression/TableGet.ts | 31 ++++++++++++++++++++++++ ts/src/classes/expression/TableSet.ts | 34 +++++++++++++++++++++++++++ ts/src/classes/expression/index.ts | 4 ++++ ts/src/globals.ts | 4 ++++ 4 files changed, 73 insertions(+) create mode 100644 ts/src/classes/expression/TableGet.ts create mode 100644 ts/src/classes/expression/TableSet.ts diff --git a/ts/src/classes/expression/TableGet.ts b/ts/src/classes/expression/TableGet.ts new file mode 100644 index 00000000000..8780cff9ab8 --- /dev/null +++ b/ts/src/classes/expression/TableGet.ts @@ -0,0 +1,31 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class TableGet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.TableGet, expr); + } + + + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetGetTable"](this[THIS_PTR])); } + set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGetSetTable"](this[THIS_PTR], strToStack(name))); } + + get index(): number { return BinaryenObj["_BinaryenTableGetGetIndex"](this[THIS_PTR]); } + set index(index: number) { BinaryenObj["_BinaryenTableGetSetIndex"](this[THIS_PTR], index); } +} diff --git a/ts/src/classes/expression/TableSet.ts b/ts/src/classes/expression/TableSet.ts new file mode 100644 index 00000000000..192651dbd69 --- /dev/null +++ b/ts/src/classes/expression/TableSet.ts @@ -0,0 +1,34 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class TableSet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.TableSet, expr); + } + + + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetGetTable"](this[THIS_PTR])); } + set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGetSetTable"](this[THIS_PTR], strToStack(name))); } + + get index(): number { return BinaryenObj["_BinaryenTableSetGetIndex"](this[THIS_PTR]); } + set index(index: number) { BinaryenObj["_BinaryenTableSetSetIndex"](this[THIS_PTR], index); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenTableSetGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenTableSetSetValue"](this[THIS_PTR], valueExpr); } +} diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 609c6086d97..c7156a6f741 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -36,5 +36,9 @@ export {LocalSet} from "./LocalSet.ts"; export {GlobalGet} from "./GlobalGet.ts"; export {GlobalSet} from "./GlobalSet.ts"; +// ## Table ## // +export {TableGet} from "./TableGet.ts"; +export {TableSet} from "./TableSet.ts"; + // ## Numeric & Vector ## // export {Const} from "./Const.ts"; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 4892ff4b5c3..8d0e8cd847d 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -57,6 +57,10 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Fri, 8 May 2026 09:53:31 -0400 Subject: [PATCH 161/247] lint: whitespace --- ts/src/classes/expression/Drop.ts | 9 ++------- ts/src/classes/expression/LocalGet.ts | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/ts/src/classes/expression/Drop.ts b/ts/src/classes/expression/Drop.ts index 3d217f44dfb..2994f81cd4f 100644 --- a/ts/src/classes/expression/Drop.ts +++ b/ts/src/classes/expression/Drop.ts @@ -20,11 +20,6 @@ export class Drop extends Expression { } - get value(): ExpressionRef { - return BinaryenObj["_BinaryenDropGetValue"](this[THIS_PTR]); - } - - set value(valueExpr: ExpressionRef) { - BinaryenObj["_BinaryenDropSetValue"](this[THIS_PTR], valueExpr); - } + get value(): ExpressionRef { return BinaryenObj["_BinaryenDropGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenDropSetValue"](this[THIS_PTR], valueExpr); } } diff --git a/ts/src/classes/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts index 6cfa9e599ed..d79ff4cff7b 100644 --- a/ts/src/classes/expression/LocalGet.ts +++ b/ts/src/classes/expression/LocalGet.ts @@ -20,11 +20,6 @@ export class LocalGet extends Expression { } - get index(): number { - return BinaryenObj["_BinaryenLocalGetGetIndex"](this[THIS_PTR]); - } - - set index(index: number) { - BinaryenObj["_BinaryenLocalGetSetIndex"](this[THIS_PTR], index); - } + get index(): number { return BinaryenObj["_BinaryenLocalGetGetIndex"](this[THIS_PTR]); } + set index(index: number) { BinaryenObj["_BinaryenLocalGetSetIndex"](this[THIS_PTR], index); } } From dac4edbf33ca781c034e6a745470cfc18586d142 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 10:11:32 -0400 Subject: [PATCH 162/247] refactor: reorg parametric instrs --- .../expression-builder/expressionBuilder.ts | 24 ++++++------- .../{control.ts => generic.ts} | 27 ++++++++++++++ .../services/expression-builder/parametric.ts | 36 ------------------- 3 files changed, 37 insertions(+), 50 deletions(-) rename ts/src/services/expression-builder/{control.ts => generic.ts} (91%) delete mode 100644 ts/src/services/expression-builder/parametric.ts diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index d05952c2d01..9fb8fb04fec 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -1,3 +1,4 @@ +/* eslint-disable @stylistic/object-curly-newline */ import { BinaryenObj, } from "../../-pre.ts"; @@ -9,31 +10,27 @@ import { struct, tuple, } from "./aggregate.ts"; +import {f32} from "./f32.ts"; +import {f32x4} from "./f32x4.ts"; +import {f64} from "./f64.ts"; +import {f64x2} from "./f64x2.ts"; import { blocks, breaks, calls, + parametrics, throws, -} from "./control.ts"; -/* eslint-disable @stylistic/object-curly-newline */ -import {f32} from "./f32.ts"; -import {f32x4} from "./f32x4.ts"; -import {f64} from "./f64.ts"; -import {f64x2} from "./f64x2.ts"; +} from "./generic.ts"; import {i8x16} from "./i8x16.ts"; import {i16x8} from "./i16x8.ts"; import {i32} from "./i32.ts"; import {i32x4} from "./i32x4.ts"; import {i64} from "./i64.ts"; import {i64x2} from "./i64x2.ts"; -/* eslint-enable @stylistic/object-curly-newline */ import { data, memory, } from "./memory.ts"; -import { - parametric, -} from "./parametric.ts"; import { i31, ref, @@ -41,13 +38,12 @@ import { import { table, } from "./table.ts"; -import { - v128, -} from "./v128.ts"; +import {v128} from "./v128.ts"; import { global, local, } from "./variable.ts"; +/* eslint-enable @stylistic/object-curly-newline */ @@ -64,7 +60,7 @@ export function expressionBuilder(mod: Module) { * If any object literal has more than one property, move it out into a separate function. */ return { - ...parametric(mod), + ...parametrics(mod), ...blocks(mod), ...breaks(mod), ...calls(mod), diff --git a/ts/src/services/expression-builder/control.ts b/ts/src/services/expression-builder/generic.ts similarity index 91% rename from ts/src/services/expression-builder/control.ts rename to ts/src/services/expression-builder/generic.ts index 0702b03380a..d97d05d3cc0 100644 --- a/ts/src/services/expression-builder/control.ts +++ b/ts/src/services/expression-builder/generic.ts @@ -24,6 +24,33 @@ import { +/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#parametric-instructions */ +export function parametrics(mod: Module) { + return { + /** Creates a no-operation `(nop)` instruction. */ + nop: (): ExpressionRef => ( + BinaryenObj["_BinaryenNop"](mod.ptr) + ), + + /** Creates an unreachable instruction that will always trap. */ + unreachable: (): ExpressionRef => ( + BinaryenObj["_BinaryenUnreachable"](mod.ptr) + ), + + /** Creates a `(drop)` of a value. */ + drop: (value: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenDrop"](mod.ptr, value) + ), + + /** Creates a `(select)` of one of two values. */ + select: (ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenSelect"](mod.ptr, ifTrue, ifFalse) + ), + } as const; +} + + + /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ export function blocks(mod: Module) { return { diff --git a/ts/src/services/expression-builder/parametric.ts b/ts/src/services/expression-builder/parametric.ts deleted file mode 100644 index a07ff7f664d..00000000000 --- a/ts/src/services/expression-builder/parametric.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; -import type { - Module, -} from "../../classes/module/Module.ts"; -import type { - ExpressionRef, -} from "../../constants.ts"; - - - -/** @see https://webassembly.github.io/spec/core/syntax/instructions.html#parametric-instructions */ -export function parametric(mod: Module) { - return { - /** Creates a no-operation `(nop)` instruction. */ - nop: (): ExpressionRef => ( - BinaryenObj["_BinaryenNop"](mod.ptr) - ), - - /** Creates an unreachable instruction that will always trap. */ - unreachable: (): ExpressionRef => ( - BinaryenObj["_BinaryenUnreachable"](mod.ptr) - ), - - /** Creates a `(drop)` of a value. */ - drop: (value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenDrop"](mod.ptr, value) - ), - - /** Creates a `(select)` of one of two values. */ - select: (ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenSelect"](mod.ptr, ifTrue, ifFalse) - ), - } as const; -} From 876aa3f80d70e57ae514a10b7d6af7b44715d222 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 10:38:18 -0400 Subject: [PATCH 163/247] refactor: reorg expression classes --- ts/src/classes/expression/BrOn.ts | 38 ---- ts/src/classes/expression/Break.ts | 40 ---- ts/src/classes/expression/Call.ts | 75 -------- ts/src/classes/expression/CallIndirect.ts | 85 -------- ts/src/classes/expression/CallRef.ts | 47 ----- ts/src/classes/expression/Drop.ts | 25 --- ts/src/classes/expression/GlobalGet.ts | 28 --- ts/src/classes/expression/GlobalSet.ts | 31 --- ts/src/classes/expression/If.ts | 31 --- ts/src/classes/expression/LocalGet.ts | 25 --- ts/src/classes/expression/LocalSet.ts | 32 ---- ts/src/classes/expression/Loop.ts | 37 ---- ts/src/classes/expression/Rethrow.ts | 34 ---- ts/src/classes/expression/Return.ts | 25 --- ts/src/classes/expression/TableGet.ts | 31 --- ts/src/classes/expression/Throw.ts | 72 ------- .../expression/{Block.ts => blocks.ts} | 38 +++- .../expression/{Switch.ts => breaks.ts} | 46 ++++- ts/src/classes/expression/calls.ts | 181 ++++++++++++++++++ ts/src/classes/expression/index.ts | 64 ++++--- .../expression/{Select.ts => parametrics.ts} | 12 +- .../expression/{TableSet.ts => tables.ts} | 15 +- .../classes/expression/{Try.ts => throws.ts} | 74 ++++++- ts/src/classes/expression/variables.ts | 70 +++++++ 24 files changed, 463 insertions(+), 693 deletions(-) delete mode 100644 ts/src/classes/expression/BrOn.ts delete mode 100644 ts/src/classes/expression/Break.ts delete mode 100644 ts/src/classes/expression/Call.ts delete mode 100644 ts/src/classes/expression/CallIndirect.ts delete mode 100644 ts/src/classes/expression/CallRef.ts delete mode 100644 ts/src/classes/expression/Drop.ts delete mode 100644 ts/src/classes/expression/GlobalGet.ts delete mode 100644 ts/src/classes/expression/GlobalSet.ts delete mode 100644 ts/src/classes/expression/If.ts delete mode 100644 ts/src/classes/expression/LocalGet.ts delete mode 100644 ts/src/classes/expression/LocalSet.ts delete mode 100644 ts/src/classes/expression/Loop.ts delete mode 100644 ts/src/classes/expression/Rethrow.ts delete mode 100644 ts/src/classes/expression/Return.ts delete mode 100644 ts/src/classes/expression/TableGet.ts delete mode 100644 ts/src/classes/expression/Throw.ts rename ts/src/classes/expression/{Block.ts => blocks.ts} (59%) rename ts/src/classes/expression/{Switch.ts => breaks.ts} (59%) create mode 100644 ts/src/classes/expression/calls.ts rename ts/src/classes/expression/{Select.ts => parametrics.ts} (75%) rename ts/src/classes/expression/{TableSet.ts => tables.ts} (65%) rename ts/src/classes/expression/{Try.ts => throws.ts} (66%) create mode 100644 ts/src/classes/expression/variables.ts diff --git a/ts/src/classes/expression/BrOn.ts b/ts/src/classes/expression/BrOn.ts deleted file mode 100644 index 9bfc568af56..00000000000 --- a/ts/src/classes/expression/BrOn.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - preserveStack, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, - type Type, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class BrOn extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.BrOn, expr); - } - - - get op(): number { return BinaryenObj["_BinaryenBrOnGetOp"](this[THIS_PTR]); } - set op(op: number) { BinaryenObj["_BinaryenBrOnSetOp"](this[THIS_PTR], op); } - - get name(): string { return UTF8ToString(BinaryenObj["_BinaryenBrOnGetName"](this[THIS_PTR])); } - set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenBrOnSetName"](this[THIS_PTR], strToStack(name))); } - - get ref(): ExpressionRef { return BinaryenObj["_BinaryenBrOnGetRef"](this[THIS_PTR]); } - set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenBrOnSetRef"](this[THIS_PTR], ref); } - - get castType(): Type { return BinaryenObj["_BinaryenBrOnGetCastType"](this[THIS_PTR]); } - set castType(castType: Type) { BinaryenObj["_BinaryenBrOnSetCastType"](this[THIS_PTR], castType); } -} diff --git a/ts/src/classes/expression/Break.ts b/ts/src/classes/expression/Break.ts deleted file mode 100644 index 141e6377c63..00000000000 --- a/ts/src/classes/expression/Break.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - preserveStack, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class Break extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.Break, expr); - } - - - get name(): string | null { - const name = BinaryenObj["_BinaryenBreakGetName"](this[THIS_PTR]); - return name ? UTF8ToString(name) : null; - } - - set name(name: string) { - preserveStack(() => BinaryenObj["_BinaryenBreakSetName"](this[THIS_PTR], strToStack(name))); - } - - get condition(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetCondition"](this[THIS_PTR]); } - set condition(condExpr: ExpressionRef) {BinaryenObj["_BinaryenBreakSetCondition"](this[THIS_PTR], condExpr);} - - get value(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenBreakSetValue"](this[THIS_PTR], valueExpr); } -} diff --git a/ts/src/classes/expression/Call.ts b/ts/src/classes/expression/Call.ts deleted file mode 100644 index b5517ff8ee8..00000000000 --- a/ts/src/classes/expression/Call.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - getAllNested, - preserveStack, - setAllNested, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class Call extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.Call, expr); - } - - - get target(): string { return UTF8ToString(BinaryenObj["_BinaryenCallGetTarget"](this[THIS_PTR])); } - set target(targetName: string) { preserveStack(() => BinaryenObj["_BinaryenCallSetTarget"](this[THIS_PTR], strToStack(targetName))); } - - get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIsReturn"](this[THIS_PTR])); } - set return(isReturn: boolean) { BinaryenObj["_BinaryenCallSetReturn"](this[THIS_PTR], isReturn); } - - get numOperands(): number { return BinaryenObj["_BinaryenCallGetNumOperands"](this[THIS_PTR]); } - - get operands(): ExpressionRef[] { - return getAllNested( - this[THIS_PTR], - BinaryenObj["_BinaryenCallGetNumOperands"], - BinaryenObj["_BinaryenCallGetOperandAt"], - ); - } - - set operands(operands: readonly ExpressionRef[]) { - setAllNested( - this[THIS_PTR], - operands, - BinaryenObj["_BinaryenCallGetNumOperands"], - BinaryenObj["_BinaryenCallSetOperandAt"], - BinaryenObj["_BinaryenCallAppendOperand"], - BinaryenObj["_BinaryenCallRemoveOperandAt"], - ); - } - - - getOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallGetOperandAt"](this[THIS_PTR], index); - } - - setOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallSetOperandAt"](this[THIS_PTR], index, operandExpr); - } - - appendOperand(operandExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenCallAppendOperand"](this[THIS_PTR], operandExpr); - } - - insertOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallInsertOperandAt"](this[THIS_PTR], index, operandExpr); - } - - removeOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallRemoveOperandAt"](this[THIS_PTR], index); - } -} diff --git a/ts/src/classes/expression/CallIndirect.ts b/ts/src/classes/expression/CallIndirect.ts deleted file mode 100644 index d04ab50cee9..00000000000 --- a/ts/src/classes/expression/CallIndirect.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - getAllNested, - preserveStack, - setAllNested, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, - type Type, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class CallIndirect extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.CallIndirect, expr); - } - - - get target(): ExpressionRef { return BinaryenObj["_BinaryenCallIndirectGetTarget"](this[THIS_PTR]); } - set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallIndirectSetTarget"](this[THIS_PTR], targetExpr); } - - get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIndirectIsReturn"](this[THIS_PTR])); } - set return(isReturn: boolean) { BinaryenObj["_BinaryenCallIndirectSetReturn"](this[THIS_PTR], isReturn); } - - get table(): string { return UTF8ToString(BinaryenObj["_BinaryenCallIndirectGetTable"](this[THIS_PTR])); } - set table(table: string) { preserveStack(() => BinaryenObj["_BinaryenCallIndirectSetTable"](this[THIS_PTR], strToStack(table))); } - - get params(): Type {return BinaryenObj["_BinaryenCallIndirectGetParams"](this[THIS_PTR]);} - set params(params: Type) { BinaryenObj["_BinaryenCallIndirectSetParams"](this[THIS_PTR], params); } - - get results(): Type { return BinaryenObj["_BinaryenCallIndirectGetResults"](this[THIS_PTR]); } - set results(results: Type) { BinaryenObj["_BinaryenCallIndirectSetResults"](this[THIS_PTR], results); } - - get numOperands(): number { return BinaryenObj["_BinaryenCallIndirectGetNumOperands"](this[THIS_PTR]); } - - get operands(): ExpressionRef[] { - return getAllNested( - this[THIS_PTR], - BinaryenObj["_BinaryenCallIndirectGetNumOperands"], - BinaryenObj["_BinaryenCallIndirectGetOperandAt"], - ); - } - - set operands(operands: readonly ExpressionRef[]) { - setAllNested( - this[THIS_PTR], - operands, - BinaryenObj["_BinaryenCallIndirectGetNumOperands"], - BinaryenObj["_BinaryenCallIndirectSetOperandAt"], - BinaryenObj["_BinaryenCallIndirectAppendOperand"], - BinaryenObj["_BinaryenCallIndirectRemoveOperandAt"], - ); - } - - - getOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallIndirectGetOperandAt"](this[THIS_PTR], index); - } - - setOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallIndirectSetOperandAt"](this[THIS_PTR], index, operandExpr); - } - - appendOperand(operandExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenCallIndirectAppendOperand"](this[THIS_PTR], operandExpr); - } - - insertOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallIndirectInsertOperandAt"](this[THIS_PTR], index, operandExpr); - } - - removeOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallIndirectRemoveOperandAt"](this[THIS_PTR], index); - } -} diff --git a/ts/src/classes/expression/CallRef.ts b/ts/src/classes/expression/CallRef.ts deleted file mode 100644 index 89654372085..00000000000 --- a/ts/src/classes/expression/CallRef.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; -import { - THIS_PTR, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class CallRef extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.CallRef, expr); - } - - - get target(): ExpressionRef { return BinaryenObj["_BinaryenCallRefGetTarget"](this[THIS_PTR]); } - set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallRefSetTarget"](this[THIS_PTR], targetExpr); } - - get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallRefIsReturn"](this[THIS_PTR])); } - set return(isReturn: boolean) { BinaryenObj["_BinaryenCallRefSetReturn"](this[THIS_PTR], isReturn); } - - get numOperands(): number { return BinaryenObj["_BinaryenCallRefGetNumOperands"](this[THIS_PTR]); } - - - getOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallRefGetOperandAt"](this[THIS_PTR], index); - } - - setOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallRefSetOperandAt"](this[THIS_PTR], index, operandExpr); - } - - appendOperand(operandExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenCallRefAppendOperand"](this[THIS_PTR], operandExpr); - } - - removeOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallRefRemoveOperandAt"](this[THIS_PTR], index); - } -} diff --git a/ts/src/classes/expression/Drop.ts b/ts/src/classes/expression/Drop.ts deleted file mode 100644 index 2994f81cd4f..00000000000 --- a/ts/src/classes/expression/Drop.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; -import { - THIS_PTR, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class Drop extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.Drop, expr); - } - - - get value(): ExpressionRef { return BinaryenObj["_BinaryenDropGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenDropSetValue"](this[THIS_PTR], valueExpr); } -} diff --git a/ts/src/classes/expression/GlobalGet.ts b/ts/src/classes/expression/GlobalGet.ts deleted file mode 100644 index bd38b3d4542..00000000000 --- a/ts/src/classes/expression/GlobalGet.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - preserveStack, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class GlobalGet extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.GlobalGet, expr); - } - - - get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalGetGetName"](this[THIS_PTR])); } - set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalGetSetName"](this[THIS_PTR], strToStack(name))); } -} diff --git a/ts/src/classes/expression/GlobalSet.ts b/ts/src/classes/expression/GlobalSet.ts deleted file mode 100644 index 7002231d354..00000000000 --- a/ts/src/classes/expression/GlobalSet.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - preserveStack, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class GlobalSet extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.GlobalSet, expr); - } - - - get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalSetGetName"](this[THIS_PTR])); } - set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalSetSetName"](this[THIS_PTR], strToStack(name))); } - - get value(): ExpressionRef { return BinaryenObj["_BinaryenGlobalSetGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenGlobalSetSetValue"](this[THIS_PTR], valueExpr); } -} diff --git a/ts/src/classes/expression/If.ts b/ts/src/classes/expression/If.ts deleted file mode 100644 index d7a4e2daf46..00000000000 --- a/ts/src/classes/expression/If.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; -import { - THIS_PTR, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class If extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.If, expr); - } - - - get condition(): ExpressionRef { return BinaryenObj["_BinaryenIfGetCondition"](this[THIS_PTR]); } - set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetCondition"](condExpr); } - - get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfTrue"](this[THIS_PTR]); } - set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfTrue"](this[THIS_PTR], ifTrueExpr); } - - get ifFalse(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfFalse"](this[THIS_PTR]); } - set ifFalse(ifFalseExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfFalse"](this[THIS_PTR], ifFalseExpr); } -} diff --git a/ts/src/classes/expression/LocalGet.ts b/ts/src/classes/expression/LocalGet.ts deleted file mode 100644 index d79ff4cff7b..00000000000 --- a/ts/src/classes/expression/LocalGet.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; -import { - THIS_PTR, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class LocalGet extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.LocalGet, expr); - } - - - get index(): number { return BinaryenObj["_BinaryenLocalGetGetIndex"](this[THIS_PTR]); } - set index(index: number) { BinaryenObj["_BinaryenLocalGetSetIndex"](this[THIS_PTR], index); } -} diff --git a/ts/src/classes/expression/LocalSet.ts b/ts/src/classes/expression/LocalSet.ts deleted file mode 100644 index cb5f7fd59a5..00000000000 --- a/ts/src/classes/expression/LocalSet.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; -import { - THIS_PTR, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class LocalSet extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.LocalSet, expr); - } - - - get index(): number { return BinaryenObj["_BinaryenLocalSetGetIndex"](this[THIS_PTR]); } - set index(index: number) { BinaryenObj["_BinaryenLocalSetSetIndex"](this[THIS_PTR], index); } - - get value(): ExpressionRef { return BinaryenObj["_BinaryenLocalSetGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenLocalSetSetValue"](this[THIS_PTR], valueExpr); } - - get isTee(): boolean { - return Boolean(BinaryenObj["_BinaryenLocalSetIsTee"](this[THIS_PTR])); - } -} diff --git a/ts/src/classes/expression/Loop.ts b/ts/src/classes/expression/Loop.ts deleted file mode 100644 index c2d28400e6d..00000000000 --- a/ts/src/classes/expression/Loop.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - preserveStack, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class Loop extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.Loop, expr); - } - - - get name(): string | null { - const name = BinaryenObj["_BinaryenLoopGetName"](this[THIS_PTR]); - return name ? UTF8ToString(name) : null; - } - - set name(name: string) { - preserveStack(() => BinaryenObj["_BinaryenLoopSetName"](this[THIS_PTR], strToStack(name))); - } - - get body(): ExpressionRef { return BinaryenObj["_BinaryenLoopGetBody"](this[THIS_PTR]); } - set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenLoopSetBody"](this[THIS_PTR], bodyExpr); } -} diff --git a/ts/src/classes/expression/Rethrow.ts b/ts/src/classes/expression/Rethrow.ts deleted file mode 100644 index 107eed8135d..00000000000 --- a/ts/src/classes/expression/Rethrow.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - preserveStack, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class Rethrow extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.Rethrow, expr); - } - - - get target(): string | null { - const target = BinaryenObj["_BinaryenRethrowGetTarget"](this[THIS_PTR]); - return target ? UTF8ToString(target) : null; - } - - set target(target: string) { - preserveStack(() => BinaryenObj["_BinaryenRethrowSetTarget"](this[THIS_PTR], strToStack(target))); - } -} diff --git a/ts/src/classes/expression/Return.ts b/ts/src/classes/expression/Return.ts deleted file mode 100644 index bb1b0b50728..00000000000 --- a/ts/src/classes/expression/Return.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; -import { - THIS_PTR, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class Return extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.Return, expr); - } - - - get value(): ExpressionRef { return BinaryenObj["_BinaryenReturnGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenReturnSetValue"](this[THIS_PTR], valueExpr); } -} diff --git a/ts/src/classes/expression/TableGet.ts b/ts/src/classes/expression/TableGet.ts deleted file mode 100644 index 8780cff9ab8..00000000000 --- a/ts/src/classes/expression/TableGet.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - preserveStack, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class TableGet extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.TableGet, expr); - } - - - get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetGetTable"](this[THIS_PTR])); } - set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGetSetTable"](this[THIS_PTR], strToStack(name))); } - - get index(): number { return BinaryenObj["_BinaryenTableGetGetIndex"](this[THIS_PTR]); } - set index(index: number) { BinaryenObj["_BinaryenTableGetSetIndex"](this[THIS_PTR], index); } -} diff --git a/ts/src/classes/expression/Throw.ts b/ts/src/classes/expression/Throw.ts deleted file mode 100644 index 4493f72649c..00000000000 --- a/ts/src/classes/expression/Throw.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { - BinaryenObj, - UTF8ToString, -} from "../../-pre.ts"; -import { - THIS_PTR, - getAllNested, - preserveStack, - setAllNested, - strToStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class Throw extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.Throw, expr); - } - - - getTag(): string { return UTF8ToString(BinaryenObj["_BinaryenThrowGetTag"](this[THIS_PTR])); } - setTag(tagName: string) { preserveStack(() => BinaryenObj["_BinaryenThrowSetTag"](this[THIS_PTR], strToStack(tagName))); } - - getNumOperands(): number { return BinaryenObj["_BinaryenThrowGetNumOperands"](this[THIS_PTR]); } - - getOperands(): ExpressionRef[] { - return getAllNested( - this[THIS_PTR], - BinaryenObj["_BinaryenThrowGetNumOperands"], - BinaryenObj["_BinaryenThrowGetOperandAt"], - ); - } - - setOperands(operands: readonly ExpressionRef[]) { - setAllNested( - this[THIS_PTR], - operands, - BinaryenObj["_BinaryenThrowGetNumOperands"], - BinaryenObj["_BinaryenThrowSetOperandAt"], - BinaryenObj["_BinaryenThrowAppendOperand"], - BinaryenObj["_BinaryenThrowRemoveOperandAt"], - ); - } - - - getOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenThrowGetOperandAt"](this[THIS_PTR], index); - } - - setOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenThrowSetOperandAt"](this[THIS_PTR], index, operandExpr); - } - - appendOperand(operandExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenThrowAppendOperand"](this[THIS_PTR], operandExpr); - } - - insertOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenThrowInsertOperandAt"](this[THIS_PTR], index, operandExpr); - } - - removeOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenThrowRemoveOperandAt"](this[THIS_PTR], index); - } -} diff --git a/ts/src/classes/expression/Block.ts b/ts/src/classes/expression/blocks.ts similarity index 59% rename from ts/src/classes/expression/Block.ts rename to ts/src/classes/expression/blocks.ts index 97c15da86f6..19b2ba7668e 100644 --- a/ts/src/classes/expression/Block.ts +++ b/ts/src/classes/expression/blocks.ts @@ -24,7 +24,6 @@ export class Block extends Expression { super(ExpressionId.Block, expr); } - get name(): string | null { const name = BinaryenObj["_BinaryenBlockGetName"](this[THIS_PTR]); return name ? UTF8ToString(name) : null; @@ -73,3 +72,40 @@ export class Block extends Expression { return BinaryenObj["_BinaryenBlockRemoveChildAt"](this[THIS_PTR], index); } } + + + +export class Loop extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Loop, expr); + } + + get name(): string | null { + const name = BinaryenObj["_BinaryenLoopGetName"](this[THIS_PTR]); + return name ? UTF8ToString(name) : null; + } + + set name(name: string) { + preserveStack(() => BinaryenObj["_BinaryenLoopSetName"](this[THIS_PTR], strToStack(name))); + } + + get body(): ExpressionRef { return BinaryenObj["_BinaryenLoopGetBody"](this[THIS_PTR]); } + set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenLoopSetBody"](this[THIS_PTR], bodyExpr); } +} + + + +export class If extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.If, expr); + } + + get condition(): ExpressionRef { return BinaryenObj["_BinaryenIfGetCondition"](this[THIS_PTR]); } + set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetCondition"](condExpr); } + + get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfTrue"](this[THIS_PTR]); } + set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfTrue"](this[THIS_PTR], ifTrueExpr); } + + get ifFalse(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfFalse"](this[THIS_PTR]); } + set ifFalse(ifFalseExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfFalse"](this[THIS_PTR], ifFalseExpr); } +} diff --git a/ts/src/classes/expression/Switch.ts b/ts/src/classes/expression/breaks.ts similarity index 59% rename from ts/src/classes/expression/Switch.ts rename to ts/src/classes/expression/breaks.ts index ed4e9a775a0..5d22d921593 100644 --- a/ts/src/classes/expression/Switch.ts +++ b/ts/src/classes/expression/breaks.ts @@ -12,6 +12,7 @@ import { import { ExpressionId, type ExpressionRef, + type Type, } from "../../constants.ts"; import { Expression, @@ -19,12 +20,34 @@ import { +export class Break extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Break, expr); + } + + get name(): string | null { + const name = BinaryenObj["_BinaryenBreakGetName"](this[THIS_PTR]); + return name ? UTF8ToString(name) : null; + } + + set name(name: string) { + preserveStack(() => BinaryenObj["_BinaryenBreakSetName"](this[THIS_PTR], strToStack(name))); + } + + get condition(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetCondition"](this[THIS_PTR]); } + set condition(condExpr: ExpressionRef) {BinaryenObj["_BinaryenBreakSetCondition"](this[THIS_PTR], condExpr);} + + get value(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenBreakSetValue"](this[THIS_PTR], valueExpr); } +} + + + export class Switch extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.Switch, expr); } - get condition(): ExpressionRef { return BinaryenObj["_BinaryenSwitchGetCondition"](this[THIS_PTR]); } set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSwitchSetCondition"](condExpr); } @@ -61,7 +84,6 @@ export class Switch extends Expression { preserveStack(() => BinaryenObj["_BinaryenSwitchSetDefaultName"](this[THIS_PTR], strToStack(defaultName))); } - getNameAt(index: number): string { return UTF8ToString(BinaryenObj["_BinaryenSwitchGetNameAt"](this[THIS_PTR], index)); } @@ -82,3 +104,23 @@ export class Switch extends Expression { return UTF8ToString(BinaryenObj["_BinaryenSwitchRemoveNameAt"](this[THIS_PTR], index)); } } + + + +export class BrOn extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.BrOn, expr); + } + + get op(): number { return BinaryenObj["_BinaryenBrOnGetOp"](this[THIS_PTR]); } + set op(op: number) { BinaryenObj["_BinaryenBrOnSetOp"](this[THIS_PTR], op); } + + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenBrOnGetName"](this[THIS_PTR])); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenBrOnSetName"](this[THIS_PTR], strToStack(name))); } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenBrOnGetRef"](this[THIS_PTR]); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenBrOnSetRef"](this[THIS_PTR], ref); } + + get castType(): Type { return BinaryenObj["_BinaryenBrOnGetCastType"](this[THIS_PTR]); } + set castType(castType: Type) { BinaryenObj["_BinaryenBrOnSetCastType"](this[THIS_PTR], castType); } +} diff --git a/ts/src/classes/expression/calls.ts b/ts/src/classes/expression/calls.ts new file mode 100644 index 00000000000..7b8e0ef554e --- /dev/null +++ b/ts/src/classes/expression/calls.ts @@ -0,0 +1,181 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + THIS_PTR, + getAllNested, + preserveStack, + setAllNested, + strToStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, + type Type, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Call extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Call, expr); + } + + get target(): string { return UTF8ToString(BinaryenObj["_BinaryenCallGetTarget"](this[THIS_PTR])); } + set target(targetName: string) { preserveStack(() => BinaryenObj["_BinaryenCallSetTarget"](this[THIS_PTR], strToStack(targetName))); } + + get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIsReturn"](this[THIS_PTR])); } + set return(isReturn: boolean) { BinaryenObj["_BinaryenCallSetReturn"](this[THIS_PTR], isReturn); } + + get numOperands(): number { return BinaryenObj["_BinaryenCallGetNumOperands"](this[THIS_PTR]); } + + get operands(): ExpressionRef[] { + return getAllNested( + this[THIS_PTR], + BinaryenObj["_BinaryenCallGetNumOperands"], + BinaryenObj["_BinaryenCallGetOperandAt"], + ); + } + + set operands(operands: readonly ExpressionRef[]) { + setAllNested( + this[THIS_PTR], + operands, + BinaryenObj["_BinaryenCallGetNumOperands"], + BinaryenObj["_BinaryenCallSetOperandAt"], + BinaryenObj["_BinaryenCallAppendOperand"], + BinaryenObj["_BinaryenCallRemoveOperandAt"], + ); + } + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallGetOperandAt"](this[THIS_PTR], index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallSetOperandAt"](this[THIS_PTR], index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenCallAppendOperand"](this[THIS_PTR], operandExpr); + } + + insertOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallInsertOperandAt"](this[THIS_PTR], index, operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallRemoveOperandAt"](this[THIS_PTR], index); + } +} + + + +export class CallRef extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.CallRef, expr); + } + + get target(): ExpressionRef { return BinaryenObj["_BinaryenCallRefGetTarget"](this[THIS_PTR]); } + set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallRefSetTarget"](this[THIS_PTR], targetExpr); } + + get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallRefIsReturn"](this[THIS_PTR])); } + set return(isReturn: boolean) { BinaryenObj["_BinaryenCallRefSetReturn"](this[THIS_PTR], isReturn); } + + get numOperands(): number { return BinaryenObj["_BinaryenCallRefGetNumOperands"](this[THIS_PTR]); } + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallRefGetOperandAt"](this[THIS_PTR], index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallRefSetOperandAt"](this[THIS_PTR], index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenCallRefAppendOperand"](this[THIS_PTR], operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallRefRemoveOperandAt"](this[THIS_PTR], index); + } +} + + + +export class CallIndirect extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.CallIndirect, expr); + } + + get target(): ExpressionRef { return BinaryenObj["_BinaryenCallIndirectGetTarget"](this[THIS_PTR]); } + set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallIndirectSetTarget"](this[THIS_PTR], targetExpr); } + + get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIndirectIsReturn"](this[THIS_PTR])); } + set return(isReturn: boolean) { BinaryenObj["_BinaryenCallIndirectSetReturn"](this[THIS_PTR], isReturn); } + + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenCallIndirectGetTable"](this[THIS_PTR])); } + set table(table: string) { preserveStack(() => BinaryenObj["_BinaryenCallIndirectSetTable"](this[THIS_PTR], strToStack(table))); } + + get params(): Type {return BinaryenObj["_BinaryenCallIndirectGetParams"](this[THIS_PTR]);} + set params(params: Type) { BinaryenObj["_BinaryenCallIndirectSetParams"](this[THIS_PTR], params); } + + get results(): Type { return BinaryenObj["_BinaryenCallIndirectGetResults"](this[THIS_PTR]); } + set results(results: Type) { BinaryenObj["_BinaryenCallIndirectSetResults"](this[THIS_PTR], results); } + + get numOperands(): number { return BinaryenObj["_BinaryenCallIndirectGetNumOperands"](this[THIS_PTR]); } + + get operands(): ExpressionRef[] { + return getAllNested( + this[THIS_PTR], + BinaryenObj["_BinaryenCallIndirectGetNumOperands"], + BinaryenObj["_BinaryenCallIndirectGetOperandAt"], + ); + } + + set operands(operands: readonly ExpressionRef[]) { + setAllNested( + this[THIS_PTR], + operands, + BinaryenObj["_BinaryenCallIndirectGetNumOperands"], + BinaryenObj["_BinaryenCallIndirectSetOperandAt"], + BinaryenObj["_BinaryenCallIndirectAppendOperand"], + BinaryenObj["_BinaryenCallIndirectRemoveOperandAt"], + ); + } + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallIndirectGetOperandAt"](this[THIS_PTR], index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallIndirectSetOperandAt"](this[THIS_PTR], index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenCallIndirectAppendOperand"](this[THIS_PTR], operandExpr); + } + + insertOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenCallIndirectInsertOperandAt"](this[THIS_PTR], index, operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenCallIndirectRemoveOperandAt"](this[THIS_PTR], index); + } +} + + + +export class Return extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Return, expr); + } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenReturnGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenReturnSetValue"](this[THIS_PTR], valueExpr); } +} diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index c7156a6f741..445ae2e7326 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -11,34 +11,40 @@ export {Expression} from "./Expression.ts"; -// ## Parametric ## // -export {Drop} from "./Drop.ts"; -export {Select} from "./Select.ts"; +export { + Drop, + Select, +} from "./parametrics.ts"; +export { + Block, + Loop, + If, +} from "./blocks.ts"; +export { + Break, + Switch, + BrOn, +} from "./breaks.ts"; +export { + Call, + CallRef, + CallIndirect, + Return, +} from "./calls.ts"; +export { + Throw, + Rethrow, + Try, +} from "./throws.ts"; +export { + LocalGet, + LocalSet, + GlobalGet, + GlobalSet, +} from "./variables.ts"; +export { + TableGet, + TableSet, +} from "./tables.ts"; -// ## Control ## // -export {Block} from "./Block.ts"; -export {Loop} from "./Loop.ts"; -export {If} from "./If.ts"; -export {Break} from "./Break.ts"; -export {Switch} from "./Switch.ts"; -export {BrOn} from "./BrOn.ts"; -export {Call} from "./Call.ts"; -export {CallRef} from "./CallRef.ts"; -export {CallIndirect} from "./CallIndirect.ts"; -export {Return} from "./Return.ts"; -export {Throw} from "./Throw.ts"; -export {Rethrow} from "./Rethrow.ts"; -export {Try} from "./Try.ts"; - -// ## Variable ## // -export {LocalGet} from "./LocalGet.ts"; -export {LocalSet} from "./LocalSet.ts"; -export {GlobalGet} from "./GlobalGet.ts"; -export {GlobalSet} from "./GlobalSet.ts"; - -// ## Table ## // -export {TableGet} from "./TableGet.ts"; -export {TableSet} from "./TableSet.ts"; - -// ## Numeric & Vector ## // export {Const} from "./Const.ts"; diff --git a/ts/src/classes/expression/Select.ts b/ts/src/classes/expression/parametrics.ts similarity index 75% rename from ts/src/classes/expression/Select.ts rename to ts/src/classes/expression/parametrics.ts index 23698f6cece..62961a81ed8 100644 --- a/ts/src/classes/expression/Select.ts +++ b/ts/src/classes/expression/parametrics.ts @@ -14,12 +14,22 @@ import { +export class Drop extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Drop, expr); + } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenDropGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenDropSetValue"](this[THIS_PTR], valueExpr); } +} + + + export class Select extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.Select, expr); } - get condition(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetCondition"](this[THIS_PTR]); } set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetCondition"](this[THIS_PTR], condExpr); } diff --git a/ts/src/classes/expression/TableSet.ts b/ts/src/classes/expression/tables.ts similarity index 65% rename from ts/src/classes/expression/TableSet.ts rename to ts/src/classes/expression/tables.ts index 192651dbd69..3eda36180b8 100644 --- a/ts/src/classes/expression/TableSet.ts +++ b/ts/src/classes/expression/tables.ts @@ -17,12 +17,25 @@ import { +export class TableGet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.TableGet, expr); + } + + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetGetTable"](this[THIS_PTR])); } + set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGetSetTable"](this[THIS_PTR], strToStack(name))); } + + get index(): number { return BinaryenObj["_BinaryenTableGetGetIndex"](this[THIS_PTR]); } + set index(index: number) { BinaryenObj["_BinaryenTableGetSetIndex"](this[THIS_PTR], index); } +} + + + export class TableSet extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.TableSet, expr); } - get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetGetTable"](this[THIS_PTR])); } set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGetSetTable"](this[THIS_PTR], strToStack(name))); } diff --git a/ts/src/classes/expression/Try.ts b/ts/src/classes/expression/throws.ts similarity index 66% rename from ts/src/classes/expression/Try.ts rename to ts/src/classes/expression/throws.ts index 05e85d032f7..74bce7699aa 100644 --- a/ts/src/classes/expression/Try.ts +++ b/ts/src/classes/expression/throws.ts @@ -6,8 +6,8 @@ import { THIS_PTR, getAllNested, preserveStack, - strToStack, setAllNested, + strToStack, } from "../../-utils.ts"; import { ExpressionId, @@ -19,12 +19,81 @@ import { +export class Throw extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Throw, expr); + } + + getTag(): string { return UTF8ToString(BinaryenObj["_BinaryenThrowGetTag"](this[THIS_PTR])); } + setTag(tagName: string) { preserveStack(() => BinaryenObj["_BinaryenThrowSetTag"](this[THIS_PTR], strToStack(tagName))); } + + getNumOperands(): number { return BinaryenObj["_BinaryenThrowGetNumOperands"](this[THIS_PTR]); } + + getOperands(): ExpressionRef[] { + return getAllNested( + this[THIS_PTR], + BinaryenObj["_BinaryenThrowGetNumOperands"], + BinaryenObj["_BinaryenThrowGetOperandAt"], + ); + } + + setOperands(operands: readonly ExpressionRef[]) { + setAllNested( + this[THIS_PTR], + operands, + BinaryenObj["_BinaryenThrowGetNumOperands"], + BinaryenObj["_BinaryenThrowSetOperandAt"], + BinaryenObj["_BinaryenThrowAppendOperand"], + BinaryenObj["_BinaryenThrowRemoveOperandAt"], + ); + } + + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenThrowGetOperandAt"](this[THIS_PTR], index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenThrowSetOperandAt"](this[THIS_PTR], index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenThrowAppendOperand"](this[THIS_PTR], operandExpr); + } + + insertOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenThrowInsertOperandAt"](this[THIS_PTR], index, operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenThrowRemoveOperandAt"](this[THIS_PTR], index); + } +} + + + +export class Rethrow extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Rethrow, expr); + } + + get target(): string | null { + const target = BinaryenObj["_BinaryenRethrowGetTarget"](this[THIS_PTR]); + return target ? UTF8ToString(target) : null; + } + + set target(target: string) { + preserveStack(() => BinaryenObj["_BinaryenRethrowSetTarget"](this[THIS_PTR], strToStack(target))); + } +} + + + export class Try extends Expression { constructor(expr: ExpressionRef) { super(ExpressionId.Try, expr); } - get body(): ExpressionRef { return BinaryenObj["_BinaryenTryGetBody"](this[THIS_PTR]); } set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenTrySetBody"](this[THIS_PTR], bodyExpr); } @@ -90,7 +159,6 @@ export class Try extends Expression { preserveStack(() => BinaryenObj["_BinaryenTrySetDelegateTarget"](this[THIS_PTR], strToStack(name))); } - getCatchTagAt(index: number): string { return UTF8ToString(BinaryenObj["_BinaryenTryGetCatchTagAt"](this[THIS_PTR], index)); } diff --git a/ts/src/classes/expression/variables.ts b/ts/src/classes/expression/variables.ts new file mode 100644 index 00000000000..4c750bd3f6b --- /dev/null +++ b/ts/src/classes/expression/variables.ts @@ -0,0 +1,70 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class LocalGet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.LocalGet, expr); + } + + get index(): number { return BinaryenObj["_BinaryenLocalGetGetIndex"](this[THIS_PTR]); } + set index(index: number) { BinaryenObj["_BinaryenLocalGetSetIndex"](this[THIS_PTR], index); } +} + + + +export class LocalSet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.LocalSet, expr); + } + + get index(): number { return BinaryenObj["_BinaryenLocalSetGetIndex"](this[THIS_PTR]); } + set index(index: number) { BinaryenObj["_BinaryenLocalSetSetIndex"](this[THIS_PTR], index); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenLocalSetGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenLocalSetSetValue"](this[THIS_PTR], valueExpr); } + + get isTee(): boolean { + return Boolean(BinaryenObj["_BinaryenLocalSetIsTee"](this[THIS_PTR])); + } +} + + + +export class GlobalGet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.GlobalGet, expr); + } + + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalGetGetName"](this[THIS_PTR])); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalGetSetName"](this[THIS_PTR], strToStack(name))); } +} + + + +export class GlobalSet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.GlobalSet, expr); + } + + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalSetGetName"](this[THIS_PTR])); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalSetSetName"](this[THIS_PTR], strToStack(name))); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenGlobalSetGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenGlobalSetSetValue"](this[THIS_PTR], valueExpr); } +} From 5d105241368b67f68d57a8bc316e7c1b6d3e156c Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 10:41:22 -0400 Subject: [PATCH 164/247] fix: convert Throw tag & operands methods to accessors --- ts/src/classes/expression/throws.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ts/src/classes/expression/throws.ts b/ts/src/classes/expression/throws.ts index 74bce7699aa..eff23506f5e 100644 --- a/ts/src/classes/expression/throws.ts +++ b/ts/src/classes/expression/throws.ts @@ -24,12 +24,12 @@ export class Throw extends Expression { super(ExpressionId.Throw, expr); } - getTag(): string { return UTF8ToString(BinaryenObj["_BinaryenThrowGetTag"](this[THIS_PTR])); } - setTag(tagName: string) { preserveStack(() => BinaryenObj["_BinaryenThrowSetTag"](this[THIS_PTR], strToStack(tagName))); } + get tag(): string { return UTF8ToString(BinaryenObj["_BinaryenThrowGetTag"](this[THIS_PTR])); } + set tag(tagName: string) { preserveStack(() => BinaryenObj["_BinaryenThrowSetTag"](this[THIS_PTR], strToStack(tagName))); } getNumOperands(): number { return BinaryenObj["_BinaryenThrowGetNumOperands"](this[THIS_PTR]); } - getOperands(): ExpressionRef[] { + get operands(): ExpressionRef[] { return getAllNested( this[THIS_PTR], BinaryenObj["_BinaryenThrowGetNumOperands"], @@ -37,7 +37,7 @@ export class Throw extends Expression { ); } - setOperands(operands: readonly ExpressionRef[]) { + set operands(operands: readonly ExpressionRef[]) { setAllNested( this[THIS_PTR], operands, From fe7a4295fa4af31f1e85687dcba121d1cfb502bc Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 13:27:16 -0400 Subject: [PATCH 165/247] feat: add `Table{Size,Grow}` classes --- ts/src/classes/expression/index.ts | 2 ++ ts/src/classes/expression/tables.ts | 28 ++++++++++++++++++++++++++++ ts/src/globals.ts | 2 ++ 3 files changed, 32 insertions(+) diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 445ae2e7326..dc5a7093253 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -45,6 +45,8 @@ export { export { TableGet, TableSet, + TableSize, + TableGrow, } from "./tables.ts"; export {Const} from "./Const.ts"; diff --git a/ts/src/classes/expression/tables.ts b/ts/src/classes/expression/tables.ts index 3eda36180b8..5ffd6f0a6b9 100644 --- a/ts/src/classes/expression/tables.ts +++ b/ts/src/classes/expression/tables.ts @@ -45,3 +45,31 @@ export class TableSet extends Expression { get value(): ExpressionRef { return BinaryenObj["_BinaryenTableSetGetValue"](this[THIS_PTR]); } set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenTableSetSetValue"](this[THIS_PTR], valueExpr); } } + + + +export class TableSize extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.TableSize, expr); + } + + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableSizeGetTable"](this[THIS_PTR])); } + set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableSizeSetTable"](this[THIS_PTR], strToStack(name))); } +} + + + +export class TableGrow extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.TableSize, expr); + } + + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGrowGetTable"](this[THIS_PTR])); } + set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGrowSetTable"](this[THIS_PTR], strToStack(name))); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenTableGrowGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenTableGrowSetValue"](this[THIS_PTR], valueExpr); } + + get delta(): ExpressionRef { return BinaryenObj["_BinaryenTableGrowGetDelta"](this[THIS_PTR]); } + set delta(deltaExpr: ExpressionRef) { BinaryenObj["_BinaryenTableGrowSetDelta"](this[THIS_PTR], deltaExpr); } +} diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 8d0e8cd847d..d01987297f2 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -60,6 +60,8 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Fri, 8 May 2026 15:31:35 -0400 Subject: [PATCH 166/247] feat: add memories classes --- ts/src/classes/expression/index.ts | 12 ++ ts/src/classes/expression/memories.ts | 214 ++++++++++++++++++++++++++ ts/src/globals.ts | 12 ++ 3 files changed, 238 insertions(+) create mode 100644 ts/src/classes/expression/memories.ts diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index dc5a7093253..048e2b4a0b0 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -48,5 +48,17 @@ export { TableSize, TableGrow, } from "./tables.ts"; +export { + Load, + Store, + SIMDLoad, + SIMDLoadStoreLane, + MemorySize, + MemoryGrow, + MemoryFill, + MemoryCopy, + MemoryInit, + DataDrop, +} from "./memories.ts"; export {Const} from "./Const.ts"; diff --git a/ts/src/classes/expression/memories.ts b/ts/src/classes/expression/memories.ts new file mode 100644 index 00000000000..043f92b02a1 --- /dev/null +++ b/ts/src/classes/expression/memories.ts @@ -0,0 +1,214 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + THIS_PTR, + preserveStack, + strToStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, + type MemoryOrder, + type Type, +} from "../../constants.ts"; +import type { + Operation, +} from "../../services/expression-builder/Operation.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Load extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Load, expr); + } + + get bytes(): number { return BinaryenObj["_BinaryenLoadGetBytes"](this[THIS_PTR]); } + set bytes(bytes: number) { BinaryenObj["_BinaryenLoadSetBytes"](this[THIS_PTR], bytes); } + + get signed(): boolean { return Boolean(BinaryenObj["_BinaryenLoadIsSigned"](this[THIS_PTR])); } + set signed(isSigned: boolean) { BinaryenObj["_BinaryenLoadSetSigned"](this[THIS_PTR], isSigned); } + + get offset(): number { return BinaryenObj["_BinaryenLoadGetOffset"](this[THIS_PTR]); } + set offset(offset: number) { BinaryenObj["_BinaryenLoadSetOffset"](this[THIS_PTR], offset); } + + get align(): number { return BinaryenObj["_BinaryenLoadGetAlign"](this[THIS_PTR]); } + set align(align: number) { BinaryenObj["_BinaryenLoadSetAlign"](this[THIS_PTR], align); } + + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenLoadGetPtr"](this[THIS_PTR]); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenLoadSetPtr"](this[THIS_PTR], ptrExpr); } + + get atomic(): boolean { return Boolean(BinaryenObj["_BinaryenLoadIsAtomic"](this[THIS_PTR])); } + // TODO: set atomic + + get memoryOrder(): MemoryOrder { return BinaryenObj["_BinaryenLoadGetMemoryOrder"](this[THIS_PTR]); } + set memoryOrder(order: MemoryOrder) { BinaryenObj["_BinaryenLoadSetMemoryOrder"](this[THIS_PTR], order); } +} + + + +export class Store extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Store, expr); + } + + get bytes(): number { return BinaryenObj["_BinaryenStoreGetBytes"](this[THIS_PTR]); } + set bytes(bytes: number) { BinaryenObj["_BinaryenStoreSetBytes"](this[THIS_PTR], bytes); } + + get offset(): number { return BinaryenObj["_BinaryenStoreGetOffset"](this[THIS_PTR]); } + set offset(offset: number) { BinaryenObj["_BinaryenStoreSetOffset"](this[THIS_PTR], offset); } + + get align(): number { return BinaryenObj["_BinaryenStoreGetAlign"](this[THIS_PTR]); } + set align(align: number) { BinaryenObj["_BinaryenStoreSetAlign"](this[THIS_PTR], align); } + + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenLoadGetPtr"](this[THIS_PTR]); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenLoadSetPtr"](this[THIS_PTR], ptrExpr); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenStoreGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenStoreSetValue"](this[THIS_PTR], valueExpr); } + + get valueType(): Type { return BinaryenObj["_BinaryenStoreGetValueType"](this[THIS_PTR]); } + set valueType(valueType: Type) { BinaryenObj["_BinaryenStoreSetValueType"](this[THIS_PTR], valueType); } + + get atomic(): boolean {return Boolean(BinaryenObj["_BinaryenStoreIsAtomic"](this[THIS_PTR]));} + // TODO: set atomic + + get memoryOrder(): MemoryOrder { return BinaryenObj["_BinaryenStoreGetMemoryOrder"](this[THIS_PTR]); } + set memoryOrder(order: MemoryOrder) { BinaryenObj["_BinaryenStoreSetMemoryOrder"](this[THIS_PTR], order); } +} + + + +export class SIMDLoad extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.SIMDLoad, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenSIMDLoadGetOp"](this[THIS_PTR]); } + set op(op: Operation) { BinaryenObj["_BinaryenSIMDLoadSetOp"](this[THIS_PTR], op); } + + get offset(): number { return BinaryenObj["_BinaryenSIMDLoadGetOffset"](this[THIS_PTR]); } + set offset(offset: number) { BinaryenObj["_BinaryenSIMDLoadSetOffset"](this[THIS_PTR], offset); } + + get align(): number { return BinaryenObj["_BinaryenSIMDLoadGetAlign"](this[THIS_PTR]); } + set align(align: number) { BinaryenObj["_BinaryenSIMDLoadSetAlign"](this[THIS_PTR], align); } + + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadGetPtr"](this[THIS_PTR]); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadSetPtr"](this[THIS_PTR], ptrExpr); } +} + + + +export class SIMDLoadStoreLane extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.SIMDLoadStoreLane, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetOp"](this[THIS_PTR]); } + set op(op: Operation) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetOp"](this[THIS_PTR], op); } + + get offset(): number { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetOffset"](this[THIS_PTR]); } + set offset(offset: number) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetOffset"](this[THIS_PTR], offset); } + + get align(): number { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetAlign"](this[THIS_PTR]); } + set align(align: number) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetAlign"](this[THIS_PTR], align); } + + get index(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetIndex"](this[THIS_PTR]); } + set index(index: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetIndex"](this[THIS_PTR], index); } + + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetPtr"](this[THIS_PTR]); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetPtr"](this[THIS_PTR], ptrExpr); } + + get vec(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetVec"](this[THIS_PTR]); } + set vec(vecExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetVec"](this[THIS_PTR], vecExpr); } + + get store(): boolean {return Boolean(BinaryenObj["_BinaryenSIMDLoadStoreLaneIsStore"](this[THIS_PTR]));} +} + + + +export class MemorySize extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.MemorySize, expr); + } +} + + + +export class MemoryGrow extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.MemoryGrow, expr); + } + + get delta(): ExpressionRef { return BinaryenObj["_BinaryenMemoryGrowGetDelta"](this[THIS_PTR]); } + set delta(deltaExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryGrowSetDelta"](this[THIS_PTR], deltaExpr); } +} + + + +export class MemoryFill extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.MemoryFill, expr); + } + + get dest(): ExpressionRef { return BinaryenObj["_BinaryenMemoryFillGetDest"](this[THIS_PTR]); } + set dest(destExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryFillSetDest"](this[THIS_PTR], destExpr); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenMemoryFillGetValue"](this[THIS_PTR]); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryFillSetValue"](this[THIS_PTR], valueExpr); } + + get size(): ExpressionRef { return BinaryenObj["_BinaryenMemoryFillGetSize"](this[THIS_PTR]); } + set size(sizeExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryFillSetSize"](this[THIS_PTR], sizeExpr); } +} + + + +export class MemoryCopy extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.MemoryCopy, expr); + } + + get dest(): ExpressionRef { return BinaryenObj["_BinaryenMemoryCopyGetDest"](this[THIS_PTR]); } + set dest(destExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryCopySetDest"](this[THIS_PTR], destExpr); } + + get source(): ExpressionRef { return BinaryenObj["_BinaryenMemoryCopyGetSource"](this[THIS_PTR]); } + set source(sourceExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryCopySetSource"](this[THIS_PTR], sourceExpr); } + + get size(): ExpressionRef { return BinaryenObj["_BinaryenMemoryCopyGetSize"](this[THIS_PTR]); } + set size(sizeExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryCopySetSize"](this[THIS_PTR], sizeExpr); } +} + + + +export class MemoryInit extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.MemoryInit, expr); + } + + get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenMemoryInitGetSegment"](this[THIS_PTR])); } + set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenMemoryCopySetDest"](this[THIS_PTR], strToStack(segment))); } + + get dest(): ExpressionRef { return BinaryenObj["_BinaryenMemoryInitGetDest"](this[THIS_PTR]); } + set dest(destExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryInitSetDest"](this[THIS_PTR], destExpr); } + + get offset(): ExpressionRef { return BinaryenObj["_BinaryenMemoryInitGetOffset"](this[THIS_PTR]); } + set offset(offsetExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryInitSetOffset"](this[THIS_PTR], offsetExpr); } + + get size(): ExpressionRef { return BinaryenObj["_BinaryenMemoryInitGetSize"](this[THIS_PTR]); } + set size(sizeExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryInitGetSize"](this[THIS_PTR], sizeExpr); } +} + + + +export class DataDrop extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.DataDrop, expr); + } + + get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenDataDropGetSegment"](this[THIS_PTR])); } + set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenDataDropSetSegment"](this[THIS_PTR], strToStack(segment))); } +} diff --git a/ts/src/globals.ts b/ts/src/globals.ts index d01987297f2..f133e1345ec 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -63,6 +63,18 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Fri, 8 May 2026 15:40:47 -0400 Subject: [PATCH 167/247] refactor: move Operation enum back to constants --- ts/src/classes/expression/memories.ts | 4 +- ts/src/constants.ts | 476 +++++++++++++++++ ts/src/services/expression-builder/-utils.ts | 4 +- .../services/expression-builder/Operation.ts | 481 ------------------ ts/src/services/expression-builder/f32.ts | 4 +- ts/src/services/expression-builder/f32x4.ts | 6 +- ts/src/services/expression-builder/f64.ts | 4 +- ts/src/services/expression-builder/f64x2.ts | 6 +- ts/src/services/expression-builder/generic.ts | 4 +- ts/src/services/expression-builder/i16x8.ts | 6 +- ts/src/services/expression-builder/i32.ts | 4 +- ts/src/services/expression-builder/i32x4.ts | 6 +- ts/src/services/expression-builder/i64.ts | 4 +- ts/src/services/expression-builder/i64x2.ts | 6 +- ts/src/services/expression-builder/i8x16.ts | 8 +- .../services/expression-builder/reference.ts | 8 +- ts/src/services/expression-builder/v128.ts | 4 +- 17 files changed, 505 insertions(+), 530 deletions(-) delete mode 100644 ts/src/services/expression-builder/Operation.ts diff --git a/ts/src/classes/expression/memories.ts b/ts/src/classes/expression/memories.ts index 043f92b02a1..5f30834d6e4 100644 --- a/ts/src/classes/expression/memories.ts +++ b/ts/src/classes/expression/memories.ts @@ -11,11 +11,9 @@ import { ExpressionId, type ExpressionRef, type MemoryOrder, + type Operation, type Type, } from "../../constants.ts"; -import type { - Operation, -} from "../../services/expression-builder/Operation.ts"; import { Expression, } from "./Expression.ts"; diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 51ff71b590b..d45c13c7586 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -243,6 +243,482 @@ export enum ExternalKind { ExternalFunction = BinaryenObj["_BinaryenExternalFunction"](), } +/** + * Operations + * @see https://webassembly.github.io/spec/core/exec/numerics.html + */ +export enum Operation { + // ### Control Operations ### // + BrOnNull = BinaryenObj["_BinaryenBrOnNull"](), + BrOnNonNull = BinaryenObj["_BinaryenBrOnNonNull"](), + BrOnCast = BinaryenObj["_BinaryenBrOnCast"](), + BrOnCastFail = BinaryenObj["_BinaryenBrOnCastFail"](), + + // ### Memory Operations ### // + Load8x8SVec128 = BinaryenObj["_BinaryenLoad8x8SVec128"](), + Load8x8UVec128 = BinaryenObj["_BinaryenLoad8x8UVec128"](), + Load16x4SVec128 = BinaryenObj["_BinaryenLoad16x4SVec128"](), + Load16x4UVec128 = BinaryenObj["_BinaryenLoad16x4UVec128"](), + Load32x2SVec128 = BinaryenObj["_BinaryenLoad32x2SVec128"](), + Load32x2UVec128 = BinaryenObj["_BinaryenLoad32x2UVec128"](), + Load8SplatVec128 = BinaryenObj["_BinaryenLoad8SplatVec128"](), + Load16SplatVec128 = BinaryenObj["_BinaryenLoad16SplatVec128"](), + Load32SplatVec128 = BinaryenObj["_BinaryenLoad32SplatVec128"](), + Load64SplatVec128 = BinaryenObj["_BinaryenLoad64SplatVec128"](), + Load32ZeroVec128 = BinaryenObj["_BinaryenLoad32ZeroVec128"](), + Load64ZeroVec128 = BinaryenObj["_BinaryenLoad64ZeroVec128"](), + Load8LaneVec128 = BinaryenObj["_BinaryenLoad8LaneVec128"](), + Load16LaneVec128 = BinaryenObj["_BinaryenLoad16LaneVec128"](), + Load32LaneVec128 = BinaryenObj["_BinaryenLoad32LaneVec128"](), + Load64LaneVec128 = BinaryenObj["_BinaryenLoad64LaneVec128"](), + Store8LaneVec128 = BinaryenObj["_BinaryenStore8LaneVec128"](), + Store16LaneVec128 = BinaryenObj["_BinaryenStore16LaneVec128"](), + Store32LaneVec128 = BinaryenObj["_BinaryenStore32LaneVec128"](), + Store64LaneVec128 = BinaryenObj["_BinaryenStore64LaneVec128"](), + + // ### Reference Operations ### // + RefAsNonNull = BinaryenObj["_BinaryenRefAsNonNull"](), + RefAsExternInternalize = BinaryenObj["_BinaryenRefAsExternInternalize"](), + RefAsExternExternalize = BinaryenObj["_BinaryenRefAsExternExternalize"](), + RefAsAnyConvertExtern = BinaryenObj["_BinaryenRefAsAnyConvertExtern"](), + RefAsExternConvertAny = BinaryenObj["_BinaryenRefAsExternConvertAny"](), + + // ### Integer Operations ### // + // #### unop #### // + ClzInt32 = BinaryenObj["_BinaryenClzInt32"](), + ClzInt64 = BinaryenObj["_BinaryenClzInt64"](), + CtzInt32 = BinaryenObj["_BinaryenCtzInt32"](), + CtzInt64 = BinaryenObj["_BinaryenCtzInt64"](), + PopcntInt32 = BinaryenObj["_BinaryenPopcntInt32"](), + PopcntInt64 = BinaryenObj["_BinaryenPopcntInt64"](), + ExtendS8Int32 = BinaryenObj["_BinaryenExtendS8Int32"](), + ExtendS8Int64 = BinaryenObj["_BinaryenExtendS8Int64"](), + ExtendS16Int32 = BinaryenObj["_BinaryenExtendS16Int32"](), + ExtendS16Int64 = BinaryenObj["_BinaryenExtendS16Int64"](), + ExtendS32Int64 = BinaryenObj["_BinaryenExtendS32Int64"](), + // #### binop #### // + AddInt32 = BinaryenObj["_BinaryenAddInt32"](), + AddInt64 = BinaryenObj["_BinaryenAddInt64"](), + SubInt32 = BinaryenObj["_BinaryenSubInt32"](), + SubInt64 = BinaryenObj["_BinaryenSubInt64"](), + MulInt32 = BinaryenObj["_BinaryenMulInt32"](), + MulInt64 = BinaryenObj["_BinaryenMulInt64"](), + DivSInt32 = BinaryenObj["_BinaryenDivSInt32"](), + DivSInt64 = BinaryenObj["_BinaryenDivSInt64"](), + DivUInt32 = BinaryenObj["_BinaryenDivUInt32"](), + DivUInt64 = BinaryenObj["_BinaryenDivUInt64"](), + RemSInt32 = BinaryenObj["_BinaryenRemSInt32"](), + RemSInt64 = BinaryenObj["_BinaryenRemSInt64"](), + RemUInt32 = BinaryenObj["_BinaryenRemUInt32"](), + RemUInt64 = BinaryenObj["_BinaryenRemUInt64"](), + AndInt32 = BinaryenObj["_BinaryenAndInt32"](), + AndInt64 = BinaryenObj["_BinaryenAndInt64"](), + OrInt32 = BinaryenObj["_BinaryenOrInt32"](), + OrInt64 = BinaryenObj["_BinaryenOrInt64"](), + XorInt32 = BinaryenObj["_BinaryenXorInt32"](), + XorInt64 = BinaryenObj["_BinaryenXorInt64"](), + ShlInt32 = BinaryenObj["_BinaryenShlInt32"](), + ShlInt64 = BinaryenObj["_BinaryenShlInt64"](), + ShrSInt32 = BinaryenObj["_BinaryenShrSInt32"](), + ShrSInt64 = BinaryenObj["_BinaryenShrSInt64"](), + ShrUInt32 = BinaryenObj["_BinaryenShrUInt32"](), + ShrUInt64 = BinaryenObj["_BinaryenShrUInt64"](), + RotLInt32 = BinaryenObj["_BinaryenRotLInt32"](), + RotLInt64 = BinaryenObj["_BinaryenRotLInt64"](), + RotRInt32 = BinaryenObj["_BinaryenRotRInt32"](), + RotRInt64 = BinaryenObj["_BinaryenRotRInt64"](), + // #### testop #### // + EqZInt32 = BinaryenObj["_BinaryenEqZInt32"](), + EqZInt64 = BinaryenObj["_BinaryenEqZInt64"](), + // #### relop #### // + EqInt32 = BinaryenObj["_BinaryenEqInt32"](), + EqInt64 = BinaryenObj["_BinaryenEqInt64"](), + NeInt32 = BinaryenObj["_BinaryenNeInt32"](), + NeInt64 = BinaryenObj["_BinaryenNeInt64"](), + LtSInt32 = BinaryenObj["_BinaryenLtSInt32"](), + LtSInt64 = BinaryenObj["_BinaryenLtSInt64"](), + LtUInt32 = BinaryenObj["_BinaryenLtUInt32"](), + LtUInt64 = BinaryenObj["_BinaryenLtUInt64"](), + GtSInt32 = BinaryenObj["_BinaryenGtSInt32"](), + GtSInt64 = BinaryenObj["_BinaryenGtSInt64"](), + GtUInt32 = BinaryenObj["_BinaryenGtUInt32"](), + GtUInt64 = BinaryenObj["_BinaryenGtUInt64"](), + LeSInt32 = BinaryenObj["_BinaryenLeSInt32"](), + LeSInt64 = BinaryenObj["_BinaryenLeSInt64"](), + LeUInt32 = BinaryenObj["_BinaryenLeUInt32"](), + LeUInt64 = BinaryenObj["_BinaryenLeUInt64"](), + GeSInt32 = BinaryenObj["_BinaryenGeSInt32"](), + GeSInt64 = BinaryenObj["_BinaryenGeSInt64"](), + GeUInt32 = BinaryenObj["_BinaryenGeUInt32"](), + GeUInt64 = BinaryenObj["_BinaryenGeUInt64"](), + + // ### Floating-Point Operations ### // + // #### unop #### // + AbsFloat32 = BinaryenObj["_BinaryenAbsFloat32"](), + AbsFloat64 = BinaryenObj["_BinaryenAbsFloat64"](), + NegFloat32 = BinaryenObj["_BinaryenNegFloat32"](), + NegFloat64 = BinaryenObj["_BinaryenNegFloat64"](), + SqrtFloat32 = BinaryenObj["_BinaryenSqrtFloat32"](), + SqrtFloat64 = BinaryenObj["_BinaryenSqrtFloat64"](), + CeilFloat32 = BinaryenObj["_BinaryenCeilFloat32"](), + CeilFloat64 = BinaryenObj["_BinaryenCeilFloat64"](), + FloorFloat32 = BinaryenObj["_BinaryenFloorFloat32"](), + FloorFloat64 = BinaryenObj["_BinaryenFloorFloat64"](), + TruncFloat32 = BinaryenObj["_BinaryenTruncFloat32"](), + TruncFloat64 = BinaryenObj["_BinaryenTruncFloat64"](), + NearestFloat32 = BinaryenObj["_BinaryenNearestFloat32"](), + NearestFloat64 = BinaryenObj["_BinaryenNearestFloat64"](), + // #### binop #### // + AddFloat32 = BinaryenObj["_BinaryenAddFloat32"](), + AddFloat64 = BinaryenObj["_BinaryenAddFloat64"](), + SubFloat32 = BinaryenObj["_BinaryenSubFloat32"](), + SubFloat64 = BinaryenObj["_BinaryenSubFloat64"](), + MulFloat32 = BinaryenObj["_BinaryenMulFloat32"](), + MulFloat64 = BinaryenObj["_BinaryenMulFloat64"](), + DivFloat32 = BinaryenObj["_BinaryenDivFloat32"](), + DivFloat64 = BinaryenObj["_BinaryenDivFloat64"](), + MinFloat32 = BinaryenObj["_BinaryenMinFloat32"](), + MinFloat64 = BinaryenObj["_BinaryenMinFloat64"](), + MaxFloat32 = BinaryenObj["_BinaryenMaxFloat32"](), + MaxFloat64 = BinaryenObj["_BinaryenMaxFloat64"](), + CopySignFloat32 = BinaryenObj["_BinaryenCopySignFloat32"](), + CopySignFloat64 = BinaryenObj["_BinaryenCopySignFloat64"](), + // #### relop #### // + EqFloat32 = BinaryenObj["_BinaryenEqFloat32"](), + EqFloat64 = BinaryenObj["_BinaryenEqFloat64"](), + NeFloat32 = BinaryenObj["_BinaryenNeFloat32"](), + NeFloat64 = BinaryenObj["_BinaryenNeFloat64"](), + LtFloat32 = BinaryenObj["_BinaryenLtFloat32"](), + LtFloat64 = BinaryenObj["_BinaryenLtFloat64"](), + GtFloat32 = BinaryenObj["_BinaryenGtFloat32"](), + GtFloat64 = BinaryenObj["_BinaryenGtFloat64"](), + LeFloat32 = BinaryenObj["_BinaryenLeFloat32"](), + LeFloat64 = BinaryenObj["_BinaryenLeFloat64"](), + GeFloat32 = BinaryenObj["_BinaryenGeFloat32"](), + GeFloat64 = BinaryenObj["_BinaryenGeFloat64"](), + + // ### Conversions ### // + ExtendSInt32 = BinaryenObj["_BinaryenExtendSInt32"](), + ExtendUInt32 = BinaryenObj["_BinaryenExtendUInt32"](), + WrapInt64 = BinaryenObj["_BinaryenWrapInt64"](), + TruncSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSFloat32ToInt32"](), + TruncSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSFloat32ToInt64"](), + TruncSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSFloat64ToInt32"](), + TruncSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSFloat64ToInt64"](), + TruncUFloat32ToInt32 = BinaryenObj["_BinaryenTruncUFloat32ToInt32"](), + TruncUFloat32ToInt64 = BinaryenObj["_BinaryenTruncUFloat32ToInt64"](), + TruncUFloat64ToInt32 = BinaryenObj["_BinaryenTruncUFloat64ToInt32"](), + TruncUFloat64ToInt64 = BinaryenObj["_BinaryenTruncUFloat64ToInt64"](), + TruncSatSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt32"](), + TruncSatSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt64"](), + TruncSatSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt32"](), + TruncSatSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt64"](), + TruncSatUFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt32"](), + TruncSatUFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt64"](), + TruncSatUFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt32"](), + TruncSatUFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt64"](), + ConvertSInt32ToFloat32 = BinaryenObj["_BinaryenConvertSInt32ToFloat32"](), + ConvertSInt32ToFloat64 = BinaryenObj["_BinaryenConvertSInt32ToFloat64"](), + ConvertSInt64ToFloat32 = BinaryenObj["_BinaryenConvertSInt64ToFloat32"](), + ConvertSInt64ToFloat64 = BinaryenObj["_BinaryenConvertSInt64ToFloat64"](), + ConvertUInt32ToFloat32 = BinaryenObj["_BinaryenConvertUInt32ToFloat32"](), + ConvertUInt32ToFloat64 = BinaryenObj["_BinaryenConvertUInt32ToFloat64"](), + ConvertUInt64ToFloat32 = BinaryenObj["_BinaryenConvertUInt64ToFloat32"](), + ConvertUInt64ToFloat64 = BinaryenObj["_BinaryenConvertUInt64ToFloat64"](), + ReinterpretInt32 = BinaryenObj["_BinaryenReinterpretInt32"](), + ReinterpretInt64 = BinaryenObj["_BinaryenReinterpretInt64"](), + ReinterpretFloat32 = BinaryenObj["_BinaryenReinterpretFloat32"](), + ReinterpretFloat64 = BinaryenObj["_BinaryenReinterpretFloat64"](), + PromoteFloat32 = BinaryenObj["_BinaryenPromoteFloat32"](), + DemoteFloat64 = BinaryenObj["_BinaryenDemoteFloat64"](), + + // ### Vector Operations ### // + // #### vvunop #### // + NotVec128 = BinaryenObj["_BinaryenNotVec128"](), + // #### vvbinop #### // + AndVec128 = BinaryenObj["_BinaryenAndVec128"](), + AndNotVec128 = BinaryenObj["_BinaryenAndNotVec128"](), + OrVec128 = BinaryenObj["_BinaryenOrVec128"](), + XorVec128 = BinaryenObj["_BinaryenXorVec128"](), + // #### vvternop #### // + BitselectVec128 = BinaryenObj["_BinaryenBitselectVec128"](), + // #### vvtestop #### // + AnyTrueVec128 = BinaryenObj["_BinaryenAnyTrueVec128"](), + // #### vunop_i #### // + AbsVecI8x16 = BinaryenObj["_BinaryenAbsVecI8x16"](), + AbsVecI16x8 = BinaryenObj["_BinaryenAbsVecI16x8"](), + AbsVecI32x4 = BinaryenObj["_BinaryenAbsVecI32x4"](), + AbsVecI64x2 = BinaryenObj["_BinaryenAbsVecI64x2"](), + NegVecI8x16 = BinaryenObj["_BinaryenNegVecI8x16"](), + NegVecI16x8 = BinaryenObj["_BinaryenNegVecI16x8"](), + NegVecI32x4 = BinaryenObj["_BinaryenNegVecI32x4"](), + NegVecI64x2 = BinaryenObj["_BinaryenNegVecI64x2"](), + PopcntVecI8x16 = BinaryenObj["_BinaryenPopcntVecI8x16"](), + // #### vunop_f #### // + AbsVecF32x4 = BinaryenObj["_BinaryenAbsVecF32x4"](), + AbsVecF64x2 = BinaryenObj["_BinaryenAbsVecF64x2"](), + NegVecF32x4 = BinaryenObj["_BinaryenNegVecF32x4"](), + NegVecF64x2 = BinaryenObj["_BinaryenNegVecF64x2"](), + SqrtVecF32x4 = BinaryenObj["_BinaryenSqrtVecF32x4"](), + SqrtVecF64x2 = BinaryenObj["_BinaryenSqrtVecF64x2"](), + CeilVecF32x4 = BinaryenObj["_BinaryenCeilVecF32x4"](), + CeilVecF64x2 = BinaryenObj["_BinaryenCeilVecF64x2"](), + FloorVecF32x4 = BinaryenObj["_BinaryenFloorVecF32x4"](), + FloorVecF64x2 = BinaryenObj["_BinaryenFloorVecF64x2"](), + TruncVecF32x4 = BinaryenObj["_BinaryenTruncVecF32x4"](), + TruncVecF64x2 = BinaryenObj["_BinaryenTruncVecF64x2"](), + NearestVecF32x4 = BinaryenObj["_BinaryenNearestVecF32x4"](), + NearestVecF64x2 = BinaryenObj["_BinaryenNearestVecF64x2"](), + // #### vbinop_i #### // + AddVecI8x16 = BinaryenObj["_BinaryenAddVecI8x16"](), + AddVecI16x8 = BinaryenObj["_BinaryenAddVecI16x8"](), + AddVecI32x4 = BinaryenObj["_BinaryenAddVecI32x4"](), + AddVecI64x2 = BinaryenObj["_BinaryenAddVecI64x2"](), + SubVecI8x16 = BinaryenObj["_BinaryenSubVecI8x16"](), + SubVecI16x8 = BinaryenObj["_BinaryenSubVecI16x8"](), + SubVecI32x4 = BinaryenObj["_BinaryenSubVecI32x4"](), + SubVecI64x2 = BinaryenObj["_BinaryenSubVecI64x2"](), + AddSatSVecI8x16 = BinaryenObj["_BinaryenAddSatSVecI8x16"](), + AddSatSVecI16x8 = BinaryenObj["_BinaryenAddSatSVecI16x8"](), + AddSatUVecI8x16 = BinaryenObj["_BinaryenAddSatUVecI8x16"](), + AddSatUVecI16x8 = BinaryenObj["_BinaryenAddSatUVecI16x8"](), + SubSatSVecI8x16 = BinaryenObj["_BinaryenSubSatSVecI8x16"](), + SubSatSVecI16x8 = BinaryenObj["_BinaryenSubSatSVecI16x8"](), + SubSatUVecI8x16 = BinaryenObj["_BinaryenSubSatUVecI8x16"](), + SubSatUVecI16x8 = BinaryenObj["_BinaryenSubSatUVecI16x8"](), + MulVecI16x8 = BinaryenObj["_BinaryenMulVecI16x8"](), + MulVecI32x4 = BinaryenObj["_BinaryenMulVecI32x4"](), + MulVecI64x2 = BinaryenObj["_BinaryenMulVecI64x2"](), + AvgrUVecI8x16 = BinaryenObj["_BinaryenAvgrUVecI8x16"](), + AvgrUVecI16x8 = BinaryenObj["_BinaryenAvgrUVecI16x8"](), + Q15MulrSatSVecI16x8 = BinaryenObj["_BinaryenQ15MulrSatSVecI16x8"](), + RelaxedQ15MulrSVecI16x8 = BinaryenObj["_BinaryenRelaxedQ15MulrSVecI16x8"](), + MinSVecI8x16 = BinaryenObj["_BinaryenMinSVecI8x16"](), + MinSVecI16x8 = BinaryenObj["_BinaryenMinSVecI16x8"](), + MinSVecI32x4 = BinaryenObj["_BinaryenMinSVecI32x4"](), + MinUVecI8x16 = BinaryenObj["_BinaryenMinUVecI8x16"](), + MinUVecI16x8 = BinaryenObj["_BinaryenMinUVecI16x8"](), + MinUVecI32x4 = BinaryenObj["_BinaryenMinUVecI32x4"](), + MaxSVecI8x16 = BinaryenObj["_BinaryenMaxSVecI8x16"](), + MaxSVecI16x8 = BinaryenObj["_BinaryenMaxSVecI16x8"](), + MaxSVecI32x4 = BinaryenObj["_BinaryenMaxSVecI32x4"](), + MaxUVecI8x16 = BinaryenObj["_BinaryenMaxUVecI8x16"](), + MaxUVecI16x8 = BinaryenObj["_BinaryenMaxUVecI16x8"](), + MaxUVecI32x4 = BinaryenObj["_BinaryenMaxUVecI32x4"](), + // #### vbinop_f #### // + AddVecF32x4 = BinaryenObj["_BinaryenAddVecF32x4"](), + AddVecF64x2 = BinaryenObj["_BinaryenAddVecF64x2"](), + SubVecF32x4 = BinaryenObj["_BinaryenSubVecF32x4"](), + SubVecF64x2 = BinaryenObj["_BinaryenSubVecF64x2"](), + MulVecF32x4 = BinaryenObj["_BinaryenMulVecF32x4"](), + MulVecF64x2 = BinaryenObj["_BinaryenMulVecF64x2"](), + DivVecF32x4 = BinaryenObj["_BinaryenDivVecF32x4"](), + DivVecF64x2 = BinaryenObj["_BinaryenDivVecF64x2"](), + MinVecF32x4 = BinaryenObj["_BinaryenMinVecF32x4"](), + MinVecF64x2 = BinaryenObj["_BinaryenMinVecF64x2"](), + MaxVecF32x4 = BinaryenObj["_BinaryenMaxVecF32x4"](), + MaxVecF64x2 = BinaryenObj["_BinaryenMaxVecF64x2"](), + PMinVecF32x4 = BinaryenObj["_BinaryenPMinVecF32x4"](), + PMinVecF64x2 = BinaryenObj["_BinaryenPMinVecF64x2"](), + PMaxVecF32x4 = BinaryenObj["_BinaryenPMaxVecF32x4"](), + PMaxVecF64x2 = BinaryenObj["_BinaryenPMaxVecF64x2"](), + RelaxedMinVecF32x4 = BinaryenObj["_BinaryenRelaxedMinVecF32x4"](), + RelaxedMinVecF64x2 = BinaryenObj["_BinaryenRelaxedMinVecF64x2"](), + RelaxedMaxVecF32x4 = BinaryenObj["_BinaryenRelaxedMaxVecF32x4"](), + RelaxedMaxVecF64x2 = BinaryenObj["_BinaryenRelaxedMaxVecF64x2"](), + // #### vternop_i #### // + RelaxedLaneselectI8x16 = BinaryenObj["_BinaryenRelaxedLaneselectI8x16"](), + RelaxedLaneselectI16x8 = BinaryenObj["_BinaryenRelaxedLaneselectI16x8"](), + RelaxedLaneselectI32x4 = BinaryenObj["_BinaryenRelaxedLaneselectI32x4"](), + RelaxedLaneselectI64x2 = BinaryenObj["_BinaryenRelaxedLaneselectI64x2"](), + // #### vternop_f #### // + RelaxedMaddVecF32x4 = BinaryenObj["_BinaryenRelaxedMaddVecF32x4"](), + RelaxedMaddVecF64x2 = BinaryenObj["_BinaryenRelaxedMaddVecF64x2"](), + RelaxedNmaddVecF32x4 = BinaryenObj["_BinaryenRelaxedNmaddVecF32x4"](), + RelaxedNmaddVecF64x2 = BinaryenObj["_BinaryenRelaxedNmaddVecF64x2"](), + // #### vtestop_i #### // + AllTrueVecI8x16 = BinaryenObj["_BinaryenAllTrueVecI8x16"](), + AllTrueVecI16x8 = BinaryenObj["_BinaryenAllTrueVecI16x8"](), + AllTrueVecI32x4 = BinaryenObj["_BinaryenAllTrueVecI32x4"](), + AllTrueVecI64x2 = BinaryenObj["_BinaryenAllTrueVecI64x2"](), + // #### vrelop_i #### // + EqVecI8x16 = BinaryenObj["_BinaryenEqVecI8x16"](), + EqVecI16x8 = BinaryenObj["_BinaryenEqVecI16x8"](), + EqVecI32x4 = BinaryenObj["_BinaryenEqVecI32x4"](), + EqVecI64x2 = BinaryenObj["_BinaryenEqVecI64x2"](), + NeVecI8x16 = BinaryenObj["_BinaryenNeVecI8x16"](), + NeVecI16x8 = BinaryenObj["_BinaryenNeVecI16x8"](), + NeVecI32x4 = BinaryenObj["_BinaryenNeVecI32x4"](), + NeVecI64x2 = BinaryenObj["_BinaryenNeVecI64x2"](), + LtSVecI8x16 = BinaryenObj["_BinaryenLtSVecI8x16"](), + LtSVecI16x8 = BinaryenObj["_BinaryenLtSVecI16x8"](), + LtSVecI32x4 = BinaryenObj["_BinaryenLtSVecI32x4"](), + LtSVecI64x2 = BinaryenObj["_BinaryenLtSVecI64x2"](), + LtUVecI8x16 = BinaryenObj["_BinaryenLtUVecI8x16"](), + LtUVecI16x8 = BinaryenObj["_BinaryenLtUVecI16x8"](), + LtUVecI32x4 = BinaryenObj["_BinaryenLtUVecI32x4"](), + // LtUVecI64x2 // not supported; see #414 + GtSVecI8x16 = BinaryenObj["_BinaryenGtSVecI8x16"](), + GtSVecI16x8 = BinaryenObj["_BinaryenGtSVecI16x8"](), + GtSVecI32x4 = BinaryenObj["_BinaryenGtSVecI32x4"](), + GtSVecI64x2 = BinaryenObj["_BinaryenGtSVecI64x2"](), + GtUVecI8x16 = BinaryenObj["_BinaryenGtUVecI8x16"](), + GtUVecI16x8 = BinaryenObj["_BinaryenGtUVecI16x8"](), + GtUVecI32x4 = BinaryenObj["_BinaryenGtUVecI32x4"](), + // GtUVecI64x2 // not supported; see #414 + LeSVecI8x16 = BinaryenObj["_BinaryenLeSVecI8x16"](), + LeSVecI16x8 = BinaryenObj["_BinaryenLeSVecI16x8"](), + LeSVecI32x4 = BinaryenObj["_BinaryenLeSVecI32x4"](), + LeSVecI64x2 = BinaryenObj["_BinaryenLeSVecI64x2"](), + LeUVecI8x16 = BinaryenObj["_BinaryenLeUVecI8x16"](), + LeUVecI16x8 = BinaryenObj["_BinaryenLeUVecI16x8"](), + LeUVecI32x4 = BinaryenObj["_BinaryenLeUVecI32x4"](), + // LeUVecI64x2 // not supported; see #414 + GeSVecI8x16 = BinaryenObj["_BinaryenGeSVecI8x16"](), + GeSVecI16x8 = BinaryenObj["_BinaryenGeSVecI16x8"](), + GeSVecI32x4 = BinaryenObj["_BinaryenGeSVecI32x4"](), + GeSVecI64x2 = BinaryenObj["_BinaryenGeSVecI64x2"](), + GeUVecI8x16 = BinaryenObj["_BinaryenGeUVecI8x16"](), + GeUVecI16x8 = BinaryenObj["_BinaryenGeUVecI16x8"](), + GeUVecI32x4 = BinaryenObj["_BinaryenGeUVecI32x4"](), + // GeUVecI64x2 // not supported; see #414 + // #### vrelop_f #### // + EqVecF32x4 = BinaryenObj["_BinaryenEqVecF32x4"](), + EqVecF64x2 = BinaryenObj["_BinaryenEqVecF64x2"](), + NeVecF32x4 = BinaryenObj["_BinaryenNeVecF32x4"](), + NeVecF64x2 = BinaryenObj["_BinaryenNeVecF64x2"](), + LtVecF32x4 = BinaryenObj["_BinaryenLtVecF32x4"](), + LtVecF64x2 = BinaryenObj["_BinaryenLtVecF64x2"](), + GtVecF32x4 = BinaryenObj["_BinaryenGtVecF32x4"](), + GtVecF64x2 = BinaryenObj["_BinaryenGtVecF64x2"](), + LeVecF32x4 = BinaryenObj["_BinaryenLeVecF32x4"](), + LeVecF64x2 = BinaryenObj["_BinaryenLeVecF64x2"](), + GeVecF32x4 = BinaryenObj["_BinaryenGeVecF32x4"](), + GeVecF64x2 = BinaryenObj["_BinaryenGeVecF64x2"](), + // #### vshiftop #### // + ShlVecI8x16 = BinaryenObj["_BinaryenShlVecI8x16"](), + ShlVecI16x8 = BinaryenObj["_BinaryenShlVecI16x8"](), + ShlVecI32x4 = BinaryenObj["_BinaryenShlVecI32x4"](), + ShlVecI64x2 = BinaryenObj["_BinaryenShlVecI64x2"](), + ShrSVecI8x16 = BinaryenObj["_BinaryenShrSVecI8x16"](), + ShrSVecI16x8 = BinaryenObj["_BinaryenShrSVecI16x8"](), + ShrSVecI32x4 = BinaryenObj["_BinaryenShrSVecI32x4"](), + ShrSVecI64x2 = BinaryenObj["_BinaryenShrSVecI64x2"](), + ShrUVecI8x16 = BinaryenObj["_BinaryenShrUVecI8x16"](), + ShrUVecI16x8 = BinaryenObj["_BinaryenShrUVecI16x8"](), + ShrUVecI32x4 = BinaryenObj["_BinaryenShrUVecI32x4"](), + ShrUVecI64x2 = BinaryenObj["_BinaryenShrUVecI64x2"](), + // #### bitmask #### // + BitmaskVecI8x16 = BinaryenObj["_BinaryenBitmaskVecI8x16"](), + BitmaskVecI16x8 = BinaryenObj["_BinaryenBitmaskVecI16x8"](), + BitmaskVecI32x4 = BinaryenObj["_BinaryenBitmaskVecI32x4"](), + BitmaskVecI64x2 = BinaryenObj["_BinaryenBitmaskVecI64x2"](), + // #### vswizzleop #### // + SwizzleVecI8x16 = BinaryenObj["_BinaryenSwizzleVecI8x16"](), + RelaxedSwizzleVecI8x16 = BinaryenObj["_BinaryenRelaxedSwizzleVecI8x16"](), + // #### vextunop #### // + ExtAddPairwiseSVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseSVecI8x16ToI16x8"](), + ExtAddPairwiseSVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseSVecI16x8ToI32x4"](), + ExtAddPairwiseUVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseUVecI8x16ToI16x8"](), + ExtAddPairwiseUVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseUVecI16x8ToI32x4"](), + // #### vextbinop #### // + ExtMulLowSVecI16x8 = BinaryenObj["_BinaryenExtMulLowSVecI16x8"](), + ExtMulLowSVecI32x4 = BinaryenObj["_BinaryenExtMulLowSVecI32x4"](), + ExtMulLowSVecI64x2 = BinaryenObj["_BinaryenExtMulLowSVecI64x2"](), + ExtMulLowUVecI16x8 = BinaryenObj["_BinaryenExtMulLowUVecI16x8"](), + ExtMulLowUVecI32x4 = BinaryenObj["_BinaryenExtMulLowUVecI32x4"](), + ExtMulLowUVecI64x2 = BinaryenObj["_BinaryenExtMulLowUVecI64x2"](), + ExtMulHighSVecI16x8 = BinaryenObj["_BinaryenExtMulHighSVecI16x8"](), + ExtMulHighSVecI32x4 = BinaryenObj["_BinaryenExtMulHighSVecI32x4"](), + ExtMulHighSVecI64x2 = BinaryenObj["_BinaryenExtMulHighSVecI64x2"](), + ExtMulHighUVecI16x8 = BinaryenObj["_BinaryenExtMulHighUVecI16x8"](), + ExtMulHighUVecI32x4 = BinaryenObj["_BinaryenExtMulHighUVecI32x4"](), + ExtMulHighUVecI64x2 = BinaryenObj["_BinaryenExtMulHighUVecI64x2"](), + DotSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenDotSVecI16x8ToVecI32x4"](), + RelaxedDotI8x16I7x16SToVecI16x8 = BinaryenObj["_BinaryenRelaxedDotI8x16I7x16SToVecI16x8"](), + RelaxedDotI8x16I7x16AddSToVecI32x4 = BinaryenObj["_BinaryenRelaxedDotI8x16I7x16AddSToVecI32x4"](), + // #### narrow #### // + NarrowSVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowSVecI16x8ToVecI8x16"](), + NarrowSVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowSVecI32x4ToVecI16x8"](), + NarrowUVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowUVecI16x8ToVecI8x16"](), + NarrowUVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowUVecI32x4ToVecI16x8"](), + // #### vcvtop #### // + ExtendLowSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowSVecI8x16ToVecI16x8"](), + ExtendLowSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowSVecI16x8ToVecI32x4"](), + ExtendLowSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowSVecI32x4ToVecI64x2"](), + ExtendLowUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowUVecI8x16ToVecI16x8"](), + ExtendLowUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowUVecI16x8ToVecI32x4"](), + ExtendLowUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowUVecI32x4ToVecI64x2"](), + ExtendHighSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighSVecI8x16ToVecI16x8"](), + ExtendHighSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighSVecI16x8ToVecI32x4"](), + ExtendHighSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighSVecI32x4ToVecI64x2"](), + ExtendHighUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighUVecI8x16ToVecI16x8"](), + ExtendHighUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighUVecI16x8ToVecI32x4"](), + ExtendHighUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighUVecI32x4ToVecI64x2"](), + ConvertSVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertSVecI32x4ToVecF32x4"](), + ConvertUVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertUVecI32x4ToVecF32x4"](), + ConvertLowSVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowSVecI32x4ToVecF64x2"](), + ConvertLowUVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowUVecI32x4ToVecF64x2"](), + TruncSatSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatSVecF32x4ToVecI32x4"](), + TruncSatUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatUVecF32x4ToVecI32x4"](), + TruncSatZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroSVecF64x2ToVecI32x4"](), + TruncSatZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroUVecF64x2ToVecI32x4"](), + RelaxedTruncSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncSVecF32x4ToVecI32x4"](), + RelaxedTruncUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncUVecF32x4ToVecI32x4"](), + RelaxedTruncZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroSVecF64x2ToVecI32x4"](), + RelaxedTruncZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4"](), + DemoteZeroVecF64x2ToVecF32x4 = BinaryenObj["_BinaryenDemoteZeroVecF64x2ToVecF32x4"](), + PromoteLowVecF32x4ToVecF64x2 = BinaryenObj["_BinaryenPromoteLowVecF32x4ToVecF64x2"](), + // #### splat #### // + SplatVecI8x16 = BinaryenObj["_BinaryenSplatVecI8x16"](), + SplatVecI16x8 = BinaryenObj["_BinaryenSplatVecI16x8"](), + SplatVecI32x4 = BinaryenObj["_BinaryenSplatVecI32x4"](), + SplatVecI64x2 = BinaryenObj["_BinaryenSplatVecI64x2"](), + SplatVecF32x4 = BinaryenObj["_BinaryenSplatVecF32x4"](), + SplatVecF64x2 = BinaryenObj["_BinaryenSplatVecF64x2"](), + // #### extract_lane #### // + ExtractLaneSVecI8x16 = BinaryenObj["_BinaryenExtractLaneSVecI8x16"](), + ExtractLaneSVecI16x8 = BinaryenObj["_BinaryenExtractLaneSVecI16x8"](), + ExtractLaneUVecI8x16 = BinaryenObj["_BinaryenExtractLaneUVecI8x16"](), + ExtractLaneUVecI16x8 = BinaryenObj["_BinaryenExtractLaneUVecI16x8"](), + ExtractLaneVecI32x4 = BinaryenObj["_BinaryenExtractLaneVecI32x4"](), + ExtractLaneVecI64x2 = BinaryenObj["_BinaryenExtractLaneVecI64x2"](), + ExtractLaneVecF32x4 = BinaryenObj["_BinaryenExtractLaneVecF32x4"](), + ExtractLaneVecF64x2 = BinaryenObj["_BinaryenExtractLaneVecF64x2"](), + // #### replace_lane #### // + ReplaceLaneVecI8x16 = BinaryenObj["_BinaryenReplaceLaneVecI8x16"](), + ReplaceLaneVecI16x8 = BinaryenObj["_BinaryenReplaceLaneVecI16x8"](), + ReplaceLaneVecI32x4 = BinaryenObj["_BinaryenReplaceLaneVecI32x4"](), + ReplaceLaneVecI64x2 = BinaryenObj["_BinaryenReplaceLaneVecI64x2"](), + ReplaceLaneVecF32x4 = BinaryenObj["_BinaryenReplaceLaneVecF32x4"](), + ReplaceLaneVecF64x2 = BinaryenObj["_BinaryenReplaceLaneVecF64x2"](), + + // ### Atomic Operations ### // + AtomicRMWAdd = BinaryenObj["_BinaryenAtomicRMWAdd"](), + AtomicRMWSub = BinaryenObj["_BinaryenAtomicRMWSub"](), + AtomicRMWAnd = BinaryenObj["_BinaryenAtomicRMWAnd"](), + AtomicRMWOr = BinaryenObj["_BinaryenAtomicRMWOr"](), + AtomicRMWXor = BinaryenObj["_BinaryenAtomicRMWXor"](), + AtomicRMWXchg = BinaryenObj["_BinaryenAtomicRMWXchg"](), + + // ### String Operations ### // + StringNewLossyUTF8Array = BinaryenObj["_BinaryenStringNewLossyUTF8Array"](), + StringNewWTF16Array = BinaryenObj["_BinaryenStringNewWTF16Array"](), + StringNewFromCodePoint = BinaryenObj["_BinaryenStringNewFromCodePoint"](), + StringMeasureUTF8 = BinaryenObj["_BinaryenStringMeasureUTF8"](), + StringMeasureWTF16 = BinaryenObj["_BinaryenStringMeasureWTF16"](), + StringEncodeLossyUTF8Array = BinaryenObj["_BinaryenStringEncodeLossyUTF8Array"](), + StringEncodeWTF16Array = BinaryenObj["_BinaryenStringEncodeWTF16Array"](), + StringEqEqual = BinaryenObj["_BinaryenStringEqEqual"](), + StringEqCompare = BinaryenObj["_BinaryenStringEqCompare"](), + + // ### WideInt Operations ### // + AddInt128 = BinaryenObj["_BinaryenAddInt128"](), + SubInt128 = BinaryenObj["_BinaryenSubInt128"](), + MulWideSInt64 = BinaryenObj["_BinaryenMulWideSInt64"](), + MulWideUInt64 = BinaryenObj["_BinaryenMulWideUInt64"](), +} + /** * [description] * @experimental diff --git a/ts/src/services/expression-builder/-utils.ts b/ts/src/services/expression-builder/-utils.ts index a78c5ae801c..90a85c5d332 100644 --- a/ts/src/services/expression-builder/-utils.ts +++ b/ts/src/services/expression-builder/-utils.ts @@ -12,11 +12,9 @@ import type { import { type ExpressionRef, MemoryOrder, + Operation, type Type, } from "../../constants.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/Operation.ts b/ts/src/services/expression-builder/Operation.ts deleted file mode 100644 index d96233b2bee..00000000000 --- a/ts/src/services/expression-builder/Operation.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { - BinaryenObj, -} from "../../-pre.ts"; - - - -/** - * Operations - * @see https://webassembly.github.io/spec/core/exec/numerics.html - */ -export enum Operation { - // ### Control Operations ### // - BrOnNull = BinaryenObj["_BinaryenBrOnNull"](), - BrOnNonNull = BinaryenObj["_BinaryenBrOnNonNull"](), - BrOnCast = BinaryenObj["_BinaryenBrOnCast"](), - BrOnCastFail = BinaryenObj["_BinaryenBrOnCastFail"](), - - // ### Memory Operations ### // - Load8x8SVec128 = BinaryenObj["_BinaryenLoad8x8SVec128"](), - Load8x8UVec128 = BinaryenObj["_BinaryenLoad8x8UVec128"](), - Load16x4SVec128 = BinaryenObj["_BinaryenLoad16x4SVec128"](), - Load16x4UVec128 = BinaryenObj["_BinaryenLoad16x4UVec128"](), - Load32x2SVec128 = BinaryenObj["_BinaryenLoad32x2SVec128"](), - Load32x2UVec128 = BinaryenObj["_BinaryenLoad32x2UVec128"](), - Load8SplatVec128 = BinaryenObj["_BinaryenLoad8SplatVec128"](), - Load16SplatVec128 = BinaryenObj["_BinaryenLoad16SplatVec128"](), - Load32SplatVec128 = BinaryenObj["_BinaryenLoad32SplatVec128"](), - Load64SplatVec128 = BinaryenObj["_BinaryenLoad64SplatVec128"](), - Load32ZeroVec128 = BinaryenObj["_BinaryenLoad32ZeroVec128"](), - Load64ZeroVec128 = BinaryenObj["_BinaryenLoad64ZeroVec128"](), - Load8LaneVec128 = BinaryenObj["_BinaryenLoad8LaneVec128"](), - Load16LaneVec128 = BinaryenObj["_BinaryenLoad16LaneVec128"](), - Load32LaneVec128 = BinaryenObj["_BinaryenLoad32LaneVec128"](), - Load64LaneVec128 = BinaryenObj["_BinaryenLoad64LaneVec128"](), - Store8LaneVec128 = BinaryenObj["_BinaryenStore8LaneVec128"](), - Store16LaneVec128 = BinaryenObj["_BinaryenStore16LaneVec128"](), - Store32LaneVec128 = BinaryenObj["_BinaryenStore32LaneVec128"](), - Store64LaneVec128 = BinaryenObj["_BinaryenStore64LaneVec128"](), - - // ### Reference Operations ### // - RefAsNonNull = BinaryenObj["_BinaryenRefAsNonNull"](), - RefAsExternInternalize = BinaryenObj["_BinaryenRefAsExternInternalize"](), - RefAsExternExternalize = BinaryenObj["_BinaryenRefAsExternExternalize"](), - RefAsAnyConvertExtern = BinaryenObj["_BinaryenRefAsAnyConvertExtern"](), - RefAsExternConvertAny = BinaryenObj["_BinaryenRefAsExternConvertAny"](), - - // ### Integer Operations ### // - // #### unop #### // - ClzInt32 = BinaryenObj["_BinaryenClzInt32"](), - ClzInt64 = BinaryenObj["_BinaryenClzInt64"](), - CtzInt32 = BinaryenObj["_BinaryenCtzInt32"](), - CtzInt64 = BinaryenObj["_BinaryenCtzInt64"](), - PopcntInt32 = BinaryenObj["_BinaryenPopcntInt32"](), - PopcntInt64 = BinaryenObj["_BinaryenPopcntInt64"](), - ExtendS8Int32 = BinaryenObj["_BinaryenExtendS8Int32"](), - ExtendS8Int64 = BinaryenObj["_BinaryenExtendS8Int64"](), - ExtendS16Int32 = BinaryenObj["_BinaryenExtendS16Int32"](), - ExtendS16Int64 = BinaryenObj["_BinaryenExtendS16Int64"](), - ExtendS32Int64 = BinaryenObj["_BinaryenExtendS32Int64"](), - // #### binop #### // - AddInt32 = BinaryenObj["_BinaryenAddInt32"](), - AddInt64 = BinaryenObj["_BinaryenAddInt64"](), - SubInt32 = BinaryenObj["_BinaryenSubInt32"](), - SubInt64 = BinaryenObj["_BinaryenSubInt64"](), - MulInt32 = BinaryenObj["_BinaryenMulInt32"](), - MulInt64 = BinaryenObj["_BinaryenMulInt64"](), - DivSInt32 = BinaryenObj["_BinaryenDivSInt32"](), - DivSInt64 = BinaryenObj["_BinaryenDivSInt64"](), - DivUInt32 = BinaryenObj["_BinaryenDivUInt32"](), - DivUInt64 = BinaryenObj["_BinaryenDivUInt64"](), - RemSInt32 = BinaryenObj["_BinaryenRemSInt32"](), - RemSInt64 = BinaryenObj["_BinaryenRemSInt64"](), - RemUInt32 = BinaryenObj["_BinaryenRemUInt32"](), - RemUInt64 = BinaryenObj["_BinaryenRemUInt64"](), - AndInt32 = BinaryenObj["_BinaryenAndInt32"](), - AndInt64 = BinaryenObj["_BinaryenAndInt64"](), - OrInt32 = BinaryenObj["_BinaryenOrInt32"](), - OrInt64 = BinaryenObj["_BinaryenOrInt64"](), - XorInt32 = BinaryenObj["_BinaryenXorInt32"](), - XorInt64 = BinaryenObj["_BinaryenXorInt64"](), - ShlInt32 = BinaryenObj["_BinaryenShlInt32"](), - ShlInt64 = BinaryenObj["_BinaryenShlInt64"](), - ShrSInt32 = BinaryenObj["_BinaryenShrSInt32"](), - ShrSInt64 = BinaryenObj["_BinaryenShrSInt64"](), - ShrUInt32 = BinaryenObj["_BinaryenShrUInt32"](), - ShrUInt64 = BinaryenObj["_BinaryenShrUInt64"](), - RotLInt32 = BinaryenObj["_BinaryenRotLInt32"](), - RotLInt64 = BinaryenObj["_BinaryenRotLInt64"](), - RotRInt32 = BinaryenObj["_BinaryenRotRInt32"](), - RotRInt64 = BinaryenObj["_BinaryenRotRInt64"](), - // #### testop #### // - EqZInt32 = BinaryenObj["_BinaryenEqZInt32"](), - EqZInt64 = BinaryenObj["_BinaryenEqZInt64"](), - // #### relop #### // - EqInt32 = BinaryenObj["_BinaryenEqInt32"](), - EqInt64 = BinaryenObj["_BinaryenEqInt64"](), - NeInt32 = BinaryenObj["_BinaryenNeInt32"](), - NeInt64 = BinaryenObj["_BinaryenNeInt64"](), - LtSInt32 = BinaryenObj["_BinaryenLtSInt32"](), - LtSInt64 = BinaryenObj["_BinaryenLtSInt64"](), - LtUInt32 = BinaryenObj["_BinaryenLtUInt32"](), - LtUInt64 = BinaryenObj["_BinaryenLtUInt64"](), - GtSInt32 = BinaryenObj["_BinaryenGtSInt32"](), - GtSInt64 = BinaryenObj["_BinaryenGtSInt64"](), - GtUInt32 = BinaryenObj["_BinaryenGtUInt32"](), - GtUInt64 = BinaryenObj["_BinaryenGtUInt64"](), - LeSInt32 = BinaryenObj["_BinaryenLeSInt32"](), - LeSInt64 = BinaryenObj["_BinaryenLeSInt64"](), - LeUInt32 = BinaryenObj["_BinaryenLeUInt32"](), - LeUInt64 = BinaryenObj["_BinaryenLeUInt64"](), - GeSInt32 = BinaryenObj["_BinaryenGeSInt32"](), - GeSInt64 = BinaryenObj["_BinaryenGeSInt64"](), - GeUInt32 = BinaryenObj["_BinaryenGeUInt32"](), - GeUInt64 = BinaryenObj["_BinaryenGeUInt64"](), - - // ### Floating-Point Operations ### // - // #### unop #### // - AbsFloat32 = BinaryenObj["_BinaryenAbsFloat32"](), - AbsFloat64 = BinaryenObj["_BinaryenAbsFloat64"](), - NegFloat32 = BinaryenObj["_BinaryenNegFloat32"](), - NegFloat64 = BinaryenObj["_BinaryenNegFloat64"](), - SqrtFloat32 = BinaryenObj["_BinaryenSqrtFloat32"](), - SqrtFloat64 = BinaryenObj["_BinaryenSqrtFloat64"](), - CeilFloat32 = BinaryenObj["_BinaryenCeilFloat32"](), - CeilFloat64 = BinaryenObj["_BinaryenCeilFloat64"](), - FloorFloat32 = BinaryenObj["_BinaryenFloorFloat32"](), - FloorFloat64 = BinaryenObj["_BinaryenFloorFloat64"](), - TruncFloat32 = BinaryenObj["_BinaryenTruncFloat32"](), - TruncFloat64 = BinaryenObj["_BinaryenTruncFloat64"](), - NearestFloat32 = BinaryenObj["_BinaryenNearestFloat32"](), - NearestFloat64 = BinaryenObj["_BinaryenNearestFloat64"](), - // #### binop #### // - AddFloat32 = BinaryenObj["_BinaryenAddFloat32"](), - AddFloat64 = BinaryenObj["_BinaryenAddFloat64"](), - SubFloat32 = BinaryenObj["_BinaryenSubFloat32"](), - SubFloat64 = BinaryenObj["_BinaryenSubFloat64"](), - MulFloat32 = BinaryenObj["_BinaryenMulFloat32"](), - MulFloat64 = BinaryenObj["_BinaryenMulFloat64"](), - DivFloat32 = BinaryenObj["_BinaryenDivFloat32"](), - DivFloat64 = BinaryenObj["_BinaryenDivFloat64"](), - MinFloat32 = BinaryenObj["_BinaryenMinFloat32"](), - MinFloat64 = BinaryenObj["_BinaryenMinFloat64"](), - MaxFloat32 = BinaryenObj["_BinaryenMaxFloat32"](), - MaxFloat64 = BinaryenObj["_BinaryenMaxFloat64"](), - CopySignFloat32 = BinaryenObj["_BinaryenCopySignFloat32"](), - CopySignFloat64 = BinaryenObj["_BinaryenCopySignFloat64"](), - // #### relop #### // - EqFloat32 = BinaryenObj["_BinaryenEqFloat32"](), - EqFloat64 = BinaryenObj["_BinaryenEqFloat64"](), - NeFloat32 = BinaryenObj["_BinaryenNeFloat32"](), - NeFloat64 = BinaryenObj["_BinaryenNeFloat64"](), - LtFloat32 = BinaryenObj["_BinaryenLtFloat32"](), - LtFloat64 = BinaryenObj["_BinaryenLtFloat64"](), - GtFloat32 = BinaryenObj["_BinaryenGtFloat32"](), - GtFloat64 = BinaryenObj["_BinaryenGtFloat64"](), - LeFloat32 = BinaryenObj["_BinaryenLeFloat32"](), - LeFloat64 = BinaryenObj["_BinaryenLeFloat64"](), - GeFloat32 = BinaryenObj["_BinaryenGeFloat32"](), - GeFloat64 = BinaryenObj["_BinaryenGeFloat64"](), - - // ### Conversions ### // - ExtendSInt32 = BinaryenObj["_BinaryenExtendSInt32"](), - ExtendUInt32 = BinaryenObj["_BinaryenExtendUInt32"](), - WrapInt64 = BinaryenObj["_BinaryenWrapInt64"](), - TruncSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSFloat32ToInt32"](), - TruncSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSFloat32ToInt64"](), - TruncSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSFloat64ToInt32"](), - TruncSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSFloat64ToInt64"](), - TruncUFloat32ToInt32 = BinaryenObj["_BinaryenTruncUFloat32ToInt32"](), - TruncUFloat32ToInt64 = BinaryenObj["_BinaryenTruncUFloat32ToInt64"](), - TruncUFloat64ToInt32 = BinaryenObj["_BinaryenTruncUFloat64ToInt32"](), - TruncUFloat64ToInt64 = BinaryenObj["_BinaryenTruncUFloat64ToInt64"](), - TruncSatSFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt32"](), - TruncSatSFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat32ToInt64"](), - TruncSatSFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt32"](), - TruncSatSFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatSFloat64ToInt64"](), - TruncSatUFloat32ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt32"](), - TruncSatUFloat32ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat32ToInt64"](), - TruncSatUFloat64ToInt32 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt32"](), - TruncSatUFloat64ToInt64 = BinaryenObj["_BinaryenTruncSatUFloat64ToInt64"](), - ConvertSInt32ToFloat32 = BinaryenObj["_BinaryenConvertSInt32ToFloat32"](), - ConvertSInt32ToFloat64 = BinaryenObj["_BinaryenConvertSInt32ToFloat64"](), - ConvertSInt64ToFloat32 = BinaryenObj["_BinaryenConvertSInt64ToFloat32"](), - ConvertSInt64ToFloat64 = BinaryenObj["_BinaryenConvertSInt64ToFloat64"](), - ConvertUInt32ToFloat32 = BinaryenObj["_BinaryenConvertUInt32ToFloat32"](), - ConvertUInt32ToFloat64 = BinaryenObj["_BinaryenConvertUInt32ToFloat64"](), - ConvertUInt64ToFloat32 = BinaryenObj["_BinaryenConvertUInt64ToFloat32"](), - ConvertUInt64ToFloat64 = BinaryenObj["_BinaryenConvertUInt64ToFloat64"](), - ReinterpretInt32 = BinaryenObj["_BinaryenReinterpretInt32"](), - ReinterpretInt64 = BinaryenObj["_BinaryenReinterpretInt64"](), - ReinterpretFloat32 = BinaryenObj["_BinaryenReinterpretFloat32"](), - ReinterpretFloat64 = BinaryenObj["_BinaryenReinterpretFloat64"](), - PromoteFloat32 = BinaryenObj["_BinaryenPromoteFloat32"](), - DemoteFloat64 = BinaryenObj["_BinaryenDemoteFloat64"](), - - // ### Vector Operations ### // - // #### vvunop #### // - NotVec128 = BinaryenObj["_BinaryenNotVec128"](), - // #### vvbinop #### // - AndVec128 = BinaryenObj["_BinaryenAndVec128"](), - AndNotVec128 = BinaryenObj["_BinaryenAndNotVec128"](), - OrVec128 = BinaryenObj["_BinaryenOrVec128"](), - XorVec128 = BinaryenObj["_BinaryenXorVec128"](), - // #### vvternop #### // - BitselectVec128 = BinaryenObj["_BinaryenBitselectVec128"](), - // #### vvtestop #### // - AnyTrueVec128 = BinaryenObj["_BinaryenAnyTrueVec128"](), - // #### vunop_i #### // - AbsVecI8x16 = BinaryenObj["_BinaryenAbsVecI8x16"](), - AbsVecI16x8 = BinaryenObj["_BinaryenAbsVecI16x8"](), - AbsVecI32x4 = BinaryenObj["_BinaryenAbsVecI32x4"](), - AbsVecI64x2 = BinaryenObj["_BinaryenAbsVecI64x2"](), - NegVecI8x16 = BinaryenObj["_BinaryenNegVecI8x16"](), - NegVecI16x8 = BinaryenObj["_BinaryenNegVecI16x8"](), - NegVecI32x4 = BinaryenObj["_BinaryenNegVecI32x4"](), - NegVecI64x2 = BinaryenObj["_BinaryenNegVecI64x2"](), - PopcntVecI8x16 = BinaryenObj["_BinaryenPopcntVecI8x16"](), - // #### vunop_f #### // - AbsVecF32x4 = BinaryenObj["_BinaryenAbsVecF32x4"](), - AbsVecF64x2 = BinaryenObj["_BinaryenAbsVecF64x2"](), - NegVecF32x4 = BinaryenObj["_BinaryenNegVecF32x4"](), - NegVecF64x2 = BinaryenObj["_BinaryenNegVecF64x2"](), - SqrtVecF32x4 = BinaryenObj["_BinaryenSqrtVecF32x4"](), - SqrtVecF64x2 = BinaryenObj["_BinaryenSqrtVecF64x2"](), - CeilVecF32x4 = BinaryenObj["_BinaryenCeilVecF32x4"](), - CeilVecF64x2 = BinaryenObj["_BinaryenCeilVecF64x2"](), - FloorVecF32x4 = BinaryenObj["_BinaryenFloorVecF32x4"](), - FloorVecF64x2 = BinaryenObj["_BinaryenFloorVecF64x2"](), - TruncVecF32x4 = BinaryenObj["_BinaryenTruncVecF32x4"](), - TruncVecF64x2 = BinaryenObj["_BinaryenTruncVecF64x2"](), - NearestVecF32x4 = BinaryenObj["_BinaryenNearestVecF32x4"](), - NearestVecF64x2 = BinaryenObj["_BinaryenNearestVecF64x2"](), - // #### vbinop_i #### // - AddVecI8x16 = BinaryenObj["_BinaryenAddVecI8x16"](), - AddVecI16x8 = BinaryenObj["_BinaryenAddVecI16x8"](), - AddVecI32x4 = BinaryenObj["_BinaryenAddVecI32x4"](), - AddVecI64x2 = BinaryenObj["_BinaryenAddVecI64x2"](), - SubVecI8x16 = BinaryenObj["_BinaryenSubVecI8x16"](), - SubVecI16x8 = BinaryenObj["_BinaryenSubVecI16x8"](), - SubVecI32x4 = BinaryenObj["_BinaryenSubVecI32x4"](), - SubVecI64x2 = BinaryenObj["_BinaryenSubVecI64x2"](), - AddSatSVecI8x16 = BinaryenObj["_BinaryenAddSatSVecI8x16"](), - AddSatSVecI16x8 = BinaryenObj["_BinaryenAddSatSVecI16x8"](), - AddSatUVecI8x16 = BinaryenObj["_BinaryenAddSatUVecI8x16"](), - AddSatUVecI16x8 = BinaryenObj["_BinaryenAddSatUVecI16x8"](), - SubSatSVecI8x16 = BinaryenObj["_BinaryenSubSatSVecI8x16"](), - SubSatSVecI16x8 = BinaryenObj["_BinaryenSubSatSVecI16x8"](), - SubSatUVecI8x16 = BinaryenObj["_BinaryenSubSatUVecI8x16"](), - SubSatUVecI16x8 = BinaryenObj["_BinaryenSubSatUVecI16x8"](), - MulVecI16x8 = BinaryenObj["_BinaryenMulVecI16x8"](), - MulVecI32x4 = BinaryenObj["_BinaryenMulVecI32x4"](), - MulVecI64x2 = BinaryenObj["_BinaryenMulVecI64x2"](), - AvgrUVecI8x16 = BinaryenObj["_BinaryenAvgrUVecI8x16"](), - AvgrUVecI16x8 = BinaryenObj["_BinaryenAvgrUVecI16x8"](), - Q15MulrSatSVecI16x8 = BinaryenObj["_BinaryenQ15MulrSatSVecI16x8"](), - RelaxedQ15MulrSVecI16x8 = BinaryenObj["_BinaryenRelaxedQ15MulrSVecI16x8"](), - MinSVecI8x16 = BinaryenObj["_BinaryenMinSVecI8x16"](), - MinSVecI16x8 = BinaryenObj["_BinaryenMinSVecI16x8"](), - MinSVecI32x4 = BinaryenObj["_BinaryenMinSVecI32x4"](), - MinUVecI8x16 = BinaryenObj["_BinaryenMinUVecI8x16"](), - MinUVecI16x8 = BinaryenObj["_BinaryenMinUVecI16x8"](), - MinUVecI32x4 = BinaryenObj["_BinaryenMinUVecI32x4"](), - MaxSVecI8x16 = BinaryenObj["_BinaryenMaxSVecI8x16"](), - MaxSVecI16x8 = BinaryenObj["_BinaryenMaxSVecI16x8"](), - MaxSVecI32x4 = BinaryenObj["_BinaryenMaxSVecI32x4"](), - MaxUVecI8x16 = BinaryenObj["_BinaryenMaxUVecI8x16"](), - MaxUVecI16x8 = BinaryenObj["_BinaryenMaxUVecI16x8"](), - MaxUVecI32x4 = BinaryenObj["_BinaryenMaxUVecI32x4"](), - // #### vbinop_f #### // - AddVecF32x4 = BinaryenObj["_BinaryenAddVecF32x4"](), - AddVecF64x2 = BinaryenObj["_BinaryenAddVecF64x2"](), - SubVecF32x4 = BinaryenObj["_BinaryenSubVecF32x4"](), - SubVecF64x2 = BinaryenObj["_BinaryenSubVecF64x2"](), - MulVecF32x4 = BinaryenObj["_BinaryenMulVecF32x4"](), - MulVecF64x2 = BinaryenObj["_BinaryenMulVecF64x2"](), - DivVecF32x4 = BinaryenObj["_BinaryenDivVecF32x4"](), - DivVecF64x2 = BinaryenObj["_BinaryenDivVecF64x2"](), - MinVecF32x4 = BinaryenObj["_BinaryenMinVecF32x4"](), - MinVecF64x2 = BinaryenObj["_BinaryenMinVecF64x2"](), - MaxVecF32x4 = BinaryenObj["_BinaryenMaxVecF32x4"](), - MaxVecF64x2 = BinaryenObj["_BinaryenMaxVecF64x2"](), - PMinVecF32x4 = BinaryenObj["_BinaryenPMinVecF32x4"](), - PMinVecF64x2 = BinaryenObj["_BinaryenPMinVecF64x2"](), - PMaxVecF32x4 = BinaryenObj["_BinaryenPMaxVecF32x4"](), - PMaxVecF64x2 = BinaryenObj["_BinaryenPMaxVecF64x2"](), - RelaxedMinVecF32x4 = BinaryenObj["_BinaryenRelaxedMinVecF32x4"](), - RelaxedMinVecF64x2 = BinaryenObj["_BinaryenRelaxedMinVecF64x2"](), - RelaxedMaxVecF32x4 = BinaryenObj["_BinaryenRelaxedMaxVecF32x4"](), - RelaxedMaxVecF64x2 = BinaryenObj["_BinaryenRelaxedMaxVecF64x2"](), - // #### vternop_i #### // - RelaxedLaneselectI8x16 = BinaryenObj["_BinaryenRelaxedLaneselectI8x16"](), - RelaxedLaneselectI16x8 = BinaryenObj["_BinaryenRelaxedLaneselectI16x8"](), - RelaxedLaneselectI32x4 = BinaryenObj["_BinaryenRelaxedLaneselectI32x4"](), - RelaxedLaneselectI64x2 = BinaryenObj["_BinaryenRelaxedLaneselectI64x2"](), - // #### vternop_f #### // - RelaxedMaddVecF32x4 = BinaryenObj["_BinaryenRelaxedMaddVecF32x4"](), - RelaxedMaddVecF64x2 = BinaryenObj["_BinaryenRelaxedMaddVecF64x2"](), - RelaxedNmaddVecF32x4 = BinaryenObj["_BinaryenRelaxedNmaddVecF32x4"](), - RelaxedNmaddVecF64x2 = BinaryenObj["_BinaryenRelaxedNmaddVecF64x2"](), - // #### vtestop_i #### // - AllTrueVecI8x16 = BinaryenObj["_BinaryenAllTrueVecI8x16"](), - AllTrueVecI16x8 = BinaryenObj["_BinaryenAllTrueVecI16x8"](), - AllTrueVecI32x4 = BinaryenObj["_BinaryenAllTrueVecI32x4"](), - AllTrueVecI64x2 = BinaryenObj["_BinaryenAllTrueVecI64x2"](), - // #### vrelop_i #### // - EqVecI8x16 = BinaryenObj["_BinaryenEqVecI8x16"](), - EqVecI16x8 = BinaryenObj["_BinaryenEqVecI16x8"](), - EqVecI32x4 = BinaryenObj["_BinaryenEqVecI32x4"](), - EqVecI64x2 = BinaryenObj["_BinaryenEqVecI64x2"](), - NeVecI8x16 = BinaryenObj["_BinaryenNeVecI8x16"](), - NeVecI16x8 = BinaryenObj["_BinaryenNeVecI16x8"](), - NeVecI32x4 = BinaryenObj["_BinaryenNeVecI32x4"](), - NeVecI64x2 = BinaryenObj["_BinaryenNeVecI64x2"](), - LtSVecI8x16 = BinaryenObj["_BinaryenLtSVecI8x16"](), - LtSVecI16x8 = BinaryenObj["_BinaryenLtSVecI16x8"](), - LtSVecI32x4 = BinaryenObj["_BinaryenLtSVecI32x4"](), - LtSVecI64x2 = BinaryenObj["_BinaryenLtSVecI64x2"](), - LtUVecI8x16 = BinaryenObj["_BinaryenLtUVecI8x16"](), - LtUVecI16x8 = BinaryenObj["_BinaryenLtUVecI16x8"](), - LtUVecI32x4 = BinaryenObj["_BinaryenLtUVecI32x4"](), - // LtUVecI64x2 // not supported; see #414 - GtSVecI8x16 = BinaryenObj["_BinaryenGtSVecI8x16"](), - GtSVecI16x8 = BinaryenObj["_BinaryenGtSVecI16x8"](), - GtSVecI32x4 = BinaryenObj["_BinaryenGtSVecI32x4"](), - GtSVecI64x2 = BinaryenObj["_BinaryenGtSVecI64x2"](), - GtUVecI8x16 = BinaryenObj["_BinaryenGtUVecI8x16"](), - GtUVecI16x8 = BinaryenObj["_BinaryenGtUVecI16x8"](), - GtUVecI32x4 = BinaryenObj["_BinaryenGtUVecI32x4"](), - // GtUVecI64x2 // not supported; see #414 - LeSVecI8x16 = BinaryenObj["_BinaryenLeSVecI8x16"](), - LeSVecI16x8 = BinaryenObj["_BinaryenLeSVecI16x8"](), - LeSVecI32x4 = BinaryenObj["_BinaryenLeSVecI32x4"](), - LeSVecI64x2 = BinaryenObj["_BinaryenLeSVecI64x2"](), - LeUVecI8x16 = BinaryenObj["_BinaryenLeUVecI8x16"](), - LeUVecI16x8 = BinaryenObj["_BinaryenLeUVecI16x8"](), - LeUVecI32x4 = BinaryenObj["_BinaryenLeUVecI32x4"](), - // LeUVecI64x2 // not supported; see #414 - GeSVecI8x16 = BinaryenObj["_BinaryenGeSVecI8x16"](), - GeSVecI16x8 = BinaryenObj["_BinaryenGeSVecI16x8"](), - GeSVecI32x4 = BinaryenObj["_BinaryenGeSVecI32x4"](), - GeSVecI64x2 = BinaryenObj["_BinaryenGeSVecI64x2"](), - GeUVecI8x16 = BinaryenObj["_BinaryenGeUVecI8x16"](), - GeUVecI16x8 = BinaryenObj["_BinaryenGeUVecI16x8"](), - GeUVecI32x4 = BinaryenObj["_BinaryenGeUVecI32x4"](), - // GeUVecI64x2 // not supported; see #414 - // #### vrelop_f #### // - EqVecF32x4 = BinaryenObj["_BinaryenEqVecF32x4"](), - EqVecF64x2 = BinaryenObj["_BinaryenEqVecF64x2"](), - NeVecF32x4 = BinaryenObj["_BinaryenNeVecF32x4"](), - NeVecF64x2 = BinaryenObj["_BinaryenNeVecF64x2"](), - LtVecF32x4 = BinaryenObj["_BinaryenLtVecF32x4"](), - LtVecF64x2 = BinaryenObj["_BinaryenLtVecF64x2"](), - GtVecF32x4 = BinaryenObj["_BinaryenGtVecF32x4"](), - GtVecF64x2 = BinaryenObj["_BinaryenGtVecF64x2"](), - LeVecF32x4 = BinaryenObj["_BinaryenLeVecF32x4"](), - LeVecF64x2 = BinaryenObj["_BinaryenLeVecF64x2"](), - GeVecF32x4 = BinaryenObj["_BinaryenGeVecF32x4"](), - GeVecF64x2 = BinaryenObj["_BinaryenGeVecF64x2"](), - // #### vshiftop #### // - ShlVecI8x16 = BinaryenObj["_BinaryenShlVecI8x16"](), - ShlVecI16x8 = BinaryenObj["_BinaryenShlVecI16x8"](), - ShlVecI32x4 = BinaryenObj["_BinaryenShlVecI32x4"](), - ShlVecI64x2 = BinaryenObj["_BinaryenShlVecI64x2"](), - ShrSVecI8x16 = BinaryenObj["_BinaryenShrSVecI8x16"](), - ShrSVecI16x8 = BinaryenObj["_BinaryenShrSVecI16x8"](), - ShrSVecI32x4 = BinaryenObj["_BinaryenShrSVecI32x4"](), - ShrSVecI64x2 = BinaryenObj["_BinaryenShrSVecI64x2"](), - ShrUVecI8x16 = BinaryenObj["_BinaryenShrUVecI8x16"](), - ShrUVecI16x8 = BinaryenObj["_BinaryenShrUVecI16x8"](), - ShrUVecI32x4 = BinaryenObj["_BinaryenShrUVecI32x4"](), - ShrUVecI64x2 = BinaryenObj["_BinaryenShrUVecI64x2"](), - // #### bitmask #### // - BitmaskVecI8x16 = BinaryenObj["_BinaryenBitmaskVecI8x16"](), - BitmaskVecI16x8 = BinaryenObj["_BinaryenBitmaskVecI16x8"](), - BitmaskVecI32x4 = BinaryenObj["_BinaryenBitmaskVecI32x4"](), - BitmaskVecI64x2 = BinaryenObj["_BinaryenBitmaskVecI64x2"](), - // #### vswizzleop #### // - SwizzleVecI8x16 = BinaryenObj["_BinaryenSwizzleVecI8x16"](), - RelaxedSwizzleVecI8x16 = BinaryenObj["_BinaryenRelaxedSwizzleVecI8x16"](), - // #### vextunop #### // - ExtAddPairwiseSVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseSVecI8x16ToI16x8"](), - ExtAddPairwiseSVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseSVecI16x8ToI32x4"](), - ExtAddPairwiseUVecI8x16ToI16x8 = BinaryenObj["_BinaryenExtAddPairwiseUVecI8x16ToI16x8"](), - ExtAddPairwiseUVecI16x8ToI32x4 = BinaryenObj["_BinaryenExtAddPairwiseUVecI16x8ToI32x4"](), - // #### vextbinop #### // - ExtMulLowSVecI16x8 = BinaryenObj["_BinaryenExtMulLowSVecI16x8"](), - ExtMulLowSVecI32x4 = BinaryenObj["_BinaryenExtMulLowSVecI32x4"](), - ExtMulLowSVecI64x2 = BinaryenObj["_BinaryenExtMulLowSVecI64x2"](), - ExtMulLowUVecI16x8 = BinaryenObj["_BinaryenExtMulLowUVecI16x8"](), - ExtMulLowUVecI32x4 = BinaryenObj["_BinaryenExtMulLowUVecI32x4"](), - ExtMulLowUVecI64x2 = BinaryenObj["_BinaryenExtMulLowUVecI64x2"](), - ExtMulHighSVecI16x8 = BinaryenObj["_BinaryenExtMulHighSVecI16x8"](), - ExtMulHighSVecI32x4 = BinaryenObj["_BinaryenExtMulHighSVecI32x4"](), - ExtMulHighSVecI64x2 = BinaryenObj["_BinaryenExtMulHighSVecI64x2"](), - ExtMulHighUVecI16x8 = BinaryenObj["_BinaryenExtMulHighUVecI16x8"](), - ExtMulHighUVecI32x4 = BinaryenObj["_BinaryenExtMulHighUVecI32x4"](), - ExtMulHighUVecI64x2 = BinaryenObj["_BinaryenExtMulHighUVecI64x2"](), - DotSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenDotSVecI16x8ToVecI32x4"](), - RelaxedDotI8x16I7x16SToVecI16x8 = BinaryenObj["_BinaryenRelaxedDotI8x16I7x16SToVecI16x8"](), - RelaxedDotI8x16I7x16AddSToVecI32x4 = BinaryenObj["_BinaryenRelaxedDotI8x16I7x16AddSToVecI32x4"](), - // #### narrow #### // - NarrowSVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowSVecI16x8ToVecI8x16"](), - NarrowSVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowSVecI32x4ToVecI16x8"](), - NarrowUVecI16x8ToVecI8x16 = BinaryenObj["_BinaryenNarrowUVecI16x8ToVecI8x16"](), - NarrowUVecI32x4ToVecI16x8 = BinaryenObj["_BinaryenNarrowUVecI32x4ToVecI16x8"](), - // #### vcvtop #### // - ExtendLowSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowSVecI8x16ToVecI16x8"](), - ExtendLowSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowSVecI16x8ToVecI32x4"](), - ExtendLowSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowSVecI32x4ToVecI64x2"](), - ExtendLowUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendLowUVecI8x16ToVecI16x8"](), - ExtendLowUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendLowUVecI16x8ToVecI32x4"](), - ExtendLowUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendLowUVecI32x4ToVecI64x2"](), - ExtendHighSVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighSVecI8x16ToVecI16x8"](), - ExtendHighSVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighSVecI16x8ToVecI32x4"](), - ExtendHighSVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighSVecI32x4ToVecI64x2"](), - ExtendHighUVecI8x16ToVecI16x8 = BinaryenObj["_BinaryenExtendHighUVecI8x16ToVecI16x8"](), - ExtendHighUVecI16x8ToVecI32x4 = BinaryenObj["_BinaryenExtendHighUVecI16x8ToVecI32x4"](), - ExtendHighUVecI32x4ToVecI64x2 = BinaryenObj["_BinaryenExtendHighUVecI32x4ToVecI64x2"](), - ConvertSVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertSVecI32x4ToVecF32x4"](), - ConvertUVecI32x4ToVecF32x4 = BinaryenObj["_BinaryenConvertUVecI32x4ToVecF32x4"](), - ConvertLowSVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowSVecI32x4ToVecF64x2"](), - ConvertLowUVecI32x4ToVecF64x2 = BinaryenObj["_BinaryenConvertLowUVecI32x4ToVecF64x2"](), - TruncSatSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatSVecF32x4ToVecI32x4"](), - TruncSatUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenTruncSatUVecF32x4ToVecI32x4"](), - TruncSatZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroSVecF64x2ToVecI32x4"](), - TruncSatZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenTruncSatZeroUVecF64x2ToVecI32x4"](), - RelaxedTruncSVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncSVecF32x4ToVecI32x4"](), - RelaxedTruncUVecF32x4ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncUVecF32x4ToVecI32x4"](), - RelaxedTruncZeroSVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroSVecF64x2ToVecI32x4"](), - RelaxedTruncZeroUVecF64x2ToVecI32x4 = BinaryenObj["_BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4"](), - DemoteZeroVecF64x2ToVecF32x4 = BinaryenObj["_BinaryenDemoteZeroVecF64x2ToVecF32x4"](), - PromoteLowVecF32x4ToVecF64x2 = BinaryenObj["_BinaryenPromoteLowVecF32x4ToVecF64x2"](), - // #### splat #### // - SplatVecI8x16 = BinaryenObj["_BinaryenSplatVecI8x16"](), - SplatVecI16x8 = BinaryenObj["_BinaryenSplatVecI16x8"](), - SplatVecI32x4 = BinaryenObj["_BinaryenSplatVecI32x4"](), - SplatVecI64x2 = BinaryenObj["_BinaryenSplatVecI64x2"](), - SplatVecF32x4 = BinaryenObj["_BinaryenSplatVecF32x4"](), - SplatVecF64x2 = BinaryenObj["_BinaryenSplatVecF64x2"](), - // #### extract_lane #### // - ExtractLaneSVecI8x16 = BinaryenObj["_BinaryenExtractLaneSVecI8x16"](), - ExtractLaneSVecI16x8 = BinaryenObj["_BinaryenExtractLaneSVecI16x8"](), - ExtractLaneUVecI8x16 = BinaryenObj["_BinaryenExtractLaneUVecI8x16"](), - ExtractLaneUVecI16x8 = BinaryenObj["_BinaryenExtractLaneUVecI16x8"](), - ExtractLaneVecI32x4 = BinaryenObj["_BinaryenExtractLaneVecI32x4"](), - ExtractLaneVecI64x2 = BinaryenObj["_BinaryenExtractLaneVecI64x2"](), - ExtractLaneVecF32x4 = BinaryenObj["_BinaryenExtractLaneVecF32x4"](), - ExtractLaneVecF64x2 = BinaryenObj["_BinaryenExtractLaneVecF64x2"](), - // #### replace_lane #### // - ReplaceLaneVecI8x16 = BinaryenObj["_BinaryenReplaceLaneVecI8x16"](), - ReplaceLaneVecI16x8 = BinaryenObj["_BinaryenReplaceLaneVecI16x8"](), - ReplaceLaneVecI32x4 = BinaryenObj["_BinaryenReplaceLaneVecI32x4"](), - ReplaceLaneVecI64x2 = BinaryenObj["_BinaryenReplaceLaneVecI64x2"](), - ReplaceLaneVecF32x4 = BinaryenObj["_BinaryenReplaceLaneVecF32x4"](), - ReplaceLaneVecF64x2 = BinaryenObj["_BinaryenReplaceLaneVecF64x2"](), - - // ### Atomic Operations ### // - AtomicRMWAdd = BinaryenObj["_BinaryenAtomicRMWAdd"](), - AtomicRMWSub = BinaryenObj["_BinaryenAtomicRMWSub"](), - AtomicRMWAnd = BinaryenObj["_BinaryenAtomicRMWAnd"](), - AtomicRMWOr = BinaryenObj["_BinaryenAtomicRMWOr"](), - AtomicRMWXor = BinaryenObj["_BinaryenAtomicRMWXor"](), - AtomicRMWXchg = BinaryenObj["_BinaryenAtomicRMWXchg"](), - - // ### String Operations ### // - StringNewLossyUTF8Array = BinaryenObj["_BinaryenStringNewLossyUTF8Array"](), - StringNewWTF16Array = BinaryenObj["_BinaryenStringNewWTF16Array"](), - StringNewFromCodePoint = BinaryenObj["_BinaryenStringNewFromCodePoint"](), - StringMeasureUTF8 = BinaryenObj["_BinaryenStringMeasureUTF8"](), - StringMeasureWTF16 = BinaryenObj["_BinaryenStringMeasureWTF16"](), - StringEncodeLossyUTF8Array = BinaryenObj["_BinaryenStringEncodeLossyUTF8Array"](), - StringEncodeWTF16Array = BinaryenObj["_BinaryenStringEncodeWTF16Array"](), - StringEqEqual = BinaryenObj["_BinaryenStringEqEqual"](), - StringEqCompare = BinaryenObj["_BinaryenStringEqCompare"](), - - // ### WideInt Operations ### // - AddInt128 = BinaryenObj["_BinaryenAddInt128"](), - SubInt128 = BinaryenObj["_BinaryenSubInt128"](), - MulWideSInt64 = BinaryenObj["_BinaryenMulWideSInt64"](), - MulWideUInt64 = BinaryenObj["_BinaryenMulWideUInt64"](), -} diff --git a/ts/src/services/expression-builder/f32.ts b/ts/src/services/expression-builder/f32.ts index 31fb3d3d1bd..0bb8a217388 100644 --- a/ts/src/services/expression-builder/f32.ts +++ b/ts/src/services/expression-builder/f32.ts @@ -6,6 +6,7 @@ import type { } from "../../classes/module/Module.ts"; import { type ExpressionRef, + Operation, f32 as f32_t, } from "../../constants.ts"; import { @@ -15,9 +16,6 @@ import { storeFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/f32x4.ts b/ts/src/services/expression-builder/f32x4.ts index 7058198b3c3..f696d962a38 100644 --- a/ts/src/services/expression-builder/f32x4.ts +++ b/ts/src/services/expression-builder/f32x4.ts @@ -1,15 +1,15 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + Operation, +} from "../../constants.ts"; import { binaryFn, simdExtractFn, simdReplaceFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/f64.ts b/ts/src/services/expression-builder/f64.ts index 574686b4ec5..e26f18f060b 100644 --- a/ts/src/services/expression-builder/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -6,6 +6,7 @@ import type { } from "../../classes/module/Module.ts"; import { type ExpressionRef, + Operation, f64 as f64_t, } from "../../constants.ts"; import { @@ -15,9 +16,6 @@ import { storeFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/f64x2.ts b/ts/src/services/expression-builder/f64x2.ts index 330f546fdd3..f94c06ce948 100644 --- a/ts/src/services/expression-builder/f64x2.ts +++ b/ts/src/services/expression-builder/f64x2.ts @@ -1,15 +1,15 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + Operation, +} from "../../constants.ts"; import { binaryFn, simdExtractFn, simdReplaceFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/generic.ts b/ts/src/services/expression-builder/generic.ts index d97d05d3cc0..7c7e53e7af0 100644 --- a/ts/src/services/expression-builder/generic.ts +++ b/ts/src/services/expression-builder/generic.ts @@ -14,13 +14,11 @@ import type { } from "../../classes/module/Module.ts"; import { type ExpressionRef, + Operation, type Type, none, unreachable, } from "../../constants.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/i16x8.ts b/ts/src/services/expression-builder/i16x8.ts index f0fa6477898..f483b9e09be 100644 --- a/ts/src/services/expression-builder/i16x8.ts +++ b/ts/src/services/expression-builder/i16x8.ts @@ -1,6 +1,9 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + Operation, +} from "../../constants.ts"; import { consoleWarn, } from "../../lib.ts"; @@ -11,9 +14,6 @@ import { simdShiftFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/i32.ts b/ts/src/services/expression-builder/i32.ts index 1ef22803e30..85aec1f8cba 100644 --- a/ts/src/services/expression-builder/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -6,6 +6,7 @@ import type { } from "../../classes/module/Module.ts"; import { type ExpressionRef, + Operation, i32 as i32_t, } from "../../constants.ts"; import { @@ -18,9 +19,6 @@ import { storeFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/i32x4.ts b/ts/src/services/expression-builder/i32x4.ts index a0793e1d6da..cc711d01610 100644 --- a/ts/src/services/expression-builder/i32x4.ts +++ b/ts/src/services/expression-builder/i32x4.ts @@ -1,6 +1,9 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + Operation, +} from "../../constants.ts"; import { binaryFn, simdExtractFn, @@ -8,9 +11,6 @@ import { simdShiftFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index cc95a35bae3..5782a2fb6a8 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -9,6 +9,7 @@ import type { } from "../../classes/module/Module.ts"; import { type ExpressionRef, + Operation, i64 as i64_t, } from "../../constants.ts"; import { @@ -21,9 +22,6 @@ import { storeFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/i64x2.ts b/ts/src/services/expression-builder/i64x2.ts index 1ea3505e57f..74a78124f13 100644 --- a/ts/src/services/expression-builder/i64x2.ts +++ b/ts/src/services/expression-builder/i64x2.ts @@ -1,6 +1,9 @@ import type { Module, } from "../../classes/module/Module.ts"; +import { + Operation, +} from "../../constants.ts"; import { binaryFn, simdExtractFn, @@ -8,9 +11,6 @@ import { simdShiftFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/i8x16.ts b/ts/src/services/expression-builder/i8x16.ts index c70f2fd7620..2733f3e0913 100644 --- a/ts/src/services/expression-builder/i8x16.ts +++ b/ts/src/services/expression-builder/i8x16.ts @@ -8,8 +8,9 @@ import { import type { Module, } from "../../classes/module/Module.ts"; -import type { - ExpressionRef, +import { + type ExpressionRef, + Operation, } from "../../constants.ts"; import { consoleWarn, @@ -21,9 +22,6 @@ import { simdShiftFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; diff --git a/ts/src/services/expression-builder/reference.ts b/ts/src/services/expression-builder/reference.ts index ddf736f6c23..b9cea96fa8a 100644 --- a/ts/src/services/expression-builder/reference.ts +++ b/ts/src/services/expression-builder/reference.ts @@ -8,13 +8,11 @@ import { import type { Module, } from "../../classes/module/Module.ts"; -import type { - ExpressionRef, - Type, -} from "../../constants.ts"; import { + type ExpressionRef, Operation, -} from "./Operation.ts"; + type Type, +} from "../../constants.ts"; diff --git a/ts/src/services/expression-builder/v128.ts b/ts/src/services/expression-builder/v128.ts index c4b711d9227..6454f1ff93e 100644 --- a/ts/src/services/expression-builder/v128.ts +++ b/ts/src/services/expression-builder/v128.ts @@ -9,6 +9,7 @@ import type { } from "../../classes/module/Module.ts"; import { type ExpressionRef, + Operation, v128 as v128_t, } from "../../constants.ts"; import { @@ -20,9 +21,6 @@ import { storeFn, unaryFn, } from "./-utils.ts"; -import { - Operation, -} from "./Operation.ts"; From bac66b77bcafce0f61565be674c901c875b5a0b9 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 18:35:59 -0400 Subject: [PATCH 168/247] refactor: use private fields over unique symbol keys --- ts/src/classes/expression/Const.ts | 21 ++-- ts/src/classes/expression/Expression.ts | 18 ++- ts/src/classes/expression/blocks.ts | 39 +++--- ts/src/classes/expression/breaks.ts | 53 ++++---- ts/src/classes/expression/calls.ts | 83 +++++++------ ts/src/classes/expression/memories.ts | 147 +++++++++++------------ ts/src/classes/expression/parametrics.ts | 19 ++- ts/src/classes/expression/tables.ts | 37 +++--- ts/src/classes/expression/throws.ts | 73 ++++++----- ts/src/classes/expression/variables.ts | 27 ++--- ts/src/classes/module/Function.ts | 36 +++--- ts/src/classes/module/Module.ts | 5 +- ts/src/classes/module/Table.ts | 30 ++--- 13 files changed, 289 insertions(+), 299 deletions(-) diff --git a/ts/src/classes/expression/Const.ts b/ts/src/classes/expression/Const.ts index 9f9b1937889..4ec1768cdec 100644 --- a/ts/src/classes/expression/Const.ts +++ b/ts/src/classes/expression/Const.ts @@ -4,7 +4,6 @@ import { stackAlloc, } from "../../-pre.ts"; import { - THIS_PTR, preserveStack, } from "../../-utils.ts"; import { @@ -39,23 +38,23 @@ export class Const extends Expression { throw new Error(`Unexpected type: ${ this_type }.`); } - get valueI32(): number { return BinaryenObj["_BinaryenConstGetValueI32"](this[THIS_PTR]); } - set valueI32(value: number) { BinaryenObj["_BinaryenConstSetValueI32"](this[THIS_PTR], value); } + get valueI32(): number { return BinaryenObj["_BinaryenConstGetValueI32"](this._ptr); } + set valueI32(value: number) { BinaryenObj["_BinaryenConstSetValueI32"](this._ptr, value); } - get valueI64(): number { return BinaryenObj["_BinaryenConstGetValueI64"](this[THIS_PTR]); } - set valueI64(value: number) { BinaryenObj["_BinaryenConstSetValueI64"](this[THIS_PTR], BigInt(value)); } + get valueI64(): number { return BinaryenObj["_BinaryenConstGetValueI64"](this._ptr); } + set valueI64(value: number) { BinaryenObj["_BinaryenConstSetValueI64"](this._ptr, BigInt(value)); } - get valueF32(): number { return BinaryenObj["_BinaryenConstGetValueF32"](this[THIS_PTR]); } - set valueF32(value: number) { BinaryenObj["_BinaryenConstSetValueF32"](this[THIS_PTR], value); } + get valueF32(): number { return BinaryenObj["_BinaryenConstGetValueF32"](this._ptr); } + set valueF32(value: number) { BinaryenObj["_BinaryenConstSetValueF32"](this._ptr, value); } - get valueF64(): number { return BinaryenObj["_BinaryenConstGetValueF64"](this[THIS_PTR]); } - set valueF64(value: number) { BinaryenObj["_BinaryenConstSetValueF64"](this[THIS_PTR], value); } + get valueF64(): number { return BinaryenObj["_BinaryenConstGetValueF64"](this._ptr); } + set valueF64(value: number) { BinaryenObj["_BinaryenConstSetValueF64"](this._ptr, value); } get valueV128(): number[] { const value: number[] = []; preserveStack(() => { const tempBuffer = stackAlloc(16); - BinaryenObj["_BinaryenConstGetValueV128"](this[THIS_PTR], tempBuffer); + BinaryenObj["_BinaryenConstGetValueV128"](this._ptr, tempBuffer); for (let i = 0; i < 16; ++i) { value[i] = HEAPU8[tempBuffer + i]; } @@ -69,7 +68,7 @@ export class Const extends Expression { for (let i = 0; i < 16; ++i) { HEAPU8[tempBuffer + i] = value[i]; } - BinaryenObj["_BinaryenConstSetValueV128"](this[THIS_PTR], tempBuffer); + BinaryenObj["_BinaryenConstSetValueV128"](this._ptr, tempBuffer); }); } } diff --git a/ts/src/classes/expression/Expression.ts b/ts/src/classes/expression/Expression.ts index f0e2e1c0549..a9b4c329e58 100644 --- a/ts/src/classes/expression/Expression.ts +++ b/ts/src/classes/expression/Expression.ts @@ -1,9 +1,6 @@ import { BinaryenObj, } from "../../-pre.ts"; -import { - THIS_PTR, -} from "../../-utils.ts"; import type { ExpressionId, ExpressionRef, @@ -17,7 +14,8 @@ import { export class Expression { - protected readonly [THIS_PTR]: ExpressionRef; + /** The underlying C-API pointer of the wrapped expression. */ + protected readonly _ptr: ExpressionRef; /** Not really an “ID”, just the “kind” of expression. */ readonly #id: ExpressionId; @@ -31,7 +29,7 @@ export class Expression { * @param expr the expression reference */ constructor(exprId: ExpressionId, expr: ExpressionRef) { - this[THIS_PTR] = expr; + this._ptr = expr; this.#id = exprId; } @@ -40,22 +38,22 @@ export class Expression { } get type(): Type { - return getExpressionType(this[THIS_PTR]); + return getExpressionType(this._ptr); } set type(typ: Type) { - BinaryenObj["_BinaryenExpressionSetType"](this[THIS_PTR], typ); + BinaryenObj["_BinaryenExpressionSetType"](this._ptr, typ); } valueOf(): ExpressionRef { - return this[THIS_PTR]; + return this._ptr; } finalize(): void { - BinaryenObj["_BinaryenExpressionFinalize"](this[THIS_PTR]); + BinaryenObj["_BinaryenExpressionFinalize"](this._ptr); } toText(): string { - return emitText(this[THIS_PTR]); + return emitText(this._ptr); } } diff --git a/ts/src/classes/expression/blocks.ts b/ts/src/classes/expression/blocks.ts index 19b2ba7668e..bdc126f7c73 100644 --- a/ts/src/classes/expression/blocks.ts +++ b/ts/src/classes/expression/blocks.ts @@ -3,7 +3,6 @@ import { UTF8ToString, } from "../../-pre.ts"; import { - THIS_PTR, getAllNested, preserveStack, setAllNested, @@ -25,25 +24,25 @@ export class Block extends Expression { } get name(): string | null { - const name = BinaryenObj["_BinaryenBlockGetName"](this[THIS_PTR]); + const name = BinaryenObj["_BinaryenBlockGetName"](this._ptr); return name ? UTF8ToString(name) : null; } set name(name: string) { - preserveStack(() => BinaryenObj["_BinaryenBlockSetName"](this[THIS_PTR], strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenBlockSetName"](this._ptr, strToStack(name))); } get numChildren(): number { - return BinaryenObj["_BinaryenBlockGetNumChildren"](this[THIS_PTR]); + return BinaryenObj["_BinaryenBlockGetNumChildren"](this._ptr); } get children() { - return getAllNested(this[THIS_PTR], BinaryenObj["_BinaryenBlockGetNumChildren"], BinaryenObj["_BinaryenBlockGetChildAt"]); + return getAllNested(this._ptr, BinaryenObj["_BinaryenBlockGetNumChildren"], BinaryenObj["_BinaryenBlockGetChildAt"]); } set children(children: readonly ExpressionRef[]) { setAllNested( - this[THIS_PTR], + this._ptr, children, BinaryenObj["_BinaryenBlockGetNumChildren"], BinaryenObj["_BinaryenBlockSetChildAt"], @@ -53,23 +52,23 @@ export class Block extends Expression { } getChildAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenBlockGetChildAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenBlockGetChildAt"](this._ptr, index); } setChildAt(index: number, childExpr: ExpressionRef): void { - BinaryenObj["_BinaryenBlockSetChildAt"](this[THIS_PTR], index, childExpr); + BinaryenObj["_BinaryenBlockSetChildAt"](this._ptr, index, childExpr); } appendChild(childExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenBlockAppendChild"](this[THIS_PTR], childExpr); + return BinaryenObj["_BinaryenBlockAppendChild"](this._ptr, childExpr); } insertChildAt(index: number, childExpr: ExpressionRef): void { - BinaryenObj["_BinaryenBlockInsertChildAt"](this[THIS_PTR], index, childExpr); + BinaryenObj["_BinaryenBlockInsertChildAt"](this._ptr, index, childExpr); } removeChildAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenBlockRemoveChildAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenBlockRemoveChildAt"](this._ptr, index); } } @@ -81,16 +80,16 @@ export class Loop extends Expression { } get name(): string | null { - const name = BinaryenObj["_BinaryenLoopGetName"](this[THIS_PTR]); + const name = BinaryenObj["_BinaryenLoopGetName"](this._ptr); return name ? UTF8ToString(name) : null; } set name(name: string) { - preserveStack(() => BinaryenObj["_BinaryenLoopSetName"](this[THIS_PTR], strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenLoopSetName"](this._ptr, strToStack(name))); } - get body(): ExpressionRef { return BinaryenObj["_BinaryenLoopGetBody"](this[THIS_PTR]); } - set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenLoopSetBody"](this[THIS_PTR], bodyExpr); } + get body(): ExpressionRef { return BinaryenObj["_BinaryenLoopGetBody"](this._ptr); } + set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenLoopSetBody"](this._ptr, bodyExpr); } } @@ -100,12 +99,12 @@ export class If extends Expression { super(ExpressionId.If, expr); } - get condition(): ExpressionRef { return BinaryenObj["_BinaryenIfGetCondition"](this[THIS_PTR]); } + get condition(): ExpressionRef { return BinaryenObj["_BinaryenIfGetCondition"](this._ptr); } set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetCondition"](condExpr); } - get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfTrue"](this[THIS_PTR]); } - set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfTrue"](this[THIS_PTR], ifTrueExpr); } + get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfTrue"](this._ptr); } + set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfTrue"](this._ptr, ifTrueExpr); } - get ifFalse(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfFalse"](this[THIS_PTR]); } - set ifFalse(ifFalseExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfFalse"](this[THIS_PTR], ifFalseExpr); } + get ifFalse(): ExpressionRef { return BinaryenObj["_BinaryenIfGetIfFalse"](this._ptr); } + set ifFalse(ifFalseExpr: ExpressionRef) { BinaryenObj["_BinaryenIfSetIfFalse"](this._ptr, ifFalseExpr); } } diff --git a/ts/src/classes/expression/breaks.ts b/ts/src/classes/expression/breaks.ts index 5d22d921593..0a8543af8b5 100644 --- a/ts/src/classes/expression/breaks.ts +++ b/ts/src/classes/expression/breaks.ts @@ -3,7 +3,6 @@ import { UTF8ToString, } from "../../-pre.ts"; import { - THIS_PTR, getAllNested, preserveStack, setAllNested, @@ -26,19 +25,19 @@ export class Break extends Expression { } get name(): string | null { - const name = BinaryenObj["_BinaryenBreakGetName"](this[THIS_PTR]); + const name = BinaryenObj["_BinaryenBreakGetName"](this._ptr); return name ? UTF8ToString(name) : null; } set name(name: string) { - preserveStack(() => BinaryenObj["_BinaryenBreakSetName"](this[THIS_PTR], strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenBreakSetName"](this._ptr, strToStack(name))); } - get condition(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetCondition"](this[THIS_PTR]); } - set condition(condExpr: ExpressionRef) {BinaryenObj["_BinaryenBreakSetCondition"](this[THIS_PTR], condExpr);} + get condition(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetCondition"](this._ptr); } + set condition(condExpr: ExpressionRef) {BinaryenObj["_BinaryenBreakSetCondition"](this._ptr, condExpr);} - get value(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenBreakSetValue"](this[THIS_PTR], valueExpr); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenBreakSetValue"](this._ptr, valueExpr); } } @@ -48,17 +47,17 @@ export class Switch extends Expression { super(ExpressionId.Switch, expr); } - get condition(): ExpressionRef { return BinaryenObj["_BinaryenSwitchGetCondition"](this[THIS_PTR]); } + get condition(): ExpressionRef { return BinaryenObj["_BinaryenSwitchGetCondition"](this._ptr); } set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSwitchSetCondition"](condExpr); } - get value(): ExpressionRef { return BinaryenObj["_BinaryenSwitchGetValue"](this[THIS_PTR]); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenSwitchGetValue"](this._ptr); } set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenSwitchSetValue"](valueExpr); } - get numNames(): number { return BinaryenObj["_BinaryenSwitchGetNumNames"](this[THIS_PTR]); } + get numNames(): number { return BinaryenObj["_BinaryenSwitchGetNumNames"](this._ptr); } get names(): string[] { return getAllNested( - this[THIS_PTR], + this._ptr, BinaryenObj["_BinaryenSwitchGetNumNames"], BinaryenObj["_BinaryenSwitchGetNameAt"], ).map((p) => UTF8ToString(p)); @@ -66,7 +65,7 @@ export class Switch extends Expression { set names(names: readonly string[]) { preserveStack(() => setAllNested( - this[THIS_PTR], + this._ptr, names.map(strToStack), BinaryenObj["_BinaryenSwitchGetNumNames"], BinaryenObj["_BinaryenSwitchSetNameAt"], @@ -76,32 +75,32 @@ export class Switch extends Expression { } get defaultName(): string | null { - const name = BinaryenObj["_BinaryenSwitchGetDefaultName"](this[THIS_PTR]); + const name = BinaryenObj["_BinaryenSwitchGetDefaultName"](this._ptr); return name ? UTF8ToString(name) : null; } set defaultName(defaultName: string) { - preserveStack(() => BinaryenObj["_BinaryenSwitchSetDefaultName"](this[THIS_PTR], strToStack(defaultName))); + preserveStack(() => BinaryenObj["_BinaryenSwitchSetDefaultName"](this._ptr, strToStack(defaultName))); } getNameAt(index: number): string { - return UTF8ToString(BinaryenObj["_BinaryenSwitchGetNameAt"](this[THIS_PTR], index)); + return UTF8ToString(BinaryenObj["_BinaryenSwitchGetNameAt"](this._ptr, index)); } setNameAt(index: number, name: string): void { - preserveStack(() => BinaryenObj["_BinaryenSwitchSetNameAt"](this[THIS_PTR], index, strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenSwitchSetNameAt"](this._ptr, index, strToStack(name))); } appendName(name: string): void { - preserveStack(() => BinaryenObj["_BinaryenSwitchAppendName"](this[THIS_PTR], strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenSwitchAppendName"](this._ptr, strToStack(name))); } insertNameAt(index: number, name: string): void { - preserveStack(() => BinaryenObj["_BinaryenSwitchInsertNameAt"](this[THIS_PTR], index, strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenSwitchInsertNameAt"](this._ptr, index, strToStack(name))); } removeNameAt(index: number): string { - return UTF8ToString(BinaryenObj["_BinaryenSwitchRemoveNameAt"](this[THIS_PTR], index)); + return UTF8ToString(BinaryenObj["_BinaryenSwitchRemoveNameAt"](this._ptr, index)); } } @@ -112,15 +111,15 @@ export class BrOn extends Expression { super(ExpressionId.BrOn, expr); } - get op(): number { return BinaryenObj["_BinaryenBrOnGetOp"](this[THIS_PTR]); } - set op(op: number) { BinaryenObj["_BinaryenBrOnSetOp"](this[THIS_PTR], op); } + get op(): number { return BinaryenObj["_BinaryenBrOnGetOp"](this._ptr); } + set op(op: number) { BinaryenObj["_BinaryenBrOnSetOp"](this._ptr, op); } - get name(): string { return UTF8ToString(BinaryenObj["_BinaryenBrOnGetName"](this[THIS_PTR])); } - set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenBrOnSetName"](this[THIS_PTR], strToStack(name))); } + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenBrOnGetName"](this._ptr)); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenBrOnSetName"](this._ptr, strToStack(name))); } - get ref(): ExpressionRef { return BinaryenObj["_BinaryenBrOnGetRef"](this[THIS_PTR]); } - set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenBrOnSetRef"](this[THIS_PTR], ref); } + get ref(): ExpressionRef { return BinaryenObj["_BinaryenBrOnGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenBrOnSetRef"](this._ptr, ref); } - get castType(): Type { return BinaryenObj["_BinaryenBrOnGetCastType"](this[THIS_PTR]); } - set castType(castType: Type) { BinaryenObj["_BinaryenBrOnSetCastType"](this[THIS_PTR], castType); } + get castType(): Type { return BinaryenObj["_BinaryenBrOnGetCastType"](this._ptr); } + set castType(castType: Type) { BinaryenObj["_BinaryenBrOnSetCastType"](this._ptr, castType); } } diff --git a/ts/src/classes/expression/calls.ts b/ts/src/classes/expression/calls.ts index 7b8e0ef554e..2ec651b7034 100644 --- a/ts/src/classes/expression/calls.ts +++ b/ts/src/classes/expression/calls.ts @@ -3,7 +3,6 @@ import { UTF8ToString, } from "../../-pre.ts"; import { - THIS_PTR, getAllNested, preserveStack, setAllNested, @@ -25,17 +24,17 @@ export class Call extends Expression { super(ExpressionId.Call, expr); } - get target(): string { return UTF8ToString(BinaryenObj["_BinaryenCallGetTarget"](this[THIS_PTR])); } - set target(targetName: string) { preserveStack(() => BinaryenObj["_BinaryenCallSetTarget"](this[THIS_PTR], strToStack(targetName))); } + get target(): string { return UTF8ToString(BinaryenObj["_BinaryenCallGetTarget"](this._ptr)); } + set target(targetName: string) { preserveStack(() => BinaryenObj["_BinaryenCallSetTarget"](this._ptr, strToStack(targetName))); } - get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIsReturn"](this[THIS_PTR])); } - set return(isReturn: boolean) { BinaryenObj["_BinaryenCallSetReturn"](this[THIS_PTR], isReturn); } + get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIsReturn"](this._ptr)); } + set return(isReturn: boolean) { BinaryenObj["_BinaryenCallSetReturn"](this._ptr, isReturn); } - get numOperands(): number { return BinaryenObj["_BinaryenCallGetNumOperands"](this[THIS_PTR]); } + get numOperands(): number { return BinaryenObj["_BinaryenCallGetNumOperands"](this._ptr); } get operands(): ExpressionRef[] { return getAllNested( - this[THIS_PTR], + this._ptr, BinaryenObj["_BinaryenCallGetNumOperands"], BinaryenObj["_BinaryenCallGetOperandAt"], ); @@ -43,7 +42,7 @@ export class Call extends Expression { set operands(operands: readonly ExpressionRef[]) { setAllNested( - this[THIS_PTR], + this._ptr, operands, BinaryenObj["_BinaryenCallGetNumOperands"], BinaryenObj["_BinaryenCallSetOperandAt"], @@ -53,23 +52,23 @@ export class Call extends Expression { } getOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallGetOperandAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenCallGetOperandAt"](this._ptr, index); } setOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallSetOperandAt"](this[THIS_PTR], index, operandExpr); + BinaryenObj["_BinaryenCallSetOperandAt"](this._ptr, index, operandExpr); } appendOperand(operandExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenCallAppendOperand"](this[THIS_PTR], operandExpr); + return BinaryenObj["_BinaryenCallAppendOperand"](this._ptr, operandExpr); } insertOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallInsertOperandAt"](this[THIS_PTR], index, operandExpr); + BinaryenObj["_BinaryenCallInsertOperandAt"](this._ptr, index, operandExpr); } removeOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallRemoveOperandAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenCallRemoveOperandAt"](this._ptr, index); } } @@ -80,28 +79,28 @@ export class CallRef extends Expression { super(ExpressionId.CallRef, expr); } - get target(): ExpressionRef { return BinaryenObj["_BinaryenCallRefGetTarget"](this[THIS_PTR]); } - set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallRefSetTarget"](this[THIS_PTR], targetExpr); } + get target(): ExpressionRef { return BinaryenObj["_BinaryenCallRefGetTarget"](this._ptr); } + set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallRefSetTarget"](this._ptr, targetExpr); } - get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallRefIsReturn"](this[THIS_PTR])); } - set return(isReturn: boolean) { BinaryenObj["_BinaryenCallRefSetReturn"](this[THIS_PTR], isReturn); } + get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallRefIsReturn"](this._ptr)); } + set return(isReturn: boolean) { BinaryenObj["_BinaryenCallRefSetReturn"](this._ptr, isReturn); } - get numOperands(): number { return BinaryenObj["_BinaryenCallRefGetNumOperands"](this[THIS_PTR]); } + get numOperands(): number { return BinaryenObj["_BinaryenCallRefGetNumOperands"](this._ptr); } getOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallRefGetOperandAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenCallRefGetOperandAt"](this._ptr, index); } setOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallRefSetOperandAt"](this[THIS_PTR], index, operandExpr); + BinaryenObj["_BinaryenCallRefSetOperandAt"](this._ptr, index, operandExpr); } appendOperand(operandExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenCallRefAppendOperand"](this[THIS_PTR], operandExpr); + return BinaryenObj["_BinaryenCallRefAppendOperand"](this._ptr, operandExpr); } removeOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallRefRemoveOperandAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenCallRefRemoveOperandAt"](this._ptr, index); } } @@ -112,26 +111,26 @@ export class CallIndirect extends Expression { super(ExpressionId.CallIndirect, expr); } - get target(): ExpressionRef { return BinaryenObj["_BinaryenCallIndirectGetTarget"](this[THIS_PTR]); } - set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallIndirectSetTarget"](this[THIS_PTR], targetExpr); } + get target(): ExpressionRef { return BinaryenObj["_BinaryenCallIndirectGetTarget"](this._ptr); } + set target(targetExpr: ExpressionRef) { BinaryenObj["_BinaryenCallIndirectSetTarget"](this._ptr, targetExpr); } - get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIndirectIsReturn"](this[THIS_PTR])); } - set return(isReturn: boolean) { BinaryenObj["_BinaryenCallIndirectSetReturn"](this[THIS_PTR], isReturn); } + get return(): boolean { return Boolean(BinaryenObj["_BinaryenCallIndirectIsReturn"](this._ptr)); } + set return(isReturn: boolean) { BinaryenObj["_BinaryenCallIndirectSetReturn"](this._ptr, isReturn); } - get table(): string { return UTF8ToString(BinaryenObj["_BinaryenCallIndirectGetTable"](this[THIS_PTR])); } - set table(table: string) { preserveStack(() => BinaryenObj["_BinaryenCallIndirectSetTable"](this[THIS_PTR], strToStack(table))); } + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenCallIndirectGetTable"](this._ptr)); } + set table(table: string) { preserveStack(() => BinaryenObj["_BinaryenCallIndirectSetTable"](this._ptr, strToStack(table))); } - get params(): Type {return BinaryenObj["_BinaryenCallIndirectGetParams"](this[THIS_PTR]);} - set params(params: Type) { BinaryenObj["_BinaryenCallIndirectSetParams"](this[THIS_PTR], params); } + get params(): Type {return BinaryenObj["_BinaryenCallIndirectGetParams"](this._ptr);} + set params(params: Type) { BinaryenObj["_BinaryenCallIndirectSetParams"](this._ptr, params); } - get results(): Type { return BinaryenObj["_BinaryenCallIndirectGetResults"](this[THIS_PTR]); } - set results(results: Type) { BinaryenObj["_BinaryenCallIndirectSetResults"](this[THIS_PTR], results); } + get results(): Type { return BinaryenObj["_BinaryenCallIndirectGetResults"](this._ptr); } + set results(results: Type) { BinaryenObj["_BinaryenCallIndirectSetResults"](this._ptr, results); } - get numOperands(): number { return BinaryenObj["_BinaryenCallIndirectGetNumOperands"](this[THIS_PTR]); } + get numOperands(): number { return BinaryenObj["_BinaryenCallIndirectGetNumOperands"](this._ptr); } get operands(): ExpressionRef[] { return getAllNested( - this[THIS_PTR], + this._ptr, BinaryenObj["_BinaryenCallIndirectGetNumOperands"], BinaryenObj["_BinaryenCallIndirectGetOperandAt"], ); @@ -139,7 +138,7 @@ export class CallIndirect extends Expression { set operands(operands: readonly ExpressionRef[]) { setAllNested( - this[THIS_PTR], + this._ptr, operands, BinaryenObj["_BinaryenCallIndirectGetNumOperands"], BinaryenObj["_BinaryenCallIndirectSetOperandAt"], @@ -149,23 +148,23 @@ export class CallIndirect extends Expression { } getOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallIndirectGetOperandAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenCallIndirectGetOperandAt"](this._ptr, index); } setOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallIndirectSetOperandAt"](this[THIS_PTR], index, operandExpr); + BinaryenObj["_BinaryenCallIndirectSetOperandAt"](this._ptr, index, operandExpr); } appendOperand(operandExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenCallIndirectAppendOperand"](this[THIS_PTR], operandExpr); + return BinaryenObj["_BinaryenCallIndirectAppendOperand"](this._ptr, operandExpr); } insertOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenCallIndirectInsertOperandAt"](this[THIS_PTR], index, operandExpr); + BinaryenObj["_BinaryenCallIndirectInsertOperandAt"](this._ptr, index, operandExpr); } removeOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenCallIndirectRemoveOperandAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenCallIndirectRemoveOperandAt"](this._ptr, index); } } @@ -176,6 +175,6 @@ export class Return extends Expression { super(ExpressionId.Return, expr); } - get value(): ExpressionRef { return BinaryenObj["_BinaryenReturnGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenReturnSetValue"](this[THIS_PTR], valueExpr); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenReturnGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenReturnSetValue"](this._ptr, valueExpr); } } diff --git a/ts/src/classes/expression/memories.ts b/ts/src/classes/expression/memories.ts index 5f30834d6e4..5c9726b7a7c 100644 --- a/ts/src/classes/expression/memories.ts +++ b/ts/src/classes/expression/memories.ts @@ -3,7 +3,6 @@ import { UTF8ToString, } from "../../-pre.ts"; import { - THIS_PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -25,26 +24,26 @@ export class Load extends Expression { super(ExpressionId.Load, expr); } - get bytes(): number { return BinaryenObj["_BinaryenLoadGetBytes"](this[THIS_PTR]); } - set bytes(bytes: number) { BinaryenObj["_BinaryenLoadSetBytes"](this[THIS_PTR], bytes); } + get bytes(): number { return BinaryenObj["_BinaryenLoadGetBytes"](this._ptr); } + set bytes(bytes: number) { BinaryenObj["_BinaryenLoadSetBytes"](this._ptr, bytes); } - get signed(): boolean { return Boolean(BinaryenObj["_BinaryenLoadIsSigned"](this[THIS_PTR])); } - set signed(isSigned: boolean) { BinaryenObj["_BinaryenLoadSetSigned"](this[THIS_PTR], isSigned); } + get signed(): boolean { return Boolean(BinaryenObj["_BinaryenLoadIsSigned"](this._ptr)); } + set signed(isSigned: boolean) { BinaryenObj["_BinaryenLoadSetSigned"](this._ptr, isSigned); } - get offset(): number { return BinaryenObj["_BinaryenLoadGetOffset"](this[THIS_PTR]); } - set offset(offset: number) { BinaryenObj["_BinaryenLoadSetOffset"](this[THIS_PTR], offset); } + get offset(): number { return BinaryenObj["_BinaryenLoadGetOffset"](this._ptr); } + set offset(offset: number) { BinaryenObj["_BinaryenLoadSetOffset"](this._ptr, offset); } - get align(): number { return BinaryenObj["_BinaryenLoadGetAlign"](this[THIS_PTR]); } - set align(align: number) { BinaryenObj["_BinaryenLoadSetAlign"](this[THIS_PTR], align); } + get align(): number { return BinaryenObj["_BinaryenLoadGetAlign"](this._ptr); } + set align(align: number) { BinaryenObj["_BinaryenLoadSetAlign"](this._ptr, align); } - get ptr(): ExpressionRef { return BinaryenObj["_BinaryenLoadGetPtr"](this[THIS_PTR]); } - set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenLoadSetPtr"](this[THIS_PTR], ptrExpr); } + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenLoadGetPtr"](this._ptr); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenLoadSetPtr"](this._ptr, ptrExpr); } - get atomic(): boolean { return Boolean(BinaryenObj["_BinaryenLoadIsAtomic"](this[THIS_PTR])); } + get atomic(): boolean { return Boolean(BinaryenObj["_BinaryenLoadIsAtomic"](this._ptr)); } // TODO: set atomic - get memoryOrder(): MemoryOrder { return BinaryenObj["_BinaryenLoadGetMemoryOrder"](this[THIS_PTR]); } - set memoryOrder(order: MemoryOrder) { BinaryenObj["_BinaryenLoadSetMemoryOrder"](this[THIS_PTR], order); } + get memoryOrder(): MemoryOrder { return BinaryenObj["_BinaryenLoadGetMemoryOrder"](this._ptr); } + set memoryOrder(order: MemoryOrder) { BinaryenObj["_BinaryenLoadSetMemoryOrder"](this._ptr, order); } } @@ -54,29 +53,29 @@ export class Store extends Expression { super(ExpressionId.Store, expr); } - get bytes(): number { return BinaryenObj["_BinaryenStoreGetBytes"](this[THIS_PTR]); } - set bytes(bytes: number) { BinaryenObj["_BinaryenStoreSetBytes"](this[THIS_PTR], bytes); } + get bytes(): number { return BinaryenObj["_BinaryenStoreGetBytes"](this._ptr); } + set bytes(bytes: number) { BinaryenObj["_BinaryenStoreSetBytes"](this._ptr, bytes); } - get offset(): number { return BinaryenObj["_BinaryenStoreGetOffset"](this[THIS_PTR]); } - set offset(offset: number) { BinaryenObj["_BinaryenStoreSetOffset"](this[THIS_PTR], offset); } + get offset(): number { return BinaryenObj["_BinaryenStoreGetOffset"](this._ptr); } + set offset(offset: number) { BinaryenObj["_BinaryenStoreSetOffset"](this._ptr, offset); } - get align(): number { return BinaryenObj["_BinaryenStoreGetAlign"](this[THIS_PTR]); } - set align(align: number) { BinaryenObj["_BinaryenStoreSetAlign"](this[THIS_PTR], align); } + get align(): number { return BinaryenObj["_BinaryenStoreGetAlign"](this._ptr); } + set align(align: number) { BinaryenObj["_BinaryenStoreSetAlign"](this._ptr, align); } - get ptr(): ExpressionRef { return BinaryenObj["_BinaryenLoadGetPtr"](this[THIS_PTR]); } - set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenLoadSetPtr"](this[THIS_PTR], ptrExpr); } + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenLoadGetPtr"](this._ptr); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenLoadSetPtr"](this._ptr, ptrExpr); } - get value(): ExpressionRef { return BinaryenObj["_BinaryenStoreGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenStoreSetValue"](this[THIS_PTR], valueExpr); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenStoreGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenStoreSetValue"](this._ptr, valueExpr); } - get valueType(): Type { return BinaryenObj["_BinaryenStoreGetValueType"](this[THIS_PTR]); } - set valueType(valueType: Type) { BinaryenObj["_BinaryenStoreSetValueType"](this[THIS_PTR], valueType); } + get valueType(): Type { return BinaryenObj["_BinaryenStoreGetValueType"](this._ptr); } + set valueType(valueType: Type) { BinaryenObj["_BinaryenStoreSetValueType"](this._ptr, valueType); } - get atomic(): boolean {return Boolean(BinaryenObj["_BinaryenStoreIsAtomic"](this[THIS_PTR]));} + get atomic(): boolean {return Boolean(BinaryenObj["_BinaryenStoreIsAtomic"](this._ptr));} // TODO: set atomic - get memoryOrder(): MemoryOrder { return BinaryenObj["_BinaryenStoreGetMemoryOrder"](this[THIS_PTR]); } - set memoryOrder(order: MemoryOrder) { BinaryenObj["_BinaryenStoreSetMemoryOrder"](this[THIS_PTR], order); } + get memoryOrder(): MemoryOrder { return BinaryenObj["_BinaryenStoreGetMemoryOrder"](this._ptr); } + set memoryOrder(order: MemoryOrder) { BinaryenObj["_BinaryenStoreSetMemoryOrder"](this._ptr, order); } } @@ -86,17 +85,17 @@ export class SIMDLoad extends Expression { super(ExpressionId.SIMDLoad, expr); } - get op(): Operation { return BinaryenObj["_BinaryenSIMDLoadGetOp"](this[THIS_PTR]); } - set op(op: Operation) { BinaryenObj["_BinaryenSIMDLoadSetOp"](this[THIS_PTR], op); } + get op(): Operation { return BinaryenObj["_BinaryenSIMDLoadGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenSIMDLoadSetOp"](this._ptr, op); } - get offset(): number { return BinaryenObj["_BinaryenSIMDLoadGetOffset"](this[THIS_PTR]); } - set offset(offset: number) { BinaryenObj["_BinaryenSIMDLoadSetOffset"](this[THIS_PTR], offset); } + get offset(): number { return BinaryenObj["_BinaryenSIMDLoadGetOffset"](this._ptr); } + set offset(offset: number) { BinaryenObj["_BinaryenSIMDLoadSetOffset"](this._ptr, offset); } - get align(): number { return BinaryenObj["_BinaryenSIMDLoadGetAlign"](this[THIS_PTR]); } - set align(align: number) { BinaryenObj["_BinaryenSIMDLoadSetAlign"](this[THIS_PTR], align); } + get align(): number { return BinaryenObj["_BinaryenSIMDLoadGetAlign"](this._ptr); } + set align(align: number) { BinaryenObj["_BinaryenSIMDLoadSetAlign"](this._ptr, align); } - get ptr(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadGetPtr"](this[THIS_PTR]); } - set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadSetPtr"](this[THIS_PTR], ptrExpr); } + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadGetPtr"](this._ptr); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadSetPtr"](this._ptr, ptrExpr); } } @@ -106,25 +105,25 @@ export class SIMDLoadStoreLane extends Expression { super(ExpressionId.SIMDLoadStoreLane, expr); } - get op(): Operation { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetOp"](this[THIS_PTR]); } - set op(op: Operation) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetOp"](this[THIS_PTR], op); } + get op(): Operation { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetOp"](this._ptr, op); } - get offset(): number { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetOffset"](this[THIS_PTR]); } - set offset(offset: number) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetOffset"](this[THIS_PTR], offset); } + get offset(): number { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetOffset"](this._ptr); } + set offset(offset: number) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetOffset"](this._ptr, offset); } - get align(): number { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetAlign"](this[THIS_PTR]); } - set align(align: number) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetAlign"](this[THIS_PTR], align); } + get align(): number { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetAlign"](this._ptr); } + set align(align: number) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetAlign"](this._ptr, align); } - get index(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetIndex"](this[THIS_PTR]); } - set index(index: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetIndex"](this[THIS_PTR], index); } + get index(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetIndex"](this._ptr); } + set index(index: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetIndex"](this._ptr, index); } - get ptr(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetPtr"](this[THIS_PTR]); } - set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetPtr"](this[THIS_PTR], ptrExpr); } + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetPtr"](this._ptr); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetPtr"](this._ptr, ptrExpr); } - get vec(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetVec"](this[THIS_PTR]); } - set vec(vecExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetVec"](this[THIS_PTR], vecExpr); } + get vec(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetVec"](this._ptr); } + set vec(vecExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetVec"](this._ptr, vecExpr); } - get store(): boolean {return Boolean(BinaryenObj["_BinaryenSIMDLoadStoreLaneIsStore"](this[THIS_PTR]));} + get store(): boolean {return Boolean(BinaryenObj["_BinaryenSIMDLoadStoreLaneIsStore"](this._ptr));} } @@ -142,8 +141,8 @@ export class MemoryGrow extends Expression { super(ExpressionId.MemoryGrow, expr); } - get delta(): ExpressionRef { return BinaryenObj["_BinaryenMemoryGrowGetDelta"](this[THIS_PTR]); } - set delta(deltaExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryGrowSetDelta"](this[THIS_PTR], deltaExpr); } + get delta(): ExpressionRef { return BinaryenObj["_BinaryenMemoryGrowGetDelta"](this._ptr); } + set delta(deltaExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryGrowSetDelta"](this._ptr, deltaExpr); } } @@ -153,14 +152,14 @@ export class MemoryFill extends Expression { super(ExpressionId.MemoryFill, expr); } - get dest(): ExpressionRef { return BinaryenObj["_BinaryenMemoryFillGetDest"](this[THIS_PTR]); } - set dest(destExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryFillSetDest"](this[THIS_PTR], destExpr); } + get dest(): ExpressionRef { return BinaryenObj["_BinaryenMemoryFillGetDest"](this._ptr); } + set dest(destExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryFillSetDest"](this._ptr, destExpr); } - get value(): ExpressionRef { return BinaryenObj["_BinaryenMemoryFillGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryFillSetValue"](this[THIS_PTR], valueExpr); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenMemoryFillGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryFillSetValue"](this._ptr, valueExpr); } - get size(): ExpressionRef { return BinaryenObj["_BinaryenMemoryFillGetSize"](this[THIS_PTR]); } - set size(sizeExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryFillSetSize"](this[THIS_PTR], sizeExpr); } + get size(): ExpressionRef { return BinaryenObj["_BinaryenMemoryFillGetSize"](this._ptr); } + set size(sizeExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryFillSetSize"](this._ptr, sizeExpr); } } @@ -170,14 +169,14 @@ export class MemoryCopy extends Expression { super(ExpressionId.MemoryCopy, expr); } - get dest(): ExpressionRef { return BinaryenObj["_BinaryenMemoryCopyGetDest"](this[THIS_PTR]); } - set dest(destExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryCopySetDest"](this[THIS_PTR], destExpr); } + get dest(): ExpressionRef { return BinaryenObj["_BinaryenMemoryCopyGetDest"](this._ptr); } + set dest(destExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryCopySetDest"](this._ptr, destExpr); } - get source(): ExpressionRef { return BinaryenObj["_BinaryenMemoryCopyGetSource"](this[THIS_PTR]); } - set source(sourceExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryCopySetSource"](this[THIS_PTR], sourceExpr); } + get source(): ExpressionRef { return BinaryenObj["_BinaryenMemoryCopyGetSource"](this._ptr); } + set source(sourceExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryCopySetSource"](this._ptr, sourceExpr); } - get size(): ExpressionRef { return BinaryenObj["_BinaryenMemoryCopyGetSize"](this[THIS_PTR]); } - set size(sizeExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryCopySetSize"](this[THIS_PTR], sizeExpr); } + get size(): ExpressionRef { return BinaryenObj["_BinaryenMemoryCopyGetSize"](this._ptr); } + set size(sizeExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryCopySetSize"](this._ptr, sizeExpr); } } @@ -187,17 +186,17 @@ export class MemoryInit extends Expression { super(ExpressionId.MemoryInit, expr); } - get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenMemoryInitGetSegment"](this[THIS_PTR])); } - set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenMemoryCopySetDest"](this[THIS_PTR], strToStack(segment))); } + get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenMemoryInitGetSegment"](this._ptr)); } + set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenMemoryCopySetDest"](this._ptr, strToStack(segment))); } - get dest(): ExpressionRef { return BinaryenObj["_BinaryenMemoryInitGetDest"](this[THIS_PTR]); } - set dest(destExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryInitSetDest"](this[THIS_PTR], destExpr); } + get dest(): ExpressionRef { return BinaryenObj["_BinaryenMemoryInitGetDest"](this._ptr); } + set dest(destExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryInitSetDest"](this._ptr, destExpr); } - get offset(): ExpressionRef { return BinaryenObj["_BinaryenMemoryInitGetOffset"](this[THIS_PTR]); } - set offset(offsetExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryInitSetOffset"](this[THIS_PTR], offsetExpr); } + get offset(): ExpressionRef { return BinaryenObj["_BinaryenMemoryInitGetOffset"](this._ptr); } + set offset(offsetExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryInitSetOffset"](this._ptr, offsetExpr); } - get size(): ExpressionRef { return BinaryenObj["_BinaryenMemoryInitGetSize"](this[THIS_PTR]); } - set size(sizeExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryInitGetSize"](this[THIS_PTR], sizeExpr); } + get size(): ExpressionRef { return BinaryenObj["_BinaryenMemoryInitGetSize"](this._ptr); } + set size(sizeExpr: ExpressionRef) { BinaryenObj["_BinaryenMemoryInitGetSize"](this._ptr, sizeExpr); } } @@ -207,6 +206,6 @@ export class DataDrop extends Expression { super(ExpressionId.DataDrop, expr); } - get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenDataDropGetSegment"](this[THIS_PTR])); } - set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenDataDropSetSegment"](this[THIS_PTR], strToStack(segment))); } + get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenDataDropGetSegment"](this._ptr)); } + set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenDataDropSetSegment"](this._ptr, strToStack(segment))); } } diff --git a/ts/src/classes/expression/parametrics.ts b/ts/src/classes/expression/parametrics.ts index 62961a81ed8..4b825072e3e 100644 --- a/ts/src/classes/expression/parametrics.ts +++ b/ts/src/classes/expression/parametrics.ts @@ -1,9 +1,6 @@ import { BinaryenObj, } from "../../-pre.ts"; -import { - THIS_PTR, -} from "../../-utils.ts"; import { ExpressionId, type ExpressionRef, @@ -19,8 +16,8 @@ export class Drop extends Expression { super(ExpressionId.Drop, expr); } - get value(): ExpressionRef { return BinaryenObj["_BinaryenDropGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenDropSetValue"](this[THIS_PTR], valueExpr); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenDropGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenDropSetValue"](this._ptr, valueExpr); } } @@ -30,12 +27,12 @@ export class Select extends Expression { super(ExpressionId.Select, expr); } - get condition(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetCondition"](this[THIS_PTR]); } - set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetCondition"](this[THIS_PTR], condExpr); } + get condition(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetCondition"](this._ptr); } + set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetCondition"](this._ptr, condExpr); } - get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetIfTrue"](this[THIS_PTR]); } - set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetIfTrue"](this[THIS_PTR], ifTrueExpr); } + get ifTrue(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetIfTrue"](this._ptr); } + set ifTrue(ifTrueExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetIfTrue"](this._ptr, ifTrueExpr); } - get ifFalse(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetIfFalse"](this[THIS_PTR]); } - set ifFalse(ifFalseExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetIfFalse"](this[THIS_PTR], ifFalseExpr); } + get ifFalse(): ExpressionRef { return BinaryenObj["_BinaryenSelectGetIfFalse"](this._ptr); } + set ifFalse(ifFalseExpr: ExpressionRef) { BinaryenObj["_BinaryenSelectSetIfFalse"](this._ptr, ifFalseExpr); } } diff --git a/ts/src/classes/expression/tables.ts b/ts/src/classes/expression/tables.ts index 5ffd6f0a6b9..83f6bbed679 100644 --- a/ts/src/classes/expression/tables.ts +++ b/ts/src/classes/expression/tables.ts @@ -3,7 +3,6 @@ import { UTF8ToString, } from "../../-pre.ts"; import { - THIS_PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -22,11 +21,11 @@ export class TableGet extends Expression { super(ExpressionId.TableGet, expr); } - get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetGetTable"](this[THIS_PTR])); } - set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGetSetTable"](this[THIS_PTR], strToStack(name))); } + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetGetTable"](this._ptr)); } + set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGetSetTable"](this._ptr, strToStack(name))); } - get index(): number { return BinaryenObj["_BinaryenTableGetGetIndex"](this[THIS_PTR]); } - set index(index: number) { BinaryenObj["_BinaryenTableGetSetIndex"](this[THIS_PTR], index); } + get index(): number { return BinaryenObj["_BinaryenTableGetGetIndex"](this._ptr); } + set index(index: number) { BinaryenObj["_BinaryenTableGetSetIndex"](this._ptr, index); } } @@ -36,14 +35,14 @@ export class TableSet extends Expression { super(ExpressionId.TableSet, expr); } - get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetGetTable"](this[THIS_PTR])); } - set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGetSetTable"](this[THIS_PTR], strToStack(name))); } + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetGetTable"](this._ptr)); } + set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGetSetTable"](this._ptr, strToStack(name))); } - get index(): number { return BinaryenObj["_BinaryenTableSetGetIndex"](this[THIS_PTR]); } - set index(index: number) { BinaryenObj["_BinaryenTableSetSetIndex"](this[THIS_PTR], index); } + get index(): number { return BinaryenObj["_BinaryenTableSetGetIndex"](this._ptr); } + set index(index: number) { BinaryenObj["_BinaryenTableSetSetIndex"](this._ptr, index); } - get value(): ExpressionRef { return BinaryenObj["_BinaryenTableSetGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenTableSetSetValue"](this[THIS_PTR], valueExpr); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenTableSetGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenTableSetSetValue"](this._ptr, valueExpr); } } @@ -53,8 +52,8 @@ export class TableSize extends Expression { super(ExpressionId.TableSize, expr); } - get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableSizeGetTable"](this[THIS_PTR])); } - set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableSizeSetTable"](this[THIS_PTR], strToStack(name))); } + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableSizeGetTable"](this._ptr)); } + set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableSizeSetTable"](this._ptr, strToStack(name))); } } @@ -64,12 +63,12 @@ export class TableGrow extends Expression { super(ExpressionId.TableSize, expr); } - get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGrowGetTable"](this[THIS_PTR])); } - set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGrowSetTable"](this[THIS_PTR], strToStack(name))); } + get table(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGrowGetTable"](this._ptr)); } + set table(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableGrowSetTable"](this._ptr, strToStack(name))); } - get value(): ExpressionRef { return BinaryenObj["_BinaryenTableGrowGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenTableGrowSetValue"](this[THIS_PTR], valueExpr); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenTableGrowGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenTableGrowSetValue"](this._ptr, valueExpr); } - get delta(): ExpressionRef { return BinaryenObj["_BinaryenTableGrowGetDelta"](this[THIS_PTR]); } - set delta(deltaExpr: ExpressionRef) { BinaryenObj["_BinaryenTableGrowSetDelta"](this[THIS_PTR], deltaExpr); } + get delta(): ExpressionRef { return BinaryenObj["_BinaryenTableGrowGetDelta"](this._ptr); } + set delta(deltaExpr: ExpressionRef) { BinaryenObj["_BinaryenTableGrowSetDelta"](this._ptr, deltaExpr); } } diff --git a/ts/src/classes/expression/throws.ts b/ts/src/classes/expression/throws.ts index eff23506f5e..8e5c1e907d1 100644 --- a/ts/src/classes/expression/throws.ts +++ b/ts/src/classes/expression/throws.ts @@ -3,7 +3,6 @@ import { UTF8ToString, } from "../../-pre.ts"; import { - THIS_PTR, getAllNested, preserveStack, setAllNested, @@ -24,14 +23,14 @@ export class Throw extends Expression { super(ExpressionId.Throw, expr); } - get tag(): string { return UTF8ToString(BinaryenObj["_BinaryenThrowGetTag"](this[THIS_PTR])); } - set tag(tagName: string) { preserveStack(() => BinaryenObj["_BinaryenThrowSetTag"](this[THIS_PTR], strToStack(tagName))); } + get tag(): string { return UTF8ToString(BinaryenObj["_BinaryenThrowGetTag"](this._ptr)); } + set tag(tagName: string) { preserveStack(() => BinaryenObj["_BinaryenThrowSetTag"](this._ptr, strToStack(tagName))); } - getNumOperands(): number { return BinaryenObj["_BinaryenThrowGetNumOperands"](this[THIS_PTR]); } + getNumOperands(): number { return BinaryenObj["_BinaryenThrowGetNumOperands"](this._ptr); } get operands(): ExpressionRef[] { return getAllNested( - this[THIS_PTR], + this._ptr, BinaryenObj["_BinaryenThrowGetNumOperands"], BinaryenObj["_BinaryenThrowGetOperandAt"], ); @@ -39,7 +38,7 @@ export class Throw extends Expression { set operands(operands: readonly ExpressionRef[]) { setAllNested( - this[THIS_PTR], + this._ptr, operands, BinaryenObj["_BinaryenThrowGetNumOperands"], BinaryenObj["_BinaryenThrowSetOperandAt"], @@ -50,23 +49,23 @@ export class Throw extends Expression { getOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenThrowGetOperandAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenThrowGetOperandAt"](this._ptr, index); } setOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenThrowSetOperandAt"](this[THIS_PTR], index, operandExpr); + BinaryenObj["_BinaryenThrowSetOperandAt"](this._ptr, index, operandExpr); } appendOperand(operandExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenThrowAppendOperand"](this[THIS_PTR], operandExpr); + return BinaryenObj["_BinaryenThrowAppendOperand"](this._ptr, operandExpr); } insertOperandAt(index: number, operandExpr: ExpressionRef): void { - BinaryenObj["_BinaryenThrowInsertOperandAt"](this[THIS_PTR], index, operandExpr); + BinaryenObj["_BinaryenThrowInsertOperandAt"](this._ptr, index, operandExpr); } removeOperandAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenThrowRemoveOperandAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenThrowRemoveOperandAt"](this._ptr, index); } } @@ -78,12 +77,12 @@ export class Rethrow extends Expression { } get target(): string | null { - const target = BinaryenObj["_BinaryenRethrowGetTarget"](this[THIS_PTR]); + const target = BinaryenObj["_BinaryenRethrowGetTarget"](this._ptr); return target ? UTF8ToString(target) : null; } set target(target: string) { - preserveStack(() => BinaryenObj["_BinaryenRethrowSetTarget"](this[THIS_PTR], strToStack(target))); + preserveStack(() => BinaryenObj["_BinaryenRethrowSetTarget"](this._ptr, strToStack(target))); } } @@ -94,27 +93,27 @@ export class Try extends Expression { super(ExpressionId.Try, expr); } - get body(): ExpressionRef { return BinaryenObj["_BinaryenTryGetBody"](this[THIS_PTR]); } - set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenTrySetBody"](this[THIS_PTR], bodyExpr); } + get body(): ExpressionRef { return BinaryenObj["_BinaryenTryGetBody"](this._ptr); } + set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenTrySetBody"](this._ptr, bodyExpr); } - get numCatchTags(): number { return BinaryenObj["_BinaryenTryGetNumCatchTags"](this[THIS_PTR]); } + get numCatchTags(): number { return BinaryenObj["_BinaryenTryGetNumCatchTags"](this._ptr); } - get numCatchBodies(): number { return BinaryenObj["_BinaryenTryGetNumCatchBodies"](this[THIS_PTR]); } + get numCatchBodies(): number { return BinaryenObj["_BinaryenTryGetNumCatchBodies"](this._ptr); } - get delegate(): boolean { return Boolean(BinaryenObj["_BinaryenTryIsDelegate"](this[THIS_PTR])); } + get delegate(): boolean { return Boolean(BinaryenObj["_BinaryenTryIsDelegate"](this._ptr)); } get name(): string | null { - const name = BinaryenObj["_BinaryenTryGetName"](this[THIS_PTR]); + const name = BinaryenObj["_BinaryenTryGetName"](this._ptr); return name ? UTF8ToString(name) : null; } set name(name: string) { - preserveStack(() => BinaryenObj["_BinaryenTrySetName"](this[THIS_PTR], strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenTrySetName"](this._ptr, strToStack(name))); } get catchTags(): string[] { return getAllNested( - this[THIS_PTR], + this._ptr, BinaryenObj["_BinaryenTryGetNumCatchTags"], BinaryenObj["_BinaryenTryGetCatchTagAt"], ).map((p) => UTF8ToString(p)); @@ -122,7 +121,7 @@ export class Try extends Expression { set catchTags(catchTags: readonly string[]) { preserveStack(() => setAllNested( - this[THIS_PTR], + this._ptr, catchTags.map(strToStack), BinaryenObj["_BinaryenTryGetNumCatchTags"], BinaryenObj["_BinaryenTrySetCatchTagAt"], @@ -133,7 +132,7 @@ export class Try extends Expression { get catchBodies(): ExpressionRef[] { return getAllNested( - this[THIS_PTR], + this._ptr, BinaryenObj["_BinaryenTryGetNumCatchBodies"], BinaryenObj["_BinaryenTryGetCatchBodyAt"], ); @@ -141,7 +140,7 @@ export class Try extends Expression { set catchBodies(catchBodies: readonly ExpressionRef[]) { setAllNested( - this[THIS_PTR], + this._ptr, catchBodies, BinaryenObj["_BinaryenTryGetNumCatchBodies"], BinaryenObj["_BinaryenTrySetCatchBodyAt"], @@ -151,55 +150,55 @@ export class Try extends Expression { } get delegateTarget(): string | null { - const name = BinaryenObj["_BinaryenTryGetDelegateTarget"](this[THIS_PTR]); + const name = BinaryenObj["_BinaryenTryGetDelegateTarget"](this._ptr); return name ? UTF8ToString(name) : null; } set delegateTarget(name: string) { - preserveStack(() => BinaryenObj["_BinaryenTrySetDelegateTarget"](this[THIS_PTR], strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenTrySetDelegateTarget"](this._ptr, strToStack(name))); } getCatchTagAt(index: number): string { - return UTF8ToString(BinaryenObj["_BinaryenTryGetCatchTagAt"](this[THIS_PTR], index)); + return UTF8ToString(BinaryenObj["_BinaryenTryGetCatchTagAt"](this._ptr, index)); } setCatchTagAt(index: number, catchTag: string): void { - preserveStack(() => BinaryenObj["_BinaryenTrySetCatchTagAt"](this[THIS_PTR], index, strToStack(catchTag))); + preserveStack(() => BinaryenObj["_BinaryenTrySetCatchTagAt"](this._ptr, index, strToStack(catchTag))); } appendCatchTag(catchTag: string): void { - preserveStack(() => BinaryenObj["_BinaryenTryAppendCatchTag"](this[THIS_PTR], strToStack(catchTag))); + preserveStack(() => BinaryenObj["_BinaryenTryAppendCatchTag"](this._ptr, strToStack(catchTag))); } insertCatchTagAt(index: number, catchTag: string): void { - preserveStack(() => BinaryenObj["_BinaryenTryInsertCatchTagAt"](this[THIS_PTR], index, strToStack(catchTag))); + preserveStack(() => BinaryenObj["_BinaryenTryInsertCatchTagAt"](this._ptr, index, strToStack(catchTag))); } removeCatchTagAt(index: number): string { - return UTF8ToString(BinaryenObj["_BinaryenTryRemoveCatchTagAt"](this[THIS_PTR], index)); + return UTF8ToString(BinaryenObj["_BinaryenTryRemoveCatchTagAt"](this._ptr, index)); } getCatchBodyAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenTryGetCatchBodyAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenTryGetCatchBodyAt"](this._ptr, index); } setCatchBodyAt(index: number, catchExpr: ExpressionRef): void { - BinaryenObj["_BinaryenTrySetCatchBodyAt"](this[THIS_PTR], index, catchExpr); + BinaryenObj["_BinaryenTrySetCatchBodyAt"](this._ptr, index, catchExpr); } appendCatchBody(catchExpr: ExpressionRef): number { - return BinaryenObj["_BinaryenTryAppendCatchBody"](this[THIS_PTR], catchExpr); + return BinaryenObj["_BinaryenTryAppendCatchBody"](this._ptr, catchExpr); } insertCatchBodyAt(index: number, catchExpr: ExpressionRef): void { - BinaryenObj["_BinaryenTryInsertCatchBodyAt"](this[THIS_PTR], index, catchExpr); + BinaryenObj["_BinaryenTryInsertCatchBodyAt"](this._ptr, index, catchExpr); } removeCatchBodyAt(index: number): ExpressionRef { - return BinaryenObj["_BinaryenTryRemoveCatchBodyAt"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenTryRemoveCatchBodyAt"](this._ptr, index); } hasCatchAll(): boolean { - return Boolean(BinaryenObj["_BinaryenTryHasCatchAll"](this[THIS_PTR])); + return Boolean(BinaryenObj["_BinaryenTryHasCatchAll"](this._ptr)); } } diff --git a/ts/src/classes/expression/variables.ts b/ts/src/classes/expression/variables.ts index 4c750bd3f6b..a1e502cd00c 100644 --- a/ts/src/classes/expression/variables.ts +++ b/ts/src/classes/expression/variables.ts @@ -3,7 +3,6 @@ import { UTF8ToString, } from "../../-pre.ts"; import { - THIS_PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -22,8 +21,8 @@ export class LocalGet extends Expression { super(ExpressionId.LocalGet, expr); } - get index(): number { return BinaryenObj["_BinaryenLocalGetGetIndex"](this[THIS_PTR]); } - set index(index: number) { BinaryenObj["_BinaryenLocalGetSetIndex"](this[THIS_PTR], index); } + get index(): number { return BinaryenObj["_BinaryenLocalGetGetIndex"](this._ptr); } + set index(index: number) { BinaryenObj["_BinaryenLocalGetSetIndex"](this._ptr, index); } } @@ -33,14 +32,14 @@ export class LocalSet extends Expression { super(ExpressionId.LocalSet, expr); } - get index(): number { return BinaryenObj["_BinaryenLocalSetGetIndex"](this[THIS_PTR]); } - set index(index: number) { BinaryenObj["_BinaryenLocalSetSetIndex"](this[THIS_PTR], index); } + get index(): number { return BinaryenObj["_BinaryenLocalSetGetIndex"](this._ptr); } + set index(index: number) { BinaryenObj["_BinaryenLocalSetSetIndex"](this._ptr, index); } - get value(): ExpressionRef { return BinaryenObj["_BinaryenLocalSetGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenLocalSetSetValue"](this[THIS_PTR], valueExpr); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenLocalSetGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenLocalSetSetValue"](this._ptr, valueExpr); } get isTee(): boolean { - return Boolean(BinaryenObj["_BinaryenLocalSetIsTee"](this[THIS_PTR])); + return Boolean(BinaryenObj["_BinaryenLocalSetIsTee"](this._ptr)); } } @@ -51,8 +50,8 @@ export class GlobalGet extends Expression { super(ExpressionId.GlobalGet, expr); } - get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalGetGetName"](this[THIS_PTR])); } - set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalGetSetName"](this[THIS_PTR], strToStack(name))); } + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalGetGetName"](this._ptr)); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalGetSetName"](this._ptr, strToStack(name))); } } @@ -62,9 +61,9 @@ export class GlobalSet extends Expression { super(ExpressionId.GlobalSet, expr); } - get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalSetGetName"](this[THIS_PTR])); } - set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalSetSetName"](this[THIS_PTR], strToStack(name))); } + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenGlobalSetGetName"](this._ptr)); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenGlobalSetSetName"](this._ptr, strToStack(name))); } - get value(): ExpressionRef { return BinaryenObj["_BinaryenGlobalSetGetValue"](this[THIS_PTR]); } - set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenGlobalSetSetValue"](this[THIS_PTR], valueExpr); } + get value(): ExpressionRef { return BinaryenObj["_BinaryenGlobalSetGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenGlobalSetSetValue"](this._ptr, valueExpr); } } diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index 01efa184934..d4aa54a8af4 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -3,7 +3,6 @@ import { UTF8ToString, } from "../../-pre.ts"; import { - THIS_PTR, getAllNested, i32sToStack, preserveStack, @@ -24,7 +23,8 @@ import type { * Information about a function in a WASM module. */ class BinaryenFunction { - private readonly [THIS_PTR]: FunctionRef; + /** The underlying C-API pointer of the wrapped function. */ + readonly #ptr: FunctionRef; readonly module: string; readonly base: string; @@ -38,47 +38,47 @@ class BinaryenFunction { constructor(func: FunctionRef) { - this[THIS_PTR] = func; - this.module = UTF8ToString(BinaryenObj["_BinaryenFunctionImportGetModule"](this[THIS_PTR])); - this.base = UTF8ToString(BinaryenObj["_BinaryenFunctionImportGetBase"](this[THIS_PTR])); - this.name = UTF8ToString(BinaryenObj["_BinaryenFunctionGetName"](this[THIS_PTR])); - this.type = BinaryenObj["_BinaryenFunctionGetType"](this[THIS_PTR]); - this.params = BinaryenObj["_BinaryenFunctionGetParams"](this[THIS_PTR]); - this.results = BinaryenObj["_BinaryenFunctionGetResults"](this[THIS_PTR]); - this.numVars = BinaryenObj["_BinaryenFunctionGetNumVars"](this[THIS_PTR]); - this.numLocals = BinaryenObj["_BinaryenFunctionGetNumLocals"](this[THIS_PTR]); + this.#ptr = func; + this.module = UTF8ToString(BinaryenObj["_BinaryenFunctionImportGetModule"](this.#ptr)); + this.base = UTF8ToString(BinaryenObj["_BinaryenFunctionImportGetBase"](this.#ptr)); + this.name = UTF8ToString(BinaryenObj["_BinaryenFunctionGetName"](this.#ptr)); + this.type = BinaryenObj["_BinaryenFunctionGetType"](this.#ptr); + this.params = BinaryenObj["_BinaryenFunctionGetParams"](this.#ptr); + this.results = BinaryenObj["_BinaryenFunctionGetResults"](this.#ptr); + this.numVars = BinaryenObj["_BinaryenFunctionGetNumVars"](this.#ptr); + this.numLocals = BinaryenObj["_BinaryenFunctionGetNumLocals"](this.#ptr); this.vars = getAllNested(func, BinaryenObj["_BinaryenFunctionGetNumVars"], BinaryenObj["_BinaryenFunctionGetVar"]); } get body(): ExpressionRef { - return BinaryenObj["_BinaryenFunctionGetBody"](this[THIS_PTR]); + return BinaryenObj["_BinaryenFunctionGetBody"](this.#ptr); } set body(bodyExpr: ExpressionRef) { - BinaryenObj["_BinaryenFunctionSetBody"](this[THIS_PTR], bodyExpr); + BinaryenObj["_BinaryenFunctionSetBody"](this.#ptr, bodyExpr); } valueOf(): FunctionRef { - return this[THIS_PTR]; + return this.#ptr; } getVar(index: number): Type { - return BinaryenObj["_BinaryenFunctionGetVar"](this[THIS_PTR], index); + return BinaryenObj["_BinaryenFunctionGetVar"](this.#ptr, index); } hasLocalName(index: number): boolean { - return Boolean(BinaryenObj["_BinaryenFunctionHasLocalName"](this[THIS_PTR], index)); + return Boolean(BinaryenObj["_BinaryenFunctionHasLocalName"](this.#ptr, index)); } getLocalName(index: number): string { - return UTF8ToString(BinaryenObj["_BinaryenFunctionGetLocalName"](this[THIS_PTR], index)); + return UTF8ToString(BinaryenObj["_BinaryenFunctionGetLocalName"](this.#ptr, index)); } setLocalName(index: number, name: string): void { preserveStack(() => { - BinaryenObj["_BinaryenFunctionSetLocalName"](this[THIS_PTR], index, strToStack(name)); + BinaryenObj["_BinaryenFunctionSetLocalName"](this.#ptr, index, strToStack(name)); }); } } diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 12963486e91..3bbf6dfd435 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -158,7 +158,10 @@ export class Module { /** @class */ static readonly Export = Export_; - /** @internal */ + /** + * The underlying C-API pointer of the wrapped module. + * @internal + */ readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); // ## Expression Manipulation ## // diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index c7119e1c6d7..29a736e528d 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -3,7 +3,6 @@ import { UTF8ToString, } from "../../-pre.ts"; import { - THIS_PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -24,44 +23,45 @@ import type { * Information about a table in a WASM module. */ export class Table { - private readonly [THIS_PTR]: TableRef; + /** The underlying C-API pointer of the wrapped table. */ + readonly #ptr: TableRef; readonly module: string; readonly base: string; constructor(table: TableRef) { - this[THIS_PTR] = table; - this.module = UTF8ToString(BinaryenObj["_BinaryenTableImportGetModule"](this[THIS_PTR])); - this.base = UTF8ToString(BinaryenObj["_BinaryenTableImportGetBase"](this[THIS_PTR])); + this.#ptr = table; + this.module = UTF8ToString(BinaryenObj["_BinaryenTableImportGetModule"](this.#ptr)); + this.base = UTF8ToString(BinaryenObj["_BinaryenTableImportGetBase"](this.#ptr)); } /** The name of this table */ - get name(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetName"](this[THIS_PTR])); } - set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableSetName"](this[THIS_PTR], strToStack(name))); } + get name(): string { return UTF8ToString(BinaryenObj["_BinaryenTableGetName"](this.#ptr)); } + set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenTableSetName"](this.#ptr, strToStack(name))); } /** The initial number of pages of this table. */ - get initial(): number { return BinaryenObj["_BinaryenTableGetInitial"](this[THIS_PTR]); } - set initial(initial: number) { BinaryenObj["_BinaryenTableSetInitial"](this[THIS_PTR], initial); } + get initial(): number { return BinaryenObj["_BinaryenTableGetInitial"](this.#ptr); } + set initial(initial: number) { BinaryenObj["_BinaryenTableSetInitial"](this.#ptr, initial); } /** The maximum number of pages of this table. */ - get max(): number { return BinaryenObj["_BinaryenTableGetMax"](this[THIS_PTR]); } - set max(max: number) { BinaryenObj["_BinaryenTableSetMax"](this[THIS_PTR], max); } + get max(): number { return BinaryenObj["_BinaryenTableGetMax"](this.#ptr); } + set max(max: number) { BinaryenObj["_BinaryenTableSetMax"](this.#ptr, max); } /** The type of this table. */ - get type(): Type { return BinaryenObj["_BinaryenTableGetType"](this[THIS_PTR]); } - set type(tableType: Type) { BinaryenObj["_BinaryenTableSetType"](this[THIS_PTR], tableType); } + get type(): Type { return BinaryenObj["_BinaryenTableGetType"](this.#ptr); } + set type(tableType: Type) { BinaryenObj["_BinaryenTableSetType"](this.#ptr, tableType); } valueOf(): TableRef { - return this[THIS_PTR]; + return this.#ptr; } /** * @returns does this table have a maximum number of pages? */ hasMax(): boolean { - return Boolean(BinaryenObj["_BinaryenTableHasMax"](this[THIS_PTR])); + return Boolean(BinaryenObj["_BinaryenTableHasMax"](this.#ptr)); } } From 8a8b1e761fe7cae231660ccc443ba2b84dec848e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 18:38:15 -0400 Subject: [PATCH 169/247] feat: add ModuleRef & MemoryRef --- ts/src/classes/module/Module.ts | 3 ++- ts/src/constants.ts | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 3bbf6dfd435..798c1e81225 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -17,6 +17,7 @@ import { type ExpressionRef, type FunctionRef, type HeapType, + type ModuleRef, type SideEffect, type TableRef, type Type, @@ -162,7 +163,7 @@ export class Module { * The underlying C-API pointer of the wrapped module. * @internal */ - readonly ptr: number = BinaryenObj["_BinaryenModuleCreate"](); + readonly ptr: ModuleRef = BinaryenObj["_BinaryenModuleCreate"](); // ## Expression Manipulation ## // /** diff --git a/ts/src/constants.ts b/ts/src/constants.ts index d45c13c7586..2b86d0fe5cd 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -17,11 +17,14 @@ export type PackedType = number; export type ExpressionRef = number; // ### Module Components ### // +/** Reference to a {@link Module}. */ +export type ModuleRef = number; /** Reference to a {@link Module.Tag}. */ export type TagRef = number; /** Reference to a {@link Module.Global}. */ export type GlobalRef = number; -// no `MemoryRef` +/** Reference to a {@link Module.Memory}. */ +export type MemoryRef = number; /** Reference to a {@link Module.Table}. */ export type TableRef = number; /** Reference to a {@link Module.Function}. */ From e1c2782b3d52e1b11ff5e592ef5b18c5935e16ae Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 19:15:02 -0400 Subject: [PATCH 170/247] refactor: use internal field `Module#[PTR]` --- ts/src/-utils.ts | 11 +++- ts/src/classes/ExpressionRunner.ts | 3 +- ts/src/classes/Relooper.ts | 3 +- ts/src/classes/module/DataSegment.ts | 9 ++-- ts/src/classes/module/ElementSegment.ts | 13 ++--- ts/src/classes/module/Export.ts | 11 ++-- ts/src/classes/module/Function.ts | 11 ++-- ts/src/classes/module/Global.ts | 11 ++-- ts/src/classes/module/Import.ts | 3 +- ts/src/classes/module/Memory.ts | 19 +++---- ts/src/classes/module/Module.ts | 53 ++++++++++--------- ts/src/classes/module/Table.ts | 15 +++--- ts/src/classes/module/Tag.ts | 7 +-- ts/src/globals.ts | 3 +- ts/src/services/expression-builder/-utils.ts | 29 +++++----- .../services/expression-builder/aggregate.ts | 45 ++++++++-------- .../expression-builder/expressionBuilder.ts | 5 +- ts/src/services/expression-builder/generic.ts | 43 +++++++-------- ts/src/services/expression-builder/i64.ts | 11 ++-- ts/src/services/expression-builder/i8x16.ts | 3 +- ts/src/services/expression-builder/memory.ts | 17 +++--- .../services/expression-builder/reference.ts | 21 ++++---- ts/src/services/expression-builder/table.ts | 9 ++-- ts/src/services/expression-builder/v128.ts | 3 +- .../services/expression-builder/variable.ts | 11 ++-- 25 files changed, 202 insertions(+), 167 deletions(-) diff --git a/ts/src/-utils.ts b/ts/src/-utils.ts index 37b3a2493dd..d2fdfe6f785 100644 --- a/ts/src/-utils.ts +++ b/ts/src/-utils.ts @@ -14,8 +14,15 @@ import { -/** Private symbol used to store the underlying C-API pointer of a wrapped object. */ -export const THIS_PTR: unique symbol = Symbol(); +/** + * “Secret” symbol used to store the underlying C-API pointer of an object. + * + * Sometimes an object’s underlying pointer value needs to be visible outside its class + * so that other classes in this codebase can access it, + * but using a regular public field would expose it to the world. + * Therefore this unique symbol is used as a key, which only we have access to. + */ +export const PTR: unique symbol = Symbol(); diff --git a/ts/src/classes/ExpressionRunner.ts b/ts/src/classes/ExpressionRunner.ts index 422c15362a4..f743285b5c4 100644 --- a/ts/src/classes/ExpressionRunner.ts +++ b/ts/src/classes/ExpressionRunner.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../-utils.ts"; @@ -29,7 +30,7 @@ export class ExpressionRunner { readonly #ptr: number; constructor(mod: Module, flags: ExpressionRunnerFlag, maxDepth: number, maxLoopIterations: number) { - this.#ptr = BinaryenObj["_ExpressionRunnerCreate"](mod.ptr, flags, maxDepth, maxLoopIterations); + this.#ptr = BinaryenObj["_ExpressionRunnerCreate"](mod[PTR], flags, maxDepth, maxLoopIterations); } setLocalValue(index: number, valueExpr: ExpressionRef): boolean { diff --git a/ts/src/classes/Relooper.ts b/ts/src/classes/Relooper.ts index 111c01ea8ea..c34227fb3cd 100644 --- a/ts/src/classes/Relooper.ts +++ b/ts/src/classes/Relooper.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../-pre.ts"; import { + PTR, i32sToStack, preserveStack, } from "../-utils.ts"; @@ -27,7 +28,7 @@ export class Relooper { * @param mod the binaryen Module */ constructor(mod: Module) { - this.#ptr = BinaryenObj["_RelooperCreate"](mod.ptr); + this.#ptr = BinaryenObj["_RelooperCreate"](mod[PTR]); } /** diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index 107e8a305f5..b4eac1002ee 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -6,6 +6,7 @@ import { UTF8ToString, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -32,7 +33,7 @@ export class DataSegment { this.name = UTF8ToString(BinaryenObj["_BinaryenDataSegmentGetName"](segment)); this.passive = Boolean(BinaryenObj["_BinaryenGetDataSegmentPassive"](segment)); if (!this.passive) { - this.offset = BinaryenObj["_BinaryenGetDataSegmentByteOffset"](mod.ptr, segment); + this.offset = BinaryenObj["_BinaryenGetDataSegmentByteOffset"](mod[PTR], segment); } const size = BinaryenObj["_BinaryenGetDataSegmentByteLength"](segment); @@ -57,16 +58,16 @@ export class ModuleDataSegments { /** Gets a data segment by name. */ get(name: string): DataSegmentRef { - return preserveStack(() => BinaryenObj["_BinaryenGetDataSegment"](this.mod.ptr, strToStack(name))); + return preserveStack(() => BinaryenObj["_BinaryenGetDataSegment"](this.mod[PTR], strToStack(name))); } /** Gets a data segment by index. */ getByIndex(index: number): DataSegmentRef { - return BinaryenObj["_BinaryenGetDataSegmentByIndex"](this.mod.ptr, index); + return BinaryenObj["_BinaryenGetDataSegmentByIndex"](this.mod[PTR], index); } /** Gets the number of data segments within the module. */ count(): number { - return BinaryenObj["_BinaryenGetNumDataSegments"](this.mod.ptr); + return BinaryenObj["_BinaryenGetNumDataSegments"](this.mod[PTR]); } } diff --git a/ts/src/classes/module/ElementSegment.ts b/ts/src/classes/module/ElementSegment.ts index e9d7d5a2e47..1f1eff612b6 100644 --- a/ts/src/classes/module/ElementSegment.ts +++ b/ts/src/classes/module/ElementSegment.ts @@ -3,6 +3,7 @@ import { UTF8ToString, } from "../../-pre.ts"; import { + PTR, i32sToStack, preserveStack, strToStack, @@ -54,7 +55,7 @@ export class ModuleElementSegments { /** Adds an active element segment. */ addActive(table: string, name: string, funcNames: readonly string[], offset: ExpressionRef = this.mod.wasm.i32.const(0)): ElementSegmentRef { return preserveStack(() => BinaryenObj["_BinaryenAddActiveElementSegment"]( - this.mod.ptr, + this.mod[PTR], strToStack(table), strToStack(name), i32sToStack(funcNames.map(strToStack)), @@ -66,7 +67,7 @@ export class ModuleElementSegments { /** Adds a passive element segment. */ addPassive(name: string, funcNames: readonly string[]): ElementSegmentRef { return preserveStack(() => BinaryenObj["_BinaryenAddPassiveElementSegment"]( - this.mod.ptr, + this.mod[PTR], strToStack(name), i32sToStack(funcNames.map(strToStack)), funcNames.length, @@ -75,21 +76,21 @@ export class ModuleElementSegments { /** Gets an element segment by name. */ get(name: string): ElementSegmentRef { - return preserveStack(() => BinaryenObj["_BinaryenGetElementSegment"](this.mod.ptr, strToStack(name))); + return preserveStack(() => BinaryenObj["_BinaryenGetElementSegment"](this.mod[PTR], strToStack(name))); } /** Gets an element segment by index. */ getByIndex(index: number): ElementSegmentRef { - return BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.mod.ptr, index); + return BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.mod[PTR], index); } /** Gets the number of element segments within the module. */ count(): number { - return BinaryenObj["_BinaryenGetNumElementSegments"](this.mod.ptr); + return BinaryenObj["_BinaryenGetNumElementSegments"](this.mod[PTR]); } /** Removes an element segment by name. */ remove(name: string): void { - preserveStack(() => BinaryenObj["_BinaryenRemoveElementSegment"](this.mod.ptr, strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenRemoveElementSegment"](this.mod[PTR], strToStack(name))); } } diff --git a/ts/src/classes/module/Export.ts b/ts/src/classes/module/Export.ts index 0b6cb392127..4df381afbef 100644 --- a/ts/src/classes/module/Export.ts +++ b/ts/src/classes/module/Export.ts @@ -3,6 +3,7 @@ import { UTF8ToString, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -43,22 +44,22 @@ export class ModuleExports { /** Gets an export by name. */ get(externalName: string): ExportRef { - return preserveStack(() => BinaryenObj["_BinaryenGetExport"](this.mod.ptr, strToStack(externalName))); + return preserveStack(() => BinaryenObj["_BinaryenGetExport"](this.mod[PTR], strToStack(externalName))); } /** Gets an export by index. */ getByIndex(index: number): ExportRef { - return BinaryenObj["_BinaryenGetExportByIndex"](this.mod.ptr, index); + return BinaryenObj["_BinaryenGetExportByIndex"](this.mod[PTR], index); } /** Gets the number of exports witin the module. */ count(): number { - return BinaryenObj["_BinaryenGetNumExports"](this.mod.ptr); + return BinaryenObj["_BinaryenGetNumExports"](this.mod[PTR]); } /** Removes an export, by external name. */ remove(externalName: string): void { - preserveStack(() => BinaryenObj["_BinaryenRemoveExport"](this.mod.ptr, strToStack(externalName))); + preserveStack(() => BinaryenObj["_BinaryenRemoveExport"](this.mod[PTR], strToStack(externalName))); } /** Adds a tag export. */ @@ -87,6 +88,6 @@ export class ModuleExports { } #addComponent(binaryenFuncName: string, internalName: string, externalName: string): ExportRef { - return preserveStack(() => BinaryenObj[binaryenFuncName](this.mod.ptr, strToStack(internalName), strToStack(externalName))); + return preserveStack(() => BinaryenObj[binaryenFuncName](this.mod[PTR], strToStack(internalName), strToStack(externalName))); } } diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index d4aa54a8af4..dc1ca710503 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -3,6 +3,7 @@ import { UTF8ToString, } from "../../-pre.ts"; import { + PTR, getAllNested, i32sToStack, preserveStack, @@ -96,7 +97,7 @@ export class ModuleFunctions { /** Adds a function. `varTypes` indicate additional locals, in the given order. */ add(name: string, params: Type, results: Type, varTypes: readonly Type[], body: ExpressionRef): FunctionRef { return preserveStack(() => BinaryenObj["_BinaryenAddFunction"]( - this.mod.ptr, + this.mod[PTR], strToStack(name), params, results, @@ -108,21 +109,21 @@ export class ModuleFunctions { /** Gets a function by name. */ get(name: string): FunctionRef { - return preserveStack(() => BinaryenObj["_BinaryenGetFunction"](this.mod.ptr, strToStack(name))); + return preserveStack(() => BinaryenObj["_BinaryenGetFunction"](this.mod[PTR], strToStack(name))); } /** Gets a function by index. */ getByIndex(index: number): FunctionRef { - return BinaryenObj["_BinaryenGetFunctionByIndex"](this.mod.ptr, index); + return BinaryenObj["_BinaryenGetFunctionByIndex"](this.mod[PTR], index); } /** Gets the number of functions within the module. */ count(): number { - return BinaryenObj["_BinaryenGetNumFunctions"](this.mod.ptr); + return BinaryenObj["_BinaryenGetNumFunctions"](this.mod[PTR]); } /** Removes a function by name. */ remove(name: string): void { - preserveStack(() => BinaryenObj["_BinaryenRemoveFunction"](this.mod.ptr, strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenRemoveFunction"](this.mod[PTR], strToStack(name))); } } diff --git a/ts/src/classes/module/Global.ts b/ts/src/classes/module/Global.ts index ba24de61931..e826677cbe9 100644 --- a/ts/src/classes/module/Global.ts +++ b/ts/src/classes/module/Global.ts @@ -3,6 +3,7 @@ import { UTF8ToString, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -50,26 +51,26 @@ export class ModuleGlobals { /** Adds a global instance variable. */ add(name: string, type: Type, mutable: boolean, init: ExpressionRef): GlobalRef { - return preserveStack(() => BinaryenObj["_BinaryenAddGlobal"](this.mod.ptr, strToStack(name), type, mutable, init)); + return preserveStack(() => BinaryenObj["_BinaryenAddGlobal"](this.mod[PTR], strToStack(name), type, mutable, init)); } /** Gets a global by name. */ get(name: string): GlobalRef { - return preserveStack(() => BinaryenObj["_BinaryenGetGlobal"](this.mod.ptr, strToStack(name))); + return preserveStack(() => BinaryenObj["_BinaryenGetGlobal"](this.mod[PTR], strToStack(name))); } /** Gets a global by index. */ getByIndex(index: number): GlobalRef { - return BinaryenObj["_BinaryenGetGlobalByIndex"](this.mod.ptr, index); + return BinaryenObj["_BinaryenGetGlobalByIndex"](this.mod[PTR], index); } /** Gets the number of globals within the module. */ count(): number { - return BinaryenObj["_BinaryenGetNumGlobals"](this.mod.ptr); + return BinaryenObj["_BinaryenGetNumGlobals"](this.mod[PTR]); } /** Removes a global by name. */ remove(name: string): void { - preserveStack(() => BinaryenObj["_BinaryenRemoveGlobal"](this.mod.ptr, strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenRemoveGlobal"](this.mod[PTR], strToStack(name))); } } diff --git a/ts/src/classes/module/Import.ts b/ts/src/classes/module/Import.ts index 79830a34e4c..57bcdea02d8 100644 --- a/ts/src/classes/module/Import.ts +++ b/ts/src/classes/module/Import.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -57,7 +58,7 @@ export class ModuleImports { #addComponent(binaryenFuncName: string, internalName: string, externalModuleName: string, externalBaseName: string, ...rest: any[]): void { preserveStack(() => BinaryenObj[binaryenFuncName]( - this.mod.ptr, + this.mod[PTR], strToStack(internalName), strToStack(externalModuleName), strToStack(externalBaseName), diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index 9e3b058dc38..a0296d7a6a1 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -6,6 +6,7 @@ import { UTF8ToString, } from "../../-pre.ts"; import { + PTR, i32sToStack, preserveStack, strToStack, @@ -45,13 +46,13 @@ export class Memory { constructor(mod: Module, name: string) { - this.module = UTF8ToString(BinaryenObj["_BinaryenMemoryImportGetModule"](mod.ptr, strToStack(name))); - this.base = UTF8ToString(BinaryenObj["_BinaryenMemoryImportGetBase"](mod.ptr, strToStack(name))); - this.initial = BinaryenObj["_BinaryenMemoryGetInitial"](mod.ptr, strToStack(name)); - this.shared = Boolean(BinaryenObj["_BinaryenMemoryIsShared"](mod.ptr, strToStack(name))); - this.is64 = Boolean(BinaryenObj["_BinaryenMemoryIs64"](mod.ptr, strToStack(name))); - if (BinaryenObj["_BinaryenMemoryHasMax"](mod.ptr, strToStack(name))) { - this.max = BinaryenObj["_BinaryenMemoryGetMax"](mod.ptr, strToStack(name)); + this.module = UTF8ToString(BinaryenObj["_BinaryenMemoryImportGetModule"](mod[PTR], strToStack(name))); + this.base = UTF8ToString(BinaryenObj["_BinaryenMemoryImportGetBase"](mod[PTR], strToStack(name))); + this.initial = BinaryenObj["_BinaryenMemoryGetInitial"](mod[PTR], strToStack(name)); + this.shared = Boolean(BinaryenObj["_BinaryenMemoryIsShared"](mod[PTR], strToStack(name))); + this.is64 = Boolean(BinaryenObj["_BinaryenMemoryIs64"](mod[PTR], strToStack(name))); + if (BinaryenObj["_BinaryenMemoryHasMax"](mod[PTR], strToStack(name))) { + this.max = BinaryenObj["_BinaryenMemoryGetMax"](mod[PTR], strToStack(name)); } } } @@ -91,7 +92,7 @@ export class ModuleMemories { lengths[i] = data.length; } BinaryenObj["_BinaryenSetMemory"]( - this.mod.ptr, + this.mod[PTR], initial, maximum, strToStack(exportName), @@ -113,6 +114,6 @@ export class ModuleMemories { /** Returns whether the module has a memory. */ has(): boolean { - return Boolean(BinaryenObj["_BinaryenHasMemory"](this.mod.ptr)); + return Boolean(BinaryenObj["_BinaryenHasMemory"](this.mod[PTR])); } } diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 798c1e81225..6c5c5410c3c 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -7,6 +7,7 @@ import { stackAlloc, } from "../../-pre.ts"; import { + PTR, i8sToStack, i32sToStack, preserveStack, @@ -161,9 +162,9 @@ export class Module { /** * The underlying C-API pointer of the wrapped module. - * @internal + * @hidden */ - readonly ptr: ModuleRef = BinaryenObj["_BinaryenModuleCreate"](); + readonly [PTR]: ModuleRef = BinaryenObj["_BinaryenModuleCreate"](); // ## Expression Manipulation ## // /** @@ -206,7 +207,7 @@ export class Module { externref, stringref, ].includes(typ)) { - return BinaryenObj["_BinaryenPop"](this.ptr, typ); + return BinaryenObj["_BinaryenPop"](this[PTR], typ); } else { throw new Error(`Unexpected type ${ typ }.`); } @@ -217,7 +218,7 @@ export class Module { * @category Expression Manipulation */ getSideEffects(expr: ExpressionRef): SideEffect { - return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, this.ptr); + return BinaryenObj["_BinaryenExpressionGetSideEffects"](expr, this[PTR]); } /** @@ -225,7 +226,7 @@ export class Module { * @category Expression Manipulation */ copyExpression(expr: ExpressionRef): ExpressionRef { - return BinaryenObj["_BinaryenExpressionCopy"](expr, this.ptr); + return BinaryenObj["_BinaryenExpressionCopy"](expr, this[PTR]); } // ## Module Component Operations ## // @@ -250,11 +251,11 @@ export class Module { * @category Module Component Operations */ get start(): FunctionRef { - return BinaryenObj["_BinaryenGetStart"](this.ptr); + return BinaryenObj["_BinaryenGetStart"](this[PTR]); } set start(start: FunctionRef) { - BinaryenObj["_BinaryenSetStart"](this.ptr, start); + BinaryenObj["_BinaryenSetStart"](this[PTR], start); } /** @@ -263,11 +264,11 @@ export class Module { * @category Module Component Operations */ get features(): Feature { - return BinaryenObj["_BinaryenModuleGetFeatures"](this.ptr); + return BinaryenObj["_BinaryenModuleGetFeatures"](this[PTR]); } set features(features: Feature) { - BinaryenObj["_BinaryenModuleSetFeatures"](this.ptr, features); + BinaryenObj["_BinaryenModuleSetFeatures"](this[PTR], features); } /** @deprecated Use {@link Module#tags | `this.tags.add`} instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } @@ -340,7 +341,7 @@ export class Module { * @category Emission & Execution */ emitText(): string { - const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteText"](this.ptr); + const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteText"](this[PTR]); const text = UTF8ToString(textPtr); if (textPtr) { _free(textPtr); @@ -353,7 +354,7 @@ export class Module { * @category Emission & Execution */ emitStackIR(): string { - const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteStackIR"](this.ptr); + const textPtr = BinaryenObj["_BinaryenModuleAllocateAndWriteStackIR"](this[PTR]); const text = UTF8ToString(textPtr); if (textPtr) { _free(textPtr); @@ -371,7 +372,7 @@ export class Module { out = (x: string) => { returned += `${ x }\n`; }; - BinaryenObj["_BinaryenModulePrintAsmjs"](this.ptr); + BinaryenObj["_BinaryenModulePrintAsmjs"](this[PTR]); out = saved; return returned; } @@ -389,7 +390,7 @@ export class Module { emitBinary(sourceMapUrl?: string): Uint8Array | {binary: Uint8Array, sourceMap: string} { return preserveStack(() => { const tempBuffer = stackAlloc(BinaryenObj["_BinaryenSizeofAllocateAndWriteResult"]()); - BinaryenObj["_BinaryenModuleAllocateAndWrite"](tempBuffer, this.ptr, strToStack(sourceMapUrl)); + BinaryenObj["_BinaryenModuleAllocateAndWrite"](tempBuffer, this[PTR], strToStack(sourceMapUrl)); const binaryPtr = HEAPU32[tempBuffer >>> 2]; const binaryBytes = HEAPU32[(tempBuffer >>> 2) + 1]; const sourceMapPtr = HEAPU32[(tempBuffer >>> 2) + 2]; @@ -413,7 +414,7 @@ export class Module { * @category Emission & Execution */ interpret(): void { - BinaryenObj["_BinaryenModuleInterpret"](this.ptr); + BinaryenObj["_BinaryenModuleInterpret"](this[PTR]); } /** @@ -421,7 +422,7 @@ export class Module { * @category Emission & Execution */ dispose(): void { - BinaryenObj["_BinaryenModuleDispose"](this.ptr); + BinaryenObj["_BinaryenModuleDispose"](this[PTR]); } // ### Validation & Optimization ### // @@ -430,7 +431,7 @@ export class Module { * @category Validation & Optimization */ validate(): number { - return BinaryenObj["_BinaryenModuleValidate"](this.ptr); + return BinaryenObj["_BinaryenModuleValidate"](this[PTR]); } /** @@ -438,7 +439,7 @@ export class Module { * @category Validation & Optimization */ optimize(): void { - BinaryenObj["_BinaryenModuleOptimize"](this.ptr); + BinaryenObj["_BinaryenModuleOptimize"](this[PTR]); } /** @@ -449,7 +450,7 @@ export class Module { if (typeof func === "string") { func = this.functions.get(func); } - BinaryenObj["_BinaryenFunctionOptimize"](func, this.ptr); + BinaryenObj["_BinaryenFunctionOptimize"](func, this[PTR]); } /** @@ -457,7 +458,7 @@ export class Module { * @category Validation & Optimization */ runPasses(passes: readonly string[]): void { - preserveStack(() => BinaryenObj["_BinaryenModuleRunPasses"](this.ptr, i32sToStack(passes.map(strToStack)), passes.length)); + preserveStack(() => BinaryenObj["_BinaryenModuleRunPasses"](this[PTR], i32sToStack(passes.map(strToStack)), passes.length)); } /** @@ -468,7 +469,7 @@ export class Module { if (typeof func === "string") { func = this.functions.get(func); } - preserveStack(() => BinaryenObj["_BinaryenFunctionRunPasses"](func, this.ptr, i32sToStack(passes.map(strToStack)), passes.length)); + preserveStack(() => BinaryenObj["_BinaryenFunctionRunPasses"](func, this[PTR], i32sToStack(passes.map(strToStack)), passes.length)); } // ### Debugging ### // @@ -477,7 +478,7 @@ export class Module { * @category Debugging */ addDebugInfoFileName(filename: string): number { - return preserveStack(() => BinaryenObj["_BinaryenModuleAddDebugInfoFileName"](this.ptr, strToStack(filename))); + return preserveStack(() => BinaryenObj["_BinaryenModuleAddDebugInfoFileName"](this[PTR], strToStack(filename))); } /** @@ -485,7 +486,7 @@ export class Module { * @category Debugging */ getDebugInfoFileName(index: number): string { - return UTF8ToString(BinaryenObj["_BinaryenModuleGetDebugInfoFileName"](this.ptr, index)); + return UTF8ToString(BinaryenObj["_BinaryenModuleGetDebugInfoFileName"](this[PTR], index)); } /** @@ -499,17 +500,17 @@ export class Module { // ### Other ### // /** [description] */ setTypeName(heapType: HeapType, name: string): void { - preserveStack(() => BinaryenObj["_BinaryenModuleSetTypeName"](this.ptr, heapType, strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenModuleSetTypeName"](this[PTR], heapType, strToStack(name))); } /** [description] */ setFieldName(heapType: HeapType, index: number, name: string): void { - preserveStack(() => BinaryenObj["_BinaryenModuleSetFieldName"](this.ptr, heapType, index, strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenModuleSetFieldName"](this[PTR], heapType, index, strToStack(name))); } /** Adds a custom section to the binary. */ addCustomSection(name: string, contents: Uint8Array): void { - preserveStack(() => BinaryenObj["_BinaryenAddCustomSection"](this.ptr, strToStack(name), i8sToStack([...contents]), contents.length)); + preserveStack(() => BinaryenObj["_BinaryenAddCustomSection"](this[PTR], strToStack(name), i8sToStack([...contents]), contents.length)); } /** @@ -517,7 +518,7 @@ export class Module { * This must be called after renaming module elements. */ updateMaps(): void { - BinaryenObj["_BinaryenModuleUpdateMaps"](this.ptr); + BinaryenObj["_BinaryenModuleUpdateMaps"](this[PTR]); } } diff --git a/ts/src/classes/module/Table.ts b/ts/src/classes/module/Table.ts index 29a736e528d..4befd85847c 100644 --- a/ts/src/classes/module/Table.ts +++ b/ts/src/classes/module/Table.ts @@ -3,6 +3,7 @@ import { UTF8ToString, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -76,26 +77,26 @@ export class ModuleTables { /** Adds a table. */ add(name: string, initial: number, maximum: number, type: Type = funcref, init?: ExpressionRef): TableRef { - return preserveStack(() => BinaryenObj["_BinaryenAddTable"](this.mod.ptr, strToStack(name), initial, maximum, type, init ?? 0)); + return preserveStack(() => BinaryenObj["_BinaryenAddTable"](this.mod[PTR], strToStack(name), initial, maximum, type, init ?? 0)); } /** Gets a table by name. */ get(name: string): TableRef { - return preserveStack(() => BinaryenObj["_BinaryenGetTable"](this.mod.ptr, strToStack(name))); + return preserveStack(() => BinaryenObj["_BinaryenGetTable"](this.mod[PTR], strToStack(name))); } /** Gets a table by index. */ getByIndex(index: number): TableRef { - return BinaryenObj["_BinaryenGetTableByIndex"](this.mod.ptr, index); + return BinaryenObj["_BinaryenGetTableByIndex"](this.mod[PTR], index); } /** Gets the number of table segments within the module. */ getSegments(table: TableRef): ElementSegmentRef[] { - const numElementSegments = BinaryenObj["_BinaryenGetNumElementSegments"](this.mod.ptr); + const numElementSegments = BinaryenObj["_BinaryenGetNumElementSegments"](this.mod[PTR]); const tableName = UTF8ToString(BinaryenObj["_BinaryenTableGetName"](table)); const ret = []; for (let i = 0; i < numElementSegments; i++) { - const segment = BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.mod.ptr, i); + const segment = BinaryenObj["_BinaryenGetElementSegmentByIndex"](this.mod[PTR], i); const elemTableName = UTF8ToString(BinaryenObj["_BinaryenElementSegmentGetTable"](segment)); if (tableName === elemTableName) { ret.push(segment); @@ -106,11 +107,11 @@ export class ModuleTables { /** Gets the number of tables within the module. */ count(): number { - return BinaryenObj["_BinaryenGetNumTables"](this.mod.ptr); + return BinaryenObj["_BinaryenGetNumTables"](this.mod[PTR]); } /** Removes a table by name. */ remove(name: string): void { - preserveStack(() => BinaryenObj["_BinaryenRemoveTable"](this.mod.ptr, strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenRemoveTable"](this.mod[PTR], strToStack(name))); } } diff --git a/ts/src/classes/module/Tag.ts b/ts/src/classes/module/Tag.ts index b1a4c340e23..368ada71599 100644 --- a/ts/src/classes/module/Tag.ts +++ b/ts/src/classes/module/Tag.ts @@ -3,6 +3,7 @@ import { UTF8ToString, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -47,16 +48,16 @@ export class ModuleTags { /** Adds a tag. */ add(name: string, params: Type, results: Type): TagRef { - return preserveStack(() => BinaryenObj["_BinaryenAddTag"](this.mod.ptr, strToStack(name), params, results)); + return preserveStack(() => BinaryenObj["_BinaryenAddTag"](this.mod[PTR], strToStack(name), params, results)); } /** Gets a tag by name. */ get(name: string): TagRef { - return preserveStack(() => BinaryenObj["_BinaryenGetTag"](this.mod.ptr, strToStack(name))); + return preserveStack(() => BinaryenObj["_BinaryenGetTag"](this.mod[PTR], strToStack(name))); } /** Removes a tag by name. */ remove(name: string): void { - preserveStack(() => BinaryenObj["_BinaryenRemoveTag"](this.mod.ptr, strToStack(name))); + preserveStack(() => BinaryenObj["_BinaryenRemoveTag"](this.mod[PTR], strToStack(name))); } } diff --git a/ts/src/globals.ts b/ts/src/globals.ts index f133e1345ec..8ae170e580c 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -14,6 +14,7 @@ import { stringToAscii, } from "./-pre.ts"; import { + PTR, i32sToStack, preserveStack, } from "./-utils.ts"; @@ -88,7 +89,7 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap ExpressionRef { - return (value) => BinaryenObj["_BinaryenUnary"](mod.ptr, op, value); + return (value) => BinaryenObj["_BinaryenUnary"](mod[PTR], op, value); } export function binaryFn(mod: Module, op: Operation): (left: ExpressionRef, right: ExpressionRef) => ExpressionRef { - return (left, right) => BinaryenObj["_BinaryenBinary"](mod.ptr, op, left, right); + return (left, right) => BinaryenObj["_BinaryenBinary"](mod[PTR], op, left, right); } export function loadFn(mod: Module, typ: Type, bytes: number, isSigned: boolean): (offset: number, align: number, ptr: ExpressionRef, name?: string) => ExpressionRef { return (offset, align, ptr, name) => ( - preserveStack(() => BinaryenObj["_BinaryenLoad"](mod.ptr, bytes, isSigned, offset, align, typ, ptr, strToStack(name))) + preserveStack(() => BinaryenObj["_BinaryenLoad"](mod[PTR], bytes, isSigned, offset, align, typ, ptr, strToStack(name))) ); } export function storeFn(mod: Module, typ: Type, bytes: number): (offset: number, align: number, ptr: ExpressionRef, value: ExpressionRef, name?: string) => ExpressionRef { return (offset, align, ptr, value, name) => ( - preserveStack(() => BinaryenObj["_BinaryenStore"](mod.ptr, bytes, offset, align, ptr, value, typ, strToStack(name))) + preserveStack(() => BinaryenObj["_BinaryenStore"](mod[PTR], bytes, offset, align, ptr, value, typ, strToStack(name))) ); } export function simdLoadFn(mod: Module, op: Operation): (offset: number, align: number, ptr: ExpressionRef, name?: string) => ExpressionRef { return (offset, align, ptr, name) => ( - preserveStack(() => BinaryenObj["_BinaryenSIMDLoad"](mod.ptr, op, offset, align, ptr, strToStack(name))) + preserveStack(() => BinaryenObj["_BinaryenSIMDLoad"](mod[PTR], op, offset, align, ptr, strToStack(name))) ); } export function simdLoadStoreLaneFn(mod: Module, op: Operation): (offset: number, align: number, index: number, ptr: ExpressionRef, vec: ExpressionRef, name?: string) => ExpressionRef { return (offset, align, index, ptr, vec, name) => ( - preserveStack(() => BinaryenObj["_BinaryenSIMDLoadStoreLane"](mod.ptr, op, offset, align, index, ptr, vec, strToStack(name))) + preserveStack(() => BinaryenObj["_BinaryenSIMDLoadStoreLane"](mod[PTR], op, offset, align, index, ptr, vec, strToStack(name))) ); } export function simdShiftFn(mod: Module, op: Operation): (vec: ExpressionRef, shift: ExpressionRef) => ExpressionRef { - return (vec, shift) => BinaryenObj["_BinaryenSIMDShift"](mod.ptr, op, vec, shift); + return (vec, shift) => BinaryenObj["_BinaryenSIMDShift"](mod[PTR], op, vec, shift); } export function simdExtractFn(mod: Module, op: Operation): (vec: ExpressionRef, index: number) => ExpressionRef { - return (vec, index) => BinaryenObj["_BinaryenSIMDExtract"](mod.ptr, op, vec, index); + return (vec, index) => BinaryenObj["_BinaryenSIMDExtract"](mod[PTR], op, vec, index); } export function simdReplaceFn(mod: Module, op: Operation): (vec: ExpressionRef, index: number, value: ExpressionRef) => ExpressionRef { - return (vec, index, value) => BinaryenObj["_BinaryenSIMDReplace"](mod.ptr, op, vec, index, value); + return (vec, index, value) => BinaryenObj["_BinaryenSIMDReplace"](mod[PTR], op, vec, index, value); } export function atomicLoadFn(mod: Module, typ: Type, bytes: number): (offset: number, ptr: ExpressionRef, name?: string, order?: MemoryOrder) => ExpressionRef { return (offset, ptr, name, order = MemoryOrder.SeqCst) => ( - preserveStack(() => BinaryenObj["_BinaryenAtomicLoad"](mod.ptr, bytes, offset, typ, ptr, strToStack(name), order)) + preserveStack(() => BinaryenObj["_BinaryenAtomicLoad"](mod[PTR], bytes, offset, typ, ptr, strToStack(name), order)) ); } export function atomicStoreFn(mod: Module, typ: Type, bytes: number): (offset: number, ptr: ExpressionRef, value: ExpressionRef, name?: string, order?: MemoryOrder) => ExpressionRef { return (offset, ptr, value, name, order = MemoryOrder.SeqCst) => ( - preserveStack(() => BinaryenObj["_BinaryenAtomicStore"](mod.ptr, bytes, offset, ptr, value, typ, strToStack(name), order)) + preserveStack(() => BinaryenObj["_BinaryenAtomicStore"](mod[PTR], bytes, offset, ptr, value, typ, strToStack(name), order)) ); } @@ -120,7 +121,7 @@ export function atomicStoreFn(mod: Module, typ: Type, bytes: number): (offset: n function atomicRmwFn(mod: Module, op: Operation, typ: Type, bytes: number): (offset: number, ptr: ExpressionRef, value: ExpressionRef, name?: string, order?: MemoryOrder) => ExpressionRef { return (offset, ptr, value, name, order = MemoryOrder.SeqCst) => ( - preserveStack(() => BinaryenObj["_BinaryenAtomicRMW"](mod.ptr, op, bytes, offset, ptr, value, typ, strToStack(name), order)) + preserveStack(() => BinaryenObj["_BinaryenAtomicRMW"](mod[PTR], op, bytes, offset, ptr, value, typ, strToStack(name), order)) ); } @@ -134,7 +135,7 @@ export function atomicRmwOps(mod: Module, typ: Type, bytes: number) { xchg: atomicRmwFn(mod, Operation.AtomicRMWXchg, typ, bytes), cmpxchg: (offset: number, ptr: ExpressionRef, expected: ExpressionRef, replacement: ExpressionRef, name?: string, order: MemoryOrder = MemoryOrder.SeqCst): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenAtomicCmpxchg"](mod.ptr, bytes, offset, ptr, expected, replacement, typ, strToStack(name), order)) + preserveStack(() => BinaryenObj["_BinaryenAtomicCmpxchg"](mod[PTR], bytes, offset, ptr, expected, replacement, typ, strToStack(name), order)) ), } as const; } diff --git a/ts/src/services/expression-builder/aggregate.ts b/ts/src/services/expression-builder/aggregate.ts index e498a391a50..bd896b30081 100644 --- a/ts/src/services/expression-builder/aggregate.ts +++ b/ts/src/services/expression-builder/aggregate.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../../-pre.ts"; import { + PTR, i32sToStack, preserveStack, strToStack, @@ -25,12 +26,12 @@ export function tuple(mod: Module) { * not an actual object stored in the heap. */ make: (elements: readonly ExpressionRef[]): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenTupleMake"](mod.ptr, i32sToStack(elements), elements.length)) + preserveStack(() => BinaryenObj["_BinaryenTupleMake"](mod[PTR], i32sToStack(elements), elements.length)) ), /** Extracts a value from a Binaryen virtual tuple. */ extract: (tupl: ExpressionRef, index: number): ExpressionRef => ( - BinaryenObj["_BinaryenTupleExtract"](mod.ptr, tupl, index) + BinaryenObj["_BinaryenTupleExtract"](mod[PTR], tupl, index) ), } as const; } @@ -45,12 +46,12 @@ export function struct(mod: Module) { * Passing in an empty array for `operands` returns `(struct.new_default)`. */ new: (operands: readonly ExpressionRef[], heapType: HeapType): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenStructNew"](mod.ptr, i32sToStack(operands), operands.length, heapType)) + preserveStack(() => BinaryenObj["_BinaryenStructNew"](mod[PTR], i32sToStack(operands), operands.length, heapType)) ), /** Allocate a new struct and initializes it with default values. */ new_default: (heapType: HeapType): ExpressionRef => ( - BinaryenObj["_BinaryenStructNew"](mod.ptr, 0, 0, heapType) + BinaryenObj["_BinaryenStructNew"](mod[PTR], 0, 0, heapType) ), /** @@ -61,7 +62,7 @@ export function struct(mod: Module) { */ get: function (index: number, ref: number, type: number, deprecated_isSigned?: boolean) { return deprecated_isSigned === undefined - ? BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type) + ? BinaryenObj["_BinaryenStructGet"](mod[PTR], index, ref, type) : deprecated_isSigned ? this.get_s(index, ref, type) : this.get_u(index, ref, type); @@ -69,17 +70,17 @@ export function struct(mod: Module) { /** Gets a struct entry with a signed packed type at an index. */ get_s: (index: number, ref: ExpressionRef, type: Type): ExpressionRef => ( - BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type, true) + BinaryenObj["_BinaryenStructGet"](mod[PTR], index, ref, type, true) ), /** Gets a struct entry with an unsigned packed type at an index. */ get_u: (index: number, ref: ExpressionRef, type: Type): ExpressionRef => ( - BinaryenObj["_BinaryenStructGet"](mod.ptr, index, ref, type, false) + BinaryenObj["_BinaryenStructGet"](mod[PTR], index, ref, type, false) ), /** Sets a struct entry at an index. */ set: (index: number, ref: ExpressionRef, value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenStructSet"](mod.ptr, index, ref, value) + BinaryenObj["_BinaryenStructSet"](mod[PTR], index, ref, value) ), } as const; } @@ -91,27 +92,27 @@ export function array(mod: Module) { return { /** Allocates a new array and initializes it with the given operand (repeated). */ new: (heapType: HeapType, size: ExpressionRef, operand: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenArrayNew"](mod.ptr, heapType, size, operand) + BinaryenObj["_BinaryenArrayNew"](mod[PTR], heapType, size, operand) ), /** Allocates a new array and initializes it with a default value (repeated). */ new_default: (heapType: HeapType, size: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenArrayNew"](mod.ptr, heapType, size, 0) + BinaryenObj["_BinaryenArrayNew"](mod[PTR], heapType, size, 0) ), /** Allocates a new array with the given operands and a statically fixed size. */ new_fixed: (heapType: HeapType, operands: readonly ExpressionRef[]): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenArrayNewFixed"](mod.ptr, heapType, i32sToStack(operands), operands.length)) + preserveStack(() => BinaryenObj["_BinaryenArrayNewFixed"](mod[PTR], heapType, i32sToStack(operands), operands.length)) ), /** Allocates a new array and initializes it from a data segment. */ new_data: (heapType: HeapType, name: string, offset: ExpressionRef, size: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenArrayNewData"](mod.ptr, heapType, strToStack(name), offset, size)) + preserveStack(() => BinaryenObj["_BinaryenArrayNewData"](mod[PTR], heapType, strToStack(name), offset, size)) ), /** Allocates a new array and initializes it from an element segment. */ new_elem: (heapType: HeapType, name: string, offset: ExpressionRef, size: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenArrayNewElem"](mod.ptr, heapType, strToStack(name), offset, size)) + preserveStack(() => BinaryenObj["_BinaryenArrayNewElem"](mod[PTR], heapType, strToStack(name), offset, size)) ), /** @@ -122,7 +123,7 @@ export function array(mod: Module) { */ get: function (ref: number, index: number, type: number, deprecated_isSigned?: boolean) { return deprecated_isSigned === undefined - ? BinaryenObj["_BinaryenArrayGet"](mod.ptr, ref, index, type) + ? BinaryenObj["_BinaryenArrayGet"](mod[PTR], ref, index, type) : deprecated_isSigned ? this.get_s(ref, index, type) : this.get_u(ref, index, type); @@ -130,27 +131,27 @@ export function array(mod: Module) { /** Gets an array entry with a signed packed type at an index. */ get_s: (ref: ExpressionRef, index: ExpressionRef, type: Type): ExpressionRef => ( - BinaryenObj["_BinaryenArrayGet"](mod.ptr, ref, index, type, true) + BinaryenObj["_BinaryenArrayGet"](mod[PTR], ref, index, type, true) ), /** Gets an array entry with an unsigned packed type at an index. */ get_u: (ref: ExpressionRef, index: ExpressionRef, type: Type): ExpressionRef => ( - BinaryenObj["_BinaryenArrayGet"](mod.ptr, ref, index, type, false) + BinaryenObj["_BinaryenArrayGet"](mod[PTR], ref, index, type, false) ), /** Sets an array entry at an index. */ set: (ref: ExpressionRef, index: ExpressionRef, value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenArraySet"](mod.ptr, ref, index, value) + BinaryenObj["_BinaryenArraySet"](mod[PTR], ref, index, value) ), /** Produces the length of an array. */ len: (ref: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenArrayLen"](mod.ptr, ref) + BinaryenObj["_BinaryenArrayLen"](mod[PTR], ref) ), /** Fills a specified slice of an array with the given value. */ fill: (ref: ExpressionRef, index: ExpressionRef, value: ExpressionRef, size: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenArrayFill"](mod.ptr, ref, index, value, size) + BinaryenObj["_BinaryenArrayFill"](mod[PTR], ref, index, value, size) ), /** Copies elements to a specified slice of an array from a given array. */ @@ -161,7 +162,7 @@ export function array(mod: Module) { srcIndex: ExpressionRef, length: ExpressionRef, ): ExpressionRef => ( - BinaryenObj["_BinaryenArrayCopy"](mod.ptr, destRef, destIndex, srcRef, srcIndex, length) + BinaryenObj["_BinaryenArrayCopy"](mod[PTR], destRef, destIndex, srcRef, srcIndex, length) ), /** Copies elements to a specified slice of an array from a given data segment. */ @@ -172,7 +173,7 @@ export function array(mod: Module) { offset: ExpressionRef, size: ExpressionRef, ): ExpressionRef => ( - BinaryenObj["_BinaryenArrayInitData"](mod.ptr, strToStack(name), ref, index, offset, size) + BinaryenObj["_BinaryenArrayInitData"](mod[PTR], strToStack(name), ref, index, offset, size) ), /** Copies elements to a specified slice of an array from a given element segment. */ @@ -183,7 +184,7 @@ export function array(mod: Module) { offset: ExpressionRef, size: ExpressionRef, ): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenArrayInitElem"](mod.ptr, strToStack(name), ref, index, offset, size)) + preserveStack(() => BinaryenObj["_BinaryenArrayInitElem"](mod[PTR], strToStack(name), ref, index, offset, size)) ), } as const; } diff --git a/ts/src/services/expression-builder/expressionBuilder.ts b/ts/src/services/expression-builder/expressionBuilder.ts index 9fb8fb04fec..a206b8fe8d2 100644 --- a/ts/src/services/expression-builder/expressionBuilder.ts +++ b/ts/src/services/expression-builder/expressionBuilder.ts @@ -2,6 +2,9 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + PTR, +} from "../../-utils.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -89,7 +92,7 @@ export function expressionBuilder(mod: Module) { i64x2: i64x2(mod), f32x4: f32x4(mod), f64x2: f64x2(mod), - atomic: {fence: () => BinaryenObj["_BinaryenAtomicFence"](mod.ptr)}, + atomic: {fence: () => BinaryenObj["_BinaryenAtomicFence"](mod[PTR])}, } as const; } diff --git a/ts/src/services/expression-builder/generic.ts b/ts/src/services/expression-builder/generic.ts index 7c7e53e7af0..f5bcd744208 100644 --- a/ts/src/services/expression-builder/generic.ts +++ b/ts/src/services/expression-builder/generic.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../../-pre.ts"; import { + PTR, i32sToStack, preserveStack, strToStack, @@ -27,22 +28,22 @@ export function parametrics(mod: Module) { return { /** Creates a no-operation `(nop)` instruction. */ nop: (): ExpressionRef => ( - BinaryenObj["_BinaryenNop"](mod.ptr) + BinaryenObj["_BinaryenNop"](mod[PTR]) ), /** Creates an unreachable instruction that will always trap. */ unreachable: (): ExpressionRef => ( - BinaryenObj["_BinaryenUnreachable"](mod.ptr) + BinaryenObj["_BinaryenUnreachable"](mod[PTR]) ), /** Creates a `(drop)` of a value. */ drop: (value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenDrop"](mod.ptr, value) + BinaryenObj["_BinaryenDrop"](mod[PTR], value) ), /** Creates a `(select)` of one of two values. */ select: (ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenSelect"](mod.ptr, ifTrue, ifFalse) + BinaryenObj["_BinaryenSelect"](mod[PTR], ifTrue, ifFalse) ), } as const; } @@ -55,7 +56,7 @@ export function blocks(mod: Module) { /** Creates a `(block)`. */ block: (name: string | null, children: readonly ExpressionRef[], resultType: Type = none): ExpressionRef => ( preserveStack(() => BinaryenObj["_BinaryenBlock"]( - mod.ptr, + mod[PTR], name ? strToStack(name) : 0, i32sToStack(children), children.length, @@ -65,12 +66,12 @@ export function blocks(mod: Module) { /** Creates a `(loop)`. */ loop: (name: string, body: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenLoop"](mod.ptr, strToStack(name), body)) + preserveStack(() => BinaryenObj["_BinaryenLoop"](mod[PTR], strToStack(name), body)) ), /** Creates an ‘if’ or ‘if/else’ combination. */ if: (ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenIf"](mod.ptr, ifTrue, ifFalse) + BinaryenObj["_BinaryenIf"](mod[PTR], ifTrue, ifFalse) ), } as const; } @@ -80,24 +81,24 @@ export function blocks(mod: Module) { /** @see https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions */ export function breaks(mod: Module) { function brOn(op: Operation, label: string, value: ExpressionRef, castType: Type): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenBrOn"](mod.ptr, op, strToStack(label), value, castType)); + return preserveStack(() => BinaryenObj["_BinaryenBrOn"](mod[PTR], op, strToStack(label), value, castType)); } return { /** Creates an unconditional branch `(br)` to a label. */ br: (label: string, condition?: ExpressionRef, value?: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition!, value!)) + preserveStack(() => BinaryenObj["_BinaryenBreak"](mod[PTR], strToStack(label), condition!, value!)) ), /** Creates a conditional branch `(br_if)` to a label. */ br_if: (label: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenBreak"](mod.ptr, strToStack(label), condition, value!)) + preserveStack(() => BinaryenObj["_BinaryenBreak"](mod[PTR], strToStack(label), condition, value!)) ), /** Creates a switch. */ br_table: (labels: readonly string[], defaultLabel: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef => ( preserveStack(() => BinaryenObj["_BinaryenSwitch"]( - mod.ptr, + mod[PTR], i32sToStack(labels.map(strToStack)), labels.length, strToStack(defaultLabel), @@ -143,37 +144,37 @@ export function calls(mod: Module) { * Note that we must specify the return type here as we may not have created the function being called yet. */ call: (name: string, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenCall"](mod.ptr, strToStack(name), i32sToStack(operands), operands.length, resultsType)) + preserveStack(() => BinaryenObj["_BinaryenCall"](mod[PTR], strToStack(name), i32sToStack(operands), operands.length, resultsType)) ), /** Similar to `call`, but takes a function reference operand instead of a name as the called value. */ call_ref: (target: ExpressionRef, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenCallRef"](mod.ptr, target, i32sToStack(operands), operands.length, resultsType)) + preserveStack(() => BinaryenObj["_BinaryenCallRef"](mod[PTR], target, i32sToStack(operands), operands.length, resultsType)) ), /** Similar to `call_ref`, but indexes into a table to find the function to call. */ call_indirect: (table: string, target: ExpressionRef, operands: readonly ExpressionRef[], paramsType: Type, resultsType: Type): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenCallIndirect"](mod.ptr, strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)) + preserveStack(() => BinaryenObj["_BinaryenCallIndirect"](mod[PTR], strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)) ), /** Unconditional branch to the body of the current function. */ return: (value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenReturn"](mod.ptr, value) + BinaryenObj["_BinaryenReturn"](mod[PTR], value) ), /** Tail-call variant of `call`. */ return_call: (name: string, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenReturnCall"](mod.ptr, strToStack(name), i32sToStack(operands), operands.length, resultsType)) + preserveStack(() => BinaryenObj["_BinaryenReturnCall"](mod[PTR], strToStack(name), i32sToStack(operands), operands.length, resultsType)) ), /** Tail-call variant of `call_ref`. */ return_call_ref: (target: ExpressionRef, operands: readonly ExpressionRef[], resultsType: Type): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenReturnCallRef"](mod.ptr, target, i32sToStack(operands), operands.length, resultsType)) + preserveStack(() => BinaryenObj["_BinaryenReturnCallRef"](mod[PTR], target, i32sToStack(operands), operands.length, resultsType)) ), /** Tail-call variant of `call_indirect`. */ return_call_indirect: (table: string, target: ExpressionRef, operands: readonly ExpressionRef[], paramsType: Type, resultsType: Type): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenReturnCallIndirect"](mod.ptr, strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)) + preserveStack(() => BinaryenObj["_BinaryenReturnCallIndirect"](mod[PTR], strToStack(table), target, i32sToStack(operands), operands.length, paramsType, resultsType)) ), // @ts-expect-error @@ -192,12 +193,12 @@ export function throws(mod: Module) { return { /** Raise an exception. */ throw: (tag: string, operands: readonly ExpressionRef[]): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenThrow"](mod.ptr, strToStack(tag), i32sToStack(operands), operands.length)) + preserveStack(() => BinaryenObj["_BinaryenThrow"](mod[PTR], strToStack(tag), i32sToStack(operands), operands.length)) ), /** Reraise an exception. */ throw_ref: (target: string): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenRethrow"](mod.ptr, strToStack(target))) + preserveStack(() => BinaryenObj["_BinaryenRethrow"](mod[PTR], strToStack(target))) ), /** Installs an exception handler that handles exceptions as specified by its catch clauses. */ @@ -208,7 +209,7 @@ export function throws(mod: Module) { catchBodies: readonly ExpressionRef[], delegateTarget: string, ): ExpressionRef => preserveStack(() => BinaryenObj["_BinaryenTry"]( - mod.ptr, + mod[PTR], strToStack(name), body, i32sToStack(catchTags.map(strToStack)), diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index 5782a2fb6a8..c7b16a059db 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -1,6 +1,9 @@ import { BinaryenObj, } from "../../-pre.ts"; +import { + PTR, +} from "../../-utils.ts"; import { consoleWarn, } from "../../lib.ts"; @@ -86,19 +89,19 @@ export function i64(mod: Module) { rem_u: binaryFn(mod, Operation.RemUInt64), add128: (leftLow: ExpressionRef, leftHigh: ExpressionRef, rightLow: ExpressionRef, rightHigh: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenWideIntAddSub"](mod.ptr, Operation.AddInt128, leftLow, leftHigh, rightLow, rightHigh) + BinaryenObj["_BinaryenWideIntAddSub"](mod[PTR], Operation.AddInt128, leftLow, leftHigh, rightLow, rightHigh) ), sub128: (leftLow: ExpressionRef, leftHigh: ExpressionRef, rightLow: ExpressionRef, rightHigh: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenWideIntAddSub"](mod.ptr, Operation.SubInt128, leftLow, leftHigh, rightLow, rightHigh) + BinaryenObj["_BinaryenWideIntAddSub"](mod[PTR], Operation.SubInt128, leftLow, leftHigh, rightLow, rightHigh) ), mul_wide_s: (left: ExpressionRef, right: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenWideIntMul"](mod.ptr, Operation.MulWideSInt64, left, right) + BinaryenObj["_BinaryenWideIntMul"](mod[PTR], Operation.MulWideSInt64, left, right) ), mul_wide_u: (left: ExpressionRef, right: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenWideIntMul"](mod.ptr, Operation.MulWideUInt64, left, right) + BinaryenObj["_BinaryenWideIntMul"](mod[PTR], Operation.MulWideUInt64, left, right) ), and: binaryFn(mod, Operation.AndInt64), diff --git a/ts/src/services/expression-builder/i8x16.ts b/ts/src/services/expression-builder/i8x16.ts index 2733f3e0913..8377390e6f3 100644 --- a/ts/src/services/expression-builder/i8x16.ts +++ b/ts/src/services/expression-builder/i8x16.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../../-pre.ts"; import { + PTR, i8sToStack, preserveStack, } from "../../-utils.ts"; @@ -69,7 +70,7 @@ export function i8x16(mod: Module) { // TODO: relaxed_swizzle shuffle: (left: ExpressionRef, right: ExpressionRef, mask: readonly number[]): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenSIMDShuffle"](mod.ptr, left, right, i8sToStack(mask))) + preserveStack(() => BinaryenObj["_BinaryenSIMDShuffle"](mod[PTR], left, right, i8sToStack(mask))) ), narrow_i16x8_s: binaryFn(mod, Operation.NarrowSVecI16x8ToVecI8x16), diff --git a/ts/src/services/expression-builder/memory.ts b/ts/src/services/expression-builder/memory.ts index 12e6ea797ae..42fb944e91f 100644 --- a/ts/src/services/expression-builder/memory.ts +++ b/ts/src/services/expression-builder/memory.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -19,13 +20,13 @@ import { function atomic(mod: Module) { function wait(typ: Type, ptr: ExpressionRef, expected: ExpressionRef, timeout: ExpressionRef, name: string): ExpressionRef { - return preserveStack(() => BinaryenObj["_BinaryenAtomicWait"](mod.ptr, ptr, expected, timeout, typ, strToStack(name))); + return preserveStack(() => BinaryenObj["_BinaryenAtomicWait"](mod[PTR], ptr, expected, timeout, typ, strToStack(name))); } return { /** @experimental */ notify: (ptr: ExpressionRef, notifyCount: ExpressionRef, name: string): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenAtomicNotify"](mod.ptr, ptr, notifyCount, strToStack(name))) + preserveStack(() => BinaryenObj["_BinaryenAtomicNotify"](mod[PTR], ptr, notifyCount, strToStack(name))) ), /** @experimental */ @@ -47,17 +48,17 @@ export function memory(mod: Module) { return { /** Returns the current size of a memory. */ size: (name: string, memory64: boolean = false): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenMemorySize"](mod.ptr, strToStack(name), memory64)) + preserveStack(() => BinaryenObj["_BinaryenMemorySize"](mod[PTR], strToStack(name), memory64)) ), /** Grows memory by a given delta and returns the previous size, or -1 if not enough space can be allocated. */ grow: (delta: ExpressionRef, name: string, memory64: boolean = false): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenMemoryGrow"](mod.ptr, delta, strToStack(name), memory64)) + preserveStack(() => BinaryenObj["_BinaryenMemoryGrow"](mod[PTR], delta, strToStack(name), memory64)) ), /** Sets all values in a region of memory to a given byte. */ fill: (dest: ExpressionRef, value: ExpressionRef, size: ExpressionRef, name: string): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenMemoryFill"](mod.ptr, dest, value, size, strToStack(name))) + preserveStack(() => BinaryenObj["_BinaryenMemoryFill"](mod[PTR], dest, value, size, strToStack(name))) ), /** @@ -65,12 +66,12 @@ export function memory(mod: Module) { * The first index denotes the destination. */ copy: (dest: ExpressionRef, source: ExpressionRef, size: ExpressionRef, destMemory: string, sourceMemory: string): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenMemoryCopy"](mod.ptr, dest, source, size, strToStack(destMemory), strToStack(sourceMemory))) + preserveStack(() => BinaryenObj["_BinaryenMemoryCopy"](mod[PTR], dest, source, size, strToStack(destMemory), strToStack(sourceMemory))) ), /** Copies data from a passive data segment into a memory. */ init: (segment: string, dest: ExpressionRef, offset: ExpressionRef, size: ExpressionRef, name: string): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenMemoryInit"](mod.ptr, strToStack(segment), dest, offset, size, strToStack(name))) + preserveStack(() => BinaryenObj["_BinaryenMemoryInit"](mod[PTR], strToStack(segment), dest, offset, size, strToStack(name))) ), /** @experimental */ @@ -85,7 +86,7 @@ export function data(mod: Module) { return { /** Prevents further use of a passive data segment. */ drop: (segment: string): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenDataDrop"](mod.ptr, strToStack(segment))) + preserveStack(() => BinaryenObj["_BinaryenDataDrop"](mod[PTR], strToStack(segment))) ), } as const; } diff --git a/ts/src/services/expression-builder/reference.ts b/ts/src/services/expression-builder/reference.ts index b9cea96fa8a..d990860e94c 100644 --- a/ts/src/services/expression-builder/reference.ts +++ b/ts/src/services/expression-builder/reference.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -21,42 +22,42 @@ export function ref(mod: Module) { return { /** Produces a reference to a given function. */ func: (name: string, type: Type) => ( - preserveStack(() => BinaryenObj["_BinaryenRefFunc"](mod.ptr, strToStack(name), type)) + preserveStack(() => BinaryenObj["_BinaryenRefFunc"](mod[PTR], strToStack(name), type)) ), /** Produces a null reference. */ null: (typ: Type): ExpressionRef => ( - BinaryenObj["_BinaryenRefNull"](mod.ptr, typ) + BinaryenObj["_BinaryenRefNull"](mod[PTR], typ) ), /** Checks for null. */ is_null: (value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenRefIsNull"](mod.ptr, value) + BinaryenObj["_BinaryenRefIsNull"](mod[PTR], value) ), /** Converts a nullible reference to a non-null one, or traps. */ as_non_null: (value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenRefAs"](mod.ptr, Operation.RefAsNonNull, value) + BinaryenObj["_BinaryenRefAs"](mod[PTR], Operation.RefAsNonNull, value) ), /** Compares two references. */ eq: (left: ExpressionRef, right: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenRefEq"](mod.ptr, left, right) + BinaryenObj["_BinaryenRefEq"](mod[PTR], left, right) ), /** Tests the dynamic type of a reference, and returns boolean. */ test: (value: ExpressionRef, castType: Type): ExpressionRef => ( - BinaryenObj["_BinaryenRefTest"](mod.ptr, value, castType) + BinaryenObj["_BinaryenRefTest"](mod[PTR], value, castType) ), /** Tests the dynamic type of a reference, and performs a downcast or traps. */ cast: (value: ExpressionRef, castType: Type): ExpressionRef => ( - BinaryenObj["_BinaryenRefCast"](mod.ptr, value, castType) + BinaryenObj["_BinaryenRefCast"](mod[PTR], value, castType) ), /** Converts type i32 to an unboxed scalar. */ i31: (value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenRefI31"](mod.ptr, value) + BinaryenObj["_BinaryenRefI31"](mod[PTR], value) ), } as const; } @@ -68,12 +69,12 @@ export function i31(mod: Module) { return { /** Converts an unboxed scalar to type i32, signed. */ get_s: (value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenI31Get"](mod.ptr, value, true) + BinaryenObj["_BinaryenI31Get"](mod[PTR], value, true) ), /** Converts an unboxed scalar to type i32, unsigned. */ get_u: (value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenI31Get"](mod.ptr, value, false) + BinaryenObj["_BinaryenI31Get"](mod[PTR], value, false) ), } as const; } diff --git a/ts/src/services/expression-builder/table.ts b/ts/src/services/expression-builder/table.ts index 3d31c21b7c9..63405b1ec96 100644 --- a/ts/src/services/expression-builder/table.ts +++ b/ts/src/services/expression-builder/table.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -20,22 +21,22 @@ export function table(mod: Module) { return { /** Load an element in a table. */ get: (name: string, index: number, typ: Type): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenTableGet"](mod.ptr, strToStack(name), index, typ)) + preserveStack(() => BinaryenObj["_BinaryenTableGet"](mod[PTR], strToStack(name), index, typ)) ), /** Store an element in a table. */ set: (name: string, index: number, value: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenTableSet"](mod.ptr, strToStack(name), index, value)) + preserveStack(() => BinaryenObj["_BinaryenTableSet"](mod[PTR], strToStack(name), index, value)) ), /** Returns the current size of a table. */ size: (name: string): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenTableSize"](mod.ptr, strToStack(name))) + preserveStack(() => BinaryenObj["_BinaryenTableSize"](mod[PTR], strToStack(name))) ), /** Grows table by a given delta and returns the previous size, or -1 if not enough space can be allocated. */ grow: (name: string, value: ExpressionRef, delta: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenTableGrow"](mod.ptr, strToStack(name), value, delta)) + preserveStack(() => BinaryenObj["_BinaryenTableGrow"](mod[PTR], strToStack(name), value, delta)) ), // TODO: fill diff --git a/ts/src/services/expression-builder/v128.ts b/ts/src/services/expression-builder/v128.ts index 6454f1ff93e..102d8f6f31f 100644 --- a/ts/src/services/expression-builder/v128.ts +++ b/ts/src/services/expression-builder/v128.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../../-pre.ts"; import { + PTR, i8sToStack, } from "../../-utils.ts"; import type { @@ -67,7 +68,7 @@ export function v128(mod: Module) { xor: binaryFn(mod, Operation.XorVec128), bitselect: (left: ExpressionRef, right: ExpressionRef, cond: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenSIMDTernary"](mod.ptr, Operation.BitselectVec128, left, right, cond) + BinaryenObj["_BinaryenSIMDTernary"](mod[PTR], Operation.BitselectVec128, left, right, cond) ), anytrue: unaryFn(mod, Operation.AnyTrueVec128), diff --git a/ts/src/services/expression-builder/variable.ts b/ts/src/services/expression-builder/variable.ts index 21dda50d737..44909058510 100644 --- a/ts/src/services/expression-builder/variable.ts +++ b/ts/src/services/expression-builder/variable.ts @@ -2,6 +2,7 @@ import { BinaryenObj, } from "../../-pre.ts"; import { + PTR, preserveStack, strToStack, } from "../../-utils.ts"; @@ -23,12 +24,12 @@ export function local(mod: Module) { * Note that we must specify the type here as we may not have created the local being accessed yet. */ get: (index: number, typ: Type): ExpressionRef => ( - BinaryenObj["_BinaryenLocalGet"](mod.ptr, index, typ) + BinaryenObj["_BinaryenLocalGet"](mod[PTR], index, typ) ), /** Creates a `(local.set)` for the local at the specified index. */ set: (index: number, value: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenLocalSet"](mod.ptr, index, value) + BinaryenObj["_BinaryenLocalSet"](mod[PTR], index, value) ), /** @@ -36,7 +37,7 @@ export function local(mod: Module) { * Note that we must specify the type here as we may not have created the local being accessed yet. */ tee: (index: number, value: ExpressionRef, typ: Type): ExpressionRef => ( - BinaryenObj["_BinaryenLocalTee"](mod.ptr, index, value, typ) + BinaryenObj["_BinaryenLocalTee"](mod[PTR], index, value, typ) ), } as const; } @@ -51,12 +52,12 @@ export function global(mod: Module) { * Note that we must specify the type here as we may not have created the global being accessed yet. */ get: (name: string, typ: Type): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenGlobalGet"](mod.ptr, strToStack(name), typ)) + preserveStack(() => BinaryenObj["_BinaryenGlobalGet"](mod[PTR], strToStack(name), typ)) ), /** Creates a `(global.set)` for the global with the specified name. */ set: (name: string, value: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenGlobalSet"](mod.ptr, strToStack(name), value)) + preserveStack(() => BinaryenObj["_BinaryenGlobalSet"](mod[PTR], strToStack(name), value)) ), } as const; } From bd6deab338e492139e8caf87e76f7e681897113f Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 19:26:28 -0400 Subject: [PATCH 171/247] lint: whitespace --- ts/src/classes/expression/Expression.ts | 9 ++------- ts/src/classes/module/Module.ts | 18 ++++-------------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/ts/src/classes/expression/Expression.ts b/ts/src/classes/expression/Expression.ts index a9b4c329e58..04c57bd65a3 100644 --- a/ts/src/classes/expression/Expression.ts +++ b/ts/src/classes/expression/Expression.ts @@ -37,13 +37,8 @@ export class Expression { return this.#id; } - get type(): Type { - return getExpressionType(this._ptr); - } - - set type(typ: Type) { - BinaryenObj["_BinaryenExpressionSetType"](this._ptr, typ); - } + get type(): Type { return getExpressionType(this._ptr); } + set type(typ: Type) { BinaryenObj["_BinaryenExpressionSetType"](this._ptr, typ); } valueOf(): ExpressionRef { return this._ptr; diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 6c5c5410c3c..d19e6ce1e64 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -250,26 +250,16 @@ export class Module { * The start function. * @category Module Component Operations */ - get start(): FunctionRef { - return BinaryenObj["_BinaryenGetStart"](this[PTR]); - } - - set start(start: FunctionRef) { - BinaryenObj["_BinaryenSetStart"](this[PTR], start); - } + get start(): FunctionRef { return BinaryenObj["_BinaryenGetStart"](this[PTR]); } + set start(start: FunctionRef) { BinaryenObj["_BinaryenSetStart"](this[PTR], start); } /** * The WebAssembly features enabled for this module. * Features are a bitmask of `Feature` enum members. * @category Module Component Operations */ - get features(): Feature { - return BinaryenObj["_BinaryenModuleGetFeatures"](this[PTR]); - } - - set features(features: Feature) { - BinaryenObj["_BinaryenModuleSetFeatures"](this[PTR], features); - } + get features(): Feature { return BinaryenObj["_BinaryenModuleGetFeatures"](this[PTR]); } + set features(features: Feature) { BinaryenObj["_BinaryenModuleSetFeatures"](this[PTR], features); } /** @deprecated Use {@link Module#tags | `this.tags.add`} instead. */ @replacedBy("`this.tags.add`") addTag(name: string, params: Type, results: Type) { return this.tags.add(name, params, results); } /** @deprecated Use {@link Module#tags | `this.tags.get`} instead. */ @replacedBy("`this.tags.get`") getTag(name: string) { return this.tags.get(name); } From 56730743bb5399adbdd033b986002babd544d85e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 8 May 2026 19:42:15 -0400 Subject: [PATCH 172/247] feat: add references classes --- ts/src/classes/expression/index.ts | 11 +++ ts/src/classes/expression/references.ts | 121 ++++++++++++++++++++++++ ts/src/globals.ts | 11 +++ 3 files changed, 143 insertions(+) create mode 100644 ts/src/classes/expression/references.ts diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 048e2b4a0b0..a703ce76ee4 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -60,5 +60,16 @@ export { MemoryInit, DataDrop, } from "./memories.ts"; +export { + RefFunc, + // TODO: RefNull, + RefIsNull, + RefAs, + RefEq, + RefTest, + RefCast, + RefI31, + I31Get, +} from "./references.ts"; export {Const} from "./Const.ts"; diff --git a/ts/src/classes/expression/references.ts b/ts/src/classes/expression/references.ts new file mode 100644 index 00000000000..d0e3a42d60f --- /dev/null +++ b/ts/src/classes/expression/references.ts @@ -0,0 +1,121 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + preserveStack, + strToStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, + type Operation, + type Type, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class RefFunc extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.RefFunc, expr); + } + + get func(): string { return UTF8ToString(BinaryenObj["_BinaryenRefFuncGetFunc"](this._ptr)); } + set func(funcName: string) { preserveStack(() => BinaryenObj["_BinaryenRefFuncSetFunc"](this._ptr, strToStack(funcName))); } +} + + + +// TODO: class RefNull + + + +export class RefIsNull extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.RefIsNull, expr); + } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenRefIsNullGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenRefIsNullSetValue"](this._ptr, valueExpr); } +} + + + +export class RefAs extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.RefAs, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenRefAsGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenRefAsSetOp"](this._ptr, op); } + + get value(): ExpressionRef {return BinaryenObj["_BinaryenRefAsGetValue"](this._ptr);} + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenRefAsSetValue"](this._ptr, valueExpr); } +} + + + +export class RefEq extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.RefEq, expr); + } + + get left(): ExpressionRef { return BinaryenObj["_BinaryenRefEqGetLeft"](this._ptr); } + set left(leftExpr: ExpressionRef) { BinaryenObj["_BinaryenRefEqSetLeft"](this._ptr, leftExpr); } + + get right(): ExpressionRef { return BinaryenObj["_BinaryenRefEqGetRight"](this._ptr); } + set right(rightExpr: ExpressionRef) { BinaryenObj["_BinaryenRefEqSetRight"](this._ptr, rightExpr); } +} + + + +export class RefTest extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.RefTest, expr); + } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenRefTestGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenRefTestSetRef"](this._ptr, ref); } + + get castType(): Type { return BinaryenObj["_BinaryenRefTestGetCastType"](this._ptr); } + set castType(castType: Type) { BinaryenObj["_BinaryenRefTestSetCastType"](this._ptr, castType); } +} + + + +export class RefCast extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.RefCast, expr); + } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenRefCastGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenRefCastSetRef"](this._ptr, ref); } +} + + + +export class RefI31 extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.RefI31, expr); + } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenRefI31GetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenRefI31SetValue"](this._ptr, valueExpr); } +} + + + +export class I31Get extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.I31Get, expr); + } + + get i31(): ExpressionRef { return BinaryenObj["_BinaryenI31GetGetI31"](this._ptr); } + set i31(i31Expr: ExpressionRef) { BinaryenObj["_BinaryenI31GetSetI31"](this._ptr, i31Expr); } + + get signed(): boolean { return Boolean(BinaryenObj["_BinaryenI31GetIsSigned"](this._ptr)); } + set signed(isSigned: boolean) { BinaryenObj["_BinaryenI31GetSetSigned"](this._ptr, isSigned); } +} diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 8ae170e580c..c6508966686 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -76,6 +76,17 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Sat, 9 May 2026 07:51:19 -0400 Subject: [PATCH 173/247] docs: add note about non-namespaced expr methods --- ts/docs/API-Overview.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index e2f802b7bb9..569a2b84fe2 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -387,15 +387,21 @@ Some of `Module`’s instance methods have been converted into getters/setters: Global `getSideEffects(expr, mod)` has been moved to `Module#getSideEffects()` where it lives alongside `Module#copyExpression()`. -All “type” properties (`.i32`, `.i64`, etc) on `Module` previously served as namespaces containing functions for building expressions. -(E.g., `Module#i32.add()` produced an `(i32.add)` WASM instruction.) -These have all migrated to `Module#wasm`, an [Expression Builder](#expression-building). -These properties also each contained its own `.pop()` method, which didn’t build a WASM expression, +All expression creation methods (`.nop()`, `.drop()`, `.block()`, `.call()`, etc.) directly on `Module` +were functions for building expressions, and have migrated to `Module#wasm`, an [Expression Builder](#expression-building). + +All “type” properties (`.i32`, `.i64`, etc) on `Module` previously served as namespaces containing similar functions. +(E.g., `Module#i32.add()` produced an `(i32.add)` WASM instruction.) These also have all migrated to `Module#wasm`. + +These “type” properties also each contained its own `.pop()` method, which didn’t build a WASM expression, but was a pseudo-instruction enabling Binaryen to reason about multiple values on the stack. They have been combined into one method on Module, `Module#pop(t: Type)`, where `t` is one of the corresponding type namespaces. ### Expression Builder Methods +These methods were previously directly on the `Module` class, and have been moved to `Module#wasm`. +Some of them have also been renamed to align with the WASM spec. + Note: To improve readability, assume all methods written in this section are bound to an Expression Builder (an object returned by `Module#wasm`). - `.break()` → `.br()` From 4a85914b6cba3cff896a44538ac9ef3dc940c808 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 10 May 2026 09:31:27 -0400 Subject: [PATCH 174/247] feat: add aggregate classes --- ts/src/-utils.ts | 4 +- ts/src/classes/expression/aggregates.ts | 400 ++++++++++++++++++++++++ ts/src/classes/expression/index.ts | 18 ++ ts/src/globals.ts | 18 ++ 4 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 ts/src/classes/expression/aggregates.ts diff --git a/ts/src/-utils.ts b/ts/src/-utils.ts index d2fdfe6f785..7114fd8b0dc 100644 --- a/ts/src/-utils.ts +++ b/ts/src/-utils.ts @@ -86,10 +86,10 @@ export function getAllNested( numFn: (ref: T) => number, getFn: (ref: T, i: number) => U, ): U[] { - const num = numFn.call(undefined, ref); + const num = numFn(ref); const ret: U[] = []; for (let i = 0; i < num; ++i) { - ret[i] = getFn.call(undefined, ref, i); + ret[i] = getFn(ref, i); } return ret; } diff --git a/ts/src/classes/expression/aggregates.ts b/ts/src/classes/expression/aggregates.ts new file mode 100644 index 00000000000..39d1b60c544 --- /dev/null +++ b/ts/src/classes/expression/aggregates.ts @@ -0,0 +1,400 @@ +import { + BinaryenObj, + UTF8ToString, +} from "../../-pre.ts"; +import { + getAllNested, + preserveStack, + setAllNested, + strToStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class TupleMake extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.TupleMake, expr); + } + + get numOperands(): number { + return BinaryenObj["_BinaryenTupleMakeGetNumOperands"](this._ptr); + } + + get operands(): ExpressionRef[] { + return getAllNested( + this._ptr, + BinaryenObj["_BinaryenTupleMakeGetNumOperands"], + BinaryenObj["_BinaryenTupleMakeGetOperandAt"], + ); + } + + set operands(operands: readonly ExpressionRef[]) { + setAllNested( + this._ptr, + operands, + BinaryenObj["_BinaryenTupleMakeGetNumOperands"], + BinaryenObj["_BinaryenTupleMakeSetOperandAt"], + BinaryenObj["_BinaryenTupleMakeAppendOperand"], + BinaryenObj["_BinaryenTupleMakeRemoveOperandAt"], + ); + } + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenTupleMakeGetOperandAt"](this._ptr, index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenTupleMakeSetOperandAt"](this._ptr, index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenTupleMakeAppendOperand"](this._ptr, operandExpr); + } + + insertOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenTupleMakeInsertOperandAt"](this._ptr, index, operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenTupleMakeRemoveOperandAt"](this._ptr, index); + } +} + + + +export class TupleExtract extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.TupleExtract, expr); + } + + get tuple(): ExpressionRef { return BinaryenObj["_BinaryenTupleExtractGetTuple"](this._ptr); } + set tuple(tupleExpr: ExpressionRef) { BinaryenObj["_BinaryenTupleExtractSetTuple"](this._ptr, tupleExpr); } + + get index(): number { return BinaryenObj["_BinaryenTupleExtractGetIndex"](this._ptr); } + set index(index: number) { BinaryenObj["_BinaryenTupleExtractSetIndex"](this._ptr, index); } +} + + + +export class StructNew extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StructNew, expr); + } + + get numOperands(): number { + return BinaryenObj["_BinaryenStructNewGetNumOperands"](this._ptr); + } + + get operands(): ExpressionRef[] { + return getAllNested( + this._ptr, + BinaryenObj["_BinaryenStructNewGetNumOperands"], + BinaryenObj["_BinaryenStructNewGetOperandAt"], + ); + } + + set operands(operands: readonly ExpressionRef[]) { + setAllNested( + this._ptr, + operands, + BinaryenObj["_BinaryenStructNewGetNumOperands"], + BinaryenObj["_BinaryenStructNewSetOperandAt"], + BinaryenObj["_BinaryenStructNewAppendOperand"], + BinaryenObj["_BinaryenStructNewRemoveOperandAt"], + ); + } + + getOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenStructNewGetOperandAt"](this._ptr, index); + } + + setOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenStructNewSetOperandAt"](this._ptr, index, operandExpr); + } + + appendOperand(operandExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenStructNewAppendOperand"](this._ptr, operandExpr); + } + + insertOperandAt(index: number, operandExpr: ExpressionRef): void { + BinaryenObj["_BinaryenStructNewInsertOperandAt"](this._ptr, index, operandExpr); + } + + removeOperandAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenStructNewRemoveOperandAt"](this._ptr, index); + } +} + + + +export class StructGet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StructGet, expr); + } + + get index(): number { return BinaryenObj["_BinaryenStructGetGetIndex"](this._ptr); } + set index(index: number) { BinaryenObj["_BinaryenStructGetSetIndex"](this._ptr, index); } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenStructGetGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenStructGetSetRef"](this._ptr, ref); } + + get signed(): boolean { return Boolean(BinaryenObj["_BinaryenStructGetIsSigned"](this._ptr)); } + set signed(signed: boolean) { BinaryenObj["_BinaryenStructGetSetSigned"](this._ptr, signed); } +} + + + +export class StructSet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StructSet, expr); + } + + get index(): number { return BinaryenObj["_BinaryenStructSetGetIndex"](this._ptr); } + set index(index: number) { BinaryenObj["_BinaryenStructSetSetIndex"](this._ptr, index); } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenStructSetGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenStructSetSetRef"](this._ptr, ref); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenStructSetGetValue"](this._ptr); } + set value(value: ExpressionRef) { BinaryenObj["_BinaryenStructSetSetValue"](this._ptr, value); } +} + + + +export class ArrayNew extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayNew, expr); + } + + get init(): ExpressionRef { return BinaryenObj["_BinaryenArrayNewGetInit"](this._ptr); } + set init(init: ExpressionRef) { BinaryenObj["_BinaryenArrayNewSetInit"](this._ptr, init); } + + get size(): ExpressionRef { return BinaryenObj["_BinaryenArrayNewGetSize"](this._ptr); } + set size(size: ExpressionRef) { BinaryenObj["_BinaryenArrayNewSetSize"](this._ptr, size); } +} + + + +export class ArrayNewFixed extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayNewFixed, expr); + } + + get numValues(): number { + return BinaryenObj["_BinaryenArrayNewFixedGetNumValues"](this._ptr); + } + + get values(): ExpressionRef[] { + return getAllNested( + this._ptr, + BinaryenObj["_BinaryenArrayNewFixedGetNumValues"], + BinaryenObj["_BinaryenArrayNewFixedGetValueAt"], + ); + } + + set values(operands: readonly ExpressionRef[]) { + setAllNested( + this._ptr, + operands, + BinaryenObj["_BinaryenArrayNewFixedGetNumValues"], + BinaryenObj["_BinaryenArrayNewFixedSetValueAt"], + BinaryenObj["_BinaryenArrayNewFixedAppendValue"], + BinaryenObj["_BinaryenArrayNewFixedRemoveValueAt"], + ); + } + + getValueAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenArrayNewFixedGetValueAt"](this._ptr, index); + } + + setValueAt(index: number, valueExpr: ExpressionRef): void { + BinaryenObj["_BinaryenArrayNewFixedSetValueAt"](this._ptr, index, valueExpr); + } + + appendValue(valueExpr: ExpressionRef): number { + return BinaryenObj["_BinaryenArrayNewFixedAppendValue"](this._ptr, valueExpr); + } + + insertValueAt(index: number, valueExpr: ExpressionRef): void { + BinaryenObj["_BinaryenArrayNewFixedInsertValueAt"](this._ptr, index, valueExpr); + } + + removeValueAt(index: number): ExpressionRef { + return BinaryenObj["_BinaryenArrayNewFixedRemoveValueAt"](this._ptr, index); + } +} + + + +export class ArrayNewData extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayNewData, expr); + } + + get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenArrayNewDataGetSegment"](this._ptr)); } + set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenArrayNewDataSetSegment"](this._ptr, strToStack(segment))); } + + get offset(): ExpressionRef { return BinaryenObj["_BinaryenArrayNewDataGetOffset"](this._ptr); } + set offset(offset: ExpressionRef) { BinaryenObj["_BinaryenArrayNewDataSetOffset"](this._ptr, offset); } + + get size(): ExpressionRef { return BinaryenObj["_BinaryenArrayNewDataGetSize"](this._ptr); } + set size(size: ExpressionRef) { BinaryenObj["_BinaryenArrayNewDataSetSize"](this._ptr, size); } +} + + + +export class ArrayNewElem extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayNewElem, expr); + } + + get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenArrayNewElemGetSegment"](this._ptr)); } + set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenArrayNewElemSetSegment"](this._ptr, strToStack(segment))); } + + get offset(): ExpressionRef { return BinaryenObj["_BinaryenArrayNewElemGetOffset"](this._ptr); } + set offset(offset: ExpressionRef) { BinaryenObj["_BinaryenArrayNewElemSetOffset"](this._ptr, offset); } + + get size(): ExpressionRef { return BinaryenObj["_BinaryenArrayNewElemGetSize"](this._ptr); } + set size(size: ExpressionRef) { BinaryenObj["_BinaryenArrayNewElemSetSize"](this._ptr, size); } +} + + + +export class ArrayGet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayGet, expr); + } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenArrayGetGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenArrayGetSetRef"](this._ptr, ref); } + + get index(): ExpressionRef { return BinaryenObj["_BinaryenArrayGetGetIndex"](this._ptr); } + set index(index: ExpressionRef) { BinaryenObj["_BinaryenArrayGetSetIndex"](this._ptr, index); } + + get signed(): boolean { return Boolean(BinaryenObj["_BinaryenArrayGetIsSigned"](this._ptr)); } + set signed(signed: boolean) { BinaryenObj["_BinaryenArrayGetSetSigned"](this._ptr, signed); } +} + + + +export class ArraySet extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArraySet, expr); + } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenArraySetGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenArraySetSetRef"](this._ptr, ref); } + + get index(): ExpressionRef { return BinaryenObj["_BinaryenArraySetGetIndex"](this._ptr); } + set index(index: ExpressionRef) { BinaryenObj["_BinaryenArraySetSetIndex"](this._ptr, index); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenArraySetGetValue"](this._ptr); } + set value(value: ExpressionRef) { BinaryenObj["_BinaryenArraySetSetValue"](this._ptr, value); } +} + + + +export class ArrayLen extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayLen, expr); + } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenArrayLenGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenArrayLenSetRef"](this._ptr, ref); } +} + + + +export class ArrayFill extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayFill, expr); + } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenArrayFillGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenArrayFillSetRef"](this._ptr, ref); } + + get index(): ExpressionRef { return BinaryenObj["_BinaryenArrayFillGetIndex"](this._ptr); } + set index(index: ExpressionRef) { BinaryenObj["_BinaryenArrayFillSetIndex"](this._ptr, index); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenArrayFillGetValue"](this._ptr); } + set value(value: ExpressionRef) { BinaryenObj["_BinaryenArrayFillSetValue"](this._ptr, value); } + + get size(): ExpressionRef { return BinaryenObj["_BinaryenArrayFillGetSize"](this._ptr); } + set size(size: ExpressionRef) { BinaryenObj["_BinaryenArrayFillSetSize"](this._ptr, size); } +} + + + +export class ArrayCopy extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayCopy, expr); + } + + get destRef(): ExpressionRef { return BinaryenObj["_BinaryenArrayCopyGetDestRef"](this._ptr); } + set destRef(ref: ExpressionRef) { BinaryenObj["_BinaryenArrayCopySetDestRef"](this._ptr, ref); } + + get destIndex(): ExpressionRef { return BinaryenObj["_BinaryenArrayCopyGetDestIndex"](this._ptr); } + set destIndex(index: ExpressionRef) { BinaryenObj["_BinaryenArrayCopySetDestIndex"](this._ptr, index); } + + get srcRef(): ExpressionRef { return BinaryenObj["_BinaryenArrayCopyGetSrcRef"](this._ptr); } + set srcRef(ref: ExpressionRef) { BinaryenObj["_BinaryenArrayCopySetSrcRef"](this._ptr, ref); } + + get srcIndex(): ExpressionRef { return BinaryenObj["_BinaryenArrayCopyGetSrcIndex"](this._ptr); } + set srcIndex(index: ExpressionRef) { BinaryenObj["_BinaryenArrayCopySetSrcIndex"](this._ptr, index); } + + get length(): ExpressionRef { return BinaryenObj["_BinaryenArrayCopyGetLength"](this._ptr); } + set length(length: ExpressionRef) { BinaryenObj["_BinaryenArrayCopySetLength"](this._ptr, length); } +} + + + +export class ArrayInitData extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayInitData, expr); + } + + get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenArrayInitDataGetSegment"](this._ptr)); } + set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenArrayInitDataSetSegment"](this._ptr, strToStack(segment))); } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenArrayInitDataGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenArrayInitDataSetRef"](this._ptr, ref); } + + get index(): ExpressionRef { return BinaryenObj["_BinaryenArrayInitDataGetIndex"](this._ptr); } + set index(index: ExpressionRef) { BinaryenObj["_BinaryenArrayInitDataSetIndex"](this._ptr, index); } + + get offset(): ExpressionRef { return BinaryenObj["_BinaryenArrayInitDataGetOffset"](this._ptr); } + set offset(offset: ExpressionRef) { BinaryenObj["_BinaryenArrayInitDataSetOffset"](this._ptr, offset); } + + get size(): ExpressionRef { return BinaryenObj["_BinaryenArrayInitDataGetSize"](this._ptr); } + set size(size: ExpressionRef) { BinaryenObj["_BinaryenArrayInitDataSetSize"](this._ptr, size); } +} + + + +export class ArrayInitElem extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.ArrayInitElem, expr); + } + + get segment(): string { return UTF8ToString(BinaryenObj["_BinaryenArrayInitElemGetSegment"](this._ptr)); } + set segment(segment: string) { preserveStack(() => BinaryenObj["_BinaryenArrayInitElemSetSegment"](this._ptr, strToStack(segment))); } + + get ref(): ExpressionRef { return BinaryenObj["_BinaryenArrayInitElemGetRef"](this._ptr); } + set ref(ref: ExpressionRef) { BinaryenObj["_BinaryenArrayInitElemSetRef"](this._ptr, ref); } + + get index(): ExpressionRef { return BinaryenObj["_BinaryenArrayInitElemGetIndex"](this._ptr); } + set index(index: ExpressionRef) { BinaryenObj["_BinaryenArrayInitElemSetIndex"](this._ptr, index); } + + get offset(): ExpressionRef { return BinaryenObj["_BinaryenArrayInitElemGetOffset"](this._ptr); } + set offset(offset: ExpressionRef) { BinaryenObj["_BinaryenArrayInitElemSetOffset"](this._ptr, offset); } + + get size(): ExpressionRef { return BinaryenObj["_BinaryenArrayInitElemGetSize"](this._ptr); } + set size(size: ExpressionRef) { BinaryenObj["_BinaryenArrayInitElemSetSize"](this._ptr, size); } +} diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index a703ce76ee4..953cfde6d00 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -71,5 +71,23 @@ export { RefI31, I31Get, } from "./references.ts"; +export { + TupleMake, + TupleExtract, + StructNew, + StructGet, + StructSet, + ArrayNew, + ArrayNewFixed, + ArrayNewData, + ArrayNewElem, + ArrayGet, + ArraySet, + ArrayLen, + ArrayFill, + ArrayCopy, + ArrayInitData, + ArrayInitElem, +} from "./aggregates.ts"; export {Const} from "./Const.ts"; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index c6508966686..af99e940657 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -87,6 +87,24 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Sun, 10 May 2026 13:58:45 -0400 Subject: [PATCH 175/247] feat: add numerics classes --- ts/src/classes/expression/Const.ts | 74 ---------- ts/src/classes/expression/WideIntAddSub.txt | 32 ----- ts/src/classes/expression/WideIntMul.txt | 20 --- ts/src/classes/expression/index.ts | 9 +- ts/src/classes/expression/numerics.ts | 146 ++++++++++++++++++++ ts/src/constants.ts | 6 +- ts/src/globals.ts | 4 + 7 files changed, 162 insertions(+), 129 deletions(-) delete mode 100644 ts/src/classes/expression/Const.ts delete mode 100644 ts/src/classes/expression/WideIntAddSub.txt delete mode 100644 ts/src/classes/expression/WideIntMul.txt create mode 100644 ts/src/classes/expression/numerics.ts diff --git a/ts/src/classes/expression/Const.ts b/ts/src/classes/expression/Const.ts deleted file mode 100644 index 4ec1768cdec..00000000000 --- a/ts/src/classes/expression/Const.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { - BinaryenObj, - HEAPU8, - stackAlloc, -} from "../../-pre.ts"; -import { - preserveStack, -} from "../../-utils.ts"; -import { - ExpressionId, - type ExpressionRef, - i32, - i64, - f32, - f64, - v128, -} from "../../constants.ts"; -import { - Expression, -} from "./Expression.ts"; - - - -export class Const extends Expression { - constructor(expr: ExpressionRef) { - super(ExpressionId.Const, expr); - } - - get value(): number | number[] { - const this_type = this.type; - switch (this_type) { - case i32: { return this.valueI32; } - case i64: { return this.valueI64; } - case f32: { return this.valueF32; } - case f64: { return this.valueF64; } - case v128: { return this.valueV128; } - } - throw new Error(`Unexpected type: ${ this_type }.`); - } - - get valueI32(): number { return BinaryenObj["_BinaryenConstGetValueI32"](this._ptr); } - set valueI32(value: number) { BinaryenObj["_BinaryenConstSetValueI32"](this._ptr, value); } - - get valueI64(): number { return BinaryenObj["_BinaryenConstGetValueI64"](this._ptr); } - set valueI64(value: number) { BinaryenObj["_BinaryenConstSetValueI64"](this._ptr, BigInt(value)); } - - get valueF32(): number { return BinaryenObj["_BinaryenConstGetValueF32"](this._ptr); } - set valueF32(value: number) { BinaryenObj["_BinaryenConstSetValueF32"](this._ptr, value); } - - get valueF64(): number { return BinaryenObj["_BinaryenConstGetValueF64"](this._ptr); } - set valueF64(value: number) { BinaryenObj["_BinaryenConstSetValueF64"](this._ptr, value); } - - get valueV128(): number[] { - const value: number[] = []; - preserveStack(() => { - const tempBuffer = stackAlloc(16); - BinaryenObj["_BinaryenConstGetValueV128"](this._ptr, tempBuffer); - for (let i = 0; i < 16; ++i) { - value[i] = HEAPU8[tempBuffer + i]; - } - }); - return value; - } - - set valueV128(value: readonly number[]) { - preserveStack(() => { - const tempBuffer = stackAlloc(16); - for (let i = 0; i < 16; ++i) { - HEAPU8[tempBuffer + i] = value[i]; - } - BinaryenObj["_BinaryenConstSetValueV128"](this._ptr, tempBuffer); - }); - } -} diff --git a/ts/src/classes/expression/WideIntAddSub.txt b/ts/src/classes/expression/WideIntAddSub.txt deleted file mode 100644 index a45f294345b..00000000000 --- a/ts/src/classes/expression/WideIntAddSub.txt +++ /dev/null @@ -1,32 +0,0 @@ -Module['WideIntAddSub'] = makeExpressionWrapper(Module['_BinaryenWideIntAddSubId'](), { - 'getOp'(expr) { - return Module['_BinaryenWideIntAddSubGetOp'](expr); - }, - 'setOp'(expr, op) { - Module['_BinaryenWideIntAddSubSetOp'](expr, op); - }, - 'getLeftLow'(expr) { - return Module['_BinaryenWideIntAddSubGetLeftLow'](expr); - }, - 'setLeftLow'(expr, leftLowExpr) { - Module['_BinaryenWideIntAddSubSetLeftLow'](expr, leftLowExpr); - }, - 'getLeftHigh'(expr) { - return Module['_BinaryenWideIntAddSubGetLeftHigh'](expr); - }, - 'setLeftHigh'(expr, leftHighExpr) { - Module['_BinaryenWideIntAddSubSetLeftHigh'](expr, leftHighExpr); - }, - 'getRightLow'(expr) { - return Module['_BinaryenWideIntAddSubGetRightLow'](expr); - }, - 'setRightLow'(expr, rightLowExpr) { - Module['_BinaryenWideIntAddSubSetRightLow'](expr, rightLowExpr); - }, - 'getRightHigh'(expr) { - return Module['_BinaryenWideIntAddSubGetRightHigh'](expr); - }, - 'setRightHigh'(expr, rightHighExpr) { - Module['_BinaryenWideIntAddSubSetRightHigh'](expr, rightHighExpr); - } -}); diff --git a/ts/src/classes/expression/WideIntMul.txt b/ts/src/classes/expression/WideIntMul.txt deleted file mode 100644 index 889cb25f550..00000000000 --- a/ts/src/classes/expression/WideIntMul.txt +++ /dev/null @@ -1,20 +0,0 @@ -Module['WideIntMul'] = makeExpressionWrapper(Module['_BinaryenWideIntMulId'](), { - 'getOp'(expr) { - return Module['_BinaryenWideIntMulGetOp'](expr); - }, - 'setOp'(expr, op) { - Module['_BinaryenWideIntMulSetOp'](expr, op); - }, - 'getLeft'(expr) { - return Module['_BinaryenWideIntMulGetLeft'](expr); - }, - 'setLeft'(expr, leftExpr) { - Module['_BinaryenWideIntMulSetLeft'](expr, leftExpr); - }, - 'getRight'(expr) { - return Module['_BinaryenWideIntMulGetRight'](expr); - }, - 'setRight'(expr, rightExpr) { - Module['_BinaryenWideIntMulSetRight'](expr, rightExpr); - } -}); diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 953cfde6d00..f5b64f1baf6 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -89,5 +89,10 @@ export { ArrayInitData, ArrayInitElem, } from "./aggregates.ts"; - -export {Const} from "./Const.ts"; +export { + Const, + Unary, + Binary, + WideIntAddSub, + WideIntMul, +} from "./numerics.ts"; diff --git a/ts/src/classes/expression/numerics.ts b/ts/src/classes/expression/numerics.ts new file mode 100644 index 00000000000..d8f8dbb5f12 --- /dev/null +++ b/ts/src/classes/expression/numerics.ts @@ -0,0 +1,146 @@ +import { + BinaryenObj, + HEAPU8, + stackAlloc, +} from "../../-pre.ts"; +import { + preserveStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, + type Operation, + i32, + i64, + f32, + f64, + v128, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class Const extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Const, expr); + } + + get value(): number | number[] { + const this_type = this.type; + switch (this_type) { + case i32: { return this.valueI32; } + case i64: { return this.valueI64; } + case f32: { return this.valueF32; } + case f64: { return this.valueF64; } + case v128: { return this.valueV128; } + } + throw new Error(`Unexpected type: ${ this_type }.`); + } + + get valueI32(): number { return BinaryenObj["_BinaryenConstGetValueI32"](this._ptr); } + set valueI32(value: number) { BinaryenObj["_BinaryenConstSetValueI32"](this._ptr, value); } + + get valueI64(): number { return BinaryenObj["_BinaryenConstGetValueI64"](this._ptr); } + set valueI64(value: number) { BinaryenObj["_BinaryenConstSetValueI64"](this._ptr, BigInt(value)); } + + get valueF32(): number { return BinaryenObj["_BinaryenConstGetValueF32"](this._ptr); } + set valueF32(value: number) { BinaryenObj["_BinaryenConstSetValueF32"](this._ptr, value); } + + get valueF64(): number { return BinaryenObj["_BinaryenConstGetValueF64"](this._ptr); } + set valueF64(value: number) { BinaryenObj["_BinaryenConstSetValueF64"](this._ptr, value); } + + get valueV128(): number[] { + const value: number[] = []; + preserveStack(() => { + const tempBuffer = stackAlloc(16); + BinaryenObj["_BinaryenConstGetValueV128"](this._ptr, tempBuffer); + for (let i = 0; i < 16; ++i) { + value[i] = HEAPU8[tempBuffer + i]; + } + }); + return value; + } + + set valueV128(value: readonly number[]) { + preserveStack(() => { + const tempBuffer = stackAlloc(16); + for (let i = 0; i < 16; ++i) { + HEAPU8[tempBuffer + i] = value[i]; + } + BinaryenObj["_BinaryenConstSetValueV128"](this._ptr, tempBuffer); + }); + } +} + + + +export class Unary extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Unary, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenUnaryGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenUnarySetOp"](this._ptr, op); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenUnaryGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenUnarySetValue"](this._ptr, valueExpr); } +} + + + +export class Binary extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.Binary, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenBinaryGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenBinarySetOp"](this._ptr, op); } + + get left(): ExpressionRef { return BinaryenObj["_BinaryenBinaryGetLeft"](this._ptr); } + set left(leftExpr: ExpressionRef) { BinaryenObj["_BinaryenBinarySetLeft"](this._ptr, leftExpr); } + + get right(): ExpressionRef { return BinaryenObj["_BinaryenBinaryGetRight"](this._ptr); } + set right(rightExpr: ExpressionRef) { BinaryenObj["_BinaryenBinarySetRight"](this._ptr, rightExpr); } +} + + + +export class WideIntAddSub extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.WideIntAddSub, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenWideIntAddSubGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenWideIntAddSubSetOp"](this._ptr, op); } + + get leftLow(): ExpressionRef { return BinaryenObj["_BinaryenWideIntAddSubGetLeftLow"](this._ptr); } + set leftLow(leftExpr: ExpressionRef) { BinaryenObj["_BinaryenWideIntAddSubSetLeftLow"](this._ptr, leftExpr); } + + get leftHigh(): ExpressionRef { return BinaryenObj["_BinaryenWideIntAddSubGetLeftHigh"](this._ptr); } + set leftHigh(leftExpr: ExpressionRef) { BinaryenObj["_BinaryenWideIntAddSubSetLeftHigh"](this._ptr, leftExpr); } + + get rightLow(): ExpressionRef { return BinaryenObj["_BinaryenWideIntAddSubGetRightLow"](this._ptr); } + set rightLow(rightExpr: ExpressionRef) { BinaryenObj["_BinaryenWideIntAddSubSetRightLow"](this._ptr, rightExpr); } + + get rightHigh(): ExpressionRef { return BinaryenObj["_BinaryenWideIntAddSubGetRightHigh"](this._ptr); } + set rightHigh(rightExpr: ExpressionRef) { BinaryenObj["_BinaryenWideIntAddSubSetRightHigh"](this._ptr, rightExpr); } +} + + + +export class WideIntMul extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.WideIntMul, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenWideIntMulGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenWideIntMulSetOp"](this._ptr, op); } + + get left(): ExpressionRef { return BinaryenObj["_BinaryenWideIntMulGetLeft"](this._ptr); } + set left(leftExpr: ExpressionRef) { BinaryenObj["_BinaryenWideIntMulSetLeft"](this._ptr, leftExpr); } + + get right(): ExpressionRef { return BinaryenObj["_BinaryenWideIntMulGetRight"](this._ptr); } + set right(rightExpr: ExpressionRef) { BinaryenObj["_BinaryenWideIntMulSetRight"](this._ptr, rightExpr); } +} diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 2b86d0fe5cd..899e470ec5e 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -203,6 +203,7 @@ export enum ExpressionId { // ### Proposed Instruction Ids ### // // These insructions are not yet in the WASM spec. Move them to their respective sections once finalized. + // #### Strings #### // StringNew = BinaryenObj["_BinaryenStringNewId"](), StringConst = BinaryenObj["_BinaryenStringConstId"](), StringMeasure = BinaryenObj["_BinaryenStringMeasureId"](), @@ -211,6 +212,9 @@ export enum ExpressionId { StringEq = BinaryenObj["_BinaryenStringEqId"](), StringWTF16Get = BinaryenObj["_BinaryenStringWTF16GetId"](), StringSliceWTF = BinaryenObj["_BinaryenStringSliceWTFId"](), + // #### Wide Arithmetic #### // + WideIntAddSub = BinaryenObj["_BinaryenWideIntAddSubId"](), + WideIntMul = BinaryenObj["_BinaryenWideIntMulId"](), } /** Expression side-effects. */ @@ -715,7 +719,7 @@ export enum Operation { StringEqEqual = BinaryenObj["_BinaryenStringEqEqual"](), StringEqCompare = BinaryenObj["_BinaryenStringEqCompare"](), - // ### WideInt Operations ### // + // ### Wide Arithmetic Operations ### // AddInt128 = BinaryenObj["_BinaryenAddInt128"](), SubInt128 = BinaryenObj["_BinaryenSubInt128"](), MulWideSInt64 = BinaryenObj["_BinaryenMulWideSInt64"](), diff --git a/ts/src/globals.ts b/ts/src/globals.ts index af99e940657..8eb00817a25 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -107,6 +107,10 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Sun, 10 May 2026 18:25:21 -0400 Subject: [PATCH 176/247] feat: add vectors classes --- ts/src/classes/expression/index.ts | 7 ++ ts/src/classes/expression/vectors.ts | 126 +++++++++++++++++++++++++++ ts/src/globals.ts | 5 ++ 3 files changed, 138 insertions(+) create mode 100644 ts/src/classes/expression/vectors.ts diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index f5b64f1baf6..2e38c3a35ec 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -96,3 +96,10 @@ export { WideIntAddSub, WideIntMul, } from "./numerics.ts"; +export { + SIMDTernary, + SIMDShift, + SIMDShuffle, + SIMDExtract, + SIMDReplace, +} from "./vectors.ts"; diff --git a/ts/src/classes/expression/vectors.ts b/ts/src/classes/expression/vectors.ts new file mode 100644 index 00000000000..27dfd1c6c29 --- /dev/null +++ b/ts/src/classes/expression/vectors.ts @@ -0,0 +1,126 @@ +import { + BinaryenObj, + HEAPU8, + stackAlloc, +} from "../../-pre.ts"; +import { + preserveStack, +} from "../../-utils.ts"; +import { + ExpressionId, + type ExpressionRef, + type Operation, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class SIMDTernary extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.SIMDTernary, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenSIMDTernaryGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenSIMDTernarySetOp"](this._ptr, op); } + + get a(): ExpressionRef { return BinaryenObj["_BinaryenSIMDTernaryGetA"](this._ptr); } + set a(aExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDTernarySetA"](this._ptr, aExpr); } + + get b(): ExpressionRef { return BinaryenObj["_BinaryenSIMDTernaryGetB"](this._ptr); } + set b(bExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDTernarySetB"](this._ptr, bExpr); } + + get c(): ExpressionRef { return BinaryenObj["_BinaryenSIMDTernaryGetC"](this._ptr); } + set c(cExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDTernarySetC"](this._ptr, cExpr); } +} + + + +export class SIMDShift extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.SIMDShift, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenSIMDShiftGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenSIMDShiftSetOp"](this._ptr, op); } + + get vec(): ExpressionRef { return BinaryenObj["_BinaryenSIMDShiftGetVec"](this._ptr); } + set vec(vecExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDShiftSetVec"](this._ptr, vecExpr); } + + get shift(): ExpressionRef { return BinaryenObj["_BinaryenSIMDShiftGetShift"](this._ptr); } + set shift(shiftExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDShiftSetShift"](this._ptr, shiftExpr); } +} + + + +export class SIMDShuffle extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.SIMDShuffle, expr); + } + + get left(): ExpressionRef { return BinaryenObj["_BinaryenSIMDShuffleGetLeft"](this._ptr); } + set left(leftExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDShuffleSetLeft"](this._ptr, leftExpr); } + + get right(): ExpressionRef { return BinaryenObj["_BinaryenSIMDShuffleGetRight"](this._ptr); } + set right(rightExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDShuffleSetRight"](this._ptr, rightExpr); } + + get mask(): number[] { + const mask: number[] = []; + preserveStack(() => { + const tempBuffer = stackAlloc(16); + BinaryenObj["_BinaryenSIMDShuffleGetMask"](this._ptr, tempBuffer); + for (let i = 0; i < 16; ++i) { + mask[i] = HEAPU8[tempBuffer + i]; + } + }); + return mask; + } + + set mask(mask: readonly number[]) { + preserveStack(() => { + const tempBuffer = stackAlloc(16); + for (let i = 0; i < 16; ++i) { + HEAPU8[tempBuffer + i] = mask[i]; + } + BinaryenObj["_BinaryenSIMDShuffleSetMask"](this._ptr, tempBuffer); + }); + } +} + + + +export class SIMDExtract extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.SIMDExtract, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenSIMDExtractGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenSIMDExtractSetOp"](this._ptr, op); } + + get vec(): ExpressionRef { return BinaryenObj["_BinaryenSIMDExtractGetVec"](this._ptr); } + set vec(vecExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDExtractSetVec"](this._ptr, vecExpr); } + + get index(): number { return BinaryenObj["_BinaryenSIMDExtractGetIndex"](this._ptr); } + set index(index: number) { BinaryenObj["_BinaryenSIMDExtractSetIndex"](this._ptr, index); } +} + + + +export class SIMDReplace extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.SIMDReplace, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenSIMDReplaceGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenSIMDReplaceSetOp"](this._ptr, op); } + + get vec(): ExpressionRef { return BinaryenObj["_BinaryenSIMDReplaceGetVec"](this._ptr); } + set vec(vecExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDReplaceSetVec"](this._ptr, vecExpr); } + + get index(): number { return BinaryenObj["_BinaryenSIMDReplaceGetIndex"](this._ptr); } + set index(index: number) { BinaryenObj["_BinaryenSIMDReplaceSetIndex"](this._ptr, index); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenSIMDReplaceGetValue"](this._ptr); } + set value(value: ExpressionRef) { BinaryenObj["_BinaryenSIMDReplaceSetValue"](this._ptr, value); } +} diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 8eb00817a25..956c1cc372d 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -111,6 +111,11 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Sun, 10 May 2026 20:15:28 -0400 Subject: [PATCH 177/247] feat: add atomics classes --- ts/src/classes/expression/atomics.ts | 110 +++++++++++++++++++++++++++ ts/src/classes/expression/index.ts | 7 ++ ts/src/constants.ts | 2 +- ts/src/globals.ts | 7 ++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 ts/src/classes/expression/atomics.ts diff --git a/ts/src/classes/expression/atomics.ts b/ts/src/classes/expression/atomics.ts new file mode 100644 index 00000000000..a7040e4b792 --- /dev/null +++ b/ts/src/classes/expression/atomics.ts @@ -0,0 +1,110 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; +import { + ExpressionId, + type ExpressionRef, + type MemoryOrder, + type Operation, + type Type, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class AtomicRMW extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.AtomicRMW, expr); + } + + get op(): Operation { return BinaryenObj["_BinaryenAtomicRMWGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenAtomicRMWSetOp"](this._ptr, op); } + + get memoryOrder(): MemoryOrder { return BinaryenObj["_BinaryenAtomicRMWGetMemoryOrder"](this._ptr); } + set memoryOrder(order: MemoryOrder) { BinaryenObj["_BinaryenAtomicRMWSetMemoryOrder"](this._ptr, order); } + + get bytes(): number { return BinaryenObj["_BinaryenAtomicRMWGetBytes"](this._ptr); } + set bytes(bytes: number) { BinaryenObj["_BinaryenAtomicRMWSetBytes"](this._ptr, bytes); } + + get offset(): number { return BinaryenObj["_BinaryenAtomicRMWGetOffset"](this._ptr); } + set offset(offset: number) { BinaryenObj["_BinaryenAtomicRMWSetOffset"](this._ptr, offset); } + + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenAtomicRMWGetPtr"](this._ptr); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicRMWSetPtr"](this._ptr, ptrExpr); } + + get value(): ExpressionRef { return BinaryenObj["_BinaryenAtomicRMWGetValue"](this._ptr); } + set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicRMWSetValue"](this._ptr, valueExpr); } +} + + + +export class AtomicCmpxchg extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.AtomicCmpxchg, expr); + } + + get memoryOrder(): MemoryOrder { return BinaryenObj["_BinaryenAtomicCmpxchgGetMemoryOrder"](this._ptr); } + set memoryOrder(order: MemoryOrder) { BinaryenObj["_BinaryenAtomicCmpxchgSetMemoryOrder"](this._ptr, order); } + + get bytes(): number { return BinaryenObj["_BinaryenAtomicCmpxchgGetBytes"](this._ptr); } + set bytes(bytes: number) { BinaryenObj["_BinaryenAtomicCmpxchgSetBytes"](this._ptr, bytes); } + + get offset(): number { return BinaryenObj["_BinaryenAtomicCmpxchgGetOffset"](this._ptr); } + set offset(offset: number) { BinaryenObj["_BinaryenAtomicCmpxchgSetOffset"](this._ptr, offset); } + + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenAtomicCmpxchgGetPtr"](this._ptr); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicCmpxchgSetPtr"](this._ptr, ptrExpr); } + + get expected(): ExpressionRef { return BinaryenObj["_BinaryenAtomicCmpxchgGetExpected"](this._ptr); } + set expected(expectedExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicCmpxchgSetExpected"](this._ptr, expectedExpr); } + + get replacement(): ExpressionRef { return BinaryenObj["_BinaryenAtomicCmpxchgGetReplacement"](this._ptr); } + set replacement(replacementExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicCmpxchgSetReplacement"](this._ptr, replacementExpr); } +} + + + +export class AtomicWait extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.AtomicWait, expr); + } + + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenAtomicWaitGetPtr"](this._ptr); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicWaitSetPtr"](this._ptr, ptrExpr); } + + get expected(): ExpressionRef { return BinaryenObj["_BinaryenAtomicWaitGetExpected"](this._ptr); } + set expected(expectedExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicWaitSetExpected"](this._ptr, expectedExpr); } + + get timeout(): ExpressionRef { return BinaryenObj["_BinaryenAtomicWaitGetTimeout"](this._ptr); } + set timeout(timeoutExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicWaitSetTimeout"](this._ptr, timeoutExpr); } + + get expectedType(): Type { return BinaryenObj["_BinaryenAtomicWaitGetExpectedType"](this._ptr); } + set expectedType(expectedType: Type) { BinaryenObj["_BinaryenAtomicWaitSetExpectedType"](this._ptr, expectedType); } +} + + + +export class AtomicNotify extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.AtomicNotify, expr); + } + + get ptr(): ExpressionRef { return BinaryenObj["_BinaryenAtomicNotifyGetPtr"](this._ptr); } + set ptr(ptrExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicNotifySetPtr"](this._ptr, ptrExpr); } + + get notifyCount(): ExpressionRef { return BinaryenObj["_BinaryenAtomicNotifyGetNotifyCount"](this._ptr); } + set notifyCount(notifyCountExpr: ExpressionRef) { BinaryenObj["_BinaryenAtomicNotifySetNotifyCount"](this._ptr, notifyCountExpr); } +} + + + +export class AtomicFence extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.AtomicFence, expr); + } + + get order(): number { return BinaryenObj["_BinaryenAtomicFenceGetOrder"](this._ptr); } + set order(order: number) { BinaryenObj["_BinaryenAtomicFenceSetOrder"](this._ptr, order); } +} diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index 2e38c3a35ec..ea7be5c33d1 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -103,3 +103,10 @@ export { SIMDExtract, SIMDReplace, } from "./vectors.ts"; +export { + AtomicRMW, + AtomicCmpxchg, + AtomicWait, + AtomicNotify, + AtomicFence, +} from "./atomics.ts"; diff --git a/ts/src/constants.ts b/ts/src/constants.ts index 899e470ec5e..c5e1a0915a1 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -195,8 +195,8 @@ export enum ExpressionId { SIMDReplace = BinaryenObj["_BinaryenSIMDReplaceId"](), // ### Atomic Instruction Ids ### // - AtomicCmpxchg = BinaryenObj["_BinaryenAtomicCmpxchgId"](), AtomicRMW = BinaryenObj["_BinaryenAtomicRMWId"](), + AtomicCmpxchg = BinaryenObj["_BinaryenAtomicCmpxchgId"](), AtomicWait = BinaryenObj["_BinaryenAtomicWaitId"](), AtomicNotify = BinaryenObj["_BinaryenAtomicNotifyId"](), AtomicFence = BinaryenObj["_BinaryenAtomicFenceId"](), diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 956c1cc372d..973a430f5ad 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -116,6 +116,13 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Sun, 10 May 2026 20:20:57 -0400 Subject: [PATCH 178/247] feat: add strings classes --- ts/src/classes/expression/index.ts | 10 ++++ ts/src/classes/expression/strings.ts | 71 ++++++++++++++++++++++++++++ ts/src/globals.ts | 10 ++++ 3 files changed, 91 insertions(+) create mode 100644 ts/src/classes/expression/strings.ts diff --git a/ts/src/classes/expression/index.ts b/ts/src/classes/expression/index.ts index ea7be5c33d1..62c1f16f03e 100644 --- a/ts/src/classes/expression/index.ts +++ b/ts/src/classes/expression/index.ts @@ -110,3 +110,13 @@ export { AtomicNotify, AtomicFence, } from "./atomics.ts"; +export { + StringNew, + StringConst, + StringMeasure, + StringEncode, + StringConcat, + StringEq, + StringWTF16Get, + StringSliceWTF, +} from "./strings.ts"; diff --git a/ts/src/classes/expression/strings.ts b/ts/src/classes/expression/strings.ts new file mode 100644 index 00000000000..9bd67ffd4f7 --- /dev/null +++ b/ts/src/classes/expression/strings.ts @@ -0,0 +1,71 @@ +import { + ExpressionId, + type ExpressionRef, +} from "../../constants.ts"; +import { + Expression, +} from "./Expression.ts"; + + + +export class StringNew extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StringNew, expr); + } +} + + + +export class StringConst extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StringConst, expr); + } +} + + + +export class StringMeasure extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StringMeasure, expr); + } +} + + + +export class StringEncode extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StringEncode, expr); + } +} + + + +export class StringConcat extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StringConcat, expr); + } +} + + + +export class StringEq extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StringEq, expr); + } +} + + + +export class StringWTF16Get extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StringWTF16Get, expr); + } +} + + + +export class StringSliceWTF extends Expression { + constructor(expr: ExpressionRef) { + super(ExpressionId.StringSliceWTF, expr); + } +} diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 973a430f5ad..c3b3fe70297 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -123,6 +123,16 @@ const EXPRESSION_TYPE_REGISTRY: ReadonlyMap Date: Wed, 13 May 2026 21:36:46 -0400 Subject: [PATCH 179/247] feat: add deprecation warnings to any ExpressionBuilder props accessed on Module --- ts/src/classes/module/Module.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index d19e6ce1e64..33a94c048b7 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -37,6 +37,7 @@ import { stringref, } from "../../constants.ts"; import { + consoleWarn, replacedBy, } from "../../lib.ts"; import { @@ -531,3 +532,21 @@ export namespace Module { export type Import = Import_; export type Export = Export_; } + + + +/* + * The relocation of all `ExpressionBuilder` props from `Module` to `Module#wasm` is a breaking change, + * so we want to let users access it the old way but with deprecation warnings. + * This function delegates any accesses to those properties. + */ +Object.keys(new Module().wasm).forEach((key) => { + if (!Reflect.has(Module.prototype, key)) { + Reflect.defineProperty(Module.prototype, key, { + get() { + consoleWarn(`Module property \`.${ key }\` is deprecated; use \`.wasm.${ key }\` instead.`); + return (this as Module).wasm[key as keyof ExpressionBuilder]; + }, + }); + } +}); From b8da5786c83c582e67a3b5d1970ae68ac70a4d2b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 01:43:35 -0400 Subject: [PATCH 180/247] build: add "make" script --- ts/.gitignore | 3 +++ ts/eslint.config.js | 2 +- ts/package.json | 2 ++ ts/src/types/binaryen_js.d.ts | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ts/.gitignore b/ts/.gitignore index 57f5fce8900..eb09596e6b4 100644 --- a/ts/.gitignore +++ b/ts/.gitignore @@ -1,6 +1,9 @@ # dependency directories node_modules/ +# build files +build/ + # compiling TypeScript dist/ diff --git a/ts/eslint.config.js b/ts/eslint.config.js index 5daa19ed490..963ebddb078 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -6,7 +6,7 @@ import tseslint from "typescript-eslint"; export default [ - {ignores: ["./dist/", "./docs/out/"]}, + {ignores: ["./build/", "./dist/", "./docs/out/"]}, eslint.configs.recommended, // https://github.com/eslint/eslint/blob/v10.2.1/packages/js/src/configs/eslint-recommended.js { diff --git a/ts/package.json b/ts/package.json index b6dc56ddba5..fef89d03cbe 100644 --- a/ts/package.json +++ b/ts/package.json @@ -16,6 +16,8 @@ "type": "module", "main": "./dist/binaryen.js", "scripts": { + "make": "mkdir -p ../build/ && (cd ../build/ && emcmake cmake ../ && emmake make binaryen_js)", + "postmake": "rm -rf ./build/ && mkdir -p ./build/ && cp -r ../build/bin/* ./build/", "compile": "rm -rf ./dist/ && tsc && tsc --project ./test/tsconfig.json", "lint": "eslint ./", "docs": "rm -rf ./docs/out/ && typedoc", diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index 93bd9815930..9ef6c725b89 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -1,4 +1,4 @@ -// Artifacts provided by the Emscripten build, located at `/build/bin/binaryen_js.js`. +// Artifacts provided by the Emscripten build, located at `./build/binaryen_js.js`. From d81bfdfe666bc6f411f9fbdbc4847d9e9924c4c5 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 05:00:40 -0400 Subject: [PATCH 181/247] build: fix runtime module resolution --- ts/package.json | 6 ++++++ ts/src/-pre.ts | 2 +- ts/src/types/binaryen_js.d.ts | 2 +- ts/tsconfig.json | 3 --- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ts/package.json b/ts/package.json index fef89d03cbe..9be8abee442 100644 --- a/ts/package.json +++ b/ts/package.json @@ -30,6 +30,12 @@ "./dist/*.d.ts", "./dist/*.js" ], + "imports": { + "#binaryen-raw": { + "types": "./src/types/binaryen_js.d.ts", + "default": "./build/binaryen_js.js" + } + }, "devDependencies": { "@eslint/js": "^10.0.1", "@stylistic/eslint-plugin": "^5.10.0", diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index 19ef41aeec9..cb1b8e40e95 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -1,5 +1,5 @@ // # Preprocess # // -import Binaryen from "binaryen-raw"; +import Binaryen from "#binaryen-raw"; diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index 9ef6c725b89..cbdd1fb950e 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -2,7 +2,7 @@ -declare module "binaryen-raw" { +declare module "#binaryen-raw" { interface BinaryenObjType { // https://github.com/emscripten-core/emscripten/blob/main/src/preamble.js _free(ptr: number): void; diff --git a/ts/tsconfig.json b/ts/tsconfig.json index 1d6f8c3075b..ffcee485644 100644 --- a/ts/tsconfig.json +++ b/ts/tsconfig.json @@ -9,9 +9,6 @@ // Modules "module": "esnext", - "paths": { - "binaryen-raw": ["./src/types/binaryen_js.d.ts"], - }, "rewriteRelativeImportExtensions": true, "rootDir": "./src/", From 8d8cc15ff5eb40d4935366e9601d189c88d29058 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 05:05:29 -0400 Subject: [PATCH 182/247] test: add binaryen tests --- ts/test/binaryen.test.ts | 89 ++++++++++++++++++++++++++++++++++++++++ ts/test/demo.test.ts | 24 ----------- 2 files changed, 89 insertions(+), 24 deletions(-) create mode 100644 ts/test/binaryen.test.ts delete mode 100644 ts/test/demo.test.ts diff --git a/ts/test/binaryen.test.ts b/ts/test/binaryen.test.ts new file mode 100644 index 00000000000..88d3480d48a --- /dev/null +++ b/ts/test/binaryen.test.ts @@ -0,0 +1,89 @@ +import * as assert from "node:assert"; +import { + suite, + test, +} from "node:test"; +import * as binaryen from "../src/binaryen.ts"; + + + +suite("binaryen", () => { + test("namespace exists and has all the right top-level exports.", () => { + assert.ok(binaryen); + + // constants + assert.ok(binaryen.unreachable); + assert.strictEqual(binaryen.none, 0); + assert.ok(binaryen.auto); + assert.ok(binaryen.i32); + assert.ok(binaryen.i64); + assert.ok(binaryen.f32); + assert.ok(binaryen.f64); + assert.ok(binaryen.v128); + assert.ok(binaryen.anyref); + assert.ok(binaryen.eqref); + assert.ok(binaryen.i31ref); + assert.ok(binaryen.structref); + assert.ok(binaryen.arrayref); + assert.ok(binaryen.funcref); + assert.ok(!Reflect.has(binaryen, "exnref")); + assert.ok(binaryen.externref); + assert.ok(binaryen.nullref); + assert.ok(binaryen.nullfuncref); + assert.ok(!Reflect.has(binaryen, "nullexnref")); + assert.ok(binaryen.nullexternref); + assert.strictEqual(binaryen.notPacked, 0); + assert.ok(binaryen.i8); + assert.ok(binaryen.i16); + assert.ok(binaryen.stringref); + + // enums + assert.strictEqual(typeof binaryen.ExpressionId, "object"); + assert.strictEqual(typeof binaryen.SideEffect, "object"); + assert.strictEqual(typeof binaryen.ExternalKind, "object"); + assert.strictEqual(typeof binaryen.Operation, "object"); + assert.strictEqual(typeof binaryen.MemoryOrder, "object"); + assert.strictEqual(typeof binaryen.Feature, "object"); + assert.strictEqual(typeof binaryen.ExpressionRunnerFlag, "object"); + + // functions + assert.strictEqual(typeof binaryen.emitText, "function"); + assert.strictEqual(typeof binaryen.readBinary, "function"); + assert.strictEqual(typeof binaryen.readBinaryWithFeatures, "function"); + assert.strictEqual(typeof binaryen.parseText, "function"); + assert.strictEqual(typeof binaryen.exit, "function"); + assert.strictEqual(typeof binaryen.createType, "function"); + assert.strictEqual(typeof binaryen.expandType, "function"); + assert.strictEqual(typeof binaryen.getTypeFromHeapType, "function"); + assert.strictEqual(typeof binaryen.getHeapType, "function"); + assert.strictEqual(typeof binaryen.getExpressionId, "function"); + assert.strictEqual(typeof binaryen.getExpressionType, "function"); + assert.strictEqual(typeof binaryen.getExpressionInfo, "function"); + assert.ok(binaryen.emitText.toString().startsWith("function")); + assert.ok(binaryen.readBinary.toString().startsWith("function")); + assert.ok(binaryen.readBinaryWithFeatures.toString().startsWith("function")); + assert.ok(binaryen.parseText.toString().startsWith("function")); + assert.ok(binaryen.exit.toString().startsWith("function")); + assert.ok(binaryen.createType.toString().startsWith("function")); + assert.ok(binaryen.expandType.toString().startsWith("function")); + assert.ok(binaryen.getTypeFromHeapType.toString().startsWith("function")); + assert.ok(binaryen.getHeapType.toString().startsWith("function")); + assert.ok(binaryen.getExpressionId.toString().startsWith("function")); + assert.ok(binaryen.getExpressionType.toString().startsWith("function")); + assert.ok(binaryen.getExpressionInfo.toString().startsWith("function")); + + // classes + assert.strictEqual(typeof binaryen.Module, "function"); + assert.strictEqual(typeof binaryen.TypeBuilder, "function"); + assert.strictEqual(typeof binaryen.ExpressionRunner, "function"); + assert.strictEqual(typeof binaryen.Relooper, "function"); + assert.ok(binaryen.Module.toString().startsWith("class")); + assert.ok(binaryen.TypeBuilder.toString().startsWith("class")); + assert.ok(binaryen.ExpressionRunner.toString().startsWith("class")); + assert.ok(binaryen.Relooper.toString().startsWith("class")); + + // other + assert.ok(binaryen.settings); + assert.ok(binaryen.expressions); + }); +}); diff --git a/ts/test/demo.test.ts b/ts/test/demo.test.ts deleted file mode 100644 index d02a8cdde0c..00000000000 --- a/ts/test/demo.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as assert from "node:assert"; -import { - suite, - test, -} from "node:test"; - - - -suite("Demo", () => { - test("basic assertions.", () => { - assert.ok(true, "expected value to be truthy."); - assert.strictEqual(2 ** 7, 128, "expected values to be value-equal."); - - const arr = ["f64", "i32"]; - assert.strictEqual(arr, arr.sort(), "expected values to be reference-equal."); - assert.notStrictEqual(arr, ["f64", "i32"], "expected values not to be reference-equal."); - assert.deepStrictEqual(arr, ["f64", "i32"], "expected values to be recursively deep equal."); - assert.notDeepStrictEqual(arr, ["i32", "f64"], "arrays are not deep-equal when item order differs."); - - const obj = {i: 32, f: 64}; - assert.deepStrictEqual(obj, {f: 64, i: 32}, "deep-equal objects need not have the same property order."); - assert.partialDeepStrictEqual(obj, {i: 32}, "expected the left to contain all properties & values in the right."); - }); -}); From 43dec24997588ec73a6745ca3b7683aa2369b519 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 12:00:59 -0400 Subject: [PATCH 183/247] fix: update `-sEXPORTED_RUNTIME_METHODS` --- CMakeLists.txt | 2 +- ts/src/-pre.ts | 10 +++++----- ts/src/types/binaryen_js.d.ts | 15 ++++++++++----- ts/test/binaryen.test.ts | 19 +++++++++++++++++++ 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97863ffb52b..5b6ba0303a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -555,7 +555,7 @@ if(EMSCRIPTEN) else() target_link_libraries(binaryen_js PRIVATE "-sEXPORT_ES6") endif() - target_link_libraries(binaryen_js PRIVATE "-sEXPORTED_RUNTIME_METHODS=stringToUTF8OnStack,stringToAscii,getExceptionMessage") + target_link_libraries(binaryen_js PRIVATE "-sEXPORTED_RUNTIME_METHODS=HEAP8,HEAPU8,HEAP32,HEAPU32,stackSave,stackRestore,stackAlloc,UTF8ToString,stringToAscii,stringToUTF8OnStack,getExceptionMessage") target_link_libraries(binaryen_js PRIVATE "-sEXPORTED_FUNCTIONS=_malloc,_free,__i32_load") target_link_libraries(binaryen_js PRIVATE "--post-js=${CMAKE_CURRENT_SOURCE_DIR}/src/js/binaryen.js-post.js") target_link_libraries(binaryen_js PRIVATE optimized "--closure=1") diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index cb1b8e40e95..da336ca046b 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -9,17 +9,17 @@ export const BinaryenObj = await Binaryen(); export const { - _free, _malloc, + _free, HEAP8, HEAPU8, HEAP32, HEAPU32, - UTF8ToString, - getExceptionMessage, - stackAlloc, - stackRestore, stackSave, + stackRestore, + stackAlloc, + UTF8ToString, stringToAscii, stringToUTF8OnStack, + getExceptionMessage, } = BinaryenObj; diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index cbdd1fb950e..dbf4ed7ef96 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -4,10 +4,13 @@ declare module "#binaryen-raw" { interface BinaryenObjType { + // Standard C functions listed in `EXPORTED_FUNCTIONS`. // https://github.com/emscripten-core/emscripten/blob/main/src/preamble.js - _free(ptr: number): void; _malloc(ptr: number): number; + _free(ptr: number): void; + + // Helper tools defined in Emscripten’s codebase needed in TS. Listed in `EXPORTED_RUNTIME_METHODS`. // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libcore.js HEAP8: Int8Array; HEAPU8: Uint8Array; @@ -19,13 +22,15 @@ declare module "#binaryen-raw" { // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libstrings.js UTF8ToString(n: number): string; - stringToAscii(text: string, buffer: number): void; - stringToUTF8OnStack(str: string): number; + stringToAscii(text: string, buffer: number): void; // yes + stringToUTF8OnStack(str: string): number; // yes // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libexceptions.js - getExceptionMessage(e: number | Error): [string, string]; + getExceptionMessage(e: number | Error): [string, string]; // yes + - // C-defined functions + // Binaryen’s functions in the C++ codebase, e.g. `_BinaryenTypeUnreachable`. + // These are exposed via `-sEXPORT_NAME=Binaryen` in the makelists. [key: string]: (...args: readonly (number | bigint | boolean)[]) => number; } diff --git a/ts/test/binaryen.test.ts b/ts/test/binaryen.test.ts index 88d3480d48a..8b426f4c74e 100644 --- a/ts/test/binaryen.test.ts +++ b/ts/test/binaryen.test.ts @@ -8,6 +8,25 @@ import * as binaryen from "../src/binaryen.ts"; suite("binaryen", () => { + test("[internal] Emscripten artifacts exist.", async () => { + const __pre = await import("../src/-pre.ts"); + assert.ok(__pre.BinaryenObj); + assert.ok(__pre._malloc); + assert.ok(__pre._free); + assert.ok(__pre.HEAP8); + assert.ok(__pre.HEAPU8); + assert.ok(__pre.HEAP32); + assert.ok(__pre.HEAPU32); + assert.ok(__pre.stackSave); + assert.ok(__pre.stackRestore); + assert.ok(__pre.stackAlloc); + assert.ok(__pre.UTF8ToString); + assert.ok(__pre.stringToAscii); + assert.ok(__pre.stringToUTF8OnStack); + assert.ok(__pre.getExceptionMessage); + }); + + test("namespace exists and has all the right top-level exports.", () => { assert.ok(binaryen); From f60393bb613909ee2af4344b644a1fe18d644eba Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 13:09:48 -0400 Subject: [PATCH 184/247] build: upgrade to node v26 && fresh install --- ts/package-lock.json | 424 ++++++++++++++++++++----------------------- ts/package.json | 13 +- 2 files changed, 211 insertions(+), 226 deletions(-) diff --git a/ts/package-lock.json b/ts/package-lock.json index 742cbd41210..1b53e83fdc7 100644 --- a/ts/package-lock.json +++ b/ts/package-lock.json @@ -11,7 +11,7 @@ "devDependencies": { "@eslint/js": "^10.0.1", "@stylistic/eslint-plugin": "^5.10.0", - "@types/node": "^24.12.2", + "@types/node": "^25.8.0 || ^26", "eslint": "^10.2.1", "globals": "^17.5.0", "tsx": "^4.21.0", @@ -20,13 +20,13 @@ "typescript-eslint": "^8.59.1" }, "engines": { - "node": "^24.12" + "node": "^20 || ^22 || ^24 || ^26" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", - "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", "cpu": [ "ppc64" ], @@ -41,9 +41,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", - "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", "cpu": [ "arm" ], @@ -58,9 +58,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", - "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", "cpu": [ "arm64" ], @@ -75,9 +75,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", - "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", "cpu": [ "x64" ], @@ -92,9 +92,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", - "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", "cpu": [ "arm64" ], @@ -109,9 +109,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", - "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", "cpu": [ "x64" ], @@ -126,9 +126,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", - "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", "cpu": [ "arm64" ], @@ -143,9 +143,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", - "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", "cpu": [ "x64" ], @@ -160,9 +160,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", - "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", "cpu": [ "arm" ], @@ -177,9 +177,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", - "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", "cpu": [ "arm64" ], @@ -194,9 +194,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", - "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", "cpu": [ "ia32" ], @@ -211,9 +211,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", - "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", "cpu": [ "loong64" ], @@ -228,9 +228,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", - "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", "cpu": [ "mips64el" ], @@ -245,9 +245,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", - "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", "cpu": [ "ppc64" ], @@ -262,9 +262,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", - "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", "cpu": [ "riscv64" ], @@ -279,9 +279,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", - "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", "cpu": [ "s390x" ], @@ -296,9 +296,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", - "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", "cpu": [ "x64" ], @@ -313,9 +313,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", - "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", "cpu": [ "arm64" ], @@ -330,9 +330,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", - "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", "cpu": [ "x64" ], @@ -347,9 +347,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", - "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", "cpu": [ "arm64" ], @@ -364,9 +364,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", - "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", "cpu": [ "x64" ], @@ -381,9 +381,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", - "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", "cpu": [ "arm64" ], @@ -398,9 +398,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", - "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", "cpu": [ "x64" ], @@ -415,9 +415,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", - "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", "cpu": [ "arm64" ], @@ -432,9 +432,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", - "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", "cpu": [ "ia32" ], @@ -449,9 +449,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", - "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", "cpu": [ "x64" ], @@ -523,9 +523,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", - "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -751,9 +751,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "dev": true, "license": "MIT" }, @@ -775,13 +775,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", - "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", + "version": "25.8.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.8.0.tgz", + "integrity": "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": ">=7.24.0 <7.24.7" } }, "node_modules/@types/unist": { @@ -792,17 +792,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.1.tgz", - "integrity": "sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.3.tgz", + "integrity": "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.59.1", - "@typescript-eslint/type-utils": "8.59.1", - "@typescript-eslint/utils": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1", + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/type-utils": "8.59.3", + "@typescript-eslint/utils": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -815,7 +815,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.59.1", + "@typescript-eslint/parser": "^8.59.3", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -831,16 +831,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.1.tgz", - "integrity": "sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.3.tgz", + "integrity": "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.59.1", - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/typescript-estree": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1", + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3" }, "engines": { @@ -856,14 +856,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz", - "integrity": "sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.3.tgz", + "integrity": "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.59.1", - "@typescript-eslint/types": "^8.59.1", + "@typescript-eslint/tsconfig-utils": "^8.59.3", + "@typescript-eslint/types": "^8.59.3", "debug": "^4.4.3" }, "engines": { @@ -878,14 +878,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz", - "integrity": "sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.3.tgz", + "integrity": "sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1" + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -896,9 +896,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz", - "integrity": "sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.3.tgz", + "integrity": "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==", "dev": true, "license": "MIT", "engines": { @@ -913,15 +913,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.1.tgz", - "integrity": "sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.3.tgz", + "integrity": "sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/typescript-estree": "8.59.1", - "@typescript-eslint/utils": "8.59.1", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/utils": "8.59.3", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -938,9 +938,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz", - "integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.3.tgz", + "integrity": "sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==", "dev": true, "license": "MIT", "engines": { @@ -952,16 +952,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz", - "integrity": "sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.3.tgz", + "integrity": "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.59.1", - "@typescript-eslint/tsconfig-utils": "8.59.1", - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/visitor-keys": "8.59.1", + "@typescript-eslint/project-service": "8.59.3", + "@typescript-eslint/tsconfig-utils": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -980,16 +980,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.1.tgz", - "integrity": "sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.3.tgz", + "integrity": "sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.59.1", - "@typescript-eslint/types": "8.59.1", - "@typescript-eslint/typescript-estree": "8.59.1" + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1004,13 +1004,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz", - "integrity": "sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.3.tgz", + "integrity": "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/types": "8.59.3", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -1092,9 +1092,9 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -1158,9 +1158,9 @@ } }, "node_modules/esbuild": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1171,32 +1171,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.7", - "@esbuild/android-arm": "0.27.7", - "@esbuild/android-arm64": "0.27.7", - "@esbuild/android-x64": "0.27.7", - "@esbuild/darwin-arm64": "0.27.7", - "@esbuild/darwin-x64": "0.27.7", - "@esbuild/freebsd-arm64": "0.27.7", - "@esbuild/freebsd-x64": "0.27.7", - "@esbuild/linux-arm": "0.27.7", - "@esbuild/linux-arm64": "0.27.7", - "@esbuild/linux-ia32": "0.27.7", - "@esbuild/linux-loong64": "0.27.7", - "@esbuild/linux-mips64el": "0.27.7", - "@esbuild/linux-ppc64": "0.27.7", - "@esbuild/linux-riscv64": "0.27.7", - "@esbuild/linux-s390x": "0.27.7", - "@esbuild/linux-x64": "0.27.7", - "@esbuild/netbsd-arm64": "0.27.7", - "@esbuild/netbsd-x64": "0.27.7", - "@esbuild/openbsd-arm64": "0.27.7", - "@esbuild/openbsd-x64": "0.27.7", - "@esbuild/openharmony-arm64": "0.27.7", - "@esbuild/sunos-x64": "0.27.7", - "@esbuild/win32-arm64": "0.27.7", - "@esbuild/win32-ia32": "0.27.7", - "@esbuild/win32-x64": "0.27.7" + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" } }, "node_modules/escape-string-regexp": { @@ -1213,16 +1213,16 @@ } }, "node_modules/eslint": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.3.0.tgz", - "integrity": "sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.4.0.tgz", + "integrity": "sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.5", - "@eslint/config-helpers": "^0.5.5", + "@eslint/config-helpers": "^0.6.0", "@eslint/core": "^1.2.1", "@eslint/plugin-kit": "^0.7.1", "@humanfs/node": "^0.16.6", @@ -1500,19 +1500,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/get-tsconfig": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", - "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -1835,20 +1822,10 @@ "node": ">=6" } }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", "dev": true, "license": "ISC", "bin": { @@ -1912,14 +1889,13 @@ } }, "node_modules/tsx": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", - "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.22.0.tgz", + "integrity": "sha512-8ccZMPD69s1AbKXx0C5ddTNZfNjwV04iIKgjZmKfKxMynEtSYcK0Lh7iQFh53fI5Yu4pb9usgAiqyPmEONaALg==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "~0.27.0", - "get-tsconfig": "^4.7.5" + "esbuild": "~0.28.0" }, "bin": { "tsx": "dist/cli.mjs" @@ -1983,16 +1959,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.59.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.1.tgz", - "integrity": "sha512-xqDcFVBmlrltH64lklOVp1wYxgJr6LVdg3NamBgH2OOQDLFdTKfIZXF5PfghrnXQKXZGTQs8tr1vL7fJvq8CTQ==", + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.3.tgz", + "integrity": "sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.59.1", - "@typescript-eslint/parser": "8.59.1", - "@typescript-eslint/typescript-estree": "8.59.1", - "@typescript-eslint/utils": "8.59.1" + "@typescript-eslint/eslint-plugin": "8.59.3", + "@typescript-eslint/parser": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/utils": "8.59.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2014,9 +1990,9 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", "dev": true, "license": "MIT" }, @@ -2057,9 +2033,9 @@ } }, "node_modules/yaml": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.4.tgz", - "integrity": "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "dev": true, "license": "ISC", "bin": { diff --git a/ts/package.json b/ts/package.json index 9be8abee442..f503534a750 100644 --- a/ts/package.json +++ b/ts/package.json @@ -39,7 +39,7 @@ "devDependencies": { "@eslint/js": "^10.0.1", "@stylistic/eslint-plugin": "^5.10.0", - "@types/node": "^24.12.2", + "@types/node": "^25.8.0 || ^26", "eslint": "^10.2.1", "globals": "^17.5.0", "tsx": "^4.21.0", @@ -48,6 +48,15 @@ "typescript-eslint": "^8.59.1" }, "engines": { - "node": "^24.12" + "node": "^20 || ^22 || ^24 || ^26" + }, + "devEngines": { + "runtime": { + "name": "node", + "version": "^26.1.0" + }, + "packageManager": { + "name": "npm" + } } } From ed30d583b6ca715fe112864a56ed89ab371a2453 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 13:41:25 -0400 Subject: [PATCH 185/247] test: fix missing item assertions --- ts/test/binaryen.test.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ts/test/binaryen.test.ts b/ts/test/binaryen.test.ts index 8b426f4c74e..88768edcb4c 100644 --- a/ts/test/binaryen.test.ts +++ b/ts/test/binaryen.test.ts @@ -32,7 +32,7 @@ suite("binaryen", () => { // constants assert.ok(binaryen.unreachable); - assert.strictEqual(binaryen.none, 0); + assert.ok("none" in binaryen); assert.ok(binaryen.auto); assert.ok(binaryen.i32); assert.ok(binaryen.i64); @@ -45,11 +45,13 @@ suite("binaryen", () => { assert.ok(binaryen.structref); assert.ok(binaryen.arrayref); assert.ok(binaryen.funcref); - assert.ok(!Reflect.has(binaryen, "exnref")); + // @ts-expect-error + assert.ok(!binaryen.exnref); assert.ok(binaryen.externref); assert.ok(binaryen.nullref); assert.ok(binaryen.nullfuncref); - assert.ok(!Reflect.has(binaryen, "nullexnref")); + // @ts-expect-error + assert.ok(!binaryen.nullexnref); assert.ok(binaryen.nullexternref); assert.strictEqual(binaryen.notPacked, 0); assert.ok(binaryen.i8); From 7cd91110fd732fcf7d4d413462e89959279c5d1d Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 14:23:46 -0400 Subject: [PATCH 186/247] test: test constant & enum values --- ts/src/classes/module/Module.ts | 2 + ts/src/constants.ts | 14 +++ ts/test/binaryen.test.ts | 210 ++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 33a94c048b7..5d2317a6e71 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -111,8 +111,10 @@ export enum Feature { FP16 = BinaryenObj["_BinaryenFeatureFP16"](), BulkMemoryOpt = BinaryenObj["_BinaryenFeatureBulkMemoryOpt"](), CallIndirectOverlong = BinaryenObj["_BinaryenFeatureCallIndirectOverlong"](), + // TODO: CustomDescriptors RelaxedAtomics = BinaryenObj["_BinaryenFeatureRelaxedAtomics"](), CustomPageSizes = BinaryenObj["_BinaryenFeatureCustomPageSizes"](), + // TODO: Multibyte WideArithmetic = BinaryenObj["_BinaryenFeatureWideArithmetic"](), All = BinaryenObj["_BinaryenFeatureAll"](), } diff --git a/ts/src/constants.ts b/ts/src/constants.ts index c5e1a0915a1..aed156357b2 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -129,7 +129,9 @@ export enum ExpressionId { Return = BinaryenObj["_BinaryenReturnId"](), Throw = BinaryenObj["_BinaryenThrowId"](), Rethrow = BinaryenObj["_BinaryenRethrowId"](), + // TODO: ThrowRef Try = BinaryenObj["_BinaryenTryId"](), + // TODO: TryTable // ### Variable Instruction Ids ### // LocalGet = BinaryenObj["_BinaryenLocalGetId"](), @@ -142,6 +144,10 @@ export enum ExpressionId { TableSet = BinaryenObj["_BinaryenTableSetId"](), TableSize = BinaryenObj["_BinaryenTableSizeId"](), TableGrow = BinaryenObj["_BinaryenTableGrowId"](), + // TODO: TableFill + // TODO: TableCopy + // TODO: TableInit + // TODO: ElemDrop // ### Memory Instruction Ids ### // Load = BinaryenObj["_BinaryenLoadId"](), @@ -163,6 +169,7 @@ export enum ExpressionId { RefEq = BinaryenObj["_BinaryenRefEqId"](), RefTest = BinaryenObj["_BinaryenRefTestId"](), RefCast = BinaryenObj["_BinaryenRefCastId"](), + // TODO: RefGetDesc RefI31 = BinaryenObj["_BinaryenRefI31Id"](), I31Get = BinaryenObj["_BinaryenI31GetId"](), @@ -172,17 +179,23 @@ export enum ExpressionId { StructNew = BinaryenObj["_BinaryenStructNewId"](), StructGet = BinaryenObj["_BinaryenStructGetId"](), StructSet = BinaryenObj["_BinaryenStructSetId"](), + // TODO: StructRMW + // TODO: StructCmpxchg ArrayNew = BinaryenObj["_BinaryenArrayNewId"](), ArrayNewFixed = BinaryenObj["_BinaryenArrayNewFixedId"](), ArrayNewData = BinaryenObj["_BinaryenArrayNewDataId"](), ArrayNewElem = BinaryenObj["_BinaryenArrayNewElemId"](), ArrayGet = BinaryenObj["_BinaryenArrayGetId"](), ArraySet = BinaryenObj["_BinaryenArraySetId"](), + // TODO: ArrayLoadId + // TODO: ArrayStoreId ArrayLen = BinaryenObj["_BinaryenArrayLenId"](), ArrayFill = BinaryenObj["_BinaryenArrayFillId"](), ArrayCopy = BinaryenObj["_BinaryenArrayCopyId"](), ArrayInitData = BinaryenObj["_BinaryenArrayInitDataId"](), ArrayInitElem = BinaryenObj["_BinaryenArrayInitElemId"](), + // TODO: ArrayRMWId + // TODO: ArrayCmpxchgId // ### Numeric & Vector Instruction Ids ### // Const = BinaryenObj["_BinaryenConstId"](), @@ -210,6 +223,7 @@ export enum ExpressionId { StringEncode = BinaryenObj["_BinaryenStringEncodeId"](), StringConcat = BinaryenObj["_BinaryenStringConcatId"](), StringEq = BinaryenObj["_BinaryenStringEqId"](), + // TODO: StringTest StringWTF16Get = BinaryenObj["_BinaryenStringWTF16GetId"](), StringSliceWTF = BinaryenObj["_BinaryenStringSliceWTFId"](), // #### Wide Arithmetic #### // diff --git a/ts/test/binaryen.test.ts b/ts/test/binaryen.test.ts index 88768edcb4c..6c758e0cbb4 100644 --- a/ts/test/binaryen.test.ts +++ b/ts/test/binaryen.test.ts @@ -107,4 +107,214 @@ suite("binaryen", () => { assert.ok(binaryen.settings); assert.ok(binaryen.expressions); }); + + + test("types.", () => { + assert.strictEqual(binaryen.auto, -1); + assert.strictEqual(binaryen.none, 0); + assert.strictEqual(binaryen.unreachable, 1); + assert.strictEqual(binaryen.i32, 2); + assert.strictEqual(binaryen.i64, 3); + assert.strictEqual(binaryen.f32, 4); + assert.strictEqual(binaryen.f64, 5); + assert.strictEqual(binaryen.v128, 6); + assert.strictEqual(binaryen.anyref, 0x22); + assert.strictEqual(binaryen.eqref, 0x2a); + assert.strictEqual(binaryen.i31ref, 0x32); + assert.strictEqual(binaryen.structref, 0x3a); + assert.strictEqual(binaryen.arrayref, 0x42); + assert.strictEqual(binaryen.funcref, 0x12); + // @ts-expect-error + assert.strictEqual(binaryen.exnref, undefined); + assert.strictEqual(binaryen.externref, 0x0a); + assert.strictEqual(binaryen.nullref, 0x5a); + assert.strictEqual(binaryen.nullfuncref, 0x6a); + // @ts-expect-error + assert.strictEqual(binaryen.nullexnref, undefined); + assert.strictEqual(binaryen.nullexternref, 0x62); + assert.strictEqual(binaryen.notPacked, 0); + assert.strictEqual(binaryen.i8, 1); + assert.strictEqual(binaryen.i16, 2); + assert.strictEqual(binaryen.stringref, 0x52); + + const i32_pair = binaryen.createType([binaryen.i32, binaryen.i32]); + const duplicate_pair = binaryen.createType([binaryen.i32, binaryen.i32]); + assert.strictEqual(binaryen.expandType(i32_pair).toString(), "2,2"); + assert.strictEqual(binaryen.expandType(duplicate_pair).toString(), "2,2"); + assert.strictEqual(i32_pair, duplicate_pair); + + assert.strictEqual(binaryen.expandType(binaryen.createType([binaryen.f32, binaryen.f32])).toString(), "4,4"); + }); + + + test(".Feature", () => { + // NOTE: the length is twice the number of members due to how TypeScript emits enums. + assert.strictEqual(Object.entries(binaryen.Feature).length, 52); + + assert.strictEqual(binaryen.Feature.MVP, 0); + assert.strictEqual(binaryen.Feature.Atomics, 1 << 0); + assert.strictEqual(binaryen.Feature.MutableGlobals, 1 << 1); + assert.strictEqual(binaryen.Feature.NontrappingFPToInt, 1 << 2); + assert.strictEqual(binaryen.Feature.SIMD128, 1 << 3); + assert.strictEqual(binaryen.Feature.BulkMemory, 1 << 4); + assert.strictEqual(binaryen.Feature.SignExt, 1 << 5); + assert.strictEqual(binaryen.Feature.ExceptionHandling, 1 << 6); + assert.strictEqual(binaryen.Feature.TailCall, 1 << 7); + assert.strictEqual(binaryen.Feature.ReferenceTypes, 1 << 8); + assert.strictEqual(binaryen.Feature.Multivalue, 1 << 9); + assert.strictEqual(binaryen.Feature.GC, 1 << 10); + assert.strictEqual(binaryen.Feature.Memory64, 1 << 11); + assert.strictEqual(binaryen.Feature.RelaxedSIMD, 1 << 12); + assert.strictEqual(binaryen.Feature.ExtendedConst, 1 << 13); + assert.strictEqual(binaryen.Feature.Strings, 1 << 14); + assert.strictEqual(binaryen.Feature.MultiMemory, 1 << 15); + assert.strictEqual(binaryen.Feature.StackSwitching, 1 << 16); + assert.strictEqual(binaryen.Feature.SharedEverything, 1 << 17); + assert.strictEqual(binaryen.Feature.FP16, 1 << 18); + assert.strictEqual(binaryen.Feature.BulkMemoryOpt, 1 << 19); + assert.strictEqual(binaryen.Feature.CallIndirectOverlong, 1 << 20); + // @ts-expect-error + assert.strictEqual(binaryen.Feature.CustomDescriptors, undefined); assert.notStrictEqual(binaryen.Feature.CustomDescriptors, 1 << 21); + assert.strictEqual(binaryen.Feature.RelaxedAtomics, 1 << 22); + assert.strictEqual(binaryen.Feature.CustomPageSizes, 1 << 23); + // @ts-expect-error + assert.strictEqual(binaryen.Feature.Multibyte, undefined); assert.notStrictEqual(binaryen.Feature.Multibyte, 1 << 24); + assert.strictEqual(binaryen.Feature.WideArithmetic, 1 << 25); + assert.strictEqual(binaryen.Feature.All, (1 << 26) - 1); + }); + + + test(".ExpressionId", () => { + // NOTE: the length is twice the number of members due to how TypeScript emits enums. + assert.strictEqual(Object.entries(binaryen.ExpressionId).length, 170); + + assert.strictEqual(binaryen.ExpressionId.Invalid, 0); + assert.strictEqual(binaryen.ExpressionId.Block, 1); + assert.strictEqual(binaryen.ExpressionId.If, 2); + assert.strictEqual(binaryen.ExpressionId.Loop, 3); + assert.strictEqual(binaryen.ExpressionId.Break, 4); + assert.strictEqual(binaryen.ExpressionId.Switch, 5); + assert.strictEqual(binaryen.ExpressionId.Call, 6); + assert.strictEqual(binaryen.ExpressionId.CallIndirect, 7); + assert.strictEqual(binaryen.ExpressionId.LocalGet, 8); + assert.strictEqual(binaryen.ExpressionId.LocalSet, 9); + assert.strictEqual(binaryen.ExpressionId.GlobalGet, 10); + assert.strictEqual(binaryen.ExpressionId.GlobalSet, 11); + assert.strictEqual(binaryen.ExpressionId.Load, 12); + assert.strictEqual(binaryen.ExpressionId.Store, 13); + assert.strictEqual(binaryen.ExpressionId.Const, 14); + assert.strictEqual(binaryen.ExpressionId.Unary, 15); + assert.strictEqual(binaryen.ExpressionId.Binary, 16); + assert.strictEqual(binaryen.ExpressionId.Select, 17); + assert.strictEqual(binaryen.ExpressionId.Drop, 18); + assert.strictEqual(binaryen.ExpressionId.Return, 19); + assert.strictEqual(binaryen.ExpressionId.MemorySize, 20); + assert.strictEqual(binaryen.ExpressionId.MemoryGrow, 21); + assert.strictEqual(binaryen.ExpressionId.Nop, 22); + assert.strictEqual(binaryen.ExpressionId.Unreachable, 23); + assert.strictEqual(binaryen.ExpressionId.AtomicRMW, 24); + assert.strictEqual(binaryen.ExpressionId.AtomicCmpxchg, 25); + assert.strictEqual(binaryen.ExpressionId.AtomicWait, 26); + assert.strictEqual(binaryen.ExpressionId.AtomicNotify, 27); + assert.strictEqual(binaryen.ExpressionId.AtomicFence, 28); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.Pause, undefined); assert.notStrictEqual(binaryen.ExpressionId.Pause, 29); + assert.strictEqual(binaryen.ExpressionId.SIMDExtract, 30); + assert.strictEqual(binaryen.ExpressionId.SIMDReplace, 31); + assert.strictEqual(binaryen.ExpressionId.SIMDShuffle, 32); + assert.strictEqual(binaryen.ExpressionId.SIMDTernary, 33); + assert.strictEqual(binaryen.ExpressionId.SIMDShift, 34); + assert.strictEqual(binaryen.ExpressionId.SIMDLoad, 35); + assert.strictEqual(binaryen.ExpressionId.SIMDLoadStoreLane, 36); + assert.strictEqual(binaryen.ExpressionId.MemoryInit, 37); + assert.strictEqual(binaryen.ExpressionId.DataDrop, 38); + assert.strictEqual(binaryen.ExpressionId.MemoryCopy, 39); + assert.strictEqual(binaryen.ExpressionId.MemoryFill, 40); + assert.strictEqual(binaryen.ExpressionId.Pop, 41); + assert.strictEqual(binaryen.ExpressionId.RefNull, 42); + assert.strictEqual(binaryen.ExpressionId.RefIsNull, 43); + assert.strictEqual(binaryen.ExpressionId.RefFunc, 44); + assert.strictEqual(binaryen.ExpressionId.RefEq, 45); + assert.strictEqual(binaryen.ExpressionId.TableGet, 46); + assert.strictEqual(binaryen.ExpressionId.TableSet, 47); + assert.strictEqual(binaryen.ExpressionId.TableSize, 48); + assert.strictEqual(binaryen.ExpressionId.TableGrow, 49); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.TableFill, undefined); assert.notStrictEqual(binaryen.ExpressionId.TableFill, 50); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.TableCopy, undefined); assert.notStrictEqual(binaryen.ExpressionId.TableCopy, 51); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.TableInit, undefined); assert.notStrictEqual(binaryen.ExpressionId.TableInit, 52); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.ElemDrop, undefined); assert.notStrictEqual(binaryen.ExpressionId.ElemDrop, 53); + assert.strictEqual(binaryen.ExpressionId.Try, 54); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.TryTable, undefined); assert.notStrictEqual(binaryen.ExpressionId.TryTable, 55); + assert.strictEqual(binaryen.ExpressionId.Throw, 56); + assert.strictEqual(binaryen.ExpressionId.Rethrow, 57); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.ThrowRef, undefined); assert.notStrictEqual(binaryen.ExpressionId.ThrowRef, 58); + assert.strictEqual(binaryen.ExpressionId.TupleMake, 59); + assert.strictEqual(binaryen.ExpressionId.TupleExtract, 60); + assert.strictEqual(binaryen.ExpressionId.RefI31, 61); + assert.strictEqual(binaryen.ExpressionId.I31Get, 62); + assert.strictEqual(binaryen.ExpressionId.CallRef, 63); + assert.strictEqual(binaryen.ExpressionId.RefTest, 64); + assert.strictEqual(binaryen.ExpressionId.RefCast, 65); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.RefGetDesc, undefined); assert.notStrictEqual(binaryen.ExpressionId.RefGetDesc, 66); + assert.strictEqual(binaryen.ExpressionId.BrOn, 67); + assert.strictEqual(binaryen.ExpressionId.StructNew, 68); + assert.strictEqual(binaryen.ExpressionId.StructGet, 69); + assert.strictEqual(binaryen.ExpressionId.StructSet, 70); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.StructRMW, undefined); assert.notStrictEqual(binaryen.ExpressionId.StructRMW, 71); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.StructCmpxchg, undefined); assert.notStrictEqual(binaryen.ExpressionId.StructCmpxchg, 72); + assert.strictEqual(binaryen.ExpressionId.ArrayNew, 73); + assert.strictEqual(binaryen.ExpressionId.ArrayNewData, 74); + assert.strictEqual(binaryen.ExpressionId.ArrayNewElem, 75); + assert.strictEqual(binaryen.ExpressionId.ArrayNewFixed, 76); + assert.strictEqual(binaryen.ExpressionId.ArrayGet, 77); + assert.strictEqual(binaryen.ExpressionId.ArraySet, 78); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.ArrayLoadId, undefined); assert.notStrictEqual(binaryen.ExpressionId.ArrayLoadId, 79); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.ArrayStoreId, undefined); assert.notStrictEqual(binaryen.ExpressionId.ArrayStoreId, 80); + assert.strictEqual(binaryen.ExpressionId.ArrayLen, 81); + assert.strictEqual(binaryen.ExpressionId.ArrayCopy, 82); + assert.strictEqual(binaryen.ExpressionId.ArrayFill, 83); + assert.strictEqual(binaryen.ExpressionId.ArrayInitData, 84); + assert.strictEqual(binaryen.ExpressionId.ArrayInitElem, 85); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.ArrayRMWId, undefined); assert.notStrictEqual(binaryen.ExpressionId.ArrayRMWId, 86); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.ArrayCmpxchgId, undefined); assert.notStrictEqual(binaryen.ExpressionId.ArrayCmpxchgId, 87); + assert.strictEqual(binaryen.ExpressionId.RefAs, 88); + assert.strictEqual(binaryen.ExpressionId.StringNew, 89); + assert.strictEqual(binaryen.ExpressionId.StringConst, 90); + assert.strictEqual(binaryen.ExpressionId.StringMeasure, 91); + assert.strictEqual(binaryen.ExpressionId.StringEncode, 92); + assert.strictEqual(binaryen.ExpressionId.StringConcat, 93); + assert.strictEqual(binaryen.ExpressionId.StringEq, 94); + // @ts-expect-error + assert.strictEqual(binaryen.ExpressionId.StringTest, undefined); assert.notStrictEqual(binaryen.ExpressionId.StringTest, 95); + assert.strictEqual(binaryen.ExpressionId.StringWTF16Get, 96); + assert.strictEqual(binaryen.ExpressionId.StringSliceWTF, 97); + + assert.strictEqual(binaryen.ExpressionId.WideIntAddSub, 106); + assert.strictEqual(binaryen.ExpressionId.WideIntMul, 107); + }); + + + test(".ExternalKind", () => { + // NOTE: the length is twice the number of members due to how TypeScript emits enums. + assert.strictEqual(Object.entries(binaryen.ExternalKind).length, 10); + + assert.strictEqual(binaryen.ExternalKind.ExternalFunction, 0); + assert.strictEqual(binaryen.ExternalKind.ExternalTable, 1); + assert.strictEqual(binaryen.ExternalKind.ExternalMemory, 2); + assert.strictEqual(binaryen.ExternalKind.ExternalGlobal, 3); + assert.strictEqual(binaryen.ExternalKind.ExternalTag, 4); + }); }); From ed7dc16de309d983682bc16ee811d16c8ed52a94 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 15:53:35 -0400 Subject: [PATCH 187/247] fix: capitalize `-R` cli arg --- ts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/package.json b/ts/package.json index f503534a750..e2710a11771 100644 --- a/ts/package.json +++ b/ts/package.json @@ -17,7 +17,7 @@ "main": "./dist/binaryen.js", "scripts": { "make": "mkdir -p ../build/ && (cd ../build/ && emcmake cmake ../ && emmake make binaryen_js)", - "postmake": "rm -rf ./build/ && mkdir -p ./build/ && cp -r ../build/bin/* ./build/", + "postmake": "rm -rf ./build/ && mkdir -p ./build/ && cp -R ../build/bin/* ./build/", "compile": "rm -rf ./dist/ && tsc && tsc --project ./test/tsconfig.json", "lint": "eslint ./", "docs": "rm -rf ./docs/out/ && typedoc", From 39517455f3841d63e940438f682f006f8e33604b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 15:55:40 -0400 Subject: [PATCH 188/247] style: gitignore comment adjectives --- ts/.gitignore | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ts/.gitignore b/ts/.gitignore index eb09596e6b4..14246bc4362 100644 --- a/ts/.gitignore +++ b/ts/.gitignore @@ -1,11 +1,11 @@ # dependency directories node_modules/ -# build files +# built files build/ -# compiling TypeScript +# compiled TypeScript dist/ -# generating documentation +# generated documentation docs/out/ From 0ebf8d970079c757b799bbd5c7cad8458f9ed90a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 16:09:28 -0400 Subject: [PATCH 189/247] docs: move generated docs directory --- .gitignore | 3 +++ ts/.gitignore | 3 --- ts/README.md | 10 +++++----- ts/eslint.config.js | 2 +- ts/package.json | 2 +- ts/typedoc.config.js | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 825a446c7fa..3265d12718e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ options-pinned.h # Files generated by test suite and fuzzer /out/ +# generated documentation +docs/ + # files related to building in-tree CMakeFiles *.cmake diff --git a/ts/.gitignore b/ts/.gitignore index 14246bc4362..c497ac9cba5 100644 --- a/ts/.gitignore +++ b/ts/.gitignore @@ -6,6 +6,3 @@ build/ # compiled TypeScript dist/ - -# generated documentation -docs/out/ diff --git a/ts/README.md b/ts/README.md index 17fc73aa1d0..e8e6c0d49e9 100644 --- a/ts/README.md +++ b/ts/README.md @@ -78,10 +78,10 @@ Generated documentation is built with [TypeDoc](https://typedoc.org/), a tool th After developing and updating doc-comments, regenerate docs and view them in your browser. ```zsh -$ npm run docs # builds a static site to ./docs/out/ -$ open ./docs/out/index.html +$ npm run docs # builds a static site to ../docs/binaryen.ts/ +$ open ../docs/binaryen.ts/index.html ``` -Don’t put anything important in `./docs/out/`, as it gets deleted and rebuilt each time. +Don’t put anything important in `../docs/`. TODO: Docs will be hosted publicly online somewhere soon. @@ -152,6 +152,6 @@ TODO: this section - `dist/` *(gitignored)*: output of **tsc**; this gets published to npm for consumers -- `docs/`: documentation +- `docs/`: documentation assets - - `out/` *(gitignored)*: output of **typedoc**; this will probably be hosted online +- `../docs/binaryen.ts/` *(gitignored)*: output of **typedoc**; this will probably be hosted online diff --git a/ts/eslint.config.js b/ts/eslint.config.js index 963ebddb078..f788cead9a5 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -6,7 +6,7 @@ import tseslint from "typescript-eslint"; export default [ - {ignores: ["./build/", "./dist/", "./docs/out/"]}, + {ignores: ["./build/", "./dist/", "./docs/"]}, eslint.configs.recommended, // https://github.com/eslint/eslint/blob/v10.2.1/packages/js/src/configs/eslint-recommended.js { diff --git a/ts/package.json b/ts/package.json index e2710a11771..0878d06c6f9 100644 --- a/ts/package.json +++ b/ts/package.json @@ -20,7 +20,7 @@ "postmake": "rm -rf ./build/ && mkdir -p ./build/ && cp -R ../build/bin/* ./build/", "compile": "rm -rf ./dist/ && tsc && tsc --project ./test/tsconfig.json", "lint": "eslint ./", - "docs": "rm -rf ./docs/out/ && typedoc", + "docs": "rm -rf ../docs/binaryen.ts/ && typedoc", "test": "tsx --test --test-isolation=none -- './test/**/*.test.ts'", "build": "npm run compile && npm run lint && npm run docs && npm run test" }, diff --git a/ts/typedoc.config.js b/ts/typedoc.config.js index 9d67ad8a8e3..13746415bcf 100644 --- a/ts/typedoc.config.js +++ b/ts/typedoc.config.js @@ -3,7 +3,7 @@ export default { entryPoints: ["./src/binaryen.ts"], projectDocuments: ["./docs/API-Overview.md"], useFirstParagraphOfCommentAsSummary: true, - out: "./docs/out/", + out: "../docs/binaryen.ts/", githubPages: false, // when `false`, does not generate a `.nojekyll` file to prevent GitHub Pages from using Jekyll customCss: "./docs/styles.css", From 03247fa98c600ca8882569c4b89f4efa89afed8f Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 16:36:02 -0400 Subject: [PATCH 190/247] docs: update README --- ts/README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ts/README.md b/ts/README.md index e8e6c0d49e9..8d0f2081048 100644 --- a/ts/README.md +++ b/ts/README.md @@ -83,11 +83,12 @@ $ open ../docs/binaryen.ts/index.html ``` Don’t put anything important in `../docs/`. -TODO: Docs will be hosted publicly online somewhere soon. +Docs are hosted online at , +and will be moved to once this fork is merged in. #### Run Tests -The test suite is empty for now, but you can still run it. -Node v24+ required. +The test suite is still in progress, migrating from `../test/binaryen.js/`. +The new test suite uses the Node v26+ test runner. ```zsh $ npm run test ``` @@ -128,6 +129,8 @@ TODO: this section - `typedoc.config.js`: documentation generator configuration +- `build/` *(gitignored)*: output of **Emscripten**; this is imported by the `src/` library + - `src/`: human-written source code - `binaryen.ts`: the entrypoint; exports everything available to consumers @@ -150,8 +153,8 @@ TODO: this section - `services/`: namespace-like, stateless classes -- `dist/` *(gitignored)*: output of **tsc**; this gets published to npm for consumers +- `dist/` *(gitignored)*: output of **tsc**; this gets bundled and published to NPM for consumers - `docs/`: documentation assets -- `../docs/binaryen.ts/` *(gitignored)*: output of **typedoc**; this will probably be hosted online +- `../docs/binaryen.ts/` *(gitignored)*: output of **typedoc**; hosted online From eec0a9de43a4e414a71562f43b91556bfe1e793f Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 17:04:53 -0400 Subject: [PATCH 191/247] fixup! 03247fa98 --- ts/README.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/ts/README.md b/ts/README.md index 8d0f2081048..75e16a2a06b 100644 --- a/ts/README.md +++ b/ts/README.md @@ -73,19 +73,30 @@ $ git commit -m "test: add/update tests" $ git commit -m "build: make a change related to the package build system" ``` -#### Read the Docs +#### Update Docs Generated documentation is built with [TypeDoc](https://typedoc.org/), a tool that parses comments in the TS source files and produces beautiful HTML. -After developing and updating doc-comments, regenerate docs and view them in your browser. +After developing and updating doc-comments, regenerate docs and view them locally in your browser. ```zsh $ npm run docs # builds a static site to ../docs/binaryen.ts/ $ open ../docs/binaryen.ts/index.html ``` Don’t put anything important in `../docs/`. -Docs are hosted online at , +Documentation is hosted online via GitHub Pages at , and will be moved to once this fork is merged in. +Upon every release, public docs should be redeployed via updating the `gh-pages` branch. On that branch, the `../docs/` folder is checked in. +You need to switch to that branch, merge in your changes, rebuild the docs, then commit and push. +```zsh +$ git switch gh-pages +$ git merge --no-commit main +$ npm run docs +$ git add ../docs/binaryen.ts/ +$ git merge --continue +$ git push +``` + #### Run Tests The test suite is still in progress, migrating from `../test/binaryen.js/`. The new test suite uses the Node v26+ test runner. From 2040fd01c349f64aca15772b3419c069501c187a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 18:50:13 -0400 Subject: [PATCH 192/247] fix: import `out` & `err` from emscripten --- CMakeLists.txt | 2 +- ts/src/-pre.ts | 2 ++ ts/src/classes/module/Module.ts | 12 ++++-------- ts/src/globals.ts | 18 +++++++++++++----- ts/src/types/binaryen_js.d.ts | 4 ++++ ts/test/binaryen.test.ts | 2 ++ 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b6ba0303a1..99057012b5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -555,7 +555,7 @@ if(EMSCRIPTEN) else() target_link_libraries(binaryen_js PRIVATE "-sEXPORT_ES6") endif() - target_link_libraries(binaryen_js PRIVATE "-sEXPORTED_RUNTIME_METHODS=HEAP8,HEAPU8,HEAP32,HEAPU32,stackSave,stackRestore,stackAlloc,UTF8ToString,stringToAscii,stringToUTF8OnStack,getExceptionMessage") + target_link_libraries(binaryen_js PRIVATE "-sEXPORTED_RUNTIME_METHODS=out,err,HEAP8,HEAPU8,HEAP32,HEAPU32,stackSave,stackRestore,stackAlloc,UTF8ToString,stringToAscii,stringToUTF8OnStack,getExceptionMessage") target_link_libraries(binaryen_js PRIVATE "-sEXPORTED_FUNCTIONS=_malloc,_free,__i32_load") target_link_libraries(binaryen_js PRIVATE "--post-js=${CMAKE_CURRENT_SOURCE_DIR}/src/js/binaryen.js-post.js") target_link_libraries(binaryen_js PRIVATE optimized "--closure=1") diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index da336ca046b..d0567c23faf 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -11,6 +11,8 @@ export const BinaryenObj = await Binaryen(); export const { _malloc, _free, + out, + err, HEAP8, HEAPU8, HEAP32, diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 5d2317a6e71..f1f994bf846 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -83,11 +83,6 @@ import { -/** Probably used in `BinaryenObj["_BinaryenModulePrintAsmjs"]`. */ -declare let out: any; - - - export enum Feature { MVP = BinaryenObj["_BinaryenFeatureMVP"](), Atomics = BinaryenObj["_BinaryenFeatureAtomics"](), @@ -360,13 +355,14 @@ export class Module { * @category Emission & Execution */ emitAsmjs(): string { + /* See comment in the `emitText()` global function (`../../globals.ts`) for what’s going on here. */ let returned = ""; - const saved = out; - out = (x: string) => { + const temp_out = BinaryenObj.out; + BinaryenObj.out = (x: string): void => { returned += `${ x }\n`; }; BinaryenObj["_BinaryenModulePrintAsmjs"](this[PTR]); - out = saved; + BinaryenObj.out = temp_out; return returned; } diff --git a/ts/src/globals.ts b/ts/src/globals.ts index c3b3fe70297..a1aeeb3d6cf 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -187,17 +187,25 @@ function handleFatalError(func: () => T): T { // ## General Binaryen Functions ## // -/** Probably used in `BinaryenObj["_BinaryenExpressionPrint"]`. */ -declare let out: any; /** Emits the expression in Binaryen’s s-expression text format (not official stack-style text format). */ export function emitText(expr: ExpressionRef): string { + /* + * `out` is Emscripten's `stdout` function (an alias of `console.log`), + * called internally by `BinaryenExpressionPrint()` to print its output. + * We have to temporarily swap out the function itself + * so that when `BinaryenExpressionPrint()` calls it, + * it calls our capturing function instead. + * + * We can’t use `import {out} from "./-pre.ts";` because ES Module imports can’t be reassigned. + * Instead, we reassign directly on `BinaryenObj`. + */ let returned = ""; - const saved = out; - out = (x: string) => { + const temp_out = BinaryenObj.out; + BinaryenObj.out = (x: string): void => { returned += `${ x }\n`; }; BinaryenObj["_BinaryenExpressionPrint"](expr); - out = saved; + BinaryenObj.out = temp_out; return returned; } diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index dbf4ed7ef96..1f4d3241a5d 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -11,6 +11,10 @@ declare module "#binaryen-raw" { // Helper tools defined in Emscripten’s codebase needed in TS. Listed in `EXPORTED_RUNTIME_METHODS`. + // https://github.com/emscripten-core/emscripten/blob/main/src/shell_minimal.js + out(x: unknown): void; // alias of `console.log` + err(x: unknown): void; // alias of `console.error` + // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libcore.js HEAP8: Int8Array; HEAPU8: Uint8Array; diff --git a/ts/test/binaryen.test.ts b/ts/test/binaryen.test.ts index 6c758e0cbb4..1ea27b16149 100644 --- a/ts/test/binaryen.test.ts +++ b/ts/test/binaryen.test.ts @@ -13,6 +13,8 @@ suite("binaryen", () => { assert.ok(__pre.BinaryenObj); assert.ok(__pre._malloc); assert.ok(__pre._free); + assert.ok(__pre.out); + assert.ok(__pre.err); assert.ok(__pre.HEAP8); assert.ok(__pre.HEAPU8); assert.ok(__pre.HEAP32); From fca86c4ea92491441a78923b3403bef96109c6c4 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 20:19:55 -0400 Subject: [PATCH 193/247] fix: typings --- ts/src/binaryen.ts | 5 ++++- ts/src/classes/TypeBuilder.ts | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ts/src/binaryen.ts b/ts/src/binaryen.ts index c2238f29e34..6d25713160b 100644 --- a/ts/src/binaryen.ts +++ b/ts/src/binaryen.ts @@ -13,5 +13,8 @@ export { ExpressionRunner, ExpressionRunnerFlag, } from "./classes/ExpressionRunner.ts"; -export {Relooper} from "./classes/Relooper.ts"; +export { + type RelooperBlockRef, + Relooper, +} from "./classes/Relooper.ts"; export * from "./-deprecations.ts"; diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index d6ea02c82c9..5f109b8392f 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -22,11 +22,11 @@ import type { */ type Field = { /** The type of the struct field. */ - type: Type, + readonly type: Type, /** The field’s packed type. */ - packedType: PackedType, + readonly packedType: PackedType, /** Is the field mutable? */ - mutable: boolean, + readonly mutable: boolean, }; From 556eacf7c8925784df353ddb07f054c7c5b70985 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 20:20:39 -0400 Subject: [PATCH 194/247] feat: default params --- ts/src/classes/TypeBuilder.ts | 2 +- ts/src/services/expression-builder/generic.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index 5f109b8392f..54a90289374 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -34,7 +34,7 @@ type Field = { export class TypeBuilder { readonly #ptr: number; - constructor(size: number) { + constructor(size: number = 0) { this.#ptr = BinaryenObj["_TypeBuilderCreate"](size); } diff --git a/ts/src/services/expression-builder/generic.ts b/ts/src/services/expression-builder/generic.ts index f5bcd744208..1730ee63956 100644 --- a/ts/src/services/expression-builder/generic.ts +++ b/ts/src/services/expression-builder/generic.ts @@ -20,6 +20,9 @@ import { none, unreachable, } from "../../constants.ts"; +import { + expressionBuilder, +} from "./expressionBuilder.ts"; @@ -70,7 +73,7 @@ export function blocks(mod: Module) { ), /** Creates an ‘if’ or ‘if/else’ combination. */ - if: (ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef => ( + if: (ifTrue: ExpressionRef, ifFalse: ExpressionRef = expressionBuilder(mod).nop()): ExpressionRef => ( BinaryenObj["_BinaryenIf"](mod[PTR], ifTrue, ifFalse) ), } as const; From 0b0876c39f6b2f6904c3153de0d9bdaf95959856 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 15 May 2026 20:21:02 -0400 Subject: [PATCH 195/247] fix: `if` condition --- ts/src/services/expression-builder/generic.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ts/src/services/expression-builder/generic.ts b/ts/src/services/expression-builder/generic.ts index 1730ee63956..0c0e9e5a0b2 100644 --- a/ts/src/services/expression-builder/generic.ts +++ b/ts/src/services/expression-builder/generic.ts @@ -73,8 +73,8 @@ export function blocks(mod: Module) { ), /** Creates an ‘if’ or ‘if/else’ combination. */ - if: (ifTrue: ExpressionRef, ifFalse: ExpressionRef = expressionBuilder(mod).nop()): ExpressionRef => ( - BinaryenObj["_BinaryenIf"](mod[PTR], ifTrue, ifFalse) + if: (condition: ExpressionRef, ifTrue: ExpressionRef, ifFalse: ExpressionRef = expressionBuilder(mod).nop()): ExpressionRef => ( + BinaryenObj["_BinaryenIf"](mod[PTR], condition, ifTrue, ifFalse) ), } as const; } From a216355e23e462b13cbb99da0d3e023071edf979 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 12:49:31 -0400 Subject: [PATCH 196/247] docs: add typings for expression-builder functions on Module --- ts/src/classes/module/Module.ts | 58 ++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index f1f994bf846..088ee29df6a 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -536,8 +536,64 @@ export namespace Module { /* * The relocation of all `ExpressionBuilder` props from `Module` to `Module#wasm` is a breaking change, * so we want to let users access it the old way but with deprecation warnings. - * This function delegates any accesses to those properties. + * The following interface declares typings for TS support, and + * the function below delegates accesses to those properties at runtime. */ +export interface Module { + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ nop: ExpressionBuilder["nop"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ unreachable: ExpressionBuilder["unreachable"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ drop: ExpressionBuilder["drop"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ select: ExpressionBuilder["select"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ block: ExpressionBuilder["block"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ loop: ExpressionBuilder["loop"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ if: ExpressionBuilder["if"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ br: ExpressionBuilder["br"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ br_if: ExpressionBuilder["br_if"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ br_table: ExpressionBuilder["br_table"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ br_on_null: ExpressionBuilder["br_on_null"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ br_on_non_null: ExpressionBuilder["br_on_non_null"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ br_on_cast: ExpressionBuilder["br_on_cast"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ br_on_cast_fail: ExpressionBuilder["br_on_cast_fail"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ break: ExpressionBuilder["break"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ switch: ExpressionBuilder["switch"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ call: ExpressionBuilder["call"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ call_ref: ExpressionBuilder["call_ref"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ call_indirect: ExpressionBuilder["call_indirect"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ return: ExpressionBuilder["return"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ return_call: ExpressionBuilder["return_call"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ return_call_ref: ExpressionBuilder["return_call_ref"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ return_call_indirect: ExpressionBuilder["return_call_indirect"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ callIndirect: ExpressionBuilder["callIndirect"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ returnCall: ExpressionBuilder["returnCall"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ returnCallIndirect: ExpressionBuilder["returnCallIndirect"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ throw: ExpressionBuilder["throw"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ throw_ref: ExpressionBuilder["throw_ref"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ try_table: ExpressionBuilder["try_table"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ rethrow: ExpressionBuilder["rethrow"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ try: ExpressionBuilder["try"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ local: ExpressionBuilder["local"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ global: ExpressionBuilder["global"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ table: ExpressionBuilder["table"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ memory: ExpressionBuilder["memory"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ data: ExpressionBuilder["data"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ ref: ExpressionBuilder["ref"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ i31: ExpressionBuilder["i31"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ tuple: ExpressionBuilder["tuple"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ struct: ExpressionBuilder["struct"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ array: ExpressionBuilder["array"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ i32: ExpressionBuilder["i32"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ i64: ExpressionBuilder["i64"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ f32: ExpressionBuilder["f32"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ f64: ExpressionBuilder["f64"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ v128: ExpressionBuilder["v128"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ i8x16: ExpressionBuilder["i8x16"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ i16x8: ExpressionBuilder["i16x8"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ i32x4: ExpressionBuilder["i32x4"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ i64x2: ExpressionBuilder["i64x2"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ f32x4: ExpressionBuilder["f32x4"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ f64x2: ExpressionBuilder["f64x2"]; + /** @deprecated This function moved to {@link Module#wasm}. @hidden */ atomic: ExpressionBuilder["atomic"]; +} Object.keys(new Module().wasm).forEach((key) => { if (!Reflect.has(Module.prototype, key)) { Reflect.defineProperty(Module.prototype, key, { From 2eba32670e8267702369ec29eb1c34b64912ab2e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 13:34:59 -0400 Subject: [PATCH 197/247] chore: delete scratch comments --- ts/src/types/binaryen_js.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index 1f4d3241a5d..4f17d9e5a29 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -26,11 +26,11 @@ declare module "#binaryen-raw" { // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libstrings.js UTF8ToString(n: number): string; - stringToAscii(text: string, buffer: number): void; // yes - stringToUTF8OnStack(str: string): number; // yes + stringToAscii(text: string, buffer: number): void; + stringToUTF8OnStack(str: string): number; // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libexceptions.js - getExceptionMessage(e: number | Error): [string, string]; // yes + getExceptionMessage(e: number | Error): [string, string]; // Binaryen’s functions in the C++ codebase, e.g. `_BinaryenTypeUnreachable`. From b6a26dffdd04913958163a2c572096087716325a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 13:40:23 -0400 Subject: [PATCH 198/247] fix: handleFatalError typings --- ts/src/globals.ts | 6 ++---- ts/src/types/binaryen_js.d.ts | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ts/src/globals.ts b/ts/src/globals.ts index a1aeeb3d6cf..57791e87195 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -168,7 +168,7 @@ function handleFatalError(func: () => T): T { throw new Error(message.slice(7).trim()); } } else { - const err = e as Error; + const err = e as Error | {message?: string}; // Newer version of emscripten always throw CppException object but don’t // always populate the `.message` field. // TODO: Set EXCEPTION_STACK_TRACES instead? @@ -176,10 +176,8 @@ function handleFatalError(func: () => T): T { const [_, message] = getExceptionMessage(err); err.message = message; } - err.message = err.message.replace("Fatal:", ""); - err.message = err.message.trim(); + err.message = err.message.replace("Fatal:", "").trim(); } - // Rethrow anything else. throw e; } } diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index 4f17d9e5a29..1111c81ca6a 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -30,7 +30,7 @@ declare module "#binaryen-raw" { stringToUTF8OnStack(str: string): number; // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libexceptions.js - getExceptionMessage(e: number | Error): [string, string]; + getExceptionMessage(e: number | Error | object): [string, string]; // Binaryen’s functions in the C++ codebase, e.g. `_BinaryenTypeUnreachable`. From a444398d576b6d55cc77e35111076e0abc2d6089 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 16:56:51 -0400 Subject: [PATCH 199/247] feat: add moduleArgs --- ts/src/-pre.ts | 9 ++++++++- ts/src/lib.ts | 1 + ts/src/types/binaryen_js.d.ts | 2 +- ts/test/binaryen.test.ts | 6 +++++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index d0567c23faf..a9598211659 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -4,7 +4,14 @@ import Binaryen from "#binaryen-raw"; /** The main object provided by Emscripten. This is what gets wrapped. It is not exposed to the consumer. */ -export const BinaryenObj = await Binaryen(); +export const BinaryenObj = await Binaryen({ + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + print: (...args: readonly any[]): void => console?.log?.(...args), + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + printWarn: (...args: readonly any[]): void => (console?.warn ?? console?.log)?.(...args), + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + printErr: (...args: readonly any[]): void => (console?.error ?? console?.log)?.(...args), +}); diff --git a/ts/src/lib.ts b/ts/src/lib.ts index 7af0cee5832..be875bae025 100644 --- a/ts/src/lib.ts +++ b/ts/src/lib.ts @@ -3,6 +3,7 @@ +/** @deprecated use `BinaryenObj.printWarn`. */ export function consoleWarn(...args: any[]): void { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition return (console?.warn ?? console?.log)?.call(undefined, ...args); diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index 1111c81ca6a..930e96fecf1 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -38,5 +38,5 @@ declare module "#binaryen-raw" { [key: string]: (...args: readonly (number | bigint | boolean)[]) => number; } - export default function Binaryen(): Promise; + export default function Binaryen(moduleArg?: T): Promise; } diff --git a/ts/test/binaryen.test.ts b/ts/test/binaryen.test.ts index 1ea27b16149..c084f916345 100644 --- a/ts/test/binaryen.test.ts +++ b/ts/test/binaryen.test.ts @@ -8,7 +8,7 @@ import * as binaryen from "../src/binaryen.ts"; suite("binaryen", () => { - test("[internal] Emscripten artifacts exist.", async () => { + test("[internal] Emscripten artifacts and module arguments exist.", async () => { const __pre = await import("../src/-pre.ts"); assert.ok(__pre.BinaryenObj); assert.ok(__pre._malloc); @@ -26,6 +26,10 @@ suite("binaryen", () => { assert.ok(__pre.stringToAscii); assert.ok(__pre.stringToUTF8OnStack); assert.ok(__pre.getExceptionMessage); + + assert.ok(__pre.BinaryenObj.print); + assert.ok(__pre.BinaryenObj.printWarn); + assert.ok(__pre.BinaryenObj.printErr); }); From c470e48bafc6f0bc92df0fd619ecb7216c3cdbf6 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 17:12:51 -0400 Subject: [PATCH 200/247] refactor: delete `consoleWarn` --- ts/src/-deprecations.ts | 88 +++++++++---------- ts/src/classes/module/Module.ts | 3 +- ts/src/lib.ts | 10 +-- ts/src/services/expression-builder/f32.ts | 16 ++-- ts/src/services/expression-builder/f64.ts | 16 ++-- ts/src/services/expression-builder/generic.ts | 17 ++-- ts/src/services/expression-builder/i16x8.ts | 14 +-- ts/src/services/expression-builder/i32.ts | 24 ++--- ts/src/services/expression-builder/i64.ts | 25 +++--- ts/src/services/expression-builder/i8x16.ts | 11 +-- 10 files changed, 106 insertions(+), 118 deletions(-) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index c4b8571bc62..a1f91a37347 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -2,6 +2,9 @@ +import { + BinaryenObj, +} from "./-pre.ts"; import type * as expressions from "./classes/expression/index.ts"; import { Feature, @@ -19,9 +22,6 @@ import { type TableRef, type TagRef, } from "./constants.ts"; -import { - consoleWarn, -} from "./lib.ts"; import { settings, } from "./services/SettingsService.ts"; @@ -86,7 +86,7 @@ export const Table = Module.Table; /** @deprecated Use {@link Module#getSideEffects} instead. */ export function getSideEffects(expr: ExpressionRef, mod: Module) { - consoleWarn("Global function `getSideEffects(expr, mod)` is deprecated; use `mod.getSideEffects(expr)` instead."); + BinaryenObj.printWarn("Global function `getSideEffects(expr, mod)` is deprecated; use `mod.getSideEffects(expr)` instead."); return mod.getSideEffects(expr); } @@ -94,35 +94,35 @@ export function getSideEffects(expr: ExpressionRef, mod: Module) { /** @deprecated Use {@link Module.Tag | `new Module.Tag(tagref)`} instead. */ export function getTagInfo(tag: TagRef) { - consoleWarn("Global function `getTagInfo` is deprecated; use `new Module.Tag(tagref)` instead."); + BinaryenObj.printWarn("Global function `getTagInfo` is deprecated; use `new Module.Tag(tagref)` instead."); return new Module.Tag(tag); } /** @deprecated Use {@link Module.Global | `new Module.Global(globalref)`} instead. */ export function getGlobalInfo(global: GlobalRef) { - consoleWarn("Global function `getGlobalInfo` is deprecated; use `new Module.Global(globalref)` instead."); + BinaryenObj.printWarn("Global function `getGlobalInfo` is deprecated; use `new Module.Global(globalref)` instead."); return new Module.Global(global); } // function `getMemoryInfo` always existed in `Module` /** @deprecated Use {@link Module.Table | `new Module.Table(tableref)`} instead. */ export function getTableInfo(table: TableRef) { - consoleWarn("Global function `getTableInfo` is deprecated; use `new Module.Table(tableref)` instead."); + BinaryenObj.printWarn("Global function `getTableInfo` is deprecated; use `new Module.Table(tableref)` instead."); return new Module.Table(table); } /** @deprecated Use {@link Module.Function | `new Module.Function(funcref)`} instead. */ export function getFunctionInfo(func: FunctionRef) { - consoleWarn("Global function `getFunctionInfo` is deprecated; use `new Module.Function(funcref)` instead."); + BinaryenObj.printWarn("Global function `getFunctionInfo` is deprecated; use `new Module.Function(funcref)` instead."); return new Module.Function(func); } // function `getDataSegmentInfo` always existed in `Module` /** @deprecated Use {@link Module.ElementSegment | `new Module.ElementSegment(segmentref)`} instead. */ export function getElementSegmentInfo(segment: ElementSegmentRef) { - consoleWarn("Global function `getElementSegmentInfo` is deprecated; use `new Module.ElementSegment(segmentref)` instead."); + BinaryenObj.printWarn("Global function `getElementSegmentInfo` is deprecated; use `new Module.ElementSegment(segmentref)` instead."); return new Module.ElementSegment(segment); } // no function `getImportInfo` ever existed /** @deprecated Use {@link Module.Export | `new Module.Export(exportref)`} instead. */ export function getExportInfo(xport: ExportRef) { - consoleWarn("Global function `getExportInfo` is deprecated; use `new Module.Export(exportref)` instead."); + BinaryenObj.printWarn("Global function `getExportInfo` is deprecated; use `new Module.Export(exportref)` instead."); return new Module.Export(xport); } @@ -130,142 +130,142 @@ export function getExportInfo(xport: ExportRef) { /** @deprecated Use {@link settings.optimizeLevel} instead. */ export function getOptimizeLevel() { - consoleWarn("Global function `getOptimizeLevel` is deprecated; use `settings.optimizeLevel` instead."); + BinaryenObj.printWarn("Global function `getOptimizeLevel` is deprecated; use `settings.optimizeLevel` instead."); return settings.optimizeLevel; } /** @deprecated Use {@link settings.optimizeLevel} instead. */ export function setOptimizeLevel(level: number) { - consoleWarn("Global function `setOptimizeLevel` is deprecated; use `settings.optimizeLevel = level` instead."); + BinaryenObj.printWarn("Global function `setOptimizeLevel` is deprecated; use `settings.optimizeLevel = level` instead."); settings.optimizeLevel = level; } /** @deprecated Use {@link settings.shrinkLevel} instead. */ export function getShrinkLevel() { - consoleWarn("Global function `getShrinkLevel` is deprecated; use `settings.shrinkLevel` instead."); + BinaryenObj.printWarn("Global function `getShrinkLevel` is deprecated; use `settings.shrinkLevel` instead."); return settings.shrinkLevel; } /** @deprecated Use {@link settings.shrinkLevel} instead. */ export function setShrinkLevel(level: number) { - consoleWarn("Global function `setShrinkLevel` is deprecated; use `settings.shrinkLevel = level` instead."); + BinaryenObj.printWarn("Global function `setShrinkLevel` is deprecated; use `settings.shrinkLevel = level` instead."); settings.shrinkLevel = level; } /** @deprecated Use {@link settings.debugInfo} instead. */ export function getDebugInfo(): boolean { - consoleWarn("Global function `getDebugInfo` is deprecated; use `settings.debugInfo` instead."); + BinaryenObj.printWarn("Global function `getDebugInfo` is deprecated; use `settings.debugInfo` instead."); return settings.debugInfo; } /** @deprecated Use {@link settings.debugInfo} instead. */ export function setDebugInfo(enabled: boolean) { - consoleWarn("Global function `setDebugInfo` is deprecated; use `settings.debugInfo = enabled` instead."); + BinaryenObj.printWarn("Global function `setDebugInfo` is deprecated; use `settings.debugInfo = enabled` instead."); settings.debugInfo = enabled; } /** @deprecated Use {@link settings.trapsNeverHappen} instead. */ export function getTrapsNeverHappen(): boolean { - consoleWarn("Global function `getTrapsNeverHappen` is deprecated; use `settings.trapsNeverHappen` instead."); + BinaryenObj.printWarn("Global function `getTrapsNeverHappen` is deprecated; use `settings.trapsNeverHappen` instead."); return settings.trapsNeverHappen; } /** @deprecated Use {@link settings.trapsNeverHappen} instead. */ export function setTrapsNeverHappen(enabled: boolean) { - consoleWarn("Global function `setTrapsNeverHappen` is deprecated; use `settings.trapsNeverHappen = enabled` instead."); + BinaryenObj.printWarn("Global function `setTrapsNeverHappen` is deprecated; use `settings.trapsNeverHappen = enabled` instead."); settings.trapsNeverHappen = enabled; } /** @deprecated Use {@link settings.closedWorld} instead. */ export function getClosedWorld() { - consoleWarn("Global function `getClosedWorld` is deprecated; use `settings.closedWorld` instead."); + BinaryenObj.printWarn("Global function `getClosedWorld` is deprecated; use `settings.closedWorld` instead."); return settings.closedWorld; } /** @deprecated Use {@link settings.closedWorld} instead. */ export function setClosedWorld(enabled: boolean) { - consoleWarn("Global function `setClosedWorld` is deprecated; use `settings.closedWorld = enabled` instead."); + BinaryenObj.printWarn("Global function `setClosedWorld` is deprecated; use `settings.closedWorld = enabled` instead."); settings.closedWorld = enabled; } /** @deprecated Use {@link settings.lowMemoryUnused} instead. */ export function getLowMemoryUnused() { - consoleWarn("Global function `getLowMemoryUnused` is deprecated; use `settings.lowMemoryUnused` instead."); + BinaryenObj.printWarn("Global function `getLowMemoryUnused` is deprecated; use `settings.lowMemoryUnused` instead."); return settings.lowMemoryUnused; } /** @deprecated Use {@link settings.lowMemoryUnused} instead. */ export function setLowMemoryUnused(enabled: boolean) { - consoleWarn("Global function `setLowMemoryUnused` is deprecated; use `settings.lowMemoryUnused = enabled` instead."); + BinaryenObj.printWarn("Global function `setLowMemoryUnused` is deprecated; use `settings.lowMemoryUnused = enabled` instead."); settings.lowMemoryUnused = enabled; } /** @deprecated Use {@link settings.zeroFilledMemory} instead. */ export function getZeroFilledMemory() { - consoleWarn("Global function `getZeroFilledMemory` is deprecated; use `settings.zeroFilledMemory` instead."); + BinaryenObj.printWarn("Global function `getZeroFilledMemory` is deprecated; use `settings.zeroFilledMemory` instead."); return settings.zeroFilledMemory; } /** @deprecated Use {@link settings.zeroFilledMemory} instead. */ export function setZeroFilledMemory(enabled: boolean) { - consoleWarn("Global function `setZeroFilledMemory` is deprecated; use `settings.zeroFilledMemory = enabled` instead."); + BinaryenObj.printWarn("Global function `setZeroFilledMemory` is deprecated; use `settings.zeroFilledMemory = enabled` instead."); settings.zeroFilledMemory = enabled; } /** @deprecated Use {@link settings.fastMath} instead. */ export function getFastMath() { - consoleWarn("Global function `getFastMath` is deprecated; use `settings.fastMath` instead."); + BinaryenObj.printWarn("Global function `getFastMath` is deprecated; use `settings.fastMath` instead."); return settings.fastMath; } /** @deprecated Use {@link settings.fastMath} instead. */ export function setFastMath(enabled: boolean) { - consoleWarn("Global function `setFastMath` is deprecated; use `settings.fastMath = enabled` instead."); + BinaryenObj.printWarn("Global function `setFastMath` is deprecated; use `settings.fastMath = enabled` instead."); settings.fastMath = enabled; } /** @deprecated Use {@link settings.generateStackIR} instead. */ export function getGenerateStackIR() { - consoleWarn("Global function `getGenerateStackIR` is deprecated; use `settings.generateStackIR` instead."); + BinaryenObj.printWarn("Global function `getGenerateStackIR` is deprecated; use `settings.generateStackIR` instead."); return settings.generateStackIR; } /** @deprecated Use {@link settings.generateStackIR} instead. */ export function setGenerateStackIR(enabled: boolean) { - consoleWarn("Global function `setGenerateStackIR` is deprecated; use `settings.generateStackIR = enabled` instead."); + BinaryenObj.printWarn("Global function `setGenerateStackIR` is deprecated; use `settings.generateStackIR = enabled` instead."); settings.generateStackIR = enabled; } /** @deprecated Use {@link settings.optimizeStackIR} instead. */ export function getOptimizeStackIR() { - consoleWarn("Global function `getOptimizeStackIR` is deprecated; use `settings.optimizeStackIR` instead."); + BinaryenObj.printWarn("Global function `getOptimizeStackIR` is deprecated; use `settings.optimizeStackIR` instead."); return settings.optimizeStackIR; } /** @deprecated Use {@link settings.optimizeStackIR} instead. */ export function setOptimizeStackIR(enabled: boolean) { - consoleWarn("Global function `setOptimizeStackIR` is deprecated; use `settings.optimizeStackIR = enabled` instead."); + BinaryenObj.printWarn("Global function `setOptimizeStackIR` is deprecated; use `settings.optimizeStackIR = enabled` instead."); settings.optimizeStackIR = enabled; } /** @deprecated Use {@link settings.alwaysInlineMaxSize} instead. */ export function getAlwaysInlineMaxSize() { - consoleWarn("Global function `getAlwaysInlineMaxSize` is deprecated; use `settings.alwaysInlineMaxSize` instead."); + BinaryenObj.printWarn("Global function `getAlwaysInlineMaxSize` is deprecated; use `settings.alwaysInlineMaxSize` instead."); return settings.alwaysInlineMaxSize; } /** @deprecated Use {@link settings.alwaysInlineMaxSize} instead. */ export function setAlwaysInlineMaxSize(size: number) { - consoleWarn("Global function `setAlwaysInlineMaxSize` is deprecated; use `settings.alwaysInlineMaxSize = size` instead."); + BinaryenObj.printWarn("Global function `setAlwaysInlineMaxSize` is deprecated; use `settings.alwaysInlineMaxSize = size` instead."); settings.alwaysInlineMaxSize = size; } /** @deprecated Use {@link settings.flexibleInlineMaxSize} instead. */ export function getFlexibleInlineMaxSize() { - consoleWarn("Global function `getFlexibleInlineMaxSize` is deprecated; use `settings.flexibleInlineMaxSize` instead."); + BinaryenObj.printWarn("Global function `getFlexibleInlineMaxSize` is deprecated; use `settings.flexibleInlineMaxSize` instead."); return settings.flexibleInlineMaxSize; } /** @deprecated Use {@link settings.flexibleInlineMaxSize} instead. */ export function setFlexibleInlineMaxSize(size: number) { - consoleWarn("Global function `setFlexibleInlineMaxSize` is deprecated; use `settings.flexibleInlineMaxSize = size` instead."); + BinaryenObj.printWarn("Global function `setFlexibleInlineMaxSize` is deprecated; use `settings.flexibleInlineMaxSize = size` instead."); settings.flexibleInlineMaxSize = size; } /** @deprecated Use {@link settings.oneCallerInlineMaxSize} instead. */ export function getOneCallerInlineMaxSize() { - consoleWarn("Global function `getOneCallerInlineMaxSize` is deprecated; use `settings.oneCallerInlineMaxSize` instead."); + BinaryenObj.printWarn("Global function `getOneCallerInlineMaxSize` is deprecated; use `settings.oneCallerInlineMaxSize` instead."); return settings.oneCallerInlineMaxSize; } /** @deprecated Use {@link settings.oneCallerInlineMaxSize} instead. */ export function setOneCallerInlineMaxSize(size: number) { - consoleWarn("Global function `setOneCallerInlineMaxSize` is deprecated; use `settings.oneCallerInlineMaxSize = size` instead."); + BinaryenObj.printWarn("Global function `setOneCallerInlineMaxSize` is deprecated; use `settings.oneCallerInlineMaxSize = size` instead."); settings.oneCallerInlineMaxSize = size; } /** @deprecated Use {@link settings.allowInliningFunctionsWithLoops} instead. */ export function getAllowInliningFunctionsWithLoops() { - consoleWarn("Global function `getAllowInliningFunctionsWithLoops` is deprecated; use `settings.allowInliningFunctionsWithLoops` instead."); + BinaryenObj.printWarn("Global function `getAllowInliningFunctionsWithLoops` is deprecated; use `settings.allowInliningFunctionsWithLoops` instead."); return settings.allowInliningFunctionsWithLoops; } /** @deprecated Use {@link settings.allowInliningFunctionsWithLoops} instead. */ export function setAllowInliningFunctionsWithLoops(enabled: boolean) { - consoleWarn("Global function `setAllowInliningFunctionsWithLoops` is deprecated; use `settings.allowInliningFunctionsWithLoops = enabled` instead."); + BinaryenObj.printWarn("Global function `setAllowInliningFunctionsWithLoops` is deprecated; use `settings.allowInliningFunctionsWithLoops = enabled` instead."); settings.allowInliningFunctionsWithLoops = enabled; } @@ -273,31 +273,31 @@ export function setAllowInliningFunctionsWithLoops(enabled: boolean) { /** @deprecated Use {@link settings.getPassArgument} instead. */ export function getPassArgument(key: string) { - consoleWarn("Global function `getPassArgument` is deprecated; use `settings.getPassArgument(key)` instead."); + BinaryenObj.printWarn("Global function `getPassArgument` is deprecated; use `settings.getPassArgument(key)` instead."); return settings.getPassArgument(key); } /** @deprecated Use {@link settings.setPassArgument} instead. */ export function setPassArgument(key: string, value?: string) { - consoleWarn("Global function `setPassArgument` is deprecated; use `settings.setPassArgument(key, value)` instead."); + BinaryenObj.printWarn("Global function `setPassArgument` is deprecated; use `settings.setPassArgument(key, value)` instead."); return settings.setPassArgument(key, value); } /** @deprecated Use {@link settings.clearPassArguments} instead. */ export function clearPassArguments() { - consoleWarn("Global function `clearPassArguments` is deprecated; use `settings.clearPassArguments()` instead."); + BinaryenObj.printWarn("Global function `clearPassArguments` is deprecated; use `settings.clearPassArguments()` instead."); return settings.clearPassArguments(); } /** @deprecated Use {@link settings.hasPassToSkip} instead. */ export function hasPassToSkip(pass: string) { - consoleWarn("Global function `hasPassToSkip` is deprecated; use `settings.hasPassToSkip(pass)` instead."); + BinaryenObj.printWarn("Global function `hasPassToSkip` is deprecated; use `settings.hasPassToSkip(pass)` instead."); return settings.hasPassToSkip(pass); } /** @deprecated Use {@link settings.addPassToSkip} instead. */ export function addPassToSkip(pass: string) { - consoleWarn("Global function `addPassToSkip` is deprecated; use `settings.addPassToSkip(pass)` instead."); + BinaryenObj.printWarn("Global function `addPassToSkip` is deprecated; use `settings.addPassToSkip(pass)` instead."); return settings.addPassToSkip(pass); } /** @deprecated Use {@link settings.clearPassesToSkip} instead. */ export function clearPassesToSkip() { - consoleWarn("Global function `clearPassesToSkip` is deprecated; use `settings.clearPassesToSkip()` instead."); + BinaryenObj.printWarn("Global function `clearPassesToSkip` is deprecated; use `settings.clearPassesToSkip()` instead."); return settings.clearPassesToSkip(); } diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 088ee29df6a..960fafa731e 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -37,7 +37,6 @@ import { stringref, } from "../../constants.ts"; import { - consoleWarn, replacedBy, } from "../../lib.ts"; import { @@ -598,7 +597,7 @@ Object.keys(new Module().wasm).forEach((key) => { if (!Reflect.has(Module.prototype, key)) { Reflect.defineProperty(Module.prototype, key, { get() { - consoleWarn(`Module property \`.${ key }\` is deprecated; use \`.wasm.${ key }\` instead.`); + BinaryenObj.printWarn(`Module property \`.${ key }\` is deprecated; use \`.wasm.${ key }\` instead.`); return (this as Module).wasm[key as keyof ExpressionBuilder]; }, }); diff --git a/ts/src/lib.ts b/ts/src/lib.ts index be875bae025..f99b2c6a1c8 100644 --- a/ts/src/lib.ts +++ b/ts/src/lib.ts @@ -3,11 +3,9 @@ -/** @deprecated use `BinaryenObj.printWarn`. */ -export function consoleWarn(...args: any[]): void { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return (console?.warn ?? console?.log)?.call(undefined, ...args); -} +import { + BinaryenObj, +} from "./-pre.ts"; @@ -30,7 +28,7 @@ export function replacedBy(replacement: ) => (typeof method) | void { return (method, context) => function (...args) { const message = `WARNING: ${ context.static ? "Static" : "Instance" } method \`${ String(context.name) }\` is deprecated${ replacement && `; use ${ replacement } instead` }.`; - consoleWarn(message); + BinaryenObj.printWarn(message); return method.call(this, ...args); }; } diff --git a/ts/src/services/expression-builder/f32.ts b/ts/src/services/expression-builder/f32.ts index 0bb8a217388..a7f043b61d8 100644 --- a/ts/src/services/expression-builder/f32.ts +++ b/ts/src/services/expression-builder/f32.ts @@ -1,6 +1,6 @@ import { - consoleWarn, -} from "../../lib.ts"; + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -71,20 +71,20 @@ export function f32(mod: Module) { /** @deprecated */ convert_s: { // @ts-expect-error - /** @deprecated Use `.convert_i32_s()` instead. */ i32: (...args) => { consoleWarn("`.convert_s.i32()` is deprecated; use `.convert_i32_s()` instead."); return f32(mod).convert_i32_s(...args); }, + /** @deprecated Use `.convert_i32_s()` instead. */ i32: (...args) => { BinaryenObj.printWarn("`.convert_s.i32()` is deprecated; use `.convert_i32_s()` instead."); return f32(mod).convert_i32_s(...args); }, // @ts-expect-error - /** @deprecated Use `.convert_i64_s()` instead. */ i64: (...args) => { consoleWarn("`.convert_s.i64()` is deprecated; use `.convert_i64_s()` instead."); return f32(mod).convert_i64_s(...args); }, + /** @deprecated Use `.convert_i64_s()` instead. */ i64: (...args) => { BinaryenObj.printWarn("`.convert_s.i64()` is deprecated; use `.convert_i64_s()` instead."); return f32(mod).convert_i64_s(...args); }, }, /** @deprecated */ convert_u: { // @ts-expect-error - /** @deprecated Use `.convert_i32_u()` instead. */ i32: (...args) => { consoleWarn("`.convert_u.i32()` is deprecated; use `.convert_i32_u()` instead."); return f32(mod).convert_i32_u(...args); }, + /** @deprecated Use `.convert_i32_u()` instead. */ i32: (...args) => { BinaryenObj.printWarn("`.convert_u.i32()` is deprecated; use `.convert_i32_u()` instead."); return f32(mod).convert_i32_u(...args); }, // @ts-expect-error - /** @deprecated Use `.convert_i64_u()` instead. */ i64: (...args) => { consoleWarn("`.convert_u.i64()` is deprecated; use `.convert_i64_u()` instead."); return f32(mod).convert_i64_u(...args); }, + /** @deprecated Use `.convert_i64_u()` instead. */ i64: (...args) => { BinaryenObj.printWarn("`.convert_u.i64()` is deprecated; use `.convert_i64_u()` instead."); return f32(mod).convert_i64_u(...args); }, }, // @ts-expect-error - /** @deprecated Use `.reinterpret_i32()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_i32()` instead."); return this.reinterpret_i32(...args); }, + /** @deprecated Use `.reinterpret_i32()` instead. */ reinterpret(...args) { BinaryenObj.printWarn("`.reinterpret()` is deprecated; use `.reinterpret_i32()` instead."); return this.reinterpret_i32(...args); }, // @ts-expect-error - /** @deprecated Use `.demote_f64()` instead. */ demote(...args) { consoleWarn("`.demote()` is deprecated; use `.demote_f64()` instead."); return this.demote_f64(...args); }, + /** @deprecated Use `.demote_f64()` instead. */ demote(...args) { BinaryenObj.printWarn("`.demote()` is deprecated; use `.demote_f64()` instead."); return this.demote_f64(...args); }, } as const; } diff --git a/ts/src/services/expression-builder/f64.ts b/ts/src/services/expression-builder/f64.ts index e26f18f060b..5b347387bc5 100644 --- a/ts/src/services/expression-builder/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -1,6 +1,6 @@ import { - consoleWarn, -} from "../../lib.ts"; + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -71,20 +71,20 @@ export function f64(mod: Module) { /** @deprecated */ convert_s: { // @ts-expect-error - /** @deprecated Use `.convert_i32_s()` instead. */ i32: (...args) => { consoleWarn("`.convert_s.i32()` is deprecated; use `.convert_i32_s()` instead."); return f64(mod).convert_i32_s(...args); }, + /** @deprecated Use `.convert_i32_s()` instead. */ i32: (...args) => { BinaryenObj.printWarn("`.convert_s.i32()` is deprecated; use `.convert_i32_s()` instead."); return f64(mod).convert_i32_s(...args); }, // @ts-expect-error - /** @deprecated Use `.convert_i64_s()` instead. */ i64: (...args) => { consoleWarn("`.convert_s.i64()` is deprecated; use `.convert_i64_s()` instead."); return f64(mod).convert_i64_s(...args); }, + /** @deprecated Use `.convert_i64_s()` instead. */ i64: (...args) => { BinaryenObj.printWarn("`.convert_s.i64()` is deprecated; use `.convert_i64_s()` instead."); return f64(mod).convert_i64_s(...args); }, }, /** @deprecated */ convert_u: { // @ts-expect-error - /** @deprecated Use `.convert_i32_u()` instead. */ i32: (...args) => { consoleWarn("`.convert_u.i32()` is deprecated; use `.convert_i32_u()` instead."); return f64(mod).convert_i32_u(...args); }, + /** @deprecated Use `.convert_i32_u()` instead. */ i32: (...args) => { BinaryenObj.printWarn("`.convert_u.i32()` is deprecated; use `.convert_i32_u()` instead."); return f64(mod).convert_i32_u(...args); }, // @ts-expect-error - /** @deprecated Use `.convert_i64_u()` instead. */ i64: (...args) => { consoleWarn("`.convert_u.i64()` is deprecated; use `.convert_i64_u()` instead."); return f64(mod).convert_i64_u(...args); }, + /** @deprecated Use `.convert_i64_u()` instead. */ i64: (...args) => { BinaryenObj.printWarn("`.convert_u.i64()` is deprecated; use `.convert_i64_u()` instead."); return f64(mod).convert_i64_u(...args); }, }, // @ts-expect-error - /** @deprecated Use `.reinterpret_i64()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_i64()` instead."); return this.reinterpret_i64(...args); }, + /** @deprecated Use `.reinterpret_i64()` instead. */ reinterpret(...args) { BinaryenObj.printWarn("`.reinterpret()` is deprecated; use `.reinterpret_i64()` instead."); return this.reinterpret_i64(...args); }, // @ts-expect-error - /** @deprecated Use `.promote_f32()` instead. */ promote(...args) { consoleWarn("`.promote()` is deprecated; use `.promote_f32()` instead."); return this.promote_f32(...args); }, + /** @deprecated Use `.promote_f32()` instead. */ promote(...args) { BinaryenObj.printWarn("`.promote()` is deprecated; use `.promote_f32()` instead."); return this.promote_f32(...args); }, } as const; } diff --git a/ts/src/services/expression-builder/generic.ts b/ts/src/services/expression-builder/generic.ts index 0c0e9e5a0b2..1c32a59c141 100644 --- a/ts/src/services/expression-builder/generic.ts +++ b/ts/src/services/expression-builder/generic.ts @@ -7,9 +7,6 @@ import { preserveStack, strToStack, } from "../../-utils.ts"; -import { - consoleWarn, -} from "../../lib.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -131,9 +128,9 @@ export function breaks(mod: Module) { ), // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#br} instead. */ break(...args) { consoleWarn("`.break()` is deprecated; use `.br()` instead."); return this.br(...args); }, + /** @deprecated Use {@link ExpressionBuilder#br} instead. */ break(...args) { BinaryenObj.printWarn("`.break()` is deprecated; use `.br()` instead."); return this.br(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#br_table} instead. */ switch(...args) { consoleWarn("`.switch()` is deprecated; use `.br_table()` instead."); return this.br_table(...args); }, + /** @deprecated Use {@link ExpressionBuilder#br_table} instead. */ switch(...args) { BinaryenObj.printWarn("`.switch()` is deprecated; use `.br_table()` instead."); return this.br_table(...args); }, } as const; } @@ -181,11 +178,11 @@ export function calls(mod: Module) { ), // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#call_indirect} instead. */ callIndirect(...args) { consoleWarn("`.callIndirect()` is deprecated; use `.call_indirect()` instead."); return this.call_indirect(...args); }, + /** @deprecated Use {@link ExpressionBuilder#call_indirect} instead. */ callIndirect(...args) { BinaryenObj.printWarn("`.callIndirect()` is deprecated; use `.call_indirect()` instead."); return this.call_indirect(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#return_call} instead. */ returnCall(...args) { consoleWarn("`.returnCall()` is deprecated; use `.return_call()` instead."); return this.return_call(...args); }, + /** @deprecated Use {@link ExpressionBuilder#return_call} instead. */ returnCall(...args) { BinaryenObj.printWarn("`.returnCall()` is deprecated; use `.return_call()` instead."); return this.return_call(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#return_call_indirect} instead. */ returnCallIndirect(...args) { consoleWarn("`.returnCallIndirect()` is deprecated; use `.return_call_indirect()` instead."); return this.return_call_indirect(...args); }, + /** @deprecated Use {@link ExpressionBuilder#return_call_indirect} instead. */ returnCallIndirect(...args) { BinaryenObj.printWarn("`.returnCallIndirect()` is deprecated; use `.return_call_indirect()` instead."); return this.return_call_indirect(...args); }, } as const; } @@ -228,8 +225,8 @@ export function throws(mod: Module) { // TODO: catch_all_ref // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#throw_ref} instead. */ rethrow(...args) { consoleWarn("`.rethrow()` is deprecated; use `.throw_ref()` instead."); return this.throw_ref(...args); }, + /** @deprecated Use {@link ExpressionBuilder#throw_ref} instead. */ rethrow(...args) { BinaryenObj.printWarn("`.rethrow()` is deprecated; use `.throw_ref()` instead."); return this.throw_ref(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#try_table} instead. */ try(...args) { consoleWarn("`.try()` is deprecated; use `.try_table()` instead."); return this.try_table(...args); }, + /** @deprecated Use {@link ExpressionBuilder#try_table} instead. */ try(...args) { BinaryenObj.printWarn("`.try()` is deprecated; use `.try_table()` instead."); return this.try_table(...args); }, } as const; } diff --git a/ts/src/services/expression-builder/i16x8.ts b/ts/src/services/expression-builder/i16x8.ts index f483b9e09be..1b8ff51e8e2 100644 --- a/ts/src/services/expression-builder/i16x8.ts +++ b/ts/src/services/expression-builder/i16x8.ts @@ -1,12 +1,12 @@ +import { + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; import { Operation, } from "../../constants.ts"; -import { - consoleWarn, -} from "../../lib.ts"; import { binaryFn, simdExtractFn, @@ -84,12 +84,12 @@ export function i16x8(mod: Module) { replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecI16x8), // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.add_sat_s} instead. */ add_saturate_s(...args) { consoleWarn("`.i16x8.add_saturate_s()` is deprecated; use `.i16x8.add_sat_s()` instead."); return this.add_sat_s(...args); }, + /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.add_sat_s} instead. */ add_saturate_s(...args) { BinaryenObj.printWarn("`.i16x8.add_saturate_s()` is deprecated; use `.i16x8.add_sat_s()` instead."); return this.add_sat_s(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.add_sat_u} instead. */ add_saturate_u(...args) { consoleWarn("`.i16x8.add_saturate_u()` is deprecated; use `.i16x8.add_sat_u()` instead."); return this.add_sat_u(...args); }, + /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.add_sat_u} instead. */ add_saturate_u(...args) { BinaryenObj.printWarn("`.i16x8.add_saturate_u()` is deprecated; use `.i16x8.add_sat_u()` instead."); return this.add_sat_u(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.sub_sat_s} instead. */ sub_saturate_s(...args) { consoleWarn("`.i16x8.sub_saturate_s()` is deprecated; use `.i16x8.sub_sat_s()` instead."); return this.sub_sat_s(...args); }, + /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.sub_sat_s} instead. */ sub_saturate_s(...args) { BinaryenObj.printWarn("`.i16x8.sub_saturate_s()` is deprecated; use `.i16x8.sub_sat_s()` instead."); return this.sub_sat_s(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.sub_sat_u} instead. */ sub_saturate_u(...args) { consoleWarn("`.i16x8.sub_saturate_u()` is deprecated; use `.i16x8.sub_sat_u()` instead."); return this.sub_sat_u(...args); }, + /** @deprecated Use {@link ExpressionBuilder#i16x8 | ExpressionBuilder#i16x8.sub_sat_u} instead. */ sub_saturate_u(...args) { BinaryenObj.printWarn("`.i16x8.sub_saturate_u()` is deprecated; use `.i16x8.sub_sat_u()` instead."); return this.sub_sat_u(...args); }, } as const; } diff --git a/ts/src/services/expression-builder/i32.ts b/ts/src/services/expression-builder/i32.ts index 85aec1f8cba..fde0a79f1a6 100644 --- a/ts/src/services/expression-builder/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -1,6 +1,6 @@ import { - consoleWarn, -} from "../../lib.ts"; + BinaryenObj, +} from "../../-pre.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -113,36 +113,36 @@ export function i32(mod: Module) { atomic: atomic(mod), // @ts-expect-error - /** @deprecated Use `.wrap_i64()` instead. */ wrap(...args) { consoleWarn("`.wrap()` is deprecated; use `.wrap_i64()` instead."); return this.wrap_i64(...args); }, + /** @deprecated Use `.wrap_i64()` instead. */ wrap(...args) { BinaryenObj.printWarn("`.wrap()` is deprecated; use `.wrap_i64()` instead."); return this.wrap_i64(...args); }, /** @deprecated */ trunc_s: { // @ts-expect-error - /** @deprecated Use `.trunc_f32_s()` instead. */ f32: (...args) => { consoleWarn("`.trunc_s.f32()` is deprecated; use `.trunc_f32_s()` instead."); return i32(mod).trunc_f32_s(...args); }, + /** @deprecated Use `.trunc_f32_s()` instead. */ f32: (...args) => { BinaryenObj.printWarn("`.trunc_s.f32()` is deprecated; use `.trunc_f32_s()` instead."); return i32(mod).trunc_f32_s(...args); }, // @ts-expect-error - /** @deprecated Use `.trunc_f64_s()` instead. */ f64: (...args) => { consoleWarn("`.trunc_s.f64()` is deprecated; use `.trunc_f64_s()` instead."); return i32(mod).trunc_f64_s(...args); }, + /** @deprecated Use `.trunc_f64_s()` instead. */ f64: (...args) => { BinaryenObj.printWarn("`.trunc_s.f64()` is deprecated; use `.trunc_f64_s()` instead."); return i32(mod).trunc_f64_s(...args); }, }, /** @deprecated */ trunc_u: { // @ts-expect-error - /** @deprecated Use `.trunc_f32_u()` instead. */ f32: (...args) => { consoleWarn("`.trunc_u.f32()` is deprecated; use `.trunc_f32_u()` instead."); return i32(mod).trunc_f32_u(...args); }, + /** @deprecated Use `.trunc_f32_u()` instead. */ f32: (...args) => { BinaryenObj.printWarn("`.trunc_u.f32()` is deprecated; use `.trunc_f32_u()` instead."); return i32(mod).trunc_f32_u(...args); }, // @ts-expect-error - /** @deprecated Use `.trunc_f64_u()` instead. */ f64: (...args) => { consoleWarn("`.trunc_u.f64()` is deprecated; use `.trunc_f64_u()` instead."); return i32(mod).trunc_f64_u(...args); }, + /** @deprecated Use `.trunc_f64_u()` instead. */ f64: (...args) => { BinaryenObj.printWarn("`.trunc_u.f64()` is deprecated; use `.trunc_f64_u()` instead."); return i32(mod).trunc_f64_u(...args); }, }, /** @deprecated */ trunc_s_sat: { // @ts-expect-error - /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: (...args) => { consoleWarn("`.trunc_s_sat.f32()` is deprecated; use `.trunc_sat_f32_s()` instead."); return i32(mod).trunc_sat_f32_s(...args); }, + /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: (...args) => { BinaryenObj.printWarn("`.trunc_s_sat.f32()` is deprecated; use `.trunc_sat_f32_s()` instead."); return i32(mod).trunc_sat_f32_s(...args); }, // @ts-expect-error - /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: (...args) => { consoleWarn("`.trunc_s_sat.f64()` is deprecated; use `.trunc_sat_f64_s()` instead."); return i32(mod).trunc_sat_f64_s(...args); }, + /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: (...args) => { BinaryenObj.printWarn("`.trunc_s_sat.f64()` is deprecated; use `.trunc_sat_f64_s()` instead."); return i32(mod).trunc_sat_f64_s(...args); }, }, /** @deprecated */ trunc_u_sat: { // @ts-expect-error - /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: (...args) => { consoleWarn("`.trunc_u_sat.f32()` is deprecated; use `.trunc_sat_f32_u()` instead."); return i32(mod).trunc_sat_f32_u(...args); }, + /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: (...args) => { BinaryenObj.printWarn("`.trunc_u_sat.f32()` is deprecated; use `.trunc_sat_f32_u()` instead."); return i32(mod).trunc_sat_f32_u(...args); }, // @ts-expect-error - /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: (...args) => { consoleWarn("`.trunc_u_sat.f64()` is deprecated; use `.trunc_sat_f64_u()` instead."); return i32(mod).trunc_sat_f64_u(...args); }, + /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: (...args) => { BinaryenObj.printWarn("`.trunc_u_sat.f64()` is deprecated; use `.trunc_sat_f64_u()` instead."); return i32(mod).trunc_sat_f64_u(...args); }, }, // @ts-expect-error - /** @deprecated Use `.reinterpret_f32()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_f32()` instead."); return this.reinterpret_f32(...args); }, + /** @deprecated Use `.reinterpret_f32()` instead. */ reinterpret(...args) { BinaryenObj.printWarn("`.reinterpret()` is deprecated; use `.reinterpret_f32()` instead."); return this.reinterpret_f32(...args); }, } as const; } diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index c7b16a059db..4b433195a1e 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -4,9 +4,6 @@ import { import { PTR, } from "../../-utils.ts"; -import { - consoleWarn, -} from "../../lib.ts"; import type { Module, } from "../../classes/module/Module.ts"; @@ -143,38 +140,38 @@ export function i64(mod: Module) { atomic: atomic(mod), // @ts-expect-error - /** @deprecated Use `.extend_i32_s()` instead. */ extend_s(...args) { consoleWarn("`.extend_s()` is deprecated; use `.extend_i32_s()` instead."); return this.extend_i32_s(...args); }, + /** @deprecated Use `.extend_i32_s()` instead. */ extend_s(...args) { BinaryenObj.printWarn("`.extend_s()` is deprecated; use `.extend_i32_s()` instead."); return this.extend_i32_s(...args); }, // @ts-expect-error - /** @deprecated Use `.extend_i32_u()` instead. */ extend_u(...args) { consoleWarn("`.extend_u()` is deprecated; use `.extend_i32_u()` instead."); return this.extend_i32_u(...args); }, + /** @deprecated Use `.extend_i32_u()` instead. */ extend_u(...args) { BinaryenObj.printWarn("`.extend_u()` is deprecated; use `.extend_i32_u()` instead."); return this.extend_i32_u(...args); }, /** @deprecated */ trunc_s: { // @ts-expect-error - /** @deprecated Use `.trunc_f32_s()` instead. */ f32: (...args) => { consoleWarn("`.trunc_s.f32()` is deprecated; use `.trunc_f32_s()` instead."); return i64(mod).trunc_f32_s(...args); }, + /** @deprecated Use `.trunc_f32_s()` instead. */ f32: (...args) => { BinaryenObj.printWarn("`.trunc_s.f32()` is deprecated; use `.trunc_f32_s()` instead."); return i64(mod).trunc_f32_s(...args); }, // @ts-expect-error - /** @deprecated Use `.trunc_f64_s()` instead. */ f64: (...args) => { consoleWarn("`.trunc_s.f64()` is deprecated; use `.trunc_f64_s()` instead."); return i64(mod).trunc_f64_s(...args); }, + /** @deprecated Use `.trunc_f64_s()` instead. */ f64: (...args) => { BinaryenObj.printWarn("`.trunc_s.f64()` is deprecated; use `.trunc_f64_s()` instead."); return i64(mod).trunc_f64_s(...args); }, }, /** @deprecated */ trunc_u: { // @ts-expect-error - /** @deprecated Use `.trunc_f32_u()` instead. */ f32: (...args) => { consoleWarn("`.trunc_u.f32()` is deprecated; use `.trunc_f32_u()` instead."); return i64(mod).trunc_f32_u(...args); }, + /** @deprecated Use `.trunc_f32_u()` instead. */ f32: (...args) => { BinaryenObj.printWarn("`.trunc_u.f32()` is deprecated; use `.trunc_f32_u()` instead."); return i64(mod).trunc_f32_u(...args); }, // @ts-expect-error - /** @deprecated Use `.trunc_f64_u()` instead. */ f64: (...args) => { consoleWarn("`.trunc_u.f64()` is deprecated; use `.trunc_f64_u()` instead."); return i64(mod).trunc_f64_u(...args); }, + /** @deprecated Use `.trunc_f64_u()` instead. */ f64: (...args) => { BinaryenObj.printWarn("`.trunc_u.f64()` is deprecated; use `.trunc_f64_u()` instead."); return i64(mod).trunc_f64_u(...args); }, }, /** @deprecated */ trunc_s_sat: { // @ts-expect-error - /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: (...args) => { consoleWarn("`.trunc_s_sat.f32()` is deprecated; use `.trunc_sat_f32_s()` instead."); return i64(mod).trunc_sat_f32_s(...args); }, + /** @deprecated Use `.trunc_sat_f32_s()` instead. */ f32: (...args) => { BinaryenObj.printWarn("`.trunc_s_sat.f32()` is deprecated; use `.trunc_sat_f32_s()` instead."); return i64(mod).trunc_sat_f32_s(...args); }, // @ts-expect-error - /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: (...args) => { consoleWarn("`.trunc_s_sat.f64()` is deprecated; use `.trunc_sat_f64_s()` instead."); return i64(mod).trunc_sat_f64_s(...args); }, + /** @deprecated Use `.trunc_sat_f64_s()` instead. */ f64: (...args) => { BinaryenObj.printWarn("`.trunc_s_sat.f64()` is deprecated; use `.trunc_sat_f64_s()` instead."); return i64(mod).trunc_sat_f64_s(...args); }, }, /** @deprecated */ trunc_u_sat: { // @ts-expect-error - /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: (...args) => { consoleWarn("`.trunc_u_sat.f32()` is deprecated; use `.trunc_sat_f32_u()` instead."); return i64(mod).trunc_sat_f32_u(...args); }, + /** @deprecated Use `.trunc_sat_f32_u()` instead. */ f32: (...args) => { BinaryenObj.printWarn("`.trunc_u_sat.f32()` is deprecated; use `.trunc_sat_f32_u()` instead."); return i64(mod).trunc_sat_f32_u(...args); }, // @ts-expect-error - /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: (...args) => { consoleWarn("`.trunc_u_sat.f64()` is deprecated; use `.trunc_sat_f64_u()` instead."); return i64(mod).trunc_sat_f64_u(...args); }, + /** @deprecated Use `.trunc_sat_f64_u()` instead. */ f64: (...args) => { BinaryenObj.printWarn("`.trunc_u_sat.f64()` is deprecated; use `.trunc_sat_f64_u()` instead."); return i64(mod).trunc_sat_f64_u(...args); }, }, // @ts-expect-error - /** @deprecated Use `.reinterpret_f64()` instead. */ reinterpret(...args) { consoleWarn("`.reinterpret()` is deprecated; use `.reinterpret_f64()` instead."); return this.reinterpret_f64(...args); }, + /** @deprecated Use `.reinterpret_f64()` instead. */ reinterpret(...args) { BinaryenObj.printWarn("`.reinterpret()` is deprecated; use `.reinterpret_f64()` instead."); return this.reinterpret_f64(...args); }, } as const; } diff --git a/ts/src/services/expression-builder/i8x16.ts b/ts/src/services/expression-builder/i8x16.ts index 8377390e6f3..92499bad0f6 100644 --- a/ts/src/services/expression-builder/i8x16.ts +++ b/ts/src/services/expression-builder/i8x16.ts @@ -13,9 +13,6 @@ import { type ExpressionRef, Operation, } from "../../constants.ts"; -import { - consoleWarn, -} from "../../lib.ts"; import { binaryFn, simdExtractFn, @@ -82,12 +79,12 @@ export function i8x16(mod: Module) { replace_lane: simdReplaceFn(mod, Operation.ReplaceLaneVecI8x16), // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.add_sat_s} instead. */ add_saturate_s(...args) { consoleWarn("`.i8x16.add_saturate_s()` is deprecated; use `.i8x16.add_sat_s()` instead."); return this.add_sat_s(...args); }, + /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.add_sat_s} instead. */ add_saturate_s(...args) { BinaryenObj.printWarn("`.i8x16.add_saturate_s()` is deprecated; use `.i8x16.add_sat_s()` instead."); return this.add_sat_s(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.add_sat_u} instead. */ add_saturate_u(...args) { consoleWarn("`.i8x16.add_saturate_u()` is deprecated; use `.i8x16.add_sat_u()` instead."); return this.add_sat_u(...args); }, + /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.add_sat_u} instead. */ add_saturate_u(...args) { BinaryenObj.printWarn("`.i8x16.add_saturate_u()` is deprecated; use `.i8x16.add_sat_u()` instead."); return this.add_sat_u(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.sub_sat_s} instead. */ sub_saturate_s(...args) { consoleWarn("`.i8x16.sub_saturate_s()` is deprecated; use `.i8x16.sub_sat_s()` instead."); return this.sub_sat_s(...args); }, + /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.sub_sat_s} instead. */ sub_saturate_s(...args) { BinaryenObj.printWarn("`.i8x16.sub_saturate_s()` is deprecated; use `.i8x16.sub_sat_s()` instead."); return this.sub_sat_s(...args); }, // @ts-expect-error - /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.sub_sat_u} instead. */ sub_saturate_u(...args) { consoleWarn("`.i8x16.sub_saturate_u()` is deprecated; use `.i8x16.sub_sat_u()` instead."); return this.sub_sat_u(...args); }, + /** @deprecated Use {@link ExpressionBuilder#i8x16 | ExpressionBuilder#i8x16.sub_sat_u} instead. */ sub_saturate_u(...args) { BinaryenObj.printWarn("`.i8x16.sub_saturate_u()` is deprecated; use `.i8x16.sub_sat_u()` instead."); return this.sub_sat_u(...args); }, } as const; } From 246946d044e76f9e611253941065a3ec745bbe71 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 17:16:55 -0400 Subject: [PATCH 201/247] refactor: delete lib.ts --- ts/README.md | 2 +- ts/src/classes/module/Module.ts | 29 +++++++++++++++++++++++++--- ts/src/lib.ts | 34 --------------------------------- 3 files changed, 27 insertions(+), 38 deletions(-) delete mode 100644 ts/src/lib.ts diff --git a/ts/README.md b/ts/README.md index 75e16a2a06b..86bbf9890af 100644 --- a/ts/README.md +++ b/ts/README.md @@ -148,7 +148,7 @@ TODO: this section - `-pre.ts`: artifacts provided by Emscripten - - `{lib,utils}.ts`: internal tools + - `-utils.ts`: internal tools - `{constants,globals}.ts`: top-level exported globals diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 960fafa731e..e887f7d05a3 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -36,9 +36,6 @@ import { externref, stringref, } from "../../constants.ts"; -import { - replacedBy, -} from "../../lib.ts"; import { type ExpressionBuilder, expressionBuilder, @@ -115,6 +112,32 @@ export enum Feature { +/** + * Mark a method as deprecated by logging a warning in the console. + * @example + * class Module { + * \@replacedBy("`this.global.addExport`") + * addGlobalExport(...args) { + * return this.global.addExport(...args); + * } + * } + * + * @param replacement the name or signature of the new method replacing the deprecated one + * @returns a method decorator + */ +function replacedBy(replacement: string = ""): ( + method: (this: This, ...args: Params) => Return, + context: ClassMethodDecoratorContext, +) => (typeof method) | void { + return (method, context) => function (...args) { + const message = `WARNING: ${ context.static ? "Static" : "Instance" } method \`${ String(context.name) }\` is deprecated${ replacement && `; use ${ replacement } instead` }.`; + BinaryenObj.printWarn(message); + return method.call(this, ...args); + }; +} + + + /** * A WASM module. * diff --git a/ts/src/lib.ts b/ts/src/lib.ts deleted file mode 100644 index f99b2c6a1c8..00000000000 --- a/ts/src/lib.ts +++ /dev/null @@ -1,34 +0,0 @@ -// # Library # // -// Project-agnostic library artifacts for TypeScript development. - - - -import { - BinaryenObj, -} from "./-pre.ts"; - - - -/** - * Mark a method as deprecated by logging a warning in the console. - * @example - * class Module { - * \@replacedBy("`this.global.addExport`") - * addGlobalExport(...args) { - * return this.global.addExport(...args); - * } - * } - * - * @param replacement the name or signature of the new method replacing the deprecated one - * @returns a method decorator - */ -export function replacedBy(replacement: string = ""): ( - method: (this: This, ...args: Params) => Return, - context: ClassMethodDecoratorContext, -) => (typeof method) | void { - return (method, context) => function (...args) { - const message = `WARNING: ${ context.static ? "Static" : "Instance" } method \`${ String(context.name) }\` is deprecated${ replacement && `; use ${ replacement } instead` }.`; - BinaryenObj.printWarn(message); - return method.call(this, ...args); - }; -} From ea701c806d38eceaf9d5fc1aaf0896df0c7ae75f Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 18:41:19 -0400 Subject: [PATCH 202/247] docs: print warning for `ExpressionRunner.Flags` --- ts/src/classes/ExpressionRunner.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ts/src/classes/ExpressionRunner.ts b/ts/src/classes/ExpressionRunner.ts index f743285b5c4..764d935fe87 100644 --- a/ts/src/classes/ExpressionRunner.ts +++ b/ts/src/classes/ExpressionRunner.ts @@ -24,7 +24,10 @@ export enum ExpressionRunnerFlag { export class ExpressionRunner { /** @deprecated Static field `ExpressionRunner.Flags` is now a standalone enum {@link ExpressionRunnerFlag}. */ - static Flags = ExpressionRunnerFlag; + static get Flags() { + BinaryenObj.printWarn("The enum `ExpressionRunner.Flags` has been renamed to `ExpressionRunnerFlag`."); + return ExpressionRunnerFlag; + } readonly #ptr: number; From 3a9c4ce8e329802361aefdd660f698b5d14d417b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 18:48:31 -0400 Subject: [PATCH 203/247] modified: docs/API-Overview.md --- ts/docs/API-Overview.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 569a2b84fe2..861206c2cf1 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -38,7 +38,7 @@ import {type Type, type ExpressionRef, i32} from "binaryen.ts"; - module component ref types: - `TagRef` - `GlobalRef` - - ~~`MemoryRef`~~ ⛔️ + - `MemoryRef` - `TableRef` - `FunctionRef` - `DataSegmentRef` @@ -82,10 +82,19 @@ import {type Type, type ExpressionRef, i32} from "binaryen.ts"; - a slight misnomer, as these are not unique IDs per expression, but different IDs for the “kinds” of expression - `SideEffect`: an enumeration of values returend by `getSideEffects()` - `ExternalKind`: an enumeration of kinds of exports; serves as type of the `Module.Export#kind` field +- `Operation`: used in [manipulating expressions](#expression-manipulation) - `MemoryOrder`: an enumeration of values used in atomic expression methods +- `Feature`: WASM Module features +- `ExpressionRunnerFlag`: flags for the `ExpressionRunner` class ### Global Bindings +Classes (see generated docs for descriptions): +- `Module` +- `TypeBuilder` +- `ExpressionRunner` +- `Relooper` + Functions (see generated docs for descriptions): - `emitText(expr: ExpressionRef): string` - `readBinary(data: Uint8Array): Module` @@ -99,8 +108,6 @@ Functions (see generated docs for descriptions): - `getExpressionId(expr: ExpressionRef): ExpressionId` - `getExpressionType(expr: ExpressionRef): Type` - `getExpressionInfo(expr: ExpressionRef): Expression` -- `getSideEffects(expr: ExpressionRef, mod: Module): SideEffect` -- `copyExpression(expr: ExpressionRef, mod: Module): ExpressionRef` Objects: - `settings`: global settings manager; see `SettingsService` docs @@ -120,7 +127,10 @@ Properties of `Module` as a namespace: - `new Module.Export(ref: ExportRef)`: an object containing information about an **Export** Properties of `Module` instances (see full list of methods in generated docs): -- `Module#wasm`: [build WASM expressions](#expression-building) +- `Module#wasm`: [build WASM expressions](#expression-building) +- `Module#start`: get/set the start function +- `Module#features`: get/set WASM features (a bitmask) +> - `Module#tags`: **Tag** manipulation - `Module#globals`: **Global** manipulation - `Module#memories`: **Memory** manipulation @@ -132,6 +142,10 @@ Properties of `Module` instances (see full list of methods in generated docs): - `Module#exports`: **Export** manipulation Module methods (see signatures and descriptions in generated docs): +- Expression Manipulation + - `.pop()` + - `.getSideEffects()` + - `.copyExpression()` - Emission & Execution - `.emitText()` - `.emitStackIR()` From 6457bc608da0775645cbebfe8d8667f469c0ee7d Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 19:36:57 -0400 Subject: [PATCH 204/247] feat: add BinaryenExpressionAllocateAndWriteText --- src/binaryen-c.cpp | 14 ++++++++++++++ src/binaryen-c.h | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 0f8cb4805f9..592d426b1c6 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -2077,6 +2077,20 @@ BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr, BinaryenModuleRef module) { return ExpressionManipulator::copy(expr, *(Module*)module); } +char* BinaryenExpressionAllocateAndWriteText(BinaryenExpressionRef expr) { + std::ostringstream os; + bool colors = Colors::isEnabled(); + + Colors::setEnabled(false); // do not use colors for writing + os << *(Expression*)expr; + Colors::setEnabled(colors); // restore colors state + + auto str = os.str(); + const size_t len = str.length() + 1; + char* output = (char*)malloc(len); + std::copy_n(str.c_str(), len, output); + return output; +} // Specific expression utility diff --git a/src/binaryen-c.h b/src/binaryen-c.h index fbde9d2a08d..dfafbc6efa4 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -1218,6 +1218,10 @@ BINARYEN_API void BinaryenExpressionFinalize(BinaryenExpressionRef expr); // Makes a deep copy of the given expression. BINARYEN_API BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr, BinaryenModuleRef module); +// Serialize an expression in s-expression form. Implicitly allocates the returned +// char* with malloc(), and expects the user to free() them manually +// once not needed anymore. +BINARYEN_API char* BinaryenExpressionAllocateAndWriteText(BinaryenExpressionRef expr); // Block From c8480841763431088615194e1900a60b473d1d29 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 16 May 2026 19:48:15 -0400 Subject: [PATCH 205/247] feat: update `emitText` depends on #8717 --- ts/src/classes/module/Module.ts | 11 ++++++++++- ts/src/globals.ts | 25 +++++++------------------ 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index e887f7d05a3..11904029b8e 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -377,7 +377,16 @@ export class Module { * @category Emission & Execution */ emitAsmjs(): string { - /* See comment in the `emitText()` global function (`../../globals.ts`) for what’s going on here. */ + /* + * `out` is Emscripten's `stdout` function (an alias of `console.log`), + * called internally by `BinaryenModulePrintAsmjs()` to print its output. + * We have to temporarily swap out the function itself + * so that when `BinaryenModulePrintAsmjs()` calls it, + * it calls our capturing function instead. + * + * We can’t use `import {out} from "../../-pre.ts";` because ES Module imports can’t be reassigned. + * Instead, we reassign directly on `BinaryenObj`. + */ let returned = ""; const temp_out = BinaryenObj.out; BinaryenObj.out = (x: string): void => { diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 57791e87195..f0e66f29d22 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -9,6 +9,7 @@ import { HEAP8, HEAPU32, BinaryenObj, + UTF8ToString, getExceptionMessage, stackAlloc, stringToAscii, @@ -187,24 +188,12 @@ function handleFatalError(func: () => T): T { // ## General Binaryen Functions ## // /** Emits the expression in Binaryen’s s-expression text format (not official stack-style text format). */ export function emitText(expr: ExpressionRef): string { - /* - * `out` is Emscripten's `stdout` function (an alias of `console.log`), - * called internally by `BinaryenExpressionPrint()` to print its output. - * We have to temporarily swap out the function itself - * so that when `BinaryenExpressionPrint()` calls it, - * it calls our capturing function instead. - * - * We can’t use `import {out} from "./-pre.ts";` because ES Module imports can’t be reassigned. - * Instead, we reassign directly on `BinaryenObj`. - */ - let returned = ""; - const temp_out = BinaryenObj.out; - BinaryenObj.out = (x: string): void => { - returned += `${ x }\n`; - }; - BinaryenObj["_BinaryenExpressionPrint"](expr); - BinaryenObj.out = temp_out; - return returned; + const textPtr = BinaryenObj["_BinaryenExpressionAllocateAndWriteText"](expr); + const text = UTF8ToString(textPtr); + if (textPtr) { + _free(textPtr); + } + return text; } /** Creates a module from binary data. */ From b1d5981450aa3b608dcb6c144a50c2f7f79c56d5 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 17 May 2026 02:27:06 -0400 Subject: [PATCH 206/247] docs: add expr classes to API Overview --- ts/docs/API-Overview.md | 87 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 861206c2cf1..571aa888c5a 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -176,7 +176,7 @@ See the generated **ExpressionBuilder** docs for all available functions and det Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`”. -- Parametric Instructions +- parametrics - `.nop()` - `.unreachable()` - `.drop()` @@ -318,20 +318,97 @@ They can be used to inspect and manipulate expressions. See generated docs for fields, methods, and descriptions of each. - `expressions.Expression` (root class) -- parametric instructions +- Parametric Expressions - `expressions.Drop` - `expressions.Select` -- control instructions +- Control Expressions - `expressions.Block` - `expressions.Loop` + - `expressions.If` - `expressions.Break` -- variable instructions + - `expressions.Switch` + - `expressions.BrOn` + - `expressions.Call` + - `expressions.CallRef` + - `expressions.CallIndirect` + - `expressions.Return` + - `expressions.Throw` + - `expressions.Rethrow` + - `expressions.Try` +- Variable Expressions - `expressions.LocalGet` - `expressions.LocalSet` - `expressions.GlobalGet` - `expressions.GlobalSet` -- numeric instructions +- Table Expressions + - `expressions.TableGet` + - `expressions.TableSet` + - `expressions.TableSize` + - `expressions.TableGrow` +- Memory Expressions + - `expressions.Load` + - `expressions.Store` + - `expressions.SIMDLoad` + - `expressions.SIMDLoadStoreLane` + - `expressions.MemorySize` + - `expressions.MemoryGrow` + - `expressions.MemoryFill` + - `expressions.MemoryCopy` + - `expressions.MemoryInit` + - `expressions.DataDrop` +- Reference Expressions + - `expressions.RefFunc` + - `expressions.RefIsNull` + - `expressions.RefAs` + - `expressions.RefEq` + - `expressions.RefTest` + - `expressions.RefCast` + - `expressions.RefI31` + - `expressions.I31Get` +- Aggregate Expressions + - `expressions.TupleMake` + - `expressions.TupleExtract` + - `expressions.StructNew` + - `expressions.StructGet` + - `expressions.StructSet` + - `expressions.ArrayNew` + - `expressions.ArrayNewFixed` + - `expressions.ArrayNewData` + - `expressions.ArrayNewElem` + - `expressions.ArrayGet` + - `expressions.ArraySet` + - `expressions.ArrayLen` + - `expressions.ArrayFill` + - `expressions.ArrayCopy` + - `expressions.ArrayInitData` + - `expressions.ArrayInitElem` +- Numeric Expressions - `expressions.Const` + - `expressions.Unary` + - `expressions.Binary` + - `expressions.WideIntAddSub` + - `expressions.WideIntMul` +- Vector Expressions + - `expressions.SIMDTernary` + - `expressions.SIMDShift` + - `expressions.SIMDShuffle` + - `expressions.SIMDExtract` + - `expressions.SIMDReplace` +- Atomic Expressions + - `expressions.AtomicRMW` + - `expressions.AtomicCmpxchg` + - `expressions.AtomicWait` + - `expressions.AtomicNotify` + - `expressions.AtomicFence` +- String Expressions + - `expressions.StringNew` + - `expressions.StringConst` + - `expressions.StringMeasure` + - `expressions.StringEncode` + - `expressions.StringConcat` + - `expressions.StringEq` + - `expressions.StringWTF16Get` + - `expressions.StringSliceWTF` From 6e920939cb02b82be76450d6ce830352e5ee885b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 17 May 2026 11:17:27 -0400 Subject: [PATCH 207/247] docs: add Deprecation Roadmap --- ts/docs/API-Overview.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 571aa888c5a..548a3e50d10 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -413,6 +413,23 @@ See generated docs for fields, methods, and descriptions of each. ## ⚠️ Deprecations, Renames, and Moves +### Deprecation Roadmap +This section lists all bindings that have been deprecated in favor of another binding name or its relocation. +These deprecations are marked with `/** @deprecated */` doc-comments so they can be picked up by intellisense and linting tools. + +Additionally, most of these bindings log a warning to the console notifying their deprecation and what they should be replaced with. +E.g., when running the code, you’ll see the following in standard output: +> "`.returnCall()` is deprecated; use `.return_call()` instead." + +1. For the time being, we’ll leave these deprecations in place with their runtime warnings. +2. In a future major version of Binaryen.TS, we’ll convert from logging strings to logging actual `Error` objects (with stacks), +which are more verbose and should be more attention-grabbing. +These messages will be sent to the ‘error’ output instead of ‘standard’. +3. Then in another release we’ll resort to *throwing* the error instead of just logging it. +This will be a breaking change; at this stage the deprecations should be considered **obsolete** +and this serves as a final warning that they will be removed soon. +4. Then in yet another release we’ll remove all deprecations. + ### Enums and Types Enum names have been singularized. - `ExpressionIds` → `ExpressionId` From 9a128ab6a91b43425049729c233df6d8b3e4b5b0 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 17 May 2026 11:21:01 -0400 Subject: [PATCH 208/247] build: loosen devEngine version --- ts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/package.json b/ts/package.json index 0878d06c6f9..92ef84928ed 100644 --- a/ts/package.json +++ b/ts/package.json @@ -53,7 +53,7 @@ "devEngines": { "runtime": { "name": "node", - "version": "^26.1.0" + "version": "^22 || ^24 || ^26" }, "packageManager": { "name": "npm" From 76b088573a3b0b497080971e29f59b90eda6c9b1 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 17 May 2026 16:30:23 -0400 Subject: [PATCH 209/247] lint: add block-spacing rule --- ts/eslint.config.js | 1 + ts/src/classes/expression/breaks.ts | 2 +- ts/src/classes/expression/calls.ts | 2 +- ts/src/classes/expression/memories.ts | 4 ++-- ts/src/classes/expression/references.ts | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ts/eslint.config.js b/ts/eslint.config.js index f788cead9a5..e05beaaad1d 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -25,6 +25,7 @@ export default [ /* # Layout & Formatting */ /* ## Indentation, Spacing, and Alignment */ "@stylistic/arrow-spacing": "error", + "@stylistic/block-spacing": "error", "@stylistic/comma-spacing": "error", "@stylistic/dot-location": ["error", "property"], "@stylistic/function-call-spacing": "error", diff --git a/ts/src/classes/expression/breaks.ts b/ts/src/classes/expression/breaks.ts index 0a8543af8b5..740888e5bb0 100644 --- a/ts/src/classes/expression/breaks.ts +++ b/ts/src/classes/expression/breaks.ts @@ -34,7 +34,7 @@ export class Break extends Expression { } get condition(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetCondition"](this._ptr); } - set condition(condExpr: ExpressionRef) {BinaryenObj["_BinaryenBreakSetCondition"](this._ptr, condExpr);} + set condition(condExpr: ExpressionRef) { BinaryenObj["_BinaryenBreakSetCondition"](this._ptr, condExpr); } get value(): ExpressionRef { return BinaryenObj["_BinaryenBreakGetValue"](this._ptr); } set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenBreakSetValue"](this._ptr, valueExpr); } diff --git a/ts/src/classes/expression/calls.ts b/ts/src/classes/expression/calls.ts index 2ec651b7034..70fe04867f3 100644 --- a/ts/src/classes/expression/calls.ts +++ b/ts/src/classes/expression/calls.ts @@ -120,7 +120,7 @@ export class CallIndirect extends Expression { get table(): string { return UTF8ToString(BinaryenObj["_BinaryenCallIndirectGetTable"](this._ptr)); } set table(table: string) { preserveStack(() => BinaryenObj["_BinaryenCallIndirectSetTable"](this._ptr, strToStack(table))); } - get params(): Type {return BinaryenObj["_BinaryenCallIndirectGetParams"](this._ptr);} + get params(): Type { return BinaryenObj["_BinaryenCallIndirectGetParams"](this._ptr); } set params(params: Type) { BinaryenObj["_BinaryenCallIndirectSetParams"](this._ptr, params); } get results(): Type { return BinaryenObj["_BinaryenCallIndirectGetResults"](this._ptr); } diff --git a/ts/src/classes/expression/memories.ts b/ts/src/classes/expression/memories.ts index 5c9726b7a7c..77495dc9789 100644 --- a/ts/src/classes/expression/memories.ts +++ b/ts/src/classes/expression/memories.ts @@ -71,7 +71,7 @@ export class Store extends Expression { get valueType(): Type { return BinaryenObj["_BinaryenStoreGetValueType"](this._ptr); } set valueType(valueType: Type) { BinaryenObj["_BinaryenStoreSetValueType"](this._ptr, valueType); } - get atomic(): boolean {return Boolean(BinaryenObj["_BinaryenStoreIsAtomic"](this._ptr));} + get atomic(): boolean { return Boolean(BinaryenObj["_BinaryenStoreIsAtomic"](this._ptr)); } // TODO: set atomic get memoryOrder(): MemoryOrder { return BinaryenObj["_BinaryenStoreGetMemoryOrder"](this._ptr); } @@ -123,7 +123,7 @@ export class SIMDLoadStoreLane extends Expression { get vec(): ExpressionRef { return BinaryenObj["_BinaryenSIMDLoadStoreLaneGetVec"](this._ptr); } set vec(vecExpr: ExpressionRef) { BinaryenObj["_BinaryenSIMDLoadStoreLaneSetVec"](this._ptr, vecExpr); } - get store(): boolean {return Boolean(BinaryenObj["_BinaryenSIMDLoadStoreLaneIsStore"](this._ptr));} + get store(): boolean { return Boolean(BinaryenObj["_BinaryenSIMDLoadStoreLaneIsStore"](this._ptr)); } } diff --git a/ts/src/classes/expression/references.ts b/ts/src/classes/expression/references.ts index d0e3a42d60f..caf1b296970 100644 --- a/ts/src/classes/expression/references.ts +++ b/ts/src/classes/expression/references.ts @@ -52,7 +52,7 @@ export class RefAs extends Expression { get op(): Operation { return BinaryenObj["_BinaryenRefAsGetOp"](this._ptr); } set op(op: Operation) { BinaryenObj["_BinaryenRefAsSetOp"](this._ptr, op); } - get value(): ExpressionRef {return BinaryenObj["_BinaryenRefAsGetValue"](this._ptr);} + get value(): ExpressionRef { return BinaryenObj["_BinaryenRefAsGetValue"](this._ptr); } set value(valueExpr: ExpressionRef) { BinaryenObj["_BinaryenRefAsSetValue"](this._ptr, valueExpr); } } From 35c31b197671751e0bb98b7147d733e0cecc3f7b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 18 May 2026 02:23:33 -0400 Subject: [PATCH 210/247] docs: fix f32 --- ts/src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/src/constants.ts b/ts/src/constants.ts index aed156357b2..157d1c4de34 100644 --- a/ts/src/constants.ts +++ b/ts/src/constants.ts @@ -55,7 +55,7 @@ export const auto: Type = BinaryenObj["_BinaryenTypeAuto"](); export const i32: Type = BinaryenObj["_BinaryenTypeInt32"](); /** 64-bit integer. */ export const i64: Type = BinaryenObj["_BinaryenTypeInt64"](); -/** 64-bit float. */ +/** 32-bit float. */ export const f32: Type = BinaryenObj["_BinaryenTypeFloat32"](); /** 64-bit float. */ export const f64: Type = BinaryenObj["_BinaryenTypeFloat64"](); From d10cf2a3edfb5d6f34410cdd650ddc8ee1a0d887 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 18 May 2026 23:26:41 -0400 Subject: [PATCH 211/247] fix: keep heaps attached to BinaryenObj --- ts/src/-pre.ts | 4 ---- ts/src/-utils.ts | 7 +++---- ts/src/classes/TypeBuilder.ts | 3 +-- ts/src/classes/expression/numerics.ts | 5 ++--- ts/src/classes/expression/vectors.ts | 5 ++--- ts/src/classes/module/DataSegment.ts | 3 +-- ts/src/classes/module/Memory.ts | 3 +-- ts/src/classes/module/Module.ts | 10 ++++------ ts/src/globals.ts | 8 +++----- ts/src/types/binaryen_js.d.ts | 8 ++++---- ts/test/binaryen.test.ts | 4 ---- 11 files changed, 21 insertions(+), 39 deletions(-) diff --git a/ts/src/-pre.ts b/ts/src/-pre.ts index a9598211659..551250ab9ce 100644 --- a/ts/src/-pre.ts +++ b/ts/src/-pre.ts @@ -20,10 +20,6 @@ export const { _free, out, err, - HEAP8, - HEAPU8, - HEAP32, - HEAPU32, stackSave, stackRestore, stackAlloc, diff --git a/ts/src/-utils.ts b/ts/src/-utils.ts index 7114fd8b0dc..3fb51478a12 100644 --- a/ts/src/-utils.ts +++ b/ts/src/-utils.ts @@ -4,8 +4,7 @@ import { - HEAP8, - HEAP32, + BinaryenObj, stackAlloc, stackRestore, stackSave, @@ -57,7 +56,7 @@ export function strToStack(str?: string): number { */ export function i32sToStack(i32s: readonly number[]): number { const ret = stackAlloc(i32s.length << 2); - HEAP32.set(i32s, ret >>> 2); + BinaryenObj.HEAP32.set(i32s, ret >>> 2); return ret; } @@ -68,7 +67,7 @@ export function i32sToStack(i32s: readonly number[]): number { */ export function i8sToStack(i8s: readonly number[]): number { const ret = stackAlloc(i8s.length); - HEAP8.set(i8s, ret); + BinaryenObj.HEAP8.set(i8s, ret); return ret; } diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index 54a90289374..bf922cc1759 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -1,6 +1,5 @@ import { BinaryenObj, - HEAPU32, stackAlloc, } from "../-pre.ts"; import { @@ -168,7 +167,7 @@ export class TypeBuilder { } const types = new Array(numTypes); for (let i = 0; i < numTypes; i++) { - types[i] = HEAPU32[(array >>> 2) + i]; + types[i] = BinaryenObj.HEAPU32[(array >>> 2) + i]; } return types; }); diff --git a/ts/src/classes/expression/numerics.ts b/ts/src/classes/expression/numerics.ts index d8f8dbb5f12..3581cfe1c99 100644 --- a/ts/src/classes/expression/numerics.ts +++ b/ts/src/classes/expression/numerics.ts @@ -1,6 +1,5 @@ import { BinaryenObj, - HEAPU8, stackAlloc, } from "../../-pre.ts"; import { @@ -57,7 +56,7 @@ export class Const extends Expression { const tempBuffer = stackAlloc(16); BinaryenObj["_BinaryenConstGetValueV128"](this._ptr, tempBuffer); for (let i = 0; i < 16; ++i) { - value[i] = HEAPU8[tempBuffer + i]; + value[i] = BinaryenObj.HEAPU8[tempBuffer + i]; } }); return value; @@ -67,7 +66,7 @@ export class Const extends Expression { preserveStack(() => { const tempBuffer = stackAlloc(16); for (let i = 0; i < 16; ++i) { - HEAPU8[tempBuffer + i] = value[i]; + BinaryenObj.HEAPU8[tempBuffer + i] = value[i]; } BinaryenObj["_BinaryenConstSetValueV128"](this._ptr, tempBuffer); }); diff --git a/ts/src/classes/expression/vectors.ts b/ts/src/classes/expression/vectors.ts index 27dfd1c6c29..e0358191af2 100644 --- a/ts/src/classes/expression/vectors.ts +++ b/ts/src/classes/expression/vectors.ts @@ -1,6 +1,5 @@ import { BinaryenObj, - HEAPU8, stackAlloc, } from "../../-pre.ts"; import { @@ -71,7 +70,7 @@ export class SIMDShuffle extends Expression { const tempBuffer = stackAlloc(16); BinaryenObj["_BinaryenSIMDShuffleGetMask"](this._ptr, tempBuffer); for (let i = 0; i < 16; ++i) { - mask[i] = HEAPU8[tempBuffer + i]; + mask[i] = BinaryenObj.HEAPU8[tempBuffer + i]; } }); return mask; @@ -81,7 +80,7 @@ export class SIMDShuffle extends Expression { preserveStack(() => { const tempBuffer = stackAlloc(16); for (let i = 0; i < 16; ++i) { - HEAPU8[tempBuffer + i] = mask[i]; + BinaryenObj.HEAPU8[tempBuffer + i] = mask[i]; } BinaryenObj["_BinaryenSIMDShuffleSetMask"](this._ptr, tempBuffer); }); diff --git a/ts/src/classes/module/DataSegment.ts b/ts/src/classes/module/DataSegment.ts index b4eac1002ee..b9870ea3ccc 100644 --- a/ts/src/classes/module/DataSegment.ts +++ b/ts/src/classes/module/DataSegment.ts @@ -2,7 +2,6 @@ import { _free, _malloc, BinaryenObj, - HEAP8, UTF8ToString, } from "../../-pre.ts"; import { @@ -40,7 +39,7 @@ export class DataSegment { const ptr = _malloc(size); BinaryenObj["_BinaryenCopyDataSegmentData"](segment, ptr); const res = new Uint8Array(size); - res.set(HEAP8.subarray(ptr, ptr + size)); + res.set(BinaryenObj.HEAP8.subarray(ptr, ptr + size)); _free(ptr); this.data = res.buffer; diff --git a/ts/src/classes/module/Memory.ts b/ts/src/classes/module/Memory.ts index a0296d7a6a1..acfaf1bc088 100644 --- a/ts/src/classes/module/Memory.ts +++ b/ts/src/classes/module/Memory.ts @@ -2,7 +2,6 @@ import { _free, _malloc, BinaryenObj, - HEAP8, UTF8ToString, } from "../../-pre.ts"; import { @@ -88,7 +87,7 @@ export class ModuleMemories { datas[i] = _malloc(data.length); passives[i] = Number(passive); offsets[i] = offset; - HEAP8.set(data, datas[i]); + BinaryenObj.HEAP8.set(data, datas[i]); lengths[i] = data.length; } BinaryenObj["_BinaryenSetMemory"]( diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 11904029b8e..63f6bca280b 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -1,8 +1,6 @@ import { _free, BinaryenObj, - HEAPU8, - HEAPU32, UTF8ToString, stackAlloc, } from "../../-pre.ts"; @@ -411,12 +409,12 @@ export class Module { return preserveStack(() => { const tempBuffer = stackAlloc(BinaryenObj["_BinaryenSizeofAllocateAndWriteResult"]()); BinaryenObj["_BinaryenModuleAllocateAndWrite"](tempBuffer, this[PTR], strToStack(sourceMapUrl)); - const binaryPtr = HEAPU32[tempBuffer >>> 2]; - const binaryBytes = HEAPU32[(tempBuffer >>> 2) + 1]; - const sourceMapPtr = HEAPU32[(tempBuffer >>> 2) + 2]; + const binaryPtr = BinaryenObj.HEAPU32[tempBuffer >>> 2]; + const binaryBytes = BinaryenObj.HEAPU32[(tempBuffer >>> 2) + 1]; + const sourceMapPtr = BinaryenObj.HEAPU32[(tempBuffer >>> 2) + 2]; try { const buffer = new Uint8Array(binaryBytes); - buffer.set(HEAPU8.subarray(binaryPtr, binaryPtr + binaryBytes)); + buffer.set(BinaryenObj.HEAPU8.subarray(binaryPtr, binaryPtr + binaryBytes)); return typeof sourceMapUrl === "undefined" ? buffer : {binary: buffer, sourceMap: UTF8ToString(sourceMapPtr)}; diff --git a/ts/src/globals.ts b/ts/src/globals.ts index f0e66f29d22..8a77132784f 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -6,8 +6,6 @@ import { _free, _malloc, - HEAP8, - HEAPU32, BinaryenObj, UTF8ToString, getExceptionMessage, @@ -199,7 +197,7 @@ export function emitText(expr: ExpressionRef): string { /** Creates a module from binary data. */ export function readBinary(data: Uint8Array): Module { const buffer = _malloc(data.length); - HEAP8.set(data, buffer); + BinaryenObj.HEAP8.set(data, buffer); const ptr = handleFatalError(() => BinaryenObj["_BinaryenModuleRead"](buffer, data.length)); _free(buffer); return wrapModule(ptr); @@ -207,7 +205,7 @@ export function readBinary(data: Uint8Array): Module { export function readBinaryWithFeatures(data: Uint8Array, features: Feature): Module { const buffer = _malloc(data.length); - HEAP8.set(data, buffer); + BinaryenObj.HEAP8.set(data, buffer); const ptr = handleFatalError(() => BinaryenObj["_BinaryenModuleReadWithFeatures"](buffer, data.length, features)); _free(buffer); return wrapModule(ptr); @@ -253,7 +251,7 @@ export function expandType(typ: Type): Type[] { BinaryenObj["_BinaryenTypeExpand"](typ, array); const types = new Array(numTypes); for (let i = 0; i < numTypes; i++) { - types[i] = HEAPU32[(array >>> 2) + i]; + types[i] = BinaryenObj.HEAPU32[(array >>> 2) + i]; } return types; }); diff --git a/ts/src/types/binaryen_js.d.ts b/ts/src/types/binaryen_js.d.ts index 930e96fecf1..84d939482d1 100644 --- a/ts/src/types/binaryen_js.d.ts +++ b/ts/src/types/binaryen_js.d.ts @@ -16,10 +16,10 @@ declare module "#binaryen-raw" { err(x: unknown): void; // alias of `console.error` // https://github.com/emscripten-core/emscripten/blob/main/src/lib/libcore.js - HEAP8: Int8Array; - HEAPU8: Uint8Array; - HEAP32: Int32Array; - HEAPU32: Uint32Array; + readonly HEAP8: Int8Array; + readonly HEAPU8: Uint8Array; + readonly HEAP32: Int32Array; + readonly HEAPU32: Uint32Array; stackSave(): number; stackRestore(stack: number): number; stackAlloc(length: number): number; diff --git a/ts/test/binaryen.test.ts b/ts/test/binaryen.test.ts index c084f916345..fa910cedfc4 100644 --- a/ts/test/binaryen.test.ts +++ b/ts/test/binaryen.test.ts @@ -15,10 +15,6 @@ suite("binaryen", () => { assert.ok(__pre._free); assert.ok(__pre.out); assert.ok(__pre.err); - assert.ok(__pre.HEAP8); - assert.ok(__pre.HEAPU8); - assert.ok(__pre.HEAP32); - assert.ok(__pre.HEAPU32); assert.ok(__pre.stackSave); assert.ok(__pre.stackRestore); assert.ok(__pre.stackAlloc); From b3f7afbb72117702758d587ec03801cbc04e523a Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 19 May 2026 19:29:44 -0400 Subject: [PATCH 212/247] fix: lint --- src/binaryen-c.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/binaryen-c.h b/src/binaryen-c.h index dfafbc6efa4..c6f0ce1d6e9 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -1218,10 +1218,11 @@ BINARYEN_API void BinaryenExpressionFinalize(BinaryenExpressionRef expr); // Makes a deep copy of the given expression. BINARYEN_API BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr, BinaryenModuleRef module); -// Serialize an expression in s-expression form. Implicitly allocates the returned -// char* with malloc(), and expects the user to free() them manually +// Serialize an expression in s-expression form. Implicitly allocates the +// returned char* with malloc(), and expects the user to free() them manually // once not needed anymore. -BINARYEN_API char* BinaryenExpressionAllocateAndWriteText(BinaryenExpressionRef expr); +BINARYEN_API char* +BinaryenExpressionAllocateAndWriteText(BinaryenExpressionRef expr); // Block From fdbba7fdc285f98409c973f7dbced503dd24b572 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 19 May 2026 19:41:48 -0400 Subject: [PATCH 213/247] feat: update `Module['emitText']` to use new C api --- src/js/binaryen.js-post.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index a3494d31ca4..f9d78a4a1e9 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -3308,12 +3308,10 @@ Module['emitText'] = function(expr) { if (typeof expr === 'object') { return expr.emitText(); } - const old = out; - let ret = ''; - out = x => { ret += x + '\n' }; - Module['_BinaryenExpressionPrint'](expr); - out = old; - return ret; + const textPtr = BinaryenObj["_BinaryenExpressionAllocateAndWriteText"](expr); + const text = UTF8ToString(textPtr); + if (textPtr) _free(textPtr); + return text; }; // Calls a function, wrapping it in error handling code so that if it hits a From 8f69c851c1c428255b5d2dbeb2de667df4f25725 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 19 May 2026 20:14:34 -0400 Subject: [PATCH 214/247] =?UTF-8?q?fix:=20wrap=20UTF8ToString=20in=20try?= =?UTF-8?q?=E2=80=93finally?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/js/binaryen.js-post.js | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index f9d78a4a1e9..742bd60cab7 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -2905,16 +2905,24 @@ function wrapModule(module, self = {}) { return Module['_BinaryenGetElementSegmentByIndex'](module, index); }; self['emitText'] = function() { - let textPtr = Module['_BinaryenModuleAllocateAndWriteText'](module); - let text = UTF8ToString(textPtr); - if (textPtr) _free(textPtr); - return text; + const textPtr = Module['_BinaryenModuleAllocateAndWriteText'](module); + try { + return UTF8ToString(textPtr); + } finally { + if (textPtr) { + _free(textPtr); + } + } }; self['emitStackIR'] = function() { - let textPtr = Module['_BinaryenModuleAllocateAndWriteStackIR'](module); - let text = UTF8ToString(textPtr); - if (textPtr) _free(textPtr); - return text; + const textPtr = Module['_BinaryenModuleAllocateAndWriteStackIR'](module); + try { + return UTF8ToString(textPtr); + } finally { + if (textPtr) { + _free(textPtr); + } + } }; self['emitAsmjs'] = function() { const old = out; @@ -3309,9 +3317,13 @@ Module['emitText'] = function(expr) { return expr.emitText(); } const textPtr = BinaryenObj["_BinaryenExpressionAllocateAndWriteText"](expr); - const text = UTF8ToString(textPtr); - if (textPtr) _free(textPtr); - return text; + try { + return UTF8ToString(textPtr); + } finally { + if (textPtr) { + _free(textPtr); + } + } }; // Calls a function, wrapping it in error handling code so that if it hits a From 0843a21fd6d5aba6ffbb1539b923baaef13ee4a5 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Tue, 19 May 2026 21:41:23 -0400 Subject: [PATCH 215/247] fixup! fdbba7fdc --- src/js/binaryen.js-post.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 742bd60cab7..1d7f88122bf 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -3316,7 +3316,7 @@ Module['emitText'] = function(expr) { if (typeof expr === 'object') { return expr.emitText(); } - const textPtr = BinaryenObj["_BinaryenExpressionAllocateAndWriteText"](expr); + const textPtr = Module['_BinaryenExpressionAllocateAndWriteText'](expr); try { return UTF8ToString(textPtr); } finally { From 4c2ce2341ce610ebefe8a997c3449dc29f057c37 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 20 May 2026 01:33:16 -0400 Subject: [PATCH 216/247] fix: `wasm.select` missing param --- ts/src/services/expression-builder/generic.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ts/src/services/expression-builder/generic.ts b/ts/src/services/expression-builder/generic.ts index 1c32a59c141..b84d6a7d0ff 100644 --- a/ts/src/services/expression-builder/generic.ts +++ b/ts/src/services/expression-builder/generic.ts @@ -42,8 +42,8 @@ export function parametrics(mod: Module) { ), /** Creates a `(select)` of one of two values. */ - select: (ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef => ( - BinaryenObj["_BinaryenSelect"](mod[PTR], ifTrue, ifFalse) + select: (condition: ExpressionRef, ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef => ( + BinaryenObj["_BinaryenSelect"](mod[PTR], condition, ifTrue, ifFalse) ), } as const; } From 85decfadc34e90af9dbcdd12c2cd7a05c2e22160 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 20 May 2026 02:08:43 -0400 Subject: [PATCH 217/247] fix: postmake script syntax --- ts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/package.json b/ts/package.json index 92ef84928ed..fd2b2e6da3c 100644 --- a/ts/package.json +++ b/ts/package.json @@ -17,7 +17,7 @@ "main": "./dist/binaryen.js", "scripts": { "make": "mkdir -p ../build/ && (cd ../build/ && emcmake cmake ../ && emmake make binaryen_js)", - "postmake": "rm -rf ./build/ && mkdir -p ./build/ && cp -R ../build/bin/* ./build/", + "postmake": "rm -rf ./build/ && mkdir -p ./build/ && cp -R ../build/bin/ ./build/", "compile": "rm -rf ./dist/ && tsc && tsc --project ./test/tsconfig.json", "lint": "eslint ./", "docs": "rm -rf ../docs/binaryen.ts/ && typedoc", From 2e0dea3759e09053455f824482a2f0c9261100d4 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 20 May 2026 04:43:20 -0400 Subject: [PATCH 218/247] new file: PROGRESS.md --- ts/PROGRESS.md | 343 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 ts/PROGRESS.md diff --git a/ts/PROGRESS.md b/ts/PROGRESS.md new file mode 100644 index 00000000000..f9114bba75a --- /dev/null +++ b/ts/PROGRESS.md @@ -0,0 +1,343 @@ +# Coverage Progress + +Tracks the migration of JavaScript development to TypeScript. +This document is temporary and will be removed once the migration is complete. + +Add to this checklist as the JS is updated; check when migrated to TS. + +**Status key:** +- `[ ]` — not started +- `[~]` — in progress (`@contributor`) +- `[x]` — done + + + +## Source Migration — `/src/js/binaryen.js-post.js` +### Constants and Enums +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| ------------------------ | -------- | ------------------- | ---- | ------------ | ----- | +| Types | line 32 | constants.ts | [x] | [x] | [x] | +| `ExpressionIds` | line 63 | constants.ts | [x] | [x] | [x] | +| `ExternalKinds` | line 152 | constants.ts | [x] | [x] | [x] | +| `MemoryOrder` | line 163 | constants.ts | [x] | [x] | [x] | +| `Features` | line 173 | Module.ts | [x] | [x] | [x] | +| `Operations` | line 204 | constants.ts | [x] | [x] | [x] | +| `SideEffects` | line 626 | constants.ts | [x] | [x] | [x] | +| `ExpressionRunner.Flags` | line 649 | ExpressionRunner.ts | [x] | [x] | [x] | + + +### class `Module` — Expression Building +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| ----------------------- | --------- | --------------------- | ---- | ------------ | ----- | +| `block` | line 679 | generic.ts | [x] | [x] | [ ] | +| `if` | | generic.ts | [x] | [x] | [ ] | +| `loop` | | generic.ts | [x] | [x] | [ ] | +| `br_if` | | generic.ts | [x] | [x] | [ ] | +| `switch` | | generic.ts | [x] | [x] | [ ] | +| `call` | | generic.ts | [x] | [x] | [ ] | +| `callIndirect` | | generic.ts | [x] | [x] | [ ] | +| `returnCall` | | generic.ts | [x] | [x] | [ ] | +| `returnCallIndirect` | | generic.ts | [x] | [x] | [ ] | +| `local` | line 725 | variable.ts | [x] | [x] | [ ] | +| `global` | | variable.ts | [x] | [x] | [ ] | +| `table` | | table.ts | [x] | [x] | [ ] | +| `memory` | | memory.ts | [x] | [x] | [ ] | +| `memory.atomic` | line 781 | memory.ts | [x] | [x] | [ ] | +| `data` | | memory.ts | [x] | [x] | [ ] | +| `i32` | line 800 | i32.ts | [x] | [x] | [ ] | +| `i32.atomic` | line 963 | i32.ts | [x] | [x] | [ ] | +| `i32.pop` | | Module.ts | [x] | [x] | [ ] | +| `i64` | line 1078 | i64.ts | [x] | [x] | [ ] | +| `i64.const` with bigint | | i64.ts | [x] | [x] | [ ] | +| `i64.atomic` | line 1275 | i64.ts | [x] | [x] | [ ] | +| `i64.pop` | | Module.ts | [x] | [x] | [ ] | +| `f32` | line 1426 | f32.ts | [x] | [x] | [ ] | +| `f32.const_bits` | | f32.ts | [x] | [x] | [ ] | +| `f64` | line 1534 | f64.ts | [x] | [x] | [ ] | +| `f64.const_bits` | | f64.ts | [x] | [x] | [ ] | +| `v128` | line 1647 | v128.ts | [x] | [x] | [ ] | +| `v128.pop` | | Module.ts | [x] | [x] | [ ] | +| `i8x16` | line 1755 | i8x16.ts | [x] | [x] | [ ] | +| `i16x8` | line 1869 | i16x8.ts | [x] | [x] | [ ] | +| `i32x4` | line 2010 | i32x4.ts | [x] | [x] | [ ] | +| `i64x2` | line 2139 | i64x2.ts | [x] | [x] | [ ] | +| `f32x4` | line 2223 | f32x4.ts | [x] | [x] | [ ] | +| `f64x2` | line 2307 | f64x2.ts | [x] | [x] | [ ] | +| `funcref.pop` | line 2391 | Module.ts | [x] | [x] | [ ] | +| `externref.pop` | | Module.ts | [x] | [x] | [ ] | +| `anyref.pop` | | Module.ts | [x] | [x] | [ ] | +| `eqref.pop` | | Module.ts | [x] | [x] | [ ] | +| `i31ref.pop` | | Module.ts | [x] | [x] | [ ] | +| `structref.pop` | | Module.ts | [x] | [x] | [ ] | +| `arrayref.pop` | | Module.ts | [x] | [x] | [ ] | +| `stringref.pop` | | Module.ts | [x] | [x] | [ ] | +| `ref` | line 2439 | refrence.ts | [x] | [x] | [ ] | +| `select` | | generic.ts | [x] | [x] | [ ] | +| `drop` | | generic.ts | [x] | [x] | [ ] | +| `return` | | generic.ts | [x] | [x] | [ ] | +| `nop` | | generic.ts | [x] | [x] | [ ] | +| `unreachable` | | generic.ts | [x] | [x] | [ ] | +| `atomic.fence` | | expressionBuilder.ts | [x] | [x] | [ ] | +| `try` | | generic.ts | [x] | [x] | [ ] | +| `throw` | | generic.ts | [x] | [x] | [ ] | +| `rethrow` | | generic.ts | [x] | [x] | [ ] | +| `tuple` | line 2499 | aggregate.ts | [x] | [x] | [ ] | +| `i31` | | reference.ts | [x] | [x] | [ ] | +| `call_ref` | | generic.ts | [x] | [x] | [ ] | +| `return_call_ref` | | generic.ts | [x] | [x] | [ ] | +| `any.convert_extern` | line 2529 | expressionBuilder.ts | [ ] | [~] | [ ] | +| `extern.convert_any` | | expressionBuilder.ts | [ ] | [~] | [ ] | +| `br_on_null` | line 2541 | generic.ts | [x] | [x] | [ ] | +| `br_on_cast` | | generic.ts | [x] | [x] | [ ] | +| `br_on_cast_fail` | | generic.ts | [x] | [x] | [ ] | +| `struct` | line 2557 | aggregate.ts | [x] | [x] | [ ] | +| `array` | | aggregate.ts | [x] | [x] | [ ] | + + +### class `Module` — Module Operations +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| -------------------------- | --------- | ----------------- | ---- | ------------ | ----- | +| `addFunction` | line 2616 | Function.ts | [x] | [x] | [ ] | +| `getFunction` | | Function.ts | [x] | [x] | [ ] | +| `removeFunction` | | Function.ts | [x] | [x] | [ ] | +| `addGlobal` | | Global.ts | [x] | [x] | [ ] | +| `getGlobal` | | Global.ts | [x] | [x] | [ ] | +| `addTable` | | Table.ts | [x] | [x] | [ ] | +| `getTable` | | Table.ts | [x] | [x] | [ ] | +| `addActiveElementSegment` | | ElementSegment.ts | [x] | [x] | [ ] | +| `addPassiveElementSegment` | | ElementSegment.ts | [x] | [x] | [ ] | +| `getElementSegment` | | ElementSegment.ts | [x] | [x] | [ ] | +| `getTableSegments` | | Table.ts | [x] | [x] | [ ] | +| `removeGlobal` | | Global.ts | [x] | [x] | [ ] | +| `removeTable` | | Table.ts | [x] | [x] | [ ] | +| `removeElementSegment` | | ElementSegment.ts | [x] | [x] | [ ] | +| `addTag` | | Tag.ts | [x] | [x] | [ ] | +| `getTag` | | Tag.ts | [x] | [x] | [ ] | +| `removeTag` | | Tag.ts | [x] | [x] | [ ] | +| `addFunctionImport` | | Import.ts | [x] | [x] | [ ] | +| `addTableImport` | | Import.ts | [x] | [x] | [ ] | +| `addMemoryImport` | | Import.ts | [x] | [x] | [ ] | +| `addGlobalImport` | | Import.ts | [x] | [x] | [ ] | +| `addTagImport` | | Import.ts | [x] | [x] | [ ] | +| `addFunctionExport` | | Export.ts | [x] | [x] | [ ] | +| `addTableExport` | | Export.ts | [x] | [x] | [ ] | +| `addMemoryExport` | | Export.ts | [x] | [x] | [ ] | +| `addGlobalExport` | | Export.ts | [x] | [x] | [ ] | +| `addTagExport` | | Export.ts | [x] | [x] | [ ] | +| `removeExport` | | Export.ts | [x] | [x] | [ ] | +| `setMemory` | | Memory.ts | [x] | [x] | [ ] | +| `hasMemory` | | Memory.ts | [x] | [x] | [ ] | +| `getMemoryInfo` | | Module.ts | [x] | [x] | [ ] | +| `getNumDataSegments` | | DataSegment.ts | [x] | [x] | [ ] | +| `getDataSegmentByIndex` | | DataSegment.ts | [x] | [x] | [ ] | +| `getDataSegmentInfo` | | DataSegment.ts | [x] | [x] | [ ] | +| `setStart` | | Module.ts | [x] | [x] | [ ] | +| `getStart` | | Module.ts | [x] | [x] | [ ] | +| `getFeatures` | | Module.ts | [x] | [x] | [ ] | +| `setFeatures` | | Module.ts | [x] | [x] | [ ] | +| `setTypeName` | | Module.ts | [x] | [x] | [ ] | +| `setFieldName` | | Module.ts | [x] | [x] | [ ] | +| `addCustomSection` | | Module.ts | [x] | [x] | [ ] | +| `getExport` | | Export.ts | [x] | [x] | [ ] | +| `getNumExports` | | Export.ts | [x] | [x] | [ ] | +| `getExportByIndex` | | Export.ts | [x] | [x] | [ ] | +| `getNumFunctions` | | Function.ts | [x] | [x] | [ ] | +| `getFunctionByIndex` | | Function.ts | [x] | [x] | [ ] | +| `getNumGlobals` | | Global.ts | [x] | [x] | [ ] | +| `getNumTables` | | Table.ts | [x] | [x] | [ ] | +| `getNumElementSegments` | | ElementSegment.ts | [x] | [x] | [ ] | +| `getGlobalByIndex` | | Global.ts | [x] | [x] | [ ] | +| `getTableByIndex` | | Table.ts | [x] | [x] | [ ] | +| `getElementSegmentByIndex` | | ElementSegment.ts | [x] | [x] | [ ] | + + +### class `Module` — Inspection & Debugging +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| ---------------------- | --------- | ---------- | ---- | ------------ | ----- | +| `emitText` | line 2907 | Module.ts | [x] | [x] | [ ] | +| `emitStackIR` | | Module.ts | [x] | [x] | [ ] | +| `emitAsmjs` | | Module.ts | [x] | [x] | [ ] | +| `validate` | | Module.ts | [x] | [x] | [ ] | +| `optimize` | | Module.ts | [x] | [x] | [ ] | +| `updateMaps` | | Module.ts | [x] | [x] | [ ] | +| `optimizeFunction` | | Module.ts | [x] | [x] | [ ] | +| `runPasses` | | Module.ts | [x] | [x] | [ ] | +| `runPassesOnFunction` | | Module.ts | [x] | [x] | [ ] | +| `dispose` | | Module.ts | [x] | [x] | [ ] | +| `emitBinary` | | Module.ts | [x] | [x] | [ ] | +| `interpret` | | Module.ts | [x] | [x] | [ ] | +| `addDebugInfoFileName` | | Module.ts | [x] | [x] | [ ] | +| `getDebugInfoFileName` | | Module.ts | [x] | [x] | [ ] | +| `setDebugLocation` | | Module.ts | [x] | [x] | [ ] | +| `copyExpression` | | Module.ts | [x] | [x] | [ ] | + + +### class `TypeBuilder` +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| --------------------- | --------- | -------------- | ---- | ------------ | ----- | +| `TypeBulder` | line 2999 | TypeBuilder.ts | [x] | [x] | [ ] | +| `getTypeFromHeapType` | line 3074 | globals.ts | [x] | [x] | [ ] | +| `getHeapType` | line 3079 | globals.ts | [x] | [x] | [ ] | + + +### more classes +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| ------------------ | --------- | ------------------- | ---- | ------------ | ----- | +| `Relooper` | line 3085 | Relooper.ts | [x] | [x] | [ ] | +| `ExpressionRunner` | line 3109 | ExpressionRunner.ts | [x] | [x] | [ ] | + + +### expression & component infos +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| ----------------------- | --------- | ----------------- | ---- | ------------ | ----- | +| `getExpressionId` | line 3149 | globals.ts | [x] | [x] | [ ] | +| `getExpressionType` | | globals.ts | [x] | [x] | [ ] | +| `getExpressionInfo` | | globals.ts | [x] | [x] | [ ] | +| `getSideEffects` | line 3204 | Module.ts | [x] | [x] | [ ] | +| `createType` | line 3210 | global.ts | [x] | [x] | [ ] | +| `expandType` | | global.ts | [x] | [x] | [ ] | +| `getFunctionInfo` | line 3228 | Function.ts | [x] | [x] | [ ] | +| `getGlobalInfo` | | Function.ts | [x] | [x] | [ ] | +| `getTableInfo` | | Table.ts | [x] | [x] | [ ] | +| `getElementSegmentInfo` | | ElementSegment.ts | [x] | [x] | [ ] | +| `getTagInfo` | | Tag.ts | [x] | [x] | [ ] | +| `getExportInfo` | | Export.ts | [x] | [x] | [ ] | + + +### more global functions & settings +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| ------------------------------------ | --------- | ------------------ | ---- | ------------ | ----- | +| `emitText` | line 3307 | globals.ts | [x] | [x] | [ ] | +| `readBinary` | line 3358 | globals.ts | [x] | [x] | [ ] | +| `readBinaryWithFeatures` | | globals.ts | [x] | [x] | [ ] | +| `parseText` | | globals.ts | [x] | [x] | [ ] | +| `getOptimizeLevel` | line 3384 | SettingsService.ts | [x] | [x] | [ ] | +| `setOptimizeLevel` | | SettingsService.ts | [x] | [x] | [ ] | +| `getShrinkLevel` | | SettingsService.ts | [x] | [x] | [ ] | +| `setShrinkLevel` | | SettingsService.ts | [x] | [x] | [ ] | +| `getDebugInfo` | | SettingsService.ts | [x] | [x] | [ ] | +| `setDebugInfo` | | SettingsService.ts | [x] | [x] | [ ] | +| `getTrapsNeverHappen` | | SettingsService.ts | [x] | [x] | [ ] | +| `setTrapsNeverHappen` | | SettingsService.ts | [x] | [x] | [ ] | +| `getClosedWorld` | | SettingsService.ts | [x] | [x] | [ ] | +| `setClosedWorld` | | SettingsService.ts | [x] | [x] | [ ] | +| `getLowMemoryUnused` | | SettingsService.ts | [x] | [x] | [ ] | +| `setLowMemoryUnused` | | SettingsService.ts | [x] | [x] | [ ] | +| `getZeroFilledMemory` | | SettingsService.ts | [x] | [x] | [ ] | +| `setZeroFilledMemory` | | SettingsService.ts | [x] | [x] | [ ] | +| `getFastMath` | | SettingsService.ts | [x] | [x] | [ ] | +| `setFastMath` | | SettingsService.ts | [x] | [x] | [ ] | +| `getGenerateStackIR` | | SettingsService.ts | [x] | [x] | [ ] | +| `setGenerateStackIR` | | SettingsService.ts | [x] | [x] | [ ] | +| `getOptimizeStackIR` | | SettingsService.ts | [x] | [x] | [ ] | +| `setOptimizeStackIR` | | SettingsService.ts | [x] | [x] | [ ] | +| `getPassArgument` | | SettingsService.ts | [x] | [x] | [ ] | +| `setPassArgument` | | SettingsService.ts | [x] | [x] | [ ] | +| `clearPassArguments` | | SettingsService.ts | [x] | [x] | [ ] | +| `hasPassToSkip` | | SettingsService.ts | [x] | [x] | [ ] | +| `addPassToSkip` | | SettingsService.ts | [x] | [x] | [ ] | +| `clearPassesToSkip` | | SettingsService.ts | [x] | [x] | [ ] | +| `getAlwaysInlineMaxSize` | | SettingsService.ts | [x] | [x] | [ ] | +| `setAlwaysInlineMaxSize` | | SettingsService.ts | [x] | [x] | [ ] | +| `getFlexibleInlineMaxSize` | | SettingsService.ts | [x] | [x] | [ ] | +| `setFlexibleInlineMaxSize` | | SettingsService.ts | [x] | [x] | [ ] | +| `getOneCallerInlineMaxSize` | | SettingsService.ts | [x] | [x] | [ ] | +| `setOneCallerInlineMaxSize` | | SettingsService.ts | [x] | [x] | [ ] | +| `getAllowInliningFunctionsWithLoops` | | SettingsService.ts | [x] | [x] | [ ] | +| `setAllowInliningFunctionsWithLoops` | | SettingsService.ts | [x] | [x] | [ ] | + + +### Expression Wrappers +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| ------------------- | --------- | --------------- | ---- | ------------ | ----- | +| `Expression` | line 3645 | Expression.ts | [x] | [x] | [ ] | +| `Block` | line 3677 | blocks.ts | [x] | [x] | [ ] | +| `If` | | blocks.ts | [x] | [x] | [ ] | +| `Loop` | | blocks.ts | [x] | [x] | [ ] | +| `Break` | | breaks.ts | [x] | [x] | [ ] | +| `Switch` | | breaks.ts | [x] | [x] | [ ] | +| `Call` | | calls.ts | [x] | [x] | [ ] | +| `CallIndirect` | | calls.ts | [x] | [x] | [ ] | +| `LocalGet` | | variables.ts | [x] | [x] | [ ] | +| `LocalSet` | | variables.ts | [x] | [x] | [ ] | +| `GlobalGet` | | variables.ts | [x] | [x] | [ ] | +| `GlobalSet` | | variables.ts | [x] | [x] | [ ] | +| `TableGet` | | tables.ts | [x] | [x] | [ ] | +| `TableSet` | | tables.ts | [x] | [x] | [ ] | +| `TableSize` | | tables.ts | [x] | [x] | [ ] | +| `TableGrow` | | tables.ts | [x] | [x] | [ ] | +| `MemorySize` | | memories.ts | [x] | [x] | [ ] | +| `MemoryGrow` | | memories.ts | [x] | [x] | [ ] | +| `Load` | | memories.ts | [x] | [x] | [ ] | +| `Store` | | memories.ts | [x] | [x] | [ ] | +| `Const` | | numerics.ts | [x] | [x] | [ ] | +| `Unary` | | numerics.ts | [x] | [x] | [ ] | +| `Binary` | | numerics.ts | [x] | [x] | [ ] | +| `WideIntAddSub` | | numerics.ts | [x] | [x] | [ ] | +| `WideIntMul` | | numerics.ts | [x] | [x] | [ ] | +| `Select` | | parametrics.ts | [x] | [x] | [ ] | +| `Drop` | | parametrics.ts | [x] | [x] | [ ] | +| `Return` | | calls.ts | [x] | [x] | [ ] | +| `AtomicRMW` | | atomics.ts | [x] | [x] | [ ] | +| `AtomicCmpxchg` | | atomics.ts | [x] | [x] | [ ] | +| `AtomicWait` | | atomics.ts | [x] | [x] | [ ] | +| `AtomicNotify` | | atomics.ts | [x] | [x] | [ ] | +| `AtomicFence` | | atomics.ts | [x] | [x] | [ ] | +| `SIMDExtract` | | vectors.ts | [x] | [x] | [ ] | +| `SIMDReplace` | | vectors.ts | [x] | [x] | [ ] | +| `SIMDShuffle` | | vectors.ts | [x] | [x] | [ ] | +| `SIMDTernary` | | vectors.ts | [x] | [x] | [ ] | +| `SIMDShift` | | vectors.ts | [x] | [x] | [ ] | +| `SIMDLoad` | | memories.ts | [x] | [x] | [ ] | +| `SIMDLoadStoreLane` | | memories.ts | [x] | [x] | [ ] | +| `MemoryInit` | | memories.ts | [x] | [x] | [ ] | +| `DataDrop` | | memories.ts | [x] | [x] | [ ] | +| `MemoryCopy` | | memories.ts | [x] | [x] | [ ] | +| `MemoryFill` | | memories.ts | [x] | [x] | [ ] | +| `RefIsNull` | | references.ts | [x] | [x] | [ ] | +| `RefAs` | | references.ts | [x] | [x] | [ ] | +| `RefFunc` | | references.ts | [x] | [x] | [ ] | +| `RefEq` | | references.ts | [x] | [x] | [ ] | +| `RefTest` | | references.ts | [x] | [x] | [ ] | +| `RefCast` | | references.ts | [x] | [x] | [ ] | +| `BrOn` | | breaks.ts | [x] | [x] | [ ] | +| `StructNew` | | aggregates.ts | [x] | [x] | [ ] | +| `StructGet` | | aggregates.ts | [x] | [x] | [ ] | +| `StructSet` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayNew` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayNewFixed` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayNewData` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayNewElem` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayGet` | | aggregates.ts | [x] | [x] | [ ] | +| `ArraySet` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayLen` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayFill` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayCopy` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayInitData` | | aggregates.ts | [x] | [x] | [ ] | +| `ArrayInitElem` | | aggregates.ts | [x] | [x] | [ ] | +| `Try` | | throws.ts | [x] | [x] | [ ] | +| `Throw` | | throws.ts | [x] | [x] | [ ] | +| `Rethrow` | | throws.ts | [x] | [x] | [ ] | +| `TupleMake` | | aggregates.ts | [x] | [x] | [ ] | +| `TupleExtract` | | aggregates.ts | [x] | [x] | [ ] | +| `RefI31` | | references.ts | [x] | [x] | [ ] | +| `I31Get` | | references.ts | [x] | [x] | [ ] | +| `CallRef` | | calls.ts | [x] | [x] | [ ] | + + +### Component Wrappers +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| ----------- | --------- | ----------- | ---- | ------------ | ----- | +| `Function` | line 5388 | Function.ts | [x] | [x] | [ ] | +| `Table` | line 5445 | Table.ts | [x] | [x] | [ ] | + + +### Additional +| Name | JS Loc | TS Loc | Code | API Overview | Tests | +| ------- | --------- | ----------- | ---- | ------------ | ----- | +| `exit` | line 5570 | globals.ts | [x] | [x] | [ ] | + + + +## Test Migration — `/test/binaryen.js/` +TODO From 4d0e9abca30ac07d0229c8fc7afe071956fe5df6 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 21 May 2026 00:52:22 -0400 Subject: [PATCH 219/247] build: turn off init-declarations lint rule eslint 10 has better rules enabled by default that prevent footguns with uninitialized variables --- ts/eslint.config.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/ts/eslint.config.js b/ts/eslint.config.js index e05beaaad1d..43680d20adf 100644 --- a/ts/eslint.config.js +++ b/ts/eslint.config.js @@ -105,7 +105,6 @@ export default [ "prefer-template": "error", /* ## Variable Declarations */ - "init-declarations": "error", "no-shadow": "error", "no-use-before-define": "error", "one-var": ["error", "never"], @@ -146,8 +145,6 @@ export default [ /* # Best Practices */ /* ## Variable Declarations */ - "init-declarations": "off", - "@typescript-eslint/init-declarations": "error", "no-shadow": "off", "@typescript-eslint/no-shadow": "error", "no-unused-vars": "off", From b1c45964964e2a8761d42fe8d5e4b722b3e9a1b0 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 21 May 2026 13:41:03 -0400 Subject: [PATCH 220/247] fix: optionalize argument `Module#getMemoryInfo@name` --- ts/src/classes/module/Module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 63f6bca280b..cfe500105f3 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -333,7 +333,7 @@ export class Module { /** @deprecated Use {@link Module#exports | `this.exports.addFunction`} instead. */ @replacedBy("`this.exports.addFunction`") addFunctionExport(internalName: string, externalName: string) { return this.exports.addFunction(internalName, externalName); } /** @category Module Component Operations */ - getMemoryInfo(name: string): Memory_ { + getMemoryInfo(name: string = ""): Memory_ { return new Memory_(this, name); } From 9a9b916ad4550e3f50d4191147895ccfd09f06be Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 21 May 2026 14:35:45 -0400 Subject: [PATCH 221/247] fix: `BrOn#op` type --- ts/src/classes/expression/breaks.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ts/src/classes/expression/breaks.ts b/ts/src/classes/expression/breaks.ts index 740888e5bb0..ee37fbe2ec8 100644 --- a/ts/src/classes/expression/breaks.ts +++ b/ts/src/classes/expression/breaks.ts @@ -11,6 +11,7 @@ import { import { ExpressionId, type ExpressionRef, + type Operation, type Type, } from "../../constants.ts"; import { @@ -111,8 +112,8 @@ export class BrOn extends Expression { super(ExpressionId.BrOn, expr); } - get op(): number { return BinaryenObj["_BinaryenBrOnGetOp"](this._ptr); } - set op(op: number) { BinaryenObj["_BinaryenBrOnSetOp"](this._ptr, op); } + get op(): Operation { return BinaryenObj["_BinaryenBrOnGetOp"](this._ptr); } + set op(op: Operation) { BinaryenObj["_BinaryenBrOnSetOp"](this._ptr, op); } get name(): string { return UTF8ToString(BinaryenObj["_BinaryenBrOnGetName"](this._ptr)); } set name(name: string) { preserveStack(() => BinaryenObj["_BinaryenBrOnSetName"](this._ptr, strToStack(name))); } From c9c72528b3b4a6fcd2b22bc88708a21321a66a3e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 21 May 2026 22:43:20 -0400 Subject: [PATCH 222/247] refactor: use more specific default value --- ts/src/services/expression-builder/generic.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ts/src/services/expression-builder/generic.ts b/ts/src/services/expression-builder/generic.ts index b84d6a7d0ff..fa811bd7a70 100644 --- a/ts/src/services/expression-builder/generic.ts +++ b/ts/src/services/expression-builder/generic.ts @@ -17,9 +17,6 @@ import { none, unreachable, } from "../../constants.ts"; -import { - expressionBuilder, -} from "./expressionBuilder.ts"; @@ -70,7 +67,7 @@ export function blocks(mod: Module) { ), /** Creates an ‘if’ or ‘if/else’ combination. */ - if: (condition: ExpressionRef, ifTrue: ExpressionRef, ifFalse: ExpressionRef = expressionBuilder(mod).nop()): ExpressionRef => ( + if: (condition: ExpressionRef, ifTrue: ExpressionRef, ifFalse: ExpressionRef = parametrics(mod).nop()): ExpressionRef => ( BinaryenObj["_BinaryenIf"](mod[PTR], condition, ifTrue, ifFalse) ), } as const; From 65a6a404c003beeeec56628a61c7a515100adbf8 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 21 May 2026 23:08:23 -0400 Subject: [PATCH 223/247] fix: add ExpressionBuilder missing types --- ts/src/services/expression-builder/aggregate.ts | 4 ++-- ts/src/services/expression-builder/reference.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ts/src/services/expression-builder/aggregate.ts b/ts/src/services/expression-builder/aggregate.ts index bd896b30081..0242c1b9987 100644 --- a/ts/src/services/expression-builder/aggregate.ts +++ b/ts/src/services/expression-builder/aggregate.ts @@ -60,7 +60,7 @@ export function struct(mod: Module) { * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. */ - get: function (index: number, ref: number, type: number, deprecated_isSigned?: boolean) { + get: function (index: number, ref: ExpressionRef, type: Type, deprecated_isSigned?: boolean): ExpressionRef { return deprecated_isSigned === undefined ? BinaryenObj["_BinaryenStructGet"](mod[PTR], index, ref, type) : deprecated_isSigned @@ -121,7 +121,7 @@ export function array(mod: Module) { * **Warning:** `.get()` no longer takes the boolean `isSigned` argument, and assumes an unpacked type. * For packed types, use `.get_s()` for signed and `.get_u()` for unsigned. */ - get: function (ref: number, index: number, type: number, deprecated_isSigned?: boolean) { + get: function (ref: ExpressionRef, index: ExpressionRef, type: Type, deprecated_isSigned?: boolean): ExpressionRef { return deprecated_isSigned === undefined ? BinaryenObj["_BinaryenArrayGet"](mod[PTR], ref, index, type) : deprecated_isSigned diff --git a/ts/src/services/expression-builder/reference.ts b/ts/src/services/expression-builder/reference.ts index d990860e94c..eaf41fde892 100644 --- a/ts/src/services/expression-builder/reference.ts +++ b/ts/src/services/expression-builder/reference.ts @@ -21,8 +21,8 @@ import { export function ref(mod: Module) { return { /** Produces a reference to a given function. */ - func: (name: string, type: Type) => ( - preserveStack(() => BinaryenObj["_BinaryenRefFunc"](mod[PTR], strToStack(name), type)) + func: (name: string, type: Type): ExpressionRef => ( + preserveStack(() => BinaryenObj["_BinaryenRefFunc"](mod[PTR], strToStack(name), type) as ExpressionRef) ), /** Produces a null reference. */ From a630cdb57152d280739a2e25521b589ddc9870a3 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Thu, 21 May 2026 23:46:47 -0400 Subject: [PATCH 224/247] docs: show not supported instrs --- ts/docs/API-Overview.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index 548a3e50d10..d4f3a1bc423 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -200,8 +200,10 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.global.set()` - tables and memories - `.table.get()`, `.table.set()`, `.table.size()`, `.table.grow()` + - ~~`.table.fill()`, `.table.copy()`, `table.init()`~~; ⛔️ not yet supported - `.memory.size()`, `.memory.grow()`, `.memory.fill()`, `.memory.copy()`, `.memory.init()`, - - `.elem.drop()`, `.data.drop()` + - ~~`.elem.drop()`~~; ⛔️ not yet supported + - `.data.drop()` - references - `.ref.func()`, `.ref.null()`, `.ref.is_null()`, `.ref.as_non_null()`, `.ref.eq()`, `.ref.test()`, `.ref.cast()` - `.ref.i31()`, `i31.get_{s,u}()` @@ -269,11 +271,11 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.{i16x8,i32x4,i64x2}.mul()` - `.{i8x16,i16x8}.avgr_u()` - `.i16x8.q15mulr_sat_s()` - - `.i16x8.relaxed_q15mulr_s()` + - ~~`.i16x8.relaxed_q15mulr_s()`~~; ⛔️ not yet supported - `.{i8x16,i16x8,i32x4}.min{s,u}()` - `.{i8x16,i16x8,i32x4}.max{s,u}()` > - - `.{i8x16,i16x8,i32x4,i64x2}.relaxed_laneselect()` + - ~~`.{i8x16,i16x8,i32x4,i64x2}.relaxed_laneselect()`~~; ⛔️ not yet supported - `.{i8x16,i16x8,i32x4,i64x2}.all_true()` - `.{i8x16,i16x8,i32x4,i64x2}.eq()` - `.{i8x16,i16x8,i32x4,i64x2}.ne()` @@ -285,23 +287,25 @@ Note: For brevity, glob-like syntax `_{s,u}` is used to mean “`_s` and `_u`” - `.{i8x16,i16x8,i32x4,i64x2}.shl()` - `.{i8x16,i16x8,i32x4,i64x2}.shr{s,u}()` - `.{i8x16,i16x8,i32x4,i64x2}.bitmask()` - - `.i8x16.swizzle()`, `.i8x16.relaxed_swizzle()` + - `.i8x16.swizzle()` + - ~~`.i8x16.relaxed_swizzle()`~~; ⛔️ not yet supported - `.i8x16.shuffle()` > - `.i16x8.extadd_pairwise_i8x16_{s,u}()`, `.i32x4.extadd_pairwise_i16x8_{s,u}()` - `.i16x8.extmul_{low,high}_i8x16_{s,u}()`, `.i32x4.extmul_{low,high}_i16x8_{s,u}()`, `.i64x2.extmul_{low,high}_i32x4_{s,u}()` - `.i32x4.dot_i16x8_s()` - - `.i16x8.relaxed_dot_i8x16_i7x16_s()` - - `.i32x4.relaxed_dot_i8x16_i7x16_add_s()` + - ~~`.i16x8.relaxed_dot_i8x16_i7x16_s()`~~; ⛔️ not yet supported + - ~~`.i32x4.relaxed_dot_i8x16_i7x16_add_s()`~~; ⛔️ not yet supported - `.i8x16.narrow_i16x8_{s,u}()`, `.i16x8.narrow_i32x4_{s,u}()` > - `.i16x8.extend_{low,high}_i8x16_{s,u}()`, `.i32x4.extend_{low,high}_i16x8_{s,u}()`, `.i64x2.extend_{low,high}_i32x4_{s,u}()` - `.i32x4.trunc_sat_f32x4_{s,u}()`, `.i32x4.trunc_sat_f64x2_{s,u}_zero()` - - `.i32x4.relaxed_trunc_f32x4_{s,u}()`, `.i32x4.relaxed_trunc_f64x2_{s,u}_zero()` + - ~~`.i32x4.relaxed_trunc_f32x4_{s,u}()`, `.i32x4.relaxed_trunc_f64x2_{s,u}_zero()`~~; ⛔️ not yet supported - SIMD floats - `.{f32x4,f64x2}.abs()`, `.{f32x4,f64x2}.neg()`, `.{f32x4,f64x2}.sqrt()`, `.{f32x4,f64x2}.ceil()`, `.{f32x4,f64x2}.floor()`, `.{f32x4,f64x2}.trunc()`, `.{f32x4,f64x2}.nearest()` - - `.{f32x4,f64x2}.add()`, `.{f32x4,f64x2}.sub()`, `.{f32x4,f64x2}.mul()`, `.{f32x4,f64x2}.div()`, `.{f32x4,f64x2}.min()`, `.{f32x4,f64x2}.max()`, `.{f32x4,f64x2}.pmin()`, `.{f32x4,f64x2}.pmax()`, `.{f32x4,f64x2}.relaxed_min()`, `.{f32x4,f64x2}.relaxed_max()` - - `.{f32x4,f64x2}.relaxed_madd()`, `.{f32x4,f64x2}.relaxed_nmadd()` + - `.{f32x4,f64x2}.add()`, `.{f32x4,f64x2}.sub()`, `.{f32x4,f64x2}.mul()`, `.{f32x4,f64x2}.div()`, `.{f32x4,f64x2}.min()`, `.{f32x4,f64x2}.max()`, `.{f32x4,f64x2}.pmin()`, `.{f32x4,f64x2}.pmax()` + - ~~`.{f32x4,f64x2}.relaxed_min()`, `.{f32x4,f64x2}.relaxed_max()`~~; ⛔️ not yet supported + - ~~`.{f32x4,f64x2}.relaxed_madd()`, `.{f32x4,f64x2}.relaxed_nmadd()`~~; ⛔️ not yet supported - `.{f32x4,f64x2}.eq()`, `.{f32x4,f64x2}.ne()`, `.{f32x4,f64x2}.lt()`, `.{f32x4,f64x2}.gt()`, `.{f32x4,f64x2}.le()`, `.{f32x4,f64x2}.ge()` - `.f32x4.convert_i32x4_{s,u}()`, `.f64x2.convert_low_i32x4_{s,u}()` - `.f32x4.demote_f64x2_zero()`, `.f64x2.promote_low_f32x4()` From aea6e0306192d0190fd136fc5260f865a1c12f10 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 23 May 2026 18:42:38 -0400 Subject: [PATCH 225/247] fix: missing `preserveStack` call --- ts/src/services/expression-builder/aggregate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/src/services/expression-builder/aggregate.ts b/ts/src/services/expression-builder/aggregate.ts index 0242c1b9987..80b80dee1e3 100644 --- a/ts/src/services/expression-builder/aggregate.ts +++ b/ts/src/services/expression-builder/aggregate.ts @@ -173,7 +173,7 @@ export function array(mod: Module) { offset: ExpressionRef, size: ExpressionRef, ): ExpressionRef => ( - BinaryenObj["_BinaryenArrayInitData"](mod[PTR], strToStack(name), ref, index, offset, size) + preserveStack(() => BinaryenObj["_BinaryenArrayInitData"](mod[PTR], strToStack(name), ref, index, offset, size)) ), /** Copies elements to a specified slice of an array from a given element segment. */ From 793cf447301807bf19b3c5a0a2a92f41e9304e34 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 23 May 2026 18:49:05 -0400 Subject: [PATCH 226/247] refactor: `preserveStack` tail calls --- ts/src/classes/TypeBuilder.ts | 2 +- ts/src/classes/expression/numerics.ts | 2 +- ts/src/classes/expression/vectors.ts | 2 +- ts/src/classes/module/Function.ts | 4 +--- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ts/src/classes/TypeBuilder.ts b/ts/src/classes/TypeBuilder.ts index bf922cc1759..d905d5af3ea 100644 --- a/ts/src/classes/TypeBuilder.ts +++ b/ts/src/classes/TypeBuilder.ts @@ -78,7 +78,7 @@ export class TypeBuilder { packedTypes[i] = packedType; mutables[i] = +mutable; } - BinaryenObj["_TypeBuilderSetStructType"]( + return BinaryenObj["_TypeBuilderSetStructType"]( this.#ptr, index, i32sToStack(types), diff --git a/ts/src/classes/expression/numerics.ts b/ts/src/classes/expression/numerics.ts index 3581cfe1c99..e638c92e786 100644 --- a/ts/src/classes/expression/numerics.ts +++ b/ts/src/classes/expression/numerics.ts @@ -68,7 +68,7 @@ export class Const extends Expression { for (let i = 0; i < 16; ++i) { BinaryenObj.HEAPU8[tempBuffer + i] = value[i]; } - BinaryenObj["_BinaryenConstSetValueV128"](this._ptr, tempBuffer); + return BinaryenObj["_BinaryenConstSetValueV128"](this._ptr, tempBuffer); }); } } diff --git a/ts/src/classes/expression/vectors.ts b/ts/src/classes/expression/vectors.ts index e0358191af2..f3a57ccebbf 100644 --- a/ts/src/classes/expression/vectors.ts +++ b/ts/src/classes/expression/vectors.ts @@ -82,7 +82,7 @@ export class SIMDShuffle extends Expression { for (let i = 0; i < 16; ++i) { BinaryenObj.HEAPU8[tempBuffer + i] = mask[i]; } - BinaryenObj["_BinaryenSIMDShuffleSetMask"](this._ptr, tempBuffer); + return BinaryenObj["_BinaryenSIMDShuffleSetMask"](this._ptr, tempBuffer); }); } } diff --git a/ts/src/classes/module/Function.ts b/ts/src/classes/module/Function.ts index dc1ca710503..23eddfc854d 100644 --- a/ts/src/classes/module/Function.ts +++ b/ts/src/classes/module/Function.ts @@ -78,9 +78,7 @@ class BinaryenFunction { } setLocalName(index: number, name: string): void { - preserveStack(() => { - BinaryenObj["_BinaryenFunctionSetLocalName"](this.#ptr, index, strToStack(name)); - }); + preserveStack(() => BinaryenObj["_BinaryenFunctionSetLocalName"](this.#ptr, index, strToStack(name))); } } export {BinaryenFunction as Function}; From 23375b1a4c4c5189594769310fc5024dd9b41223 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 23 May 2026 19:10:17 -0400 Subject: [PATCH 227/247] fix: `f64.reinterpret{f64 => i64}` --- ts/src/services/expression-builder/f64.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/src/services/expression-builder/f64.ts b/ts/src/services/expression-builder/f64.ts index 5b347387bc5..c5ca4dfaf18 100644 --- a/ts/src/services/expression-builder/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -64,7 +64,7 @@ export function f64(mod: Module) { convert_i32_u: unaryFn(mod, Operation.ConvertUInt32ToFloat64), convert_i64_s: unaryFn(mod, Operation.ConvertSInt64ToFloat64), convert_i64_u: unaryFn(mod, Operation.ConvertUInt64ToFloat64), - reinterpret_f64: unaryFn(mod, Operation.ReinterpretInt64), + reinterpret_i64: unaryFn(mod, Operation.ReinterpretInt64), promote_f32: unaryFn(mod, Operation.PromoteFloat32), From 1b0a9c076e443786bc78a8c462c60091d589e6cc Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 24 May 2026 16:58:43 -0400 Subject: [PATCH 228/247] feat: allow optional condition/code args to `Relooper#addBranch` --- ts/src/classes/Relooper.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ts/src/classes/Relooper.ts b/ts/src/classes/Relooper.ts index c34227fb3cd..6406390755d 100644 --- a/ts/src/classes/Relooper.ts +++ b/ts/src/classes/Relooper.ts @@ -47,11 +47,11 @@ export class Relooper { * on the branch (useful for phis). * @param from source block * @param to destination block - * @param condition contition to evaluate: if true, jumps to the given block; else does nothing - * @param code code to evaluate in between block jumps + * @param condition contition to evaluate: if true, jumps to the given block; else does nothing; for unconditional branches, omit or pass `null`/`undefined` + * @param code code (if any) to evaluate in between block jumps */ - addBranch(from: RelooperBlockRef, to: RelooperBlockRef, condition: ExpressionRef, code: ExpressionRef): void { - BinaryenObj["_RelooperAddBranch"](from, to, condition, code); + addBranch(from: RelooperBlockRef, to: RelooperBlockRef, condition?: ExpressionRef | null, code?: ExpressionRef): void { + BinaryenObj["_RelooperAddBranch"](from, to, condition ?? 0, code ?? 0); } /** From 08cd943b3bdc2b02ce74646cdd403000cdd31666 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sun, 24 May 2026 17:00:10 -0400 Subject: [PATCH 229/247] refactor: default to 0 instead of assert --- ts/src/services/expression-builder/generic.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ts/src/services/expression-builder/generic.ts b/ts/src/services/expression-builder/generic.ts index fa811bd7a70..c1bb6e1ff3e 100644 --- a/ts/src/services/expression-builder/generic.ts +++ b/ts/src/services/expression-builder/generic.ts @@ -84,12 +84,12 @@ export function breaks(mod: Module) { return { /** Creates an unconditional branch `(br)` to a label. */ br: (label: string, condition?: ExpressionRef, value?: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenBreak"](mod[PTR], strToStack(label), condition!, value!)) + preserveStack(() => BinaryenObj["_BinaryenBreak"](mod[PTR], strToStack(label), condition ?? 0, value ?? 0)) ), /** Creates a conditional branch `(br_if)` to a label. */ br_if: (label: string, condition: ExpressionRef, value?: ExpressionRef): ExpressionRef => ( - preserveStack(() => BinaryenObj["_BinaryenBreak"](mod[PTR], strToStack(label), condition, value!)) + preserveStack(() => BinaryenObj["_BinaryenBreak"](mod[PTR], strToStack(label), condition, value ?? 0)) ), /** Creates a switch. */ @@ -100,7 +100,7 @@ export function breaks(mod: Module) { labels.length, strToStack(defaultLabel), condition, - value!, + value ?? 0, )) ), From 4ad5310b285ff521275d1768cbf4d08de03f7086 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 27 May 2026 11:37:45 -0400 Subject: [PATCH 230/247] test: add test to kitchen sink --- test/example/c-api-kitchen-sink.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index a03f670034d..eeffd8fd35e 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -1280,6 +1280,14 @@ void test_core() { BinaryenExpressionPrint( valueList[3]); // test printing a standalone expression + // test stringifying an expression + { + char* textPtr = BinaryenExpressionAllocateAndWriteText(valueList[3]); + assert(textPtr); + assert(strstr(textPtr, "f32.neg")); + assert(!strstr(textPtr, "\x1b")); // ensure color escapes are not emitted + free(textPtr); + } // Add drops of concrete expressions for (int i = 0; i < sizeof(valueList) / sizeof(valueList[0]); ++i) { From 7823b787af5be679604bab7329ff7d92a4aaf5cf Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 27 May 2026 21:00:31 -0400 Subject: [PATCH 231/247] build: update "make" script --- ts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/package.json b/ts/package.json index fd2b2e6da3c..bf4c15ca97b 100644 --- a/ts/package.json +++ b/ts/package.json @@ -16,7 +16,7 @@ "type": "module", "main": "./dist/binaryen.js", "scripts": { - "make": "mkdir -p ../build/ && (cd ../build/ && emcmake cmake ../ && emmake make binaryen_js)", + "make": "emcmake cmake -S ../ -B ../build/ && emmake make -C ../build/ binaryen_js", "postmake": "rm -rf ./build/ && mkdir -p ./build/ && cp -R ../build/bin/ ./build/", "compile": "rm -rf ./dist/ && tsc && tsc --project ./test/tsconfig.json", "lint": "eslint ./", From bf368e6a37d63260553004dd2ab69d57668fc0ba Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Mon, 1 Jun 2026 19:48:55 -0400 Subject: [PATCH 232/247] docs: correct MemorySegment deprecations --- ts/docs/API-Overview.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ts/docs/API-Overview.md b/ts/docs/API-Overview.md index d4f3a1bc423..c177f9c6321 100644 --- a/ts/docs/API-Overview.md +++ b/ts/docs/API-Overview.md @@ -447,6 +447,7 @@ Enum names have been singularized. - `MemoryInfo` → `Module.Memory` - `TableInfo` → `Module.Table` - `FunctionInfo` → `Module.Function` +- `MemorySegmentInfo` → `Module.DataSegment` - `ElementSegmentInfo` → `Module.ElementSegment` - `ExportInfo` → `Module.Export` @@ -457,8 +458,6 @@ Enum names have been singularized. - `IfInfo` → `expressions.If` - etc. -~~`MemorySegmentInfo`~~ ❌ has been removed. - ### Modules Module components previously at the top level have been moved under the `Module` namespace. @@ -470,13 +469,13 @@ Most `get*Info()` functions have been replaced by their corresponding class cons - `getGlobalInfo(global)` → `new Module.Global(global)` - `getTableInfo(table)` → `new Module.Table(table)` - `getFunctionInfo(func)` → `new Module.Function(func)` +- `getMemorySegmentInfo(segment)` → `new Module.DataSegment(segment)` - `getElementSegmentInfo(segment)` → `new Module.ElementSegment(segment)` - `getExportInfo(xport)` → `new Module.Export(xport)` > - `Module#getMemoryInfo(name)` has not changed. - `Module#getDataSegmentInfo(name)` has not changed. - global `getExpressionInfo(expr)` has not changed. -- global ~~`getMemorySegmentInfo()`~~ ❌ has been removed. Most of the `Module` class’s instance methods relating to module component manipulation have been moved. - `Module#addTag()` → `Module#tags.add()` From b60beb4ebe22142be8fe0582125694c44f7e5218 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 3 Jun 2026 02:28:53 -0400 Subject: [PATCH 233/247] fix: forgot trailing newline --- src/js/binaryen.js-post.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 1d7f88122bf..67718aefd36 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -3318,7 +3318,7 @@ Module['emitText'] = function(expr) { } const textPtr = Module['_BinaryenExpressionAllocateAndWriteText'](expr); try { - return UTF8ToString(textPtr); + return UTF8ToString(textPtr) + '\n'; } finally { if (textPtr) { _free(textPtr); From b48eaade6234879e805f8c01b291fb0187527830 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 5 Jun 2026 20:58:39 -0400 Subject: [PATCH 234/247] build: update npm scripts --- ts/package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ts/package.json b/ts/package.json index bf4c15ca97b..64e91d7ba87 100644 --- a/ts/package.json +++ b/ts/package.json @@ -16,12 +16,14 @@ "type": "module", "main": "./dist/binaryen.js", "scripts": { - "make": "emcmake cmake -S ../ -B ../build/ && emmake make -C ../build/ binaryen_js", + "make": "rm -rf ../build/ && emcmake cmake -S ../ -B ../build/ && emmake make -C ../build/ binaryen_js", "postmake": "rm -rf ./build/ && mkdir -p ./build/ && cp -R ../build/bin/ ./build/", + "check": "../check.py binaryenjs --binaryen-bin='../build/bin'", "compile": "rm -rf ./dist/ && tsc && tsc --project ./test/tsconfig.json", "lint": "eslint ./", "docs": "rm -rf ../docs/binaryen.ts/ && typedoc", - "test": "tsx --test --test-isolation=none -- './test/**/*.test.ts'", + "test": "tsx --test -- './test/**/*.test.ts'", + "test:only": "tsx --test --test-only -- './test/**/*.test.ts'", "build": "npm run compile && npm run lint && npm run docs && npm run test" }, "files": [ From dfa9b4e1005b864e1d8ba00038635dfef1004a4e Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 5 Jun 2026 22:38:57 -0400 Subject: [PATCH 235/247] feat: add `pop()` deprecation warnings --- ts/src/classes/module/Module.ts | 11 ++++++++++- ts/src/services/expression-builder/f32.ts | 6 ++++++ ts/src/services/expression-builder/f64.ts | 6 ++++++ ts/src/services/expression-builder/i32.ts | 6 ++++++ ts/src/services/expression-builder/i64.ts | 6 ++++++ ts/src/services/expression-builder/v128.ts | 6 ++++++ 6 files changed, 40 insertions(+), 1 deletion(-) diff --git a/ts/src/classes/module/Module.ts b/ts/src/classes/module/Module.ts index 491ead19062..847dcd0a71b 100644 --- a/ts/src/classes/module/Module.ts +++ b/ts/src/classes/module/Module.ts @@ -227,10 +227,19 @@ export class Module { ].includes(typ)) { return BinaryenObj["_BinaryenPop"](this[PTR], typ); } else { - throw new Error(`Unexpected type ${ typ }.`); + throw new Error(`\`Module#pop()\` was called with an unexpected type: \`${ typ }\`.`); } } + /** @deprecated Use {@link Module#pop} instead. @category Expression Manipulation */ readonly funcref = {pop: () => { BinaryenObj.printWarn("`.funcref.pop()` is deprecated; use `.pop(funcref)` instead."); return this.pop(funcref); }}; + /** @deprecated Use {@link Module#pop} instead. @category Expression Manipulation */ readonly externref = {pop: () => { BinaryenObj.printWarn("`.externref.pop()` is deprecated; use `.pop(externref)` instead."); return this.pop(externref); }}; + /** @deprecated Use {@link Module#pop} instead. @category Expression Manipulation */ readonly anyref = {pop: () => { BinaryenObj.printWarn("`.anyref.pop()` is deprecated; use `.pop(anyref)` instead."); return this.pop(anyref); }}; + /** @deprecated Use {@link Module#pop} instead. @category Expression Manipulation */ readonly eqref = {pop: () => { BinaryenObj.printWarn("`.eqref.pop()` is deprecated; use `.pop(eqref)` instead."); return this.pop(eqref); }}; + /** @deprecated Use {@link Module#pop} instead. @category Expression Manipulation */ readonly i31ref = {pop: () => { BinaryenObj.printWarn("`.i31ref.pop()` is deprecated; use `.pop(i31ref)` instead."); return this.pop(i31ref); }}; + /** @deprecated Use {@link Module#pop} instead. @category Expression Manipulation */ readonly structref = {pop: () => { BinaryenObj.printWarn("`.structref.pop()` is deprecated; use `.pop(structref)` instead."); return this.pop(structref); }}; + /** @deprecated Use {@link Module#pop} instead. @category Expression Manipulation */ readonly arrayref = {pop: () => { BinaryenObj.printWarn("`.arrayref.pop()` is deprecated; use `.pop(arrayref)` instead."); return this.pop(arrayref); }}; + /** @deprecated Use {@link Module#pop} instead. @category Expression Manipulation */ readonly stringref = {pop: () => { BinaryenObj.printWarn("`.stringref.pop()` is deprecated; use `.pop(stringref)` instead."); return this.pop(stringref); }}; + /** * Gets the side effects of the specified expression. * @category Expression Manipulation diff --git a/ts/src/services/expression-builder/f32.ts b/ts/src/services/expression-builder/f32.ts index a7f043b61d8..66c15d20ac0 100644 --- a/ts/src/services/expression-builder/f32.ts +++ b/ts/src/services/expression-builder/f32.ts @@ -86,5 +86,11 @@ export function f32(mod: Module) { /** @deprecated Use `.reinterpret_i32()` instead. */ reinterpret(...args) { BinaryenObj.printWarn("`.reinterpret()` is deprecated; use `.reinterpret_i32()` instead."); return this.reinterpret_i32(...args); }, // @ts-expect-error /** @deprecated Use `.demote_f64()` instead. */ demote(...args) { BinaryenObj.printWarn("`.demote()` is deprecated; use `.demote_f64()` instead."); return this.demote_f64(...args); }, + + /** @deprecated Use {@link Module#pop} instead. */ + pop() { + BinaryenObj.printWarn("`.f32.pop()` is deprecated; use `.pop(f32)` instead."); + return mod.pop(f32_t); + }, } as const; } diff --git a/ts/src/services/expression-builder/f64.ts b/ts/src/services/expression-builder/f64.ts index c5ca4dfaf18..c2bb03b6601 100644 --- a/ts/src/services/expression-builder/f64.ts +++ b/ts/src/services/expression-builder/f64.ts @@ -86,5 +86,11 @@ export function f64(mod: Module) { /** @deprecated Use `.reinterpret_i64()` instead. */ reinterpret(...args) { BinaryenObj.printWarn("`.reinterpret()` is deprecated; use `.reinterpret_i64()` instead."); return this.reinterpret_i64(...args); }, // @ts-expect-error /** @deprecated Use `.promote_f32()` instead. */ promote(...args) { BinaryenObj.printWarn("`.promote()` is deprecated; use `.promote_f32()` instead."); return this.promote_f32(...args); }, + + /** @deprecated Use {@link Module#pop} instead. */ + pop() { + BinaryenObj.printWarn("`.f64.pop()` is deprecated; use `.pop(f64)` instead."); + return mod.pop(f64_t); + }, } as const; } diff --git a/ts/src/services/expression-builder/i32.ts b/ts/src/services/expression-builder/i32.ts index fde0a79f1a6..bceb57cb85e 100644 --- a/ts/src/services/expression-builder/i32.ts +++ b/ts/src/services/expression-builder/i32.ts @@ -144,5 +144,11 @@ export function i32(mod: Module) { }, // @ts-expect-error /** @deprecated Use `.reinterpret_f32()` instead. */ reinterpret(...args) { BinaryenObj.printWarn("`.reinterpret()` is deprecated; use `.reinterpret_f32()` instead."); return this.reinterpret_f32(...args); }, + + /** @deprecated Use {@link Module#pop} instead. */ + pop() { + BinaryenObj.printWarn("`.i32.pop()` is deprecated; use `.pop(i32)` instead."); + return mod.pop(i32_t); + }, } as const; } diff --git a/ts/src/services/expression-builder/i64.ts b/ts/src/services/expression-builder/i64.ts index 4b433195a1e..fb34d2831d4 100644 --- a/ts/src/services/expression-builder/i64.ts +++ b/ts/src/services/expression-builder/i64.ts @@ -173,5 +173,11 @@ export function i64(mod: Module) { }, // @ts-expect-error /** @deprecated Use `.reinterpret_f64()` instead. */ reinterpret(...args) { BinaryenObj.printWarn("`.reinterpret()` is deprecated; use `.reinterpret_f64()` instead."); return this.reinterpret_f64(...args); }, + + /** @deprecated Use {@link Module#pop} instead. */ + pop() { + BinaryenObj.printWarn("`.i64.pop()` is deprecated; use `.pop(i64)` instead."); + return mod.pop(i64_t); + }, } as const; } diff --git a/ts/src/services/expression-builder/v128.ts b/ts/src/services/expression-builder/v128.ts index 102d8f6f31f..0013bb1cf93 100644 --- a/ts/src/services/expression-builder/v128.ts +++ b/ts/src/services/expression-builder/v128.ts @@ -72,5 +72,11 @@ export function v128(mod: Module) { ), anytrue: unaryFn(mod, Operation.AnyTrueVec128), + + /** @deprecated Use {@link Module#pop} instead. */ + pop() { + BinaryenObj.printWarn("`.v128.pop()` is deprecated; use `.pop(v128)` instead."); + return mod.pop(v128_t); + }, } as const; } From 2fceceedb5af3edf4e86e006616b9c4cd4fd088b Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 5 Jun 2026 23:51:40 -0400 Subject: [PATCH 236/247] fix: convert `Try#hasCatchAll` to getter --- ts/src/classes/expression/throws.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ts/src/classes/expression/throws.ts b/ts/src/classes/expression/throws.ts index 8e5c1e907d1..a66c763b730 100644 --- a/ts/src/classes/expression/throws.ts +++ b/ts/src/classes/expression/throws.ts @@ -96,12 +96,6 @@ export class Try extends Expression { get body(): ExpressionRef { return BinaryenObj["_BinaryenTryGetBody"](this._ptr); } set body(bodyExpr: ExpressionRef) { BinaryenObj["_BinaryenTrySetBody"](this._ptr, bodyExpr); } - get numCatchTags(): number { return BinaryenObj["_BinaryenTryGetNumCatchTags"](this._ptr); } - - get numCatchBodies(): number { return BinaryenObj["_BinaryenTryGetNumCatchBodies"](this._ptr); } - - get delegate(): boolean { return Boolean(BinaryenObj["_BinaryenTryIsDelegate"](this._ptr)); } - get name(): string | null { const name = BinaryenObj["_BinaryenTryGetName"](this._ptr); return name ? UTF8ToString(name) : null; @@ -111,6 +105,8 @@ export class Try extends Expression { preserveStack(() => BinaryenObj["_BinaryenTrySetName"](this._ptr, strToStack(name))); } + get numCatchTags(): number { return BinaryenObj["_BinaryenTryGetNumCatchTags"](this._ptr); } + get catchTags(): string[] { return getAllNested( this._ptr, @@ -130,6 +126,8 @@ export class Try extends Expression { )); } + get numCatchBodies(): number { return BinaryenObj["_BinaryenTryGetNumCatchBodies"](this._ptr); } + get catchBodies(): ExpressionRef[] { return getAllNested( this._ptr, @@ -149,6 +147,12 @@ export class Try extends Expression { ); } + get hasCatchAll(): boolean { + return Boolean(BinaryenObj["_BinaryenTryHasCatchAll"](this._ptr)); + } + + get delegate(): boolean { return Boolean(BinaryenObj["_BinaryenTryIsDelegate"](this._ptr)); } + get delegateTarget(): string | null { const name = BinaryenObj["_BinaryenTryGetDelegateTarget"](this._ptr); return name ? UTF8ToString(name) : null; @@ -197,8 +201,4 @@ export class Try extends Expression { removeCatchBodyAt(index: number): ExpressionRef { return BinaryenObj["_BinaryenTryRemoveCatchBodyAt"](this._ptr, index); } - - hasCatchAll(): boolean { - return Boolean(BinaryenObj["_BinaryenTryHasCatchAll"](this._ptr)); - } } From 61abf6555d28737ebbbf4c515d1fbf403018d114 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Fri, 5 Jun 2026 23:56:08 -0400 Subject: [PATCH 237/247] fix: privatize type-specific value getters of `Const` --- ts/src/classes/expression/numerics.ts | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ts/src/classes/expression/numerics.ts b/ts/src/classes/expression/numerics.ts index e638c92e786..ea6978f6b24 100644 --- a/ts/src/classes/expression/numerics.ts +++ b/ts/src/classes/expression/numerics.ts @@ -29,28 +29,28 @@ export class Const extends Expression { get value(): number | number[] { const this_type = this.type; switch (this_type) { - case i32: { return this.valueI32; } - case i64: { return this.valueI64; } - case f32: { return this.valueF32; } - case f64: { return this.valueF64; } - case v128: { return this.valueV128; } + case i32: { return this.#valueI32; } + case i64: { return this.#valueI64; } + case f32: { return this.#valueF32; } + case f64: { return this.#valueF64; } + case v128: { return this.#valueV128; } } throw new Error(`Unexpected type: ${ this_type }.`); } - get valueI32(): number { return BinaryenObj["_BinaryenConstGetValueI32"](this._ptr); } - set valueI32(value: number) { BinaryenObj["_BinaryenConstSetValueI32"](this._ptr, value); } + get #valueI32(): number { return BinaryenObj["_BinaryenConstGetValueI32"](this._ptr); } + set #valueI32(value: number) { BinaryenObj["_BinaryenConstSetValueI32"](this._ptr, value); } - get valueI64(): number { return BinaryenObj["_BinaryenConstGetValueI64"](this._ptr); } - set valueI64(value: number) { BinaryenObj["_BinaryenConstSetValueI64"](this._ptr, BigInt(value)); } + get #valueI64(): number { return BinaryenObj["_BinaryenConstGetValueI64"](this._ptr); } + set #valueI64(value: number) { BinaryenObj["_BinaryenConstSetValueI64"](this._ptr, BigInt(value)); } - get valueF32(): number { return BinaryenObj["_BinaryenConstGetValueF32"](this._ptr); } - set valueF32(value: number) { BinaryenObj["_BinaryenConstSetValueF32"](this._ptr, value); } + get #valueF32(): number { return BinaryenObj["_BinaryenConstGetValueF32"](this._ptr); } + set #valueF32(value: number) { BinaryenObj["_BinaryenConstSetValueF32"](this._ptr, value); } - get valueF64(): number { return BinaryenObj["_BinaryenConstGetValueF64"](this._ptr); } - set valueF64(value: number) { BinaryenObj["_BinaryenConstSetValueF64"](this._ptr, value); } + get #valueF64(): number { return BinaryenObj["_BinaryenConstGetValueF64"](this._ptr); } + set #valueF64(value: number) { BinaryenObj["_BinaryenConstSetValueF64"](this._ptr, value); } - get valueV128(): number[] { + get #valueV128(): number[] { const value: number[] = []; preserveStack(() => { const tempBuffer = stackAlloc(16); @@ -62,7 +62,7 @@ export class Const extends Expression { return value; } - set valueV128(value: readonly number[]) { + set #valueV128(value: readonly number[]) { preserveStack(() => { const tempBuffer = stackAlloc(16); for (let i = 0; i < 16; ++i) { From 28922421a0d457ac1248fa601ab112ae2aefe784 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 6 Jun 2026 00:19:27 -0400 Subject: [PATCH 238/247] feat: add `Expression#toJson` --- ts/src/classes/expression/Expression.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ts/src/classes/expression/Expression.ts b/ts/src/classes/expression/Expression.ts index 04c57bd65a3..83166bb244d 100644 --- a/ts/src/classes/expression/Expression.ts +++ b/ts/src/classes/expression/Expression.ts @@ -48,6 +48,26 @@ export class Expression { BinaryenObj["_BinaryenExpressionFinalize"](this._ptr); } + /** + * Adds to this object enumerable own properties that are computed from getter methods. + * Useful when calling `JSON.stringify`: + * ```ts + * JSON.stringify(exprInfo.toJson()); + * ``` + */ + toJson(): Record { + const json: Record = { + id: this.id, + type: this.type, + }; + for (const [name, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(Reflect.getPrototypeOf(this)))) { + if ("get" in descriptor) { + json[name] = descriptor.get.call(this); + } + } + return json; + } + toText(): string { return emitText(this._ptr); } From 90af4c11d6be24cbf0be3f8849e357c488aafc50 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 6 Jun 2026 00:57:14 -0400 Subject: [PATCH 239/247] fix: add missing deprecation `ExpressionInfo` types --- ts/src/-deprecations.ts | 146 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index a1f91a37347..6707fb88a38 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -68,14 +68,160 @@ export type SelectInfo = expressions.Select; export type BlockInfo = expressions.Block; /** @deprecated The `LoopInfo` object type is now called {@link expressions.Loop}. */ export type LoopInfo = expressions.Loop; +/** @deprecated The `IfInfo` object type is now called {@link expressions.If}. */ +export type IfInfo = expressions.If; /** @deprecated The `BreakInfo` object type is now called {@link expressions.Break}. */ export type BreakInfo = expressions.Break; +/** @deprecated The `SwitchInfo` object type is now called {@link expressions.Switch}. */ +export type SwitchInfo = expressions.Switch; +/** @deprecated The `BrOnInfo` object type is now called {@link expressions.BrOn}. */ +export type BrOnInfo = expressions.BrOn; +/** @deprecated The `CallInfo` object type is now called {@link expressions.Call}. */ +export type CallInfo = expressions.Call; +/** @deprecated The `CallRefInfo` object type is now called {@link expressions.CallRef}. */ +export type CallRefInfo = expressions.CallRef; +/** @deprecated The `CallIndirectInfo` object type is now called {@link expressions.CallIndirect}. */ +export type CallIndirectInfo = expressions.CallIndirect; +/** @deprecated The `ReturnInfo` object type is now called {@link expressions.Return}. */ +export type ReturnInfo = expressions.Return; +/** @deprecated The `ThrowInfo` object type is now called {@link expressions.Throw}. */ +export type ThrowInfo = expressions.Throw; +/** @deprecated The `RethrowInfo` object type is now called {@link expressions.Rethrow}. */ +export type RethrowInfo = expressions.Rethrow; +/** @deprecated The `TryInfo` object type is now called {@link expressions.Try}. */ +export type TryInfo = expressions.Try; /** @deprecated The `LocalGetInfo` object type is now called {@link expressions.LocalGet}. */ export type LocalGetInfo = expressions.LocalGet; /** @deprecated The `LocalSetInfo` object type is now called {@link expressions.LocalSet}. */ export type LocalSetInfo = expressions.LocalSet; +/** @deprecated The `GlobalGetInfo` object type is now called {@link expressions.GlobalGet}. */ +export type GlobalGetInfo = expressions.GlobalGet; +/** @deprecated The `GlobalSetInfo` object type is now called {@link expressions.GlobalSet}. */ +export type GlobalSetInfo = expressions.GlobalSet; +/** @deprecated The `TableGetInfo` object type is now called {@link expressions.TableGet}. */ +export type TableGetInfo = expressions.TableGet; +/** @deprecated The `TableSetInfo` object type is now called {@link expressions.TableSet}. */ +export type TableSetInfo = expressions.TableSet; +/** @deprecated The `TableSizeInfo` object type is now called {@link expressions.TableSize}. */ +export type TableSizeInfo = expressions.TableSize; +/** @deprecated The `TableGrowInfo` object type is now called {@link expressions.TableGrow}. */ +export type TableGrowInfo = expressions.TableGrow; +/** @deprecated The `LoadInfo` object type is now called {@link expressions.Load}. */ +export type LoadInfo = expressions.Load; +/** @deprecated The `StoreInfo` object type is now called {@link expressions.Store}. */ +export type StoreInfo = expressions.Store; +/** @deprecated The `SIMDLoadInfo` object type is now called {@link expressions.SIMDLoad}. */ +export type SIMDLoadInfo = expressions.SIMDLoad; +/** @deprecated The `SIMDLoadStoreLaneInfo` object type is now called {@link expressions.SIMDLoadStoreLane}. */ +export type SIMDLoadStoreLaneInfo = expressions.SIMDLoadStoreLane; +/** @deprecated The `MemorySizeInfo` object type is now called {@link expressions.MemorySize}. */ +export type MemorySizeInfo = expressions.MemorySize; +/** @deprecated The `MemoryGrowInfo` object type is now called {@link expressions.MemoryGrow}. */ +export type MemoryGrowInfo = expressions.MemoryGrow; +/** @deprecated The `MemoryFillInfo` object type is now called {@link expressions.MemoryFill}. */ +export type MemoryFillInfo = expressions.MemoryFill; +/** @deprecated The `MemoryCopyInfo` object type is now called {@link expressions.MemoryCopy}. */ +export type MemoryCopyInfo = expressions.MemoryCopy; +/** @deprecated The `MemoryInitInfo` object type is now called {@link expressions.MemoryInit}. */ +export type MemoryInitInfo = expressions.MemoryInit; +/** @deprecated The `DataDropInfo` object type is now called {@link expressions.DataDrop}. */ +export type DataDropInfo = expressions.DataDrop; +/** @deprecated The `RefFuncInfo` object type is now called {@link expressions.RefFunc}. */ +export type RefFuncInfo = expressions.RefFunc; +/** @deprecated The `RefIsNullInfo` object type is now called {@link expressions.RefIsNull}. */ +export type RefIsNullInfo = expressions.RefIsNull; +/** @deprecated The `RefAsInfo` object type is now called {@link expressions.RefAs}. */ +export type RefAsInfo = expressions.RefAs; +/** @deprecated The `RefEqInfo` object type is now called {@link expressions.RefEq}. */ +export type RefEqInfo = expressions.RefEq; +/** @deprecated The `RefTestInfo` object type is now called {@link expressions.RefTest}. */ +export type RefTestInfo = expressions.RefTest; +/** @deprecated The `RefCastInfo` object type is now called {@link expressions.RefCast}. */ +export type RefCastInfo = expressions.RefCast; +/** @deprecated The `RefI31Info` object type is now called {@link expressions.RefI31}. */ +export type RefI31Info = expressions.RefI31; +/** @deprecated The `I31GetInfo` object type is now called {@link expressions.I31Get}. */ +export type I31GetInfo = expressions.I31Get; +/** @deprecated The `TupleMakeInfo` object type is now called {@link expressions.TupleMake}. */ +export type TupleMakeInfo = expressions.TupleMake; +/** @deprecated The `TupleExtractInfo` object type is now called {@link expressions.TupleExtract}. */ +export type TupleExtractInfo = expressions.TupleExtract; +/** @deprecated The `StructNewInfo` object type is now called {@link expressions.StructNew}. */ +export type StructNewInfo = expressions.StructNew; +/** @deprecated The `StructGetInfo` object type is now called {@link expressions.StructGet}. */ +export type StructGetInfo = expressions.StructGet; +/** @deprecated The `StructSetInfo` object type is now called {@link expressions.StructSet}. */ +export type StructSetInfo = expressions.StructSet; +/** @deprecated The `ArrayNewInfo` object type is now called {@link expressions.ArrayNew}. */ +export type ArrayNewInfo = expressions.ArrayNew; +/** @deprecated The `ArrayNewFixedInfo` object type is now called {@link expressions.ArrayNewFixed}. */ +export type ArrayNewFixedInfo = expressions.ArrayNewFixed; +/** @deprecated The `ArrayNewDataInfo` object type is now called {@link expressions.ArrayNewData}. */ +export type ArrayNewDataInfo = expressions.ArrayNewData; +/** @deprecated The `ArrayNewElemInfo` object type is now called {@link expressions.ArrayNewElem}. */ +export type ArrayNewElemInfo = expressions.ArrayNewElem; +/** @deprecated The `ArrayGetInfo` object type is now called {@link expressions.ArrayGet}. */ +export type ArrayGetInfo = expressions.ArrayGet; +/** @deprecated The `ArraySetInfo` object type is now called {@link expressions.ArraySet}. */ +export type ArraySetInfo = expressions.ArraySet; +/** @deprecated The `ArrayLenInfo` object type is now called {@link expressions.ArrayLen}. */ +export type ArrayLenInfo = expressions.ArrayLen; +/** @deprecated The `ArrayFillInfo` object type is now called {@link expressions.ArrayFill}. */ +export type ArrayFillInfo = expressions.ArrayFill; +/** @deprecated The `ArrayCopyInfo` object type is now called {@link expressions.ArrayCopy}. */ +export type ArrayCopyInfo = expressions.ArrayCopy; +/** @deprecated The `ArrayInitDataInfo` object type is now called {@link expressions.ArrayInitData}. */ +export type ArrayInitDataInfo = expressions.ArrayInitData; +/** @deprecated The `ArrayInitElemInfo` object type is now called {@link expressions.ArrayInitElem}. */ +export type ArrayInitElemInfo = expressions.ArrayInitElem; /** @deprecated The `ConstInfo` object type is now called {@link expressions.Const}. */ export type ConstInfo = expressions.Const; +/** @deprecated The `UnaryInfo` object type is now called {@link expressions.Unary}. */ +export type UnaryInfo = expressions.Unary; +/** @deprecated The `BinaryInfo` object type is now called {@link expressions.Binary}. */ +export type BinaryInfo = expressions.Binary; +/** @deprecated The `SIMDTernaryInfo` object type is now called {@link expressions.SIMDTernary}. */ +export type SIMDTernaryInfo = expressions.SIMDTernary; +/** @deprecated The `SIMDShiftInfo` object type is now called {@link expressions.SIMDShift}. */ +export type SIMDShiftInfo = expressions.SIMDShift; +/** @deprecated The `SIMDShuffleInfo` object type is now called {@link expressions.SIMDShuffle}. */ +export type SIMDShuffleInfo = expressions.SIMDShuffle; +/** @deprecated The `SIMDExtractInfo` object type is now called {@link expressions.SIMDExtract}. */ +export type SIMDExtractInfo = expressions.SIMDExtract; +/** @deprecated The `SIMDReplaceInfo` object type is now called {@link expressions.SIMDReplace}. */ +export type SIMDReplaceInfo = expressions.SIMDReplace; +/** @deprecated The `AtomicRMWInfo` object type is now called {@link expressions.AtomicRMW}. */ +export type AtomicRMWInfo = expressions.AtomicRMW; +/** @deprecated The `AtomicCmpxchgInfo` object type is now called {@link expressions.AtomicCmpxchg}. */ +export type AtomicCmpxchgInfo = expressions.AtomicCmpxchg; +/** @deprecated The `AtomicWaitInfo` object type is now called {@link expressions.AtomicWait}. */ +export type AtomicWaitInfo = expressions.AtomicWait; +/** @deprecated The `AtomicNotifyInfo` object type is now called {@link expressions.AtomicNotify}. */ +export type AtomicNotifyInfo = expressions.AtomicNotify; +/** @deprecated The `AtomicFenceInfo` object type is now called {@link expressions.AtomicFence}. */ +export type AtomicFenceInfo = expressions.AtomicFence; +/** @deprecated The `StringNewInfo` object type is now called {@link expressions.StringNew}. */ +export type StringNewInfo = expressions.StringNew; +/** @deprecated The `StringConstInfo` object type is now called {@link expressions.StringConst}. */ +export type StringConstInfo = expressions.StringConst; +/** @deprecated The `StringMeasureInfo` object type is now called {@link expressions.StringMeasure}. */ +export type StringMeasureInfo = expressions.StringMeasure; +/** @deprecated The `StringEncodeInfo` object type is now called {@link expressions.StringEncode}. */ +export type StringEncodeInfo = expressions.StringEncode; +/** @deprecated The `StringConcatInfo` object type is now called {@link expressions.StringConcat}. */ +export type StringConcatInfo = expressions.StringConcat; +/** @deprecated The `StringEqInfo` object type is now called {@link expressions.StringEq}. */ +export type StringEqInfo = expressions.StringEq; +/** @deprecated The `StringWTF16GetInfo` object type is now called {@link expressions.StringWTF16Get}. */ +export type StringWTF16GetInfo = expressions.StringWTF16Get; +/** @deprecated The `StringSliceWTFInfo` object type is now called {@link expressions.StringSliceWTF}. */ +export type StringSliceWTFInfo = expressions.StringSliceWTF; +/** @deprecated The `WideIntAddSubInfo` object type is now called {@link expressions.WideIntAddSub}. */ +export type WideIntAddSubInfo = expressions.WideIntAddSub; +/** @deprecated The `WideIntMulInfo` object type is now called {@link expressions.WideIntMul}. */ +export type WideIntMulInfo = expressions.WideIntMul; + + /** @deprecated The `Function` class now lives under the `Module` namespace. Use {@link Module.Function}. */ export const Function = Module.Function; From a6007164745f77aa9e80a07fcd21ced8807e21d4 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 6 Jun 2026 01:02:59 -0400 Subject: [PATCH 240/247] feat: support top-level `ExpressionInfo` subclass deprecations --- ts/src/-deprecations.ts | 167 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index 6707fb88a38..b7de03a270c 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -5,7 +5,7 @@ import { BinaryenObj, } from "./-pre.ts"; -import type * as expressions from "./classes/expression/index.ts"; +import * as expressions from "./classes/expression/index.ts"; import { Feature, Module, @@ -223,6 +223,171 @@ export type WideIntMulInfo = expressions.WideIntMul; +/** @deprecated The `Expression` class now lives under the `expressions` namespace. Use {@link expressions.Expression}. */ +export const Expression = expressions.Expression; +/** @deprecated The `Drop` class now lives under the `expressions` namespace. Use {@link expressions.Drop}. */ +export const Drop = expressions.Drop; +/** @deprecated The `Select` class now lives under the `expressions` namespace. Use {@link expressions.Select}. */ +export const Select = expressions.Select; +/** @deprecated The `Block` class now lives under the `expressions` namespace. Use {@link expressions.Block}. */ +export const Block = expressions.Block; +/** @deprecated The `Loop` class now lives under the `expressions` namespace. Use {@link expressions.Loop}. */ +export const Loop = expressions.Loop; +/** @deprecated The `If` class now lives under the `expressions` namespace. Use {@link expressions.If}. */ +export const If = expressions.If; +/** @deprecated The `Break` class now lives under the `expressions` namespace. Use {@link expressions.Break}. */ +export const Break = expressions.Break; +/** @deprecated The `Switch` class now lives under the `expressions` namespace. Use {@link expressions.Switch}. */ +export const Switch = expressions.Switch; +/** @deprecated The `BrOn` class now lives under the `expressions` namespace. Use {@link expressions.BrOn}. */ +export const BrOn = expressions.BrOn; +/** @deprecated The `Call` class now lives under the `expressions` namespace. Use {@link expressions.Call}. */ +export const Call = expressions.Call; +/** @deprecated The `CallRef` class now lives under the `expressions` namespace. Use {@link expressions.CallRef}. */ +export const CallRef = expressions.CallRef; +/** @deprecated The `CallIndirect` class now lives under the `expressions` namespace. Use {@link expressions.CallIndirect}. */ +export const CallIndirect = expressions.CallIndirect; +/** @deprecated The `Return` class now lives under the `expressions` namespace. Use {@link expressions.Return}. */ +export const Return = expressions.Return; +/** @deprecated The `Throw` class now lives under the `expressions` namespace. Use {@link expressions.Throw}. */ +export const Throw = expressions.Throw; +/** @deprecated The `Rethrow` class now lives under the `expressions` namespace. Use {@link expressions.Rethrow}. */ +export const Rethrow = expressions.Rethrow; +/** @deprecated The `Try` class now lives under the `expressions` namespace. Use {@link expressions.Try}. */ +export const Try = expressions.Try; +/** @deprecated The `LocalGet` class now lives under the `expressions` namespace. Use {@link expressions.LocalGet}. */ +export const LocalGet = expressions.LocalGet; +/** @deprecated The `LocalSet` class now lives under the `expressions` namespace. Use {@link expressions.LocalSet}. */ +export const LocalSet = expressions.LocalSet; +/** @deprecated The `GlobalGet` class now lives under the `expressions` namespace. Use {@link expressions.GlobalGet}. */ +export const GlobalGet = expressions.GlobalGet; +/** @deprecated The `GlobalSet` class now lives under the `expressions` namespace. Use {@link expressions.GlobalSet}. */ +export const GlobalSet = expressions.GlobalSet; +/** @deprecated The `TableGet` class now lives under the `expressions` namespace. Use {@link expressions.TableGet}. */ +export const TableGet = expressions.TableGet; +/** @deprecated The `TableSet` class now lives under the `expressions` namespace. Use {@link expressions.TableSet}. */ +export const TableSet = expressions.TableSet; +/** @deprecated The `TableSize` class now lives under the `expressions` namespace. Use {@link expressions.TableSize}. */ +export const TableSize = expressions.TableSize; +/** @deprecated The `TableGrow` class now lives under the `expressions` namespace. Use {@link expressions.TableGrow}. */ +export const TableGrow = expressions.TableGrow; +/** @deprecated The `Load` class now lives under the `expressions` namespace. Use {@link expressions.Load}. */ +export const Load = expressions.Load; +/** @deprecated The `Store` class now lives under the `expressions` namespace. Use {@link expressions.Store}. */ +export const Store = expressions.Store; +/** @deprecated The `SIMDLoad` class now lives under the `expressions` namespace. Use {@link expressions.SIMDLoad}. */ +export const SIMDLoad = expressions.SIMDLoad; +/** @deprecated The `SIMDLoadStoreLane` class now lives under the `expressions` namespace. Use {@link expressions.SIMDLoadStoreLane}. */ +export const SIMDLoadStoreLane = expressions.SIMDLoadStoreLane; +/** @deprecated The `MemorySize` class now lives under the `expressions` namespace. Use {@link expressions.MemorySize}. */ +export const MemorySize = expressions.MemorySize; +/** @deprecated The `MemoryGrow` class now lives under the `expressions` namespace. Use {@link expressions.MemoryGrow}. */ +export const MemoryGrow = expressions.MemoryGrow; +/** @deprecated The `MemoryFill` class now lives under the `expressions` namespace. Use {@link expressions.MemoryFill}. */ +export const MemoryFill = expressions.MemoryFill; +/** @deprecated The `MemoryCopy` class now lives under the `expressions` namespace. Use {@link expressions.MemoryCopy}. */ +export const MemoryCopy = expressions.MemoryCopy; +/** @deprecated The `MemoryInit` class now lives under the `expressions` namespace. Use {@link expressions.MemoryInit}. */ +export const MemoryInit = expressions.MemoryInit; +/** @deprecated The `DataDrop` class now lives under the `expressions` namespace. Use {@link expressions.DataDrop}. */ +export const DataDrop = expressions.DataDrop; +/** @deprecated The `RefFunc` class now lives under the `expressions` namespace. Use {@link expressions.RefFunc}. */ +export const RefFunc = expressions.RefFunc; +/** @deprecated The `RefIsNull` class now lives under the `expressions` namespace. Use {@link expressions.RefIsNull}. */ +export const RefIsNull = expressions.RefIsNull; +/** @deprecated The `RefAs` class now lives under the `expressions` namespace. Use {@link expressions.RefAs}. */ +export const RefAs = expressions.RefAs; +/** @deprecated The `RefEq` class now lives under the `expressions` namespace. Use {@link expressions.RefEq}. */ +export const RefEq = expressions.RefEq; +/** @deprecated The `RefTest` class now lives under the `expressions` namespace. Use {@link expressions.RefTest}. */ +export const RefTest = expressions.RefTest; +/** @deprecated The `RefCast` class now lives under the `expressions` namespace. Use {@link expressions.RefCast}. */ +export const RefCast = expressions.RefCast; +/** @deprecated The `RefI31` class now lives under the `expressions` namespace. Use {@link expressions.RefI31}. */ +export const RefI31 = expressions.RefI31; +/** @deprecated The `I31Get` class now lives under the `expressions` namespace. Use {@link expressions.I31Get}. */ +export const I31Get = expressions.I31Get; +/** @deprecated The `TupleMake` class now lives under the `expressions` namespace. Use {@link expressions.TupleMake}. */ +export const TupleMake = expressions.TupleMake; +/** @deprecated The `TupleExtract` class now lives under the `expressions` namespace. Use {@link expressions.TupleExtract}. */ +export const TupleExtract = expressions.TupleExtract; +/** @deprecated The `StructNew` class now lives under the `expressions` namespace. Use {@link expressions.StructNew}. */ +export const StructNew = expressions.StructNew; +/** @deprecated The `StructGet` class now lives under the `expressions` namespace. Use {@link expressions.StructGet}. */ +export const StructGet = expressions.StructGet; +/** @deprecated The `StructSet` class now lives under the `expressions` namespace. Use {@link expressions.StructSet}. */ +export const StructSet = expressions.StructSet; +/** @deprecated The `ArrayNew` class now lives under the `expressions` namespace. Use {@link expressions.ArrayNew}. */ +export const ArrayNew = expressions.ArrayNew; +/** @deprecated The `ArrayNewFixed` class now lives under the `expressions` namespace. Use {@link expressions.ArrayNewFixed}. */ +export const ArrayNewFixed = expressions.ArrayNewFixed; +/** @deprecated The `ArrayNewData` class now lives under the `expressions` namespace. Use {@link expressions.ArrayNewData}. */ +export const ArrayNewData = expressions.ArrayNewData; +/** @deprecated The `ArrayNewElem` class now lives under the `expressions` namespace. Use {@link expressions.ArrayNewElem}. */ +export const ArrayNewElem = expressions.ArrayNewElem; +/** @deprecated The `ArrayGet` class now lives under the `expressions` namespace. Use {@link expressions.ArrayGet}. */ +export const ArrayGet = expressions.ArrayGet; +/** @deprecated The `ArraySet` class now lives under the `expressions` namespace. Use {@link expressions.ArraySet}. */ +export const ArraySet = expressions.ArraySet; +/** @deprecated The `ArrayLen` class now lives under the `expressions` namespace. Use {@link expressions.ArrayLen}. */ +export const ArrayLen = expressions.ArrayLen; +/** @deprecated The `ArrayFill` class now lives under the `expressions` namespace. Use {@link expressions.ArrayFill}. */ +export const ArrayFill = expressions.ArrayFill; +/** @deprecated The `ArrayCopy` class now lives under the `expressions` namespace. Use {@link expressions.ArrayCopy}. */ +export const ArrayCopy = expressions.ArrayCopy; +/** @deprecated The `ArrayInitData` class now lives under the `expressions` namespace. Use {@link expressions.ArrayInitData}. */ +export const ArrayInitData = expressions.ArrayInitData; +/** @deprecated The `ArrayInitElem` class now lives under the `expressions` namespace. Use {@link expressions.ArrayInitElem}. */ +export const ArrayInitElem = expressions.ArrayInitElem; +/** @deprecated The `Const` class now lives under the `expressions` namespace. Use {@link expressions.Const}. */ +export const Const = expressions.Const; +/** @deprecated The `Unary` class now lives under the `expressions` namespace. Use {@link expressions.Unary}. */ +export const Unary = expressions.Unary; +/** @deprecated The `Binary` class now lives under the `expressions` namespace. Use {@link expressions.Binary}. */ +export const Binary = expressions.Binary; +/** @deprecated The `SIMDTernary` class now lives under the `expressions` namespace. Use {@link expressions.SIMDTernary}. */ +export const SIMDTernary = expressions.SIMDTernary; +/** @deprecated The `SIMDShift` class now lives under the `expressions` namespace. Use {@link expressions.SIMDShift}. */ +export const SIMDShift = expressions.SIMDShift; +/** @deprecated The `SIMDShuffle` class now lives under the `expressions` namespace. Use {@link expressions.SIMDShuffle}. */ +export const SIMDShuffle = expressions.SIMDShuffle; +/** @deprecated The `SIMDExtract` class now lives under the `expressions` namespace. Use {@link expressions.SIMDExtract}. */ +export const SIMDExtract = expressions.SIMDExtract; +/** @deprecated The `SIMDReplace` class now lives under the `expressions` namespace. Use {@link expressions.SIMDReplace}. */ +export const SIMDReplace = expressions.SIMDReplace; +/** @deprecated The `AtomicRMW` class now lives under the `expressions` namespace. Use {@link expressions.AtomicRMW}. */ +export const AtomicRMW = expressions.AtomicRMW; +/** @deprecated The `AtomicCmpxchg` class now lives under the `expressions` namespace. Use {@link expressions.AtomicCmpxchg}. */ +export const AtomicCmpxchg = expressions.AtomicCmpxchg; +/** @deprecated The `AtomicWait` class now lives under the `expressions` namespace. Use {@link expressions.AtomicWait}. */ +export const AtomicWait = expressions.AtomicWait; +/** @deprecated The `AtomicNotify` class now lives under the `expressions` namespace. Use {@link expressions.AtomicNotify}. */ +export const AtomicNotify = expressions.AtomicNotify; +/** @deprecated The `AtomicFence` class now lives under the `expressions` namespace. Use {@link expressions.AtomicFence}. */ +export const AtomicFence = expressions.AtomicFence; +/** @deprecated The `StringNew` class now lives under the `expressions` namespace. Use {@link expressions.StringNew}. */ +export const StringNew = expressions.StringNew; +/** @deprecated The `StringConst` class now lives under the `expressions` namespace. Use {@link expressions.StringConst}. */ +export const StringConst = expressions.StringConst; +/** @deprecated The `StringMeasure` class now lives under the `expressions` namespace. Use {@link expressions.StringMeasure}. */ +export const StringMeasure = expressions.StringMeasure; +/** @deprecated The `StringEncode` class now lives under the `expressions` namespace. Use {@link expressions.StringEncode}. */ +export const StringEncode = expressions.StringEncode; +/** @deprecated The `StringConcat` class now lives under the `expressions` namespace. Use {@link expressions.StringConcat}. */ +export const StringConcat = expressions.StringConcat; +/** @deprecated The `StringEq` class now lives under the `expressions` namespace. Use {@link expressions.StringEq}. */ +export const StringEq = expressions.StringEq; +/** @deprecated The `StringWTF16Get` class now lives under the `expressions` namespace. Use {@link expressions.StringWTF16Get}. */ +export const StringWTF16Get = expressions.StringWTF16Get; +/** @deprecated The `StringSliceWTF` class now lives under the `expressions` namespace. Use {@link expressions.StringSliceWTF}. */ +export const StringSliceWTF = expressions.StringSliceWTF; +/** @deprecated The `WideIntAddSub` class now lives under the `expressions` namespace. Use {@link expressions.WideIntAddSub}. */ +export const WideIntAddSub = expressions.WideIntAddSub; +/** @deprecated The `WideIntMul` class now lives under the `expressions` namespace. Use {@link expressions.WideIntMul}. */ +export const WideIntMul = expressions.WideIntMul; + + + /** @deprecated The `Function` class now lives under the `Module` namespace. Use {@link Module.Function}. */ export const Function = Module.Function; /** @deprecated The `Table` class now lives under the `Module` namespace. Use {@link Module.Table}. */ From f6d677af74d9d566173d32b67de01ee5b69b3312 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 6 Jun 2026 01:16:26 -0400 Subject: [PATCH 241/247] feat: export non-constructor `Expression` function --- ts/src/-deprecations.ts | 2 -- ts/src/globals.ts | 17 ++++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ts/src/-deprecations.ts b/ts/src/-deprecations.ts index b7de03a270c..b3e424a84e8 100644 --- a/ts/src/-deprecations.ts +++ b/ts/src/-deprecations.ts @@ -223,8 +223,6 @@ export type WideIntMulInfo = expressions.WideIntMul; -/** @deprecated The `Expression` class now lives under the `expressions` namespace. Use {@link expressions.Expression}. */ -export const Expression = expressions.Expression; /** @deprecated The `Drop` class now lives under the `expressions` namespace. Use {@link expressions.Drop}. */ export const Drop = expressions.Drop; /** @deprecated The `Select` class now lives under the `expressions` namespace. Use {@link expressions.Select}. */ diff --git a/ts/src/globals.ts b/ts/src/globals.ts index ad4f01a1832..9f9ba93a5e1 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -288,13 +288,24 @@ export function getExpressionType(expr: ExpressionRef): Type { return BinaryenObj["_BinaryenExpressionGetType"](expr); } +/** + * Creates a new Expression object given an ExpressionRef argument. + * This function is called without `new`. + * You may also use the constructor `new expressions.Expression()`, + * or a specific subclass of it. + * @see {@link expressions.Expression} + */ +export function Expression(expr: ExpressionRef): expressions.Expression { + const id = getExpressionId(expr); + const specificExpression = EXPRESSION_TYPE_REGISTRY.get(id); + return specificExpression ? new specificExpression(expr) : new expressions.Expression(id, expr); +} + /** * Obtains information about an expression. * Additional properties depend on the expression’s ID * and are usually equivalent to the respective parameters when creating such an expression. */ export function getExpressionInfo(expr: ExpressionRef): expressions.Expression { - const id = getExpressionId(expr); - const specificExpression = EXPRESSION_TYPE_REGISTRY.get(id); - return specificExpression ? new specificExpression(expr) : new expressions.Expression(id, expr); + return Expression(expr); } From ab0e5398aaa5fd0bb55be1f13a0dd0ea497a19bd Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 6 Jun 2026 01:16:59 -0400 Subject: [PATCH 242/247] fix: `getExpressionInfo` returns json --- ts/src/globals.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 9f9ba93a5e1..579d16a337c 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -306,6 +306,6 @@ export function Expression(expr: ExpressionRef): expressions.Expression { * Additional properties depend on the expression’s ID * and are usually equivalent to the respective parameters when creating such an expression. */ -export function getExpressionInfo(expr: ExpressionRef): expressions.Expression { - return Expression(expr); +export function getExpressionInfo(expr: ExpressionRef): Record { + return Expression(expr).toJson(); } From 60e59d14c69f769c2c694ad28531b2e326187120 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 6 Jun 2026 02:25:11 -0400 Subject: [PATCH 243/247] docs: fix expression constructors --- ts/src/classes/expression/Expression.ts | 4 ++-- ts/src/globals.ts | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ts/src/classes/expression/Expression.ts b/ts/src/classes/expression/Expression.ts index 83166bb244d..812e29144bc 100644 --- a/ts/src/classes/expression/Expression.ts +++ b/ts/src/classes/expression/Expression.ts @@ -23,7 +23,7 @@ export class Expression { /** * Construct a new Expression object given an ID and reference. * - * Without an ID, you can still call {@link getExpressionInfo | `getExpressionInfo(expr)`}, + * Without an ID, you can still call {@link Expression | `Expression(expr)`} (without `new`), * which will compute the ID and construct an Expression object from there. * @param exprId the expression “kind” id * @param expr the expression reference @@ -52,7 +52,7 @@ export class Expression { * Adds to this object enumerable own properties that are computed from getter methods. * Useful when calling `JSON.stringify`: * ```ts - * JSON.stringify(exprInfo.toJson()); + * JSON.stringify(this.toJson()); * ``` */ toJson(): Record { diff --git a/ts/src/globals.ts b/ts/src/globals.ts index 579d16a337c..6815a242ea0 100644 --- a/ts/src/globals.ts +++ b/ts/src/globals.ts @@ -290,6 +290,7 @@ export function getExpressionType(expr: ExpressionRef): Type { /** * Creates a new Expression object given an ExpressionRef argument. + * * This function is called without `new`. * You may also use the constructor `new expressions.Expression()`, * or a specific subclass of it. @@ -303,6 +304,7 @@ export function Expression(expr: ExpressionRef): expressions.Expression { /** * Obtains information about an expression. + * * Additional properties depend on the expression’s ID * and are usually equivalent to the respective parameters when creating such an expression. */ From cc9943b6419dc7909265d7ea7c11bac5bfc4a702 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 6 Jun 2026 10:53:31 -0400 Subject: [PATCH 244/247] build: update package.json - `repository.url` was missing "git+" - adds "prepublishOnly" script - updates "files" field to include `./build/` - `package.json` is included by default - `package-lock.json` is excluded by default --- ts/package.json | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ts/package.json b/ts/package.json index 64e91d7ba87..20e9e1d7743 100644 --- a/ts/package.json +++ b/ts/package.json @@ -5,7 +5,7 @@ "license": "Apache-2.0", "repository": { "type": "git", - "url": "https://github.com/WebAssembly/binaryen.git" + "url": "git+https://github.com/WebAssembly/binaryen.git" }, "keywords": [ "webassembly", @@ -24,14 +24,10 @@ "docs": "rm -rf ../docs/binaryen.ts/ && typedoc", "test": "tsx --test -- './test/**/*.test.ts'", "test:only": "tsx --test --test-only -- './test/**/*.test.ts'", - "build": "npm run compile && npm run lint && npm run docs && npm run test" + "build": "npm run compile && npm run lint && npm run docs && npm run test", + "prepublishOnly": "npm run make && npm run check && npm run build" }, - "files": [ - "package.json", - "package-lock.json", - "./dist/*.d.ts", - "./dist/*.js" - ], + "files": ["./build/", "./dist/"], "imports": { "#binaryen-raw": { "types": "./src/types/binaryen_js.d.ts", From ca6d4adafccfe0c3ed6b9185f8ce57e3579bf676 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 6 Jun 2026 02:39:25 -0400 Subject: [PATCH 245/247] docs: update readme --- ts/README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ts/README.md b/ts/README.md index 86bbf9890af..7e30757f5c7 100644 --- a/ts/README.md +++ b/ts/README.md @@ -43,10 +43,16 @@ From the repo’s root: ```zsh $ cd ./ts/ $ npm ci -$ npm run build +$ npm run prepublishOnly # gets the package in working order ``` ### Pipeline +#### Set Up the Emscripten Build +You’ll need to do this whenever pulling changes from the C++ repo. +```zsh +$ npm run make # emits Emscripten builds to ./build/ +``` + #### Develop in TypeScript The core of this project is written in [TS](https://www.typescriptlang.org/), best paired with a powerful editor and some nice extensions. ```zsh @@ -99,16 +105,15 @@ $ git push #### Run Tests The test suite is still in progress, migrating from `../test/binaryen.js/`. -The new test suite uses the Node v26+ test runner. +The new test suite uses the Node v22+ test runner. ```zsh $ npm run test ``` #### Bundle TypeScript only compiles the source files to `./dist/`. -After that we need a bundler to optimize and minify it into one giant JS file, -which will then get processed with Emscripten’s build so that it can be used by consumers. -This will look a lot like AssemblyScript’s build process. +After that we may need a bundler to optimize and minify it into a prepackaged file, +which will be able to target different platforms so that it can be used by consumers. TODO: more details From 4b53fef62753900a325793a124f4e687e3f85ab1 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Wed, 10 Jun 2026 16:00:30 -0400 Subject: [PATCH 246/247] docs: include version in generated docs --- ts/typedoc.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ts/typedoc.config.js b/ts/typedoc.config.js index 13746415bcf..877ce548b5a 100644 --- a/ts/typedoc.config.js +++ b/ts/typedoc.config.js @@ -3,6 +3,8 @@ export default { entryPoints: ["./src/binaryen.ts"], projectDocuments: ["./docs/API-Overview.md"], useFirstParagraphOfCommentAsSummary: true, + includeVersion: true, + gitRevision: "gh-pages", out: "../docs/binaryen.ts/", githubPages: false, // when `false`, does not generate a `.nojekyll` file to prevent GitHub Pages from using Jekyll customCss: "./docs/styles.css", From 4cfccbd077ecec1bc812cc264e24f158f5cb3642 Mon Sep 17 00:00:00 2001 From: Chris Harvey <1362083+chharvey@users.noreply.github.com> Date: Sat, 13 Jun 2026 12:13:31 -0400 Subject: [PATCH 247/247] lint: format json files --- ts/.editorconfig | 2 +- ts/package.json | 5 ++++- ts/test/tsconfig.json | 24 ++++++++++++++---------- ts/tsconfig.json | 42 ++++++++++++++++++++++-------------------- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/ts/.editorconfig b/ts/.editorconfig index 555ff2e4735..b5cca5a493c 100644 --- a/ts/.editorconfig +++ b/ts/.editorconfig @@ -11,6 +11,6 @@ insert_final_newline = true max_line_length = off trim_trailing_whitespace = true -[**/package{,-lock}.json] +[**/*.json] indent_size = 2 indent_style = space diff --git a/ts/package.json b/ts/package.json index 20e9e1d7743..b98a0062a0c 100644 --- a/ts/package.json +++ b/ts/package.json @@ -27,7 +27,10 @@ "build": "npm run compile && npm run lint && npm run docs && npm run test", "prepublishOnly": "npm run make && npm run check && npm run build" }, - "files": ["./build/", "./dist/"], + "files": [ + "./build/", + "./dist/" + ], "imports": { "#binaryen-raw": { "types": "./src/types/binaryen_js.d.ts", diff --git a/ts/test/tsconfig.json b/ts/test/tsconfig.json index ac7d15ce09e..f43565f788a 100644 --- a/ts/test/tsconfig.json +++ b/ts/test/tsconfig.json @@ -1,13 +1,17 @@ { - "extends": "../tsconfig.json", - "compilerOptions": { - // Modules - "module": "nodenext", - "rootDir": "../", - "types": ["node"], + "extends": "../tsconfig.json", + "compilerOptions": { + // Modules + "module": "nodenext", + "rootDir": "../", + "types": [ + "node" + ], - // Emit - "noEmit": true, - }, - "include": ["./"], + // Emit + "noEmit": true, + }, + "include": [ + "./" + ], } diff --git a/ts/tsconfig.json b/ts/tsconfig.json index ffcee485644..b6f7d9edb29 100644 --- a/ts/tsconfig.json +++ b/ts/tsconfig.json @@ -1,26 +1,28 @@ { - // TSConfig: https://www.typescriptlang.org/tsconfig/ - "compilerOptions": { - // Type Checking - "exactOptionalPropertyTypes": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noPropertyAccessFromIndexSignature": true, + // TSConfig: https://www.typescriptlang.org/tsconfig/ + "compilerOptions": { + // Type Checking + "exactOptionalPropertyTypes": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noPropertyAccessFromIndexSignature": true, - // Modules - "module": "esnext", - "rewriteRelativeImportExtensions": true, - "rootDir": "./src/", + // Modules + "module": "esnext", + "rewriteRelativeImportExtensions": true, + "rootDir": "./src/", - // Emit - "declaration": true, - "outDir": "./dist/", + // Emit + "declaration": true, + "outDir": "./dist/", - // Interop Constraints - "verbatimModuleSyntax": true, + // Interop Constraints + "verbatimModuleSyntax": true, - // Completeness - "skipLibCheck": true, - }, - "include": ["./src/"], + // Completeness + "skipLibCheck": true, + }, + "include": [ + "./src/" + ], }