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