Add WAMR integration code

This commit is contained in:
Mayukha Vadari
2025-09-10 14:56:08 -04:00
parent 45ab15d4b5
commit dbc9dd5bfc
6 changed files with 2003 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#pragma once
#include <xrpld/app/wasm/ParamsHelper.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Slice.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/UintTypes.h>
namespace ripple {
struct HostFunctions
{
// LCOV_EXCL_START
virtual void
setRT(void const*)
{
}
virtual void const*
getRT() const
{
return nullptr;
}
virtual beast::Journal
getJournal()
{
return beast::Journal{beast::Journal::getNullSink()};
}
virtual ~HostFunctions() = default;
// LCOV_EXCL_STOP
};
} // namespace ripple

View File

@@ -0,0 +1,272 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#pragma once
#include <xrpl/basics/base_uint.h>
#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/mpl/vector.hpp>
#include <optional>
#include <string>
#include <vector>
namespace bft = boost::function_types;
namespace ripple {
using Bytes = std::vector<std::uint8_t>;
using Hash = ripple::uint256;
struct wmem
{
std::uint8_t* p = nullptr;
std::size_t s = 0;
};
template <typename T>
struct WasmResult
{
T result;
int64_t cost;
};
typedef WasmResult<int32_t> EscrowResult;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum WasmTypes { WT_I32, WT_I64, WT_F32, WT_F64, WT_U8V };
struct WasmImportFunc
{
std::string name;
std::optional<WasmTypes> result;
std::vector<WasmTypes> params;
void* udata = nullptr;
// wasm_func_callback_with_env_t
void* wrap = nullptr;
uint32_t gas = 0;
};
#define WASM_IMPORT_FUNC(v, f, ...) \
WasmImpFunc<f##_proto>( \
v, #f, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
#define WASM_IMPORT_FUNC2(v, f, n, ...) \
WasmImpFunc<f##_proto>( \
v, n, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
template <int N, int C, typename mpl>
void
WasmImpArgs(WasmImportFunc& e)
{
if constexpr (N < C)
{
using at = typename boost::mpl::at_c<mpl, N>::type;
if constexpr (std::is_pointer_v<at>)
e.params.push_back(WT_I32);
else if constexpr (std::is_same_v<at, std::int32_t>)
e.params.push_back(WT_I32);
else if constexpr (std::is_same_v<at, std::int64_t>)
e.params.push_back(WT_I64);
else if constexpr (std::is_same_v<at, float>)
e.params.push_back(WT_F32);
else if constexpr (std::is_same_v<at, double>)
e.params.push_back(WT_F64);
else
static_assert(std::is_pointer_v<at>, "Unsupported argument type");
return WasmImpArgs<N + 1, C, mpl>(e);
}
return;
}
template <typename rt>
void
WasmImpRet(WasmImportFunc& e)
{
if constexpr (std::is_pointer_v<rt>)
e.result = WT_I32;
else if constexpr (std::is_same_v<rt, std::int32_t>)
e.result = WT_I32;
else if constexpr (std::is_same_v<rt, std::int64_t>)
e.result = WT_I64;
else if constexpr (std::is_same_v<rt, float>)
e.result = WT_F32;
else if constexpr (std::is_same_v<rt, double>)
e.result = WT_F64;
else if constexpr (std::is_void_v<rt>)
e.result.reset();
#if (defined(__GNUC__) && (__GNUC__ >= 14)) || \
((defined(__clang_major__)) && (__clang_major__ >= 18))
else
static_assert(false, "Unsupported return type");
#endif
}
template <typename F>
void
WasmImpFuncHelper(WasmImportFunc& e)
{
using rt = typename bft::result_type<F>::type;
using pt = typename bft::parameter_types<F>::type;
// typename boost::mpl::at_c<mpl, N>::type
WasmImpRet<rt>(e);
WasmImpArgs<0, bft::function_arity<F>::value, pt>(e);
// WasmImpWrap(e, std::forward<F>(f));
}
template <typename F>
void
WasmImpFunc(
std::vector<WasmImportFunc>& v,
std::string_view imp_name,
void* f_wrap,
void* data = nullptr,
uint32_t gas = 0)
{
WasmImportFunc e;
e.name = imp_name;
e.udata = data;
e.wrap = f_wrap;
e.gas = gas;
WasmImpFuncHelper<F>(e);
v.push_back(std::move(e));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct WasmParamVec
{
std::uint8_t const* d = nullptr;
std::int32_t sz = 0;
};
struct WasmParam
{
WasmTypes type = WT_I32;
union
{
std::int32_t i32;
std::int64_t i64 = 0;
float f32;
double f64;
WasmParamVec u8v;
} of;
};
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int32_t p, Types&&... args)
{
v.push_back({.type = WT_I32, .of = {.i32 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::int64_t p, Types&&... args)
{
v.push_back({.type = WT_I64, .of = {.i64 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, float p, Types&&... args)
{
v.push_back({.type = WT_F32, .of = {.f32 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, double p, Types&&... args)
{
v.push_back({.type = WT_F64, .of = {.f64 = p}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(
std::vector<WasmParam>& v,
std::uint8_t const* dt,
std::int32_t sz,
Types&&... args)
{
v.push_back({.type = WT_U8V, .of = {.u8v = {.d = dt, .sz = sz}}});
wasmParamsHlp(v, std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, Bytes const& p, Types&&... args)
{
wasmParamsHlp(
v,
p.data(),
static_cast<std::int32_t>(p.size()),
std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(
std::vector<WasmParam>& v,
std::string_view const& p,
Types&&... args)
{
wasmParamsHlp(
v,
reinterpret_cast<std::uint8_t const*>(p.data()),
static_cast<std::int32_t>(p.size()),
std::forward<Types>(args)...);
}
template <class... Types>
inline void
wasmParamsHlp(std::vector<WasmParam>& v, std::string const& p, Types&&... args)
{
wasmParamsHlp(
v,
reinterpret_cast<std::uint8_t const*>(p.c_str()),
static_cast<std::int32_t>(p.size()),
std::forward<Types>(args)...);
}
inline void
wasmParamsHlp(std::vector<WasmParam>& v)
{
return;
}
template <class... Types>
inline std::vector<WasmParam>
wasmParams(Types&&... args)
{
std::vector<WasmParam> v;
v.reserve(sizeof...(args));
wasmParamsHlp(v, std::forward<Types>(args)...);
return v;
}
} // namespace ripple

327
src/xrpld/app/wasm/WamrVM.h Normal file
View File

@@ -0,0 +1,327 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2023 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#pragma once
#include <xrpld/app/wasm/WasmVM.h>
#include <wasm_c_api.h>
#include <wasm_export.h>
namespace ripple {
struct WamrResult
{
wasm_val_vec_t r;
bool f; // failure flag
WamrResult(unsigned N = 0) : r{0, nullptr, 0, 0, nullptr}, f(false)
{
if (N)
wasm_val_vec_new_uninitialized(&r, N);
}
~WamrResult()
{
if (r.size)
wasm_val_vec_delete(&r);
}
WamrResult(WamrResult const&) = delete;
WamrResult&
operator=(WamrResult const&) = delete;
WamrResult(WamrResult&& o)
{
*this = std::move(o);
}
WamrResult&
operator=(WamrResult&& o)
{
r = o.r;
o.r = {0, nullptr, 0, 0, nullptr};
f = o.f;
o.f = false;
return *this;
}
// operator wasm_val_vec_t &() {return r;}
};
using ModulePtr = std::unique_ptr<wasm_module_t, decltype(&wasm_module_delete)>;
using InstancePtr =
std::unique_ptr<wasm_instance_t, decltype(&wasm_instance_delete)>;
using FuncInfo = std::pair<wasm_func_t const*, wasm_functype_t const*>;
struct InstanceWrapper
{
wasm_extern_vec_t exports_;
InstancePtr instance_;
wasm_exec_env_t execEnv_ = nullptr;
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
private:
static InstancePtr
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);
public:
InstanceWrapper();
InstanceWrapper(InstanceWrapper&& o);
InstanceWrapper&
operator=(InstanceWrapper&& o);
InstanceWrapper(
wasm_store_t* s,
wasm_module_t* m,
int32_t maxPages,
int64_t gas,
wasm_extern_vec_t const& imports,
beast::Journal j);
~InstanceWrapper();
operator bool() const;
FuncInfo
getFunc(
std::string_view funcName,
wasm_exporttype_vec_t const& export_types) const;
wmem
getMem() const;
std::int64_t
getGas() const;
};
struct ModuleWrapper
{
ModulePtr module_;
InstanceWrapper instanceWrap_;
wasm_exporttype_vec_t exportTypes_;
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
private:
static ModulePtr
init(wasm_store_t* s, Bytes const& wasmBin, beast::Journal j);
public:
ModuleWrapper();
ModuleWrapper(ModuleWrapper&& o);
ModuleWrapper&
operator=(ModuleWrapper&& o);
ModuleWrapper(
wasm_store_t* s,
Bytes const& wasmBin,
bool instantiate,
int32_t maxPages,
int64_t gas,
std::vector<WasmImportFunc> const& imports,
beast::Journal j);
~ModuleWrapper();
operator bool() const;
FuncInfo
getFunc(std::string_view funcName) const;
wmem
getMem() const;
InstanceWrapper const&
getInstance(int i = 0) const;
int
addInstance(
wasm_store_t* s,
int32_t maxPages,
int64_t gas,
wasm_extern_vec_t const& imports = WASM_EMPTY_VEC);
std::int64_t
getGas();
private:
static void
makeImpParams(wasm_valtype_vec_t& v, WasmImportFunc const& imp);
static void
makeImpReturn(wasm_valtype_vec_t& v, WasmImportFunc const& imp);
wasm_extern_vec_t
buildImports(wasm_store_t* s, std::vector<WasmImportFunc> const& imports);
};
class WamrEngine
{
std::unique_ptr<wasm_engine_t, decltype(&wasm_engine_delete)> engine_;
std::unique_ptr<wasm_store_t, decltype(&wasm_store_delete)> store_;
std::unique_ptr<ModuleWrapper> moduleWrap_;
std::int32_t defMaxPages_ = -1;
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
std::mutex m_; // 1 instance mutex
public:
WamrEngine();
~WamrEngine() = default;
Expected<WasmResult<int32_t>, TER>
run(Bytes const& wasmCode,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::vector<WasmImportFunc> const& imports,
HostFunctions* hfs,
int64_t gas,
beast::Journal j);
NotTEC
check(
Bytes const& wasmCode,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::vector<WasmImportFunc> const& imports,
beast::Journal j);
std::int32_t
initMaxPages(std::int32_t def);
std::int64_t
getGas();
// Host functions helper functionality
wasm_trap_t*
newTrap(std::string_view msg);
beast::Journal
getJournal() const;
private:
InstanceWrapper const&
getRT(int m = 0, int i = 0);
wmem
getMem() const;
int32_t
allocate(int32_t size);
Expected<WasmResult<int32_t>, TER>
runHlp(
Bytes const& wasmCode,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::vector<WasmImportFunc> const& imports,
HostFunctions* hfs,
int64_t gas);
NotTEC
checkHlp(
Bytes const& wasmCode,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::vector<WasmImportFunc> const& imports);
int
addModule(
Bytes const& wasmCode,
bool instantiate,
int64_t gas,
std::vector<WasmImportFunc> const& imports);
void
clearModules();
// int addInstance();
int32_t
runFunc(std::string_view const funcName, int32_t p);
int32_t
makeModule(
Bytes const& wasmCode,
wasm_extern_vec_t const& imports = WASM_EMPTY_VEC);
FuncInfo
getFunc(std::string_view funcName);
std::vector<wasm_val_t>
convertParams(std::vector<WasmParam> const& params);
static int
compareParamTypes(
wasm_valtype_vec_t const* ftp,
std::vector<wasm_val_t> const& p);
static void
add_param(std::vector<wasm_val_t>& in, int32_t p);
static void
add_param(std::vector<wasm_val_t>& in, int64_t p);
template <int NR, class... Types>
inline WamrResult
call(std::string_view func, Types&&... args);
template <int NR, class... Types>
inline WamrResult
call(FuncInfo const& f, Types&&... args);
template <int NR, class... Types>
inline WamrResult
call(FuncInfo const& f, std::vector<wasm_val_t>& in);
template <int NR, class... Types>
inline WamrResult
call(
FuncInfo const& f,
std::vector<wasm_val_t>& in,
std::int32_t p,
Types&&... args);
template <int NR, class... Types>
inline WamrResult
call(
FuncInfo const& f,
std::vector<wasm_val_t>& in,
std::int64_t p,
Types&&... args);
template <int NR, class... Types>
inline WamrResult
call(
FuncInfo const& f,
std::vector<wasm_val_t>& in,
uint8_t const* d,
std::size_t sz,
Types&&... args);
template <int NR, class... Types>
inline WamrResult
call(
FuncInfo const& f,
std::vector<wasm_val_t>& in,
Bytes const& p,
Types&&... args);
};
} // namespace ripple

111
src/xrpld/app/wasm/WasmVM.h Normal file
View File

@@ -0,0 +1,111 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#pragma once
#include <xrpld/app/wasm/HostFunc.h>
#include <string_view>
namespace ripple {
static std::string_view const W_ENV = "env";
static std::string_view const W_HOST_LIB = "host_lib";
static std::string_view const W_MEM = "memory";
static std::string_view const W_STORE = "store";
static std::string_view const W_LOAD = "load";
static std::string_view const W_SIZE = "size";
static std::string_view const W_ALLOC = "allocate";
static std::string_view const W_DEALLOC = "deallocate";
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 WamrEngine;
class WasmEngine
{
std::unique_ptr<WamrEngine> const impl;
WasmEngine();
WasmEngine(WasmEngine const&) = delete;
WasmEngine(WasmEngine&&) = delete;
WasmEngine&
operator=(WasmEngine const&) = delete;
WasmEngine&
operator=(WasmEngine&&) = delete;
public:
~WasmEngine() = default;
static WasmEngine&
instance();
Expected<WasmResult<int32_t>, TER>
run(Bytes const& wasmCode,
std::string_view funcName = {},
std::vector<WasmParam> const& params = {},
std::vector<WasmImportFunc> const& imports = {},
HostFunctions* hfs = nullptr,
int64_t gasLimit = -1,
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
NotTEC
check(
Bytes const& wasmCode,
std::string_view funcName,
std::vector<WasmParam> const& params = {},
std::vector<WasmImportFunc> 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 = {});
beast::Journal
getJournal() const;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<WasmImportFunc>
createWasmImport(HostFunctions* hfs);
Expected<EscrowResult, TER>
runEscrowWasm(
Bytes const& wasmCode,
std::string_view funcName = ESCROW_FUNCTION_NAME,
std::vector<WasmParam> const& params = {},
HostFunctions* hfs = nullptr,
int64_t gasLimit = -1,
beast::Journal j = beast::Journal(beast::Journal::getNullSink()));
NotTEC
preflightEscrowWasm(
Bytes const& wasmCode,
std::string_view funcName = ESCROW_FUNCTION_NAME,
std::vector<WasmParam> const& params = {},
HostFunctions* hfs = nullptr,
beast::Journal j = beast::Journal(beast::Journal::getNullSink()));
} // namespace ripple

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,164 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2025 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifdef _DEBUG
// #define DEBUG_OUTPUT 1
#endif
#include <xrpld/app/wasm/HostFunc.h>
#include <xrpld/app/wasm/HostFuncWrapper.h>
#include <xrpld/app/wasm/WamrVM.h>
#include <xrpl/basics/Log.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <memory>
namespace ripple {
std::vector<WasmImportFunc>
createWasmImport(HostFunctions* hfs)
{
std::vector<WasmImportFunc> i;
// Add host functions here
return i;
}
Expected<EscrowResult, TER>
runEscrowWasm(
Bytes const& wasmCode,
std::string_view funcName,
std::vector<WasmParam> const& params,
HostFunctions* hfs,
int64_t gasLimit,
beast::Journal j)
{
// create VM and set cost limit
auto& vm = WasmEngine::instance();
vm.initMaxPages(MAX_PAGES);
auto const ret = vm.run(
wasmCode,
funcName,
params,
createWasmImport(hfs),
hfs,
gasLimit,
hfs ? hfs->getJournal() : j);
// std::cout << "runEscrowWasm, mod size: " << wasmCode.size()
// << ", gasLimit: " << gasLimit << ", funcName: " << funcName;
if (!ret)
{
#ifdef DEBUG_OUTPUT
std::cout << ", error: " << ret.error() << std::endl;
#endif
return Unexpected<TER>(ret.error());
}
#ifdef DEBUG_OUTPUT
std::cout << ", ret: " << ret->result << ", gas spent: " << ret->cost
<< std::endl;
#endif
return EscrowResult{ret->result, ret->cost};
}
NotTEC
preflightEscrowWasm(
Bytes const& wasmCode,
std::string_view funcName,
std::vector<WasmParam> const& params,
HostFunctions* hfs,
beast::Journal j)
{
// create VM and set cost limit
auto& vm = WasmEngine::instance();
vm.initMaxPages(MAX_PAGES);
auto const ret = vm.check(
wasmCode,
funcName,
params,
createWasmImport(hfs),
hfs ? hfs->getJournal() : j);
return ret;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WasmEngine::WasmEngine() : impl(std::make_unique<WamrEngine>())
{
}
WasmEngine&
WasmEngine::instance()
{
static WasmEngine e;
return e;
}
Expected<WasmResult<int32_t>, TER>
WasmEngine::run(
Bytes const& wasmCode,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::vector<WasmImportFunc> const& imports,
HostFunctions* hfs,
int64_t gasLimit,
beast::Journal j)
{
return impl->run(wasmCode, funcName, params, imports, hfs, gasLimit, j);
}
NotTEC
WasmEngine::check(
Bytes const& wasmCode,
std::string_view funcName,
std::vector<WasmParam> const& params,
std::vector<WasmImportFunc> const& imports,
beast::Journal j)
{
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)
{
return impl->newTrap(msg);
}
beast::Journal
WasmEngine::getJournal() const
{
return impl->getJournal();
}
} // namespace ripple