Skip to content

Commit

Permalink
Introduce StackMemory and StackMemoryCreator
Browse files Browse the repository at this point in the history
This allows custom implementations of stack memory to be plugged into
the async functionality for wasmtime. Currently, stacks are always
mmapped, and this custom allocator allows embedders to use any memory
they would like.

The new APIs are also exposed in the C api.

This has no effect on windows, as our hands are tied with fibers there.

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
  • Loading branch information
rockwotj committed Oct 10, 2023
1 parent f4be360 commit 0c25adc
Show file tree
Hide file tree
Showing 14 changed files with 456 additions and 91 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 74 additions & 0 deletions crates/c-api/include/wasmtime/async.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,80 @@ WASM_API_EXTERN wasmtime_call_future_t *wasmtime_instance_pre_instantiate_async(
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_memory_creator_t*);


#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
86 changes: 44 additions & 42 deletions crates/c-api/include/wasmtime/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ enum wasmtime_profiling_strategy_enum { // ProfilingStrategy
WASMTIME_PROFILING_STRATEGY_PERFMAP,
};

#define WASMTIME_CONFIG_PROP(ret, name, ty) \
WASM_API_EXTERN ret wasmtime_config_##name##_set(wasm_config_t*, ty);
#define WASMTIME_CONFIG_PROP(ret, name, ty) \
WASM_API_EXTERN ret wasmtime_config_##name##_set(wasm_config_t *, ty);

/**
* \brief Configures whether DWARF debug information is constructed at runtime
Expand Down Expand Up @@ -221,7 +221,8 @@ WASMTIME_CONFIG_PROP(void, wasm_memory64, bool)
WASMTIME_CONFIG_PROP(void, strategy, wasmtime_strategy_t)

/**
* \brief Configure whether wasmtime should compile a module using multiple threads.
* \brief Configure whether wasmtime should compile a module using multiple
* threads.
*
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.parallel_compilation.
Expand All @@ -239,13 +240,15 @@ WASMTIME_CONFIG_PROP(void, parallel_compilation, bool)
WASMTIME_CONFIG_PROP(void, cranelift_debug_verifier, bool)

/**
* \brief Configures whether Cranelift should perform a NaN-canonicalization pass.
* \brief Configures whether Cranelift should perform a NaN-canonicalization
* pass.
*
* When Cranelift is used as a code generation backend this will configure
* it to replace NaNs with a single canonical value. This is useful for users
* requiring entirely deterministic WebAssembly computation.
*
* This is not required by the WebAssembly spec, so it is not enabled by default.
* This is not required by the WebAssembly spec, so it is not enabled by
* default.
*
* The default value for this is `false`
*/
Expand Down Expand Up @@ -300,15 +303,17 @@ WASMTIME_CONFIG_PROP(void, static_memory_guard_size, uint64_t)
WASMTIME_CONFIG_PROP(void, dynamic_memory_guard_size, uint64_t)

/**
* \brief Configures the size, in bytes, of the extra virtual memory space reserved after a “dynamic” memory for growing into.
* \brief Configures the size, in bytes, of the extra virtual memory space
* reserved after a “dynamic” memory for growing into.
*
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.dynamic_memory_reserved_for_growth
*/
WASMTIME_CONFIG_PROP(void, dynamic_memory_reserved_for_growth, uint64_t)

/**
* \brief Configures whether to generate native unwind information (e.g. .eh_frame on Linux).
* \brief Configures whether to generate native unwind information (e.g.
* .eh_frame on Linux).
*
* This option defaults to true.
*
Expand All @@ -329,7 +334,8 @@ WASMTIME_CONFIG_PROP(void, native_unwind_info, bool)
* An error is returned if the cache configuration could not be loaded or if the
* cache could not be enabled.
*/
WASM_API_EXTERN wasmtime_error_t* wasmtime_config_cache_config_load(wasm_config_t*, const char*);
WASM_API_EXTERN wasmtime_error_t *
wasmtime_config_cache_config_load(wasm_config_t *, const char *);

/**
* \brief Configures the target triple that this configuration will produce
Expand All @@ -343,7 +349,7 @@ WASM_API_EXTERN wasmtime_error_t* wasmtime_config_cache_config_load(wasm_config_
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.config
*/
WASMTIME_CONFIG_PROP(wasmtime_error_t*, target, const char*)
WASMTIME_CONFIG_PROP(wasmtime_error_t *, target, const char *)

/**
* \brief Enables a target-specific flag in Cranelift.
Expand All @@ -354,7 +360,8 @@ WASMTIME_CONFIG_PROP(wasmtime_error_t*, target, const char*)
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cranelift_flag_enable
*/
WASM_API_EXTERN void wasmtime_config_cranelift_flag_enable(wasm_config_t*, const char*);
WASM_API_EXTERN void wasmtime_config_cranelift_flag_enable(wasm_config_t *,
const char *);

/**
* \brief Sets a target-specific flag in Cranelift to the specified value.
Expand All @@ -365,32 +372,30 @@ WASM_API_EXTERN void wasmtime_config_cranelift_flag_enable(wasm_config_t*, const
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cranelift_flag_set
*/
WASM_API_EXTERN void wasmtime_config_cranelift_flag_set(wasm_config_t*, const char *key, const char *value);

WASM_API_EXTERN void wasmtime_config_cranelift_flag_set(wasm_config_t *,
const char *key,
const char *value);

/**
* Return the data from a LinearMemory instance.
*
* The size in bytes as well as the maximum number of bytes that can be allocated should be
* returned as well.
* The size in bytes as well as the maximum number of bytes that can be
* allocated should be returned as well.
*
* For more information about see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/trait.LinearMemory.html
*/
typedef uint8_t *(*wasmtime_memory_get_callback_t)(
void *env,
size_t *byte_size,
size_t *maximum_byte_size);
typedef uint8_t *(*wasmtime_memory_get_callback_t)(void *env, size_t *byte_size,
size_t *maximum_byte_size);

/**
* Grow the memory to the `new_size` in bytes.
*
* For more information about the parameters see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/trait.LinearMemory.html#tymethod.grow_to
*/
typedef wasmtime_error_t *(*wasmtime_memory_grow_callback_t)(
void *env,
size_t new_size);
typedef wasmtime_error_t *(*wasmtime_memory_grow_callback_t)(void *env,
size_t new_size);

/**
* A LinearMemory instance created from a #wasmtime_new_memory_callback_t.
Expand All @@ -406,63 +411,60 @@ typedef struct {
/// Callback to request growing the memory
wasmtime_memory_grow_callback_t grow_memory;
/// An optional finalizer for env
void (*finalizer)(void*);
void (*finalizer)(void *);
} wasmtime_linear_memory_t;

/**
* A callback to create a new LinearMemory from the specified parameters.
*
* The result should be written to `memory_ret` and wasmtime will own the values written
* into that struct.
* The result should be written to `memory_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.MemoryCreator.html#tymethod.new_memory
*/
typedef wasmtime_error_t *(*wasmtime_new_memory_callback_t)(
void *env,
const wasm_memorytype_t *ty,
size_t minimum,
size_t maximum,
size_t reserved_size_in_bytes,
size_t guard_size_in_bytes,
void *env, const wasm_memorytype_t *ty, size_t minimum, size_t maximum,
size_t reserved_size_in_bytes, size_t guard_size_in_bytes,
wasmtime_linear_memory_t *memory_ret);

/**
* A representation of custom memory creator and methods for an instance of LinearMemory.
* A representation of custom memory creator and methods for an instance of
* LinearMemory.
*
* For more information see the Rust documentation at
* https://docs.wasmtime.dev/api/wasmtime/trait.MemoryCreator.html
*/
typedef struct {
/// User provided value to be passed to new_memory
void* env;
void *env;
/// The callback to create new memory, must be thread safe
wasmtime_new_memory_callback_t new_memory;
/// An optional finalizer for env.
void (*finalizer)(void*);
void (*finalizer)(void *);
} wasmtime_memory_creator_t;

/**
* Sets a custom memory creator.
*
* Custom memory creators are used when creating host Memory objects or when creating instance
* linear memories for the on-demand instance allocation strategy.
* Custom memory creators are used when creating host Memory objects or when
* creating instance linear memories for the on-demand instance allocation
* strategy.
*
* The config does **not** take ownership of the #wasmtime_memory_creator_t passed in, but
* instead copies all the values in the struct.
* The config does **not** take ownership of the #wasmtime_memory_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_memory
*/
WASM_API_EXTERN void wasmtime_config_host_memory_creator_set(
wasm_config_t*,
wasmtime_memory_creator_t*);
WASM_API_EXTERN void
wasmtime_config_host_memory_creator_set(wasm_config_t *,
wasmtime_memory_creator_t *);

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

#endif // WASMTIME_CONFIG_H

Loading

0 comments on commit 0c25adc

Please sign in to comment.