Remove the need for HostRef<Store> (#771)

* Remove the need for `HostRef<Store>`

This commit goes through the public API of the `wasmtime` crate and
removes the need for `HostRef<Store>`, as discussed in #708. This commit
is accompanied with a few changes:

* The `Store` type now also implements `Default`, creating a new
  `Engine` with default settings and returning that.

* The `Store` type now implements `Clone`, and is documented as being a
  "cheap clone" aka being reference counted. As before there is no
  supported way to create a deep clone of a `Store`.

* All APIs take/return `&Store` or `Store` instead of `HostRef<Store>`,
  and `HostRef<T>` is left as purely a detail of the C API.

* The `global_exports` function is tagged as `#[doc(hidden)]` for now
  while we await its removal.

* The `Store` type is not yet `Send` nor `Sync` due to the usage of
  `global_exports`, but it is intended to become so eventually.

* Touch up comments on some examples

* Run rustfmt
This commit is contained in:
Alex Crichton
2020-01-07 16:29:44 -06:00
committed by GitHub
parent 296ebc46fd
commit 045d6a7310
31 changed files with 163 additions and 155 deletions

View File

@@ -288,12 +288,13 @@ pub enum OptLevel {
///
/// Using `clone` on an `Engine` is a cheap operation. It will not create an
/// entirely new engine, but rather just a new reference to the existing engine.
/// In other words it's a shallow copy, not a deep copy.
///
/// ## Engines and `Default`
///
/// You can create an engine with default settings using `Engine::default()`.
/// This engine will not have any unstable wasm features enabled and will use
/// the default compilation backend configured at this crate's compile time.
/// You can create an engine with default configuration settings using
/// `Engine::default()`. Be sure to consult the documentation of [`Config`] for
/// default settings.
#[derive(Default, Clone)]
pub struct Engine {
pub(crate) config: Arc<Config>,
@@ -311,45 +312,72 @@ impl Engine {
// Store
/// A `Store` is a shared cache of information between WebAssembly modules.
///
/// Each `Module` is compiled into a `Store` and a `Store` is associated with an
/// [`Engine`]. You'll use a `Store` to attach to a number of global items in
/// the production of various items for wasm modules.
///
/// # Stores and `Clone`
///
/// Using `clone` on a `Store` is a cheap operation. It will not create an
/// entirely new store, but rather just a new reference to the existing object.
/// In other words it's a shallow copy, not a deep copy.
///
/// ## Stores and `Default`
///
/// You can create a store with default configuration settings using
/// `Store::default()`. This will create a brand new [`Engine`] with default
/// ocnfiguration (see [`Config`] for more information).
#[derive(Clone)]
pub struct Store {
inner: Rc<StoreInner>,
}
struct StoreInner {
engine: Engine,
context: Context,
global_exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>,
signature_cache: HashMap<wasmtime_runtime::VMSharedSignatureIndex, ir::Signature>,
signature_cache: RefCell<HashMap<wasmtime_runtime::VMSharedSignatureIndex, ir::Signature>>,
}
impl Store {
/// Creates a new store to be associated with the given [`Engine`].
pub fn new(engine: &Engine) -> Store {
Store {
engine: engine.clone(),
context: Context::new(&engine.config),
global_exports: Rc::new(RefCell::new(HashMap::new())),
signature_cache: HashMap::new(),
inner: Rc::new(StoreInner {
engine: engine.clone(),
context: Context::new(&engine.config),
global_exports: Rc::new(RefCell::new(HashMap::new())),
signature_cache: RefCell::new(HashMap::new()),
}),
}
}
/// Returns the [`Engine`] that this store is associated with.
pub fn engine(&self) -> &Engine {
&self.engine
&self.inner.engine
}
pub(crate) fn context(&mut self) -> &mut Context {
&mut self.context
pub(crate) fn context(&self) -> &Context {
&self.inner.context
}
// Specific to wasmtime: hack to pass memory around to wasi
#[doc(hidden)]
pub fn global_exports(
&self,
) -> &Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>> {
&self.global_exports
&self.inner.global_exports
}
pub(crate) fn register_wasmtime_signature(
&mut self,
&self,
signature: &ir::Signature,
) -> wasmtime_runtime::VMSharedSignatureIndex {
use std::collections::hash_map::Entry;
let index = self.context().compiler().signatures().register(signature);
match self.signature_cache.entry(index) {
match self.inner.signature_cache.borrow_mut().entry(index) {
Entry::Vacant(v) => {
v.insert(signature.clone());
}
@@ -361,8 +389,18 @@ impl Store {
pub(crate) fn lookup_wasmtime_signature(
&self,
type_index: wasmtime_runtime::VMSharedSignatureIndex,
) -> Option<&ir::Signature> {
self.signature_cache.get(&type_index)
) -> Option<ir::Signature> {
self.inner
.signature_cache
.borrow()
.get(&type_index)
.cloned()
}
}
impl Default for Store {
fn default() -> Store {
Store::new(&Engine::default())
}
}