17 auto literalMemFun() {
22 auto literalMemFun<int32_t>() {
23 return &wasm::Literal::geti32;
27 auto literalMemFun<uint64_t>() {
28 return &wasm::Literal::geti64;
32 auto literalMemFun<uint32_t>() {
33 return &wasm::Literal::geti32;
40 template <
typename T,
typename R,
auto mf,
typename... Args,
size_t... I>
41 wasm::Literal callInternal(T *host_api,
42 const wasm::LiteralList &arguments,
43 std::index_sequence<I...>) {
44 if constexpr (not std::is_same_v<void, R>) {
48 (host_api->*mf)((arguments.at(I).*literalMemFun<Args>())()...));
50 (host_api->*mf)((arguments.at(I).*literalMemFun<Args>())()...);
51 return wasm::Literal();
60 template <
typename T, T>
62 template <
typename T,
typename R,
typename... Args, R (T::*mf)(Args...)>
63 struct HostApiFunc<R (T::*)(Args...), mf> {
65 static const size_t size =
sizeof...(Args);
66 static wasm::Literal call(T *host_api,
const wasm::LiteralList &arguments) {
68 auto indices = std::index_sequence_for<Args...>{};
69 return callInternal<T, R, mf, Args...>(host_api, arguments, indices);
72 template <
typename T,
typename R,
typename... Args, R (T::*mf)(Args...)
const>
73 struct HostApiFunc<R (T::*)(Args...) const, mf> {
75 static const size_t size =
sizeof...(Args);
76 static wasm::Literal call(T *host_api,
const wasm::LiteralList &arguments) {
78 auto indices = std::index_sequence_for<Args...>{};
79 return callInternal<T, R, mf, Args...>(host_api, arguments, indices);
89 constexpr
size_t hostApiFuncArgSize() {
90 return HostApiFunc<decltype(mf), mf>::size;
102 const wasm::LiteralList &arguments) {
103 return HostApiFunc<decltype(mf), mf>::call(host_api, arguments);
114 #define REGISTER_HOST_API_FUNC(name) \ 116 &importCall<&host_api::HostApi ::name> // hack to make macro call look 120 class TrieStorageProvider;
125 const static wasm::Name
env =
"env";
131 void RuntimeExternalInterface::methodsRegistration() {
178 ext_crypto_secp256k1_ecdsa_recover_compressed_version_1);
180 ext_crypto_secp256k1_ecdsa_recover_compressed_version_2);
233 ext_offchain_local_storage_compare_and_set_version_1);
246 RuntimeExternalInterface::RuntimeExternalInterface(
247 std::shared_ptr<host_api::HostApi> host_api)
248 : host_api_{std::move(host_api)},
260 wasm::Function *
import, wasm::LiteralList &arguments) {
261 SL_TRACE(
logger_,
"Call import {}", import->base);
262 if (import->module == env) {
266 return it->second(*
this,
import, arguments);
270 wasm::Fatal() <<
"callImport: unknown import: " <<
import->module.str <<
"." 272 return wasm::Literal();
278 if (expected != actual) {
280 "Wrong number of arguments in {}. Expected: {}. Actual: {}",
284 throw std::runtime_error(
285 "Invocation of a Host API method with wrong number of arguments");
292 wasm::Function *
import,
293 wasm::LiteralList &arguments) {
295 import->base.c_str(), hostApiFuncArgSize<mf>(), arguments.size());
296 return callHostApiFunc<mf>(this_.
host_api_.get(), arguments);
wasm::Literal callImport(wasm::Function *import, wasm::LiteralList &arguments) override
wasm::ShellExternalInterface::Memory * getMemory()
static const wasm::Name env
#define REGISTER_HOST_API_FUNC(name)
check arg num and call HostApi method macro Aims to reduce boiler plate code and method name mentions...
void checkArguments(std::string_view extern_name, size_t expected, size_t actual)
constexpr size_t kInitialMemorySize
void methodsRegistration()
boost::unordered_map< std::string, ImportFuncPtr > imports_
Logger createLogger(const std::string &tag)
static wasm::Literal importCall(RuntimeExternalInterface &this_, wasm::Function *import, wasm::LiteralList &arguments)
std::shared_ptr< host_api::HostApi > host_api_