Remove HostRef<T> from the C API (#1926)

This commit removes `HostRef<T>` from the C API which only served the
purpose now of converting each type to a `wasm_ref_t*`. Our
implementation, however, does not guarantee that you'll get the same
`wasm_ref_t*` for each actual underlying item (e.g. if you put a func in
a table and then get the func as an export and from the table then
`same` will report `false`). Additionally the fate of `wasm_ref_t*`
seems somewhat unclear at this point.

The change here is to make the `same` and cast functions all abort
saying they're unimplemented. (similar to the host info functions). If
and when we get around to reimplementing these functions we can ensure
they're implemented uniformly and work well for all intended use cases.
This commit is contained in:
Alex Crichton
2020-06-26 14:34:34 -05:00
committed by GitHub
parent c3799c8ab4
commit cca558cd20
14 changed files with 113 additions and 332 deletions

View File

@@ -71,8 +71,9 @@ pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
}
#[no_mangle]
pub extern fn #same(a: &#ty, b: &#ty) -> bool {
a.externref().ptr_eq(&b.externref())
pub extern fn #same(_a: &#ty, _b: &#ty) -> bool {
eprintln!("`{}` is not implemented", stringify!(#same));
std::process::abort();
}
#[no_mangle]
@@ -98,13 +99,14 @@ pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
#[no_mangle]
pub extern fn #as_ref(a: &#ty) -> Box<crate::wasm_ref_t> {
let r = Some(a.externref());
Box::new(crate::wasm_ref_t { r })
eprintln!("`{}` is not implemented", stringify!(#as_ref));
std::process::abort();
}
#[no_mangle]
pub extern fn #as_ref_const(a: &#ty) -> Box<crate::wasm_ref_t> {
#as_ref(a)
eprintln!("`{}` is not implemented", stringify!(#as_ref_const));
std::process::abort();
}
// TODO: implement `wasm_ref_as_#name#`

View File

@@ -1,53 +1,27 @@
use crate::host_ref::HostRef;
use crate::wasm_externkind_t;
use crate::{wasm_externtype_t, wasm_func_t, wasm_global_t, wasm_memory_t, wasm_table_t};
use wasmtime::{ExternType, Func, Global, Memory, Table};
use wasmtime::Extern;
#[derive(Clone)]
pub struct wasm_extern_t {
pub(crate) which: ExternHost,
pub(crate) which: Extern,
}
wasmtime_c_api_macros::declare_ref!(wasm_extern_t);
#[derive(Clone)]
pub(crate) enum ExternHost {
Func(HostRef<Func>),
Global(HostRef<Global>),
Memory(HostRef<Memory>),
Table(HostRef<Table>),
}
impl wasm_extern_t {
pub(crate) fn externref(&self) -> wasmtime::ExternRef {
match &self.which {
ExternHost::Func(f) => f.clone().into(),
ExternHost::Global(f) => f.clone().into(),
ExternHost::Memory(f) => f.clone().into(),
ExternHost::Table(f) => f.clone().into(),
}
}
}
#[no_mangle]
pub extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t {
match e.which {
ExternHost::Func(_) => crate::WASM_EXTERN_FUNC,
ExternHost::Global(_) => crate::WASM_EXTERN_GLOBAL,
ExternHost::Table(_) => crate::WASM_EXTERN_TABLE,
ExternHost::Memory(_) => crate::WASM_EXTERN_MEMORY,
Extern::Func(_) => crate::WASM_EXTERN_FUNC,
Extern::Global(_) => crate::WASM_EXTERN_GLOBAL,
Extern::Table(_) => crate::WASM_EXTERN_TABLE,
Extern::Memory(_) => crate::WASM_EXTERN_MEMORY,
}
}
#[no_mangle]
pub extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box<wasm_externtype_t> {
let ty = match &e.which {
ExternHost::Func(f) => ExternType::Func(f.borrow().ty()),
ExternHost::Global(f) => ExternType::Global(f.borrow().ty()),
ExternHost::Table(f) => ExternType::Table(f.borrow().ty()),
ExternHost::Memory(f) => ExternType::Memory(f.borrow().ty()),
};
Box::new(wasm_externtype_t::new(ty))
Box::new(wasm_externtype_t::new(e.which.ty()))
}
#[no_mangle]

View File

@@ -1,6 +1,5 @@
use crate::host_ref::HostRef;
use crate::{wasm_extern_t, wasm_functype_t, wasm_store_t, wasm_val_t};
use crate::{wasm_name_t, wasm_trap_t, wasmtime_error_t, ExternHost};
use crate::{wasm_name_t, wasm_trap_t, wasmtime_error_t};
use anyhow::anyhow;
use std::ffi::c_void;
use std::panic::{self, AssertUnwindSafe};
@@ -59,29 +58,23 @@ impl Drop for Finalizer {
impl wasm_func_t {
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_func_t> {
match &e.which {
ExternHost::Func(_) => Some(unsafe { &*(e as *const _ as *const _) }),
Extern::Func(_) => Some(unsafe { &*(e as *const _ as *const _) }),
_ => None,
}
}
pub(crate) fn func(&self) -> &HostRef<Func> {
pub(crate) fn func(&self) -> &Func {
match &self.ext.which {
ExternHost::Func(f) => f,
Extern::Func(f) => f,
_ => unsafe { std::hint::unreachable_unchecked() },
}
}
fn externref(&self) -> wasmtime::ExternRef {
self.func().clone().into()
}
}
impl From<HostRef<Func>> for wasm_func_t {
fn from(func: HostRef<Func>) -> wasm_func_t {
impl From<Func> for wasm_func_t {
fn from(func: Func) -> wasm_func_t {
wasm_func_t {
ext: wasm_extern_t {
which: ExternHost::Func(func),
},
ext: wasm_extern_t { which: func.into() },
}
}
}
@@ -101,14 +94,14 @@ fn create_function(
let mut out_results = vec![wasm_val_t::default(); results.len()];
let out = func(caller, params.as_ptr(), out_results.as_mut_ptr());
if let Some(trap) = out {
return Err(trap.trap.borrow().clone());
return Err(trap.trap.clone());
}
for i in 0..results.len() {
results[i] = out_results[i].val();
}
Ok(())
});
Box::new(HostRef::new(func).into())
Box::new(func.into())
}
#[no_mangle]
@@ -172,7 +165,7 @@ pub unsafe extern "C" fn wasm_func_call(
args: *const wasm_val_t,
results: *mut wasm_val_t,
) -> *mut wasm_trap_t {
let func = wasm_func.func().borrow();
let func = wasm_func.func();
let mut trap = ptr::null_mut();
let error = wasmtime_func_call(
wasm_func,
@@ -211,7 +204,7 @@ fn _wasmtime_func_call(
results: &mut [wasm_val_t],
trap_ptr: &mut *mut wasm_trap_t,
) -> Option<Box<wasmtime_error_t>> {
let func = func.func().borrow();
let func = func.func();
if results.len() != func.result_arity() {
return Some(Box::new(anyhow!("wrong number of results provided").into()));
}
@@ -253,17 +246,17 @@ fn _wasmtime_func_call(
#[no_mangle]
pub extern "C" fn wasm_func_type(f: &wasm_func_t) -> Box<wasm_functype_t> {
Box::new(wasm_functype_t::new(f.func().borrow().ty()))
Box::new(wasm_functype_t::new(f.func().ty()))
}
#[no_mangle]
pub extern "C" fn wasm_func_param_arity(f: &wasm_func_t) -> usize {
f.func().borrow().param_arity()
f.func().param_arity()
}
#[no_mangle]
pub extern "C" fn wasm_func_result_arity(f: &wasm_func_t) -> usize {
f.func().borrow().result_arity()
f.func().result_arity()
}
#[no_mangle]
@@ -277,12 +270,6 @@ pub extern "C" fn wasmtime_caller_export_get(
name: &wasm_name_t,
) -> Option<Box<wasm_extern_t>> {
let name = str::from_utf8(name.as_slice()).ok()?;
let export = caller.caller.get_export(name)?;
let which = match export {
Extern::Func(f) => ExternHost::Func(HostRef::new(f)),
Extern::Global(g) => ExternHost::Global(HostRef::new(g)),
Extern::Memory(m) => ExternHost::Memory(HostRef::new(m)),
Extern::Table(t) => ExternHost::Table(HostRef::new(t)),
};
let which = caller.caller.get_export(name)?;
Some(Box::new(wasm_extern_t { which }))
}

View File

@@ -1,8 +1,7 @@
use crate::host_ref::HostRef;
use crate::{handle_result, wasmtime_error_t};
use crate::{wasm_extern_t, wasm_globaltype_t, wasm_store_t, wasm_val_t, ExternHost};
use crate::{wasm_extern_t, wasm_globaltype_t, wasm_store_t, wasm_val_t};
use std::ptr;
use wasmtime::Global;
use wasmtime::{Extern, Global};
#[derive(Clone)]
#[repr(transparent)]
@@ -15,21 +14,17 @@ wasmtime_c_api_macros::declare_ref!(wasm_global_t);
impl wasm_global_t {
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_global_t> {
match &e.which {
ExternHost::Global(_) => Some(unsafe { &*(e as *const _ as *const _) }),
Extern::Global(_) => Some(unsafe { &*(e as *const _ as *const _) }),
_ => None,
}
}
fn global(&self) -> &HostRef<Global> {
fn global(&self) -> &Global {
match &self.ext.which {
ExternHost::Global(g) => g,
Extern::Global(g) => g,
_ => unsafe { std::hint::unreachable_unchecked() },
}
}
fn externref(&self) -> wasmtime::ExternRef {
self.global().clone().into()
}
}
#[no_mangle]
@@ -59,7 +54,7 @@ pub extern "C" fn wasmtime_global_new(
handle_result(global, |global| {
*ret = Box::into_raw(Box::new(wasm_global_t {
ext: wasm_extern_t {
which: ExternHost::Global(HostRef::new(global)),
which: global.into(),
},
}));
})
@@ -72,18 +67,18 @@ pub extern "C" fn wasm_global_as_extern(g: &wasm_global_t) -> &wasm_extern_t {
#[no_mangle]
pub extern "C" fn wasm_global_type(g: &wasm_global_t) -> Box<wasm_globaltype_t> {
let globaltype = g.global().borrow().ty();
let globaltype = g.global().ty();
Box::new(wasm_globaltype_t::new(globaltype))
}
#[no_mangle]
pub extern "C" fn wasm_global_get(g: &wasm_global_t, out: &mut wasm_val_t) {
out.set(g.global().borrow().get());
out.set(g.global().get());
}
#[no_mangle]
pub extern "C" fn wasm_global_set(g: &wasm_global_t, val: &wasm_val_t) {
let result = g.global().borrow().set(val.val());
let result = g.global().set(val.val());
// FIXME(WebAssembly/wasm-c-api#131) should communicate the error here
drop(result);
}
@@ -93,5 +88,5 @@ pub extern "C" fn wasmtime_global_set(
g: &wasm_global_t,
val: &wasm_val_t,
) -> Option<Box<wasmtime_error_t>> {
handle_result(g.global().borrow().set(val.val()), |()| {})
handle_result(g.global().set(val.val()), |()| {})
}

View File

@@ -1,101 +0,0 @@
use std::any::Any;
use std::cell::{self, RefCell};
use std::convert::TryFrom;
use std::marker::PhantomData;
use wasmtime::ExternRef;
/// Represents a piece of data located in the host environment.
#[derive(Debug)]
pub struct HostRef<T>
where
T: 'static + Any,
{
externref: ExternRef,
_phantom: PhantomData<T>,
}
impl<T> HostRef<T>
where
T: 'static + Any,
{
/// Creates a new `HostRef<T>` from `T`.
pub fn new(item: T) -> HostRef<T> {
HostRef {
externref: ExternRef::new(RefCell::new(item)),
_phantom: PhantomData,
}
}
/// Immutably borrows the wrapped data.
///
/// # Panics
///
/// Panics if the value is currently mutably borrowed.
pub fn borrow(&self) -> cell::Ref<T> {
self.inner().borrow()
}
/// Mutably borrows the wrapped data.
///
/// # Panics
///
/// Panics if the `HostRef<T>` is already borrowed.
pub fn borrow_mut(&self) -> cell::RefMut<T> {
self.inner().borrow_mut()
}
/// Returns true if the two `HostRef<T>`'s point to the same value (not just
/// values that compare as equal).
pub fn ptr_eq(&self, other: &HostRef<T>) -> bool {
self.externref.ptr_eq(&other.externref)
}
fn inner(&self) -> &RefCell<T> {
self.externref
.data()
.downcast_ref::<RefCell<T>>()
.expect("`HostRef<T>`s always wrap an `ExternRef` of `RefCell<T>`")
}
}
impl<T> AsRef<ExternRef> for HostRef<T> {
fn as_ref(&self) -> &ExternRef {
&self.externref
}
}
impl<T> From<HostRef<T>> for ExternRef
where
T: 'static + Any,
{
fn from(host: HostRef<T>) -> ExternRef {
host.externref
}
}
impl<T> TryFrom<ExternRef> for HostRef<T>
where
T: 'static + Any,
{
type Error = ExternRef;
fn try_from(externref: ExternRef) -> Result<Self, ExternRef> {
if externref.data().is::<RefCell<T>>() {
Ok(HostRef {
externref,
_phantom: PhantomData,
})
} else {
Err(externref)
}
}
}
impl<T> Clone for HostRef<T> {
fn clone(&self) -> HostRef<T> {
HostRef {
externref: self.externref.clone(),
_phantom: PhantomData,
}
}
}

View File

@@ -1,30 +1,20 @@
use crate::host_ref::HostRef;
use crate::{wasm_extern_t, wasm_extern_vec_t, wasm_module_t, wasm_trap_t};
use crate::{wasm_store_t, wasmtime_error_t, ExternHost};
use crate::{wasm_store_t, wasmtime_error_t};
use anyhow::Result;
use std::cell::RefCell;
use std::ptr;
use wasmtime::{Extern, Instance, Trap};
use wasmtime::{Instance, Trap};
#[repr(C)]
#[derive(Clone)]
pub struct wasm_instance_t {
pub(crate) instance: HostRef<Instance>,
exports_cache: RefCell<Option<Vec<ExternHost>>>,
pub(crate) instance: Instance,
}
wasmtime_c_api_macros::declare_ref!(wasm_instance_t);
impl wasm_instance_t {
pub(crate) fn new(instance: Instance) -> wasm_instance_t {
wasm_instance_t {
instance: HostRef::new(instance),
exports_cache: RefCell::new(None),
}
}
fn externref(&self) -> wasmtime::ExternRef {
self.instance.clone().into()
wasm_instance_t { instance: instance }
}
}
@@ -99,16 +89,10 @@ fn _wasmtime_instance_new(
let store = &store.store;
let imports = imports
.iter()
.map(|import| match &import.which {
ExternHost::Func(e) => Extern::Func(e.borrow().clone()),
ExternHost::Table(e) => Extern::Table(e.borrow().clone()),
ExternHost::Global(e) => Extern::Global(e.borrow().clone()),
ExternHost::Memory(e) => Extern::Memory(e.borrow().clone()),
})
.map(|import| import.which.clone())
.collect::<Vec<_>>();
let module = &module.module.borrow();
handle_instantiate(
Instance::new(store, module, &imports),
Instance::new(store, &module.module, &imports),
instance_ptr,
trap_ptr,
)
@@ -140,23 +124,15 @@ pub fn handle_instantiate(
#[no_mangle]
pub extern "C" fn wasm_instance_exports(instance: &wasm_instance_t, out: &mut wasm_extern_vec_t) {
let mut cache = instance.exports_cache.borrow_mut();
let exports = cache.get_or_insert_with(|| {
let instance = &instance.instance.borrow();
out.set_buffer(
instance
.instance
.exports()
.map(|e| match e.into_extern() {
Extern::Func(f) => ExternHost::Func(HostRef::new(f)),
Extern::Global(f) => ExternHost::Global(HostRef::new(f)),
Extern::Memory(f) => ExternHost::Memory(HostRef::new(f)),
Extern::Table(f) => ExternHost::Table(HostRef::new(f)),
.map(|e| {
Some(Box::new(wasm_extern_t {
which: e.into_extern(),
}))
})
.collect()
});
let mut buffer = Vec::with_capacity(exports.len());
for e in exports {
let ext = Box::new(wasm_extern_t { which: e.clone() });
buffer.push(Some(ext));
}
out.set_buffer(buffer);
.collect(),
);
}

View File

@@ -11,7 +11,6 @@ mod error;
mod r#extern;
mod func;
mod global;
mod host_ref;
mod instance;
mod linker;
mod memory;

View File

@@ -1,9 +1,8 @@
use crate::host_ref::HostRef;
use crate::{bad_utf8, handle_result, wasmtime_error_t};
use crate::{wasm_extern_t, wasm_store_t, ExternHost};
use crate::{wasm_extern_t, wasm_store_t};
use crate::{wasm_func_t, wasm_instance_t, wasm_module_t, wasm_name_t, wasm_trap_t};
use std::str;
use wasmtime::{Extern, Linker};
use wasmtime::Linker;
#[repr(C)]
pub struct wasmtime_linker_t {
@@ -44,12 +43,7 @@ pub extern "C" fn wasmtime_linker_define(
Ok(s) => s,
Err(_) => return bad_utf8(),
};
let item = match &item.which {
ExternHost::Func(e) => Extern::Func(e.borrow().clone()),
ExternHost::Table(e) => Extern::Table(e.borrow().clone()),
ExternHost::Global(e) => Extern::Global(e.borrow().clone()),
ExternHost::Memory(e) => Extern::Memory(e.borrow().clone()),
};
let item = item.which.clone();
handle_result(linker.define(module, name, item), |_linker| ())
}
@@ -74,10 +68,7 @@ pub extern "C" fn wasmtime_linker_define_instance(
Ok(s) => s,
Err(_) => return bad_utf8(),
};
handle_result(
linker.instance(name, &instance.instance.borrow()),
|_linker| (),
)
handle_result(linker.instance(name, &instance.instance), |_linker| ())
}
#[no_mangle]
@@ -87,7 +78,7 @@ pub extern "C" fn wasmtime_linker_instantiate(
instance_ptr: &mut *mut wasm_instance_t,
trap_ptr: &mut *mut wasm_trap_t,
) -> Option<Box<wasmtime_error_t>> {
let result = linker.linker.instantiate(&module.module.borrow());
let result = linker.linker.instantiate(&module.module);
super::instance::handle_instantiate(result, instance_ptr, trap_ptr)
}
@@ -102,7 +93,7 @@ pub extern "C" fn wasmtime_linker_module(
Ok(s) => s,
Err(_) => return bad_utf8(),
};
handle_result(linker.module(name, &module.module.borrow()), |_linker| ())
handle_result(linker.module(name, &module.module), |_linker| ())
}
#[no_mangle]
@@ -117,7 +108,7 @@ pub extern "C" fn wasmtime_linker_get_default(
Err(_) => return bad_utf8(),
};
handle_result(linker.get_default(name), |f| {
*func = Box::into_raw(Box::new(HostRef::new(f).into()))
*func = Box::into_raw(Box::new(f.into()))
})
}
@@ -137,13 +128,7 @@ pub extern "C" fn wasmtime_linker_get_one_by_name(
Ok(s) => s,
Err(_) => return bad_utf8(),
};
handle_result(linker.get_one_by_name(module, name), |item| {
let which = match item {
Extern::Func(f) => ExternHost::Func(HostRef::new(f)),
Extern::Global(g) => ExternHost::Global(HostRef::new(g)),
Extern::Memory(m) => ExternHost::Memory(HostRef::new(m)),
Extern::Table(t) => ExternHost::Table(HostRef::new(t)),
};
handle_result(linker.get_one_by_name(module, name), |which| {
*item_ptr = Box::into_raw(Box::new(wasm_extern_t { which }))
})
}

View File

@@ -1,6 +1,5 @@
use crate::host_ref::HostRef;
use crate::{wasm_extern_t, wasm_memorytype_t, wasm_store_t, ExternHost};
use wasmtime::Memory;
use crate::{wasm_extern_t, wasm_memorytype_t, wasm_store_t};
use wasmtime::{Extern, Memory};
#[derive(Clone)]
#[repr(transparent)]
@@ -15,21 +14,17 @@ pub type wasm_memory_pages_t = u32;
impl wasm_memory_t {
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_memory_t> {
match &e.which {
ExternHost::Memory(_) => Some(unsafe { &*(e as *const _ as *const _) }),
Extern::Memory(_) => Some(unsafe { &*(e as *const _ as *const _) }),
_ => None,
}
}
fn memory(&self) -> &HostRef<Memory> {
fn memory(&self) -> &Memory {
match &self.ext.which {
ExternHost::Memory(m) => m,
Extern::Memory(m) => m,
_ => unsafe { std::hint::unreachable_unchecked() },
}
}
fn externref(&self) -> wasmtime::ExternRef {
self.memory().clone().into()
}
}
#[no_mangle]
@@ -37,10 +32,10 @@ pub extern "C" fn wasm_memory_new(
store: &wasm_store_t,
mt: &wasm_memorytype_t,
) -> Box<wasm_memory_t> {
let memory = HostRef::new(Memory::new(&store.store, mt.ty().ty.clone()));
let memory = Memory::new(&store.store, mt.ty().ty.clone());
Box::new(wasm_memory_t {
ext: wasm_extern_t {
which: ExternHost::Memory(memory),
which: memory.into(),
},
})
}
@@ -52,26 +47,26 @@ pub extern "C" fn wasm_memory_as_extern(m: &wasm_memory_t) -> &wasm_extern_t {
#[no_mangle]
pub extern "C" fn wasm_memory_type(m: &wasm_memory_t) -> Box<wasm_memorytype_t> {
let ty = m.memory().borrow().ty();
let ty = m.memory().ty();
Box::new(wasm_memorytype_t::new(ty))
}
#[no_mangle]
pub extern "C" fn wasm_memory_data(m: &wasm_memory_t) -> *mut u8 {
m.memory().borrow().data_ptr()
m.memory().data_ptr()
}
#[no_mangle]
pub extern "C" fn wasm_memory_data_size(m: &wasm_memory_t) -> usize {
m.memory().borrow().data_size()
m.memory().data_size()
}
#[no_mangle]
pub extern "C" fn wasm_memory_size(m: &wasm_memory_t) -> wasm_memory_pages_t {
m.memory().borrow().size()
m.memory().size()
}
#[no_mangle]
pub extern "C" fn wasm_memory_grow(m: &wasm_memory_t, delta: wasm_memory_pages_t) -> bool {
m.memory().borrow().grow(delta).is_ok()
m.memory().grow(delta).is_ok()
}

View File

@@ -1,4 +1,3 @@
use crate::host_ref::HostRef;
use crate::{
handle_result, wasm_byte_vec_t, wasm_exporttype_t, wasm_exporttype_vec_t, wasm_importtype_t,
wasm_importtype_vec_t, wasm_store_t, wasmtime_error_t,
@@ -9,19 +8,13 @@ use wasmtime::{Engine, Module};
#[repr(C)]
#[derive(Clone)]
pub struct wasm_module_t {
pub(crate) module: HostRef<Module>,
pub(crate) module: Module,
pub(crate) imports: Vec<wasm_importtype_t>,
pub(crate) exports: Vec<wasm_exporttype_t>,
}
wasmtime_c_api_macros::declare_ref!(wasm_module_t);
impl wasm_module_t {
fn externref(&self) -> wasmtime::ExternRef {
self.module.clone().into()
}
}
#[repr(C)]
#[derive(Clone)]
pub struct wasm_shared_module_t {
@@ -63,7 +56,7 @@ pub extern "C" fn wasmtime_module_new(
.map(|e| wasm_exporttype_t::new(e.name().to_owned(), e.ty()))
.collect::<Vec<_>>();
let module = Box::new(wasm_module_t {
module: HostRef::new(module),
module: module,
imports,
exports,
});
@@ -108,7 +101,7 @@ pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_imp
#[no_mangle]
pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> {
Box::new(wasm_shared_module_t {
module: module.module.borrow().clone(),
module: module.module.clone(),
})
}
@@ -130,7 +123,7 @@ pub extern "C" fn wasm_module_obtain(
.map(|e| wasm_exporttype_t::new(e.name().to_owned(), e.ty()))
.collect::<Vec<_>>();
Some(Box::new(wasm_module_t {
module: HostRef::new(module),
module: module,
imports,
exports,
}))

View File

@@ -1,8 +1,7 @@
use crate::host_ref::HostRef;
use crate::{handle_result, wasm_func_t, wasm_ref_t, wasmtime_error_t};
use crate::{wasm_extern_t, wasm_store_t, wasm_tabletype_t, ExternHost};
use crate::{wasm_extern_t, wasm_store_t, wasm_tabletype_t};
use std::ptr;
use wasmtime::{Table, Val};
use wasmtime::{Extern, Table, Val};
#[derive(Clone)]
#[repr(transparent)]
@@ -17,21 +16,17 @@ pub type wasm_table_size_t = u32;
impl wasm_table_t {
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_table_t> {
match &e.which {
ExternHost::Table(_) => Some(unsafe { &*(e as *const _ as *const _) }),
Extern::Table(_) => Some(unsafe { &*(e as *const _ as *const _) }),
_ => None,
}
}
fn table(&self) -> &HostRef<Table> {
fn table(&self) -> &Table {
match &self.ext.which {
ExternHost::Table(t) => t,
Extern::Table(t) => t,
_ => unsafe { std::hint::unreachable_unchecked() },
}
}
fn externref(&self) -> wasmtime::ExternRef {
self.table().clone().into()
}
}
#[no_mangle]
@@ -47,7 +42,7 @@ pub extern "C" fn wasm_table_new(
let table = Table::new(&store.store, tt.ty().ty.clone(), init).ok()?;
Some(Box::new(wasm_table_t {
ext: wasm_extern_t {
which: ExternHost::Table(HostRef::new(table)),
which: table.into(),
},
}))
}
@@ -60,7 +55,7 @@ pub extern "C" fn wasmtime_funcref_table_new(
out: &mut *mut wasm_table_t,
) -> Option<Box<wasmtime_error_t>> {
let init: Val = match init {
Some(val) => Val::FuncRef(Some(val.func().borrow().clone())),
Some(val) => Val::FuncRef(Some(val.func().clone())),
None => Val::FuncRef(None),
};
handle_result(
@@ -68,7 +63,7 @@ pub extern "C" fn wasmtime_funcref_table_new(
|table| {
*out = Box::into_raw(Box::new(wasm_table_t {
ext: wasm_extern_t {
which: ExternHost::Table(HostRef::new(table)),
which: table.into(),
},
}));
},
@@ -77,13 +72,13 @@ pub extern "C" fn wasmtime_funcref_table_new(
#[no_mangle]
pub extern "C" fn wasm_table_type(t: &wasm_table_t) -> Box<wasm_tabletype_t> {
let ty = t.table().borrow().ty();
let ty = t.table().ty();
Box::new(wasm_tabletype_t::new(ty))
}
#[no_mangle]
pub extern "C" fn wasm_table_get(t: &wasm_table_t, index: wasm_table_size_t) -> *mut wasm_ref_t {
match t.table().borrow().get(index) {
match t.table().get(index) {
Some(val) => into_funcref(val),
None => into_funcref(Val::FuncRef(None)),
}
@@ -95,12 +90,11 @@ pub extern "C" fn wasmtime_funcref_table_get(
index: wasm_table_size_t,
ptr: &mut *mut wasm_func_t,
) -> bool {
match t.table().borrow().get(index) {
match t.table().get(index) {
Some(val) => {
*ptr = match val {
// TODO: what do do about creating new `HostRef` handles here?
Val::FuncRef(None) => ptr::null_mut(),
Val::FuncRef(Some(f)) => Box::into_raw(Box::new(HostRef::new(f).into())),
Val::FuncRef(Some(f)) => Box::into_raw(Box::new(f.into())),
_ => return false,
};
}
@@ -117,7 +111,7 @@ pub unsafe extern "C" fn wasm_table_set(
r: *mut wasm_ref_t,
) -> bool {
let val = from_funcref(r);
t.table().borrow().set(index, val).is_ok()
t.table().set(index, val).is_ok()
}
#[no_mangle]
@@ -127,10 +121,10 @@ pub extern "C" fn wasmtime_funcref_table_set(
val: Option<&wasm_func_t>,
) -> Option<Box<wasmtime_error_t>> {
let val = match val {
Some(val) => Val::FuncRef(Some(val.func().borrow().clone())),
Some(val) => Val::FuncRef(Some(val.func().clone())),
None => Val::FuncRef(None),
};
handle_result(t.table().borrow().set(index, val), |()| {})
handle_result(t.table().set(index, val), |()| {})
}
fn into_funcref(val: Val) -> *mut wasm_ref_t {
@@ -155,7 +149,7 @@ unsafe fn from_funcref(r: *mut wasm_ref_t) -> Val {
#[no_mangle]
pub extern "C" fn wasm_table_size(t: &wasm_table_t) -> wasm_table_size_t {
t.table().borrow().size()
t.table().size()
}
#[no_mangle]
@@ -165,7 +159,7 @@ pub unsafe extern "C" fn wasm_table_grow(
init: *mut wasm_ref_t,
) -> bool {
let init = from_funcref(init);
t.table().borrow().grow(delta, init).is_ok()
t.table().grow(delta, init).is_ok()
}
#[no_mangle]
@@ -176,10 +170,10 @@ pub extern "C" fn wasmtime_funcref_table_grow(
prev_size: Option<&mut wasm_table_size_t>,
) -> Option<Box<wasmtime_error_t>> {
let val = match init {
Some(val) => Val::FuncRef(Some(val.func().borrow().clone())),
Some(val) => Val::FuncRef(Some(val.func().clone())),
None => Val::FuncRef(None),
};
handle_result(t.table().borrow().grow(delta, val), |prev| {
handle_result(t.table().grow(delta, val), |prev| {
if let Some(ptr) = prev_size {
*ptr = prev;
}

View File

@@ -1,4 +1,3 @@
use crate::host_ref::HostRef;
use crate::{wasm_frame_vec_t, wasm_instance_t, wasm_name_t, wasm_store_t};
use once_cell::unsync::OnceCell;
use wasmtime::Trap;
@@ -6,27 +5,21 @@ use wasmtime::Trap;
#[repr(C)]
#[derive(Clone)]
pub struct wasm_trap_t {
pub(crate) trap: HostRef<Trap>,
pub(crate) trap: Trap,
}
wasmtime_c_api_macros::declare_ref!(wasm_trap_t);
impl wasm_trap_t {
pub(crate) fn new(trap: Trap) -> wasm_trap_t {
wasm_trap_t {
trap: HostRef::new(trap),
}
}
fn externref(&self) -> wasmtime::ExternRef {
self.trap.clone().into()
wasm_trap_t { trap: trap }
}
}
#[repr(C)]
#[derive(Clone)]
pub struct wasm_frame_t {
trap: HostRef<Trap>,
trap: Trap,
idx: usize,
func_name: OnceCell<Option<wasm_name_t>>,
module_name: OnceCell<Option<wasm_name_t>>,
@@ -47,14 +40,14 @@ pub extern "C" fn wasm_trap_new(
}
let message = String::from_utf8_lossy(&message[..message.len() - 1]);
Box::new(wasm_trap_t {
trap: HostRef::new(Trap::new(message)),
trap: Trap::new(message),
})
}
#[no_mangle]
pub extern "C" fn wasm_trap_message(trap: &wasm_trap_t, out: &mut wasm_message_t) {
let mut buffer = Vec::new();
buffer.extend_from_slice(trap.trap.borrow().to_string().as_bytes());
buffer.extend_from_slice(trap.trap.to_string().as_bytes());
buffer.reserve_exact(1);
buffer.push(0);
out.set_buffer(buffer);
@@ -62,8 +55,7 @@ pub extern "C" fn wasm_trap_message(trap: &wasm_trap_t, out: &mut wasm_message_t
#[no_mangle]
pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option<Box<wasm_frame_t>> {
let trap = raw.trap.borrow();
if trap.trace().len() > 0 {
if raw.trap.trace().len() > 0 {
Some(Box::new(wasm_frame_t {
trap: raw.trap.clone(),
idx: 0,
@@ -77,8 +69,7 @@ pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option<Box<wasm_frame_t
#[no_mangle]
pub extern "C" fn wasm_trap_trace(raw: &wasm_trap_t, out: &mut wasm_frame_vec_t) {
let trap = raw.trap.borrow();
let vec = (0..trap.trace().len())
let vec = (0..raw.trap.trace().len())
.map(|idx| {
Some(Box::new(wasm_frame_t {
trap: raw.trap.clone(),
@@ -93,8 +84,7 @@ pub extern "C" fn wasm_trap_trace(raw: &wasm_trap_t, out: &mut wasm_frame_vec_t)
#[no_mangle]
pub extern "C" fn wasmtime_trap_exit_status(raw: &wasm_trap_t, status: &mut i32) -> bool {
let trap = raw.trap.borrow();
match trap.i32_exit_status() {
match raw.trap.i32_exit_status() {
Some(i) => {
*status = i;
true
@@ -105,7 +95,7 @@ pub extern "C" fn wasmtime_trap_exit_status(raw: &wasm_trap_t, status: &mut i32)
#[no_mangle]
pub extern "C" fn wasm_frame_func_index(frame: &wasm_frame_t) -> u32 {
frame.trap.borrow().trace()[frame.idx].func_index()
frame.trap.trace()[frame.idx].func_index()
}
#[no_mangle]
@@ -113,8 +103,7 @@ pub extern "C" fn wasmtime_frame_func_name(frame: &wasm_frame_t) -> Option<&wasm
frame
.func_name
.get_or_init(|| {
let trap = frame.trap.borrow();
trap.trace()[frame.idx]
frame.trap.trace()[frame.idx]
.func_name()
.map(|s| wasm_name_t::from(s.to_string().into_bytes()))
})
@@ -126,8 +115,7 @@ pub extern "C" fn wasmtime_frame_module_name(frame: &wasm_frame_t) -> Option<&wa
frame
.module_name
.get_or_init(|| {
let trap = frame.trap.borrow();
trap.trace()[frame.idx]
frame.trap.trace()[frame.idx]
.module_name()
.map(|s| wasm_name_t::from(s.to_string().into_bytes()))
})
@@ -136,8 +124,7 @@ pub extern "C" fn wasmtime_frame_module_name(frame: &wasm_frame_t) -> Option<&wa
#[no_mangle]
pub extern "C" fn wasm_frame_func_offset(frame: &wasm_frame_t) -> usize {
let trap = frame.trap.borrow();
trap.trace()[frame.idx].func_offset()
frame.trap.trace()[frame.idx].func_offset()
}
#[no_mangle]
@@ -147,6 +134,5 @@ pub extern "C" fn wasm_frame_instance(_arg1: *const wasm_frame_t) -> *mut wasm_i
#[no_mangle]
pub extern "C" fn wasm_frame_module_offset(frame: &wasm_frame_t) -> usize {
let trap = frame.trap.borrow();
trap.trace()[frame.idx].module_offset()
frame.trap.trace()[frame.idx].module_offset()
}

View File

@@ -1,6 +1,5 @@
//! The WASI embedding API definitions for Wasmtime.
use crate::host_ref::HostRef;
use crate::{wasm_extern_t, wasm_importtype_t, wasm_store_t, wasm_trap_t, ExternHost};
use crate::{wasm_extern_t, wasm_importtype_t, wasm_store_t, wasm_trap_t};
use anyhow::Result;
use std::collections::HashMap;
use std::ffi::CStr;
@@ -13,7 +12,7 @@ use wasi_common::{
old::snapshot_0::WasiCtxBuilder as WasiSnapshot0CtxBuilder, preopen_dir,
WasiCtxBuilder as WasiPreview1CtxBuilder,
};
use wasmtime::{Linker, Store, Trap};
use wasmtime::{Extern, Linker, Store, Trap};
use wasmtime_wasi::{old::snapshot_0::Wasi as WasiSnapshot0, Wasi as WasiPreview1};
unsafe fn cstr_to_path<'a>(path: *const c_char) -> Option<&'a Path> {
@@ -313,9 +312,7 @@ pub unsafe extern "C" fn wasi_instance_new(
export_cache: HashMap::new(),
})),
Err(e) => {
*trap = Box::into_raw(Box::new(wasm_trap_t {
trap: HostRef::new(Trap::new(e)),
}));
*trap = Box::into_raw(Box::new(wasm_trap_t { trap: Trap::new(e) }));
None
}
@@ -358,7 +355,7 @@ pub extern "C" fn wasi_instance_bind_import<'a>(
.entry(name.to_string())
.or_insert_with(|| {
Box::new(wasm_extern_t {
which: ExternHost::Func(HostRef::new(export.clone())),
which: Extern::Func(export.clone()),
})
});
Some(entry)

View File

@@ -185,7 +185,6 @@ int main(int argc, const char* argv[]) {
// Try cloning.
wasm_memory_t* copy = wasm_memory_copy(memory);
assert(wasm_memory_same(memory, copy));
wasm_memory_delete(copy);
// Check initial memory.