1 /**
2  * \file wasmtime/func.h
3  *
4  * Wasmtime definitions of how to interact with host and wasm functions.
5  */
6 
7 #ifndef WASMTIME_FUNC_H
8 #define WASMTIME_FUNC_H
9 
10 #include <wasm.h>
11 #include <wasmtime/val.h>
12 #include <wasmtime/store.h>
13 #include <wasmtime/extern.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * \typedef wasmtime_caller_t
21  * \brief Alias to #wasmtime_caller
22  *
23  * \brief Structure used to learn about the caller of a host-defined function.
24  * \struct wasmtime_caller
25  *
26  * This structure is an argument to #wasmtime_func_callback_t. The purpose
27  * of this structure is acquire a #wasmtime_context_t pointer to interact with
28  * objects, but it can also be used for inspect the state of the caller (such as
29  * getting memories and functions) with #wasmtime_caller_export_get.
30  *
31  * This object is never owned and does not need to be deleted.
32  */
33 typedef struct wasmtime_caller wasmtime_caller_t;
34 
35 /**
36  * \brief Callback signature for #wasmtime_func_new.
37  *
38  * This is the function signature for host functions that can be made accessible
39  * to WebAssembly. The arguments to this function are:
40  *
41  * \param env user-provided argument passed to #wasmtime_func_new
42  * \param caller a temporary object that can only be used during this function
43  * call. Used to acquire #wasmtime_context_t or caller's state
44  * \param args the arguments provided to this function invocation
45  * \param nargs how many arguments are provided
46  * \param results where to write the results of this function
47  * \param nresults how many results must be produced
48  *
49  * Callbacks are guaranteed to get called with the right types of arguments, but
50  * they must produce the correct number and types of results. Failure to do so
51  * will cause traps to get raised on the wasm side.
52  *
53  * This callback can optionally return a #wasm_trap_t indicating that a trap
54  * should be raised in WebAssembly. It's expected that in this case the caller
55  * relinquishes ownership of the trap and it is passed back to the engine.
56  */
57 typedef wasm_trap_t* (*wasmtime_func_callback_t)(
58     void *env,
59     wasmtime_caller_t* caller,
60     const wasmtime_val_t *args,
61     size_t nargs,
62     wasmtime_val_t *results,
63     size_t nresults);
64 
65 /**
66  * \brief Creates a new host-defined function.
67  *
68  * Inserts a host-defined function into the `store` provided which can be used
69  * to then instantiate a module with or define within a #wasmtime_linker_t.
70  *
71  * \param store the store in which to create the function
72  * \param type the wasm type of the function that's being created
73  * \param callback the host-defined callback to invoke
74  * \param env host-specific data passed to the callback invocation, can be
75  * `NULL`
76  * \param finalizer optional finalizer for `env`, can be `NULL`
77  * \param ret the #wasmtime_func_t return value to be filled in.
78  *
79  * The returned function can only be used with the specified `store`.
80  */
81 WASM_API_EXTERN void wasmtime_func_new(
82   wasmtime_context_t *store,
83   const wasm_functype_t* type,
84   wasmtime_func_callback_t callback,
85   void *env,
86   void (*finalizer)(void*),
87   wasmtime_func_t *ret
88 );
89 
90 /**
91  * \brief Callback signature for #wasmtime_func_new_unchecked.
92  *
93  * This is the function signature for host functions that can be made accessible
94  * to WebAssembly. The arguments to this function are:
95  *
96  * \param env user-provided argument passed to #wasmtime_func_new_unchecked
97  * \param caller a temporary object that can only be used during this function
98  *        call. Used to acquire #wasmtime_context_t or caller's state
99  * \param args_and_results storage space for both the parameters to the
100  *        function as well as the results of the function. The size of this
101  *        array depends on the function type that the host function is created
102  *        with, but it will be the maximum of the number of parameters and
103  *        number of results.
104  * \param num_args_and_results the size of the `args_and_results` parameter in
105  *        units of #wasmtime_val_raw_t.
106  *
107  * This callback can optionally return a #wasm_trap_t indicating that a trap
108  * should be raised in WebAssembly. It's expected that in this case the caller
109  * relinquishes ownership of the trap and it is passed back to the engine.
110  *
111  * This differs from #wasmtime_func_callback_t in that the payload of
112  * `args_and_results` does not have type information, nor does it have sizing
113  * information. This is especially unsafe because it's only valid within the
114  * particular #wasm_functype_t that the function was created with. The onus is
115  * on the embedder to ensure that `args_and_results` are all read correctly
116  * for parameters and all written for results within the execution of a
117  * function.
118  *
119  * Parameters will be listed starting at index 0 in the `args_and_results`
120  * array. Results are also written starting at index 0, which will overwrite
121  * the arguments.
122  */
123 typedef wasm_trap_t* (*wasmtime_func_unchecked_callback_t)(
124     void *env,
125     wasmtime_caller_t* caller,
126     wasmtime_val_raw_t *args_and_results,
127     size_t num_args_and_results);
128 
129 /**
130  * \brief Creates a new host function in the same manner of #wasmtime_func_new,
131  *        but the function-to-call has no type information available at runtime.
132  *
133  * This function is very similar to #wasmtime_func_new. The difference is that
134  * this version is "more unsafe" in that when the host callback is invoked there
135  * is no type information and no checks that the right types of values are
136  * produced. The onus is on the consumer of this API to ensure that all
137  * invariants are upheld such as:
138  *
139  * * The host callback reads parameters correctly and interprets their types
140  *   correctly.
141  * * If a trap doesn't happen then all results are written to the results
142  *   pointer. All results must have the correct type.
143  * * Types such as `funcref` cannot cross stores.
144  * * Types such as `externref` have valid reference counts.
145  *
146  * It's generally only recommended to use this if your application can wrap
147  * this in a safe embedding. This should not be frequently used due to the
148  * number of invariants that must be upheld on the wasm<->host boundary. On the
149  * upside, though, this flavor of host function will be faster to call than
150  * those created by #wasmtime_func_new (hence the reason for this function's
151  * existence).
152  */
153 WASM_API_EXTERN void wasmtime_func_new_unchecked(
154   wasmtime_context_t *store,
155   const wasm_functype_t* type,
156   wasmtime_func_unchecked_callback_t callback,
157   void *env,
158   void (*finalizer)(void*),
159   wasmtime_func_t *ret
160 );
161 
162 /**
163  * \brief Returns the type of the function specified
164  *
165  * The returned #wasm_functype_t is owned by the caller.
166  */
167 WASM_API_EXTERN wasm_functype_t* wasmtime_func_type(
168     const wasmtime_context_t *store,
169     const wasmtime_func_t *func
170 );
171 
172 /**
173  * \brief Call a WebAssembly function.
174  *
175  * This function is used to invoke a function defined within a store. For
176  * example this might be used after extracting a function from a
177  * #wasmtime_instance_t.
178  *
179  * \param store the store which owns `func`
180  * \param func the function to call
181  * \param args the arguments to the function call
182  * \param nargs the number of arguments provided
183  * \param results where to write the results of the function call
184  * \param nresults the number of results expected
185  * \param trap where to store a trap, if one happens.
186  *
187  * There are three possible return states from this function:
188  *
189  * 1. The returned error is non-null. This means `results`
190  *    wasn't written to and `trap` will have `NULL` written to it. This state
191  *    means that programmer error happened when calling the function, for
192  *    example when the size of the arguments/results was wrong, the types of the
193  *    arguments were wrong, or arguments may come from the wrong store.
194  * 2. The trap pointer is filled in. This means the returned error is `NULL` and
195  *    `results` was not written to. This state means that the function was
196  *    executing but hit a wasm trap while executing.
197  * 3. The error and trap returned are both `NULL` and `results` are written to.
198  *    This means that the function call succeeded and the specified results were
199  *    produced.
200  *
201  * The `trap` pointer cannot be `NULL`. The `args` and `results` pointers may be
202  * `NULL` if the corresponding length is zero.
203  *
204  * Does not take ownership of #wasmtime_val_t arguments. Gives ownership of
205  * #wasmtime_val_t results.
206  */
207 WASM_API_EXTERN wasmtime_error_t *wasmtime_func_call(
208     wasmtime_context_t *store,
209     const wasmtime_func_t *func,
210     const wasmtime_val_t *args,
211     size_t nargs,
212     wasmtime_val_t *results,
213     size_t nresults,
214     wasm_trap_t **trap
215 );
216 
217 /**
218  * \brief Call a WebAssembly function in an "unchecked" fashion.
219  *
220  * This function is similar to #wasmtime_func_call except that there is no type
221  * information provided with the arguments (or sizing information). Consequently
222  * this is less safe to call since it's up to the caller to ensure that `args`
223  * has an appropriate size and all the parameters are configured with their
224  * appropriate values/types. Additionally all the results must be interpreted
225  * correctly if this function returns successfully.
226  *
227  * Parameters must be specified starting at index 0 in the `args_and_results`
228  * array. Results are written starting at index 0, which will overwrite
229  * the arguments.
230  *
231  * Callers must ensure that various correctness variants are upheld when this
232  * API is called such as:
233  *
234  * * The `args_and_results` pointer has enough space to hold all the parameters
235  *   and all the results (but not at the same time).
236  * * Parameters must all be configured as if they were the correct type.
237  * * Values such as `externref` and `funcref` are valid within the store being
238  *   called.
239  *
240  * When in doubt it's much safer to call #wasmtime_func_call. This function is
241  * faster than that function, but the tradeoff is that embeddings must uphold
242  * more invariants rather than relying on Wasmtime to check them for you.
243  */
244 WASM_API_EXTERN wasm_trap_t *wasmtime_func_call_unchecked(
245     wasmtime_context_t *store,
246     const wasmtime_func_t *func,
247     wasmtime_val_raw_t *args_and_results
248 );
249 
250 /**
251  * \brief Loads a #wasmtime_extern_t from the caller's context
252  *
253  * This function will attempt to look up the export named `name` on the caller
254  * instance provided. If it is found then the #wasmtime_extern_t for that is
255  * returned, otherwise `NULL` is returned.
256  *
257  * Note that this only works for exported memories right now for WASI
258  * compatibility.
259  *
260  * \param caller the caller object to look up the export from
261  * \param name the name that's being looked up
262  * \param name_len the byte length of `name`
263  * \param item where to store the return value
264  *
265  * Returns a nonzero value if the export was found, or 0 if the export wasn't
266  * found. If the export wasn't found then `item` isn't written to.
267  */
268 WASM_API_EXTERN bool wasmtime_caller_export_get(
269     wasmtime_caller_t *caller,
270     const char *name,
271     size_t name_len,
272     wasmtime_extern_t *item
273 );
274 
275 /**
276  * \brief Returns the store context of the caller object.
277  */
278 WASM_API_EXTERN wasmtime_context_t* wasmtime_caller_context(wasmtime_caller_t* caller);
279 
280 /**
281  * \brief Converts a `raw` nonzero `funcref` value from #wasmtime_val_raw_t
282  * into a #wasmtime_func_t.
283  *
284  * This function can be used to interpret nonzero values of the `funcref` field
285  * of the #wasmtime_val_raw_t structure. It is assumed that `raw` does not have
286  * a value of 0, or otherwise the program will abort.
287  *
288  * Note that this function is unchecked and unsafe. It's only safe to pass
289  * values learned from #wasmtime_val_raw_t with the same corresponding
290  * #wasmtime_context_t that they were produced from. Providing arbitrary values
291  * to `raw` here or cross-context values with `context` is UB.
292  */
293 WASM_API_EXTERN void wasmtime_func_from_raw(
294     wasmtime_context_t* context,
295     size_t raw,
296     wasmtime_func_t *ret);
297 
298 /**
299  * \brief Converts a `func`  which belongs to `context` into a `usize`
300  * parameter that is suitable for insertion into a #wasmtime_val_raw_t.
301  */
302 WASM_API_EXTERN size_t wasmtime_func_to_raw(
303     wasmtime_context_t* context,
304     const wasmtime_func_t *func);
305 
306 #ifdef __cplusplus
307 }  // extern "C"
308 #endif
309 
310 #endif // WASMTIME_FUNC_H
311