From ef5d335e09ba71c72fa2829b8d2f58489e3aad35 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 25 Nov 2025 02:44:18 +0530 Subject: [PATCH] update --- src/test/app/Wasm_test.cpp | 40 +- src/xrpld/app/wasm/HostFuncWrapper.h | 2 +- src/xrpld/app/wasm/WasmVM.h | 8 +- src/xrpld/app/wasm/{WamrVM.h => WasmiVM.h} | 63 ++- src/xrpld/app/wasm/detail/HostFuncImpl.cpp | 14 +- src/xrpld/app/wasm/detail/HostFuncWrapper.cpp | 21 +- src/xrpld/app/wasm/detail/WasmVM.cpp | 14 +- .../wasm/detail/{WamrVM.cpp => WasmiVM.cpp} | 366 ++++++------------ 8 files changed, 187 insertions(+), 341 deletions(-) rename src/xrpld/app/wasm/{WamrVM.h => WasmiVM.h} (86%) rename src/xrpld/app/wasm/detail/{WamrVM.cpp => WasmiVM.cpp} (71%) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index d03dfb270b..7b738fe8f2 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -5,7 +5,6 @@ #include #include -#include namespace ripple { namespace test { @@ -79,7 +78,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 6'912, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 2, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 3, std::to_string(re->cost)); } } @@ -169,7 +168,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 0, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 39, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 5, std::to_string(re->cost)); } env.close(); @@ -183,7 +182,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 5, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 78, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 10, std::to_string(re->cost)); } } @@ -201,7 +200,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 55, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 755, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 696, std::to_string(re->cost)); } } @@ -220,7 +219,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 34'432, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 157'452, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 145'573, std::to_string(re->cost)); } } @@ -245,7 +244,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 700, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 3'066'129, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 2'701'528, std::to_string(re->cost)); } } @@ -280,7 +279,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 332'205'984, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 270'282'552, std::to_string(re->cost)); } } @@ -316,7 +315,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 838, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 842, std::to_string(re->cost)); } env.close(); @@ -350,7 +349,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 40'098, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 842, std::to_string(re->cost)); } env.close(); @@ -375,7 +374,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 40'098, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 842, std::to_string(re->cost)); } } @@ -397,7 +396,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == -201, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 4'806, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 262, std::to_string(re->cost)); } } @@ -410,7 +409,7 @@ struct Wasm_test : public beast::unit_test::suite Expected getTxField(SField const& fname) override { - return Bytes((MAX_PAGES + 1) * 64 * 1024, 1); + return Bytes((128 + 1) * 64 * 1024, 1); } }; BadTestHostFunctions nfs(env); @@ -419,7 +418,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == -201, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 4'806, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 262, std::to_string(re->cost)); } } @@ -450,9 +449,8 @@ struct Wasm_test : public beast::unit_test::suite auto const s = sink.messages().str(); BEAST_EXPECT( - countSubstr(s, "WAMR Error: failure to call func") == 1); - BEAST_EXPECT( - countSubstr(s, "Exception: wasm operand stack overflow") > 0); + countSubstr(s, "WASMI Error: failure to call func") == 1); + BEAST_EXPECT(countSubstr(s, "exception: failure") > 0); } { @@ -500,7 +498,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 97'411, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 326, std::to_string(re->cost)); } env.close(); } @@ -515,7 +513,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 2'053, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 34, std::to_string(re->cost)); } env.close(); } @@ -629,7 +627,7 @@ struct Wasm_test : public beast::unit_test::suite Bytes const wasm(wasmStr.begin(), wasmStr.end()); TestHostFunctions hfs(env, 0); - auto const allowance = 152'981; + auto const allowance = 1'814; auto re = runEscrowWasm( wasm, ESCROW_FUNCTION_NAME, {}, &hfs, allowance, env.journal); @@ -699,7 +697,7 @@ struct Wasm_test : public beast::unit_test::suite testFloat(); testCodecovWasm(); - testDisabledFloat(); + // testDisabledFloat(); // perfTest(); } diff --git a/src/xrpld/app/wasm/HostFuncWrapper.h b/src/xrpld/app/wasm/HostFuncWrapper.h index eed68f65d5..13ed916e82 100644 --- a/src/xrpld/app/wasm/HostFuncWrapper.h +++ b/src/xrpld/app/wasm/HostFuncWrapper.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace ripple { diff --git a/src/xrpld/app/wasm/WasmVM.h b/src/xrpld/app/wasm/WasmVM.h index 4feb3850be..18379d6d4d 100644 --- a/src/xrpld/app/wasm/WasmVM.h +++ b/src/xrpld/app/wasm/WasmVM.h @@ -18,12 +18,11 @@ static std::string_view const W_PROC_EXIT = "proc_exit"; static std::string_view const ESCROW_FUNCTION_NAME = "finish"; -uint32_t const MAX_PAGES = 128; // 8MB = 64KB*128 +class WasmiEngine; -class WamrEngine; class WasmEngine { - std::unique_ptr const impl; + std::unique_ptr const impl; WasmEngine(); @@ -57,9 +56,6 @@ public: std::vector const& imports = {}, beast::Journal j = beast::Journal{beast::Journal::getNullSink()}); - std::int32_t - initMaxPages(std::int32_t def); - // Host functions helper functionality void* newTrap(std::string_view msg = {}); diff --git a/src/xrpld/app/wasm/WamrVM.h b/src/xrpld/app/wasm/WasmiVM.h similarity index 86% rename from src/xrpld/app/wasm/WamrVM.h rename to src/xrpld/app/wasm/WasmiVM.h index 41f12b9d5c..967a9319a6 100644 --- a/src/xrpld/app/wasm/WamrVM.h +++ b/src/xrpld/app/wasm/WasmiVM.h @@ -2,42 +2,42 @@ #include -#include -#include +#include +#include namespace ripple { -struct WamrResult +struct WasmiResult { wasm_val_vec_t r; bool f; // failure flag - WamrResult(unsigned N = 0) : r{0, nullptr, 0, 0, nullptr}, f(false) + WasmiResult(unsigned N = 0) : r{0, nullptr}, f(false) { if (N) wasm_val_vec_new_uninitialized(&r, N); } - ~WamrResult() + ~WasmiResult() { if (r.size) wasm_val_vec_delete(&r); } - WamrResult(WamrResult const&) = delete; - WamrResult& - operator=(WamrResult const&) = delete; + WasmiResult(WasmiResult const&) = delete; + WasmiResult& + operator=(WasmiResult const&) = delete; - WamrResult(WamrResult&& o) + WasmiResult(WasmiResult&& o) { *this = std::move(o); } - WamrResult& - operator=(WamrResult&& o) + WasmiResult& + operator=(WasmiResult&& o) { r = o.r; - o.r = {0, nullptr, 0, 0, nullptr}; + o.r = {0, nullptr}; f = o.f; o.f = false; return *this; @@ -55,7 +55,6 @@ struct InstanceWrapper { wasm_extern_vec_t exports_; InstancePtr instance_; - wasm_exec_env_t execEnv_ = nullptr; beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); private: @@ -63,7 +62,6 @@ private: init( wasm_store_t* s, wasm_module_t* m, - int32_t maxPages, wasm_extern_vec_t* expt, wasm_extern_vec_t const& imports, beast::Journal j); @@ -79,8 +77,6 @@ public: InstanceWrapper( wasm_store_t* s, wasm_module_t* m, - int32_t maxPages, - int64_t gas, wasm_extern_vec_t const& imports, beast::Journal j); @@ -95,13 +91,11 @@ public: wmem getMem() const; - - std::int64_t - getGas() const; }; struct ModuleWrapper { + wasm_store_t* store_ = nullptr; ModulePtr module_; InstanceWrapper instanceWrap_; wasm_exporttype_vec_t exportTypes_; @@ -120,8 +114,6 @@ public: wasm_store_t* s, Bytes const& wasmBin, bool instantiate, - int32_t maxPages, - int64_t gas, std::vector const& imports, beast::Journal j); ~ModuleWrapper(); @@ -139,8 +131,6 @@ public: int addInstance( wasm_store_t* s, - int32_t maxPages, - int64_t gas, wasm_extern_vec_t const& imports = WASM_EMPTY_VEC); std::int64_t @@ -155,19 +145,21 @@ private: buildImports(wasm_store_t* s, std::vector const& imports); }; -class WamrEngine +class WasmiEngine { std::unique_ptr engine_; std::unique_ptr store_; std::unique_ptr moduleWrap_; - std::int32_t defMaxPages_ = -1; beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); std::mutex m_; // 1 instance mutex public: - WamrEngine(); - ~WamrEngine() = default; + WasmiEngine(); + ~WasmiEngine() = default; + + static std::unique_ptr + init(); Expected, TER> run(Bytes const& wasmCode, @@ -186,9 +178,6 @@ public: std::vector const& imports, beast::Journal j); - std::int32_t - initMaxPages(std::int32_t def); - std::int64_t getGas(); @@ -261,19 +250,19 @@ private: add_param(std::vector& in, int64_t p); template - inline WamrResult + inline WasmiResult call(std::string_view func, Types&&... args); template - inline WamrResult + inline WasmiResult call(FuncInfo const& f, Types&&... args); template - inline WamrResult + inline WasmiResult call(FuncInfo const& f, std::vector& in); template - inline WamrResult + inline WasmiResult call( FuncInfo const& f, std::vector& in, @@ -281,7 +270,7 @@ private: Types&&... args); template - inline WamrResult + inline WasmiResult call( FuncInfo const& f, std::vector& in, @@ -289,7 +278,7 @@ private: Types&&... args); template - inline WamrResult + inline WasmiResult call( FuncInfo const& f, std::vector& in, @@ -298,7 +287,7 @@ private: Types&&... args); template - inline WamrResult + inline WasmiResult call( FuncInfo const& f, std::vector& in, diff --git a/src/xrpld/app/wasm/detail/HostFuncImpl.cpp b/src/xrpld/app/wasm/detail/HostFuncImpl.cpp index b48dd4bcf1..e61d39f9aa 100644 --- a/src/xrpld/app/wasm/detail/HostFuncImpl.cpp +++ b/src/xrpld/app/wasm/detail/HostFuncImpl.cpp @@ -7,7 +7,6 @@ #ifdef _DEBUG // #define DEBUG_OUTPUT 1 -// #define DEBUG_OUTPUT_WAMR 1 #endif namespace ripple { @@ -723,7 +722,7 @@ WasmHostFunctionsImpl::trace( #endif if (!asHex) { - j << "WAMR TRACE (" << leKey.key << "): " << msg << " " + j << "HF TRACE (" << leKey.key << "): " << msg << " " << std::string_view( reinterpret_cast(data.data()), data.size()); } @@ -733,7 +732,7 @@ WasmHostFunctionsImpl::trace( hex.reserve(data.size() * 2); boost::algorithm::hex( data.begin(), data.end(), std::back_inserter(hex)); - j << "WAMR DEV TRACE (" << leKey.key << "): " << msg << " " << hex; + j << "HF DEV TRACE (" << leKey.key << "): " << msg << " " << hex; } return msg.size() + data.size() * (asHex ? 2 : 1); @@ -747,7 +746,7 @@ WasmHostFunctionsImpl::traceNum(std::string_view const& msg, int64_t data) #else auto j = getJournal().trace(); #endif - j << "WAMR TRACE NUM(" << leKey.key << "): " << msg << " " << data; + j << "HF TRACE NUM(" << leKey.key << "): " << msg << " " << data; return msg.size() + sizeof(data); } @@ -764,8 +763,7 @@ WasmHostFunctionsImpl::traceAccount( auto const accountStr = toBase58(account); - j << "WAMR TRACE ACCOUNT(" << leKey.key << "): " << msg << " " - << accountStr; + j << "HF TRACE ACCOUNT(" << leKey.key << "): " << msg << " " << accountStr; return msg.size() + accountStr.size(); } @@ -780,7 +778,7 @@ WasmHostFunctionsImpl::traceFloat( auto j = getJournal().trace(); #endif auto const s = floatToString(data); - j << "WAMR TRACE FLOAT(" << leKey.key << "): " << msg << " " << s; + j << "HF TRACE FLOAT(" << leKey.key << "): " << msg << " " << s; return msg.size() + s.size(); } @@ -795,7 +793,7 @@ WasmHostFunctionsImpl::traceAmount( auto j = getJournal().trace(); #endif auto const amountStr = amount.getFullText(); - j << "WAMR TRACE AMOUNT(" << leKey.key << "): " << msg << " " << amountStr; + j << "HF TRACE AMOUNT(" << leKey.key << "): " << msg << " " << amountStr; return msg.size() + amountStr.size(); } diff --git a/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp b/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp index 566e7a4c98..6e849fe867 100644 --- a/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp +++ b/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include @@ -229,7 +228,7 @@ std::nullptr_t hfResult(wasm_val_vec_t* results, int32_t value) { results->data[0] = WASM_I32_VAL(value); - results->num_elems = 1; + // results->size = 1; return nullptr; } @@ -237,7 +236,7 @@ std::nullptr_t hfResult(wasm_val_vec_t* results, HostFunctionError value) { results->data[0] = WASM_I32_VAL(HfErrorToInt(value)); - results->num_elems = 1; + // results->size = 1; return nullptr; } @@ -1903,7 +1902,7 @@ testGetDataIncrement() { // test int32_t - wasm_val_vec_t params = {1, &values[0], 1, sizeof(wasm_val_t), nullptr}; + wasm_val_vec_t params = {1, &values[0]}; values[0] = WASM_I32_VAL(42); @@ -1915,7 +1914,7 @@ testGetDataIncrement() { // test int64_t - wasm_val_vec_t params = {1, &values[0], 1, sizeof(wasm_val_t), nullptr}; + wasm_val_vec_t params = {1, &values[0]}; values[0] = WASM_I64_VAL(1234); @@ -1927,7 +1926,7 @@ testGetDataIncrement() { // test SFieldCRef - wasm_val_vec_t params = {1, &values[0], 1, sizeof(wasm_val_t), nullptr}; + wasm_val_vec_t params = {1, &values[0]}; values[0] = WASM_I32_VAL(sfAccount.fieldCode); @@ -1939,7 +1938,7 @@ testGetDataIncrement() { // test Slice - wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + wasm_val_vec_t params = {2, &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(3); @@ -1952,7 +1951,7 @@ testGetDataIncrement() { // test string - wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + wasm_val_vec_t params = {2, &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(5); @@ -1972,7 +1971,7 @@ testGetDataIncrement() AccountID const id(calcAccountID( generateKeyPair(KeyType::secp256k1, generateSeed("alice")).first)); - wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + wasm_val_vec_t params = {2, &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(id.bytes); @@ -1988,7 +1987,7 @@ testGetDataIncrement() // test uint256 Hash h1 = sha512Half(Slice(buffer.data(), 8)); - wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + wasm_val_vec_t params = {2, &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(h1.bytes); @@ -2004,7 +2003,7 @@ testGetDataIncrement() // test Currency Currency const c = xrpCurrency(); - wasm_val_vec_t params = {2, &values[0], 2, sizeof(wasm_val_t), nullptr}; + wasm_val_vec_t params = {2, &values[0]}; values[0] = WASM_I32_VAL(0); values[1] = WASM_I32_VAL(c.bytes); diff --git a/src/xrpld/app/wasm/detail/WasmVM.cpp b/src/xrpld/app/wasm/detail/WasmVM.cpp index e1d5f8e8b8..d87b1444f6 100644 --- a/src/xrpld/app/wasm/detail/WasmVM.cpp +++ b/src/xrpld/app/wasm/detail/WasmVM.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -114,7 +114,7 @@ runEscrowWasm( { // create VM and set cost limit auto& vm = WasmEngine::instance(); - vm.initMaxPages(MAX_PAGES); + // vm.initMaxPages(MAX_PAGES); auto const ret = vm.run( wasmCode, @@ -153,7 +153,7 @@ preflightEscrowWasm( { // create VM and set cost limit auto& vm = WasmEngine::instance(); - vm.initMaxPages(MAX_PAGES); + // vm.initMaxPages(MAX_PAGES); auto const ret = vm.check( wasmCode, @@ -167,7 +167,7 @@ preflightEscrowWasm( //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -WasmEngine::WasmEngine() : impl(std::make_unique()) +WasmEngine::WasmEngine() : impl(std::make_unique()) { } @@ -202,12 +202,6 @@ WasmEngine::check( return impl->check(wasmCode, funcName, params, imports, j); } -std::int32_t -WasmEngine::initMaxPages(std::int32_t def) -{ - return impl->initMaxPages(def); -} - void* WasmEngine::newTrap(std::string_view msg) { diff --git a/src/xrpld/app/wasm/detail/WamrVM.cpp b/src/xrpld/app/wasm/detail/WasmiVM.cpp similarity index 71% rename from src/xrpld/app/wasm/detail/WamrVM.cpp rename to src/xrpld/app/wasm/detail/WasmiVM.cpp index d1b7fb694d..c3c1e300e4 100644 --- a/src/xrpld/app/wasm/detail/WamrVM.cpp +++ b/src/xrpld/app/wasm/detail/WasmiVM.cpp @@ -1,116 +1,18 @@ -#include +#include #include -#include #include #ifdef _DEBUG // #define DEBUG_OUTPUT 1 -// #define DEBUG_OUTPUT_WAMR 1 #endif - // #define SHOW_CALL_TIME 1 -#define DISABLE_WM_LOG 1 namespace ripple { namespace { -// LCOV_EXCL_START -static log_level_t -getLogLevel(beast::severities::Severity severity) -{ - using namespace beast::severities; - switch (severity) - { - case kTrace: - return WASM_LOG_LEVEL_VERBOSE; - case kDebug: - return WASM_LOG_LEVEL_DEBUG; - case kInfo: - case kWarning: - return WASM_LOG_LEVEL_WARNING; - case kError: - return WASM_LOG_LEVEL_ERROR; - default: - UNREACHABLE("WAMR invalid severity"); - [[fallthrough]]; - case kFatal: - case kNone: - break; - } - - return WASM_LOG_LEVEL_FATAL; -} - -static beast::severities::Severity -getLogLevel(uint32_t severity) -{ - using namespace beast::severities; - switch (severity) - { - case WASM_LOG_LEVEL_VERBOSE: - return kTrace; - case WASM_LOG_LEVEL_DEBUG: - return kDebug; - case WASM_LOG_LEVEL_WARNING: - return kWarning; - case WASM_LOG_LEVEL_ERROR: - return kError; - default: - UNREACHABLE("WAMR invalid reverse severity"); - [[fallthrough]]; - case WASM_LOG_LEVEL_FATAL: - break; - } - - return kFatal; -} - -// This function is called from WAMR to log messages. -extern "C" void -wamr_log_to_rippled( - uint32_t logLevel, - char const* file, - int line, - char const* fmt, - ...) -{ -#ifdef DISABLE_WM_LOG - return; -#endif - - beast::Journal j = WasmEngine::instance().getJournal(); - std::ostringstream oss; - - // Format the variadic args - if (file) - { - oss << "WAMR (" << file << ":" << line << "): "; - } - else - { - oss << "WAMR: "; - } - - va_list args; - va_start(args, fmt); - - char formatted[4096]; - vsnprintf(formatted, sizeof(formatted), fmt, args); - formatted[sizeof(formatted) - 1] = '\0'; - - va_end(args); - - oss << formatted; - - j.stream(getLogLevel(logLevel)) << oss.str(); -#ifdef DEBUG_OUTPUT_WAMR - std::cerr << oss.str() << std::endl; -#endif -} - void print_wasm_error(std::string_view msg, wasm_trap_t* trap, beast::Journal jlog) { @@ -125,13 +27,13 @@ print_wasm_error(std::string_view msg, wasm_trap_t* trap, beast::Journal jlog) if (trap) wasm_trap_message(trap, &error_message); - if (error_message.num_elems) + if (error_message.size) { - j << "WAMR Error: " << msg << ", " - << std::string_view(error_message.data, error_message.num_elems - 1); + j << "WASMI Error: " << msg << ", " + << std::string_view(error_message.data, error_message.size - 1); } else - j << "WAMR Error: " << msg; + j << "WASMI Error: " << msg; if (error_message.size) wasm_byte_vec_delete(&error_message); @@ -151,20 +53,13 @@ InstancePtr InstanceWrapper::init( wasm_store_t* s, wasm_module_t* m, - int32_t maxPages, wasm_extern_vec_t* expt, wasm_extern_vec_t const& imports, beast::Journal j) { wasm_trap_t* trap = nullptr; - InstantiationArgs inst_args{ - 128 * 1024, - 256 * 1024, - static_cast(maxPages > 0 ? maxPages : 0)}; - InstancePtr mi = InstancePtr( - wasm_instance_new_with_args_ex(s, m, &imports, &trap, &inst_args), - &wasm_instance_delete); + wasm_instance_new(s, m, &imports, &trap), &wasm_instance_delete); if (!mi || trap) { @@ -176,14 +71,12 @@ InstanceWrapper::init( } InstanceWrapper::InstanceWrapper() - : exports_{0, nullptr, 0, 0, nullptr} - , instance_(nullptr, &wasm_instance_delete) + : exports_{0, nullptr}, instance_(nullptr, &wasm_instance_delete) { } InstanceWrapper::InstanceWrapper(InstanceWrapper&& o) - : exports_{0, nullptr, 0, 0, nullptr} - , instance_(nullptr, &wasm_instance_delete) + : exports_{0, nullptr}, instance_(nullptr, &wasm_instance_delete) { *this = std::move(o); } @@ -191,16 +84,12 @@ InstanceWrapper::InstanceWrapper(InstanceWrapper&& o) InstanceWrapper::InstanceWrapper( wasm_store_t* s, wasm_module_t* m, - int32_t maxPages, - int64_t gas, wasm_extern_vec_t const& imports, beast::Journal j) : exports_ WASM_EMPTY_VEC - , instance_(init(s, m, maxPages, &exports_, imports, j)) - , execEnv_(wasm_instance_exec_env(instance_.get())) + , instance_(init(s, m, &exports_, imports, j)) , j_(j) { - wasm_runtime_set_instruction_count_limit(execEnv_, gas); } InstanceWrapper::~InstanceWrapper() @@ -218,11 +107,9 @@ InstanceWrapper::operator=(InstanceWrapper&& o) if (exports_.size) wasm_extern_vec_delete(&exports_); exports_ = o.exports_; - o.exports_ = {0, nullptr, 0, 0, nullptr}; + o.exports_ = {0, nullptr}; instance_ = std::move(o.instance_); - execEnv_ = o.execEnv_; - o.execEnv_ = nullptr; j_ = o.j_; @@ -245,12 +132,12 @@ InstanceWrapper::getFunc( if (!instance_) throw std::runtime_error("no instance"); - if (!export_types.num_elems) + if (!export_types.size) throw std::runtime_error("no export"); - if (export_types.num_elems != exports_.num_elems) + if (export_types.size != exports_.size) throw std::runtime_error("invalid export"); - for (unsigned i = 0; i < export_types.num_elems; ++i) + for (unsigned i = 0; i < export_types.size; ++i) { auto const* exp_type(export_types.data[i]); @@ -258,7 +145,7 @@ InstanceWrapper::getFunc( wasm_externtype_t const* exn_type = wasm_exporttype_type(exp_type); if (wasm_externtype_kind(exn_type) == WASM_EXTERN_FUNC) { - if (funcName == std::string_view(name->data, name->size - 1)) + if (funcName == std::string_view(name->data, name->size)) { auto* exn(exports_.data[i]); if (wasm_extern_kind(exn) != WASM_EXTERN_FUNC) @@ -286,7 +173,7 @@ InstanceWrapper::getMem() const throw std::runtime_error("no instance"); wasm_memory_t* mem = nullptr; - for (unsigned i = 0; i < exports_.num_elems; ++i) + for (unsigned i = 0; i < exports_.size; ++i) { auto* e(exports_.data[i]); if (wasm_extern_kind(e) == WASM_EXTERN_MEMORY) @@ -304,23 +191,12 @@ InstanceWrapper::getMem() const wasm_memory_data_size(mem)}; } -std::int64_t -InstanceWrapper::getGas() const -{ - return execEnv_ ? wasm_runtime_get_instruction_count_limit(execEnv_) : 0; -} - ////////////////////////////////////////////////////////////////////////////////////////////////////////////// ModulePtr ModuleWrapper::init(wasm_store_t* s, Bytes const& wasmBin, beast::Journal j) { - wasm_byte_vec_t const code{ - wasmBin.size(), - (char*)(wasmBin.data()), - wasmBin.size(), - sizeof(std::remove_reference_t::value_type), - nullptr}; + wasm_byte_vec_t const code{wasmBin.size(), (char*)(wasmBin.data())}; ModulePtr m = ModulePtr(wasm_module_new(s, &code), &wasm_module_delete); if (!m) throw std::runtime_error("can't create module"); @@ -329,14 +205,12 @@ ModuleWrapper::init(wasm_store_t* s, Bytes const& wasmBin, beast::Journal j) } ModuleWrapper::ModuleWrapper() - : module_(nullptr, &wasm_module_delete) - , exportTypes_{0, nullptr, 0, 0, nullptr} + : module_(nullptr, &wasm_module_delete), exportTypes_{0, nullptr} { } ModuleWrapper::ModuleWrapper(ModuleWrapper&& o) - : module_(nullptr, &wasm_module_delete) - , exportTypes_{0, nullptr, 0, 0, nullptr} + : module_(nullptr, &wasm_module_delete), exportTypes_{0, nullptr} { *this = std::move(o); } @@ -345,19 +219,15 @@ ModuleWrapper::ModuleWrapper( wasm_store_t* s, Bytes const& wasmBin, bool instantiate, - int32_t maxPages, - int64_t gas, std::vector const& imports, beast::Journal j) - : module_(init(s, wasmBin, j)) - , exportTypes_{0, nullptr, 0, 0, nullptr} - , j_(j) + : store_(s), module_(init(s, wasmBin, j)), exportTypes_{0, nullptr}, j_(j) { wasm_module_exports(module_.get(), &exportTypes_); if (instantiate) { auto wimports = buildImports(s, imports); - addInstance(s, maxPages, gas, wimports); + addInstance(s, wimports); wasm_extern_vec_delete(&wimports); } } @@ -374,12 +244,14 @@ ModuleWrapper::operator=(ModuleWrapper&& o) if (this == &o) return *this; + store_ = o.store_; + o.store_ = nullptr; module_ = std::move(o.module_); instanceWrap_ = std::move(o.instanceWrap_); if (exportTypes_.size) wasm_exporttype_vec_delete(&exportTypes_); exportTypes_ = o.exportTypes_; - o.exportTypes_ = {0, nullptr, 0, 0, nullptr}; + o.exportTypes_ = {0, nullptr}; j_ = o.j_; return *this; @@ -398,7 +270,6 @@ ModuleWrapper::makeImpParams(wasm_valtype_vec_t& v, WasmImportFunc const& imp) if (paramSize) { wasm_valtype_vec_new_uninitialized(&v, paramSize); - v.num_elems = paramSize; } else v = WASM_EMPTY_VEC; @@ -425,7 +296,6 @@ ModuleWrapper::makeImpReturn(wasm_valtype_vec_t& v, WasmImportFunc const& imp) if (imp.result) { wasm_valtype_vec_new_uninitialized(&v, 1); - v.num_elems = 1; switch (*imp.result) { case WT_I32: @@ -454,29 +324,26 @@ ModuleWrapper::buildImports( itDeleter(&importTypes, &wasm_importtype_vec_delete); wasm_extern_vec_t wimports = WASM_EMPTY_VEC; - if (!importTypes.num_elems) + if (!importTypes.size) return wimports; wasm_extern_vec_new_uninitialized(&wimports, importTypes.size); - wimports.num_elems = importTypes.num_elems; unsigned impCnt = 0; - for (unsigned i = 0; i < importTypes.num_elems; ++i) + for (unsigned i = 0; i < importTypes.size; ++i) { wasm_importtype_t const* importtype = importTypes.data[i]; - if (wasm_importtype_is_linked(importtype)) - { - // create a placeholder - wimports.data[i] = wasm_extern_new_empty( - s, wasm_externtype_kind(wasm_importtype_type(importtype))); - ++impCnt; - continue; - } // wasm_name_t const* mn = wasm_importtype_module(importtype); - // auto modName = std::string_view(mn->data, mn->num_elems - 1); + // auto modName = std::string_view(mn->data, mn->num_elems); wasm_name_t const* fn = wasm_importtype_name(importtype); - auto fieldName = std::string_view(fn->data, fn->num_elems - 1); + auto fieldName = std::string_view(fn->data, fn->size); + + wasm_externkind_t const itype = + wasm_externtype_kind(wasm_importtype_type(importtype)); + if ((itype) != WASM_EXTERN_FUNC) + throw std::runtime_error( + "Invalid import type " + std::to_string(itype)); // for multi-module support // if ((W_ENV != modName) && (W_HOST_LIB != modName)) @@ -511,13 +378,13 @@ ModuleWrapper::buildImports( // LCOV_EXCL_STOP } - if (imp.gas && !wasm_func_set_gas(func, imp.gas)) - { - // LCOV_EXCL_START - throw std::runtime_error( - "can't set gas for import function " + imp.name); - // LCOV_EXCL_STOP - } + // if (imp.gas && !wasm_func_set_gas(func, imp.gas)) + // { + // // LCOV_EXCL_START + // throw std::runtime_error( + // "can't set gas for import function " + imp.name); + // // LCOV_EXCL_STOP + // } wimports.data[i] = wasm_func_as_extern(func); ++impCnt; @@ -535,11 +402,11 @@ ModuleWrapper::buildImports( } } - if (impCnt != importTypes.num_elems) + if (impCnt != importTypes.size) { print_wasm_error( std::string("Imports not finished: ") + std::to_string(impCnt) + - "/" + std::to_string(importTypes.num_elems), + "/" + std::to_string(importTypes.size), nullptr, j_); } @@ -566,13 +433,9 @@ ModuleWrapper::getInstance(int) const } int -ModuleWrapper::addInstance( - wasm_store_t* s, - int32_t maxPages, - int64_t gas, - wasm_extern_vec_t const& imports) +ModuleWrapper::addInstance(wasm_store_t* s, wasm_extern_vec_t const& imports) { - instanceWrap_ = {s, module_.get(), maxPages, gas, imports, j_}; + instanceWrap_ = {s, module_.get(), imports, j_}; return 0; } @@ -589,30 +452,43 @@ ModuleWrapper::addInstance( std::int64_t ModuleWrapper::getGas() { - return instanceWrap_.getGas(); + if (!store_) + return 0; + std::uint64_t gas = 0; + wasm_store_get_fuel(store_, &gas); + return static_cast(gas); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // void -// WamrEngine::clearModules() +// WasmiEngine::clearModules() // { // modules.clear(); // store.reset(); // to free the memory before creating new store // store = {wasm_store_new(engine.get()), &wasm_store_delete}; // } -WamrEngine::WamrEngine() - : engine_(wasm_engine_new(), &wasm_engine_delete) - , store_(nullptr, &wasm_store_delete) +std::unique_ptr +WasmiEngine::init() +{ + wasm_config_t* config = wasm_config_new(); + if (!config) + return std::unique_ptr{ + nullptr, &wasm_engine_delete}; + wasmi_config_consume_fuel_set(config, true); + + return std::unique_ptr( + wasm_engine_new_with_config(config), &wasm_engine_delete); +} + +WasmiEngine::WasmiEngine() + : engine_(init()), store_(nullptr, &wasm_store_delete) { - wasm_runtime_set_default_running_mode(Mode_Interp); - wasm_runtime_set_log_level(WASM_LOG_LEVEL_FATAL); - // wasm_runtime_set_log_level(WASM_LOG_LEVEL_VERBOSE); } int -WamrEngine::addModule( +WasmiEngine::addModule( Bytes const& wasmCode, bool instantiate, int64_t gas, @@ -621,8 +497,19 @@ WamrEngine::addModule( moduleWrap_.reset(); store_.reset(); // to free the memory before creating new store store_ = {wasm_store_new(engine_.get()), &wasm_store_delete}; + + if (gas < 0) + gas = std::numeric_limits::max(); + wasmi_error_t* err = + wasm_store_set_fuel(store_.get(), static_cast(gas)); + if (err) + { + print_wasm_error("Error setting gas", nullptr, j_); + throw std::runtime_error("can't set gas"); + } + moduleWrap_ = std::make_unique( - store_.get(), wasmCode, instantiate, defMaxPages_, gas, imports, j_); + store_.get(), wasmCode, instantiate, imports, j_); if (!moduleWrap_) throw std::runtime_error("can't create module wrapper"); @@ -631,19 +518,19 @@ WamrEngine::addModule( } // int -// WamrEngine::addInstance() +// WasmiEngine::addInstance() // { -// return module->addInstance(store.get(), defMaxPages); +// return module->addInstance(store.get()); // } FuncInfo -WamrEngine::getFunc(std::string_view funcName) +WasmiEngine::getFunc(std::string_view funcName) { return moduleWrap_->getFunc(funcName); } std::vector -WamrEngine::convertParams(std::vector const& params) +WasmiEngine::convertParams(std::vector const& params) { std::vector v; v.reserve(params.size()); @@ -678,14 +565,14 @@ WamrEngine::convertParams(std::vector const& params) } int -WamrEngine::compareParamTypes( +WasmiEngine::compareParamTypes( wasm_valtype_vec_t const* ftp, std::vector const& p) { - if (ftp->num_elems != p.size()) - return std::min(ftp->num_elems, p.size()); + if (ftp->size != p.size()) + return std::min(ftp->size, p.size()); - for (unsigned i = 0; i < ftp->num_elems; ++i) + for (unsigned i = 0; i < ftp->size; ++i) { auto const t1 = wasm_valtype_kind(ftp->data[i]); auto const t2 = p[i].kind; @@ -697,7 +584,7 @@ WamrEngine::compareParamTypes( } void -WamrEngine::add_param(std::vector& in, int32_t p) +WasmiEngine::add_param(std::vector& in, int32_t p) { in.emplace_back(); auto& el(in.back()); @@ -706,7 +593,7 @@ WamrEngine::add_param(std::vector& in, int32_t p) } void -WamrEngine::add_param(std::vector& in, int64_t p) +WasmiEngine::add_param(std::vector& in, int64_t p) { in.emplace_back(); auto& el(in.back()); @@ -714,8 +601,8 @@ WamrEngine::add_param(std::vector& in, int64_t p) } template -WamrResult -WamrEngine::call(std::string_view func, Types&&... args) +WasmiResult +WasmiEngine::call(std::string_view func, Types&&... args) { // Lookup our export function auto f = getFunc(func); @@ -723,8 +610,8 @@ WamrEngine::call(std::string_view func, Types&&... args) } template -WamrResult -WamrEngine::call(FuncInfo const& f, Types&&... args) +WasmiResult +WasmiEngine::call(FuncInfo const& f, Types&&... args) { std::vector in; return call(f, in, std::forward(args)...); @@ -743,22 +630,17 @@ usecs() #endif template -WamrResult -WamrEngine::call(FuncInfo const& f, std::vector& in) +WasmiResult +WasmiEngine::call(FuncInfo const& f, std::vector& in) { // wasm_val_t rs[1] = {WASM_I32_VAL(0)}; - WamrResult ret(NR); + WasmiResult ret(NR); // if (NR) { wasm_val_vec_new_uninitialized(&ret, NR); // // wasm_val_vec_new(&ret, NR, &rs[0]); // ret = WASM_ARRAY_VEC(rs); } wasm_val_vec_t const inv = in.empty() ? wasm_val_vec_t WASM_EMPTY_VEC - : wasm_val_vec_t{ - in.size(), - in.data(), - in.size(), - sizeof(std::remove_reference_t::value_type), - nullptr}; + : wasm_val_vec_t{in.size(), in.data()}; #ifdef SHOW_CALL_TIME auto const start = usecs(); @@ -785,8 +667,8 @@ WamrEngine::call(FuncInfo const& f, std::vector& in) } template -WamrResult -WamrEngine::call( +WasmiResult +WasmiEngine::call( FuncInfo const& f, std::vector& in, std::int32_t p, @@ -797,8 +679,8 @@ WamrEngine::call( } template -WamrResult -WamrEngine::call( +WasmiResult +WasmiEngine::call( FuncInfo const& f, std::vector& in, std::int64_t p, @@ -809,8 +691,8 @@ WamrEngine::call( } template -WamrResult -WamrEngine::call( +WasmiResult +WasmiEngine::call( FuncInfo const& f, std::vector& in, uint8_t const* d, @@ -827,8 +709,8 @@ WamrEngine::call( } template -WamrResult -WamrEngine::call( +WasmiResult +WasmiEngine::call( FuncInfo const& f, std::vector& in, Bytes const& p, @@ -838,7 +720,7 @@ WamrEngine::call( } Expected, TER> -WamrEngine::run( +WasmiEngine::run( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, @@ -848,8 +730,6 @@ WamrEngine::run( beast::Journal j) { j_ = j; - wasm_runtime_set_log_level( - std::min(getLogLevel(j_.sink().threshold()), WASM_LOG_LEVEL_ERROR)); try { return runHlp(wasmCode, funcName, params, imports, hfs, gas); @@ -866,7 +746,7 @@ WamrEngine::run( } Expected, TER> -WamrEngine::runHlp( +WasmiEngine::runHlp( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, @@ -893,7 +773,7 @@ WamrEngine::runHlp( auto const f = getFunc(!funcName.empty() ? funcName : "_start"); auto const* ftp = wasm_functype_params(f.second); - // not const because passed directly to wamr function (which accept non + // not const because passed directly to VM function (which accept non // const) auto p = convertParams(params); @@ -905,7 +785,7 @@ WamrEngine::runHlp( if (res.f) throw std::runtime_error("<" + std::string(funcName) + "> failure"); - else if (!res.r.num_elems) + else if (!res.r.size) throw std::runtime_error( "<" + std::string(funcName) + "> return nothing"); @@ -920,13 +800,13 @@ WamrEngine::runHlp( // #else // auto j = j_.debug(); // #endif - // j << "WAMR Res: " << ret.result << " cost: " << ret.cost << std::endl; + // j << "WASMI Res: " << ret.result << " cost: " << ret.cost << std::endl; return ret; } NotTEC -WamrEngine::check( +WasmiEngine::check( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, @@ -934,8 +814,7 @@ WamrEngine::check( beast::Journal j) { j_ = j; - wasm_runtime_set_log_level( - std::min(getLogLevel(j_.sink().threshold()), WASM_LOG_LEVEL_ERROR)); + try { return checkHlp(wasmCode, funcName, params, imports); @@ -953,7 +832,7 @@ WamrEngine::check( } NotTEC -WamrEngine::checkHlp( +WasmiEngine::checkHlp( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, @@ -982,27 +861,20 @@ WamrEngine::checkHlp( return tesSUCCESS; } -std::int32_t -WamrEngine::initMaxPages(std::int32_t def) -{ - defMaxPages_ = def; - return def; -} - std::int64_t -WamrEngine::getGas() +WasmiEngine::getGas() { return moduleWrap_ ? moduleWrap_->getGas() : 0; } wmem -WamrEngine::getMem() const +WasmiEngine::getMem() const { return moduleWrap_ ? moduleWrap_->getMem() : wmem(); } InstanceWrapper const& -WamrEngine::getRT(int m, int i) +WasmiEngine::getRT(int m, int i) { if (!moduleWrap_) throw std::runtime_error("no module"); @@ -1010,11 +882,11 @@ WamrEngine::getRT(int m, int i) } int32_t -WamrEngine::allocate(int32_t sz) +WasmiEngine::allocate(int32_t sz) { auto res = call<1>(W_ALLOC, static_cast(sz)); - if (res.f || !res.r.num_elems || (res.r.data[0].kind != WASM_I32) || + if (res.f || !res.r.size || (res.r.data[0].kind != WASM_I32) || !res.r.data[0].of.i32) throw std::runtime_error( "can't allocate memory, " + std::to_string(sz) + " bytes"); @@ -1022,7 +894,7 @@ WamrEngine::allocate(int32_t sz) } wasm_trap_t* -WamrEngine::newTrap(std::string_view txt) +WasmiEngine::newTrap(std::string_view txt) { wasm_message_t msg = WASM_EMPTY_VEC; @@ -1033,7 +905,7 @@ WamrEngine::newTrap(std::string_view txt) } beast::Journal -WamrEngine::getJournal() const +WasmiEngine::getJournal() const { return j_; }