Move HostRef<T> into the C API crate

It isn't used by anything except for the C API and all of our embedder-exposed
APIs are already internally `Rc`-based, so it doesn't make sense to use with
them.
This commit is contained in:
Nick Fitzgerald
2020-06-01 14:48:45 -07:00
parent 8adae5d1ad
commit 58b08b9d3a
14 changed files with 124 additions and 110 deletions

View File

@@ -1,6 +1,7 @@
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, HostRef, Memory, Table}; use wasmtime::{ExternType, Func, Global, Memory, Table};
#[derive(Clone)] #[derive(Clone)]
pub struct wasm_extern_t { pub struct wasm_extern_t {

View File

@@ -1,3 +1,4 @@
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, ExternHost};
use anyhow::anyhow; use anyhow::anyhow;
@@ -5,7 +6,7 @@ use std::ffi::c_void;
use std::panic::{self, AssertUnwindSafe}; use std::panic::{self, AssertUnwindSafe};
use std::ptr; use std::ptr;
use std::str; use std::str;
use wasmtime::{Caller, Extern, Func, HostRef, Trap}; use wasmtime::{Caller, Extern, Func, Trap};
#[derive(Clone)] #[derive(Clone)]
#[repr(transparent)] #[repr(transparent)]

View File

@@ -1,7 +1,8 @@
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, ExternHost};
use std::ptr; use std::ptr;
use wasmtime::{Global, HostRef}; use wasmtime::Global;
#[derive(Clone)] #[derive(Clone)]
#[repr(transparent)] #[repr(transparent)]

View File

@@ -0,0 +1,101 @@
use std::any::Any;
use std::cell::{self, RefCell};
use std::convert::TryFrom;
use std::marker::PhantomData;
use wasmtime::{ExternRef, Store};
/// 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(store: &Store, item: T) -> HostRef<T> {
HostRef {
externref: ExternRef::new(store, 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,9 +1,10 @@
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, ExternHost};
use anyhow::Result; use anyhow::Result;
use std::cell::RefCell; use std::cell::RefCell;
use std::ptr; use std::ptr;
use wasmtime::{Extern, HostRef, Instance, Store, Trap}; use wasmtime::{Extern, Instance, Store, Trap};
#[repr(C)] #[repr(C)]
#[derive(Clone)] #[derive(Clone)]

View File

@@ -11,6 +11,7 @@ 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;

View File

@@ -1,8 +1,9 @@
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, ExternHost};
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, HostRef, Linker}; use wasmtime::{Extern, Linker};
#[repr(C)] #[repr(C)]
pub struct wasmtime_linker_t { pub struct wasmtime_linker_t {

View File

@@ -1,5 +1,6 @@
use crate::host_ref::HostRef;
use crate::{wasm_extern_t, wasm_memorytype_t, wasm_store_t, ExternHost}; use crate::{wasm_extern_t, wasm_memorytype_t, wasm_store_t, ExternHost};
use wasmtime::{HostRef, Memory}; use wasmtime::Memory;
#[derive(Clone)] #[derive(Clone)]
#[repr(transparent)] #[repr(transparent)]

View File

@@ -1,8 +1,9 @@
use crate::host_ref::HostRef;
use crate::{handle_result, wasmtime_error_t}; use crate::{handle_result, wasmtime_error_t};
use crate::{wasm_byte_vec_t, wasm_exporttype_vec_t, wasm_importtype_vec_t}; use crate::{wasm_byte_vec_t, wasm_exporttype_vec_t, wasm_importtype_vec_t};
use crate::{wasm_exporttype_t, wasm_importtype_t, wasm_store_t}; use crate::{wasm_exporttype_t, wasm_importtype_t, wasm_store_t};
use std::ptr; use std::ptr;
use wasmtime::{HostRef, Module}; use wasmtime::Module;
#[repr(C)] #[repr(C)]
#[derive(Clone)] #[derive(Clone)]

View File

@@ -1,7 +1,8 @@
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, ExternHost};
use std::ptr; use std::ptr;
use wasmtime::{HostRef, Table, Val}; use wasmtime::{Table, Val};
#[derive(Clone)] #[derive(Clone)]
#[repr(transparent)] #[repr(transparent)]

View File

@@ -1,6 +1,7 @@
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::{HostRef, Store, Trap}; use wasmtime::{Store, Trap};
#[repr(C)] #[repr(C)]
#[derive(Clone)] #[derive(Clone)]

View File

@@ -1,4 +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, ExternHost}; 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;
@@ -12,7 +13,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::{HostRef, Linker, Store, Trap}; use wasmtime::{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> {

View File

@@ -29,7 +29,7 @@ pub use crate::func::*;
pub use crate::instance::Instance; pub use crate::instance::Instance;
pub use crate::linker::*; pub use crate::linker::*;
pub use crate::module::Module; pub use crate::module::Module;
pub use crate::r#ref::{ExternRef, HostRef}; pub use crate::r#ref::ExternRef;
pub use crate::runtime::*; pub use crate::runtime::*;
pub use crate::trap::Trap; pub use crate::trap::Trap;
pub use crate::types::*; pub use crate::types::*;

View File

@@ -1,10 +1,8 @@
#![allow(missing_docs)] #![allow(missing_docs)]
use std::any::Any; use std::any::Any;
use std::cell::{self, RefCell}; use std::cell::RefCell;
use std::convert::TryFrom;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use wasmtime_runtime::VMExternRef; use wasmtime_runtime::VMExternRef;
@@ -81,99 +79,3 @@ impl fmt::Debug for ExternRef {
.finish() .finish()
} }
} }
/// 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(store: &crate::Store, item: T) -> HostRef<T> {
HostRef {
externref: ExternRef::new(store, 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
.inner
.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.inner.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,
}
}
}