1 /** 2 * \file wasmtime/async.h 3 * 4 * \brief Wasmtime async functionality 5 * 6 * Async functionality in Wasmtime is well documented here: 7 * https://docs.wasmtime.dev/api/wasmtime/#async 8 * 9 * All WebAssembly executes synchronously, but an async support enables the Wasm 10 * code be executed on a separate stack, so it can be paused and resumed. There 11 * are three mechanisms for yielding control from wasm to the caller: fuel, 12 * epochs, and async host functions. 13 * 14 * When WebAssembly is executed, a `wasmtime_call_future_t` is returned. This 15 * struct represents the state of the execution and each call to 16 * `wasmtime_call_future_poll` will execute the WebAssembly code on a separate 17 * stack until the function returns or yields control back to the caller. 18 * 19 * It's expected these futures are pulled in a loop until completed, at which 20 * point the future should be deleted. Functions that return a 21 * `wasmtime_call_future_t` are special in that all parameters to that function 22 * should not be modified in any way and must be kept alive until the future is 23 * deleted. This includes concurrent calls for a single store - another function 24 * on a store should not be called while there is a `wasmtime_call_future_t` 25 * alive. 26 * 27 * As for asynchronous host calls - the reverse contract is upheld. Wasmtime 28 * will keep all parameters to the function alive and unmodified until the 29 * `wasmtime_func_async_continuation_callback_t` returns true. 30 * 31 */ 32 33 #ifndef WASMTIME_ASYNC_H 34 #define WASMTIME_ASYNC_H 35 36 #include <wasm.h> 37 #include <wasmtime/conf.h> 38 #include <wasmtime/config.h> 39 #include <wasmtime/error.h> 40 #include <wasmtime/func.h> 41 #include <wasmtime/linker.h> 42 #include <wasmtime/store.h> 43 44 #ifdef WASMTIME_FEATURE_ASYNC 45 46 #ifdef __cplusplus 47 extern "C" { 48 #endif 49 50 /** 51 * \brief Configures the size of the stacks used for asynchronous execution. 52 * 53 * This setting configures the size of the stacks that are allocated for 54 * asynchronous execution. 55 * 56 * The value cannot be less than max_wasm_stack. 57 * 58 * The amount of stack space guaranteed for host functions is async_stack_size - 59 * max_wasm_stack, so take care not to set these two values close to one 60 * another; doing so may cause host functions to overflow the stack and abort 61 * the process. 62 * 63 * By default this option is 2 MiB. 64 * 65 * For more information see the Rust documentation at 66 * https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.async_stack_size 67 */ 68 WASMTIME_CONFIG_PROP(void, async_stack_size, uint64_t) 69 70 /** 71 * \brief Configures a Store to yield execution of async WebAssembly code 72 * periodically. 73 * 74 * When a Store is configured to consume fuel with 75 * `wasmtime_config_consume_fuel` this method will configure what happens when 76 * fuel runs out. Specifically executing WebAssembly will be suspended and 77 * control will be yielded back to the caller. 78 * 79 * This is only suitable with use of a store associated with an async config 80 * because only then are futures used and yields are possible. 81 * 82 * \param context the context for the store to configure. 83 * \param interval the amount of fuel at which to yield. A value of 0 will 84 * disable yielding. 85 */ 86 WASM_API_EXTERN wasmtime_error_t * 87 wasmtime_context_fuel_async_yield_interval(wasmtime_context_t *context, 88 uint64_t interval); 89 90 /** 91 * \brief Configures epoch-deadline expiration to yield to the async caller and 92 * the update the deadline. 93 * 94 * This is only suitable with use of a store associated with an async config 95 * because only then are futures used and yields are possible. 96 * 97 * See the Rust documentation for more: 98 * https://docs.wasmtime.dev/api/wasmtime/struct.Store.html#method.epoch_deadline_async_yield_and_update 99 */ 100 WASM_API_EXTERN wasmtime_error_t * 101 wasmtime_context_epoch_deadline_async_yield_and_update( 102 wasmtime_context_t *context, uint64_t delta); 103 104 /** 105 * The callback to determine a continuation's current state. 106 * 107 * Return true if the host call has completed, otherwise false will 108 * continue to yield WebAssembly execution. 109 */ 110 typedef bool (*wasmtime_func_async_continuation_callback_t)(void *env); 111 112 /** 113 * A continuation for the current state of the host function's execution. 114 */ 115 typedef struct wasmtime_async_continuation_t { 116 /// Callback for if the async function has completed. 117 wasmtime_func_async_continuation_callback_t callback; 118 /// User-provided argument to pass to the callback. 119 void *env; 120 /// A finalizer for the user-provided *env 121 void (*finalizer)(void *); 122 } wasmtime_async_continuation_t; 123 124 /** 125 * \brief Callback signature for #wasmtime_linker_define_async_func. 126 * 127 * This is a host function that returns a continuation to be called later. 128 * 129 * All the arguments to this function will be kept alive until the continuation 130 * returns that it has errored or has completed. 131 * 132 * \param env user-provided argument passed to 133 * #wasmtime_linker_define_async_func 134 * \param caller a temporary object that can only be used during this function 135 * call. Used to acquire #wasmtime_context_t or caller's state 136 * \param args the arguments provided to this function invocation 137 * \param nargs how many arguments are provided 138 * \param results where to write the results of this function 139 * \param nresults how many results must be produced 140 * \param trap_ret if assigned a not `NULL` value then the called 141 * function will trap with the returned error. Note that ownership of 142 * trap is transferred to wasmtime. 143 * \param continuation_ret the returned continuation 144 * that determines when the async function has completed executing. 145 * 146 * Only supported for async stores. 147 * 148 * See #wasmtime_func_callback_t for more information. 149 */ 150 typedef void (*wasmtime_func_async_callback_t)( 151 void *env, wasmtime_caller_t *caller, const wasmtime_val_t *args, 152 size_t nargs, wasmtime_val_t *results, size_t nresults, 153 wasm_trap_t **trap_ret, wasmtime_async_continuation_t *continuation_ret); 154 155 /** 156 * \brief The structure representing a asynchronously running function. 157 * 158 * This structure is always owned by the caller and must be deleted using 159 * #wasmtime_call_future_delete. 160 * 161 * Functions that return this type require that the parameters to the function 162 * are unmodified until this future is destroyed. 163 */ 164 typedef struct wasmtime_call_future wasmtime_call_future_t; 165 166 /** 167 * \brief Executes WebAssembly in the function. 168 * 169 * Returns true if the function call has completed. After this function returns 170 * true, it should *not* be called again for a given future. 171 * 172 * This function returns false if execution has yielded either due to being out 173 * of fuel (see wasmtime_context_fuel_async_yield_interval), or the epoch has 174 * been incremented enough (see 175 * wasmtime_context_epoch_deadline_async_yield_and_update). The function may 176 * also return false if asynchronous host functions have been called, which then 177 * calling this function will call the continuation from the async host 178 * function. 179 * 180 * For more see the information at 181 * https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#asynchronous-wasm 182 * 183 */ 184 WASM_API_EXTERN bool wasmtime_call_future_poll(wasmtime_call_future_t *future); 185 186 /** 187 * /brief Frees the underlying memory for a future. 188 * 189 * All wasmtime_call_future_t are owned by the caller and should be deleted 190 * using this function. 191 */ 192 WASM_API_EXTERN void 193 wasmtime_call_future_delete(wasmtime_call_future_t *future); 194 195 /** 196 * \brief Invokes this function with the params given, returning the results 197 * asynchronously. 198 * 199 * This function is the same as wasmtime_func_call except that it is 200 * asynchronous. This is only compatible with stores associated with an 201 * asynchronous config. 202 * 203 * The result is a future that is owned by the caller and must be deleted via 204 * #wasmtime_call_future_delete. 205 * 206 * The `args` and `results` pointers may be `NULL` if the corresponding length 207 * is zero. The `trap_ret` and `error_ret` pointers may *not* be `NULL`. 208 * 209 * Does not take ownership of #wasmtime_val_t arguments or #wasmtime_val_t 210 * results, and all parameters to this function must be kept alive and not 211 * modified until the returned #wasmtime_call_future_t is deleted. This includes 212 * the context and store parameters. Only a single future can be alive for a 213 * given store at a single time (meaning only call this function after the 214 * previous call's future was deleted). 215 * 216 * See the header documentation for for more information. 217 * 218 * For more information see the Rust documentation at 219 * https://docs.wasmtime.dev/api/wasmtime/struct.Func.html#method.call_async 220 */ 221 WASM_API_EXTERN wasmtime_call_future_t *wasmtime_func_call_async( 222 wasmtime_context_t *context, const wasmtime_func_t *func, 223 const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *results, 224 size_t nresults, wasm_trap_t **trap_ret, wasmtime_error_t **error_ret); 225 226 /** 227 * \brief Defines a new async function in this linker. 228 * 229 * This function behaves similar to #wasmtime_linker_define_func, except it 230 * supports async callbacks. 231 * 232 * The callback `cb` will be invoked on another stack (fiber for Windows). 233 */ 234 WASM_API_EXTERN wasmtime_error_t *wasmtime_linker_define_async_func( 235 wasmtime_linker_t *linker, const char *module, size_t module_len, 236 const char *name, size_t name_len, const wasm_functype_t *ty, 237 wasmtime_func_async_callback_t cb, void *data, void (*finalizer)(void *)); 238 239 /** 240 * \brief Instantiates a #wasm_module_t with the items defined in this linker 241 * for an async store. 242 * 243 * This is the same as #wasmtime_linker_instantiate but used for async stores 244 * (which requires functions are called asynchronously). The returning 245 * #wasmtime_call_future_t must be polled using #wasmtime_call_future_poll, and 246 * is owned and must be deleted using #wasmtime_call_future_delete. 247 * 248 * The `trap_ret` and `error_ret` pointers may *not* be `NULL` and the returned 249 * memory is owned by the caller. 250 * 251 * All arguments to this function must outlive the returned future and be 252 * unmodified until the future is deleted. 253 */ 254 WASM_API_EXTERN wasmtime_call_future_t *wasmtime_linker_instantiate_async( 255 const wasmtime_linker_t *linker, wasmtime_context_t *store, 256 const wasmtime_module_t *module, wasmtime_instance_t *instance, 257 wasm_trap_t **trap_ret, wasmtime_error_t **error_ret); 258 259 /** 260 * \brief Instantiates instance within the given store. 261 * 262 * This will also run the function's startup function, if there is one. 263 * 264 * For more information on async instantiation see 265 * #wasmtime_linker_instantiate_async. 266 * 267 * \param instance_pre the pre-initialized instance 268 * \param store the store in which to create the instance 269 * \param instance where to store the returned instance 270 * \param trap_ret where to store the returned trap 271 * \param error_ret where to store the returned trap 272 * 273 * The `trap_ret` and `error_ret` pointers may *not* be `NULL` and the returned 274 * memory is owned by the caller. 275 * 276 * All arguments to this function must outlive the returned future and be 277 * unmodified until the future is deleted. 278 */ 279 WASM_API_EXTERN wasmtime_call_future_t *wasmtime_instance_pre_instantiate_async( 280 const wasmtime_instance_pre_t *instance_pre, wasmtime_context_t *store, 281 wasmtime_instance_t *instance, wasm_trap_t **trap_ret, 282 wasmtime_error_t **error_ret); 283 284 /** 285 * A callback to get the top of the stack address and the length of the stack, 286 * excluding guard pages. 287 * 288 * For more information about the parameters see the Rust documentation at 289 * https://docs.wasmtime.dev/api/wasmtime/trait.StackMemory.html 290 */ 291 typedef uint8_t *(*wasmtime_stack_memory_get_callback_t)(void *env, 292 size_t *out_len); 293 294 /** 295 * A Stack instance created from a #wasmtime_new_stack_memory_callback_t. 296 * 297 * For more information see the Rust documentation at 298 * https://docs.wasmtime.dev/api/wasmtime/trait.StackMemory.html 299 */ 300 typedef struct { 301 /// User provided value to be passed to get_memory and grow_memory 302 void *env; 303 /// Callback to get the memory and size of this LinearMemory 304 wasmtime_stack_memory_get_callback_t get_stack_memory; 305 /// An optional finalizer for env 306 void (*finalizer)(void *); 307 } wasmtime_stack_memory_t; 308 309 /** 310 * A callback to create a new StackMemory from the specified parameters. 311 * 312 * The result should be written to `stack_ret` and wasmtime will own the values 313 * written into that struct. 314 * 315 * This callback must be thread-safe. 316 * 317 * For more information about the parameters see the Rust documentation at 318 * https://docs.wasmtime.dev/api/wasmtime/trait.StackCreator.html#tymethod.new_stack 319 */ 320 typedef wasmtime_error_t *(*wasmtime_new_stack_memory_callback_t)( 321 void *env, size_t size, bool zeroed, wasmtime_stack_memory_t *stack_ret); 322 323 /** 324 * A representation of custom stack creator. 325 * 326 * For more information see the Rust documentation at 327 * https://docs.wasmtime.dev/api/wasmtime/trait.StackCreator.html 328 */ 329 typedef struct { 330 /// User provided value to be passed to new_stack 331 void *env; 332 /// The callback to create a new stack, must be thread safe 333 wasmtime_new_stack_memory_callback_t new_stack; 334 /// An optional finalizer for env. 335 void (*finalizer)(void *); 336 } wasmtime_stack_creator_t; 337 338 /** 339 * Sets a custom stack creator. 340 * 341 * Custom memory creators are used when creating creating async instance stacks 342 * for the on-demand instance allocation strategy. 343 * 344 * The config does **not** take ownership of the #wasmtime_stack_creator_t 345 * passed in, but instead copies all the values in the struct. 346 * 347 * For more information see the Rust documentation at 348 * https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.with_host_stack 349 */ 350 WASM_API_EXTERN void 351 wasmtime_config_host_stack_creator_set(wasm_config_t *, 352 wasmtime_stack_creator_t *); 353 354 #ifdef __cplusplus 355 } // extern "C" 356 #endif 357 358 #endif // WASMTIME_FEATURE_ASYNC 359 360 #endif // WASMTIME_ASYNC_H 361