C API tweaks for wasmtime-py (#2029)

* wasmtime-c-api: Only drop non-null `*mut wasm_ref_t`s

* wasmtime-c-api: Handle null refs in `wasm_val_t` to `Val` conversion

* wasmtime-c-api: Don't unwrap and rewrap `Option`s

The `unwrap` can panic, and there isn't any point to this unwrap+rewrap.

* wasmtime-c-api: Add conversions between `funcref` and `wasm_func_t`

* wasmtime-c-api: More ownership documentation for `wasmtime.h`
This commit is contained in:
Nick Fitzgerald
2020-07-15 17:55:31 -07:00
committed by GitHub
parent c3e8a04c90
commit a9455a8e51
4 changed files with 68 additions and 9 deletions

View File

@@ -6,7 +6,7 @@ use std::mem::MaybeUninit;
use std::panic::{self, AssertUnwindSafe};
use std::ptr;
use std::str;
use wasmtime::{Caller, Extern, Func, Trap};
use wasmtime::{Caller, Extern, Func, Trap, Val};
#[derive(Clone)]
#[repr(transparent)]
@@ -275,3 +275,21 @@ pub extern "C" fn wasmtime_caller_export_get(
let which = caller.caller.get_export(name)?;
Some(Box::new(wasm_extern_t { which }))
}
#[no_mangle]
pub extern "C" fn wasmtime_func_as_funcref(
func: &wasm_func_t,
funcrefp: &mut MaybeUninit<wasm_val_t>,
) {
let funcref = wasm_val_t::from_val(Val::FuncRef(Some(func.func().clone())));
crate::initialize(funcrefp, funcref);
}
#[no_mangle]
pub extern "C" fn wasmtime_funcref_as_func(val: &wasm_val_t) -> Option<Box<wasm_func_t>> {
if let Val::FuncRef(Some(f)) = val.val() {
Some(Box::new(f.into()))
} else {
None
}
}

View File

@@ -91,7 +91,7 @@ pub extern "C" fn wasm_table_get(
index: wasm_table_size_t,
) -> Option<Box<wasm_ref_t>> {
let val = t.table().get(index)?;
Some(val_into_ref(val).unwrap())
val_into_ref(val)
}
#[no_mangle]

View File

@@ -26,7 +26,9 @@ impl Drop for wasm_val_t {
fn drop(&mut self) {
match into_valtype(self.kind) {
ValType::ExternRef => unsafe {
drop(Box::from_raw(self.of.ref_));
if !self.of.ref_.is_null() {
drop(Box::from_raw(self.of.ref_));
}
},
_ => {}
}
@@ -116,7 +118,20 @@ impl wasm_val_t {
ValType::I64 => Val::from(unsafe { self.of.i64 }),
ValType::F32 => Val::from(unsafe { self.of.f32 }),
ValType::F64 => Val::from(unsafe { self.of.f64 }),
ValType::ExternRef | ValType::FuncRef => ref_to_val(unsafe { &*self.of.ref_ }),
ValType::ExternRef => unsafe {
if self.of.ref_.is_null() {
Val::ExternRef(None)
} else {
ref_to_val(&*self.of.ref_)
}
},
ValType::FuncRef => unsafe {
if self.of.ref_.is_null() {
Val::FuncRef(None)
} else {
ref_to_val(&*self.of.ref_)
}
},
_ => unimplemented!("wasm_val_t::val {:?}", self.kind),
}
}