Remove HostRef from the wasmtime public API (#788)

* Remove `HostRef` from the `wasmtime` public API

This commit removes all remaining usages of `HostRef` in the public API
of the `wasmtime` crate. This involved a number of API decisions such
as:

* None of `Func`, `Global`, `Table`, or `Memory` are wrapped in `HostRef`
* All of `Func`, `Global`, `Table`, and `Memory` implement `Clone` now.
* Methods called `type` are renamed to `ty` to avoid typing `r#type`.
* Methods requiring mutability for external items now no longer require
  mutability. The mutable reference here is sort of a lie anyway since
  the internals are aliased by the underlying module anyway. This
  affects:
  * `Table::set`
  * `Table::grow`
  * `Memory::grow`
  * `Instance::set_signal_handler`
* The `Val::FuncRef` type is now no longer automatically coerced to
  `AnyRef`. This is technically a breaking change which is pretty bad,
  but I'm hoping that we can live with this interim state while we sort
  out the `AnyRef` story in general.
* The implementation of the C API was refactored and updated in a few
  locations to account for these changes:
  * Accessing the exports of an instance are now cached to ensure we
    always hand out the same `HostRef` values.
  * `wasm_*_t` for external values no longer have internal cache,
    instead they all wrap `wasm_external_t` and have an unchecked
    accessor for the underlying variant (since the type is proof that
    it's there). This makes casting back and forth much more trivial.

This is all related to #708 and while there's still more work to be done
in terms of documentation, this is the major bulk of the rest of the
implementation work on #708 I believe.

* More API updates

* Run rustfmt

* Fix a doc test

* More test updates
This commit is contained in:
Alex Crichton
2020-01-10 10:42:14 -06:00
committed by GitHub
parent 068c249439
commit 6571fb8f4f
25 changed files with 435 additions and 489 deletions

View File

@@ -10,17 +10,16 @@ use wasmtime_interface_types::ModuleData;
// TODO support non-export functions
#[pyclass]
pub struct Function {
pub instance: wasmtime::HostRef<wasmtime::Instance>,
pub instance: wasmtime::Instance,
pub export_name: String,
pub args_types: Vec<wasmtime::ValType>,
pub data: Rc<ModuleData>,
}
impl Function {
pub fn func(&self) -> wasmtime::HostRef<wasmtime::Func> {
pub fn func(&self) -> wasmtime::Func {
let e = self
.instance
.borrow()
.find_export_by_name(&self.export_name)
.expect("named export")
.clone();
@@ -125,10 +124,7 @@ impl wasmtime::Callable for WrappedFn {
}
}
pub fn wrap_into_pyfunction(
store: &wasmtime::Store,
callable: &PyAny,
) -> PyResult<wasmtime::HostRef<wasmtime::Func>> {
pub fn wrap_into_pyfunction(store: &wasmtime::Store, callable: &PyAny) -> PyResult<wasmtime::Func> {
if !callable.hasattr("__annotations__")? {
// TODO support calls without annotations?
return Err(PyErr::new::<Exception, _>(
@@ -154,6 +150,5 @@ pub fn wrap_into_pyfunction(
let gil = Python::acquire_gil();
let wrapped = WrappedFn::new(callable.to_object(gil.python()), returns);
let f = wasmtime::Func::new(store, ft, Rc::new(wrapped));
Ok(wasmtime::HostRef::new(f))
Ok(wasmtime::Func::new(store, ft, Rc::new(wrapped)))
}

View File

@@ -9,7 +9,7 @@ use wasmtime_interface_types::ModuleData;
#[pyclass]
pub struct Instance {
pub instance: wasmtime::HostRef<wasmtime::Instance>,
pub instance: wasmtime::Instance,
pub data: Rc<ModuleData>,
}
@@ -20,7 +20,7 @@ impl Instance {
let gil = Python::acquire_gil();
let py = gil.python();
let exports = PyDict::new(py);
let module = self.instance.borrow().module().clone();
let module = self.instance.module().clone();
for (i, e) in module.exports().iter().enumerate() {
match e.ty() {
wasmtime::ExternType::Func(ft) => {
@@ -43,10 +43,7 @@ impl Instance {
let f = Py::new(
py,
Memory {
memory: self.instance.borrow().exports()[i]
.memory()
.unwrap()
.clone(),
memory: self.instance.exports()[i].memory().unwrap().clone(),
},
)?;
exports.set_item(e.name().to_string(), f)?;

View File

@@ -122,10 +122,8 @@ pub fn instantiate(
}
}
let instance = wasmtime::HostRef::new(
wasmtime::Instance::new(&store, &module, &imports)
.map_err(|t| PyErr::new::<Exception, _>(format!("instantiated with trap {:?}", t)))?,
);
let instance = wasmtime::Instance::new(&store, &module, &imports)
.map_err(|t| PyErr::new::<Exception, _>(format!("instantiated with trap {:?}", t)))?;
let module = Py::new(py, Module { module })?;

View File

@@ -10,14 +10,14 @@ use std::ptr;
#[pyclass]
pub struct Memory {
pub memory: wasmtime::HostRef<wasmtime::Memory>,
pub memory: wasmtime::Memory,
}
#[pymethods]
impl Memory {
#[getter(current)]
pub fn current(&self) -> u32 {
self.memory.borrow().size()
self.memory.size()
}
pub fn grow(&self, _number: u32) -> u32 {
@@ -48,8 +48,8 @@ impl PyBufferProtocol for Memory {
};
unsafe {
let base = self.memory.borrow().data_ptr();
let current_length = self.memory.borrow().data_size();
let base = self.memory.data_ptr();
let current_length = self.memory.data_size();
(*view).buf = base as *mut c_void;
(*view).len = current_length as isize;

View File

@@ -34,7 +34,7 @@ fn generate_struct(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
let root = root();
Ok(quote! {
#vis struct #name {
instance: #root::wasmtime::HostRef<#root::wasmtime::Instance>,
instance: #root::wasmtime::Instance,
data: #root::wasmtime_interface_types::ModuleData,
}
})
@@ -48,7 +48,7 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
#vis fn load_file(path: impl AsRef<std::path::Path>) -> #root::anyhow::Result<#name> {
let bytes = std::fs::read(path)?;
use #root::wasmtime::{HostRef, Config, Extern, Engine, Store, Instance, Module};
use #root::wasmtime::{Config, Extern, Engine, Store, Instance, Module};
use #root::anyhow::{bail, format_err};
let engine = Engine::new(Config::new().wasm_multi_value(true));
@@ -74,9 +74,8 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
}
}
}
let instance = HostRef::new(
Instance::new(&store, &module, &imports).map_err(|t| format_err!("instantiation trap: {:?}", t))?
);
let instance =
Instance::new(&store, &module, &imports).map_err(|t| format_err!("instantiation trap: {:?}", t))?;
Ok(#name { instance, data })
}