File: async.h

package info (click to toggle)
rust-wasmtime 26.0.1%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 48,492 kB
  • sloc: ansic: 4,003; sh: 561; javascript: 542; cpp: 254; asm: 175; ml: 96; makefile: 55
file content (374 lines) | stat: -rw-r--r-- 14,534 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/**
 * \file wasmtime/async.h
 *
 * \brief Wasmtime async functionality
 *
 * Async functionality in Wasmtime is well documented here:
 * https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.async_support
 *
 * All WebAssembly executes synchronously, but an async support enables the Wasm
 * code be executed on a separate stack, so it can be paused and resumed. There
 * are three mechanisms for yielding control from wasm to the caller: fuel,
 * epochs, and async host functions.
 *
 * When WebAssembly is executed, a `wasmtime_call_future_t` is returned. This
 * struct represents the state of the execution and each call to
 * `wasmtime_call_future_poll` will execute the WebAssembly code on a separate
 * stack until the function returns or yields control back to the caller.
 *
 * It's expected these futures are pulled in a loop until completed, at which
 * point the future should be deleted. Functions that return a
 * `wasmtime_call_future_t` are special in that all parameters to that function
 * should not be modified in any way and must be kept alive until the future is
 * deleted. This includes concurrent calls for a single store - another function
 * on a store should not be called while there is a `wasmtime_call_future_t`
 * alive.
 *
 * As for asynchronous host calls - the reverse contract is upheld. Wasmtime
 * will keep all parameters to the function alive and unmodified until the
 * `wasmtime_func_async_continuation_callback_t` returns true.
 *
 */

#ifndef WASMTIME_ASYNC_H
#define WASMTIME_ASYNC_H

#include <wasm.h>
#include <wasmtime/conf.h>
#include <wasmtime/config.h>
#include <wasmtime/error.h>
#include <wasmtime/func.h>
#include <wasmtime/linker.h>
#include <wasmtime/store.h>

#ifdef WASMTIME_FEATURE_ASYNC

#ifdef __cplusplus
extern "C" {
#endif

/**
 * \brief Whether or not to enable support for asynchronous functions in
 * Wasmtime.
 *
 * When enabled, the config can optionally define host functions with async.
 * Instances created and functions called with this Config must be called
 * through their asynchronous APIs, however. For example using
 * wasmtime_func_call will panic when used with this config.
 *
 * For more information see the Rust documentation at
 * https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.async_support
 */
WASMTIME_CONFIG_PROP(void, async_support, bool)

/**
 * \brief Configures the size of the stacks used for asynchronous execution.
 *
 * This setting configures the size of the stacks that are allocated for
 * asynchronous execution.
 *
 * The value cannot be less than max_wasm_stack.
 *
 * The amount of stack space guaranteed for host functions is async_stack_size -
 * max_wasm_stack, so take care not to set these two values close to one
 * another; doing so may cause host functions to overflow the stack and abort
 * the process.
 *
 * By default this option is 2 MiB.
 *
 * For more information see the Rust documentation at
 * https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.async_stack_size
 */
WASMTIME_CONFIG_PROP(void, async_stack_size, uint64_t)

/**
 * \brief Configures a Store to yield execution of async WebAssembly code
 * periodically.
 *
 * When a Store is configured to consume fuel with
 * `wasmtime_config_consume_fuel` this method will configure what happens when
 * fuel runs out. Specifically executing WebAssembly will be suspended and
 * control will be yielded back to the caller.
 *
 * This is only suitable with use of a store associated with an async config
 * because only then are futures used and yields are possible.
 *
 * \param context the context for the store to configure.
 * \param interval the amount of fuel at which to yield. A value of 0 will
 *        disable yielding.
 */
WASM_API_EXTERN wasmtime_error_t *
wasmtime_context_fuel_async_yield_interval(wasmtime_context_t *context,
                                           uint64_t interval);

/**
 * \brief Configures epoch-deadline expiration to yield to the async caller and
 * the update the deadline.
 *
 * This is only suitable with use of a store associated with an async config
 * because only then are futures used and yields are possible.
 *
 * See the Rust documentation for more:
 * https://docs.wasmtime.dev/api/wasmtime/struct.Store.html#method.epoch_deadline_async_yield_and_update
 */
WASM_API_EXTERN wasmtime_error_t *
wasmtime_context_epoch_deadline_async_yield_and_update(
    wasmtime_context_t *context, uint64_t delta);

/**
 * The callback to determine a continuation's current state.
 *
 * Return true if the host call has completed, otherwise false will
 * continue to yield WebAssembly execution.
 */
typedef bool (*wasmtime_func_async_continuation_callback_t)(void *env);

/**
 * A continuation for the current state of the host function's execution.
 */
typedef struct wasmtime_async_continuation_t {
  /// Callback for if the async function has completed.
  wasmtime_func_async_continuation_callback_t callback;
  /// User-provided argument to pass to the callback.
  void *env;
  /// A finalizer for the user-provided *env
  void (*finalizer)(void *);
} wasmtime_async_continuation_t;

/**
 * \brief Callback signature for #wasmtime_linker_define_async_func.
 *
 * This is a host function that returns a continuation to be called later.
 *
 * All the arguments to this function will be kept alive until the continuation
 * returns that it has errored or has completed.
 *
 * \param env user-provided argument passed to
 *        #wasmtime_linker_define_async_func
 * \param caller a temporary object that can only be used during this function
 *        call. Used to acquire #wasmtime_context_t or caller's state
 * \param args the arguments provided to this function invocation
 * \param nargs how many arguments are provided
 * \param results where to write the results of this function
 * \param nresults how many results must be produced
 * \param trap_ret if assigned a not `NULL` value then the called
 *        function will trap with the returned error. Note that ownership of
 *        trap is transferred to wasmtime.
 * \param continuation_ret the returned continuation
 *        that determines when the async function has completed executing.
 *
 * Only supported for async stores.
 *
 * See #wasmtime_func_callback_t for more information.
 */
typedef void (*wasmtime_func_async_callback_t)(
    void *env, wasmtime_caller_t *caller, const wasmtime_val_t *args,
    size_t nargs, wasmtime_val_t *results, size_t nresults,
    wasm_trap_t **trap_ret, wasmtime_async_continuation_t *continuation_ret);

/**
 * \brief The structure representing a asynchronously running function.
 *
 * This structure is always owned by the caller and must be deleted using
 * #wasmtime_call_future_delete.
 *
 * Functions that return this type require that the parameters to the function
 * are unmodified until this future is destroyed.
 */
typedef struct wasmtime_call_future wasmtime_call_future_t;

/**
 * \brief Executes WebAssembly in the function.
 *
 * Returns true if the function call has completed. After this function returns
 * true, it should *not* be called again for a given future.
 *
 * This function returns false if execution has yielded either due to being out
 * of fuel (see wasmtime_context_fuel_async_yield_interval), or the epoch has
 * been incremented enough (see
 * wasmtime_context_epoch_deadline_async_yield_and_update). The function may
 * also return false if asynchronous host functions have been called, which then
 * calling this  function will call the continuation from the async host
 * function.
 *
 * For more see the information at
 * https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#asynchronous-wasm
 *
 */
WASM_API_EXTERN bool wasmtime_call_future_poll(wasmtime_call_future_t *future);

/**
 * /brief Frees the underlying memory for a future.
 *
 * All wasmtime_call_future_t are owned by the caller and should be deleted
 * using this function.
 */
WASM_API_EXTERN void
wasmtime_call_future_delete(wasmtime_call_future_t *future);

/**
 * \brief Invokes this function with the params given, returning the results
 * asynchronously.
 *
 * This function is the same as wasmtime_func_call except that it is
 * asynchronous. This is only compatible with stores associated with an
 * asynchronous config.
 *
 * The result is a future that is owned by the caller and must be deleted via
 * #wasmtime_call_future_delete.
 *
 * The `args` and `results` pointers may be `NULL` if the corresponding length
 * is zero. The `trap_ret` and `error_ret` pointers may *not* be `NULL`.
 *
 * Does not take ownership of #wasmtime_val_t arguments or #wasmtime_val_t
 * results, and all parameters to this function must be kept alive and not
 * modified until the returned #wasmtime_call_future_t is deleted. This includes
 * the context and store parameters. Only a single future can be alive for a
 * given store at a single time (meaning only call this function after the
 * previous call's future was deleted).
 *
 * See the header documentation for for more information.
 *
 * For more information see the Rust documentation at
 * https://docs.wasmtime.dev/api/wasmtime/struct.Func.html#method.call_async
 */
WASM_API_EXTERN wasmtime_call_future_t *wasmtime_func_call_async(
    wasmtime_context_t *context, const wasmtime_func_t *func,
    const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *results,
    size_t nresults, wasm_trap_t **trap_ret, wasmtime_error_t **error_ret);

/**
 * \brief Defines a new async function in this linker.
 *
 * This function behaves similar to #wasmtime_linker_define_func, except it
 * supports async callbacks.
 *
 * The callback `cb` will be invoked on another stack (fiber for Windows).
 */
WASM_API_EXTERN wasmtime_error_t *wasmtime_linker_define_async_func(
    wasmtime_linker_t *linker, const char *module, size_t module_len,
    const char *name, size_t name_len, const wasm_functype_t *ty,
    wasmtime_func_async_callback_t cb, void *data, void (*finalizer)(void *));

/**
 * \brief Instantiates a #wasm_module_t with the items defined in this linker
 * for an async store.
 *
 * This is the same as #wasmtime_linker_instantiate but used for async stores
 * (which requires functions are called asynchronously). The returning
 * #wasmtime_call_future_t must be polled using #wasmtime_call_future_poll, and
 * is owned and must be deleted using #wasmtime_call_future_delete.
 *
 * The `trap_ret` and `error_ret` pointers may *not* be `NULL` and the returned
 * memory is owned by the caller.
 *
 * All arguments to this function must outlive the returned future and be
 * unmodified until the future is deleted.
 */
WASM_API_EXTERN wasmtime_call_future_t *wasmtime_linker_instantiate_async(
    const wasmtime_linker_t *linker, wasmtime_context_t *store,
    const wasmtime_module_t *module, wasmtime_instance_t *instance,
    wasm_trap_t **trap_ret, wasmtime_error_t **error_ret);

/**
 * \brief Instantiates instance within the given store.
 *
 * This will also run the function's startup function, if there is one.
 *
 * For more information on async instantiation see
 * #wasmtime_linker_instantiate_async.
 *
 * \param instance_pre the pre-initialized instance
 * \param store the store in which to create the instance
 * \param instance where to store the returned instance
 * \param trap_ret where to store the returned trap
 * \param error_ret where to store the returned trap
 *
 * The `trap_ret` and `error_ret` pointers may *not* be `NULL` and the returned
 * memory is owned by the caller.
 *
 * All arguments to this function must outlive the returned future and be
 * unmodified until the future is deleted.
 */
WASM_API_EXTERN wasmtime_call_future_t *wasmtime_instance_pre_instantiate_async(
    const wasmtime_instance_pre_t *instance_pre, wasmtime_context_t *store,
    wasmtime_instance_t *instance, wasm_trap_t **trap_ret,
    wasmtime_error_t **error_ret);

/**
 * A callback to get the top of the stack address and the length of the stack,
 * excluding guard pages.
 *
 * For more information about the parameters see the Rust documentation at
 * https://docs.wasmtime.dev/api/wasmtime/trait.StackMemory.html
 */
typedef uint8_t *(*wasmtime_stack_memory_get_callback_t)(void *env,
                                                         size_t *out_len);

/**
 * A Stack instance created from a #wasmtime_new_stack_memory_callback_t.
 *
 * For more information see the Rust documentation at
 * https://docs.wasmtime.dev/api/wasmtime/trait.StackMemory.html
 */
typedef struct {
  /// User provided value to be passed to get_memory and grow_memory
  void *env;
  /// Callback to get the memory and size of this LinearMemory
  wasmtime_stack_memory_get_callback_t get_stack_memory;
  /// An optional finalizer for env
  void (*finalizer)(void *);
} wasmtime_stack_memory_t;

/**
 * A callback to create a new StackMemory from the specified parameters.
 *
 * The result should be written to `stack_ret` and wasmtime will own the values
 * written into that struct.
 *
 * This callback must be thread-safe.
 *
 * For more information about the parameters see the Rust documentation at
 * https://docs.wasmtime.dev/api/wasmtime/trait.StackCreator.html#tymethod.new_stack
 */
typedef wasmtime_error_t *(*wasmtime_new_stack_memory_callback_t)(
    void *env, size_t size, wasmtime_stack_memory_t *stack_ret);

/**
 * A representation of custom stack creator.
 *
 * For more information see the Rust documentation at
 * https://docs.wasmtime.dev/api/wasmtime/trait.StackCreator.html
 */
typedef struct {
  /// User provided value to be passed to new_stack
  void *env;
  /// The callback to create a new stack, must be thread safe
  wasmtime_new_stack_memory_callback_t new_stack;
  /// An optional finalizer for env.
  void (*finalizer)(void *);
} wasmtime_stack_creator_t;

/**
 * Sets a custom stack creator.
 *
 * Custom memory creators are used when creating creating async instance stacks
 * for the on-demand instance allocation strategy.
 *
 * The config does **not** take ownership of the #wasmtime_stack_creator_t
 * passed in, but instead copies all the values in the struct.
 *
 * For more information see the Rust documentation at
 * https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.with_host_stack
 */
WASM_API_EXTERN void
wasmtime_config_host_stack_creator_set(wasm_config_t *,
                                       wasmtime_stack_creator_t *);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // WASMTIME_FEATURE_ASYNC

#endif // WASMTIME_ASYNC_H