From b68a2276f55a6cb4c97c92fa6a31016aa16316f5 Mon Sep 17 00:00:00 2001 From: Sergey Kuznetsov Date: Thu, 10 Sep 2026 17:52:39 +0100 Subject: [PATCH] Comment test to make clang-tidy happy --- src/test/app/Wasm_test.cpp | 3027 +++++++++++++++++++----------------- 1 file changed, 1593 insertions(+), 1434 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 3706428098..65fe61e56f 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -1,1434 +1,1593 @@ -#if 0 -#include -#ifdef _DEBUG -// #define DEBUG_OUTPUT 1 -#endif - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace xrpl::test { - -std::vector -hexToBytes(std::string const& hex) -{ - auto const ws = boost::algorithm::unhex(hex); - return Bytes(ws.begin(), ws.end()); -} - -template -unsigned -uleb128(IT& it, T val) -{ - unsigned count = 0; - do - { - std::uint8_t byte = val & 0x7f; - val >>= 7; - if (val) - byte |= 0x80; - *it++ = byte; - ++count; - } while (val != 0); - - return count; -} - -template -std::pair -uleb128(IT&& it) -{ - static_assert(sizeof(*it) == 1, "invalid iterator type"); - std::uint64_t val = 0; - std::uint64_t byte = 0; - unsigned shift = 0; - unsigned count = 0; - - do - { - if (shift > (sizeof(std::uint64_t) * 8) - 7) - return {0, 0}; - byte = *it++; - val |= (byte & 0x7F) << shift; - shift += 7; - ++count; - } while (byte >= 0x80); - - return {val, count}; -} - -// TODO: broken, fix after Rust re-arch. Only used by testImpExp, which is disabled -// below; kept (and kept compiling out) so it comes back with that test. -/* -static std::pair -getSection(Bytes const& module, std::uint8_t n) -{ - static std::uint8_t const kHdr[] = {0x00, 0x61, 0x73, 0x6D}; - static std::uint8_t const kVer[] = {0x01, 0x00, 0x00, 0x00}; - static std::uint8_t const kLastSec = 12; - - // sections: - // 0: "Custom", 1: "Type", 2: "Import", 3: "Function", 4: "Table", 5: "Memory", 6: "Global", - // 7: "Export", 8: "Start", 9: "Element", 10: "Code", 11: "Data", 12: "DataCount" - - if (module.size() < sizeof(kHdr) + sizeof(kVer) + 2) - return {0, 0}; - if (memcmp(module.data(), kHdr, sizeof(kHdr)) != 0) - return {0, 0}; - if (memcmp(module.data() + sizeof(kHdr), kVer, sizeof(kVer)) != 0) - return {0, 0}; - - unsigned pos = sizeof(kHdr) + sizeof(kVer); // sections start - for (; pos < module.size();) - { - auto const start = pos; - std::uint8_t const byte = module[pos++]; - if (byte > kLastSec) - return {0, 0}; - - auto [sz, cnt] = uleb128(module.cbegin() + pos); - if (cnt == 0u) - return {0, 0}; - if (pos + cnt + sz > module.size()) - return {0, 0}; - pos += cnt + sz; - - if (byte == n) - return {start, pos}; - } - return {0, 0}; -} -*/ - -static std::optional -runFinish(std::string const& code) -{ - auto const wasm = hexToBytes(code); - HostFunctions hfs; - auto const re = runEscrowWasm(wasm, hfs, 10'000'000, escrowFunctionName); - if (re.has_value()) - { - return std::optional(re->result); - } - - return std::nullopt; -} - -static bool -finishFunctionReturns(std::string const& code, int32_t expected) -{ - auto const result = runFinish(code); - return result.has_value() && *result == expected; -} - -struct Wasm_test : public beast::unit_test::Suite -{ - void - checkResult( - std::expected, WasmTER> re, - int32_t expectedResult, - int64_t expectedCost, - std::source_location const location = std::source_location::current()) - { - auto const lineStr = " (" + std::to_string(location.line()) + ")"; - if (BEAST_EXPECTS(re.has_value(), transToken(re.error().ter) + lineStr)) - { - BEAST_EXPECTS(re->result == expectedResult, std::to_string(re->result) + lineStr); - BEAST_EXPECTS(re->cost == expectedCost, std::to_string(re->cost) + lineStr); - } - } - - void - testBadWasm() - { - testcase("bad wasm test"); - - using namespace test::jtx; - - Env const env{*this}; - HostFunctions hfs(env.journal); - - { - auto wasm = hexToBytes("00000000"); - std::string const funcName("mock_escrow"); - - auto re = runEscrowWasm(wasm, hfs, 15, funcName); - BEAST_EXPECT(!re); - } - - { - auto wasm = hexToBytes("00112233445566778899AA"); - std::string const funcName("mock_escrow"); - - auto const re = preflightEscrowWasm(wasm, env.journal, funcName); - BEAST_EXPECT(!isTesSuccess(re)); - } - - { - // Bytecode wrong function name - // pub fn bad() -> bool { - // unsafe { host_lib::getLedgerSqn() >= 5 } - // } - auto const badWasm = hexToBytes( - "0061736d010000000105016000017f02190108686f73745f6c69620c6765" - "744c656467657253716e00000302010005030100100611027f00418080c0" - "000b7f00418080c0000b072b04066d656d6f727902000362616400010a5f" - "5f646174615f656e6403000b5f5f686561705f6261736503010a09010700" - "100041044a0b004d0970726f64756365727302086c616e67756167650104" - "52757374000c70726f6365737365642d6279010572757374631d312e3835" - "2e31202834656231363132353020323032352d30332d31352900490f7461" - "726765745f6665617475726573042b0f6d757461626c652d676c6f62616c" - "732b087369676e2d6578742b0f7265666572656e63652d74797065732b0a" - "6d756c746976616c7565"); - - auto const re = preflightEscrowWasm(badWasm, env.journal, escrowFunctionName); - BEAST_EXPECT(!isTesSuccess(re)); - } - } - - // TODO: broken, fix after Rust re-arch. Both tests drive WasmEngine directly: - // testImpExp installs individually-priced imports via ImportVec/WASM_IMPORT_FUNC2, - // and both call arbitrary exports with parameters. runEscrowWasm calls a single - // export and takes no parameters, so neither can be expressed against it. - /* - void - testImpExp() - { - testcase("Wasm import/export functions"); - - auto impExpWasm = hexToBytes(kImpExpHex); - - using namespace test::jtx; - - Env env{*this}; - TestLedgerDataProvider hfs(env); - ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs, 33); - WASM_IMPORT_FUNC2(imports, getParentLedgerHash, "get_parent_ledger_hash", hfs, 60); - auto& engine = WasmEngine::instance(); - - // Test exp_func1() - should return 1 - auto re = engine.run(impExpWasm, hfs, 1'000'000, "exp_func1", {}, imports, env.journal); - checkResult(re, 1, 30); - - // Test exp_func2(5) - should return 2 * 5 = 10 - re = engine.run( - impExpWasm, hfs, 1'000'000, "exp_func2", wasmParams(5), imports, env.journal); - checkResult(re, 10, 52); - - // Test test_imports() - should call get_ledger_sqn and get_parent_ledger_hash - re = engine.run(impExpWasm, hfs, 1'000'000, "test_imports", {}, imports, env.journal); - // Should return the ledger sequence number (3 by default in test env) - checkResult(re, 3, 294); - - // Test corrupted import/export sections - invert each byte and expect failure - testcase("Wasm import/export section corruption"); - { - // Import section(#2): bytes [26, 79) - 53 bytes - // Export section(#7): bytes [90, 141) - 51 bytes - auto [importStart, importEnd] = getSection(impExpWasm, 2); - auto [exportStart, exportEnd] = getSection(impExpWasm, 7); - - BEAST_EXPECTS(importStart == 26, std::to_string(importStart)); - BEAST_EXPECTS(importEnd == 79, std::to_string(importEnd)); - BEAST_EXPECTS(exportStart == 90, std::to_string(exportStart)); - BEAST_EXPECTS(exportEnd == 141, std::to_string(exportEnd)); - - auto testInv = [&](unsigned i) { - auto corruptedWasm = impExpWasm; - corruptedWasm[i] = ~corruptedWasm[i]; // Invert byte - - // Try to run any function - should fail due to corruption - auto result = engine.run( - corruptedWasm, hfs, 1'000'000, "exp_func1", {}, imports, env.journal); - BEAST_EXPECT(!result); - }; - - // Test each byte in import section - for (unsigned i = importStart; i < importEnd; ++i) - testInv(i); - - // Test each byte in export section - for (unsigned i = exportStart; i < exportEnd; ++i) - testInv(i); - } - - env.close(); - } - - void - testWasmFib() - { - testcase("Wasm fibo"); - - auto const fibWasm = hexToBytes(kFibWasmHex); - auto& engine = WasmEngine::instance(); - HostFunctions hfs; - - auto const re = engine.run(fibWasm, hfs, 10'000'000, "fib", wasmParams(10)); - - checkResult(re, 55, 1'137); - } - */ - - void - testEscrowWasmDN() - { - testcase("escrow wasm devnet test"); - - auto const allHFWasm = hexToBytes(kAllHostFunctionsWasmHex); - - using namespace test::jtx; - Env env{*this}; - { - TestHostFunctions hfs(env); - auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName); - checkResult(re, 1, 50'207); - } - - { - // max() gas - TestHostFunctions hfs(env); - auto re = runEscrowWasm( - allHFWasm, hfs, std::numeric_limits::max(), escrowFunctionName); - checkResult(re, 1, 50'207); - } - - { // fail because trying to access nonexistent field - struct FieldNotFoundHostFunctions : public TestHostFunctions - { - explicit FieldNotFoundHostFunctions(Env& env) : TestHostFunctions(env) - { - } - [[nodiscard]] std::expected - getTxField(SField const& fname) const override - { - return std::unexpected(HostFunctionError::FieldNotFound); - } - }; - - FieldNotFoundHostFunctions hfs(env); - auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName); - checkResult(re, -201, 28'901); - } - - { // fail because trying to allocate more than MAX_PAGES memory - struct OversizedFieldHostFunctions : public TestHostFunctions - { - explicit OversizedFieldHostFunctions(Env& env) : TestHostFunctions(env) - { - } - [[nodiscard]] std::expected - getTxField(SField const& fname) const override - { - return Bytes((128 + 1) * 64 * 1024, 1); - } - }; - - OversizedFieldHostFunctions hfs(env); - auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName); - checkResult(re, -201, 28'901); - } - -// This test use log output, so DEBUG_OUTPUT must be disabled. -#ifndef DEBUG_OUTPUT - { // fail because recursion too deep - - auto const deepWasm = hexToBytes(kDeepRecursionHex); - - TestHostFunctionsSink hfs(env); - std::string const funcName(escrowFunctionName); - auto re = runEscrowWasm(deepWasm, hfs, 1'000'000'000, funcName); - BEAST_EXPECT(!re && re.error().ter); - // std::cout << "bad case (deep recursion) result " << re.error() - // << std::endl; - - auto const& sink = hfs.getSink(); - auto countSubstr = [](std::string const& str, std::string const& substr) { - std::size_t pos = 0; - int occurrences = 0; - while ((pos = str.find(substr, pos)) != std::string::npos) - { - occurrences++; - pos += substr.length(); - } - return occurrences; - }; - - auto const s = sink.messages().str(); - BEAST_EXPECT(countSubstr(s, "wasm: ") == 1); - BEAST_EXPECT(countSubstr(s, "trap: call stack exhausted") > 0); - } -#endif - - { // infinite loop - auto const infiniteLoopWasm = hexToBytes(kInfiniteLoopWasmHex); - std::string const funcName("loop"); - TestHostFunctions hfs(env); - - // infinite loop should be caught and fail - auto const re = runEscrowWasm(infiniteLoopWasm, hfs, 1'000'000, funcName); - if (BEAST_EXPECT(!re.has_value())) - { - BEAST_EXPECT(re.error().ter == tecOUT_OF_GAS); - } - } - - // TODO: broken, fix after Rust re-arch. These three cases all build an - // ImportVec by hand and call WasmEngine::run; the import set is now fixed by - // the engine, so there is no way to under-provide it or desynchronise it from - // the HostFunctions the VM was given. - /* - { - // expected import not provided - auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex); - TestLedgerDataProvider hfs(env); - ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn2", hfs); - - auto& engine = WasmEngine::instance(); - - auto re = engine.run( - lgrSqnWasm, hfs, 1'000'000, escrowFunctionName, {}, imports, env.journal); - - BEAST_EXPECT(!re); - } - - { - // HF unsync between import and VM - auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex); - TestLedgerDataProvider hfs(env); - TestLedgerDataProvider hfs2(env); - ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs2); - - auto& engine = WasmEngine::instance(); - - auto re = engine.run( - lgrSqnWasm, hfs, 1'000'000, escrowFunctionName, {}, imports, env.journal); - - BEAST_EXPECT(!re); - } - - { - // bad function name - auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex); - TestLedgerDataProvider hfs(env); - ImportVec imports; - WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs); - - auto& engine = WasmEngine::instance(); - auto re = engine.run(lgrSqnWasm, hfs, 1'000'000, "func1", {}, imports, env.journal); - - BEAST_EXPECT(!re); - } - */ - } - - // TODO: testFloat is disabled until the float fixtures are regenerated. - // - // kFloatTestsWasmHex and kFloat0Hex were built against the old trace ABI, - // where the trace_* host functions returned i32. They now return void, so - // neither module instantiates and both blocks below fail with tecINTERNAL. - // - // Regenerating them is not just a rebuild: float_tests/ and float_0/ are - // still pinned to xrpl-wasm-stdlib @ "renames" and use APIs that no longer - // exist on xrpl-common-stdlib @ "error-and-trace" - // (FLOAT_ROUNDING_MODES_TO_NEAREST became RoundingMode, - // core::locator::Locator moved to fields::locator::Locator, and - // trace_data/DataRepr became trace_float/trace_hex). The fixture sources - // have to be ported first. The expected gas costs below are also stale and - // will need recomputing once the modules run again. - // - // void - // testFloat() - // { - // testcase("float point"); - // - // std::string const funcName(escrowFunctionName); - // - // using namespace test::jtx; - // - // Env env(*this); - // { - // auto const floatTestWasm = hexToBytes(kFloatTestsWasmHex); - // - // TestHostFunctions hfs(env); - // auto re = runEscrowWasm(floatTestWasm, hfs, 200'000, funcName, - // {}); checkResult(re, 1, 134'402); env.close(); - // } - // - // { - // auto const float0Wasm = hexToBytes(kFloat0Hex); - // - // TestHostFunctions hfs(env); - // auto re = runEscrowWasm(float0Wasm, hfs, 100'000, funcName); - // checkResult(re, 1, 2'775); - // env.close(); - // } - // } - - void - testCodecovWasm() - { - testcase("Codecov wasm test"); - - using namespace test::jtx; - - Env env{*this}; - - auto const codecovWasm = hexToBytes(kCodecovTestsWasmHex); - TestHostFunctions hfs(env); - - auto const allowance = 124'173; - auto re = runEscrowWasm(codecovWasm, hfs, allowance, escrowFunctionName); - - checkResult(re, 1, allowance); - } - - void - testDisabledFloat() - { - testcase("disabled float"); - - using namespace test::jtx; - Env env{*this}; - - auto disabledFloatWasm = hexToBytes(kDisabledFloatHex); - std::string const funcName(escrowFunctionName); - TestHostFunctions hfs(env); - - { - // f32 set constant, opcode disabled exception - auto const re = runEscrowWasm(disabledFloatWasm, hfs, 1'000'000, funcName); - if (BEAST_EXPECT(!re.has_value())) - { - BEAST_EXPECT(re.error().ter == tecFAILED_PROCESSING); - } - } - - { - // f32 add, can't create module exception - disabledFloatWasm[0x11e] = 0x92; - auto const re = runEscrowWasm(disabledFloatWasm, hfs, 1'000'000, funcName); - if (BEAST_EXPECT(!re.has_value())) - { - BEAST_EXPECT(re.error().ter == tecFAILED_PROCESSING); - } - } - } - - void - testWasmMemory() - { - testcase("Wasm additional memory limit tests"); - BEAST_EXPECT(finishFunctionReturns(kMemoryPointerAtLimitHex, 1)); - BEAST_EXPECT(!runFinish(kMemoryPointerOverLimitHex).has_value()); - BEAST_EXPECT(!runFinish(kMemoryOffsetOverLimitHex).has_value()); - BEAST_EXPECT(!runFinish(kMemoryEndOfWordOverLimitHex).has_value()); - BEAST_EXPECT(finishFunctionReturns(kMemoryGrow0To1PageHex, 1)); - BEAST_EXPECT(finishFunctionReturns(kMemoryGrow1To0PageHex, -1)); - BEAST_EXPECT(finishFunctionReturns(kMemoryLastByteOf8MbHex, 1)); - // Growing past the 8 MiB cap now traps ("growth operation limited") instead of - // letting memory.grow answer -1, so the run fails rather than returning. - BEAST_EXPECT(!runFinish(kMemoryGrow1MoreThan8MbHex).has_value()); - BEAST_EXPECT(finishFunctionReturns(kMemoryGrow0MoreThan8MbHex, 1)); - BEAST_EXPECT(!runFinish(kMemoryInit1MoreThan8MbHex).has_value()); - BEAST_EXPECT(!runFinish(kMemoryNegativeAddressHex).has_value()); - } - - void - testWasmTable() - { - testcase("Wasm table limit tests"); - BEAST_EXPECT(finishFunctionReturns(kTable64ElementsHex, 1)); - // 65 elements is no longer over the cap: MAX_TABLE_ELEMENTS is 1024. The - // boundary itself is covered by the engine's own test, since there is no - // 1025-element fixture here. - BEAST_EXPECT(finishFunctionReturns(kTable65ElementsHex, 1)); - BEAST_EXPECT(!runFinish(kTable2TablesHex).has_value()); - BEAST_EXPECT(finishFunctionReturns(kTable0ElementsHex, 1)); - BEAST_EXPECT(!runFinish(kTableUintMaxHex).has_value()); - } - - void - testWasmProposal() - { - testcase("Wasm disabled proposal tests"); - BEAST_EXPECT(!runFinish(kProposalMutableGlobalHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalGcStructNewHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalMultiValueHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalSignExtHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalFloatToIntHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalBulkMemoryHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalRefTypesHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalTailCallHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalExtendedConstHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalMultiMemoryHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalCustomPageSizesHex).has_value()); - BEAST_EXPECT(!runFinish(kProposalMemory64Hex).has_value()); - BEAST_EXPECT(!runFinish(kProposalWideArithmeticHex).has_value()); - } - - void - testWasmTrap() - { - testcase("Wasm trap tests"); - BEAST_EXPECT(!runFinish(kTrapDivideBy0Hex).has_value()); - BEAST_EXPECT(!runFinish(kTrapIntOverflowHex).has_value()); - BEAST_EXPECT(!runFinish(kTrapUnreachableHex).has_value()); - BEAST_EXPECT(!runFinish(kTrapNullCallHex).has_value()); - BEAST_EXPECT(!runFinish(kTrapFuncSigMismatchHex).has_value()); - } - - void - testWasmWasi() - { - testcase("Wasm Wasi tests"); - BEAST_EXPECT(!runFinish(kWasiGetTimeHex).has_value()); - BEAST_EXPECT(!runFinish(kWasiPrintHex).has_value()); - } - - void - testWasmSectionCorruption() - { - testcase("Wasm Section Corruption tests"); - BEAST_EXPECT(!runFinish(kBadMagicNumberHex).has_value()); - BEAST_EXPECT(!runFinish(kBadVersionNumberHex).has_value()); - BEAST_EXPECT(!runFinish(kLyingHeaderHex).has_value()); - BEAST_EXPECT(!runFinish(kNeverEndingNumberHex).has_value()); - BEAST_EXPECT(!runFinish(kVectorLieHex).has_value()); - BEAST_EXPECT(!runFinish(kSectionOrderingHex).has_value()); - BEAST_EXPECT(!runFinish(kGhostPayloadHex).has_value()); - BEAST_EXPECT(!runFinish(kJunkAfterSectionHex).has_value()); - BEAST_EXPECT(!runFinish(kInvalidSectionIdHex).has_value()); - BEAST_EXPECT(!runFinish(kLocalVariableBombHex).has_value()); - } - - // TODO: broken, fix after Rust re-arch. Needs WasmEngine::check, whose replacement - // preflightEscrowWasm takes no HostFunctions, and WasmEngine::run to observe that - // the start function - not the export - is what burns the gas. - /* - void - testStartFunctionLoop() - { - testcase("infinite loop in start function"); - - using namespace test::jtx; - Env env(*this); - - auto const startLoopWasm = hexToBytes(kStartLoopHex); - TestLedgerDataProvider hfs(env); - ImportVec const imports; - - auto& engine = WasmEngine::instance(); - auto checkRes = - engine.check(startLoopWasm, hfs, escrowFunctionName, {}, imports, env.journal); - BEAST_EXPECTS(checkRes == tesSUCCESS, transToken(checkRes)); - - auto result = - engine.run(startLoopWasm, hfs, 1'000'000, escrowFunctionName, {}, imports, env.journal); - auto resultTer = result.error().ter; - BEAST_EXPECTS(resultTer == tecFAILED_PROCESSING, transToken(resultTer)); - } - */ - - void - testReturnType() - { - using namespace test::jtx; - Env env(*this); - TestHostFunctions hfs(env); - - testcase("Wasm invalid return type"); - - // return int64. - { // (module - // (memory (export "memory") 1) - // (func (export "finish") (result i64) - // i64.const 0x100000000)) - auto const wasmHex = - "0061736d010000000105016000017e030201000503010001" - "071302066d656d6f727902000666696e69736800000a0a01" - "08004280808080100b"; - auto const wasm = hexToBytes(wasmHex); - auto const re = runEscrowWasm(wasm, hfs, 100'000, escrowFunctionName); - BEAST_EXPECT(!re); - } - - // return void. wasmi return execution error - { //(module - // (type (;0;) (func)) - // (func (;0;) (type 0) - // return) - // (memory (;0;) 1) - // (export "memory" (memory 0)) - // (export "finish" (func 0))) - auto const wasmHex = - "0061736d01000000010401600000030201000503010001071302066d656d6f" - "727902000666696e69736800000a050103000f0b"; - auto const wasm = hexToBytes(wasmHex); - auto const re = runEscrowWasm(wasm, hfs, 100'000, escrowFunctionName); - BEAST_EXPECT(!re); - } - - // return i32, i32. wasmi doesn't create module - { //(module - // (memory (export "memory") 1) - // (func (export "finish") (result i32 i32) - // i32.const 0x10000000 - // i32.const 0x100000FF)) - auto const wasmHex = - "0061736d010000000106016000027f7f030201000503010001071302066d65" - "6d6f727902000666696e69736800000a10010e0041808080800141ff818080" - "010b"; - auto const wasm = hexToBytes(wasmHex); - auto const re = runEscrowWasm(wasm, hfs, 100'000, escrowFunctionName); - BEAST_EXPECT(!re); - } - } - - void - testParameterType() - { - using namespace test::jtx; - Env env(*this); - TestHostFunctions hfs(env); - - testcase("Wasm invalid params"); - - // (module - // (memory (export "memory") 1) - // (func $test1 (export "test1") (param i32) (result i32) - // i32.const 1000) - // (func $test2 (export "test2") (param i32 i32) (result i32) - // i32.const 1001)) - auto const wasmHex = - "0061736d01000000010c0260017f017f60027f7f017f03030200010503010001071a03066d656d6f727902" - "00057465737431000005746573743200010a0d02050041e8070b050041e9070b"; - auto const wasm = hexToBytes(wasmHex); - - // no params. An export that wants any is refused, since runEscrowWasm has - // none to give it. - { - auto const re = runEscrowWasm(wasm, hfs, 100'000, "test1"); - BEAST_EXPECT(!re); - } - - { - auto const re = runEscrowWasm(wasm, hfs, 100'000, "test2"); - BEAST_EXPECT(!re); - } - - // TODO: broken, fix after Rust re-arch. The good-params control and the - // wrong-arity / wrong-type cases below all need to pass parameters, which - // runEscrowWasm cannot do. Without the positive case the two checks above - // only show that the export is refused, not that it would have run. - /* - // good params, module is working properly - { - auto const re = runEscrowWasm(wasm, hfs, 100'000, "test2", wasmParams(2, 10)); - BEAST_EXPECT(re && re->result == 1001 && re->cost == 37); - } - - // more params - { - auto const re = runEscrowWasm(wasm, hfs, 100'000, "test1", wasmParams(0, 1)); - BEAST_EXPECT(!re); - } - - // less params - { - auto const re = runEscrowWasm(wasm, hfs, 100'000, "test2", wasmParams(1)); - BEAST_EXPECT(!re); - } - - // invalid type - { - auto const re = - runEscrowWasm(wasm, hfs, 100'000, "test1", wasmParams(std::int64_t(15))); - BEAST_EXPECT(!re); - } - */ - } - - void - testSwapBytes() - { - testcase("Wasm swap bytes"); - - uint64_t const swapDataU64 = 0x123456789abcdeffull; - uint64_t const reverseSwapDataU64 = 0xffdebc9a78563412ull; - int64_t const swapDataI64 = 0x123456789abcdeffll; - int64_t const reverseSwapDataI64 = 0xffdebc9a78563412ll; - - uint32_t const swapDataU32 = 0x12789aff; - uint32_t const reverseSwapDataU32 = 0xff9a7812; - int32_t const swapDataI32 = 0x12789aff; - int32_t const reverseSwapDataI32 = 0xff9a7812; - - uint16_t const swapDataU16 = 0x12ff; - uint16_t const reverseSwapDataU16 = 0xff12; - int16_t const swapDataI16 = 0x12ff; - int16_t const reverseSwapDataI16 = 0xff12; - - uint64_t b1 = swapDataU64; - int64_t b2 = swapDataI64; - b1 = adjustWasmEndianessHlp(b1); - b2 = adjustWasmEndianessHlp(b2); - BEAST_EXPECT(b1 == reverseSwapDataU64); - BEAST_EXPECT(b2 == reverseSwapDataI64); - b1 = adjustWasmEndianessHlp(b1); - b2 = adjustWasmEndianessHlp(b2); - BEAST_EXPECT(b1 == swapDataU64); - BEAST_EXPECT(b2 == swapDataI64); - - uint32_t b3 = swapDataU32; - int32_t b4 = swapDataI32; - b3 = adjustWasmEndianessHlp(b3); - b4 = adjustWasmEndianessHlp(b4); - BEAST_EXPECT(b3 == reverseSwapDataU32); - BEAST_EXPECT(b4 == reverseSwapDataI32); - b3 = adjustWasmEndianessHlp(b3); - b4 = adjustWasmEndianessHlp(b4); - BEAST_EXPECT(b3 == swapDataU32); - BEAST_EXPECT(b4 == swapDataI32); - - uint16_t b5 = swapDataU16; - int16_t b6 = swapDataI16; - b5 = adjustWasmEndianessHlp(b5); - b6 = adjustWasmEndianessHlp(b6); - BEAST_EXPECT(b5 == reverseSwapDataU16); - BEAST_EXPECT(b6 == reverseSwapDataI16); - b5 = adjustWasmEndianessHlp(b5); - b6 = adjustWasmEndianessHlp(b6); - BEAST_EXPECT(b5 == swapDataU16); - BEAST_EXPECT(b6 == swapDataI16); - } - - // TODO: broken, fix after Rust re-arch. Builds a 1000-entry parameter vector and - // calls arbitrary exports through WasmEngine::run; runEscrowWasm passes no - // parameters, so the wasmi arity limit these cases straddle is unreachable. - /* - void - testManyParams() - { - testcase("Wasm Many params"); - - auto const params1k = hexToBytes(kThousandParamsHex); - auto const params1k1 = hexToBytes(kThousand1ParamsHex); - - using namespace test::jtx; - - Env env{*this}; - TestHostFunctions hfs(env); - auto imports = createWasmImport(hfs); - - // add 1k parameter (max that wasmi support) - std::vector params; - params.reserve(1000); - for (int i = 0; i < 1000; ++i) - params.push_back({.type = WasmTypes::WtI32, .of = {.i32 = 2 * i}}); - - auto& engine = WasmEngine::instance(); - { - auto re = engine.run(params1k, hfs, 1'000'000, "test", params, imports, env.journal); - BEAST_EXPECT(re && re->result == 999000); - } - - // add 1 more parameter, module can't be created now - params.push_back({.type = WasmTypes::WtI32, .of = {.i32 = 2 * 1000}}); - { - auto re = engine.run(params1k1, hfs, 1'000'000, "test", params, imports, env.journal); - BEAST_EXPECT(!re); - } - - // function that create 10k local variables - auto const locals10k = hexToBytes(kLocals10kHex); - { - auto re = engine.run( - locals10k, hfs, 1'000'000, "test", wasmParams(0, 1), imports, env.journal); - BEAST_EXPECT(re && re->result == 890'489'442); - } - - // module has 5k functions - auto const functions5k = hexToBytes(kFunctions5kHex); - { - auto re = engine.run( - functions5k, hfs, 1'000'000, "test0001", wasmParams(2, 3), imports, env.journal); - BEAST_EXPECT(re && re->result == 5); - } - - env.close(); - } - */ - - // TODO: broken, fix after Rust re-arch. Sweeps the reserved opcode space by - // patching a fixture and running its "all_instructions" export through - // WasmEngine::run with a hand-built import set. runEscrowWasm only calls - // escrow_finish, so the fixture cannot be driven. Restoring this needs - // and back at the top of the file. - // clang-format off - /* - void - testOpcodes() - { - using namespace test::jtx; - - unsigned const reserved = 64; - std::uint8_t const nop = 0x01; - std::array const codeMarker = { - nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop}; - auto const opcReserved = hexToBytes(kOpcReservedHex); - - Env env{*this}; - auto& engine = WasmEngine::instance(); - - TestHostFunctions hfs(env); - auto imports = createWasmImport(hfs); - env.close(); - - { - auto run = [&](std::vector const& code, - bool good = false, - int64_t cost = -1, - std::source_location const location = std::source_location::current()) { - auto const lineStr = " (" + std::to_string(location.line()) + ")"; - auto re = - engine.run(code, hfs, 1'000'000, "all_instructions", {}, imports, env.journal); - if (BEAST_EXPECTS(re.has_value() == good, transToken(re.error().ter) + lineStr) && - good) - BEAST_EXPECTS(re->cost == cost, std::to_string(re->cost) + lineStr); - }; - - // 1 byte instruction - auto test = [&](std::uint8_t start, - std::uint8_t finish, - bool good = false, - int64_t cost = -1, - std::source_location const location = std::source_location::current()) { - auto const lineStr = " (" + std::to_string(location.line()) + ")"; - auto code = opcReserved; - auto codeRange = std::ranges::search(code, codeMarker); - if (!BEAST_EXPECTS(!codeRange.empty(), lineStr)) - return; - - auto it = codeRange.begin(); - for (std::uint16_t i = start; i <= finish; ++i) - { - *it = i; - run(code, good, cost, location); - } - }; - - // 2 bytes instruction - auto test2 = [&](std::uint8_t major, - std::uint16_t start, - std::uint16_t finish, - bool good = false, - int64_t cost = -1, - std::source_location const location = - std::source_location::current()) { - auto const lineStr = " (" + std::to_string(location.line()) + ")"; - auto code = opcReserved; - auto codeRange = std::ranges::search(code, codeMarker); - if (!BEAST_EXPECTS(!codeRange.empty(), lineStr)) - return; - - auto it = codeRange.begin(); - *it++ = major; - for (std::uint16_t i = start; i <= finish; ++i) - { - auto it2 = it; - uleb128(it2, i); - run(code, good, cost, location); - } - }; - - // multibytes instructions - auto testMB = [&](std::vector const& codeSnap, - bool good = false, - int64_t cost = -1, - std::source_location const location = - std::source_location::current()) { - auto const lineStr = " (" + std::to_string(location.line()) + ")"; - auto code = opcReserved; - auto codeRange = std::ranges::search(code, codeMarker); - if (!BEAST_EXPECTS(!codeRange.empty(), lineStr)) - return; - - if (!BEAST_EXPECTS(codeSnap.size() < reserved, lineStr)) - return; - auto it = codeRange.begin(); - for (auto x : codeSnap) - *it++ = x; - run(code, good, cost, location); - }; - - // normal run - testcase("Wasm reserved opcodes main"); - test(nop, nop, true, 534); - - // reserved main - test(0x06, 0x0A); - test(0x12, 0x19); - test(0x25, 0x27); - test(0xC0, 0xFA); - test(0xFF, 0xFF); - - // reserved gc, string - testcase("Wasm reserved opcodes gc"); - test2(0xFB, 0x00, 0xBF); // not supported by compiler - - // reserved FC - testcase("Wasm reserved opcodes FC"); - test2(0xFC, 0x00, 0x07); // floats, disabled - test2(0xFC, 0x12, 0x1F); - - // reserved SIMD - testcase("Wasm reserved opcodes SIMD"); - test2(0xFD, 0x9A, 0x9A); - test2(0xFD, 0xA2, 0xA2); - test2(0xFD, 0xA5, 0xA6); - test2(0xFD, 0xAF, 0xB0); - test2(0xFD, 0xB2, 0xB4); - test2(0xFD, 0xB8, 0xB8); - test2(0xFD, 0xC2, 0xC2); - test2(0xFD, 0xC5, 0xC6); - test2(0xFD, 0xCF, 0xD0); - test2(0xFD, 0xD2, 0xD4); - test2(0xFD, 0xE2, 0xE2); - test2(0xFD, 0xEE, 0xEE); - test2(0xFD, 0x115, 0x12F); - - testcase("Wasm opcodes THREADS"); - test2(0xFE, 0x00, 0x4F); // not supported by compiler - - // FC mem instructions - testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x04, 0xFC, 0x08, 0x00, 0x00}); // memory.init - testMB({0xFC, 0x09, 0x00}); // data.drop - testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0xFC, 0x0A, 0x00, 0x00}); // memory.copy - testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0xFC, 0x0B, 0x00}); // memory.fill - testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0xFC, 0x0C, 0x00, 0x00}); // table.init - testMB({0xFC, 0x0D, 0x00}); // elem.drop - testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0xFC, 0x0E, 0x00, 0x00}); // table.copy - testMB({0xD2, 0x00, 0x41, 0x00, 0xFC, 0x0F, 0x00, 0x1A}); // table.grow - testMB({0x1A, 0xFC, 0x10, 0x00, 0x1A}); // table.size - testMB({0x41, 0x00, 0xD2, 0x00, 0x41, 0x00, 0xFC, 0x11, 0x00}); // table.fill - - testcase("Wasm opcodes SIMD"); - // clang-format off - - // generated by auggie - // SIMD instructions - testMB({0x41, 0x00, 0xFD, 0x00, 0x04, 0x00, 0x1A}); // v128.load - testMB({0x41, 0x00, 0xFD, 0x01, 0x03, 0x00, 0x1A}); // v128.load8x8_s - testMB({0x41, 0x00, 0xFD, 0x02, 0x03, 0x00, 0x1A}); // v128.load8x8_u - testMB({0x41, 0x00, 0xFD, 0x03, 0x03, 0x00, 0x1A}); // v128.load16x4_s - testMB({0x41, 0x00, 0xFD, 0x04, 0x03, 0x00, 0x1A}); // v128.load16x4_u - testMB({0x41, 0x00, 0xFD, 0x05, 0x03, 0x00, 0x1A}); // v128.load32x2_s - testMB({0x41, 0x00, 0xFD, 0x06, 0x03, 0x00, 0x1A}); // v128.load32x2_u - testMB({0x41, 0x00, 0xFD, 0x07, 0x00, 0x00, 0x1A}); // v128.load8_splat - testMB({0x41, 0x00, 0xFD, 0x08, 0x01, 0x00, 0x1A}); // v128.load16_splat - testMB({0x41, 0x00, 0xFD, 0x09, 0x02, 0x00, 0x1A}); // v128.load32_splat - testMB({0x41, 0x00, 0xFD, 0x0A, 0x03, 0x00, 0x1A}); // v128.load64_splat - testMB({0x41, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0B, 0x04, 0x00}); // v128.store - testMB({0xFD, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1A}); // v128.const - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0D, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x1A}); // i8x16.shuffle - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0E, 0x1A}); // i8x16.swizzle - testMB({0x41, 0x2A, 0xFD, 0x0F, 0x1A}); // i8x16.splat - testMB({0x41, 0x2A, 0xFD, 0x10, 0x1A}); // i16x8.splat - testMB({0x41, 0x2A, 0xFD, 0x11, 0x1A}); // i32x4.splat - testMB({0x42, 0x2A, 0xFD, 0x12, 0x1A}); // i64x2.splat - - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x15, 0x00, 0x1A}); // i8x16.extract_lane_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x16, 0x00, 0x1A}); // i8x16.extract_lane_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2A, 0xFD, 0x17, 0x00, 0x1A}); // i8x16.replace_lane - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x18, 0x00, 0x1A}); // i16x8.extract_lane_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x19, 0x00, 0x1A}); // i16x8.extract_lane_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2A, 0xFD, 0x1A, 0x00, 0x1A}); // i16x8.replace_lane - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x1B, 0x00, 0x1A}); // i32x4.extract_lane - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2A, 0xFD, 0x1C, 0x00, 0x1A}); // i32x4.replace_lane - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x1D, 0x00, 0x1A}); // i64x2.extract_lane - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x2A, 0xFD, 0x1E, 0x00, 0x1A}); // i64x2.replace_lane - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x1F, 0x00, 0x1A}); // f32x4.extract_lane - testMB( - {0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x80, 0x3F, 0xFD, 0x20, 0x00, 0x1A}); // f32x4.replace_lane - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x21, 0x00, 0x1A}); // f64x2.extract_lane - testMB( - {0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0xFD, 0x22, 0x00, 0x1A}); // f64x2.replace_lane - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x23, 0x1A}); // i8x16.eq - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x24, 0x1A}); // i8x16.ne - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x25, 0x1A}); // i8x16.lt_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x26, 0x1A}); // i8x16.lt_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x27, 0x1A}); // i8x16.gt_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x28, 0x1A}); // i8x16.gt_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x29, 0x1A}); // i8x16.le_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2A, 0x1A}); // i8x16.le_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2B, 0x1A}); // i8x16.ge_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2C, 0x1A}); // i8x16.ge_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2D, 0x1A}); // i16x8.eq - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2E, 0x1A}); // i16x8.ne - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2F, 0x1A}); // i16x8.lt_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x30, 0x1A}); // i16x8.lt_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x31, 0x1A}); // i16x8.gt_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x32, 0x1A}); // i16x8.gt_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x33, 0x1A}); // i16x8.le_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x34, 0x1A}); // i16x8.le_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x35, 0x1A}); // i16x8.ge_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x36, 0x1A}); // i16x8.ge_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x37, 0x1A}); // i32x4.eq - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x38, 0x1A}); // i32x4.ne - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x39, 0x1A}); // i32x4.lt_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3A, 0x1A}); // i32x4.lt_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3B, 0x1A}); // i32x4.gt_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3C, 0x1A}); // i32x4.gt_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3D, 0x1A}); // i32x4.le_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3E, 0x1A}); // i32x4.le_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3F, 0x1A}); // i32x4.ge_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x40, 0x1A}); // i32x4.ge_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x4D, 0x1A}); // v128.not - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x4E, 0x1A}); // v128.and - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x4F, 0x1A}); // v128.andnot - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x50, 0x1A}); // v128.or - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x51, 0x1A}); // v128.xor - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x52, 0x1A}); // v128.bitselect - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x53, 0x1A}); // v128.any_true - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x60, 0x1A}); // i8x16.abs - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x61, 0x1A}); // i8x16.neg - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x62, 0x1A}); // i8x16.popcnt - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x63, 0x1A}); // i8x16.all_true - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x64, 0x1A}); // i8x16.bitmask - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x6B, 0x1A}); // i8x16.shl - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x6C, 0x1A}); // i8x16.shr_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x6D, 0x1A}); // i8x16.shr_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x6E, 0x1A}); // i8x16.add - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x6F, 0x1A}); // i8x16.add_sat_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x70, 0x1A}); // i8x16.add_sat_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x71, 0x1A}); // i8x16.sub - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x72, 0x1A}); // i8x16.sub_sat_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x73, 0x1A}); // i8x16.sub_sat_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x76, 0x1A}); // i8x16.min_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x77, 0x1A}); // i8x16.min_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x78, 0x1A}); // i8x16.max_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x79, 0x1A}); // i8x16.max_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x7B, 0x1A}); // i8x16.avgr_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x80, 0x01, 0x1A}); // i16x8.abs - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x81, 0x01, 0x1A}); // i16x8.neg - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x83, 0x01, 0x1A}); // i16x8.all_true - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x84, 0x01, 0x1A}); // i16x8.bitmask - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x8B, 0x01, 0x1A}); // i16x8.shl - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x8C, 0x01, 0x1A}); // i16x8.shr_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x8D, 0x01, 0x1A}); // i16x8.shr_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x8E, 0x01, 0x1A}); // i16x8.add - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x8F, 0x01, 0x1A}); // i16x8.add_sat_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x90, 0x01, 0x1A}); // i16x8.add_sat_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x91, 0x01, 0x1A}); // i16x8.sub - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x92, 0x01, 0x1A}); // i16x8.sub_sat_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x93, 0x01, 0x1A}); // i16x8.sub_sat_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x95, 0x01, 0x1A}); // i16x8.mul - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x96, 0x01, 0x1A}); // i16x8.min_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x97, 0x01, 0x1A}); // i16x8.min_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x98, 0x01, 0x1A}); // i16x8.max_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x99, 0x01, 0x1A}); // i16x8.max_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x9B, 0x01, 0x1A}); // i16x8.avgr_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xA0, 0x01, 0x1A}); // i32x4.abs - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xA1, 0x01, 0x1A}); // i32x4.neg - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xA3, 0x01, 0x1A}); // i32x4.all_true - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xA4, 0x01, 0x1A}); // i32x4.bitmask - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xAB, 0x01, 0x1A}); // i32x4.shl - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xAC, 0x01, 0x1A}); // i32x4.shr_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xAD, 0x01, 0x1A}); // i32x4.shr_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xAE, 0x01, 0x1A}); // i32x4.add - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB1, 0x01, 0x1A}); // i32x4.sub - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB5, 0x01, 0x1A}); // i32x4.mul - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB6, 0x01, 0x1A}); // i32x4.min_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB7, 0x01, 0x1A}); // i32x4.min_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB8, 0x01, 0x1A}); // i32x4.max_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB9, 0x01, 0x1A}); // i32x4.max_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xBA, 0x01, 0x1A}); // i32x4.dot_i16x8_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xC0, 0x01, 0x1A}); // i64x2.abs - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xC1, 0x01, 0x1A}); // i64x2.neg - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xC3, 0x01, 0x1A}); // i64x2.all_true - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xC4, 0x01, 0x1A}); // i64x2.bitmask - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xCB, 0x01, 0x1A}); // i64x2.shl - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xCC, 0x01, 0x1A}); // i64x2.shr_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xCD, 0x01, 0x1A}); // i64x2.shr_u - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xCE, 0x01, 0x1A}); // i64x2.add - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD1, 0x01, 0x1A}); // i64x2.sub - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD5, 0x01, 0x1A}); // i64x2.mul - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD6, 0x01, 0x1A}); // i64x2.eq - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD7, 0x01, 0x1A}); // i64x2.ne - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD8, 0x01, 0x1A}); // i64x2.lt_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD9, 0x01, 0x1A}); // i64x2.gt_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xDA, 0x01, 0x1A}); // i64x2.le_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xDB, 0x01, 0x1A}); // i64x2.ge_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xF8, 0x01, 0x1A}); // i32x4.trunc_sat_f32x4_s - testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xF9, 0x01, 0x1A}); // i32x4.trunc_sat_f32x4_u - - // clang-format on - } - } - */ - // clang-format on - - void - run() override - { - testBadWasm(); - testEscrowWasmDN(); - // TODO: re-enable once the float fixtures are regenerated (see above) - // testFloat(); - - testCodecovWasm(); - // TODO: broken, fix after Rust re-arch - // testDisabledFloat(); - - testWasmMemory(); - testWasmTable(); - testWasmProposal(); - testWasmTrap(); - testWasmWasi(); - testWasmSectionCorruption(); - - // TODO: broken, fix after Rust re-arch - // testStartFunctionLoop(); - testReturnType(); - testSwapBytes(); - // TODO: broken, fix after Rust re-arch - // testManyParams(); - testParameterType(); - - // TODO: broken, fix after Rust re-arch - // testOpcodes(); - } -}; - -BEAST_DEFINE_TESTSUITE(Wasm, app, xrpl); - -} // namespace xrpl::test -#endif +// #include +// #ifdef _DEBUG +// // #define DEBUG_OUTPUT 1 +// #endif +// +// #include +// #include +// #include +// +// #include +// #include +// #include +// #include +// #include +// #include +// +// #include +// +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// +// namespace xrpl::test { +// +// std::vector +// hexToBytes(std::string const& hex) +// { +// auto const ws = boost::algorithm::unhex(hex); +// return Bytes(ws.begin(), ws.end()); +// } +// +// template +// unsigned +// uleb128(IT& it, T val) +// { +// unsigned count = 0; +// do +// { +// std::uint8_t byte = val & 0x7f; +// val >>= 7; +// if (val) +// byte |= 0x80; +// *it++ = byte; +// ++count; +// } while (val != 0); +// +// return count; +// } +// +// template +// std::pair +// uleb128(IT&& it) +// { +// static_assert(sizeof(*it) == 1, "invalid iterator type"); +// std::uint64_t val = 0; +// std::uint64_t byte = 0; +// unsigned shift = 0; +// unsigned count = 0; +// +// do +// { +// if (shift > (sizeof(std::uint64_t) * 8) - 7) +// return {0, 0}; +// byte = *it++; +// val |= (byte & 0x7F) << shift; +// shift += 7; +// ++count; +// } while (byte >= 0x80); +// +// return {val, count}; +// } +// +// // TODO: broken, fix after Rust re-arch. Only used by testImpExp, which is disabled +// // below; kept (and kept compiling out) so it comes back with that test. +// /* +// static std::pair +// getSection(Bytes const& module, std::uint8_t n) +// { +// static std::uint8_t const kHdr[] = {0x00, 0x61, 0x73, 0x6D}; +// static std::uint8_t const kVer[] = {0x01, 0x00, 0x00, 0x00}; +// static std::uint8_t const kLastSec = 12; +// +// // sections: +// // 0: "Custom", 1: "Type", 2: "Import", 3: "Function", 4: "Table", 5: "Memory", 6: "Global", +// // 7: "Export", 8: "Start", 9: "Element", 10: "Code", 11: "Data", 12: "DataCount" +// +// if (module.size() < sizeof(kHdr) + sizeof(kVer) + 2) +// return {0, 0}; +// if (memcmp(module.data(), kHdr, sizeof(kHdr)) != 0) +// return {0, 0}; +// if (memcmp(module.data() + sizeof(kHdr), kVer, sizeof(kVer)) != 0) +// return {0, 0}; +// +// unsigned pos = sizeof(kHdr) + sizeof(kVer); // sections start +// for (; pos < module.size();) +// { +// auto const start = pos; +// std::uint8_t const byte = module[pos++]; +// if (byte > kLastSec) +// return {0, 0}; +// +// auto [sz, cnt] = uleb128(module.cbegin() + pos); +// if (cnt == 0u) +// return {0, 0}; +// if (pos + cnt + sz > module.size()) +// return {0, 0}; +// pos += cnt + sz; +// +// if (byte == n) +// return {start, pos}; +// } +// return {0, 0}; +// } +// */ +// +// static std::optional +// runFinish(std::string const& code) +// { +// auto const wasm = hexToBytes(code); +// HostFunctions hfs; +// auto const re = runEscrowWasm(wasm, hfs, 10'000'000, escrowFunctionName); +// if (re.has_value()) +// { +// return std::optional(re->result); +// } +// +// return std::nullopt; +// } +// +// static bool +// finishFunctionReturns(std::string const& code, int32_t expected) +// { +// auto const result = runFinish(code); +// return result.has_value() && *result == expected; +// } +// +// struct Wasm_test : public beast::unit_test::Suite +// { +// void +// checkResult( +// std::expected, WasmTER> re, +// int32_t expectedResult, +// int64_t expectedCost, +// std::source_location const location = std::source_location::current()) +// { +// auto const lineStr = " (" + std::to_string(location.line()) + ")"; +// if (BEAST_EXPECTS(re.has_value(), transToken(re.error().ter) + lineStr)) +// { +// BEAST_EXPECTS(re->result == expectedResult, std::to_string(re->result) + lineStr); +// BEAST_EXPECTS(re->cost == expectedCost, std::to_string(re->cost) + lineStr); +// } +// } +// +// void +// testBadWasm() +// { +// testcase("bad wasm test"); +// +// using namespace test::jtx; +// +// Env const env{*this}; +// HostFunctions hfs(env.journal); +// +// { +// auto wasm = hexToBytes("00000000"); +// std::string const funcName("mock_escrow"); +// +// auto re = runEscrowWasm(wasm, hfs, 15, funcName); +// BEAST_EXPECT(!re); +// } +// +// { +// auto wasm = hexToBytes("00112233445566778899AA"); +// std::string const funcName("mock_escrow"); +// +// auto const re = preflightEscrowWasm(wasm, env.journal, funcName); +// BEAST_EXPECT(!isTesSuccess(re)); +// } +// +// { +// // Bytecode wrong function name +// // pub fn bad() -> bool { +// // unsafe { host_lib::getLedgerSqn() >= 5 } +// // } +// auto const badWasm = hexToBytes( +// "0061736d010000000105016000017f02190108686f73745f6c69620c6765" +// "744c656467657253716e00000302010005030100100611027f00418080c0" +// "000b7f00418080c0000b072b04066d656d6f727902000362616400010a5f" +// "5f646174615f656e6403000b5f5f686561705f6261736503010a09010700" +// "100041044a0b004d0970726f64756365727302086c616e67756167650104" +// "52757374000c70726f6365737365642d6279010572757374631d312e3835" +// "2e31202834656231363132353020323032352d30332d31352900490f7461" +// "726765745f6665617475726573042b0f6d757461626c652d676c6f62616c" +// "732b087369676e2d6578742b0f7265666572656e63652d74797065732b0a" +// "6d756c746976616c7565"); +// +// auto const re = preflightEscrowWasm(badWasm, env.journal, escrowFunctionName); +// BEAST_EXPECT(!isTesSuccess(re)); +// } +// } +// +// // TODO: broken, fix after Rust re-arch. Both tests drive WasmEngine directly: +// // testImpExp installs individually-priced imports via ImportVec/WASM_IMPORT_FUNC2, +// // and both call arbitrary exports with parameters. runEscrowWasm calls a single +// // export and takes no parameters, so neither can be expressed against it. +// /* +// void +// testImpExp() +// { +// testcase("Wasm import/export functions"); +// +// auto impExpWasm = hexToBytes(kImpExpHex); +// +// using namespace test::jtx; +// +// Env env{*this}; +// TestLedgerDataProvider hfs(env); +// ImportVec imports; +// WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs, 33); +// WASM_IMPORT_FUNC2(imports, getParentLedgerHash, "get_parent_ledger_hash", hfs, 60); +// auto& engine = WasmEngine::instance(); +// +// // Test exp_func1() - should return 1 +// auto re = engine.run(impExpWasm, hfs, 1'000'000, "exp_func1", {}, imports, env.journal); +// checkResult(re, 1, 30); +// +// // Test exp_func2(5) - should return 2 * 5 = 10 +// re = engine.run( +// impExpWasm, hfs, 1'000'000, "exp_func2", wasmParams(5), imports, env.journal); +// checkResult(re, 10, 52); +// +// // Test test_imports() - should call get_ledger_sqn and get_parent_ledger_hash +// re = engine.run(impExpWasm, hfs, 1'000'000, "test_imports", {}, imports, env.journal); +// // Should return the ledger sequence number (3 by default in test env) +// checkResult(re, 3, 294); +// +// // Test corrupted import/export sections - invert each byte and expect failure +// testcase("Wasm import/export section corruption"); +// { +// // Import section(#2): bytes [26, 79) - 53 bytes +// // Export section(#7): bytes [90, 141) - 51 bytes +// auto [importStart, importEnd] = getSection(impExpWasm, 2); +// auto [exportStart, exportEnd] = getSection(impExpWasm, 7); +// +// BEAST_EXPECTS(importStart == 26, std::to_string(importStart)); +// BEAST_EXPECTS(importEnd == 79, std::to_string(importEnd)); +// BEAST_EXPECTS(exportStart == 90, std::to_string(exportStart)); +// BEAST_EXPECTS(exportEnd == 141, std::to_string(exportEnd)); +// +// auto testInv = [&](unsigned i) { +// auto corruptedWasm = impExpWasm; +// corruptedWasm[i] = ~corruptedWasm[i]; // Invert byte +// +// // Try to run any function - should fail due to corruption +// auto result = engine.run( +// corruptedWasm, hfs, 1'000'000, "exp_func1", {}, imports, env.journal); +// BEAST_EXPECT(!result); +// }; +// +// // Test each byte in import section +// for (unsigned i = importStart; i < importEnd; ++i) +// testInv(i); +// +// // Test each byte in export section +// for (unsigned i = exportStart; i < exportEnd; ++i) +// testInv(i); +// } +// +// env.close(); +// } +// +// void +// testWasmFib() +// { +// testcase("Wasm fibo"); +// +// auto const fibWasm = hexToBytes(kFibWasmHex); +// auto& engine = WasmEngine::instance(); +// HostFunctions hfs; +// +// auto const re = engine.run(fibWasm, hfs, 10'000'000, "fib", wasmParams(10)); +// +// checkResult(re, 55, 1'137); +// } +// */ +// +// void +// testEscrowWasmDN() +// { +// testcase("escrow wasm devnet test"); +// +// auto const allHFWasm = hexToBytes(kAllHostFunctionsWasmHex); +// +// using namespace test::jtx; +// Env env{*this}; +// { +// TestHostFunctions hfs(env); +// auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName); +// checkResult(re, 1, 50'207); +// } +// +// { +// // max() gas +// TestHostFunctions hfs(env); +// auto re = runEscrowWasm( +// allHFWasm, hfs, std::numeric_limits::max(), escrowFunctionName); +// checkResult(re, 1, 50'207); +// } +// +// { // fail because trying to access nonexistent field +// struct FieldNotFoundHostFunctions : public TestHostFunctions +// { +// explicit FieldNotFoundHostFunctions(Env& env) : TestHostFunctions(env) +// { +// } +// [[nodiscard]] std::expected +// getTxField(SField const& fname) const override +// { +// return std::unexpected(HostFunctionError::FieldNotFound); +// } +// }; +// +// FieldNotFoundHostFunctions hfs(env); +// auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName); +// checkResult(re, -201, 28'901); +// } +// +// { // fail because trying to allocate more than MAX_PAGES memory +// struct OversizedFieldHostFunctions : public TestHostFunctions +// { +// explicit OversizedFieldHostFunctions(Env& env) : TestHostFunctions(env) +// { +// } +// [[nodiscard]] std::expected +// getTxField(SField const& fname) const override +// { +// return Bytes((128 + 1) * 64 * 1024, 1); +// } +// }; +// +// OversizedFieldHostFunctions hfs(env); +// auto re = runEscrowWasm(allHFWasm, hfs, 100'000, escrowFunctionName); +// checkResult(re, -201, 28'901); +// } +// +// // This test use log output, so DEBUG_OUTPUT must be disabled. +// #ifndef DEBUG_OUTPUT +// { // fail because recursion too deep +// +// auto const deepWasm = hexToBytes(kDeepRecursionHex); +// +// TestHostFunctionsSink hfs(env); +// std::string const funcName(escrowFunctionName); +// auto re = runEscrowWasm(deepWasm, hfs, 1'000'000'000, funcName); +// BEAST_EXPECT(!re && re.error().ter); +// // std::cout << "bad case (deep recursion) result " << re.error() +// // << std::endl; +// +// auto const& sink = hfs.getSink(); +// auto countSubstr = [](std::string const& str, std::string const& substr) { +// std::size_t pos = 0; +// int occurrences = 0; +// while ((pos = str.find(substr, pos)) != std::string::npos) +// { +// occurrences++; +// pos += substr.length(); +// } +// return occurrences; +// }; +// +// auto const s = sink.messages().str(); +// BEAST_EXPECT(countSubstr(s, "wasm: ") == 1); +// BEAST_EXPECT(countSubstr(s, "trap: call stack exhausted") > 0); +// } +// #endif +// +// { // infinite loop +// auto const infiniteLoopWasm = hexToBytes(kInfiniteLoopWasmHex); +// std::string const funcName("loop"); +// TestHostFunctions hfs(env); +// +// // infinite loop should be caught and fail +// auto const re = runEscrowWasm(infiniteLoopWasm, hfs, 1'000'000, funcName); +// if (BEAST_EXPECT(!re.has_value())) +// { +// BEAST_EXPECT(re.error().ter == tecOUT_OF_GAS); +// } +// } +// +// // TODO: broken, fix after Rust re-arch. These three cases all build an +// // ImportVec by hand and call WasmEngine::run; the import set is now fixed by +// // the engine, so there is no way to under-provide it or desynchronise it from +// // the HostFunctions the VM was given. +// /* +// { +// // expected import not provided +// auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex); +// TestLedgerDataProvider hfs(env); +// ImportVec imports; +// WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn2", hfs); +// +// auto& engine = WasmEngine::instance(); +// +// auto re = engine.run( +// lgrSqnWasm, hfs, 1'000'000, escrowFunctionName, {}, imports, env.journal); +// +// BEAST_EXPECT(!re); +// } +// +// { +// // HF unsync between import and VM +// auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex); +// TestLedgerDataProvider hfs(env); +// TestLedgerDataProvider hfs2(env); +// ImportVec imports; +// WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs2); +// +// auto& engine = WasmEngine::instance(); +// +// auto re = engine.run( +// lgrSqnWasm, hfs, 1'000'000, escrowFunctionName, {}, imports, env.journal); +// +// BEAST_EXPECT(!re); +// } +// +// { +// // bad function name +// auto const lgrSqnWasm = hexToBytes(kLedgerSqnWasmHex); +// TestLedgerDataProvider hfs(env); +// ImportVec imports; +// WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", hfs); +// +// auto& engine = WasmEngine::instance(); +// auto re = engine.run(lgrSqnWasm, hfs, 1'000'000, "func1", {}, imports, env.journal); +// +// BEAST_EXPECT(!re); +// } +// */ +// } +// +// // TODO: testFloat is disabled until the float fixtures are regenerated. +// // +// // kFloatTestsWasmHex and kFloat0Hex were built against the old trace ABI, +// // where the trace_* host functions returned i32. They now return void, so +// // neither module instantiates and both blocks below fail with tecINTERNAL. +// // +// // Regenerating them is not just a rebuild: float_tests/ and float_0/ are +// // still pinned to xrpl-wasm-stdlib @ "renames" and use APIs that no longer +// // exist on xrpl-common-stdlib @ "error-and-trace" +// // (FLOAT_ROUNDING_MODES_TO_NEAREST became RoundingMode, +// // core::locator::Locator moved to fields::locator::Locator, and +// // trace_data/DataRepr became trace_float/trace_hex). The fixture sources +// // have to be ported first. The expected gas costs below are also stale and +// // will need recomputing once the modules run again. +// // +// // void +// // testFloat() +// // { +// // testcase("float point"); +// // +// // std::string const funcName(escrowFunctionName); +// // +// // using namespace test::jtx; +// // +// // Env env(*this); +// // { +// // auto const floatTestWasm = hexToBytes(kFloatTestsWasmHex); +// // +// // TestHostFunctions hfs(env); +// // auto re = runEscrowWasm(floatTestWasm, hfs, 200'000, funcName, +// // {}); checkResult(re, 1, 134'402); env.close(); +// // } +// // +// // { +// // auto const float0Wasm = hexToBytes(kFloat0Hex); +// // +// // TestHostFunctions hfs(env); +// // auto re = runEscrowWasm(float0Wasm, hfs, 100'000, funcName); +// // checkResult(re, 1, 2'775); +// // env.close(); +// // } +// // } +// +// void +// testCodecovWasm() +// { +// testcase("Codecov wasm test"); +// +// using namespace test::jtx; +// +// Env env{*this}; +// +// auto const codecovWasm = hexToBytes(kCodecovTestsWasmHex); +// TestHostFunctions hfs(env); +// +// auto const allowance = 124'173; +// auto re = runEscrowWasm(codecovWasm, hfs, allowance, escrowFunctionName); +// +// checkResult(re, 1, allowance); +// } +// +// void +// testDisabledFloat() +// { +// testcase("disabled float"); +// +// using namespace test::jtx; +// Env env{*this}; +// +// auto disabledFloatWasm = hexToBytes(kDisabledFloatHex); +// std::string const funcName(escrowFunctionName); +// TestHostFunctions hfs(env); +// +// { +// // f32 set constant, opcode disabled exception +// auto const re = runEscrowWasm(disabledFloatWasm, hfs, 1'000'000, funcName); +// if (BEAST_EXPECT(!re.has_value())) +// { +// BEAST_EXPECT(re.error().ter == tecFAILED_PROCESSING); +// } +// } +// +// { +// // f32 add, can't create module exception +// disabledFloatWasm[0x11e] = 0x92; +// auto const re = runEscrowWasm(disabledFloatWasm, hfs, 1'000'000, funcName); +// if (BEAST_EXPECT(!re.has_value())) +// { +// BEAST_EXPECT(re.error().ter == tecFAILED_PROCESSING); +// } +// } +// } +// +// void +// testWasmMemory() +// { +// testcase("Wasm additional memory limit tests"); +// BEAST_EXPECT(finishFunctionReturns(kMemoryPointerAtLimitHex, 1)); +// BEAST_EXPECT(!runFinish(kMemoryPointerOverLimitHex).has_value()); +// BEAST_EXPECT(!runFinish(kMemoryOffsetOverLimitHex).has_value()); +// BEAST_EXPECT(!runFinish(kMemoryEndOfWordOverLimitHex).has_value()); +// BEAST_EXPECT(finishFunctionReturns(kMemoryGrow0To1PageHex, 1)); +// BEAST_EXPECT(finishFunctionReturns(kMemoryGrow1To0PageHex, -1)); +// BEAST_EXPECT(finishFunctionReturns(kMemoryLastByteOf8MbHex, 1)); +// // Growing past the 8 MiB cap now traps ("growth operation limited") instead of +// // letting memory.grow answer -1, so the run fails rather than returning. +// BEAST_EXPECT(!runFinish(kMemoryGrow1MoreThan8MbHex).has_value()); +// BEAST_EXPECT(finishFunctionReturns(kMemoryGrow0MoreThan8MbHex, 1)); +// BEAST_EXPECT(!runFinish(kMemoryInit1MoreThan8MbHex).has_value()); +// BEAST_EXPECT(!runFinish(kMemoryNegativeAddressHex).has_value()); +// } +// +// void +// testWasmTable() +// { +// testcase("Wasm table limit tests"); +// BEAST_EXPECT(finishFunctionReturns(kTable64ElementsHex, 1)); +// // 65 elements is no longer over the cap: MAX_TABLE_ELEMENTS is 1024. The +// // boundary itself is covered by the engine's own test, since there is no +// // 1025-element fixture here. +// BEAST_EXPECT(finishFunctionReturns(kTable65ElementsHex, 1)); +// BEAST_EXPECT(!runFinish(kTable2TablesHex).has_value()); +// BEAST_EXPECT(finishFunctionReturns(kTable0ElementsHex, 1)); +// BEAST_EXPECT(!runFinish(kTableUintMaxHex).has_value()); +// } +// +// void +// testWasmProposal() +// { +// testcase("Wasm disabled proposal tests"); +// BEAST_EXPECT(!runFinish(kProposalMutableGlobalHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalGcStructNewHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalMultiValueHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalSignExtHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalFloatToIntHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalBulkMemoryHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalRefTypesHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalTailCallHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalExtendedConstHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalMultiMemoryHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalCustomPageSizesHex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalMemory64Hex).has_value()); +// BEAST_EXPECT(!runFinish(kProposalWideArithmeticHex).has_value()); +// } +// +// void +// testWasmTrap() +// { +// testcase("Wasm trap tests"); +// BEAST_EXPECT(!runFinish(kTrapDivideBy0Hex).has_value()); +// BEAST_EXPECT(!runFinish(kTrapIntOverflowHex).has_value()); +// BEAST_EXPECT(!runFinish(kTrapUnreachableHex).has_value()); +// BEAST_EXPECT(!runFinish(kTrapNullCallHex).has_value()); +// BEAST_EXPECT(!runFinish(kTrapFuncSigMismatchHex).has_value()); +// } +// +// void +// testWasmWasi() +// { +// testcase("Wasm Wasi tests"); +// BEAST_EXPECT(!runFinish(kWasiGetTimeHex).has_value()); +// BEAST_EXPECT(!runFinish(kWasiPrintHex).has_value()); +// } +// +// void +// testWasmSectionCorruption() +// { +// testcase("Wasm Section Corruption tests"); +// BEAST_EXPECT(!runFinish(kBadMagicNumberHex).has_value()); +// BEAST_EXPECT(!runFinish(kBadVersionNumberHex).has_value()); +// BEAST_EXPECT(!runFinish(kLyingHeaderHex).has_value()); +// BEAST_EXPECT(!runFinish(kNeverEndingNumberHex).has_value()); +// BEAST_EXPECT(!runFinish(kVectorLieHex).has_value()); +// BEAST_EXPECT(!runFinish(kSectionOrderingHex).has_value()); +// BEAST_EXPECT(!runFinish(kGhostPayloadHex).has_value()); +// BEAST_EXPECT(!runFinish(kJunkAfterSectionHex).has_value()); +// BEAST_EXPECT(!runFinish(kInvalidSectionIdHex).has_value()); +// BEAST_EXPECT(!runFinish(kLocalVariableBombHex).has_value()); +// } +// +// // TODO: broken, fix after Rust re-arch. Needs WasmEngine::check, whose replacement +// // preflightEscrowWasm takes no HostFunctions, and WasmEngine::run to observe that +// // the start function - not the export - is what burns the gas. +// /* +// void +// testStartFunctionLoop() +// { +// testcase("infinite loop in start function"); +// +// using namespace test::jtx; +// Env env(*this); +// +// auto const startLoopWasm = hexToBytes(kStartLoopHex); +// TestLedgerDataProvider hfs(env); +// ImportVec const imports; +// +// auto& engine = WasmEngine::instance(); +// auto checkRes = +// engine.check(startLoopWasm, hfs, escrowFunctionName, {}, imports, env.journal); +// BEAST_EXPECTS(checkRes == tesSUCCESS, transToken(checkRes)); +// +// auto result = +// engine.run(startLoopWasm, hfs, 1'000'000, escrowFunctionName, {}, imports, +// env.journal); +// auto resultTer = result.error().ter; +// BEAST_EXPECTS(resultTer == tecFAILED_PROCESSING, transToken(resultTer)); +// } +// */ +// +// void +// testReturnType() +// { +// using namespace test::jtx; +// Env env(*this); +// TestHostFunctions hfs(env); +// +// testcase("Wasm invalid return type"); +// +// // return int64. +// { // (module +// // (memory (export "memory") 1) +// // (func (export "finish") (result i64) +// // i64.const 0x100000000)) +// auto const wasmHex = +// "0061736d010000000105016000017e030201000503010001" +// "071302066d656d6f727902000666696e69736800000a0a01" +// "08004280808080100b"; +// auto const wasm = hexToBytes(wasmHex); +// auto const re = runEscrowWasm(wasm, hfs, 100'000, escrowFunctionName); +// BEAST_EXPECT(!re); +// } +// +// // return void. wasmi return execution error +// { //(module +// // (type (;0;) (func)) +// // (func (;0;) (type 0) +// // return) +// // (memory (;0;) 1) +// // (export "memory" (memory 0)) +// // (export "finish" (func 0))) +// auto const wasmHex = +// "0061736d01000000010401600000030201000503010001071302066d656d6f" +// "727902000666696e69736800000a050103000f0b"; +// auto const wasm = hexToBytes(wasmHex); +// auto const re = runEscrowWasm(wasm, hfs, 100'000, escrowFunctionName); +// BEAST_EXPECT(!re); +// } +// +// // return i32, i32. wasmi doesn't create module +// { //(module +// // (memory (export "memory") 1) +// // (func (export "finish") (result i32 i32) +// // i32.const 0x10000000 +// // i32.const 0x100000FF)) +// auto const wasmHex = +// "0061736d010000000106016000027f7f030201000503010001071302066d65" +// "6d6f727902000666696e69736800000a10010e0041808080800141ff818080" +// "010b"; +// auto const wasm = hexToBytes(wasmHex); +// auto const re = runEscrowWasm(wasm, hfs, 100'000, escrowFunctionName); +// BEAST_EXPECT(!re); +// } +// } +// +// void +// testParameterType() +// { +// using namespace test::jtx; +// Env env(*this); +// TestHostFunctions hfs(env); +// +// testcase("Wasm invalid params"); +// +// // (module +// // (memory (export "memory") 1) +// // (func $test1 (export "test1") (param i32) (result i32) +// // i32.const 1000) +// // (func $test2 (export "test2") (param i32 i32) (result i32) +// // i32.const 1001)) +// auto const wasmHex = +// "0061736d01000000010c0260017f017f60027f7f017f03030200010503010001071a03066d656d6f727902" +// "00057465737431000005746573743200010a0d02050041e8070b050041e9070b"; +// auto const wasm = hexToBytes(wasmHex); +// +// // no params. An export that wants any is refused, since runEscrowWasm has +// // none to give it. +// { +// auto const re = runEscrowWasm(wasm, hfs, 100'000, "test1"); +// BEAST_EXPECT(!re); +// } +// +// { +// auto const re = runEscrowWasm(wasm, hfs, 100'000, "test2"); +// BEAST_EXPECT(!re); +// } +// +// // TODO: broken, fix after Rust re-arch. The good-params control and the +// // wrong-arity / wrong-type cases below all need to pass parameters, which +// // runEscrowWasm cannot do. Without the positive case the two checks above +// // only show that the export is refused, not that it would have run. +// /* +// // good params, module is working properly +// { +// auto const re = runEscrowWasm(wasm, hfs, 100'000, "test2", wasmParams(2, 10)); +// BEAST_EXPECT(re && re->result == 1001 && re->cost == 37); +// } +// +// // more params +// { +// auto const re = runEscrowWasm(wasm, hfs, 100'000, "test1", wasmParams(0, 1)); +// BEAST_EXPECT(!re); +// } +// +// // less params +// { +// auto const re = runEscrowWasm(wasm, hfs, 100'000, "test2", wasmParams(1)); +// BEAST_EXPECT(!re); +// } +// +// // invalid type +// { +// auto const re = +// runEscrowWasm(wasm, hfs, 100'000, "test1", wasmParams(std::int64_t(15))); +// BEAST_EXPECT(!re); +// } +// */ +// } +// +// void +// testSwapBytes() +// { +// testcase("Wasm swap bytes"); +// +// uint64_t const swapDataU64 = 0x123456789abcdeffull; +// uint64_t const reverseSwapDataU64 = 0xffdebc9a78563412ull; +// int64_t const swapDataI64 = 0x123456789abcdeffll; +// int64_t const reverseSwapDataI64 = 0xffdebc9a78563412ll; +// +// uint32_t const swapDataU32 = 0x12789aff; +// uint32_t const reverseSwapDataU32 = 0xff9a7812; +// int32_t const swapDataI32 = 0x12789aff; +// int32_t const reverseSwapDataI32 = 0xff9a7812; +// +// uint16_t const swapDataU16 = 0x12ff; +// uint16_t const reverseSwapDataU16 = 0xff12; +// int16_t const swapDataI16 = 0x12ff; +// int16_t const reverseSwapDataI16 = 0xff12; +// +// uint64_t b1 = swapDataU64; +// int64_t b2 = swapDataI64; +// b1 = adjustWasmEndianessHlp(b1); +// b2 = adjustWasmEndianessHlp(b2); +// BEAST_EXPECT(b1 == reverseSwapDataU64); +// BEAST_EXPECT(b2 == reverseSwapDataI64); +// b1 = adjustWasmEndianessHlp(b1); +// b2 = adjustWasmEndianessHlp(b2); +// BEAST_EXPECT(b1 == swapDataU64); +// BEAST_EXPECT(b2 == swapDataI64); +// +// uint32_t b3 = swapDataU32; +// int32_t b4 = swapDataI32; +// b3 = adjustWasmEndianessHlp(b3); +// b4 = adjustWasmEndianessHlp(b4); +// BEAST_EXPECT(b3 == reverseSwapDataU32); +// BEAST_EXPECT(b4 == reverseSwapDataI32); +// b3 = adjustWasmEndianessHlp(b3); +// b4 = adjustWasmEndianessHlp(b4); +// BEAST_EXPECT(b3 == swapDataU32); +// BEAST_EXPECT(b4 == swapDataI32); +// +// uint16_t b5 = swapDataU16; +// int16_t b6 = swapDataI16; +// b5 = adjustWasmEndianessHlp(b5); +// b6 = adjustWasmEndianessHlp(b6); +// BEAST_EXPECT(b5 == reverseSwapDataU16); +// BEAST_EXPECT(b6 == reverseSwapDataI16); +// b5 = adjustWasmEndianessHlp(b5); +// b6 = adjustWasmEndianessHlp(b6); +// BEAST_EXPECT(b5 == swapDataU16); +// BEAST_EXPECT(b6 == swapDataI16); +// } +// +// // TODO: broken, fix after Rust re-arch. Builds a 1000-entry parameter vector and +// // calls arbitrary exports through WasmEngine::run; runEscrowWasm passes no +// // parameters, so the wasmi arity limit these cases straddle is unreachable. +// /* +// void +// testManyParams() +// { +// testcase("Wasm Many params"); +// +// auto const params1k = hexToBytes(kThousandParamsHex); +// auto const params1k1 = hexToBytes(kThousand1ParamsHex); +// +// using namespace test::jtx; +// +// Env env{*this}; +// TestHostFunctions hfs(env); +// auto imports = createWasmImport(hfs); +// +// // add 1k parameter (max that wasmi support) +// std::vector params; +// params.reserve(1000); +// for (int i = 0; i < 1000; ++i) +// params.push_back({.type = WasmTypes::WtI32, .of = {.i32 = 2 * i}}); +// +// auto& engine = WasmEngine::instance(); +// { +// auto re = engine.run(params1k, hfs, 1'000'000, "test", params, imports, env.journal); +// BEAST_EXPECT(re && re->result == 999000); +// } +// +// // add 1 more parameter, module can't be created now +// params.push_back({.type = WasmTypes::WtI32, .of = {.i32 = 2 * 1000}}); +// { +// auto re = engine.run(params1k1, hfs, 1'000'000, "test", params, imports, +// env.journal); BEAST_EXPECT(!re); +// } +// +// // function that create 10k local variables +// auto const locals10k = hexToBytes(kLocals10kHex); +// { +// auto re = engine.run( +// locals10k, hfs, 1'000'000, "test", wasmParams(0, 1), imports, env.journal); +// BEAST_EXPECT(re && re->result == 890'489'442); +// } +// +// // module has 5k functions +// auto const functions5k = hexToBytes(kFunctions5kHex); +// { +// auto re = engine.run( +// functions5k, hfs, 1'000'000, "test0001", wasmParams(2, 3), imports, env.journal); +// BEAST_EXPECT(re && re->result == 5); +// } +// +// env.close(); +// } +// */ +// +// // TODO: broken, fix after Rust re-arch. Sweeps the reserved opcode space by +// // patching a fixture and running its "all_instructions" export through +// // WasmEngine::run with a hand-built import set. runEscrowWasm only calls +// // escrow_finish, so the fixture cannot be driven. Restoring this needs +// // and back at the top of the file. +// // clang-format off +// /* +// void +// testOpcodes() +// { +// using namespace test::jtx; +// +// unsigned const reserved = 64; +// std::uint8_t const nop = 0x01; +// std::array const codeMarker = { +// nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop}; +// auto const opcReserved = hexToBytes(kOpcReservedHex); +// +// Env env{*this}; +// auto& engine = WasmEngine::instance(); +// +// TestHostFunctions hfs(env); +// auto imports = createWasmImport(hfs); +// env.close(); +// +// { +// auto run = [&](std::vector const& code, +// bool good = false, +// int64_t cost = -1, +// std::source_location const location = std::source_location::current()) +// { +// auto const lineStr = " (" + std::to_string(location.line()) + ")"; +// auto re = +// engine.run(code, hfs, 1'000'000, "all_instructions", {}, imports, +// env.journal); +// if (BEAST_EXPECTS(re.has_value() == good, transToken(re.error().ter) + lineStr) +// && +// good) +// BEAST_EXPECTS(re->cost == cost, std::to_string(re->cost) + lineStr); +// }; +// +// // 1 byte instruction +// auto test = [&](std::uint8_t start, +// std::uint8_t finish, +// bool good = false, +// int64_t cost = -1, +// std::source_location const location = +// std::source_location::current()) { +// auto const lineStr = " (" + std::to_string(location.line()) + ")"; +// auto code = opcReserved; +// auto codeRange = std::ranges::search(code, codeMarker); +// if (!BEAST_EXPECTS(!codeRange.empty(), lineStr)) +// return; +// +// auto it = codeRange.begin(); +// for (std::uint16_t i = start; i <= finish; ++i) +// { +// *it = i; +// run(code, good, cost, location); +// } +// }; +// +// // 2 bytes instruction +// auto test2 = [&](std::uint8_t major, +// std::uint16_t start, +// std::uint16_t finish, +// bool good = false, +// int64_t cost = -1, +// std::source_location const location = +// std::source_location::current()) { +// auto const lineStr = " (" + std::to_string(location.line()) + ")"; +// auto code = opcReserved; +// auto codeRange = std::ranges::search(code, codeMarker); +// if (!BEAST_EXPECTS(!codeRange.empty(), lineStr)) +// return; +// +// auto it = codeRange.begin(); +// *it++ = major; +// for (std::uint16_t i = start; i <= finish; ++i) +// { +// auto it2 = it; +// uleb128(it2, i); +// run(code, good, cost, location); +// } +// }; +// +// // multibytes instructions +// auto testMB = [&](std::vector const& codeSnap, +// bool good = false, +// int64_t cost = -1, +// std::source_location const location = +// std::source_location::current()) { +// auto const lineStr = " (" + std::to_string(location.line()) + ")"; +// auto code = opcReserved; +// auto codeRange = std::ranges::search(code, codeMarker); +// if (!BEAST_EXPECTS(!codeRange.empty(), lineStr)) +// return; +// +// if (!BEAST_EXPECTS(codeSnap.size() < reserved, lineStr)) +// return; +// auto it = codeRange.begin(); +// for (auto x : codeSnap) +// *it++ = x; +// run(code, good, cost, location); +// }; +// +// // normal run +// testcase("Wasm reserved opcodes main"); +// test(nop, nop, true, 534); +// +// // reserved main +// test(0x06, 0x0A); +// test(0x12, 0x19); +// test(0x25, 0x27); +// test(0xC0, 0xFA); +// test(0xFF, 0xFF); +// +// // reserved gc, string +// testcase("Wasm reserved opcodes gc"); +// test2(0xFB, 0x00, 0xBF); // not supported by compiler +// +// // reserved FC +// testcase("Wasm reserved opcodes FC"); +// test2(0xFC, 0x00, 0x07); // floats, disabled +// test2(0xFC, 0x12, 0x1F); +// +// // reserved SIMD +// testcase("Wasm reserved opcodes SIMD"); +// test2(0xFD, 0x9A, 0x9A); +// test2(0xFD, 0xA2, 0xA2); +// test2(0xFD, 0xA5, 0xA6); +// test2(0xFD, 0xAF, 0xB0); +// test2(0xFD, 0xB2, 0xB4); +// test2(0xFD, 0xB8, 0xB8); +// test2(0xFD, 0xC2, 0xC2); +// test2(0xFD, 0xC5, 0xC6); +// test2(0xFD, 0xCF, 0xD0); +// test2(0xFD, 0xD2, 0xD4); +// test2(0xFD, 0xE2, 0xE2); +// test2(0xFD, 0xEE, 0xEE); +// test2(0xFD, 0x115, 0x12F); +// +// testcase("Wasm opcodes THREADS"); +// test2(0xFE, 0x00, 0x4F); // not supported by compiler +// +// // FC mem instructions +// testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x04, 0xFC, 0x08, 0x00, 0x00}); // memory.init +// testMB({0xFC, 0x09, 0x00}); // data.drop +// testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0xFC, 0x0A, 0x00, 0x00}); // memory.copy +// testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0xFC, 0x0B, 0x00}); // memory.fill +// testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0xFC, 0x0C, 0x00, 0x00}); // table.init +// testMB({0xFC, 0x0D, 0x00}); // elem.drop +// testMB({0x41, 0x00, 0x41, 0x00, 0x41, 0x00, 0xFC, 0x0E, 0x00, 0x00}); // table.copy +// testMB({0xD2, 0x00, 0x41, 0x00, 0xFC, 0x0F, 0x00, 0x1A}); // table.grow +// testMB({0x1A, 0xFC, 0x10, 0x00, 0x1A}); // table.size +// testMB({0x41, 0x00, 0xD2, 0x00, 0x41, 0x00, 0xFC, 0x11, 0x00}); // table.fill +// +// testcase("Wasm opcodes SIMD"); +// // clang-format off +// +// // generated by auggie +// // SIMD instructions +// testMB({0x41, 0x00, 0xFD, 0x00, 0x04, 0x00, 0x1A}); // v128.load +// testMB({0x41, 0x00, 0xFD, 0x01, 0x03, 0x00, 0x1A}); // v128.load8x8_s +// testMB({0x41, 0x00, 0xFD, 0x02, 0x03, 0x00, 0x1A}); // v128.load8x8_u +// testMB({0x41, 0x00, 0xFD, 0x03, 0x03, 0x00, 0x1A}); // v128.load16x4_s +// testMB({0x41, 0x00, 0xFD, 0x04, 0x03, 0x00, 0x1A}); // v128.load16x4_u +// testMB({0x41, 0x00, 0xFD, 0x05, 0x03, 0x00, 0x1A}); // v128.load32x2_s +// testMB({0x41, 0x00, 0xFD, 0x06, 0x03, 0x00, 0x1A}); // v128.load32x2_u +// testMB({0x41, 0x00, 0xFD, 0x07, 0x00, 0x00, 0x1A}); // v128.load8_splat +// testMB({0x41, 0x00, 0xFD, 0x08, 0x01, 0x00, 0x1A}); // v128.load16_splat +// testMB({0x41, 0x00, 0xFD, 0x09, 0x02, 0x00, 0x1A}); // v128.load32_splat +// testMB({0x41, 0x00, 0xFD, 0x0A, 0x03, 0x00, 0x1A}); // v128.load64_splat +// testMB({0x41, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0B, 0x04, 0x00}); // +// v128.store +// testMB({0xFD, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, +// 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1A}); // v128.const +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0D, 0x00, 0x01, +// 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, +// 0x0F, 0x1A}); // i8x16.shuffle +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0E, +// 0x1A}); // i8x16.swizzle +// testMB({0x41, 0x2A, 0xFD, 0x0F, 0x1A}); // i8x16.splat testMB({0x41, 0x2A, 0xFD, +// 0x10, 0x1A}); // i16x8.splat +// testMB({0x41, 0x2A, 0xFD, 0x11, 0x1A}); // i32x4.splat testMB({0x42, 0x2A, 0xFD, +// 0x12, 0x1A}); // i64x2.splat +// +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x15, 0x00, 0x1A}); // +// i8x16.extract_lane_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x16, 0x00, 0x1A}); // +// i8x16.extract_lane_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2A, 0xFD, 0x17, 0x00, 0x1A}); // +// i8x16.replace_lane +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x18, 0x00, 0x1A}); // +// i16x8.extract_lane_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x19, 0x00, 0x1A}); // +// i16x8.extract_lane_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2A, 0xFD, 0x1A, 0x00, 0x1A}); // +// i16x8.replace_lane +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x1B, 0x00, 0x1A}); // +// i32x4.extract_lane +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2A, 0xFD, 0x1C, 0x00, 0x1A}); // +// i32x4.replace_lane +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x1D, 0x00, 0x1A}); // +// i64x2.extract_lane +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x2A, 0xFD, 0x1E, 0x00, 0x1A}); // +// i64x2.replace_lane +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x1F, 0x00, 0x1A}); // +// f32x4.extract_lane +// testMB( +// {0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x80, 0x3F, 0xFD, 0x20, 0x00, 0x1A}); +// // f32x4.replace_lane +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x21, 0x00, 0x1A}); // +// f64x2.extract_lane +// testMB( +// {0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0xFD, 0x22, +// 0x00, 0x1A}); // f64x2.replace_lane +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x23, +// 0x1A}); // i8x16.eq +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x24, +// 0x1A}); // i8x16.ne +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x25, +// 0x1A}); // i8x16.lt_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x26, +// 0x1A}); // i8x16.lt_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x27, +// 0x1A}); // i8x16.gt_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x28, +// 0x1A}); // i8x16.gt_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x29, +// 0x1A}); // i8x16.le_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2A, +// 0x1A}); // i8x16.le_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2B, +// 0x1A}); // i8x16.ge_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2C, +// 0x1A}); // i8x16.ge_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2D, +// 0x1A}); // i16x8.eq +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2E, +// 0x1A}); // i16x8.ne +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x2F, +// 0x1A}); // i16x8.lt_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x30, +// 0x1A}); // i16x8.lt_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x31, +// 0x1A}); // i16x8.gt_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x32, +// 0x1A}); // i16x8.gt_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x33, +// 0x1A}); // i16x8.le_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x34, +// 0x1A}); // i16x8.le_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x35, +// 0x1A}); // i16x8.ge_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x36, +// 0x1A}); // i16x8.ge_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x37, +// 0x1A}); // i32x4.eq +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x38, +// 0x1A}); // i32x4.ne +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x39, +// 0x1A}); // i32x4.lt_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3A, +// 0x1A}); // i32x4.lt_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3B, +// 0x1A}); // i32x4.gt_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3C, +// 0x1A}); // i32x4.gt_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3D, +// 0x1A}); // i32x4.le_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3E, +// 0x1A}); // i32x4.le_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x3F, +// 0x1A}); // i32x4.ge_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x40, +// 0x1A}); // i32x4.ge_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x4D, 0x1A}); // v128.not +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x4E, +// 0x1A}); // v128.and +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x4F, +// 0x1A}); // v128.andnot +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x50, +// 0x1A}); // v128.or +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x51, +// 0x1A}); // v128.xor +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, +// 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0xFD, 0x52, 0x1A}); // v128.bitselect +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x53, 0x1A}); // +// v128.any_true +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x60, 0x1A}); // i8x16.abs +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x61, 0x1A}); // i8x16.neg +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x62, 0x1A}); // +// i8x16.popcnt +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x63, 0x1A}); // +// i8x16.all_true +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x64, 0x1A}); // +// i8x16.bitmask +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x6B, 0x1A}); // +// i8x16.shl +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x6C, 0x1A}); // +// i8x16.shr_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x6D, 0x1A}); // +// i8x16.shr_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x6E, +// 0x1A}); // i8x16.add +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x6F, +// 0x1A}); // i8x16.add_sat_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x70, +// 0x1A}); // i8x16.add_sat_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x71, +// 0x1A}); // i8x16.sub +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x72, +// 0x1A}); // i8x16.sub_sat_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x73, +// 0x1A}); // i8x16.sub_sat_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x76, +// 0x1A}); // i8x16.min_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x77, +// 0x1A}); // i8x16.min_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x78, +// 0x1A}); // i8x16.max_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x79, +// 0x1A}); // i8x16.max_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x7B, +// 0x1A}); // i8x16.avgr_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x80, 0x01, 0x1A}); // +// i16x8.abs +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x81, 0x01, 0x1A}); // +// i16x8.neg +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x83, 0x01, 0x1A}); // +// i16x8.all_true +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x84, 0x01, 0x1A}); // +// i16x8.bitmask +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x8B, 0x01, 0x1A}); // +// i16x8.shl +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x8C, 0x01, 0x1A}); // +// i16x8.shr_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0x8D, 0x01, 0x1A}); // +// i16x8.shr_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x8E, 0x01, +// 0x1A}); // i16x8.add +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x8F, 0x01, +// 0x1A}); // i16x8.add_sat_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x90, 0x01, +// 0x1A}); // i16x8.add_sat_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x91, 0x01, +// 0x1A}); // i16x8.sub +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x92, 0x01, +// 0x1A}); // i16x8.sub_sat_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x93, 0x01, +// 0x1A}); // i16x8.sub_sat_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x95, 0x01, +// 0x1A}); // i16x8.mul +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x96, 0x01, +// 0x1A}); // i16x8.min_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x97, 0x01, +// 0x1A}); // i16x8.min_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x98, 0x01, +// 0x1A}); // i16x8.max_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x99, 0x01, +// 0x1A}); // i16x8.max_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x9B, 0x01, +// 0x1A}); // i16x8.avgr_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xA0, 0x01, 0x1A}); // +// i32x4.abs +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xA1, 0x01, 0x1A}); // +// i32x4.neg +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xA3, 0x01, 0x1A}); // +// i32x4.all_true +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xA4, 0x01, 0x1A}); // +// i32x4.bitmask +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xAB, 0x01, 0x1A}); // +// i32x4.shl +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xAC, 0x01, 0x1A}); // +// i32x4.shr_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xAD, 0x01, 0x1A}); // +// i32x4.shr_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xAE, 0x01, +// 0x1A}); // i32x4.add +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB1, 0x01, +// 0x1A}); // i32x4.sub +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB5, 0x01, +// 0x1A}); // i32x4.mul +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB6, 0x01, +// 0x1A}); // i32x4.min_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB7, 0x01, +// 0x1A}); // i32x4.min_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB8, 0x01, +// 0x1A}); // i32x4.max_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xB9, 0x01, +// 0x1A}); // i32x4.max_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xBA, 0x01, +// 0x1A}); // i32x4.dot_i16x8_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xC0, 0x01, 0x1A}); // +// i64x2.abs +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xC1, 0x01, 0x1A}); // +// i64x2.neg +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xC3, 0x01, 0x1A}); // +// i64x2.all_true +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xC4, 0x01, 0x1A}); // +// i64x2.bitmask +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xCB, 0x01, 0x1A}); // +// i64x2.shl +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xCC, 0x01, 0x1A}); // +// i64x2.shr_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x01, 0xFD, 0xCD, 0x01, 0x1A}); // +// i64x2.shr_u +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xCE, 0x01, +// 0x1A}); // i64x2.add +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD1, 0x01, +// 0x1A}); // i64x2.sub +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD5, 0x01, +// 0x1A}); // i64x2.mul +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD6, 0x01, +// 0x1A}); // i64x2.eq +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD7, 0x01, +// 0x1A}); // i64x2.ne +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD8, 0x01, +// 0x1A}); // i64x2.lt_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xD9, 0x01, +// 0x1A}); // i64x2.gt_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xDA, 0x01, +// 0x1A}); // i64x2.le_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, +// 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xDB, 0x01, +// 0x1A}); // i64x2.ge_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xF8, 0x01, 0x1A}); // +// i32x4.trunc_sat_f32x4_s +// testMB({0xFD, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xF9, 0x01, 0x1A}); // +// i32x4.trunc_sat_f32x4_u +// +// // clang-format on +// } +// } +// */ +// // clang-format on +// +// /* +// void +// run() override +// { +// testBadWasm(); +// testEscrowWasmDN(); +// // TODO: re-enable once the float fixtures are regenerated (see above) +// // testFloat(); +// +// testCodecovWasm(); +// // TODO: broken, fix after Rust re-arch +// // testDisabledFloat(); +// +// testWasmMemory(); +// testWasmTable(); +// testWasmProposal(); +// testWasmTrap(); +// testWasmWasi(); +// testWasmSectionCorruption(); +// +// // TODO: broken, fix after Rust re-arch +// // testStartFunctionLoop(); +// testReturnType(); +// testSwapBytes(); +// // TODO: broken, fix after Rust re-arch +// // testManyParams(); +// testParameterType(); +// +// // TODO: broken, fix after Rust re-arch +// // testOpcodes(); +// } +// }; +// +// BEAST_DEFINE_TESTSUITE(Wasm, app, xrpl); +// +// } // namespace xrpl::test