wasmtime-c-api: Add Wasmtime-specific APIs for externrefs
This commit adds APIs to create new `externref` values (with and without finalizers) and to get an `externref`'s wrapped data.
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
use crate::wasm_val_t;
|
||||
use std::any::Any;
|
||||
use std::os::raw::c_void;
|
||||
use std::ptr;
|
||||
use wasmtime::{ExternRef, Func, Val};
|
||||
|
||||
/// `*mut wasm_ref_t` is a reference type (`externref` or `funcref`), as seen by
|
||||
@@ -92,3 +95,60 @@ pub extern "C" fn wasm_ref_set_host_info_with_finalizer(
|
||||
eprintln!("`wasm_ref_set_host_info_with_finalizer` is not implemented");
|
||||
std::process::abort();
|
||||
}
|
||||
|
||||
type wasmtime_externref_finalizer_t = extern "C" fn(*mut c_void);
|
||||
|
||||
struct CExternRef {
|
||||
data: *mut c_void,
|
||||
finalizer: Option<wasmtime_externref_finalizer_t>,
|
||||
}
|
||||
|
||||
impl Drop for CExternRef {
|
||||
fn drop(&mut self) {
|
||||
if let Some(f) = self.finalizer {
|
||||
f(self.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmtime_externref_new(data: *mut c_void) -> wasm_val_t {
|
||||
wasm_val_t::from_val(Val::ExternRef(Some(ExternRef::new(CExternRef {
|
||||
data,
|
||||
finalizer: None,
|
||||
}))))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmtime_externref_new_with_finalizer(
|
||||
data: *mut c_void,
|
||||
finalizer: Option<wasmtime_externref_finalizer_t>,
|
||||
) -> wasm_val_t {
|
||||
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 {
|
||||
match val.val() {
|
||||
Val::ExternRef(None) => {
|
||||
unsafe {
|
||||
ptr::write(datap, ptr::null_mut());
|
||||
}
|
||||
true
|
||||
}
|
||||
Val::ExternRef(Some(x)) => {
|
||||
let data = match x.data().downcast_ref::<CExternRef>() {
|
||||
Some(r) => r.data,
|
||||
None => x.data() as *const dyn Any as *mut c_void,
|
||||
};
|
||||
unsafe {
|
||||
ptr::write(datap, data);
|
||||
}
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user