17a1b7cdfSAlex Crichton /**
27a1b7cdfSAlex Crichton  * \file wasmtime/func.h
37a1b7cdfSAlex Crichton  *
47a1b7cdfSAlex Crichton  * Wasmtime definitions of how to interact with host and wasm functions.
57a1b7cdfSAlex Crichton  */
67a1b7cdfSAlex Crichton 
77a1b7cdfSAlex Crichton #ifndef WASMTIME_FUNC_H
87a1b7cdfSAlex Crichton #define WASMTIME_FUNC_H
97a1b7cdfSAlex Crichton 
107a1b7cdfSAlex Crichton #include <wasm.h>
117a1b7cdfSAlex Crichton #include <wasmtime/extern.h>
12*f8fee938STyler Rockwood #include <wasmtime/store.h>
13*f8fee938STyler Rockwood #include <wasmtime/val.h>
147a1b7cdfSAlex Crichton 
157a1b7cdfSAlex Crichton #ifdef __cplusplus
167a1b7cdfSAlex Crichton extern "C" {
177a1b7cdfSAlex Crichton #endif
187a1b7cdfSAlex Crichton 
197a1b7cdfSAlex Crichton /**
207a1b7cdfSAlex Crichton  * \typedef wasmtime_caller_t
217a1b7cdfSAlex Crichton  * \brief Alias to #wasmtime_caller
227a1b7cdfSAlex Crichton  *
237a1b7cdfSAlex Crichton  * \brief Structure used to learn about the caller of a host-defined function.
247a1b7cdfSAlex Crichton  * \struct wasmtime_caller
257a1b7cdfSAlex Crichton  *
267a1b7cdfSAlex Crichton  * This structure is an argument to #wasmtime_func_callback_t. The purpose
277a1b7cdfSAlex Crichton  * of this structure is acquire a #wasmtime_context_t pointer to interact with
287a1b7cdfSAlex Crichton  * objects, but it can also be used for inspect the state of the caller (such as
297a1b7cdfSAlex Crichton  * getting memories and functions) with #wasmtime_caller_export_get.
307a1b7cdfSAlex Crichton  *
317a1b7cdfSAlex Crichton  * This object is never owned and does not need to be deleted.
327a1b7cdfSAlex Crichton  */
337a1b7cdfSAlex Crichton typedef struct wasmtime_caller wasmtime_caller_t;
347a1b7cdfSAlex Crichton 
357a1b7cdfSAlex Crichton /**
367a1b7cdfSAlex Crichton  * \brief Callback signature for #wasmtime_func_new.
377a1b7cdfSAlex Crichton  *
387a1b7cdfSAlex Crichton  * This is the function signature for host functions that can be made accessible
397a1b7cdfSAlex Crichton  * to WebAssembly. The arguments to this function are:
407a1b7cdfSAlex Crichton  *
417a1b7cdfSAlex Crichton  * \param env user-provided argument passed to #wasmtime_func_new
427a1b7cdfSAlex Crichton  * \param caller a temporary object that can only be used during this function
437a1b7cdfSAlex Crichton  * call. Used to acquire #wasmtime_context_t or caller's state
447a1b7cdfSAlex Crichton  * \param args the arguments provided to this function invocation
457a1b7cdfSAlex Crichton  * \param nargs how many arguments are provided
467a1b7cdfSAlex Crichton  * \param results where to write the results of this function
477a1b7cdfSAlex Crichton  * \param nresults how many results must be produced
487a1b7cdfSAlex Crichton  *
497a1b7cdfSAlex Crichton  * Callbacks are guaranteed to get called with the right types of arguments, but
507a1b7cdfSAlex Crichton  * they must produce the correct number and types of results. Failure to do so
517a1b7cdfSAlex Crichton  * will cause traps to get raised on the wasm side.
527a1b7cdfSAlex Crichton  *
537a1b7cdfSAlex Crichton  * This callback can optionally return a #wasm_trap_t indicating that a trap
547a1b7cdfSAlex Crichton  * should be raised in WebAssembly. It's expected that in this case the caller
557a1b7cdfSAlex Crichton  * relinquishes ownership of the trap and it is passed back to the engine.
567a1b7cdfSAlex Crichton  */
577a1b7cdfSAlex Crichton typedef wasm_trap_t *(*wasmtime_func_callback_t)(
58*f8fee938STyler Rockwood     void *env, wasmtime_caller_t *caller, const wasmtime_val_t *args,
59*f8fee938STyler Rockwood     size_t nargs, wasmtime_val_t *results, size_t nresults);
607a1b7cdfSAlex Crichton 
617a1b7cdfSAlex Crichton /**
627a1b7cdfSAlex Crichton  * \brief Creates a new host-defined function.
637a1b7cdfSAlex Crichton  *
647a1b7cdfSAlex Crichton  * Inserts a host-defined function into the `store` provided which can be used
657a1b7cdfSAlex Crichton  * to then instantiate a module with or define within a #wasmtime_linker_t.
667a1b7cdfSAlex Crichton  *
677a1b7cdfSAlex Crichton  * \param store the store in which to create the function
687a1b7cdfSAlex Crichton  * \param type the wasm type of the function that's being created
697a1b7cdfSAlex Crichton  * \param callback the host-defined callback to invoke
707a1b7cdfSAlex Crichton  * \param env host-specific data passed to the callback invocation, can be
717a1b7cdfSAlex Crichton  * `NULL`
727a1b7cdfSAlex Crichton  * \param finalizer optional finalizer for `env`, can be `NULL`
737a1b7cdfSAlex Crichton  * \param ret the #wasmtime_func_t return value to be filled in.
747a1b7cdfSAlex Crichton  *
757a1b7cdfSAlex Crichton  * The returned function can only be used with the specified `store`.
767a1b7cdfSAlex Crichton  */
77*f8fee938STyler Rockwood WASM_API_EXTERN void wasmtime_func_new(wasmtime_context_t *store,
787a1b7cdfSAlex Crichton                                        const wasm_functype_t *type,
797a1b7cdfSAlex Crichton                                        wasmtime_func_callback_t callback,
80*f8fee938STyler Rockwood                                        void *env, void (*finalizer)(void *),
81*f8fee938STyler Rockwood                                        wasmtime_func_t *ret);
827a1b7cdfSAlex Crichton 
837a1b7cdfSAlex Crichton /**
84bfdbd10aSAlex Crichton  * \brief Callback signature for #wasmtime_func_new_unchecked.
85bfdbd10aSAlex Crichton  *
86bfdbd10aSAlex Crichton  * This is the function signature for host functions that can be made accessible
87bfdbd10aSAlex Crichton  * to WebAssembly. The arguments to this function are:
88bfdbd10aSAlex Crichton  *
89bfdbd10aSAlex Crichton  * \param env user-provided argument passed to #wasmtime_func_new_unchecked
90bfdbd10aSAlex Crichton  * \param caller a temporary object that can only be used during this function
91bfdbd10aSAlex Crichton  *        call. Used to acquire #wasmtime_context_t or caller's state
92bfdbd10aSAlex Crichton  * \param args_and_results storage space for both the parameters to the
93bfdbd10aSAlex Crichton  *        function as well as the results of the function. The size of this
94bfdbd10aSAlex Crichton  *        array depends on the function type that the host function is created
95bfdbd10aSAlex Crichton  *        with, but it will be the maximum of the number of parameters and
96bfdbd10aSAlex Crichton  *        number of results.
97f4b90209SAlex Crichton  * \param num_args_and_results the size of the `args_and_results` parameter in
98f4b90209SAlex Crichton  *        units of #wasmtime_val_raw_t.
99bfdbd10aSAlex Crichton  *
100bfdbd10aSAlex Crichton  * This callback can optionally return a #wasm_trap_t indicating that a trap
101bfdbd10aSAlex Crichton  * should be raised in WebAssembly. It's expected that in this case the caller
102bfdbd10aSAlex Crichton  * relinquishes ownership of the trap and it is passed back to the engine.
103bfdbd10aSAlex Crichton  *
104bfdbd10aSAlex Crichton  * This differs from #wasmtime_func_callback_t in that the payload of
105bfdbd10aSAlex Crichton  * `args_and_results` does not have type information, nor does it have sizing
106bfdbd10aSAlex Crichton  * information. This is especially unsafe because it's only valid within the
107bfdbd10aSAlex Crichton  * particular #wasm_functype_t that the function was created with. The onus is
108bfdbd10aSAlex Crichton  * on the embedder to ensure that `args_and_results` are all read correctly
109bfdbd10aSAlex Crichton  * for parameters and all written for results within the execution of a
110bfdbd10aSAlex Crichton  * function.
111bfdbd10aSAlex Crichton  *
112bfdbd10aSAlex Crichton  * Parameters will be listed starting at index 0 in the `args_and_results`
113bfdbd10aSAlex Crichton  * array. Results are also written starting at index 0, which will overwrite
114bfdbd10aSAlex Crichton  * the arguments.
115bfdbd10aSAlex Crichton  */
116bfdbd10aSAlex Crichton typedef wasm_trap_t *(*wasmtime_func_unchecked_callback_t)(
117*f8fee938STyler Rockwood     void *env, wasmtime_caller_t *caller, wasmtime_val_raw_t *args_and_results,
118f4b90209SAlex Crichton     size_t num_args_and_results);
119bfdbd10aSAlex Crichton 
120bfdbd10aSAlex Crichton /**
121bfdbd10aSAlex Crichton  * \brief Creates a new host function in the same manner of #wasmtime_func_new,
122bfdbd10aSAlex Crichton  *        but the function-to-call has no type information available at runtime.
123bfdbd10aSAlex Crichton  *
124bfdbd10aSAlex Crichton  * This function is very similar to #wasmtime_func_new. The difference is that
125bfdbd10aSAlex Crichton  * this version is "more unsafe" in that when the host callback is invoked there
126bfdbd10aSAlex Crichton  * is no type information and no checks that the right types of values are
127bfdbd10aSAlex Crichton  * produced. The onus is on the consumer of this API to ensure that all
128bfdbd10aSAlex Crichton  * invariants are upheld such as:
129bfdbd10aSAlex Crichton  *
130bfdbd10aSAlex Crichton  * * The host callback reads parameters correctly and interprets their types
131bfdbd10aSAlex Crichton  *   correctly.
132bfdbd10aSAlex Crichton  * * If a trap doesn't happen then all results are written to the results
133bfdbd10aSAlex Crichton  *   pointer. All results must have the correct type.
134bfdbd10aSAlex Crichton  * * Types such as `funcref` cannot cross stores.
135bfdbd10aSAlex Crichton  * * Types such as `externref` have valid reference counts.
136bfdbd10aSAlex Crichton  *
137bfdbd10aSAlex Crichton  * It's generally only recommended to use this if your application can wrap
138bfdbd10aSAlex Crichton  * this in a safe embedding. This should not be frequently used due to the
139bfdbd10aSAlex Crichton  * number of invariants that must be upheld on the wasm<->host boundary. On the
140bfdbd10aSAlex Crichton  * upside, though, this flavor of host function will be faster to call than
141bfdbd10aSAlex Crichton  * those created by #wasmtime_func_new (hence the reason for this function's
142bfdbd10aSAlex Crichton  * existence).
143bfdbd10aSAlex Crichton  */
144bfdbd10aSAlex Crichton WASM_API_EXTERN void wasmtime_func_new_unchecked(
145*f8fee938STyler Rockwood     wasmtime_context_t *store, const wasm_functype_t *type,
146*f8fee938STyler Rockwood     wasmtime_func_unchecked_callback_t callback, void *env,
147*f8fee938STyler Rockwood     void (*finalizer)(void *), wasmtime_func_t *ret);
148bfdbd10aSAlex Crichton 
149bfdbd10aSAlex Crichton /**
1507a1b7cdfSAlex Crichton  * \brief Returns the type of the function specified
1517a1b7cdfSAlex Crichton  *
1527a1b7cdfSAlex Crichton  * The returned #wasm_functype_t is owned by the caller.
1537a1b7cdfSAlex Crichton  */
154*f8fee938STyler Rockwood WASM_API_EXTERN wasm_functype_t *
155*f8fee938STyler Rockwood wasmtime_func_type(const wasmtime_context_t *store,
156*f8fee938STyler Rockwood                    const wasmtime_func_t *func);
1577a1b7cdfSAlex Crichton 
1587a1b7cdfSAlex Crichton /**
1597a1b7cdfSAlex Crichton  * \brief Call a WebAssembly function.
1607a1b7cdfSAlex Crichton  *
1617a1b7cdfSAlex Crichton  * This function is used to invoke a function defined within a store. For
1627a1b7cdfSAlex Crichton  * example this might be used after extracting a function from a
1637a1b7cdfSAlex Crichton  * #wasmtime_instance_t.
1647a1b7cdfSAlex Crichton  *
1657a1b7cdfSAlex Crichton  * \param store the store which owns `func`
1667a1b7cdfSAlex Crichton  * \param func the function to call
1677a1b7cdfSAlex Crichton  * \param args the arguments to the function call
1687a1b7cdfSAlex Crichton  * \param nargs the number of arguments provided
1697a1b7cdfSAlex Crichton  * \param results where to write the results of the function call
1707a1b7cdfSAlex Crichton  * \param nresults the number of results expected
1717a1b7cdfSAlex Crichton  * \param trap where to store a trap, if one happens.
1727a1b7cdfSAlex Crichton  *
1737a1b7cdfSAlex Crichton  * There are three possible return states from this function:
1747a1b7cdfSAlex Crichton  *
1757a1b7cdfSAlex Crichton  * 1. The returned error is non-null. This means `results`
1767a1b7cdfSAlex Crichton  *    wasn't written to and `trap` will have `NULL` written to it. This state
1777a1b7cdfSAlex Crichton  *    means that programmer error happened when calling the function, for
1787a1b7cdfSAlex Crichton  *    example when the size of the arguments/results was wrong, the types of the
1797a1b7cdfSAlex Crichton  *    arguments were wrong, or arguments may come from the wrong store.
1807a1b7cdfSAlex Crichton  * 2. The trap pointer is filled in. This means the returned error is `NULL` and
1817a1b7cdfSAlex Crichton  *    `results` was not written to. This state means that the function was
1827a1b7cdfSAlex Crichton  *    executing but hit a wasm trap while executing.
1837a1b7cdfSAlex Crichton  * 3. The error and trap returned are both `NULL` and `results` are written to.
1847a1b7cdfSAlex Crichton  *    This means that the function call succeeded and the specified results were
1857a1b7cdfSAlex Crichton  *    produced.
1867a1b7cdfSAlex Crichton  *
1877a1b7cdfSAlex Crichton  * The `trap` pointer cannot be `NULL`. The `args` and `results` pointers may be
1887a1b7cdfSAlex Crichton  * `NULL` if the corresponding length is zero.
1897a1b7cdfSAlex Crichton  *
1907a1b7cdfSAlex Crichton  * Does not take ownership of #wasmtime_val_t arguments. Gives ownership of
1917a1b7cdfSAlex Crichton  * #wasmtime_val_t results.
1927a1b7cdfSAlex Crichton  */
193*f8fee938STyler Rockwood WASM_API_EXTERN wasmtime_error_t *
194*f8fee938STyler Rockwood wasmtime_func_call(wasmtime_context_t *store, const wasmtime_func_t *func,
195*f8fee938STyler Rockwood                    const wasmtime_val_t *args, size_t nargs,
196*f8fee938STyler Rockwood                    wasmtime_val_t *results, size_t nresults,
197*f8fee938STyler Rockwood                    wasm_trap_t **trap);
1987a1b7cdfSAlex Crichton 
1997a1b7cdfSAlex Crichton /**
200bfdbd10aSAlex Crichton  * \brief Call a WebAssembly function in an "unchecked" fashion.
201bfdbd10aSAlex Crichton  *
202bfdbd10aSAlex Crichton  * This function is similar to #wasmtime_func_call except that there is no type
203bfdbd10aSAlex Crichton  * information provided with the arguments (or sizing information). Consequently
204bfdbd10aSAlex Crichton  * this is less safe to call since it's up to the caller to ensure that `args`
205bfdbd10aSAlex Crichton  * has an appropriate size and all the parameters are configured with their
206bfdbd10aSAlex Crichton  * appropriate values/types. Additionally all the results must be interpreted
207bfdbd10aSAlex Crichton  * correctly if this function returns successfully.
208bfdbd10aSAlex Crichton  *
209bfdbd10aSAlex Crichton  * Parameters must be specified starting at index 0 in the `args_and_results`
210bfdbd10aSAlex Crichton  * array. Results are written starting at index 0, which will overwrite
211bfdbd10aSAlex Crichton  * the arguments.
212bfdbd10aSAlex Crichton  *
213bfdbd10aSAlex Crichton  * Callers must ensure that various correctness variants are upheld when this
214bfdbd10aSAlex Crichton  * API is called such as:
215bfdbd10aSAlex Crichton  *
216bfdbd10aSAlex Crichton  * * The `args_and_results` pointer has enough space to hold all the parameters
217bfdbd10aSAlex Crichton  *   and all the results (but not at the same time).
218913efdf2SNick Fitzgerald  * * The `args_and_results_len` contains the length of the `args_and_results`
219913efdf2SNick Fitzgerald  *   buffer.
220bfdbd10aSAlex Crichton  * * Parameters must all be configured as if they were the correct type.
221bfdbd10aSAlex Crichton  * * Values such as `externref` and `funcref` are valid within the store being
222bfdbd10aSAlex Crichton  *   called.
223bfdbd10aSAlex Crichton  *
224bfdbd10aSAlex Crichton  * When in doubt it's much safer to call #wasmtime_func_call. This function is
225bfdbd10aSAlex Crichton  * faster than that function, but the tradeoff is that embeddings must uphold
226bfdbd10aSAlex Crichton  * more invariants rather than relying on Wasmtime to check them for you.
227bfdbd10aSAlex Crichton  */
228*f8fee938STyler Rockwood WASM_API_EXTERN wasmtime_error_t *
229*f8fee938STyler Rockwood wasmtime_func_call_unchecked(wasmtime_context_t *store,
230bfdbd10aSAlex Crichton                              const wasmtime_func_t *func,
2319c73a448SAlex Crichton                              wasmtime_val_raw_t *args_and_results,
232*f8fee938STyler Rockwood                              size_t args_and_results_len, wasm_trap_t **trap);
233bfdbd10aSAlex Crichton 
234bfdbd10aSAlex Crichton /**
2357a1b7cdfSAlex Crichton  * \brief Loads a #wasmtime_extern_t from the caller's context
2367a1b7cdfSAlex Crichton  *
2377a1b7cdfSAlex Crichton  * This function will attempt to look up the export named `name` on the caller
2387a1b7cdfSAlex Crichton  * instance provided. If it is found then the #wasmtime_extern_t for that is
2397a1b7cdfSAlex Crichton  * returned, otherwise `NULL` is returned.
2407a1b7cdfSAlex Crichton  *
2417a1b7cdfSAlex Crichton  * Note that this only works for exported memories right now for WASI
2427a1b7cdfSAlex Crichton  * compatibility.
2437a1b7cdfSAlex Crichton  *
2447a1b7cdfSAlex Crichton  * \param caller the caller object to look up the export from
2457a1b7cdfSAlex Crichton  * \param name the name that's being looked up
2467a1b7cdfSAlex Crichton  * \param name_len the byte length of `name`
2477a1b7cdfSAlex Crichton  * \param item where to store the return value
2487a1b7cdfSAlex Crichton  *
2497a1b7cdfSAlex Crichton  * Returns a nonzero value if the export was found, or 0 if the export wasn't
2507a1b7cdfSAlex Crichton  * found. If the export wasn't found then `item` isn't written to.
2517a1b7cdfSAlex Crichton  */
252*f8fee938STyler Rockwood WASM_API_EXTERN bool wasmtime_caller_export_get(wasmtime_caller_t *caller,
2537a1b7cdfSAlex Crichton                                                 const char *name,
2547a1b7cdfSAlex Crichton                                                 size_t name_len,
255*f8fee938STyler Rockwood                                                 wasmtime_extern_t *item);
2567a1b7cdfSAlex Crichton 
2577a1b7cdfSAlex Crichton /**
2587a1b7cdfSAlex Crichton  * \brief Returns the store context of the caller object.
2597a1b7cdfSAlex Crichton  */
260*f8fee938STyler Rockwood WASM_API_EXTERN wasmtime_context_t *
261*f8fee938STyler Rockwood wasmtime_caller_context(wasmtime_caller_t *caller);
2627a1b7cdfSAlex Crichton 
263bfdbd10aSAlex Crichton /**
264bfdbd10aSAlex Crichton  * \brief Converts a `raw` nonzero `funcref` value from #wasmtime_val_raw_t
265bfdbd10aSAlex Crichton  * into a #wasmtime_func_t.
266bfdbd10aSAlex Crichton  *
267bfdbd10aSAlex Crichton  * This function can be used to interpret nonzero values of the `funcref` field
268bfdbd10aSAlex Crichton  * of the #wasmtime_val_raw_t structure. It is assumed that `raw` does not have
269bfdbd10aSAlex Crichton  * a value of 0, or otherwise the program will abort.
270bfdbd10aSAlex Crichton  *
271bfdbd10aSAlex Crichton  * Note that this function is unchecked and unsafe. It's only safe to pass
272bfdbd10aSAlex Crichton  * values learned from #wasmtime_val_raw_t with the same corresponding
273bfdbd10aSAlex Crichton  * #wasmtime_context_t that they were produced from. Providing arbitrary values
274bfdbd10aSAlex Crichton  * to `raw` here or cross-context values with `context` is UB.
275bfdbd10aSAlex Crichton  */
276*f8fee938STyler Rockwood WASM_API_EXTERN void wasmtime_func_from_raw(wasmtime_context_t *context,
277*f8fee938STyler Rockwood                                             void *raw, wasmtime_func_t *ret);
278bfdbd10aSAlex Crichton 
279bfdbd10aSAlex Crichton /**
280bfdbd10aSAlex Crichton  * \brief Converts a `func`  which belongs to `context` into a `usize`
281bfdbd10aSAlex Crichton  * parameter that is suitable for insertion into a #wasmtime_val_raw_t.
282bfdbd10aSAlex Crichton  */
283*f8fee938STyler Rockwood WASM_API_EXTERN void *wasmtime_func_to_raw(wasmtime_context_t *context,
284bfdbd10aSAlex Crichton                                            const wasmtime_func_t *func);
285bfdbd10aSAlex Crichton 
2867a1b7cdfSAlex Crichton #ifdef __cplusplus
2877a1b7cdfSAlex Crichton } // extern "C"
2887a1b7cdfSAlex Crichton #endif
2897a1b7cdfSAlex Crichton 
2907a1b7cdfSAlex Crichton #endif // WASMTIME_FUNC_H
291