5#ifndef WASMTIME_FUNC_HH
6#define WASMTIME_FUNC_HH
8#include <wasmtime/_func_class.hh>
9#include <wasmtime/_val_class.hh>
18#define NATIVE_WASM_TYPE(native, valkind, field) \
19 template <> struct WasmType<native> { \
20 static const bool valid = true; \
21 static ValType valtype() { return ValType::valkind(); } \
22 static void store(Store::Context cx, wasmtime_val_raw_t *p, \
27 static native load(Store::Context cx, wasmtime_val_raw_t *p) { \
40#undef NATIVE_WASM_TYPE
43template <>
struct WasmType<std::optional<Func>> {
45 static const bool valid =
true;
50 const std::optional<Func> func) {
69template <>
struct WasmTypeList<std::monostate> {
70 static const bool valid =
true;
71 static const size_t size = 0;
72 static bool matches(ValType::ListRef types) {
return types.size() == 0; }
74 const std::monostate &t) {
82 return std::monostate();
84 static std::vector<ValType> types() {
return {}; }
88template <
typename... T>
struct WasmTypeList<std::tuple<T...>> {
89 static const bool valid = (WasmType<T>::valid && ...);
90 static const size_t size =
sizeof...(T);
91 static bool matches(ValType::ListRef types) {
92 if (types.size() != size) {
96 return ((WasmType<T>::valtype() == types.begin()[n++]) && ...);
99 std::tuple<T...> &&t) {
103 (WasmType<T>::store(cx, &storage[n++], val), ...);
108 const std::tuple<T...> &t) {
111 [&](
const auto &...val) {
112 (WasmType<T>::store(cx, &storage[n++], val), ...);
118 return std::tuple<T...>{WasmType<T>::load(cx, storage++)...};
120 static std::vector<ValType> types() {
return {WasmType<T>::valtype()...}; }
124template <>
struct WasmHostRet<void> {
125 using Results = WasmTypeList<std::tuple<>>;
127 template <
typename F,
typename... A>
139template <>
struct WasmHostRet<std::monostate> :
public WasmHostRet<void> {};
143template <
typename R>
struct WasmHostRet<Result<R, Trap>> {
144 using Results = WasmTypeList<R>;
146 template <
typename F,
typename... A>
149 Result<R, Trap> ret = f(args...);
153 Results::store(cx, raw, ret.ok());
160template <
typename R,
typename... A>
struct WasmHostFunc<R (*)(A...)> {
161 using Params = WasmTypeList<std::tuple<A...>>;
162 using Results =
typename WasmHostRet<R>::Results;
164 template <
typename F>
166 auto params = Params::load(cx, raw);
168 [&](
const auto &...val) {
169 return WasmHostRet<R>::invoke(f, cx, raw, val...);
176template <
typename R,
typename... A>
177struct WasmHostFunc<R (*)(Caller, A...)> :
public WasmHostFunc<R (*)(A...)> {
179 template <
typename F>
181 auto params = WasmTypeList<std::tuple<A...>>::load(cx, raw);
183 [&](
const auto &...val) {
184 return WasmHostRet<R>::invoke(f, cx, raw, cx, val...);
191template <
typename R,
typename C,
typename... A>
192struct WasmHostFunc<R (C::*)(A...)> :
public WasmHostFunc<R (*)(A...)> {};
195template <
typename R,
typename C,
typename... A>
196struct WasmHostFunc<R (C::*)(A...) const> :
public WasmHostFunc<R (*)(A...)> {};
200template <
typename R,
typename C,
typename... A>
201struct WasmHostFunc<R (C::*)(Caller, A...)>
202 :
public WasmHostFunc<R (*)(Caller, A...)> {};
206template <
typename R,
typename C,
typename... A>
207struct WasmHostFunc<R (C::*)(Caller, A...) const>
208 :
public WasmHostFunc<R (*)(Caller, A...)> {};
213struct WasmHostFunc<T, std::void_t<decltype(&T::operator())>>
214 :
public WasmHostFunc<decltype(&T::operator())> {};
218using namespace detail;
227 F *func =
reinterpret_cast<F *
>(env);
228 Span<const Val> args_span(
reinterpret_cast<const Val *
>(args),
230 Span<Val> results_span(
reinterpret_cast<Val *
>(results),
232 Result<std::monostate, Trap> result =
233 (*func)(Caller(caller), args_span, results_span);
235 return result.err().capi_release();
241inline TrapResult<std::vector<Val>>
243 std::vector<wasmtime_val_t> raw_params;
244 raw_params.reserve(end - begin);
245 for (
auto i = begin; i != end; i++) {
246 raw_params.push_back(i->val);
249 std::vector<wasmtime_val_t> raw_results(nresults);
254 raw_results.data(), raw_results.capacity(), &trap);
255 if (error !=
nullptr) {
258 if (trap !=
nullptr) {
262 std::vector<Val> results;
263 results.reserve(nresults);
264 for (
size_t i = 0; i < nresults; i++) {
265 results.push_back(raw_results[i]);
272 return this->
call(cx, params.begin(), params.end());
277 return this->
call(cx, params.begin(), params.end());
Errors coming from Wasmtime.
Definition: error.hh:26
ValType::ListRef results() const
Returns the list of types this function type returns.
Definition: types/func.hh:43
TrapResult< std::vector< Val > > call(Store::Context cx, const I &begin, const I &end) const
Invoke a WebAssembly function.
Definition: func.hh:242
FuncType type(Store::Context cx) const
Returns the type of this function.
Definition: _func_class.hh:282
Fallible result type used for Wasmtime.
Definition: error.hh:70
An interior pointer into a Store.
Definition: _store_class.hh:65
Information about a WebAssembly trap.
Definition: trap.hh:113
size_t size() const
Returns how many types are in this list.
Definition: types/_val_class.hh:72
static ValType funcref()
Convenience constructor for the funcref value type.
Definition: types/_val_class.hh:137
WASM_API_EXTERN wasmtime_error_t * wasmtime_func_call(wasmtime_context_t *store, const wasmtime_func_t *func, const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *results, size_t nresults, wasm_trap_t **trap)
Call a WebAssembly function.
WASM_API_EXTERN void * wasmtime_func_to_raw(wasmtime_context_t *context, const wasmtime_func_t *func)
Converts a func which belongs to context into a usize parameter that is suitable for insertion into a...
WASM_API_EXTERN void wasmtime_func_from_raw(wasmtime_context_t *context, void *raw, wasmtime_func_t *ret)
Converts a raw nonzero funcref value from wasmtime_val_raw_t into a wasmtime_func_t.
#define NATIVE_WASM_TYPE(native, valkind, field)
Definition: func.hh:18
Opaque struct representing a wasm trap.
Structure used to represent either a Trap or an Error.
Definition: trap.hh:153
Representation of a function in Wasmtime.
Definition: extern.h:26
Container for different kinds of wasm values.
Definition: val.h:376
Container for possible wasm values.
Definition: val.h:290
void * funcref
Definition: val.h:343