Wasmtime
_func_class.hh
1#ifndef WASMTIME_FUNC_CLASS_HH
2#define WASMTIME_FUNC_CLASS_HH
3
4#include <array>
5#include <wasmtime/_store_class.hh>
6#include <wasmtime/error.hh>
7#include <wasmtime/extern_declare.hh>
8#include <wasmtime/func.h>
9#include <wasmtime/span.hh>
10#include <wasmtime/trap.hh>
12#include <wasmtime/types/val.hh>
13
14namespace wasmtime {
15
16class Val;
17
25class Caller {
26 friend class Func;
27 friend class Store;
29 Caller(wasmtime_caller_t *ptr) : ptr(ptr) {}
30
31public:
36 std::optional<Extern> get_export(std::string_view name);
37
39 Store::Context context() { return this; }
40};
41
42namespace detail {
43
46template <typename T> struct WasmType {
47 static const bool valid = false;
48};
49
54template <typename T> struct WasmTypeList {
55 static const bool valid = WasmType<T>::valid;
56 static const size_t size = 1;
57 static bool matches(ValType::ListRef types) {
58 return WasmTypeList<std::tuple<T>>::matches(types);
59 }
60 static void store(Store::Context cx, wasmtime_val_raw_t *storage, T &&t) {
61 WasmType<T>::store(cx, storage, t);
62 }
63 static void store(Store::Context cx, wasmtime_val_raw_t *storage,
64 const T &t) {
65 WasmType<T>::store(cx, storage, t);
66 }
67 static T load(Store::Context cx, wasmtime_val_raw_t *storage) {
68 return WasmType<T>::load(cx, storage);
69 }
70 static std::vector<ValType> types() { return {WasmType<T>::valtype()}; }
71};
72
76template <typename R> struct WasmHostRet {
77 using Results = WasmTypeList<R>;
78
79 template <typename F, typename... A>
80 static std::optional<Trap> invoke(F f, Caller cx, wasmtime_val_raw_t *raw,
81 A... args) {
82 auto ret = f(args...);
83 Results::store(cx, raw, ret);
84 return std::nullopt;
85 }
86};
87
88template <typename F, typename = void> struct WasmHostFunc;
89
90} // namespace detail
91
92using namespace detail;
93
94// forward-declaration for `Func::typed` below.
95template <typename Params, typename Results> class TypedFunc;
96
108class Func {
109 friend class Val;
110 friend class Instance;
111 friend class Linker;
112 template <typename Params, typename Results> friend class TypedFunc;
113
114 wasmtime_func_t func;
115
116 template <typename F>
117 static wasm_trap_t *raw_callback(void *env, wasmtime_caller_t *caller,
118 const wasmtime_val_t *args, size_t nargs,
119 wasmtime_val_t *results, size_t nresults);
120
121 template <typename F>
122 static wasm_trap_t *
123 raw_callback_unchecked(void *env, wasmtime_caller_t *caller,
124 wasmtime_val_raw_t *args_and_results,
125 size_t nargs_and_results) {
126 (void)nargs_and_results;
127 using HostFunc = WasmHostFunc<F>;
128 Caller cx(caller);
129 F *func = reinterpret_cast<F *>(env); // NOLINT
130 auto trap = HostFunc::invoke(*func, cx, args_and_results);
131 if (trap) {
132 return trap->capi_release();
133 }
134 return nullptr;
135 }
136
137 template <typename F> static void raw_finalize(void *env) {
138 std::unique_ptr<F> ptr(reinterpret_cast<F *>(env)); // NOLINT
139 }
140
141public:
143 Func(wasmtime_func_t func) : func(func) {}
144
176 template <typename F,
177 std::enable_if_t<
178 std::is_invocable_r_v<Result<std::monostate, Trap>, F, Caller,
180 bool> = true>
181 Func(Store::Context cx, const FuncType &ty, F f) : func({}) {
182 wasmtime_func_new(cx.ptr, ty.ptr.get(), raw_callback<F>,
183 std::make_unique<F>(f).release(), raw_finalize<F>, &func);
184 }
185
224 template <typename F,
225 std::enable_if_t<WasmHostFunc<F>::Params::valid, bool> = true,
226 std::enable_if_t<WasmHostFunc<F>::Results::valid, bool> = true>
227 static Func wrap(Store::Context cx, F f) {
228 using HostFunc = WasmHostFunc<F>;
229 auto params = HostFunc::Params::types();
230 auto results = HostFunc::Results::types();
231 auto ty = FuncType::from_iters(params, results);
232 wasmtime_func_t func;
233 wasmtime_func_new_unchecked(cx.ptr, ty.ptr.get(), raw_callback_unchecked<F>,
234 std::make_unique<F>(f).release(),
235 raw_finalize<F>, &func);
236 return func;
237 }
238
259 template <typename I>
261 const I &end) const;
262
270 const std::vector<Val> &params) const;
271
279 call(Store::Context cx, const std::initializer_list<Val> &params) const;
280
283 return wasmtime_func_type(cx.ptr, &func);
284 }
285
303 template <typename Params, typename Results,
304 std::enable_if_t<WasmTypeList<Params>::valid, bool> = true,
305 std::enable_if_t<WasmTypeList<Results>::valid, bool> = true>
307 auto ty = this->type(cx);
308 if (!WasmTypeList<Params>::matches(ty->params()) ||
309 !WasmTypeList<Results>::matches(ty->results())) {
310 return Trap("static type for this function does not match actual type");
311 }
313 return ret;
314 }
315
317 const wasmtime_func_t &capi() const { return func; }
318};
319
324template <typename Params, typename Results> class TypedFunc {
325 friend class Func;
326 Func f;
327 TypedFunc(Func func) : f(func) {}
328
329public:
340 TrapResult<Results> call(Store::Context cx, const Params &params) const {
341 std::array<wasmtime_val_raw_t, std::max(WasmTypeList<Params>::size,
342 WasmTypeList<Results>::size)>
343 storage;
344 wasmtime_val_raw_t *ptr = storage.data();
345 if (ptr == nullptr)
346 ptr = reinterpret_cast<wasmtime_val_raw_t *>(alignof(wasmtime_val_raw_t));
347 WasmTypeList<Params>::store(cx, ptr, params);
348 wasm_trap_t *trap = nullptr;
349 auto *error = wasmtime_func_call_unchecked(cx.capi(), &f.func, ptr,
350 storage.size(), &trap);
351 if (error != nullptr) {
352 return TrapError(Error(error));
353 }
354 if (trap != nullptr) {
355 return TrapError(Trap(trap));
356 }
357 return WasmTypeList<Results>::load(cx, ptr);
358 }
359
361 const Func &func() const { return f; }
362};
363
364} // namespace wasmtime
365
366#endif // WASMTIME_FUNC_CLASS_HH
Structure provided to host functions to lookup caller information or acquire a Store::Context.
Definition: _func_class.hh:25
std::optional< Extern > get_export(std::string_view name)
Definition: extern.hh:59
Store::Context context()
Explicitly acquire a Store::Context from this Caller.
Definition: _func_class.hh:39
Errors coming from Wasmtime.
Definition: error.hh:26
Type information for a WebAssembly function.
Definition: types/func.hh:15
static FuncType from_iters(P params, R results)
Creates a new function type from the given list of parameters and results.
Definition: types/func.hh:76
Representation of a WebAssembly function.
Definition: _func_class.hh:108
TrapResult< std::vector< Val > > call(Store::Context cx, const I &begin, const I &end) const
Invoke a WebAssembly function.
Definition: func.hh:242
Func(wasmtime_func_t func)
Creates a new function from the raw underlying C API representation.
Definition: _func_class.hh:143
FuncType type(Store::Context cx) const
Returns the type of this function.
Definition: _func_class.hh:282
static Func wrap(Store::Context cx, F f)
Creates a new host function from the provided callback f, inferring the WebAssembly function type fro...
Definition: _func_class.hh:227
const wasmtime_func_t & capi() const
Returns the raw underlying C API function this is using.
Definition: _func_class.hh:317
Func(Store::Context cx, const FuncType &ty, F f)
Creates a new host-defined function.
Definition: _func_class.hh:181
Result< TypedFunc< Params, Results >, Trap > typed(Store::Context cx) const
Statically checks this function against the provided types.
Definition: _func_class.hh:306
A WebAssembly instance.
Definition: instance.hh:32
Helper class for linking modules together with name-based resolution.
Definition: linker.hh:26
Fallible result type used for Wasmtime.
Definition: error.hh:70
Span class used when c++20 is not available.
Definition: span.hh:47
An interior pointer into a Store.
Definition: _store_class.hh:65
const wasmtime_context_t * capi() const
Returns the underlying C API pointer.
Definition: _store_class.hh:183
Owner of all WebAssembly objects.
Definition: _store_class.hh:41
Information about a WebAssembly trap.
Definition: trap.hh:113
A version of a WebAssembly Func where the type signature of the function is statically known.
Definition: _func_class.hh:324
const Func & func() const
Returns the underlying un-typed Func for this function.
Definition: _func_class.hh:361
TrapResult< Results > call(Store::Context cx, const Params &params) const
Calls this function with the provided parameters.
Definition: _func_class.hh:340
Representation of a generic WebAssembly value.
Definition: _val_class.hh:54
WASM_API_EXTERN void wasmtime_func_new(wasmtime_context_t *store, const wasm_functype_t *type, wasmtime_func_callback_t callback, void *env, void(*finalizer)(void *), wasmtime_func_t *ret)
Creates a new host-defined function.
WASM_API_EXTERN wasm_functype_t * wasmtime_func_type(const wasmtime_context_t *store, const wasmtime_func_t *func)
Returns the type of the function specified.
WASM_API_EXTERN void wasmtime_func_new_unchecked(wasmtime_context_t *store, const wasm_functype_t *type, wasmtime_func_unchecked_callback_t callback, void *env, void(*finalizer)(void *), wasmtime_func_t *ret)
Creates a new host function in the same manner of wasmtime_func_new, but the function-to-call has no ...
WASM_API_EXTERN wasmtime_error_t * wasmtime_func_call_unchecked(wasmtime_context_t *store, const wasmtime_func_t *func, wasmtime_val_raw_t *args_and_results, size_t args_and_results_len, wasm_trap_t **trap)
Call a WebAssembly function in an "unchecked" fashion.
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
union wasmtime_val_raw wasmtime_val_raw_t
Convenience alias for wasmtime_val_raw.