wasmtime-c-api: Make wasmtime_externref_new write to an out pointer

The C API prefers not to return structs by value.

Same for `wasmtime_externref_new_with_finalizer`.
This commit is contained in:
Nick Fitzgerald
2020-07-10 11:21:31 -07:00
parent b9bb095e0f
commit b73b2e0d5a
3 changed files with 24 additions and 13 deletions

View File

@@ -839,13 +839,14 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_funcref_table_grow(
/** /**
* \brief Create a new `externref` value. * \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 * 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, * the reference is reclaimed. If you need a finalizer to clean up the data,
* then use #wasmtime_externref_new_with_finalizer. * 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. * \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. * \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 * 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 * provided finalizer. If you do not need to clean up the wrapped data, then use
* #wasmtime_externref_new. * #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, void *data,
wasmtime_externref_finalizer_t finalizer wasmtime_externref_finalizer_t finalizer,
wasm_val_t *valp
); );
/** /**

View File

@@ -1,5 +1,6 @@
use crate::wasm_val_t; use crate::wasm_val_t;
use std::any::Any; use std::any::Any;
use std::mem::MaybeUninit;
use std::os::raw::c_void; use std::os::raw::c_void;
use std::ptr; use std::ptr;
use wasmtime::{ExternRef, Func, Val}; use wasmtime::{ExternRef, Func, Val};
@@ -112,19 +113,25 @@ impl Drop for CExternRef {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmtime_externref_new(data: *mut c_void) -> wasm_val_t { pub extern "C" fn wasmtime_externref_new(data: *mut c_void, valp: &mut MaybeUninit<wasm_val_t>) {
wasmtime_externref_new_with_finalizer(data, None) wasmtime_externref_new_with_finalizer(data, None, valp)
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmtime_externref_new_with_finalizer( pub extern "C" fn wasmtime_externref_new_with_finalizer(
data: *mut c_void, data: *mut c_void,
finalizer: Option<wasmtime_externref_finalizer_t>, finalizer: Option<wasmtime_externref_finalizer_t>,
) -> wasm_val_t { valp: &mut MaybeUninit<wasm_val_t>,
) {
unsafe {
ptr::write(
valp.as_mut_ptr(),
wasm_val_t::from_val(Val::ExternRef(Some(ExternRef::new(CExternRef { wasm_val_t::from_val(Val::ExternRef(Some(ExternRef::new(CExternRef {
data, data,
finalizer, finalizer,
})))) })))),
)
}
} }
#[no_mangle] #[no_mangle]

View File

@@ -82,7 +82,8 @@ int main() {
printf("Creating new `externref`...\n"); printf("Creating new `externref`...\n");
// Create a new `externref` value. // 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); assert(externref.kind == WASM_ANYREF);
// The `externref`'s wrapped data should be the string "Hello, World!". // The `externref`'s wrapped data should be the string "Hello, World!".