diff --git a/crates/c-api/include/wasmtime.h b/crates/c-api/include/wasmtime.h index d83546c4a0..eb6253b728 100644 --- a/crates/c-api/include/wasmtime.h +++ b/crates/c-api/include/wasmtime.h @@ -839,13 +839,14 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_funcref_table_grow( /** * \brief Create a new `externref` value. * - * Creates a new `externref` value wrapping the provided data. + * Creates a new `externref` value wrapping the provided data, and writes it to + * `valp`. * * This function does not take an associated finalizer to clean up the data when * the reference is reclaimed. If you need a finalizer to clean up the data, * then use #wasmtime_externref_new_with_finalizer. */ -WASM_API_EXTERN wasm_val_t wasmtime_externref_new(void *data); +WASM_API_EXTERN void wasmtime_externref_new(void *data, wasm_val_t *valp); /** * \brief A finalizer for an `externref`'s wrapped data. @@ -859,15 +860,17 @@ typedef void (*wasmtime_externref_finalizer_t)(void*); /** * \brief Create a new `externref` value with a finalizer. * - * Creates a new `externref` value wrapping the provided data. + * Creates a new `externref` value wrapping the provided data, and writes it to + * `valp`. * * When the reference is reclaimed, the wrapped data is cleaned up with the * provided finalizer. If you do not need to clean up the wrapped data, then use * #wasmtime_externref_new. */ -WASM_API_EXTERN wasm_val_t wasmtime_externref_new_with_finalizer( +WASM_API_EXTERN void wasmtime_externref_new_with_finalizer( void *data, - wasmtime_externref_finalizer_t finalizer + wasmtime_externref_finalizer_t finalizer, + wasm_val_t *valp ); /** diff --git a/crates/c-api/src/ref.rs b/crates/c-api/src/ref.rs index 5b48776ced..7696fe9fa4 100644 --- a/crates/c-api/src/ref.rs +++ b/crates/c-api/src/ref.rs @@ -1,5 +1,6 @@ use crate::wasm_val_t; use std::any::Any; +use std::mem::MaybeUninit; use std::os::raw::c_void; use std::ptr; use wasmtime::{ExternRef, Func, Val}; @@ -112,19 +113,25 @@ impl Drop for CExternRef { } #[no_mangle] -pub extern "C" fn wasmtime_externref_new(data: *mut c_void) -> wasm_val_t { - wasmtime_externref_new_with_finalizer(data, None) +pub extern "C" fn wasmtime_externref_new(data: *mut c_void, valp: &mut MaybeUninit) { + wasmtime_externref_new_with_finalizer(data, None, valp) } #[no_mangle] pub extern "C" fn wasmtime_externref_new_with_finalizer( data: *mut c_void, finalizer: Option, -) -> wasm_val_t { - wasm_val_t::from_val(Val::ExternRef(Some(ExternRef::new(CExternRef { - data, - finalizer, - })))) + valp: &mut MaybeUninit, +) { + unsafe { + ptr::write( + valp.as_mut_ptr(), + wasm_val_t::from_val(Val::ExternRef(Some(ExternRef::new(CExternRef { + data, + finalizer, + })))), + ) + } } #[no_mangle] diff --git a/examples/externref.c b/examples/externref.c index b14cc34db8..bb77516dc9 100644 --- a/examples/externref.c +++ b/examples/externref.c @@ -82,7 +82,8 @@ int main() { printf("Creating new `externref`...\n"); // Create a new `externref` value. - wasm_val_t externref = wasmtime_externref_new("Hello, World!"); + wasm_val_t externref; + wasmtime_externref_new("Hello, World!", &externref); assert(externref.kind == WASM_ANYREF); // The `externref`'s wrapped data should be the string "Hello, World!".