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:
@@ -71,8 +71,9 @@ pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn #same(a: &#ty, b: &#ty) -> bool {
|
pub extern fn #same(_a: &#ty, _b: &#ty) -> bool {
|
||||||
a.externref().ptr_eq(&b.externref())
|
eprintln!("`{}` is not implemented", stringify!(#same));
|
||||||
|
std::process::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -98,13 +99,14 @@ pub fn declare_ref(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn #as_ref(a: &#ty) -> Box<crate::wasm_ref_t> {
|
pub extern fn #as_ref(a: &#ty) -> Box<crate::wasm_ref_t> {
|
||||||
let r = Some(a.externref());
|
eprintln!("`{}` is not implemented", stringify!(#as_ref));
|
||||||
Box::new(crate::wasm_ref_t { r })
|
std::process::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn #as_ref_const(a: &#ty) -> Box<crate::wasm_ref_t> {
|
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#`
|
// TODO: implement `wasm_ref_as_#name#`
|
||||||
|
|||||||
@@ -1,53 +1,27 @@
|
|||||||
use crate::host_ref::HostRef;
|
|
||||||
use crate::wasm_externkind_t;
|
use crate::wasm_externkind_t;
|
||||||
use crate::{wasm_externtype_t, wasm_func_t, wasm_global_t, wasm_memory_t, wasm_table_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)]
|
#[derive(Clone)]
|
||||||
pub struct wasm_extern_t {
|
pub struct wasm_extern_t {
|
||||||
pub(crate) which: ExternHost,
|
pub(crate) which: Extern,
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmtime_c_api_macros::declare_ref!(wasm_extern_t);
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t {
|
pub extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t {
|
||||||
match e.which {
|
match e.which {
|
||||||
ExternHost::Func(_) => crate::WASM_EXTERN_FUNC,
|
Extern::Func(_) => crate::WASM_EXTERN_FUNC,
|
||||||
ExternHost::Global(_) => crate::WASM_EXTERN_GLOBAL,
|
Extern::Global(_) => crate::WASM_EXTERN_GLOBAL,
|
||||||
ExternHost::Table(_) => crate::WASM_EXTERN_TABLE,
|
Extern::Table(_) => crate::WASM_EXTERN_TABLE,
|
||||||
ExternHost::Memory(_) => crate::WASM_EXTERN_MEMORY,
|
Extern::Memory(_) => crate::WASM_EXTERN_MEMORY,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box<wasm_externtype_t> {
|
pub extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box<wasm_externtype_t> {
|
||||||
let ty = match &e.which {
|
Box::new(wasm_externtype_t::new(e.which.ty()))
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -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_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 anyhow::anyhow;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::panic::{self, AssertUnwindSafe};
|
use std::panic::{self, AssertUnwindSafe};
|
||||||
@@ -59,29 +58,23 @@ impl Drop for Finalizer {
|
|||||||
impl wasm_func_t {
|
impl wasm_func_t {
|
||||||
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_func_t> {
|
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_func_t> {
|
||||||
match &e.which {
|
match &e.which {
|
||||||
ExternHost::Func(_) => Some(unsafe { &*(e as *const _ as *const _) }),
|
Extern::Func(_) => Some(unsafe { &*(e as *const _ as *const _) }),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn func(&self) -> &HostRef<Func> {
|
pub(crate) fn func(&self) -> &Func {
|
||||||
match &self.ext.which {
|
match &self.ext.which {
|
||||||
ExternHost::Func(f) => f,
|
Extern::Func(f) => f,
|
||||||
_ => unsafe { std::hint::unreachable_unchecked() },
|
_ => unsafe { std::hint::unreachable_unchecked() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn externref(&self) -> wasmtime::ExternRef {
|
|
||||||
self.func().clone().into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<HostRef<Func>> for wasm_func_t {
|
impl From<Func> for wasm_func_t {
|
||||||
fn from(func: HostRef<Func>) -> wasm_func_t {
|
fn from(func: Func) -> wasm_func_t {
|
||||||
wasm_func_t {
|
wasm_func_t {
|
||||||
ext: wasm_extern_t {
|
ext: wasm_extern_t { which: func.into() },
|
||||||
which: ExternHost::Func(func),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,14 +94,14 @@ fn create_function(
|
|||||||
let mut out_results = vec![wasm_val_t::default(); results.len()];
|
let mut out_results = vec![wasm_val_t::default(); results.len()];
|
||||||
let out = func(caller, params.as_ptr(), out_results.as_mut_ptr());
|
let out = func(caller, params.as_ptr(), out_results.as_mut_ptr());
|
||||||
if let Some(trap) = out {
|
if let Some(trap) = out {
|
||||||
return Err(trap.trap.borrow().clone());
|
return Err(trap.trap.clone());
|
||||||
}
|
}
|
||||||
for i in 0..results.len() {
|
for i in 0..results.len() {
|
||||||
results[i] = out_results[i].val();
|
results[i] = out_results[i].val();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
Box::new(HostRef::new(func).into())
|
Box::new(func.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -172,7 +165,7 @@ pub unsafe extern "C" fn wasm_func_call(
|
|||||||
args: *const wasm_val_t,
|
args: *const wasm_val_t,
|
||||||
results: *mut wasm_val_t,
|
results: *mut wasm_val_t,
|
||||||
) -> *mut wasm_trap_t {
|
) -> *mut wasm_trap_t {
|
||||||
let func = wasm_func.func().borrow();
|
let func = wasm_func.func();
|
||||||
let mut trap = ptr::null_mut();
|
let mut trap = ptr::null_mut();
|
||||||
let error = wasmtime_func_call(
|
let error = wasmtime_func_call(
|
||||||
wasm_func,
|
wasm_func,
|
||||||
@@ -211,7 +204,7 @@ fn _wasmtime_func_call(
|
|||||||
results: &mut [wasm_val_t],
|
results: &mut [wasm_val_t],
|
||||||
trap_ptr: &mut *mut wasm_trap_t,
|
trap_ptr: &mut *mut wasm_trap_t,
|
||||||
) -> Option<Box<wasmtime_error_t>> {
|
) -> Option<Box<wasmtime_error_t>> {
|
||||||
let func = func.func().borrow();
|
let func = func.func();
|
||||||
if results.len() != func.result_arity() {
|
if results.len() != func.result_arity() {
|
||||||
return Some(Box::new(anyhow!("wrong number of results provided").into()));
|
return Some(Box::new(anyhow!("wrong number of results provided").into()));
|
||||||
}
|
}
|
||||||
@@ -253,17 +246,17 @@ fn _wasmtime_func_call(
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_func_type(f: &wasm_func_t) -> Box<wasm_functype_t> {
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_func_param_arity(f: &wasm_func_t) -> usize {
|
pub extern "C" fn wasm_func_param_arity(f: &wasm_func_t) -> usize {
|
||||||
f.func().borrow().param_arity()
|
f.func().param_arity()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_func_result_arity(f: &wasm_func_t) -> usize {
|
pub extern "C" fn wasm_func_result_arity(f: &wasm_func_t) -> usize {
|
||||||
f.func().borrow().result_arity()
|
f.func().result_arity()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -277,12 +270,6 @@ pub extern "C" fn wasmtime_caller_export_get(
|
|||||||
name: &wasm_name_t,
|
name: &wasm_name_t,
|
||||||
) -> Option<Box<wasm_extern_t>> {
|
) -> Option<Box<wasm_extern_t>> {
|
||||||
let name = str::from_utf8(name.as_slice()).ok()?;
|
let name = str::from_utf8(name.as_slice()).ok()?;
|
||||||
let export = caller.caller.get_export(name)?;
|
let which = 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)),
|
|
||||||
};
|
|
||||||
Some(Box::new(wasm_extern_t { which }))
|
Some(Box::new(wasm_extern_t { which }))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use crate::host_ref::HostRef;
|
|
||||||
use crate::{handle_result, wasmtime_error_t};
|
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 std::ptr;
|
||||||
use wasmtime::Global;
|
use wasmtime::{Extern, Global};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
@@ -15,21 +14,17 @@ wasmtime_c_api_macros::declare_ref!(wasm_global_t);
|
|||||||
impl wasm_global_t {
|
impl wasm_global_t {
|
||||||
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_global_t> {
|
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_global_t> {
|
||||||
match &e.which {
|
match &e.which {
|
||||||
ExternHost::Global(_) => Some(unsafe { &*(e as *const _ as *const _) }),
|
Extern::Global(_) => Some(unsafe { &*(e as *const _ as *const _) }),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn global(&self) -> &HostRef<Global> {
|
fn global(&self) -> &Global {
|
||||||
match &self.ext.which {
|
match &self.ext.which {
|
||||||
ExternHost::Global(g) => g,
|
Extern::Global(g) => g,
|
||||||
_ => unsafe { std::hint::unreachable_unchecked() },
|
_ => unsafe { std::hint::unreachable_unchecked() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn externref(&self) -> wasmtime::ExternRef {
|
|
||||||
self.global().clone().into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -59,7 +54,7 @@ pub extern "C" fn wasmtime_global_new(
|
|||||||
handle_result(global, |global| {
|
handle_result(global, |global| {
|
||||||
*ret = Box::into_raw(Box::new(wasm_global_t {
|
*ret = Box::into_raw(Box::new(wasm_global_t {
|
||||||
ext: wasm_extern_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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_global_type(g: &wasm_global_t) -> Box<wasm_globaltype_t> {
|
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))
|
Box::new(wasm_globaltype_t::new(globaltype))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_global_get(g: &wasm_global_t, out: &mut wasm_val_t) {
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_global_set(g: &wasm_global_t, val: &wasm_val_t) {
|
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
|
// FIXME(WebAssembly/wasm-c-api#131) should communicate the error here
|
||||||
drop(result);
|
drop(result);
|
||||||
}
|
}
|
||||||
@@ -93,5 +88,5 @@ pub extern "C" fn wasmtime_global_set(
|
|||||||
g: &wasm_global_t,
|
g: &wasm_global_t,
|
||||||
val: &wasm_val_t,
|
val: &wasm_val_t,
|
||||||
) -> Option<Box<wasmtime_error_t>> {
|
) -> Option<Box<wasmtime_error_t>> {
|
||||||
handle_result(g.global().borrow().set(val.val()), |()| {})
|
handle_result(g.global().set(val.val()), |()| {})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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_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 anyhow::Result;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use wasmtime::{Extern, Instance, Trap};
|
use wasmtime::{Instance, Trap};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct wasm_instance_t {
|
pub struct wasm_instance_t {
|
||||||
pub(crate) instance: HostRef<Instance>,
|
pub(crate) instance: Instance,
|
||||||
exports_cache: RefCell<Option<Vec<ExternHost>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmtime_c_api_macros::declare_ref!(wasm_instance_t);
|
wasmtime_c_api_macros::declare_ref!(wasm_instance_t);
|
||||||
|
|
||||||
impl wasm_instance_t {
|
impl wasm_instance_t {
|
||||||
pub(crate) fn new(instance: Instance) -> wasm_instance_t {
|
pub(crate) fn new(instance: Instance) -> wasm_instance_t {
|
||||||
wasm_instance_t {
|
wasm_instance_t { instance: instance }
|
||||||
instance: HostRef::new(instance),
|
|
||||||
exports_cache: RefCell::new(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn externref(&self) -> wasmtime::ExternRef {
|
|
||||||
self.instance.clone().into()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,16 +89,10 @@ fn _wasmtime_instance_new(
|
|||||||
let store = &store.store;
|
let store = &store.store;
|
||||||
let imports = imports
|
let imports = imports
|
||||||
.iter()
|
.iter()
|
||||||
.map(|import| match &import.which {
|
.map(|import| import.which.clone())
|
||||||
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()),
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let module = &module.module.borrow();
|
|
||||||
handle_instantiate(
|
handle_instantiate(
|
||||||
Instance::new(store, module, &imports),
|
Instance::new(store, &module.module, &imports),
|
||||||
instance_ptr,
|
instance_ptr,
|
||||||
trap_ptr,
|
trap_ptr,
|
||||||
)
|
)
|
||||||
@@ -140,23 +124,15 @@ pub fn handle_instantiate(
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_instance_exports(instance: &wasm_instance_t, out: &mut wasm_extern_vec_t) {
|
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();
|
out.set_buffer(
|
||||||
let exports = cache.get_or_insert_with(|| {
|
|
||||||
let instance = &instance.instance.borrow();
|
|
||||||
instance
|
instance
|
||||||
|
.instance
|
||||||
.exports()
|
.exports()
|
||||||
.map(|e| match e.into_extern() {
|
.map(|e| {
|
||||||
Extern::Func(f) => ExternHost::Func(HostRef::new(f)),
|
Some(Box::new(wasm_extern_t {
|
||||||
Extern::Global(f) => ExternHost::Global(HostRef::new(f)),
|
which: e.into_extern(),
|
||||||
Extern::Memory(f) => ExternHost::Memory(HostRef::new(f)),
|
}))
|
||||||
Extern::Table(f) => ExternHost::Table(HostRef::new(f)),
|
|
||||||
})
|
})
|
||||||
.collect()
|
.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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ mod error;
|
|||||||
mod r#extern;
|
mod r#extern;
|
||||||
mod func;
|
mod func;
|
||||||
mod global;
|
mod global;
|
||||||
mod host_ref;
|
|
||||||
mod instance;
|
mod instance;
|
||||||
mod linker;
|
mod linker;
|
||||||
mod memory;
|
mod memory;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
use crate::host_ref::HostRef;
|
|
||||||
use crate::{bad_utf8, handle_result, wasmtime_error_t};
|
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 crate::{wasm_func_t, wasm_instance_t, wasm_module_t, wasm_name_t, wasm_trap_t};
|
||||||
use std::str;
|
use std::str;
|
||||||
use wasmtime::{Extern, Linker};
|
use wasmtime::Linker;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct wasmtime_linker_t {
|
pub struct wasmtime_linker_t {
|
||||||
@@ -44,12 +43,7 @@ pub extern "C" fn wasmtime_linker_define(
|
|||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => return bad_utf8(),
|
Err(_) => return bad_utf8(),
|
||||||
};
|
};
|
||||||
let item = match &item.which {
|
let item = item.which.clone();
|
||||||
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()),
|
|
||||||
};
|
|
||||||
handle_result(linker.define(module, name, item), |_linker| ())
|
handle_result(linker.define(module, name, item), |_linker| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,10 +68,7 @@ pub extern "C" fn wasmtime_linker_define_instance(
|
|||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => return bad_utf8(),
|
Err(_) => return bad_utf8(),
|
||||||
};
|
};
|
||||||
handle_result(
|
handle_result(linker.instance(name, &instance.instance), |_linker| ())
|
||||||
linker.instance(name, &instance.instance.borrow()),
|
|
||||||
|_linker| (),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -87,7 +78,7 @@ pub extern "C" fn wasmtime_linker_instantiate(
|
|||||||
instance_ptr: &mut *mut wasm_instance_t,
|
instance_ptr: &mut *mut wasm_instance_t,
|
||||||
trap_ptr: &mut *mut wasm_trap_t,
|
trap_ptr: &mut *mut wasm_trap_t,
|
||||||
) -> Option<Box<wasmtime_error_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)
|
super::instance::handle_instantiate(result, instance_ptr, trap_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +93,7 @@ pub extern "C" fn wasmtime_linker_module(
|
|||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => return bad_utf8(),
|
Err(_) => return bad_utf8(),
|
||||||
};
|
};
|
||||||
handle_result(linker.module(name, &module.module.borrow()), |_linker| ())
|
handle_result(linker.module(name, &module.module), |_linker| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -117,7 +108,7 @@ pub extern "C" fn wasmtime_linker_get_default(
|
|||||||
Err(_) => return bad_utf8(),
|
Err(_) => return bad_utf8(),
|
||||||
};
|
};
|
||||||
handle_result(linker.get_default(name), |f| {
|
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,
|
Ok(s) => s,
|
||||||
Err(_) => return bad_utf8(),
|
Err(_) => return bad_utf8(),
|
||||||
};
|
};
|
||||||
handle_result(linker.get_one_by_name(module, name), |item| {
|
handle_result(linker.get_one_by_name(module, name), |which| {
|
||||||
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)),
|
|
||||||
};
|
|
||||||
*item_ptr = Box::into_raw(Box::new(wasm_extern_t { which }))
|
*item_ptr = Box::into_raw(Box::new(wasm_extern_t { which }))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use crate::host_ref::HostRef;
|
use crate::{wasm_extern_t, wasm_memorytype_t, wasm_store_t};
|
||||||
use crate::{wasm_extern_t, wasm_memorytype_t, wasm_store_t, ExternHost};
|
use wasmtime::{Extern, Memory};
|
||||||
use wasmtime::Memory;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
@@ -15,21 +14,17 @@ pub type wasm_memory_pages_t = u32;
|
|||||||
impl wasm_memory_t {
|
impl wasm_memory_t {
|
||||||
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_memory_t> {
|
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_memory_t> {
|
||||||
match &e.which {
|
match &e.which {
|
||||||
ExternHost::Memory(_) => Some(unsafe { &*(e as *const _ as *const _) }),
|
Extern::Memory(_) => Some(unsafe { &*(e as *const _ as *const _) }),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn memory(&self) -> &HostRef<Memory> {
|
fn memory(&self) -> &Memory {
|
||||||
match &self.ext.which {
|
match &self.ext.which {
|
||||||
ExternHost::Memory(m) => m,
|
Extern::Memory(m) => m,
|
||||||
_ => unsafe { std::hint::unreachable_unchecked() },
|
_ => unsafe { std::hint::unreachable_unchecked() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn externref(&self) -> wasmtime::ExternRef {
|
|
||||||
self.memory().clone().into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -37,10 +32,10 @@ pub extern "C" fn wasm_memory_new(
|
|||||||
store: &wasm_store_t,
|
store: &wasm_store_t,
|
||||||
mt: &wasm_memorytype_t,
|
mt: &wasm_memorytype_t,
|
||||||
) -> Box<wasm_memory_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 {
|
Box::new(wasm_memory_t {
|
||||||
ext: wasm_extern_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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_memory_type(m: &wasm_memory_t) -> Box<wasm_memorytype_t> {
|
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))
|
Box::new(wasm_memorytype_t::new(ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_memory_data(m: &wasm_memory_t) -> *mut u8 {
|
pub extern "C" fn wasm_memory_data(m: &wasm_memory_t) -> *mut u8 {
|
||||||
m.memory().borrow().data_ptr()
|
m.memory().data_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_memory_data_size(m: &wasm_memory_t) -> usize {
|
pub extern "C" fn wasm_memory_data_size(m: &wasm_memory_t) -> usize {
|
||||||
m.memory().borrow().data_size()
|
m.memory().data_size()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_memory_size(m: &wasm_memory_t) -> wasm_memory_pages_t {
|
pub extern "C" fn wasm_memory_size(m: &wasm_memory_t) -> wasm_memory_pages_t {
|
||||||
m.memory().borrow().size()
|
m.memory().size()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_memory_grow(m: &wasm_memory_t, delta: wasm_memory_pages_t) -> bool {
|
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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use crate::host_ref::HostRef;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
handle_result, wasm_byte_vec_t, wasm_exporttype_t, wasm_exporttype_vec_t, wasm_importtype_t,
|
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,
|
wasm_importtype_vec_t, wasm_store_t, wasmtime_error_t,
|
||||||
@@ -9,19 +8,13 @@ use wasmtime::{Engine, Module};
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct wasm_module_t {
|
pub struct wasm_module_t {
|
||||||
pub(crate) module: HostRef<Module>,
|
pub(crate) module: Module,
|
||||||
pub(crate) imports: Vec<wasm_importtype_t>,
|
pub(crate) imports: Vec<wasm_importtype_t>,
|
||||||
pub(crate) exports: Vec<wasm_exporttype_t>,
|
pub(crate) exports: Vec<wasm_exporttype_t>,
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmtime_c_api_macros::declare_ref!(wasm_module_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)]
|
#[repr(C)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct wasm_shared_module_t {
|
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()))
|
.map(|e| wasm_exporttype_t::new(e.name().to_owned(), e.ty()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let module = Box::new(wasm_module_t {
|
let module = Box::new(wasm_module_t {
|
||||||
module: HostRef::new(module),
|
module: module,
|
||||||
imports,
|
imports,
|
||||||
exports,
|
exports,
|
||||||
});
|
});
|
||||||
@@ -108,7 +101,7 @@ pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_imp
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> {
|
pub extern "C" fn wasm_module_share(module: &wasm_module_t) -> Box<wasm_shared_module_t> {
|
||||||
Box::new(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()))
|
.map(|e| wasm_exporttype_t::new(e.name().to_owned(), e.ty()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
Some(Box::new(wasm_module_t {
|
Some(Box::new(wasm_module_t {
|
||||||
module: HostRef::new(module),
|
module: module,
|
||||||
imports,
|
imports,
|
||||||
exports,
|
exports,
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use crate::host_ref::HostRef;
|
|
||||||
use crate::{handle_result, wasm_func_t, wasm_ref_t, wasmtime_error_t};
|
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 std::ptr;
|
||||||
use wasmtime::{Table, Val};
|
use wasmtime::{Extern, Table, Val};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
@@ -17,21 +16,17 @@ pub type wasm_table_size_t = u32;
|
|||||||
impl wasm_table_t {
|
impl wasm_table_t {
|
||||||
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_table_t> {
|
pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_table_t> {
|
||||||
match &e.which {
|
match &e.which {
|
||||||
ExternHost::Table(_) => Some(unsafe { &*(e as *const _ as *const _) }),
|
Extern::Table(_) => Some(unsafe { &*(e as *const _ as *const _) }),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table(&self) -> &HostRef<Table> {
|
fn table(&self) -> &Table {
|
||||||
match &self.ext.which {
|
match &self.ext.which {
|
||||||
ExternHost::Table(t) => t,
|
Extern::Table(t) => t,
|
||||||
_ => unsafe { std::hint::unreachable_unchecked() },
|
_ => unsafe { std::hint::unreachable_unchecked() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn externref(&self) -> wasmtime::ExternRef {
|
|
||||||
self.table().clone().into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[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()?;
|
let table = Table::new(&store.store, tt.ty().ty.clone(), init).ok()?;
|
||||||
Some(Box::new(wasm_table_t {
|
Some(Box::new(wasm_table_t {
|
||||||
ext: wasm_extern_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,
|
out: &mut *mut wasm_table_t,
|
||||||
) -> Option<Box<wasmtime_error_t>> {
|
) -> Option<Box<wasmtime_error_t>> {
|
||||||
let init: Val = match init {
|
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),
|
None => Val::FuncRef(None),
|
||||||
};
|
};
|
||||||
handle_result(
|
handle_result(
|
||||||
@@ -68,7 +63,7 @@ pub extern "C" fn wasmtime_funcref_table_new(
|
|||||||
|table| {
|
|table| {
|
||||||
*out = Box::into_raw(Box::new(wasm_table_t {
|
*out = Box::into_raw(Box::new(wasm_table_t {
|
||||||
ext: wasm_extern_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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_table_type(t: &wasm_table_t) -> Box<wasm_tabletype_t> {
|
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))
|
Box::new(wasm_tabletype_t::new(ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_table_get(t: &wasm_table_t, index: wasm_table_size_t) -> *mut wasm_ref_t {
|
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),
|
Some(val) => into_funcref(val),
|
||||||
None => into_funcref(Val::FuncRef(None)),
|
None => into_funcref(Val::FuncRef(None)),
|
||||||
}
|
}
|
||||||
@@ -95,12 +90,11 @@ pub extern "C" fn wasmtime_funcref_table_get(
|
|||||||
index: wasm_table_size_t,
|
index: wasm_table_size_t,
|
||||||
ptr: &mut *mut wasm_func_t,
|
ptr: &mut *mut wasm_func_t,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match t.table().borrow().get(index) {
|
match t.table().get(index) {
|
||||||
Some(val) => {
|
Some(val) => {
|
||||||
*ptr = match val {
|
*ptr = match val {
|
||||||
// TODO: what do do about creating new `HostRef` handles here?
|
|
||||||
Val::FuncRef(None) => ptr::null_mut(),
|
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,
|
_ => return false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -117,7 +111,7 @@ pub unsafe extern "C" fn wasm_table_set(
|
|||||||
r: *mut wasm_ref_t,
|
r: *mut wasm_ref_t,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let val = from_funcref(r);
|
let val = from_funcref(r);
|
||||||
t.table().borrow().set(index, val).is_ok()
|
t.table().set(index, val).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -127,10 +121,10 @@ pub extern "C" fn wasmtime_funcref_table_set(
|
|||||||
val: Option<&wasm_func_t>,
|
val: Option<&wasm_func_t>,
|
||||||
) -> Option<Box<wasmtime_error_t>> {
|
) -> Option<Box<wasmtime_error_t>> {
|
||||||
let val = match val {
|
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),
|
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 {
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_table_size(t: &wasm_table_t) -> wasm_table_size_t {
|
pub extern "C" fn wasm_table_size(t: &wasm_table_t) -> wasm_table_size_t {
|
||||||
t.table().borrow().size()
|
t.table().size()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -165,7 +159,7 @@ pub unsafe extern "C" fn wasm_table_grow(
|
|||||||
init: *mut wasm_ref_t,
|
init: *mut wasm_ref_t,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let init = from_funcref(init);
|
let init = from_funcref(init);
|
||||||
t.table().borrow().grow(delta, init).is_ok()
|
t.table().grow(delta, init).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -176,10 +170,10 @@ pub extern "C" fn wasmtime_funcref_table_grow(
|
|||||||
prev_size: Option<&mut wasm_table_size_t>,
|
prev_size: Option<&mut wasm_table_size_t>,
|
||||||
) -> Option<Box<wasmtime_error_t>> {
|
) -> Option<Box<wasmtime_error_t>> {
|
||||||
let val = match init {
|
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),
|
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 {
|
if let Some(ptr) = prev_size {
|
||||||
*ptr = prev;
|
*ptr = prev;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 crate::{wasm_frame_vec_t, wasm_instance_t, wasm_name_t, wasm_store_t};
|
||||||
use once_cell::unsync::OnceCell;
|
use once_cell::unsync::OnceCell;
|
||||||
use wasmtime::Trap;
|
use wasmtime::Trap;
|
||||||
@@ -6,27 +5,21 @@ use wasmtime::Trap;
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct wasm_trap_t {
|
pub struct wasm_trap_t {
|
||||||
pub(crate) trap: HostRef<Trap>,
|
pub(crate) trap: Trap,
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmtime_c_api_macros::declare_ref!(wasm_trap_t);
|
wasmtime_c_api_macros::declare_ref!(wasm_trap_t);
|
||||||
|
|
||||||
impl wasm_trap_t {
|
impl wasm_trap_t {
|
||||||
pub(crate) fn new(trap: Trap) -> wasm_trap_t {
|
pub(crate) fn new(trap: Trap) -> wasm_trap_t {
|
||||||
wasm_trap_t {
|
wasm_trap_t { trap: trap }
|
||||||
trap: HostRef::new(trap),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn externref(&self) -> wasmtime::ExternRef {
|
|
||||||
self.trap.clone().into()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct wasm_frame_t {
|
pub struct wasm_frame_t {
|
||||||
trap: HostRef<Trap>,
|
trap: Trap,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
func_name: OnceCell<Option<wasm_name_t>>,
|
func_name: OnceCell<Option<wasm_name_t>>,
|
||||||
module_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]);
|
let message = String::from_utf8_lossy(&message[..message.len() - 1]);
|
||||||
Box::new(wasm_trap_t {
|
Box::new(wasm_trap_t {
|
||||||
trap: HostRef::new(Trap::new(message)),
|
trap: Trap::new(message),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_trap_message(trap: &wasm_trap_t, out: &mut wasm_message_t) {
|
pub extern "C" fn wasm_trap_message(trap: &wasm_trap_t, out: &mut wasm_message_t) {
|
||||||
let mut buffer = Vec::new();
|
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.reserve_exact(1);
|
||||||
buffer.push(0);
|
buffer.push(0);
|
||||||
out.set_buffer(buffer);
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option<Box<wasm_frame_t>> {
|
pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option<Box<wasm_frame_t>> {
|
||||||
let trap = raw.trap.borrow();
|
if raw.trap.trace().len() > 0 {
|
||||||
if trap.trace().len() > 0 {
|
|
||||||
Some(Box::new(wasm_frame_t {
|
Some(Box::new(wasm_frame_t {
|
||||||
trap: raw.trap.clone(),
|
trap: raw.trap.clone(),
|
||||||
idx: 0,
|
idx: 0,
|
||||||
@@ -77,8 +69,7 @@ pub extern "C" fn wasm_trap_origin(raw: &wasm_trap_t) -> Option<Box<wasm_frame_t
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_trap_trace(raw: &wasm_trap_t, out: &mut wasm_frame_vec_t) {
|
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..raw.trap.trace().len())
|
||||||
let vec = (0..trap.trace().len())
|
|
||||||
.map(|idx| {
|
.map(|idx| {
|
||||||
Some(Box::new(wasm_frame_t {
|
Some(Box::new(wasm_frame_t {
|
||||||
trap: raw.trap.clone(),
|
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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmtime_trap_exit_status(raw: &wasm_trap_t, status: &mut i32) -> bool {
|
pub extern "C" fn wasmtime_trap_exit_status(raw: &wasm_trap_t, status: &mut i32) -> bool {
|
||||||
let trap = raw.trap.borrow();
|
match raw.trap.i32_exit_status() {
|
||||||
match trap.i32_exit_status() {
|
|
||||||
Some(i) => {
|
Some(i) => {
|
||||||
*status = i;
|
*status = i;
|
||||||
true
|
true
|
||||||
@@ -105,7 +95,7 @@ pub extern "C" fn wasmtime_trap_exit_status(raw: &wasm_trap_t, status: &mut i32)
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_frame_func_index(frame: &wasm_frame_t) -> u32 {
|
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]
|
#[no_mangle]
|
||||||
@@ -113,8 +103,7 @@ pub extern "C" fn wasmtime_frame_func_name(frame: &wasm_frame_t) -> Option<&wasm
|
|||||||
frame
|
frame
|
||||||
.func_name
|
.func_name
|
||||||
.get_or_init(|| {
|
.get_or_init(|| {
|
||||||
let trap = frame.trap.borrow();
|
frame.trap.trace()[frame.idx]
|
||||||
trap.trace()[frame.idx]
|
|
||||||
.func_name()
|
.func_name()
|
||||||
.map(|s| wasm_name_t::from(s.to_string().into_bytes()))
|
.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
|
frame
|
||||||
.module_name
|
.module_name
|
||||||
.get_or_init(|| {
|
.get_or_init(|| {
|
||||||
let trap = frame.trap.borrow();
|
frame.trap.trace()[frame.idx]
|
||||||
trap.trace()[frame.idx]
|
|
||||||
.module_name()
|
.module_name()
|
||||||
.map(|s| wasm_name_t::from(s.to_string().into_bytes()))
|
.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]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_frame_func_offset(frame: &wasm_frame_t) -> usize {
|
pub extern "C" fn wasm_frame_func_offset(frame: &wasm_frame_t) -> usize {
|
||||||
let trap = frame.trap.borrow();
|
frame.trap.trace()[frame.idx].func_offset()
|
||||||
trap.trace()[frame.idx].func_offset()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -147,6 +134,5 @@ pub extern "C" fn wasm_frame_instance(_arg1: *const wasm_frame_t) -> *mut wasm_i
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasm_frame_module_offset(frame: &wasm_frame_t) -> usize {
|
pub extern "C" fn wasm_frame_module_offset(frame: &wasm_frame_t) -> usize {
|
||||||
let trap = frame.trap.borrow();
|
frame.trap.trace()[frame.idx].module_offset()
|
||||||
trap.trace()[frame.idx].module_offset()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
//! The WASI embedding API definitions for Wasmtime.
|
//! 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};
|
||||||
use crate::{wasm_extern_t, wasm_importtype_t, wasm_store_t, wasm_trap_t, ExternHost};
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
@@ -13,7 +12,7 @@ use wasi_common::{
|
|||||||
old::snapshot_0::WasiCtxBuilder as WasiSnapshot0CtxBuilder, preopen_dir,
|
old::snapshot_0::WasiCtxBuilder as WasiSnapshot0CtxBuilder, preopen_dir,
|
||||||
WasiCtxBuilder as WasiPreview1CtxBuilder,
|
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};
|
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> {
|
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(),
|
export_cache: HashMap::new(),
|
||||||
})),
|
})),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
*trap = Box::into_raw(Box::new(wasm_trap_t {
|
*trap = Box::into_raw(Box::new(wasm_trap_t { trap: Trap::new(e) }));
|
||||||
trap: HostRef::new(Trap::new(e)),
|
|
||||||
}));
|
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -358,7 +355,7 @@ pub extern "C" fn wasi_instance_bind_import<'a>(
|
|||||||
.entry(name.to_string())
|
.entry(name.to_string())
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
Box::new(wasm_extern_t {
|
Box::new(wasm_extern_t {
|
||||||
which: ExternHost::Func(HostRef::new(export.clone())),
|
which: Extern::Func(export.clone()),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
Some(entry)
|
Some(entry)
|
||||||
|
|||||||
@@ -185,7 +185,6 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
// Try cloning.
|
// Try cloning.
|
||||||
wasm_memory_t* copy = wasm_memory_copy(memory);
|
wasm_memory_t* copy = wasm_memory_copy(memory);
|
||||||
assert(wasm_memory_same(memory, copy));
|
|
||||||
wasm_memory_delete(copy);
|
wasm_memory_delete(copy);
|
||||||
|
|
||||||
// Check initial memory.
|
// Check initial memory.
|
||||||
|
|||||||
Reference in New Issue
Block a user