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