diff --git a/crates/c-api/include/wasmtime/config.h b/crates/c-api/include/wasmtime/config.h index a8f07feb01cf..996347d5c282 100644 --- a/crates/c-api/include/wasmtime/config.h +++ b/crates/c-api/include/wasmtime/config.h @@ -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 @@ -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. @@ -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` */ @@ -300,7 +303,8 @@ 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 @@ -308,7 +312,8 @@ WASMTIME_CONFIG_PROP(void, dynamic_memory_guard_size, uint64_t) 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. * @@ -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 @@ -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. @@ -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. @@ -365,78 +372,93 @@ 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); /** - * A callback to create a new LinearMemory from the specified parameters. + * Return the data from a LinearMemory instance created from a + * #wasmtime_new_memory_t callback. * - * The result should be written to `memory_ret` and optionally a finalizer for the returned memory - * can be returned in the finalizer pointer. + * 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 the parameters see the Rust documentation at - * https://docs.wasmtime.dev/api/wasmtime/trait.MemoryCreator.html#tymethod.new_memory + * For more information about see the Rust documentation at + * https://docs.wasmtime.dev/api/wasmtime/trait.LinearMemory.html */ -typedef wasmtime_error_t *(*wasmtime_new_memory_callback_t)( - wasm_memorytype_t *ty, - size_t minimum, - size_t maximum, - size_t reserved_size_in_bytes, - size_t guard_size_in_bytes, - void **memory_ret, - void (**finalizer)(void*)); +typedef uint8_t *(*wasmtime_memory_get_callback_t)(void *env, size_t *byte_size, + size_t *maximum_byte_size); /** - * Return the data from a LinearMemory instance created from a #wasmtime_new_memory_t callback. - * - * The size in bytes as well as the maximum number of bytes that can be allocated should be - * returned as well. + * 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); + +/** + * A LinearMemory instance created from a #wasmtime_new_memory_callback_t. + * + * For more information see the Rust documentation at * https://docs.wasmtime.dev/api/wasmtime/trait.LinearMemory.html */ -typedef void *(*wasmtime_memory_get_callback_t)( - void *memory_ptr, - size_t *byte_size, - size_t *maximum_byte_size); +typedef struct { + void *env; + wasmtime_memory_get_callback_t get_memory; + wasmtime_memory_grow_callback_t grow_memory; + void (*finalizer)(void *); +} wasmtime_linear_memory_t; /** - * Grow the memory to the `new_size` in bytes. + * 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. + * + * This callback must be thread-safe. * * For more information about the parameters see the Rust documentation at - * https://docs.wasmtime.dev/api/wasmtime/trait.LinearMemory.html#tymethod.grow_to + * https://docs.wasmtime.dev/api/wasmtime/trait.MemoryCreator.html#tymethod.new_memory */ -typedef wasmtime_error_t *(*wasmtime_memory_grow_callback_t)( - void *memory_ptr, - size_t new_size); +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, + 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 { + void *env; wasmtime_new_memory_callback_t new_memory; - wasmtime_memory_get_callback_t get_memory; - wasmtime_memory_grow_callback_t grow_memory; + 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. * * 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 - diff --git a/crates/c-api/src/config.rs b/crates/c-api/src/config.rs index f27314585913..76fe4546b69b 100644 --- a/crates/c-api/src/config.rs +++ b/crates/c-api/src/config.rs @@ -3,9 +3,9 @@ #![cfg_attr(not(feature = "cache"), allow(unused_imports))] use crate::{handle_result, wasm_memorytype_t, wasmtime_error_t}; +use std::mem::MaybeUninit; use std::ops::Range; use std::os::raw::c_char; -use std::ptr; use std::{ffi::CStr, sync::Arc}; use wasmtime::{ Config, LinearMemory, MemoryCreator, OptLevel, ProfilingStrategy, Result, Strategy, @@ -260,34 +260,33 @@ pub unsafe extern "C" fn wasmtime_config_cranelift_flag_set( c.config.cranelift_flag_set(flag, value); } -pub type wasmtime_new_memory_callback_t = extern "C" fn( - ty: &wasm_memorytype_t, - minimum: usize, - maximum: usize, - reserved_size_in_bytes: usize, - guard_size_in_bytes: usize, - memory_ret: &mut *mut std::ffi::c_void, - finalizer_ret: &mut Option, -) -> Option>; - pub type wasmtime_memory_get_callback_t = extern "C" fn( - memory_ptr: *mut std::ffi::c_void, + env: *mut std::ffi::c_void, byte_size: &mut usize, maximum_byte_size: &mut usize, ) -> *mut u8; -pub type wasmtime_memory_grow_callback_t = extern "C" fn( - memory_ptr: *mut std::ffi::c_void, - new_size: usize, -) -> Option>; +pub type wasmtime_memory_grow_callback_t = + extern "C" fn(env: *mut std::ffi::c_void, new_size: usize) -> Option>; #[repr(C)] -pub struct wasmtime_memory_creator_t { - new_memory: wasmtime_new_memory_callback_t, +pub struct wasmtime_linear_memory_t { + env: *mut std::ffi::c_void, get_memory: wasmtime_memory_get_callback_t, grow_memory: wasmtime_memory_grow_callback_t, + finalizer: Option, } +pub type wasmtime_new_memory_callback_t = extern "C" fn( + env: *mut std::ffi::c_void, + ty: &wasm_memorytype_t, + minimum: usize, + maximum: usize, + reserved_size_in_bytes: usize, + guard_size_in_bytes: usize, + memory_ret: *mut wasmtime_linear_memory_t, +) -> Option>; + struct CHostLinearMemory { foreign: crate::ForeignData, get_memory: wasmtime_memory_get_callback_t, @@ -340,8 +339,16 @@ unsafe impl LinearMemory for CHostLinearMemory { } } +#[repr(C)] +pub struct wasmtime_memory_creator_t { + env: *mut std::ffi::c_void, + new_memory: wasmtime_new_memory_callback_t, + finalizer: Option, +} + struct CHostMemoryCreator { - creator: Box, + foreign: crate::ForeignData, + new_memory: wasmtime_new_memory_callback_t, } unsafe impl Send for CHostMemoryCreator {} unsafe impl Sync for CHostMemoryCreator {} @@ -355,28 +362,28 @@ unsafe impl MemoryCreator for CHostMemoryCreator { reserved_size_in_bytes: Option, guard_size_in_bytes: usize, ) -> Result, String> { - let mut memory = ptr::null_mut(); - let mut finalizer = None; - let cb = self.creator.new_memory; + let mut memory = MaybeUninit::uninit(); + let cb = self.new_memory; let error = cb( + self.foreign.data, &wasm_memorytype_t::new(ty), minimum, maximum.unwrap_or(usize::MAX), reserved_size_in_bytes.unwrap_or(0), guard_size_in_bytes, - &mut memory, - &mut finalizer, + memory.as_mut_ptr(), ); match error { None => { + let memory = unsafe { memory.assume_init() }; let foreign = crate::ForeignData { - data: memory, - finalizer, + data: memory.env, + finalizer: memory.finalizer, }; Ok(Box::new(CHostLinearMemory { foreign, - get_memory: self.creator.get_memory, - grow_memory: self.creator.grow_memory, + get_memory: memory.get_memory, + grow_memory: memory.grow_memory, })) } Some(err) => { @@ -390,8 +397,13 @@ unsafe impl MemoryCreator for CHostMemoryCreator { #[no_mangle] pub unsafe extern "C" fn wasmtime_config_host_memory_creator_set( c: &mut wasm_config_t, - creator: Box, + creator: &wasmtime_memory_creator_t, ) { - c.config - .with_host_memory(Arc::new(CHostMemoryCreator { creator })); + c.config.with_host_memory(Arc::new(CHostMemoryCreator { + foreign: crate::ForeignData { + data: creator.env, + finalizer: creator.finalizer, + }, + new_memory: creator.new_memory, + })); }