diff --git a/external/wasmi/conandata.yml b/external/wasmi/conandata.yml index 032c12753c..7bf94fff7f 100644 --- a/external/wasmi/conandata.yml +++ b/external/wasmi/conandata.yml @@ -2,10 +2,10 @@ sources: "0.42.1": - sha256: 2a5697be33c7afce8f671af4a5a3621d9e93ce55d253d31bd8201458e465fbb8 url: https://github.com/wasmi-labs/wasmi/archive/refs/tags/v0.42.1.tar.gz + sha256: 2a5697be33c7afce8f671af4a5a3621d9e93ce55d253d31bd8201458e465fbb8 patches: "0.42.1": - patch_file: "patches/0001-xrplf-0.42.1.patch" + patch_description: Integrate wasmi lib into smart-escrow. patch_type: conan - patch_description: Integration patch. Make wasmi lib to be able to build with existing smart-escrow branch. diff --git a/external/wasmi/conanfile.py b/external/wasmi/conanfile.py index e245d62eb0..6f72298558 100644 --- a/external/wasmi/conanfile.py +++ b/external/wasmi/conanfile.py @@ -1,5 +1,5 @@ from conan import ConanFile, tools -from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout from conan.tools.files import apply_conandata_patches, export_conandata_patches, get import os @@ -30,9 +30,6 @@ class WasmiConan(ConanFile): tc.variables["BUILD_SHARED_LIBS"] = self.options.shared tc.generate() - deps = CMakeDeps(self) - deps.generate() - def build(self): cmake = CMake(self) cmake.configure(build_script_folder=os.path.join(self.source_folder, "crates", "c_api")) @@ -44,5 +41,3 @@ class WasmiConan(ConanFile): def package_info(self): self.cpp_info.libs = ["wasmi"] - self.cpp_info.names["cmake_find_package"] = "wasmi" - self.cpp_info.names["cmake_find_package_multi"] = "wasmi" diff --git a/external/wasmi/patches/0001-xrplf-0.42.1.patch b/external/wasmi/patches/0001-xrplf-0.42.1.patch index cecab3f8c2..0fbcb4408b 100644 --- a/external/wasmi/patches/0001-xrplf-0.42.1.patch +++ b/external/wasmi/patches/0001-xrplf-0.42.1.patch @@ -67,7 +67,7 @@ index b15c787a..54eaed2d 100644 - COMMENT "clang-format: Apply formatting rules for Wasmi C-API header files" -) diff --git a/crates/c_api/include/wasm.h b/crates/c_api/include/wasm.h -index 5ee617ff..37809a6f 100644 +index 5ee617ff..5c79bde3 100644 --- a/crates/c_api/include/wasm.h +++ b/crates/c_api/include/wasm.h @@ -13,11 +13,17 @@ @@ -89,7 +89,7 @@ index 5ee617ff..37809a6f 100644 #endif #ifdef __cplusplus -@@ -146,6 +152,13 @@ WASM_DECLARE_OWN(store) +@@ -146,6 +152,11 @@ WASM_DECLARE_OWN(store) WASM_API_EXTERN own wasm_store_t* wasm_store_new(wasm_engine_t*); @@ -98,8 +98,6 @@ index 5ee617ff..37809a6f 100644 + +WASM_API_EXTERN struct wasmi_error* wasm_store_get_fuel(const wasm_store_t*, uint64_t* fuel); +WASM_API_EXTERN struct wasmi_error* wasm_store_set_fuel(wasm_store_t*, uint64_t fuel); -+//WASM_API_EXTERN void *wasm_store_get_data(const wasm_store_t*); -+//WASM_API_EXTERN void wasm_store_set_data(wasm_store_t*, void *data); /////////////////////////////////////////////////////////////////////////////// // Type Representations diff --git a/src/test/app/EscrowSmart_test.cpp b/src/test/app/EscrowSmart_test.cpp index 6623522637..d5cf5fece6 100644 --- a/src/test/app/EscrowSmart_test.cpp +++ b/src/test/app/EscrowSmart_test.cpp @@ -390,7 +390,7 @@ struct EscrowSmart_test : public beast::unit_test::suite // Tests whether the ledger index is >= 5 // getLedgerSqn() >= 5} auto const& wasmHex = ledgerSqnWasmHex; - std::uint32_t const allowance = 5; + std::uint32_t const allowance = 65; auto escrowCreate = escrow::create(alice, carol, XRP(1000)); auto [createFee, finishFee] = [&]() { Env env(*this, features); @@ -683,7 +683,7 @@ struct EscrowSmart_test : public beast::unit_test::suite { env.require(balance(alice, XRP(4000) - txnFees)); - auto const allowance = 14; + auto const allowance = 1014; XRPAmount const finishFee = env.current()->fees().base + (allowance * env.current()->fees().gasPrice) / MICRO_DROPS_PER_DROP + @@ -778,7 +778,7 @@ struct EscrowSmart_test : public beast::unit_test::suite auto const txMeta = env.meta(); if (BEAST_EXPECT(txMeta && txMeta->isFieldPresent(sfGasUsed))) BEAST_EXPECTS( - txMeta->getFieldU32(sfGasUsed) == 794, + txMeta->getFieldU32(sfGasUsed) == 38'554, std::to_string(txMeta->getFieldU32(sfGasUsed))); if (BEAST_EXPECT(txMeta->isFieldPresent(sfWasmReturnCode))) BEAST_EXPECT(txMeta->getFieldI32(sfWasmReturnCode) == 1); @@ -863,7 +863,11 @@ struct EscrowSmart_test : public beast::unit_test::suite env.close(); env.close(); - auto const allowance = 2'985; + BEAST_EXPECTS( + env.ownerCount(alice) == 35, + std::to_string(env.ownerCount(alice))); + + auto const allowance = 138'485; auto const finishFee = env.current()->fees().base + (allowance * env.current()->fees().gasPrice) / MICRO_DROPS_PER_DROP + diff --git a/src/test/app/TestHostFunctions.h b/src/test/app/TestHostFunctions.h index 47d0f6204c..128bfa446f 100644 --- a/src/test/app/TestHostFunctions.h +++ b/src/test/app/TestHostFunctions.h @@ -15,11 +15,12 @@ namespace test { struct TestLedgerDataProvider : public HostFunctions { - jtx::Env* env_; + jtx::Env& env_; void const* rt_ = nullptr; public: - TestLedgerDataProvider(jtx::Env* env) : env_(env) + TestLedgerDataProvider(jtx::Env& env) + : HostFunctions(env.journal), env_(env) { } @@ -38,7 +39,7 @@ public: Expected getLedgerSqn() override { - return env_->current()->seq(); + return env_.current()->seq(); } }; @@ -52,7 +53,7 @@ struct TestHostFunctions : public HostFunctions public: TestHostFunctions(test::jtx::Env& env, int cd = 0) - : env_(env), clock_drift_(cd) + : HostFunctions(env.journal), env_(env), clock_drift_(cd) { accountID_ = env_.master.id(); std::string t = "10000"; @@ -71,12 +72,6 @@ public: return rt_; } - beast::Journal - getJournal() override - { - return env_.journal; - } - Expected getLedgerSqn() override { @@ -548,15 +543,13 @@ public: struct TestHostFunctionsSink : public TestHostFunctions { test::StreamSink sink_; - beast::Journal jlog_; void const* rt_ = nullptr; public: explicit TestHostFunctionsSink(test::jtx::Env& env, int cd = 0) - : TestHostFunctions(env, cd) - , sink_(beast::severities::kDebug) - , jlog_(sink_) + : TestHostFunctions(env, cd), sink_(beast::severities::kDebug) { + j_ = beast::Journal(sink_); } test::StreamSink& @@ -564,12 +557,6 @@ public: { return sink_; } - - beast::Journal - getJournal() override - { - return jlog_; - } }; struct PerfHostFunctions : public TestHostFunctions diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 7b738fe8f2..bcec0442f3 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -67,7 +67,7 @@ struct Wasm_test : public beast::unit_test::suite // clang-format on auto& vm = WasmEngine::instance(); - std::vector imports; + ImportVec imports; WasmImpFunc( imports, "func-add", reinterpret_cast(&Add)); @@ -90,7 +90,7 @@ struct Wasm_test : public beast::unit_test::suite using namespace test::jtx; Env env{*this}; - HostFunctions hfs; + HostFunctions hfs(env.journal); { auto wasmHex = "00000000"; @@ -98,7 +98,7 @@ struct Wasm_test : public beast::unit_test::suite std::vector wasm(wasmStr.begin(), wasmStr.end()); std::string funcName("mock_escrow"); - auto re = runEscrowWasm(wasm, funcName, {}, &hfs, 15, env.journal); + auto re = runEscrowWasm(wasm, hfs, funcName, {}, 15); BEAST_EXPECT(!re); } @@ -108,8 +108,7 @@ struct Wasm_test : public beast::unit_test::suite std::vector wasm(wasmStr.begin(), wasmStr.end()); std::string funcName("mock_escrow"); - auto const re = - preflightEscrowWasm(wasm, funcName, {}, &hfs, env.journal); + auto const re = preflightEscrowWasm(wasm, hfs, funcName); BEAST_EXPECT(!isTesSuccess(re)); } @@ -132,8 +131,8 @@ struct Wasm_test : public beast::unit_test::suite auto wasmStr = boost::algorithm::unhex(std::string(badWasmHex)); std::vector wasm(wasmStr.begin(), wasmStr.end()); - auto const re = preflightEscrowWasm( - wasm, ESCROW_FUNCTION_NAME, {}, &hfs, env.journal); + auto const re = + preflightEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME); BEAST_EXPECT(!isTesSuccess(re)); } } @@ -149,9 +148,9 @@ struct Wasm_test : public beast::unit_test::suite using namespace test::jtx; Env env{*this}; - TestLedgerDataProvider hf(&env); + TestLedgerDataProvider hf(env); - std::vector imports; + ImportVec imports; WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hf, 33); auto& engine = WasmEngine::instance(); @@ -164,11 +163,10 @@ struct Wasm_test : public beast::unit_test::suite 1'000'000, env.journal); - // code takes 11 gas + 1 getLedgerSqn call if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 0, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 5, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 38, std::to_string(re->cost)); } env.close(); @@ -178,11 +176,10 @@ struct Wasm_test : public beast::unit_test::suite re = engine.run( {}, ESCROW_FUNCTION_NAME, {}, imports, &hf, 1'000'000, env.journal); - // code takes 22 gas + 2 getLedgerSqn calls if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 5, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 10, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 76, std::to_string(re->cost)); } } @@ -299,9 +296,9 @@ struct Wasm_test : public beast::unit_test::suite auto& engine = WasmEngine::instance(); TestHostFunctions hfs(env, 0); - std::vector imp = createWasmImport(&hfs); + ImportVec imp = createWasmImport(hfs); for (auto& i : imp) - i.gas = 0; + i.second.gas = 0; auto re = engine.run( wasm, @@ -335,7 +332,7 @@ struct Wasm_test : public beast::unit_test::suite auto& engine = WasmEngine::instance(); TestHostFunctions hfs(env, 0); - std::vector const imp = createWasmImport(&hfs); + ImportVec const imp = createWasmImport(hfs); auto re = engine.run( wasm, @@ -349,7 +346,31 @@ 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 == 842, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 40'102, std::to_string(re->cost)); + } + + env.close(); + } + + // not enough gas + { + std::string const wasmHex = allHostFunctionsWasmHex; + std::string const wasmStr = boost::algorithm::unhex(wasmHex); + std::vector const wasm(wasmStr.begin(), wasmStr.end()); + + auto& engine = WasmEngine::instance(); + + TestHostFunctions hfs(env, 0); + ImportVec const imp = createWasmImport(hfs); + + auto re = engine.run( + wasm, ESCROW_FUNCTION_NAME, {}, imp, &hfs, 200, env.journal); + + if (BEAST_EXPECT(!re)) + { + BEAST_EXPECTS( + re.error() == tecFAILED_PROCESSING, + std::to_string(TERtoInt(re.error()))); } env.close(); @@ -370,11 +391,22 @@ struct Wasm_test : public beast::unit_test::suite { TestHostFunctions nfs(env, 0); auto re = - runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs, 100'000); + runEscrowWasm(wasm, nfs, ESCROW_FUNCTION_NAME, {}, 100'000); if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 842, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 40'102, std::to_string(re->cost)); + } + } + + { + // max() gas + TestHostFunctions nfs(env, 0); + auto re = runEscrowWasm(wasm, nfs, ESCROW_FUNCTION_NAME, {}, -1); + if (BEAST_EXPECT(re.has_value())) + { + BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); + BEAST_EXPECTS(re->cost == 40'102, std::to_string(re->cost)); } } @@ -392,11 +424,11 @@ struct Wasm_test : public beast::unit_test::suite }; BadTestHostFunctions nfs(env); auto re = - runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs, 100'000); + runEscrowWasm(wasm, nfs, ESCROW_FUNCTION_NAME, {}, 100'000); if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == -201, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 262, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 5'012, std::to_string(re->cost)); } } @@ -414,11 +446,11 @@ struct Wasm_test : public beast::unit_test::suite }; BadTestHostFunctions nfs(env); auto re = - runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs, 100'000); + runEscrowWasm(wasm, nfs, ESCROW_FUNCTION_NAME, {}, 100'000); if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == -201, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 262, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 5'012, std::to_string(re->cost)); } } @@ -429,7 +461,7 @@ struct Wasm_test : public beast::unit_test::suite TestHostFunctionsSink nfs(env); std::string funcName("recursive"); - auto re = runEscrowWasm(wasm, funcName, {}, &nfs, 1'000'000'000); + auto re = runEscrowWasm(wasm, nfs, funcName, {}, 1'000'000'000); BEAST_EXPECT(!re && re.error()); // std::cout << "bad case (deep recursion) result " << re.error() // << std::endl; @@ -454,11 +486,12 @@ struct Wasm_test : public beast::unit_test::suite } { + // expected import not provided auto wasmStr = boost::algorithm::unhex(ledgerSqnWasmHex); Bytes wasm(wasmStr.begin(), wasmStr.end()); - TestLedgerDataProvider ledgerDataProvider(&env); + TestLedgerDataProvider ledgerDataProvider(env); - std::vector imports; + ImportVec imports; WASM_IMPORT_FUNC2( imports, getLedgerSqn, "get_ledger_sqn2", &ledgerDataProvider); @@ -469,11 +502,58 @@ struct Wasm_test : public beast::unit_test::suite ESCROW_FUNCTION_NAME, {}, imports, - nullptr, + &ledgerDataProvider, + 1'000'000, + env.journal); + + BEAST_EXPECT(!re); + } + + { + // bad import format + auto wasmStr = boost::algorithm::unhex(ledgerSqnWasmHex); + Bytes wasm(wasmStr.begin(), wasmStr.end()); + TestLedgerDataProvider ledgerDataProvider(env); + + ImportVec imports; + WASM_IMPORT_FUNC2( + imports, getLedgerSqn, "get_ledger_sqn", &ledgerDataProvider); + imports[0].first = nullptr; + + auto& engine = WasmEngine::instance(); + + auto re = engine.run( + wasm, + ESCROW_FUNCTION_NAME, + {}, + imports, + &ledgerDataProvider, + 1'000'000, + env.journal); + + BEAST_EXPECT(!re); + } + + { + // bad function name + auto wasmStr = boost::algorithm::unhex(ledgerSqnWasmHex); + Bytes wasm(wasmStr.begin(), wasmStr.end()); + TestLedgerDataProvider ledgerDataProvider(env); + + ImportVec imports; + WASM_IMPORT_FUNC2( + imports, getLedgerSqn, "get_ledger_sqn", &ledgerDataProvider); + + auto& engine = WasmEngine::instance(); + auto re = engine.run( + wasm, + "func1", + {}, + imports, + &ledgerDataProvider, 1'000'000, env.journal); - // expected import not provided BEAST_EXPECT(!re); } } @@ -494,11 +574,11 @@ struct Wasm_test : public beast::unit_test::suite std::vector const wasm(wasmStr.begin(), wasmStr.end()); TestHostFunctions hf(env, 0); - auto re = runEscrowWasm(wasm, funcName, {}, &hf, 100'000); + auto re = runEscrowWasm(wasm, hf, funcName, {}, 100'000); if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 326, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 97'356, std::to_string(re->cost)); } env.close(); } @@ -509,11 +589,11 @@ struct Wasm_test : public beast::unit_test::suite std::vector const wasm(wasmStr.begin(), wasmStr.end()); TestHostFunctions hf(env, 0); - auto re = runEscrowWasm(wasm, funcName, {}, &hf, 100'000); + auto re = runEscrowWasm(wasm, hf, funcName, {}, 100'000); if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 34, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 2'054, std::to_string(re->cost)); } env.close(); } @@ -597,7 +677,7 @@ struct Wasm_test : public beast::unit_test::suite PerfHostFunctions nfs(env, k, env.tx()); - auto re = runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs); + auto re = runEscrowWasm(wasm, nfs, ESCROW_FUNCTION_NAME); if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECT(re->result); @@ -627,9 +707,8 @@ struct Wasm_test : public beast::unit_test::suite Bytes const wasm(wasmStr.begin(), wasmStr.end()); TestHostFunctions hfs(env, 0); - auto const allowance = 1'814; - auto re = runEscrowWasm( - wasm, ESCROW_FUNCTION_NAME, {}, &hfs, allowance, env.journal); + auto const allowance = 153'534; + auto re = runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, allowance); if (BEAST_EXPECT(re.has_value())) { @@ -653,8 +732,7 @@ struct Wasm_test : public beast::unit_test::suite { // f32 set constant, opcode disabled exception - auto const re = - runEscrowWasm(wasm, funcName, {}, &hfs, 1'000'000, env.journal); + auto const re = runEscrowWasm(wasm, hfs, funcName, {}, 1'000'000); if (BEAST_EXPECT(!re.has_value())) { BEAST_EXPECT(re.error() == tecFAILED_PROCESSING); @@ -664,8 +742,7 @@ struct Wasm_test : public beast::unit_test::suite { // f32 add, can't create module exception wasm[0x117] = 0x92; - auto const re = - runEscrowWasm(wasm, funcName, {}, &hfs, 1'000'000, env.journal); + auto const re = runEscrowWasm(wasm, hfs, funcName, {}, 1'000'000); if (BEAST_EXPECT(!re.has_value())) { BEAST_EXPECT(re.error() == tecFAILED_PROCESSING); diff --git a/src/xrpld/app/tx/detail/Escrow.cpp b/src/xrpld/app/tx/detail/Escrow.cpp index 5dd7b486c3..2fd44b33cb 100644 --- a/src/xrpld/app/tx/detail/Escrow.cpp +++ b/src/xrpld/app/tx/detail/Escrow.cpp @@ -217,9 +217,8 @@ EscrowCreate::preflight(PreflightContext const& ctx) return temMALFORMED; } - HostFunctions mock; - auto const re = - preflightEscrowWasm(code, ESCROW_FUNCTION_NAME, {}, &mock, ctx.j); + HostFunctions mock(ctx.j); + auto const re = preflightEscrowWasm(code, mock, ESCROW_FUNCTION_NAME); if (!isTesSuccess(re)) { JLOG(ctx.j.debug()) << "EscrowCreate.FinishFunction bad WASM"; @@ -1214,7 +1213,7 @@ EscrowFinish::doApply() } std::uint32_t allowance = ctx_.tx[sfComputationAllowance]; auto re = runEscrowWasm( - wasm, ESCROW_FUNCTION_NAME, {}, &ledgerDataProvider, allowance); + wasm, ledgerDataProvider, ESCROW_FUNCTION_NAME, {}, allowance); JLOG(j_.trace()) << "Escrow WASM ran"; if (auto const& data = ledgerDataProvider.getData(); data.has_value()) diff --git a/src/xrpld/app/wasm/HostFunc.h b/src/xrpld/app/wasm/HostFunc.h index bff939e0a1..9963754bfb 100644 --- a/src/xrpld/app/wasm/HostFunc.h +++ b/src/xrpld/app/wasm/HostFunc.h @@ -34,6 +34,8 @@ enum class HostFunctionError : int32_t { INDEX_OUT_OF_BOUNDS = -18, FLOAT_INPUT_MALFORMED = -19, FLOAT_COMPUTATION_ERROR = -20, + NO_RUNTIME = -21, + OUT_OF_GAS = -22, }; inline int32_t @@ -80,6 +82,14 @@ floatLogImpl(Slice const& x, int32_t mode); struct HostFunctions { + beast::Journal j_; + + HostFunctions( + beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) + : j_(j) + { + } + // LCOV_EXCL_START virtual void setRT(void const*) @@ -92,10 +102,22 @@ struct HostFunctions return nullptr; } - virtual beast::Journal + std::int64_t + getGas() + { + return -1; + } + + void + setGas(std::int64_t) + { + return; + } + + beast::Journal getJournal() { - return beast::Journal{beast::Journal::getNullSink()}; + return j_; } virtual Expected diff --git a/src/xrpld/app/wasm/HostFuncImpl.h b/src/xrpld/app/wasm/HostFuncImpl.h index f1add087fb..f5ed190230 100644 --- a/src/xrpld/app/wasm/HostFuncImpl.h +++ b/src/xrpld/app/wasm/HostFuncImpl.h @@ -42,8 +42,8 @@ class WasmHostFunctionsImpl : public HostFunctions } public: - WasmHostFunctionsImpl(ApplyContext& ctx, Keylet const& leKey) - : ctx(ctx), leKey(leKey) + WasmHostFunctionsImpl(ApplyContext& ct, Keylet const& leKey) + : HostFunctions(ct.journal), ctx(ct), leKey(leKey) { } @@ -59,12 +59,6 @@ public: return rt_; } - beast::Journal - getJournal() override - { - return ctx.journal; - } - std::optional const& getData() const { diff --git a/src/xrpld/app/wasm/ParamsHelper.h b/src/xrpld/app/wasm/ParamsHelper.h index 9d581c8158..a0eece7931 100644 --- a/src/xrpld/app/wasm/ParamsHelper.h +++ b/src/xrpld/app/wasm/ParamsHelper.h @@ -41,12 +41,15 @@ struct WasmImportFunc std::string name; std::optional result; std::vector params; - void* udata = nullptr; + // void* udata = nullptr; // wasm_func_callback_with_env_t void* wrap = nullptr; uint32_t gas = 0; }; +typedef std::pair WasmUserData; +typedef std::vector ImportVec; + #define WASM_IMPORT_FUNC(v, f, ...) \ WasmImpFunc( \ v, #f, reinterpret_cast(&f##_wrap), ##__VA_ARGS__) @@ -111,7 +114,7 @@ WasmImpFuncHelper(WasmImportFunc& e) template void WasmImpFunc( - std::vector& v, + ImportVec& v, std::string_view imp_name, void* f_wrap, void* data = nullptr, @@ -119,11 +122,10 @@ WasmImpFunc( { WasmImportFunc e; e.name = imp_name; - e.udata = data; e.wrap = f_wrap; e.gas = gas; WasmImpFuncHelper(e); - v.push_back(std::move(e)); + v.push_back(std::make_pair(data, std::move(e))); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/xrpld/app/wasm/WasmVM.h b/src/xrpld/app/wasm/WasmVM.h index 18379d6d4d..5309ed8f86 100644 --- a/src/xrpld/app/wasm/WasmVM.h +++ b/src/xrpld/app/wasm/WasmVM.h @@ -43,7 +43,7 @@ public: run(Bytes const& wasmCode, std::string_view funcName = {}, std::vector const& params = {}, - std::vector const& imports = {}, + ImportVec const& imports = {}, HostFunctions* hfs = nullptr, int64_t gasLimit = -1, beast::Journal j = beast::Journal{beast::Journal::getNullSink()}); @@ -53,12 +53,13 @@ public: Bytes const& wasmCode, std::string_view funcName, std::vector const& params = {}, - std::vector const& imports = {}, + ImportVec const& imports = {}, + HostFunctions* hfs = nullptr, beast::Journal j = beast::Journal{beast::Journal::getNullSink()}); // Host functions helper functionality void* - newTrap(std::string_view msg = {}); + newTrap(std::string const& txt = std::string()); beast::Journal getJournal() const; @@ -66,24 +67,22 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -std::vector -createWasmImport(HostFunctions* hfs); +ImportVec +createWasmImport(HostFunctions& hfs); Expected runEscrowWasm( Bytes const& wasmCode, + HostFunctions& hfs, std::string_view funcName = ESCROW_FUNCTION_NAME, std::vector const& params = {}, - HostFunctions* hfs = nullptr, - int64_t gasLimit = -1, - beast::Journal j = beast::Journal(beast::Journal::getNullSink())); + int64_t gasLimit = -1); NotTEC preflightEscrowWasm( Bytes const& wasmCode, + HostFunctions& hfs, std::string_view funcName = ESCROW_FUNCTION_NAME, - std::vector const& params = {}, - HostFunctions* hfs = nullptr, - beast::Journal j = beast::Journal(beast::Journal::getNullSink())); + std::vector const& params = {}); } // namespace ripple diff --git a/src/xrpld/app/wasm/WasmiVM.h b/src/xrpld/app/wasm/WasmiVM.h index 967a9319a6..a9b8a94332 100644 --- a/src/xrpld/app/wasm/WasmiVM.h +++ b/src/xrpld/app/wasm/WasmiVM.h @@ -48,11 +48,14 @@ struct WasmiResult using ModulePtr = std::unique_ptr; using InstancePtr = std::unique_ptr; +using EnginePtr = std::unique_ptr; +using StorePtr = std::unique_ptr; using FuncInfo = std::pair; struct InstanceWrapper { + wasm_store_t* store_ = nullptr; wasm_extern_vec_t exports_; InstancePtr instance_; beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); @@ -91,11 +94,15 @@ public: wmem getMem() const; + + std::int64_t + getGas() const; + + std::int64_t setGas(std::int64_t) const; }; struct ModuleWrapper { - wasm_store_t* store_ = nullptr; ModulePtr module_; InstanceWrapper instanceWrap_; wasm_exporttype_vec_t exportTypes_; @@ -114,7 +121,7 @@ public: wasm_store_t* s, Bytes const& wasmBin, bool instantiate, - std::vector const& imports, + ImportVec const& imports, beast::Journal j); ~ModuleWrapper(); @@ -142,13 +149,13 @@ private: static void makeImpReturn(wasm_valtype_vec_t& v, WasmImportFunc const& imp); wasm_extern_vec_t - buildImports(wasm_store_t* s, std::vector const& imports); + buildImports(wasm_store_t* s, ImportVec const& imports); }; class WasmiEngine { - std::unique_ptr engine_; - std::unique_ptr store_; + EnginePtr engine_; + StorePtr store_; std::unique_ptr moduleWrap_; beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); @@ -158,14 +165,14 @@ public: WasmiEngine(); ~WasmiEngine() = default; - static std::unique_ptr + static EnginePtr init(); Expected, TER> run(Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports, + ImportVec const& imports, HostFunctions* hfs, int64_t gas, beast::Journal j); @@ -175,7 +182,8 @@ public: Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports, + ImportVec const& imports, + HostFunctions* hfs, beast::Journal j); std::int64_t @@ -183,7 +191,7 @@ public: // Host functions helper functionality wasm_trap_t* - newTrap(std::string_view msg); + newTrap(std::string const& msg); beast::Journal getJournal() const; @@ -203,7 +211,7 @@ private: Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports, + ImportVec const& imports, HostFunctions* hfs, int64_t gas); @@ -212,14 +220,14 @@ private: Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports); + ImportVec const& imports); int addModule( Bytes const& wasmCode, bool instantiate, int64_t gas, - std::vector const& imports); + ImportVec const& imports); void clearModules(); diff --git a/src/xrpld/app/wasm/detail/HostFuncImpl.cpp b/src/xrpld/app/wasm/detail/HostFuncImpl.cpp index a0b81a2df3..59c4cbfc84 100644 --- a/src/xrpld/app/wasm/detail/HostFuncImpl.cpp +++ b/src/xrpld/app/wasm/detail/HostFuncImpl.cpp @@ -1269,10 +1269,12 @@ floatPowerImpl(Slice const& x, int32_t n, int32_t mode) return res.toBytes(); } + // LCOV_EXCL_START catch (...) { } return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR); + // LCOV_EXCL_STOP } Expected diff --git a/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp b/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp index 6e849fe867..90369e3a8d 100644 --- a/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp +++ b/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp @@ -300,13 +300,52 @@ returnResult( } } +static inline HostFunctions* +getHF(void* env) +{ + auto const* udata = reinterpret_cast(env); + HostFunctions* hf = reinterpret_cast(udata->first); + return hf; +} + +static inline Expected +checkGas(void* env) +{ + auto const* udata = reinterpret_cast(env); + HostFunctions* hf = reinterpret_cast(udata->first); + + auto const* runtime = reinterpret_cast(hf->getRT()); + if (!runtime) + { + wasm_trap_t* trap = reinterpret_cast( + WasmEngine::instance().newTrap("hf no runtime")); // LCOV_EXCL_LINE + return Unexpected(trap); // LCOV_EXCL_LINE + } + + int64_t const gas = runtime->getGas(); + WasmImportFunc const& impFunc = udata->second; + int64_t const x = gas >= impFunc.gas ? gas - impFunc.gas : 0; + runtime->setGas(x); + if (gas < impFunc.gas) + { + wasm_trap_t* trap = reinterpret_cast( + WasmEngine::instance().newTrap("hf out of gas")); + return Unexpected(trap); + } + + return x; +} + +//---------------------------------------------------------------------------------------------------------------------- wasm_trap_t* getLedgerSqn_wrap( void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -319,7 +358,9 @@ getParentLedgerTime_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -333,7 +374,9 @@ getParentLedgerHash_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -347,7 +390,9 @@ getBaseFee_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -360,7 +405,9 @@ isAmendmentEnabled_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -396,7 +443,9 @@ cacheLedgerObj_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -422,7 +471,9 @@ getTxField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -441,7 +492,9 @@ getCurrentLedgerObjField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -461,7 +514,9 @@ getLedgerObjField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -487,7 +542,9 @@ getTxNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -507,7 +564,9 @@ getCurrentLedgerObjNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -530,7 +589,9 @@ getLedgerObjNestedField_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -560,7 +621,9 @@ getTxArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -580,7 +643,9 @@ getCurrentLedgerObjArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -604,7 +669,9 @@ getLedgerObjArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -634,7 +701,9 @@ getTxNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -654,7 +723,9 @@ getCurrentLedgerObjNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -677,7 +748,9 @@ getLedgerObjNestedArrayLen_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -706,7 +779,9 @@ updateData_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -726,7 +801,9 @@ checkSignature_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -762,7 +839,9 @@ computeSha512HalfHash_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -781,7 +860,9 @@ accountKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -798,7 +879,9 @@ accountKeylet_wrap( wasm_trap_t* ammKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -828,7 +911,9 @@ checkKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -854,7 +939,9 @@ credentialKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -890,7 +977,9 @@ delegateKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -920,7 +1009,9 @@ depositPreauthKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -947,7 +1038,9 @@ depositPreauthKeylet_wrap( wasm_trap_t* didKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -967,7 +1060,9 @@ escrowKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -993,7 +1088,9 @@ lineKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1029,7 +1126,9 @@ mptIssuanceKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1059,7 +1158,9 @@ mptokenKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1095,7 +1196,9 @@ nftOfferKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1125,7 +1228,9 @@ offerKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1155,7 +1260,9 @@ oracleKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1180,7 +1287,9 @@ paychanKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1216,7 +1325,9 @@ permissionedDomainKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1246,7 +1357,9 @@ signersKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1266,7 +1379,9 @@ ticketKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1296,7 +1411,9 @@ vaultKeylet_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1323,7 +1440,9 @@ vaultKeylet_wrap( wasm_trap_t* getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1349,7 +1468,9 @@ getNFTIssuer_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1369,7 +1490,9 @@ getNFTTaxon_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1389,7 +1512,9 @@ getNFTFlags_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1409,7 +1534,9 @@ getNFTTransferFee_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1429,7 +1556,9 @@ getNFTSerial_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1446,7 +1575,9 @@ getNFTSerial_wrap( wasm_trap_t* trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; @@ -1480,7 +1611,9 @@ trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) wasm_trap_t* traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int index = 0; if (params->data[1].of.i32 > maxWasmParamLength) @@ -1510,7 +1643,9 @@ traceAccount_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); if (params->data[1].of.i32 > maxWasmParamLength) @@ -1535,7 +1670,9 @@ traceFloat_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); if (params->data[1].of.i32 > maxWasmParamLength) @@ -1560,7 +1697,9 @@ traceAmount_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); if (params->data[1].of.i32 > maxWasmParamLength) @@ -1600,7 +1739,9 @@ floatFromInt_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1624,7 +1765,9 @@ floatFromUint_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1645,7 +1788,9 @@ floatFromUint_wrap( wasm_trap_t* floatSet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1673,7 +1818,9 @@ floatCompare_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1691,7 +1838,9 @@ floatCompare_wrap( wasm_trap_t* floatAdd_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1719,7 +1868,9 @@ floatSubtract_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1747,7 +1898,9 @@ floatMultiply_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1775,7 +1928,9 @@ floatDivide_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1800,7 +1955,9 @@ floatDivide_wrap( wasm_trap_t* floatRoot_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1828,7 +1985,9 @@ floatPower_wrap( wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; @@ -1853,7 +2012,9 @@ floatPower_wrap( wasm_trap_t* floatLog_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results) { - auto* hf = reinterpret_cast(env); + if (auto g = checkGas(env); !g) + return g.error(); // LCOV_EXCL_LINE + auto* hf = getHF(env); auto const* runtime = reinterpret_cast(hf->getRT()); int i = 0; diff --git a/src/xrpld/app/wasm/detail/WasmVM.cpp b/src/xrpld/app/wasm/detail/WasmVM.cpp index d87b1444f6..9ac91358dc 100644 --- a/src/xrpld/app/wasm/detail/WasmVM.cpp +++ b/src/xrpld/app/wasm/detail/WasmVM.cpp @@ -16,7 +16,7 @@ namespace ripple { static void -setCommonHostFunctions(HostFunctions* hfs, std::vector& i) +setCommonHostFunctions(HostFunctions* hfs, ImportVec& i) { // clang-format off WASM_IMPORT_FUNC2(i, getLedgerSqn, "get_ledger_sqn", hfs, 60); @@ -89,16 +89,13 @@ setCommonHostFunctions(HostFunctions* hfs, std::vector& i) // clang-format on } -std::vector -createWasmImport(HostFunctions* hfs) +ImportVec +createWasmImport(HostFunctions& hfs) { - std::vector i; + ImportVec i; - if (hfs) - { - setCommonHostFunctions(hfs, i); - WASM_IMPORT_FUNC2(i, updateData, "update_data", hfs, 1000); - } + setCommonHostFunctions(&hfs, i); + WASM_IMPORT_FUNC2(i, updateData, "update_data", &hfs, 1000); return i; } @@ -106,11 +103,10 @@ createWasmImport(HostFunctions* hfs) Expected runEscrowWasm( Bytes const& wasmCode, + HostFunctions& hfs, std::string_view funcName, std::vector const& params, - HostFunctions* hfs, - int64_t gasLimit, - beast::Journal j) + int64_t gasLimit) { // create VM and set cost limit auto& vm = WasmEngine::instance(); @@ -121,9 +117,9 @@ runEscrowWasm( funcName, params, createWasmImport(hfs), - hfs, + &hfs, gasLimit, - hfs ? hfs->getJournal() : j); + hfs.getJournal()); // std::cout << "runEscrowWasm, mod size: " << wasmCode.size() // << ", gasLimit: " << gasLimit << ", funcName: " << funcName; @@ -146,10 +142,9 @@ runEscrowWasm( NotTEC preflightEscrowWasm( Bytes const& wasmCode, + HostFunctions& hfs, std::string_view funcName, - std::vector const& params, - HostFunctions* hfs, - beast::Journal j) + std::vector const& params) { // create VM and set cost limit auto& vm = WasmEngine::instance(); @@ -160,7 +155,8 @@ preflightEscrowWasm( funcName, params, createWasmImport(hfs), - hfs ? hfs->getJournal() : j); + &hfs, + hfs.getJournal()); return ret; } @@ -183,7 +179,7 @@ WasmEngine::run( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports, + ImportVec const& imports, HostFunctions* hfs, int64_t gasLimit, beast::Journal j) @@ -196,22 +192,25 @@ WasmEngine::check( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports, + ImportVec const& imports, + HostFunctions* hfs, beast::Journal j) { - return impl->check(wasmCode, funcName, params, imports, j); + return impl->check(wasmCode, funcName, params, imports, hfs, j); } void* -WasmEngine::newTrap(std::string_view msg) +WasmEngine::newTrap(std::string const& msg) { return impl->newTrap(msg); } +// LCOV_EXCL_START beast::Journal WasmEngine::getJournal() const { return impl->getJournal(); } +// LCOV_EXCL_STOP } // namespace ripple diff --git a/src/xrpld/app/wasm/detail/WasmiVM.cpp b/src/xrpld/app/wasm/detail/WasmiVM.cpp index 56cd321479..fe3a5629f7 100644 --- a/src/xrpld/app/wasm/detail/WasmiVM.cpp +++ b/src/xrpld/app/wasm/detail/WasmiVM.cpp @@ -75,18 +75,21 @@ InstanceWrapper::InstanceWrapper() { } +// LCOV_EXCL_START InstanceWrapper::InstanceWrapper(InstanceWrapper&& o) : exports_{0, nullptr}, instance_(nullptr, &wasm_instance_delete) { *this = std::move(o); } +// LCOV_EXCL_STOP InstanceWrapper::InstanceWrapper( wasm_store_t* s, wasm_module_t* m, wasm_extern_vec_t const& imports, beast::Journal j) - : exports_ WASM_EMPTY_VEC + : store_(s) + , exports_ WASM_EMPTY_VEC , instance_(init(s, m, &exports_, imports, j)) , j_(j) { @@ -102,10 +105,12 @@ InstanceWrapper& InstanceWrapper::operator=(InstanceWrapper&& o) { if (this == &o) - return *this; + return *this; // LCOV_EXCL_LINE + store_ = o.store_; + o.store_ = nullptr; if (exports_.size) - wasm_extern_vec_delete(&exports_); + wasm_extern_vec_delete(&exports_); // LCOV_EXCL_LINE exports_ = o.exports_; o.exports_ = {0, nullptr}; @@ -130,12 +135,12 @@ InstanceWrapper::getFunc( wasm_functype_t* ft = nullptr; if (!instance_) - throw std::runtime_error("no instance"); + throw std::runtime_error("no instance"); // LCOV_EXCL_LINE if (!export_types.size) - throw std::runtime_error("no export"); + throw std::runtime_error("no export"); // LCOV_EXCL_LINE if (export_types.size != exports_.size) - throw std::runtime_error("invalid export"); + throw std::runtime_error("invalid export"); // LCOV_EXCL_LINE for (unsigned i = 0; i < export_types.size; ++i) { @@ -149,7 +154,8 @@ InstanceWrapper::getFunc( { auto* exn(exports_.data[i]); if (wasm_extern_kind(exn) != WASM_EXTERN_FUNC) - throw std::runtime_error("invalid export"); + throw std::runtime_error( + "invalid export"); // LCOV_EXCL_LINE ft = wasm_externtype_as_functype( const_cast(exn_type)); @@ -170,7 +176,7 @@ wmem InstanceWrapper::getMem() const { if (!instance_) - throw std::runtime_error("no instance"); + throw std::runtime_error("no instance"); // LCOV_EXCL_LINE wasm_memory_t* mem = nullptr; for (unsigned i = 0; i < exports_.size; ++i) @@ -184,13 +190,43 @@ InstanceWrapper::getMem() const } if (!mem) - throw std::runtime_error("no memory exported"); + throw std::runtime_error("no memory exported"); // LCOV_EXCL_LINE return { reinterpret_cast(wasm_memory_data(mem)), wasm_memory_data_size(mem)}; } +std::int64_t +InstanceWrapper::getGas() const +{ + if (!store_) + return -1; // LCOV_EXCL_LINE + std::uint64_t gas = 0; + wasm_store_get_fuel(store_, &gas); + return static_cast(gas); +} + +std::int64_t +InstanceWrapper::setGas(std::int64_t gas) const +{ + if (!store_) + return -1; // LCOV_EXCL_LINE + + if (gas < 0) + gas = std::numeric_limits::max(); + wasmi_error_t* err = + wasm_store_set_fuel(store_, static_cast(gas)); + if (err) + { + print_wasm_error( + "Can't set instance gas", nullptr, j_); // LCOV_EXCL_LINE + throw std::runtime_error("Can't set instance gas"); // LCOV_EXCL_LINE + } + + return gas; +} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// ModulePtr @@ -204,6 +240,7 @@ ModuleWrapper::init(wasm_store_t* s, Bytes const& wasmBin, beast::Journal j) return m; } +// LCOV_EXCL_START ModuleWrapper::ModuleWrapper() : module_(nullptr, &wasm_module_delete), exportTypes_{0, nullptr} { @@ -214,14 +251,15 @@ ModuleWrapper::ModuleWrapper(ModuleWrapper&& o) { *this = std::move(o); } +// LCOV_EXCL_STOP ModuleWrapper::ModuleWrapper( wasm_store_t* s, Bytes const& wasmBin, bool instantiate, - std::vector const& imports, + ImportVec const& imports, beast::Journal j) - : store_(s), module_(init(s, wasmBin, j)), exportTypes_{0, nullptr}, j_(j) + : module_(init(s, wasmBin, j)), exportTypes_{0, nullptr}, j_(j) { wasm_module_exports(module_.get(), &exportTypes_); if (instantiate) @@ -238,14 +276,13 @@ ModuleWrapper::~ModuleWrapper() wasm_exporttype_vec_delete(&exportTypes_); } +// LCOV_EXCL_START ModuleWrapper& 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) @@ -262,6 +299,8 @@ ModuleWrapper::operator bool() const return instanceWrap_; } +// LCOV_EXCL_STOP + void ModuleWrapper::makeImpParams(wasm_valtype_vec_t& v, WasmImportFunc const& imp) { @@ -284,8 +323,10 @@ ModuleWrapper::makeImpParams(wasm_valtype_vec_t& v, WasmImportFunc const& imp) case WT_I64: v.data[i] = wasm_valtype_new_i64(); break; + // LCOV_EXCL_START default: throw std::runtime_error("invalid import type"); + // LCOV_EXCL_STOP } } } @@ -301,21 +342,21 @@ ModuleWrapper::makeImpReturn(wasm_valtype_vec_t& v, WasmImportFunc const& imp) case WT_I32: v.data[0] = wasm_valtype_new_i32(); break; + // LCOV_EXCL_START case WT_I64: v.data[0] = wasm_valtype_new_i64(); break; default: throw std::runtime_error("invalid return type"); + // LCOV_EXCL_STOP } } else - v = WASM_EMPTY_VEC; + v = WASM_EMPTY_VEC; // LCOV_EXCL_LINE } wasm_extern_vec_t -ModuleWrapper::buildImports( - wasm_store_t* s, - std::vector const& imports) +ModuleWrapper::buildImports(wasm_store_t* s, ImportVec const& imports) { wasm_importtype_vec_t importTypes = WASM_EMPTY_VEC; wasm_module_imports(module_.get(), &importTypes); @@ -343,15 +384,17 @@ ModuleWrapper::buildImports( wasm_externtype_kind(wasm_importtype_type(importtype)); if ((itype) != WASM_EXTERN_FUNC) throw std::runtime_error( - "Invalid import type " + std::to_string(itype)); + "Invalid import type " + + std::to_string(itype)); // LCOV_EXCL_LINE // for multi-module support // if ((W_ENV != modName) && (W_HOST_LIB != modName)) // continue; bool impSet = false; - for (auto const& imp : imports) + for (auto const& obj : imports) { + auto const& imp = obj.second; if (imp.name != fieldName) continue; @@ -368,7 +411,7 @@ ModuleWrapper::buildImports( s, ftype.get(), reinterpret_cast(imp.wrap), - imp.udata, + (void*)&obj, nullptr); if (!func) { @@ -378,14 +421,6 @@ 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 - // } - wimports.data[i] = wasm_func_as_extern(func); ++impCnt; impSet = true; @@ -450,11 +485,7 @@ ModuleWrapper::addInstance(wasm_store_t* s, wasm_extern_vec_t const& imports) std::int64_t ModuleWrapper::getGas() { - if (!store_) - return 0; - std::uint64_t gas = 0; - wasm_store_get_fuel(store_, &gas); - return static_cast(gas); + return instanceWrap_ ? instanceWrap_.getGas() : -1; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -473,7 +504,7 @@ WasmiEngine::init() wasm_config_t* config = wasm_config_new(); if (!config) return std::unique_ptr{ - nullptr, &wasm_engine_delete}; + nullptr, &wasm_engine_delete}; // LCOV_EXCL_LINE wasmi_config_consume_fuel_set(config, true); return std::unique_ptr( @@ -490,7 +521,7 @@ WasmiEngine::addModule( Bytes const& wasmCode, bool instantiate, int64_t gas, - std::vector const& imports) + ImportVec const& imports) { moduleWrap_.reset(); store_.reset(); // to free the memory before creating new store @@ -502,15 +533,18 @@ WasmiEngine::addModule( wasm_store_set_fuel(store_.get(), static_cast(gas)); if (err) { + // LCOV_EXCL_START print_wasm_error("Error setting gas", nullptr, j_); throw std::runtime_error("can't set gas"); + // LCOV_EXCL_STOP } moduleWrap_ = std::make_unique( store_.get(), wasmCode, instantiate, imports, j_); if (!moduleWrap_) - throw std::runtime_error("can't create module wrapper"); + throw std::runtime_error( + "can't create module wrapper"); // LCOV_EXCL_LINE return moduleWrap_ ? 0 : -1; } @@ -539,9 +573,11 @@ WasmiEngine::convertParams(std::vector const& params) case WT_I32: v.push_back(WASM_I32_VAL(p.of.i32)); break; + // LCOV_EXCL_START case WT_I64: v.push_back(WASM_I64_VAL(p.of.i64)); break; + // LCOV_EXCL_STOP case WT_U8V: { auto const sz = p.of.u8v.sz; auto const ptr = allocate(sz); @@ -552,10 +588,12 @@ WasmiEngine::convertParams(std::vector const& params) v.push_back(WASM_I32_VAL(sz)); } break; + // LCOV_EXCL_START default: throw std::runtime_error( "unknown parameter type: " + std::to_string(p.type)); break; + // LCOV_EXCL_STOP } } @@ -581,6 +619,7 @@ WasmiEngine::compareParamTypes( return -1; } +// LCOV_EXCL_START void WasmiEngine::add_param(std::vector& in, int32_t p) { @@ -590,6 +629,8 @@ WasmiEngine::add_param(std::vector& in, int32_t p) el = WASM_I32_VAL(p); // WASM_I32; } +// LCOV_EXCL_STOP + void WasmiEngine::add_param(std::vector& in, int64_t p) { @@ -717,12 +758,22 @@ WasmiEngine::call( return call(f, in, p.data(), p.size(), std::forward(args)...); } +static inline void +checkImports(ImportVec const& imports, HostFunctions* hfs) +{ + for (auto const& obj : imports) + { + if (hfs != obj.first) + Throw("Imports hf unsync"); + } +} + Expected, TER> WasmiEngine::run( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports, + ImportVec const& imports, HostFunctions* hfs, int64_t gas, beast::Journal j) @@ -730,16 +781,19 @@ WasmiEngine::run( j_ = j; try { + checkImports(imports, hfs); return runHlp(wasmCode, funcName, params, imports, hfs, gas); } catch (std::exception const& e) { print_wasm_error(std::string("exception: ") + e.what(), nullptr, j_); } + // LCOV_EXCL_START catch (...) { print_wasm_error(std::string("exception: unknown"), nullptr, j_); } + // LCOV_EXCL_STOP return Unexpected(tecFAILED_PROCESSING); } @@ -748,7 +802,7 @@ WasmiEngine::runHlp( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports, + ImportVec const& imports, HostFunctions* hfs, int64_t gas) { @@ -762,7 +816,7 @@ WasmiEngine::runHlp( } if (!moduleWrap_ || !moduleWrap_->instanceWrap_) - throw std::runtime_error("no instance"); + throw std::runtime_error("no instance"); // LCOV_EXCL_LINE if (hfs) hfs->setRT(&getRT()); @@ -785,7 +839,8 @@ WasmiEngine::runHlp( throw std::runtime_error("<" + std::string(funcName) + "> failure"); else if (!res.r.size) throw std::runtime_error( - "<" + std::string(funcName) + "> return nothing"); + "<" + std::string(funcName) + + "> return nothing"); // LCOV_EXCL_LINE assert(res.r.data[0].kind == WASM_I32); if (gas == -1) @@ -808,23 +863,27 @@ WasmiEngine::check( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports, + ImportVec const& imports, + HostFunctions* hfs, beast::Journal j) { j_ = j; try { + checkImports(imports, hfs); return checkHlp(wasmCode, funcName, params, imports); } catch (std::exception const& e) { print_wasm_error(std::string("exception: ") + e.what(), nullptr, j_); } + // LCOV_EXCL_START catch (...) { print_wasm_error(std::string("exception: unknown"), nullptr, j_); } + // LCOV_EXCL_STOP return temBAD_WASM; } @@ -834,7 +893,7 @@ WasmiEngine::checkHlp( Bytes const& wasmCode, std::string_view funcName, std::vector const& params, - std::vector const& imports) + ImportVec const& imports) { // currently only 1 module support, possible parallel UT run std::lock_guard lg(m_); @@ -845,7 +904,7 @@ WasmiEngine::checkHlp( int const m = addModule(wasmCode, true, -1, imports); if ((m < 0) || !moduleWrap_ || !moduleWrap_->instanceWrap_) - throw std::runtime_error("no instance"); + throw std::runtime_error("no instance"); // LCOV_EXCL_LINE // Looking for a func and compare parameter types auto const f = getFunc(!funcName.empty() ? funcName : "_start"); @@ -859,11 +918,13 @@ WasmiEngine::checkHlp( return tesSUCCESS; } +// LCOV_EXCL_START std::int64_t WasmiEngine::getGas() { - return moduleWrap_ ? moduleWrap_->getGas() : 0; + return moduleWrap_ ? moduleWrap_->getGas() : -1; } +// LCOV_EXCL_STOP wmem WasmiEngine::getMem() const @@ -892,20 +953,23 @@ WasmiEngine::allocate(int32_t sz) } wasm_trap_t* -WasmiEngine::newTrap(std::string_view txt) +WasmiEngine::newTrap(std::string const& txt) { - wasm_message_t msg = WASM_EMPTY_VEC; + static char empty[1] = {0}; + wasm_message_t msg = {1, empty}; if (!txt.empty()) - wasm_name_new(&msg, txt.size(), txt.data()); + wasm_name_new(&msg, txt.size() + 1, txt.c_str()); // include 0 return wasm_trap_new(store_.get(), &msg); } +// LCOV_EXCL_START beast::Journal WasmiEngine::getJournal() const { return j_; } +// LCOV_EXCL_STOP } // namespace ripple