diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /js/src/jit-test/lib/wasm-binary.js | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | js/src/jit-test/lib/wasm-binary.js | 555 |
1 files changed, 555 insertions, 0 deletions
diff --git a/js/src/jit-test/lib/wasm-binary.js b/js/src/jit-test/lib/wasm-binary.js new file mode 100644 index 0000000000..93ddc0571d --- /dev/null +++ b/js/src/jit-test/lib/wasm-binary.js @@ -0,0 +1,555 @@ +// MagicNumber = 0x6d736100; +const magic0 = 0x00; // '\0' +const magic1 = 0x61; // 'a' +const magic2 = 0x73; // 's' +const magic3 = 0x6d; // 'm' + +// EncodingVersion +const encodingVersion = 0x1; +const ver0 = (encodingVersion >>> 0) & 0xff; +const ver1 = (encodingVersion >>> 8) & 0xff; +const ver2 = (encodingVersion >>> 16) & 0xff; +const ver3 = (encodingVersion >>> 24) & 0xff; + +// Section opcodes +const userDefinedId = 0; +const typeId = 1; +const importId = 2; +const functionId = 3; +const tableId = 4; +const memoryId = 5; +const globalId = 6; +const exportId = 7; +const startId = 8; +const elemId = 9; +const codeId = 10; +const dataId = 11; +const dataCountId = 12; +const tagId = 13; + +// User-defined section names +const nameName = "name"; + +// Name section name types +const nameTypeModule = 0; +const nameTypeFunction = 1; +const nameTypeLocal = 2; +const nameTypeTag = 3; + +// Type codes +const I32Code = 0x7f; +const I64Code = 0x7e; +const F32Code = 0x7d; +const F64Code = 0x7c; +const V128Code = 0x7b; +const AnyFuncCode = 0x70; +const ExternRefCode = 0x6f; +const EqRefCode = 0x6d; +const OptRefCode = 0x6c; +const FuncCode = 0x60; +const VoidCode = 0x40; + +// Opcodes +const UnreachableCode = 0x00 +const BlockCode = 0x02; +const TryCode = 0x06; +const CatchCode = 0x07; +const ThrowCode = 0x08; +const RethrowCode = 0x09; +const EndCode = 0x0b; +const ReturnCode = 0x0f; +const CallCode = 0x10; +const CallIndirectCode = 0x11; +const DelegateCode = 0x18; +const DropCode = 0x1a; +const SelectCode = 0x1b; +const LocalGetCode = 0x20; +const I32Load = 0x28; +const I64Load = 0x29; +const F32Load = 0x2a; +const F64Load = 0x2b; +const I32Load8S = 0x2c; +const I32Load8U = 0x2d; +const I32Load16S = 0x2e; +const I32Load16U = 0x2f; +const I64Load8S = 0x30; +const I64Load8U = 0x31; +const I64Load16S = 0x32; +const I64Load16U = 0x33; +const I64Load32S = 0x34; +const I64Load32U = 0x35; +const I32Store = 0x36; +const I64Store = 0x37; +const F32Store = 0x38; +const F64Store = 0x39; +const I32Store8 = 0x3a; +const I32Store16 = 0x3b; +const I64Store8 = 0x3c; +const I64Store16 = 0x3d; +const I64Store32 = 0x3e; +const GrowMemoryCode = 0x40; +const I32ConstCode = 0x41; +const I64ConstCode = 0x42; +const F32ConstCode = 0x43; +const F64ConstCode = 0x44; +const I32AddCode = 0x6a; +const I32DivSCode = 0x6d; +const I32DivUCode = 0x6e; +const I32RemSCode = 0x6f; +const I32RemUCode = 0x70; +const I32TruncSF32Code = 0xa8; +const I32TruncUF32Code = 0xa9; +const I32TruncSF64Code = 0xaa; +const I32TruncUF64Code = 0xab; +const I64TruncSF32Code = 0xae; +const I64TruncUF32Code = 0xaf; +const I64TruncSF64Code = 0xb0; +const I64TruncUF64Code = 0xb1; +const I64DivSCode = 0x7f; +const I64DivUCode = 0x80; +const I64RemSCode = 0x81; +const I64RemUCode = 0x82; +const RefNullCode = 0xd0; +const RefIsNullCode = 0xd1; +const RefFuncCode = 0xd2; + +// SIMD opcodes +const V128LoadCode = 0x00; +const V128StoreCode = 0x0b; +const I32x4DotSI16x8Code = 0xba; +const F32x4CeilCode = 0xd8; +const F32x4FloorCode = 0xd9; +const F32x4TruncCode = 0xda; +const F32x4NearestCode = 0xdb; +const F64x2CeilCode = 0xdc; +const F64x2FloorCode = 0xdd; +const F64x2TruncCode = 0xde; +const F64x2NearestCode = 0xdf; +const F32x4PMinCode = 0xea; +const F32x4PMaxCode = 0xeb; +const F64x2PMinCode = 0xf6; +const F64x2PMaxCode = 0xf7; +const V128Load32ZeroCode = 0xfc; +const V128Load64ZeroCode = 0xfd; + +// Relaxed SIMD opcodes. +const I8x16RelaxedSwizzleCode = 0x100; +const I32x4RelaxedTruncSSatF32x4Code = 0x101; +const I32x4RelaxedTruncUSatF32x4Code = 0x102; +const I32x4RelaxedTruncSatF64x2SZeroCode = 0x103; +const I32x4RelaxedTruncSatF64x2UZeroCode = 0x104; +const F32x4RelaxedFmaCode = 0x105; +const F32x4RelaxedFnmaCode = 0x106; +const F64x2RelaxedFmaCode = 0x107; +const F64x2RelaxedFnmaCode = 0x108; +const I8x16RelaxedLaneSelectCode = 0x109; +const I16x8RelaxedLaneSelectCode = 0x10a; +const I32x4RelaxedLaneSelectCode = 0x10b; +const I64x2RelaxedLaneSelectCode = 0x10c; +const F32x4RelaxedMinCode = 0x10d; +const F32x4RelaxedMaxCode = 0x10e; +const F64x2RelaxedMinCode = 0x10f; +const F64x2RelaxedMaxCode = 0x110; +const I16x8RelaxedQ15MulrS = 0x111; +const I16x8DotI8x16I7x16S = 0x112; +const I32x4DotI8x16I7x16AddS = 0x113; + +const FirstInvalidOpcode = 0xc5; +const LastInvalidOpcode = 0xfa; +const GcPrefix = 0xfb; +const MiscPrefix = 0xfc; +const SimdPrefix = 0xfd; +const ThreadPrefix = 0xfe; +const MozPrefix = 0xff; + +// See WasmConstants.h for documentation. +// Limit this to a group of 8 per line. + +const definedOpcodes = + [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + ...(wasmExceptionsEnabled() ? [0x06, 0x07, 0x08, 0x09] : []), + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, + ...(wasmFunctionReferencesEnabled() ? [0x14] : []), + ...(wasmExceptionsEnabled() ? [0x18, 0x19] : []), + 0x1a, 0x1b, 0x1c, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, + 0xf0, + 0xfb, 0xfc, 0xfd, 0xfe, 0xff ]; + +const undefinedOpcodes = (function () { + let a = []; + let j = 0; + let i = 0; + while (i < 256) { + while (definedOpcodes[j] > i) + a.push(i++); + assertEq(definedOpcodes[j], i); + i++; + j++; + } + assertEq(definedOpcodes.length + a.length, 256); + return a; +})(); + +// Secondary opcode bytes for misc prefix +const MemoryInitCode = 0x08; // Pending +const DataDropCode = 0x09; // Pending +const MemoryCopyCode = 0x0a; // Pending +const MemoryFillCode = 0x0b; // Pending +const TableInitCode = 0x0c; // Pending +const ElemDropCode = 0x0d; // Pending +const TableCopyCode = 0x0e; // Pending + +const StructNew = 0x00; // UNOFFICIAL +const StructGet = 0x03; // UNOFFICIAL +const StructSet = 0x06; // UNOFFICIAL + +// DefinitionKind +const FunctionCode = 0x00; +const TableCode = 0x01; +const MemoryCode = 0x02; +const GlobalCode = 0x03; +const TagCode = 0x04; + +// ResizableFlags +const HasMaximumFlag = 0x1; + +function toU8(array) { + for (let b of array) + assertEq(b < 256, true); + return Uint8Array.from(array); +} + +function varU32(u32) { + assertEq(u32 >= 0, true); + assertEq(u32 < Math.pow(2,32), true); + var bytes = []; + do { + var byte = u32 & 0x7f; + u32 >>>= 7; + if (u32 != 0) + byte |= 0x80; + bytes.push(byte); + } while (u32 != 0); + return bytes; +} + +function varS32(s32) { + assertEq(s32 >= -Math.pow(2,31), true); + assertEq(s32 < Math.pow(2,31), true); + var bytes = []; + do { + var byte = s32 & 0x7f; + s32 >>= 7; + if (s32 != 0 && s32 != -1) + byte |= 0x80; + bytes.push(byte); + } while (s32 != 0 && s32 != -1); + return bytes; +} + +function moduleHeaderThen(...rest) { + return [magic0, magic1, magic2, magic3, ver0, ver1, ver2, ver3, ...rest]; +} + +function string(name) { + var nameBytes = name.split('').map(c => { + var code = c.charCodeAt(0); + assertEq(code < 128, true); // TODO + return code + }); + return varU32(nameBytes.length).concat(nameBytes); +} + +function encodedString(name, len) { + var name = unescape(encodeURIComponent(name)); // break into string of utf8 code points + var nameBytes = name.split('').map(c => c.charCodeAt(0)); // map to array of numbers + return varU32(len === undefined ? nameBytes.length : len).concat(nameBytes); +} + +function moduleWithSections(sectionArray) { + var bytes = moduleHeaderThen(); + for (let section of sectionArray) { + bytes.push(section.name); + bytes.push(...varU32(section.body.length)); + bytes.push(...section.body); + } + return toU8(bytes); +} + +function sigSection(sigs) { + var body = []; + body.push(...varU32(sigs.length)); + for (let sig of sigs) { + body.push(...varU32(FuncCode)); + body.push(...varU32(sig.args.length)); + for (let arg of sig.args) + body.push(...varU32(arg)); + if (sig.ret == VoidCode) { + body.push(...varU32(0)); + } else if (typeof sig.ret == "number") { + body.push(...varU32(1)); + body.push(...varU32(sig.ret)); + } else { + body.push(...varU32(sig.ret.length)); + for (let r of sig.ret) + body.push(...varU32(r)); + } + } + return { name: typeId, body }; +} + +function declSection(decls) { + var body = []; + body.push(...varU32(decls.length)); + for (let decl of decls) + body.push(...varU32(decl)); + return { name: functionId, body }; +} + +function funcBody(func, withEndCode=true) { + var body = varU32(func.locals.length); + for (let local of func.locals) + body.push(...varU32(local)); + body = body.concat(...func.body); + if (withEndCode) + body.push(EndCode); + body.splice(0, 0, ...varU32(body.length)); + return body; +} + +function bodySection(bodies) { + var body = varU32(bodies.length).concat(...bodies); + return { name: codeId, body }; +} + +function importSection(imports) { + var body = []; + body.push(...varU32(imports.length)); + for (let imp of imports) { + body.push(...string(imp.module)); + body.push(...string(imp.func)); + body.push(...varU32(FunctionCode)); + body.push(...varU32(imp.sigIndex)); + } + return { name: importId, body }; +} + +function exportSection(exports) { + var body = []; + body.push(...varU32(exports.length)); + for (let exp of exports) { + body.push(...string(exp.name)); + if (exp.hasOwnProperty("funcIndex")) { + body.push(...varU32(FunctionCode)); + body.push(...varU32(exp.funcIndex)); + } else if (exp.hasOwnProperty("memIndex")) { + body.push(...varU32(MemoryCode)); + body.push(...varU32(exp.memIndex)); + } else if (exp.hasOwnProperty("tagIndex")) { + body.push(...varU32(TagCode)); + body.push(...varU32(exp.tagIndex)); + } else { + throw "Bad export " + exp; + } + } + return { name: exportId, body }; +} + +function tableSection(initialSize) { + var body = []; + body.push(...varU32(1)); // number of tables + body.push(...varU32(AnyFuncCode)); + body.push(...varU32(0x0)); // for now, no maximum + body.push(...varU32(initialSize)); + return { name: tableId, body }; +} + +function memorySection(initialSize) { + var body = []; + body.push(...varU32(1)); // number of memories + body.push(...varU32(0x0)); // for now, no maximum + body.push(...varU32(initialSize)); + return { name: memoryId, body }; +} + +function tagSection(tags) { + var body = []; + body.push(...varU32(tags.length)); + for (let tag of tags) { + body.push(...varU32(0)); // exception attribute + body.push(...varU32(tag.type)); + } + return { name: tagId, body }; +} + +function dataSection(segmentArrays) { + var body = []; + body.push(...varU32(segmentArrays.length)); + for (let array of segmentArrays) { + body.push(...varU32(0)); // table index + body.push(...varU32(I32ConstCode)); + body.push(...varS32(array.offset)); + body.push(...varU32(EndCode)); + body.push(...varU32(array.elems.length)); + for (let elem of array.elems) + body.push(...varU32(elem)); + } + return { name: dataId, body }; +} + +function dataCountSection(count) { + var body = []; + body.push(...varU32(count)); + return { name: dataCountId, body }; +} + +function globalSection(globalArray) { + var body = []; + body.push(...varU32(globalArray.length)); + for (let globalObj of globalArray) { + // Value type + body.push(...varU32(globalObj.valType)); + // Flags + body.push(globalObj.flags & 255); + // Initializer expression + body.push(...globalObj.initExpr); + } + return { name: globalId, body }; +} + +function elemSection(elemArrays) { + var body = []; + body.push(...varU32(elemArrays.length)); + for (let array of elemArrays) { + body.push(...varU32(0)); // table index + body.push(...varU32(I32ConstCode)); + body.push(...varS32(array.offset)); + body.push(...varU32(EndCode)); + body.push(...varU32(array.elems.length)); + for (let elem of array.elems) + body.push(...varU32(elem)); + } + return { name: elemId, body }; +} + +// For now, the encoding spec is here: +// https://github.com/WebAssembly/bulk-memory-operations/issues/98#issuecomment-507330729 + +const LegacyActiveExternVal = 0; +const PassiveExternVal = 1; +const ActiveExternVal = 2; +const DeclaredExternVal = 3; +const LegacyActiveElemExpr = 4; +const PassiveElemExpr = 5; +const ActiveElemExpr = 6; +const DeclaredElemExpr = 7; + +function generalElemSection(elemObjs) { + let body = []; + body.push(...varU32(elemObjs.length)); + for (let elemObj of elemObjs) { + body.push(elemObj.flag); + if ((elemObj.flag & 3) == 2) + body.push(...varU32(elemObj.table)); + // TODO: This is not very flexible + if ((elemObj.flag & 1) == 0) { + body.push(...varU32(I32ConstCode)); + body.push(...varS32(elemObj.offset)); + body.push(...varU32(EndCode)); + } + if (elemObj.flag & 4) { + if (elemObj.flag & 3) + body.push(elemObj.typeCode & 255); + // Each element is an array of bytes + body.push(...varU32(elemObj.elems.length)); + for (let elemBytes of elemObj.elems) + body.push(...elemBytes); + } else { + if (elemObj.flag & 3) + body.push(elemObj.externKind & 255); + // Each element is a putative function index + body.push(...varU32(elemObj.elems.length)); + for (let elem of elemObj.elems) + body.push(...varU32(elem)); + } + } + return { name: elemId, body }; +} + +function moduleNameSubsection(moduleName) { + var body = []; + body.push(...varU32(nameTypeModule)); + + var subsection = encodedString(moduleName); + body.push(...varU32(subsection.length)); + body.push(...subsection); + + return body; +} + +function funcNameSubsection(funcNames) { + var body = []; + body.push(...varU32(nameTypeFunction)); + + var subsection = varU32(funcNames.length); + + var funcIndex = 0; + for (let f of funcNames) { + subsection.push(...varU32(f.index ? f.index : funcIndex)); + subsection.push(...encodedString(f.name, f.nameLen)); + funcIndex++; + } + + body.push(...varU32(subsection.length)); + body.push(...subsection); + return body; +} + +function nameSection(subsections) { + var body = []; + body.push(...string(nameName)); + + for (let ss of subsections) + body.push(...ss); + + return { name: userDefinedId, body }; +} + +function customSection(name, ...body) { + return { name: userDefinedId, body: [...string(name), ...body] }; +} + +function tableSection0() { + var body = []; + body.push(...varU32(0)); // number of tables + return { name: tableId, body }; +} + +function memorySection0() { + var body = []; + body.push(...varU32(0)); // number of memories + return { name: memoryId, body }; +} |