diff --git a/crates/c-api/src/func.rs b/crates/c-api/src/func.rs index 75ba6a6317..fe494dbbcb 100644 --- a/crates/c-api/src/func.rs +++ b/crates/c-api/src/func.rs @@ -220,12 +220,7 @@ fn _wasmtime_func_call( match result { Ok(Ok(out)) => { for (slot, val) in results.iter_mut().zip(out.into_vec().into_iter()) { - unsafe { - // NB: The results array is likely uninitialized memory, so - // use `ptr::write` rather than assignment (which tries to - // run destructors). - ptr::write(slot.as_mut_ptr(), wasm_val_t::from_val(val)); - } + crate::initialize(slot, wasm_val_t::from_val(val)); } None } diff --git a/crates/c-api/src/global.rs b/crates/c-api/src/global.rs index efe8b32f1b..8a370ee433 100644 --- a/crates/c-api/src/global.rs +++ b/crates/c-api/src/global.rs @@ -74,9 +74,7 @@ pub extern "C" fn wasm_global_type(g: &wasm_global_t) -> Box #[no_mangle] pub extern "C" fn wasm_global_get(g: &wasm_global_t, out: &mut MaybeUninit) { - unsafe { - ptr::write(out.as_mut_ptr(), wasm_val_t::from_val(g.global().get())); - } + crate::initialize(out, wasm_val_t::from_val(g.global().get())); } #[no_mangle] diff --git a/crates/c-api/src/lib.rs b/crates/c-api/src/lib.rs index d820882c38..9f716fb6eb 100644 --- a/crates/c-api/src/lib.rs +++ b/crates/c-api/src/lib.rs @@ -62,3 +62,14 @@ pub struct wasm_foreign_t { pub struct wasm_shared_module_t { _unused: [u8; 0], } + +/// Initialize a `MaybeUninit` +/// +/// TODO: Replace calls to this function with +/// https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.write +/// once it is stable. +pub(crate) fn initialize(dst: &mut std::mem::MaybeUninit, val: T) { + unsafe { + std::ptr::write(dst.as_mut_ptr(), val); + } +} diff --git a/crates/c-api/src/ref.rs b/crates/c-api/src/ref.rs index 7696fe9fa4..a6ffef2304 100644 --- a/crates/c-api/src/ref.rs +++ b/crates/c-api/src/ref.rs @@ -123,24 +123,23 @@ pub extern "C" fn wasmtime_externref_new_with_finalizer( finalizer: Option, valp: &mut MaybeUninit, ) { - unsafe { - ptr::write( - valp.as_mut_ptr(), - wasm_val_t::from_val(Val::ExternRef(Some(ExternRef::new(CExternRef { - data, - finalizer, - })))), - ) - } + crate::initialize( + valp, + wasm_val_t::from_val(Val::ExternRef(Some(ExternRef::new(CExternRef { + data, + finalizer, + })))), + ); } #[no_mangle] -pub extern "C" fn wasmtime_externref_data(val: &wasm_val_t, datap: *mut *mut c_void) -> bool { +pub extern "C" fn wasmtime_externref_data( + val: &wasm_val_t, + datap: &mut MaybeUninit<*mut c_void>, +) -> bool { match val.val() { Val::ExternRef(None) => { - unsafe { - ptr::write(datap, ptr::null_mut()); - } + crate::initialize(datap, ptr::null_mut()); true } Val::ExternRef(Some(x)) => { @@ -148,9 +147,7 @@ pub extern "C" fn wasmtime_externref_data(val: &wasm_val_t, datap: *mut *mut c_v Some(r) => r.data, None => x.data() as *const dyn Any as *mut c_void, }; - unsafe { - ptr::write(datap, data); - } + crate::initialize(datap, data); true } _ => false, diff --git a/crates/c-api/src/val.rs b/crates/c-api/src/val.rs index 026356347c..25754d4ed0 100644 --- a/crates/c-api/src/val.rs +++ b/crates/c-api/src/val.rs @@ -124,8 +124,8 @@ impl wasm_val_t { #[no_mangle] pub unsafe extern "C" fn wasm_val_copy(out: &mut MaybeUninit, source: &wasm_val_t) { - ptr::write( - out.as_mut_ptr(), + crate::initialize( + out, match into_valtype(source.kind) { ValType::I32 | ValType::I64