diff --git a/crates/api/examples/gcd.rs b/crates/api/examples/gcd.rs index 93313cb708..c510a176ca 100644 --- a/crates/api/examples/gcd.rs +++ b/crates/api/examples/gcd.rs @@ -54,7 +54,7 @@ fn main() -> anyhow::Result<()> { // Invoke `gcd` export let gcd = instance.exports()[gcd_index].func().expect("gcd"); - let result = gcd.borrow().call(&[Val::from(6i32), Val::from(27i32)])?; + let result = gcd.call(&[Val::from(6i32), Val::from(27i32)])?; println!("{:?}", result); Ok(()) diff --git a/crates/api/examples/hello.rs b/crates/api/examples/hello.rs index 5caaa75af6..8924dfcb7d 100644 --- a/crates/api/examples/hello.rs +++ b/crates/api/examples/hello.rs @@ -41,15 +41,15 @@ fn main() -> Result<()> { // `HelloCallback` type and its associated implementation of `Callback. println!("Creating callback..."); let hello_type = FuncType::new(Box::new([]), Box::new([])); - let hello_func = HostRef::new(Func::new(&store, hello_type, Rc::new(HelloCallback))); + let hello_func = Func::new(&store, hello_type, Rc::new(HelloCallback)); // Once we've got that all set up we can then move to the instantiation // phase, pairing together a compiled module as well as a set of imports. // Note that this is where the wasm `start` function, if any, would run. println!("Instantiating module..."); let imports = vec![hello_func.into()]; - let instance = Instance::new(&store, &module, imports.as_slice()) - .context("> Error instantiating module!")?; + let instance = + Instance::new(&store, &module, &imports).context("> Error instantiating module!")?; // Next we poke around a bit to extract the `run` function from the module. println!("Extracting export..."); @@ -59,7 +59,7 @@ fn main() -> Result<()> { // And last but not least we can call it! println!("Calling export..."); - run_func.borrow().call(&[])?; + run_func.call(&[])?; println!("Done."); Ok(()) diff --git a/crates/api/examples/memory.rs b/crates/api/examples/memory.rs index bd7d0be21a..f9df469669 100644 --- a/crates/api/examples/memory.rs +++ b/crates/api/examples/memory.rs @@ -3,7 +3,7 @@ use anyhow::{bail, ensure, Context as _, Error}; use wasmtime::*; -fn get_export_memory(exports: &[Extern], i: usize) -> Result, Error> { +fn get_export_memory(exports: &[Extern], i: usize) -> Result { if exports.len() <= i { bail!("> Error accessing memory export {}!", i); } @@ -13,7 +13,7 @@ fn get_export_memory(exports: &[Extern], i: usize) -> Result, Er .clone()) } -fn get_export_func(exports: &[Extern], i: usize) -> Result, Error> { +fn get_export_func(exports: &[Extern], i: usize) -> Result { if exports.len() <= i { bail!("> Error accessing function export {}!", i); } @@ -33,7 +33,7 @@ macro_rules! check { macro_rules! check_ok { ($func:expr, $($p:expr),*) => { - if let Err(_) = $func.borrow().call(&[$($p.into()),*]) { + if let Err(_) = $func.call(&[$($p.into()),*]) { bail!("> Error on result, expected return"); } } @@ -41,7 +41,7 @@ macro_rules! check_ok { macro_rules! check_trap { ($func:expr, $($p:expr),*) => { - if let Ok(_) = $func.borrow().call(&[$($p.into()),*]) { + if let Ok(_) = $func.call(&[$($p.into()),*]) { bail!("> Error on result, expected trap"); } } @@ -49,7 +49,7 @@ macro_rules! check_trap { macro_rules! call { ($func:expr, $($p:expr),*) => { - match $func.borrow().call(&[$($p.into()),*]) { + match $func.call(&[$($p.into()),*]) { Ok(result) => { let result: i32 = result[0].unwrap_i32(); result @@ -101,16 +101,13 @@ fn main() -> Result<(), Error> { let load_func = get_export_func(&exports, 2)?; let store_func = get_export_func(&exports, 3)?; - // Try cloning. - check!(memory.clone().ptr_eq(&memory), true); - // Check initial memory. println!("Checking memory..."); - check!(memory.borrow().size(), 2u32); - check!(memory.borrow().data_size(), 0x20000usize); - check!(unsafe { memory.borrow().data()[0] }, 0); - check!(unsafe { memory.borrow().data()[0x1000] }, 1); - check!(unsafe { memory.borrow().data()[0x1003] }, 4); + check!(memory.size(), 2u32); + check!(memory.data_size(), 0x20000usize); + check!(unsafe { memory.data()[0] }, 0); + check!(unsafe { memory.data()[0x1000] }, 1); + check!(unsafe { memory.data()[0x1003] }, 4); check!(call!(size_func,), 2); check!(call!(load_func, 0), 0); @@ -122,36 +119,36 @@ fn main() -> Result<(), Error> { // Mutate memory. println!("Mutating memory..."); unsafe { - memory.borrow_mut().data()[0x1003] = 5; + memory.data()[0x1003] = 5; } check_ok!(store_func, 0x1002, 6); check_trap!(store_func, 0x20000, 0); - check!(unsafe { memory.borrow().data()[0x1002] }, 6); - check!(unsafe { memory.borrow().data()[0x1003] }, 5); + check!(unsafe { memory.data()[0x1002] }, 6); + check!(unsafe { memory.data()[0x1003] }, 5); check!(call!(load_func, 0x1002), 6); check!(call!(load_func, 0x1003), 5); // Grow memory. println!("Growing memory..."); - check!(memory.borrow_mut().grow(1), true); - check!(memory.borrow().size(), 3u32); - check!(memory.borrow().data_size(), 0x30000usize); + check!(memory.grow(1), true); + check!(memory.size(), 3u32); + check!(memory.data_size(), 0x30000usize); check!(call!(load_func, 0x20000), 0); check_ok!(store_func, 0x20000, 0); check_trap!(load_func, 0x30000); check_trap!(store_func, 0x30000, 0); - check!(memory.borrow_mut().grow(1), false); - check!(memory.borrow_mut().grow(0), true); + check!(memory.grow(1), false); + check!(memory.grow(0), true); // Create stand-alone memory. // TODO(wasm+): Once Wasm allows multiple memories, turn this into import. println!("Creating stand-alone memory..."); let memorytype = MemoryType::new(Limits::new(5, Some(5))); - let mut memory2 = Memory::new(&store, memorytype); + let memory2 = Memory::new(&store, memorytype); check!(memory2.size(), 5u32); check!(memory2.grow(1), false); check!(memory2.grow(0), true); diff --git a/crates/api/examples/multi.rs b/crates/api/examples/multi.rs index 8898accf11..d3236501cb 100644 --- a/crates/api/examples/multi.rs +++ b/crates/api/examples/multi.rs @@ -62,7 +62,7 @@ fn main() -> Result<()> { Box::new([ValType::I32, ValType::I64]), Box::new([ValType::I64, ValType::I32]), ); - let callback_func = HostRef::new(Func::new(&store, callback_type, Rc::new(Callback))); + let callback_func = Func::new(&store, callback_type, Rc::new(Callback)); // Instantiate. println!("Instantiating module..."); @@ -83,7 +83,6 @@ fn main() -> Result<()> { println!("Calling export \"g\"..."); let args = vec![Val::I32(1), Val::I64(3)]; let results = g - .borrow() .call(&args) .map_err(|e| format_err!("> Error calling g! {:?}", e))?; @@ -108,7 +107,6 @@ fn main() -> Result<()> { Val::I64(9), ]; let results = round_trip_many - .borrow() .call(&args) .map_err(|e| format_err!("> Error calling round_trip_many! {:?}", e))?; diff --git a/crates/api/src/callable.rs b/crates/api/src/callable.rs index 317875a7fd..4aefa8b206 100644 --- a/crates/api/src/callable.rs +++ b/crates/api/src/callable.rs @@ -12,7 +12,7 @@ use wasmtime_runtime::Export; /// WebAssembly. /// # Example /// ``` -/// use wasmtime::{HostRef, Val}; +/// use wasmtime::Val; /// /// struct TimesTwo; /// @@ -54,9 +54,8 @@ use wasmtime_runtime::Export; /// ); /// /// // Build a reference to the "times_two" function that can be used. -/// let times_two_function = HostRef::new( -/// wasmtime::Func::new(&store, times_two_type, std::rc::Rc::new(TimesTwo)) -/// ); +/// let times_two_function = +/// wasmtime::Func::new(&store, times_two_type, std::rc::Rc::new(TimesTwo)); /// /// // Create module instance that imports our function /// let instance = wasmtime::Instance::new( @@ -71,7 +70,6 @@ use wasmtime_runtime::Export; /// // Borrow and call "run". Returning any error message from Wasm as a string. /// let original = 5i32; /// let results = run_function -/// .borrow() /// .call(&[original.into()]) /// .map_err(|trap| trap.to_string())?; /// diff --git a/crates/api/src/externals.rs b/crates/api/src/externals.rs index c0b6156c77..98afc5a691 100644 --- a/crates/api/src/externals.rs +++ b/crates/api/src/externals.rs @@ -1,5 +1,5 @@ use crate::callable::{Callable, NativeCallable, WasmtimeFn, WrappedCallable}; -use crate::r#ref::{AnyRef, HostRef}; +use crate::r#ref::AnyRef; use crate::runtime::Store; use crate::trampoline::{generate_global_export, generate_memory_export, generate_table_export}; use crate::trap::Trap; @@ -15,53 +15,53 @@ use wasmtime_runtime::InstanceHandle; #[derive(Clone)] pub enum Extern { - Func(HostRef), - Global(HostRef), - Table(HostRef), - Memory(HostRef), + Func(Func), + Global(Global), + Table(Table), + Memory(Memory), } impl Extern { - pub fn func(&self) -> Option<&HostRef> { + pub fn func(&self) -> Option<&Func> { match self { Extern::Func(func) => Some(func), _ => None, } } - pub fn global(&self) -> Option<&HostRef> { + pub fn global(&self) -> Option<&Global> { match self { Extern::Global(global) => Some(global), _ => None, } } - pub fn table(&self) -> Option<&HostRef
> { + pub fn table(&self) -> Option<&Table> { match self { Extern::Table(table) => Some(table), _ => None, } } - pub fn memory(&self) -> Option<&HostRef> { + pub fn memory(&self) -> Option<&Memory> { match self { Extern::Memory(memory) => Some(memory), _ => None, } } - pub fn r#type(&self) -> ExternType { + pub fn ty(&self) -> ExternType { match self { - Extern::Func(ft) => ExternType::Func(ft.borrow().r#type().clone()), - Extern::Memory(ft) => ExternType::Memory(ft.borrow().r#type().clone()), - Extern::Table(tt) => ExternType::Table(tt.borrow().r#type().clone()), - Extern::Global(gt) => ExternType::Global(gt.borrow().r#type().clone()), + Extern::Func(ft) => ExternType::Func(ft.ty().clone()), + Extern::Memory(ft) => ExternType::Memory(ft.ty().clone()), + Extern::Table(tt) => ExternType::Table(tt.ty().clone()), + Extern::Global(gt) => ExternType::Global(gt.ty().clone()), } } pub(crate) fn get_wasmtime_export(&self) -> wasmtime_runtime::Export { match self { - Extern::Func(f) => f.borrow().wasmtime_export().clone(), - Extern::Global(g) => g.borrow().wasmtime_export().clone(), - Extern::Memory(m) => m.borrow().wasmtime_export().clone(), - Extern::Table(t) => t.borrow().wasmtime_export().clone(), + Extern::Func(f) => f.wasmtime_export().clone(), + Extern::Global(g) => g.wasmtime_export().clone(), + Extern::Memory(m) => m.wasmtime_export().clone(), + Extern::Table(t) => t.wasmtime_export().clone(), } } @@ -71,50 +71,51 @@ impl Extern { export: wasmtime_runtime::Export, ) -> Extern { match export { - wasmtime_runtime::Export::Function { .. } => Extern::Func(HostRef::new( - Func::from_wasmtime_function(export, store, instance_handle), - )), - wasmtime_runtime::Export::Memory { .. } => Extern::Memory(HostRef::new( - Memory::from_wasmtime_memory(export, store, instance_handle), - )), - wasmtime_runtime::Export::Global { .. } => { - Extern::Global(HostRef::new(Global::from_wasmtime_global(export, store))) + wasmtime_runtime::Export::Function { .. } => { + Extern::Func(Func::from_wasmtime_function(export, store, instance_handle)) + } + wasmtime_runtime::Export::Memory { .. } => { + Extern::Memory(Memory::from_wasmtime_memory(export, store, instance_handle)) + } + wasmtime_runtime::Export::Global { .. } => { + Extern::Global(Global::from_wasmtime_global(export, store)) + } + wasmtime_runtime::Export::Table { .. } => { + Extern::Table(Table::from_wasmtime_table(export, store, instance_handle)) } - wasmtime_runtime::Export::Table { .. } => Extern::Table(HostRef::new( - Table::from_wasmtime_table(export, store, instance_handle), - )), } } } -impl From> for Extern { - fn from(r: HostRef) -> Self { +impl From for Extern { + fn from(r: Func) -> Self { Extern::Func(r) } } -impl From> for Extern { - fn from(r: HostRef) -> Self { +impl From for Extern { + fn from(r: Global) -> Self { Extern::Global(r) } } -impl From> for Extern { - fn from(r: HostRef) -> Self { +impl From for Extern { + fn from(r: Memory) -> Self { Extern::Memory(r) } } -impl From> for Extern { - fn from(r: HostRef
) -> Self { +impl From
for Extern { + fn from(r: Table) -> Self { Extern::Table(r) } } +#[derive(Clone)] pub struct Func { _store: Store, callable: Rc, - r#type: FuncType, + ty: FuncType, } impl Func { @@ -125,26 +126,26 @@ impl Func { fn from_wrapped( store: &Store, - r#type: FuncType, + ty: FuncType, callable: Rc, ) -> Func { Func { _store: store.clone(), callable, - r#type, + ty, } } - pub fn r#type(&self) -> &FuncType { - &self.r#type + pub fn ty(&self) -> &FuncType { + &self.ty } pub fn param_arity(&self) -> usize { - self.r#type.params().len() + self.ty.params().len() } pub fn result_arity(&self) -> usize { - self.r#type.results().len() + self.ty.results().len() } pub fn call(&self, params: &[Val]) -> Result, Trap> { @@ -178,32 +179,39 @@ impl fmt::Debug for Func { } } +#[derive(Clone)] pub struct Global { + inner: Rc, +} + +struct GlobalInner { _store: Store, - r#type: GlobalType, + ty: GlobalType, wasmtime_export: wasmtime_runtime::Export, #[allow(dead_code)] wasmtime_state: Option, } impl Global { - pub fn new(store: &Store, r#type: GlobalType, val: Val) -> Global { + pub fn new(store: &Store, ty: GlobalType, val: Val) -> Global { let (wasmtime_export, wasmtime_state) = - generate_global_export(&r#type, val).expect("generated global"); + generate_global_export(&ty, val).expect("generated global"); Global { - _store: store.clone(), - r#type, - wasmtime_export, - wasmtime_state: Some(wasmtime_state), + inner: Rc::new(GlobalInner { + _store: store.clone(), + ty, + wasmtime_export, + wasmtime_state: Some(wasmtime_state), + }), } } - pub fn r#type(&self) -> &GlobalType { - &self.r#type + pub fn ty(&self) -> &GlobalType { + &self.inner.ty } fn wasmtime_global_definition(&self) -> *mut wasmtime_runtime::VMGlobalDefinition { - match self.wasmtime_export { + match self.inner.wasmtime_export { wasmtime_runtime::Export::Global { definition, .. } => definition, _ => panic!("global definition not found"), } @@ -212,22 +220,22 @@ impl Global { pub fn get(&self) -> Val { let definition = unsafe { &mut *self.wasmtime_global_definition() }; unsafe { - match self.r#type().content() { + match self.ty().content() { ValType::I32 => Val::from(*definition.as_i32()), ValType::I64 => Val::from(*definition.as_i64()), ValType::F32 => Val::F32(*definition.as_u32()), ValType::F64 => Val::F64(*definition.as_u64()), - _ => unimplemented!("Global::get for {:?}", self.r#type().content()), + _ => unimplemented!("Global::get for {:?}", self.ty().content()), } } } - pub fn set(&mut self, val: Val) { - if val.r#type() != *self.r#type().content() { + pub fn set(&self, val: Val) { + if val.ty() != *self.ty().content() { panic!( "global of type {:?} cannot be set to {:?}", - self.r#type().content(), - val.r#type() + self.ty().content(), + val.ty() ); } let definition = unsafe { &mut *self.wasmtime_global_definition() }; @@ -237,13 +245,13 @@ impl Global { Val::I64(i) => *definition.as_i64_mut() = i, Val::F32(f) => *definition.as_u32_mut() = f, Val::F64(f) => *definition.as_u64_mut() = f, - _ => unimplemented!("Global::set for {:?}", val.r#type()), + _ => unimplemented!("Global::set for {:?}", val.ty()), } } } pub(crate) fn wasmtime_export(&self) -> &wasmtime_runtime::Export { - &self.wasmtime_export + &self.inner.wasmtime_export } pub(crate) fn from_wasmtime_global(export: wasmtime_runtime::Export, store: &Store) -> Global { @@ -254,17 +262,20 @@ impl Global { }; let ty = GlobalType::from_wasmtime_global(&global); Global { - _store: store.clone(), - r#type: ty, - wasmtime_export: export, - wasmtime_state: None, + inner: Rc::new(GlobalInner { + _store: store.clone(), + ty: ty, + wasmtime_export: export, + wasmtime_state: None, + }), } } } +#[derive(Clone)] pub struct Table { store: Store, - r#type: TableType, + ty: TableType, wasmtime_handle: InstanceHandle, wasmtime_export: wasmtime_runtime::Export, } @@ -299,13 +310,13 @@ fn set_table_item( } impl Table { - pub fn new(store: &Store, r#type: TableType, init: Val) -> Table { - match r#type.element() { + pub fn new(store: &Store, ty: TableType, init: Val) -> Table { + match ty.element() { ValType::FuncRef => (), _ => panic!("table is not for funcref"), } let (mut wasmtime_handle, wasmtime_export) = - generate_table_export(&r#type).expect("generated table"); + generate_table_export(&ty).expect("generated table"); // Initialize entries with the init value. match wasmtime_export { @@ -323,14 +334,14 @@ impl Table { Table { store: store.clone(), - r#type, + ty, wasmtime_handle, wasmtime_export, } } - pub fn r#type(&self) -> &TableType { - &self.r#type + pub fn ty(&self) -> &TableType { + &self.ty } fn wasmtime_table_index(&self) -> wasm::DefinedTableIndex { @@ -362,9 +373,9 @@ impl Table { } } - pub fn grow(&mut self, delta: u32, init: Val) -> bool { + pub fn grow(&self, delta: u32, init: Val) -> bool { let index = self.wasmtime_table_index(); - if let Some(len) = self.wasmtime_handle.table_grow(index, delta) { + if let Some(len) = self.wasmtime_handle.clone().table_grow(index, delta) { let mut wasmtime_handle = self.wasmtime_handle.clone(); for i in 0..delta { let i = len - (delta - i); @@ -395,34 +406,35 @@ impl Table { let ty = TableType::from_wasmtime_table(&table.table); Table { store: store.clone(), - r#type: ty, + ty: ty, wasmtime_handle: instance_handle, wasmtime_export: export, } } } +#[derive(Clone)] pub struct Memory { _store: Store, - r#type: MemoryType, + ty: MemoryType, wasmtime_handle: InstanceHandle, wasmtime_export: wasmtime_runtime::Export, } impl Memory { - pub fn new(store: &Store, r#type: MemoryType) -> Memory { + pub fn new(store: &Store, ty: MemoryType) -> Memory { let (wasmtime_handle, wasmtime_export) = - generate_memory_export(&r#type).expect("generated memory"); + generate_memory_export(&ty).expect("generated memory"); Memory { _store: store.clone(), - r#type, + ty, wasmtime_handle, wasmtime_export, } } - pub fn r#type(&self) -> &MemoryType { - &self.r#type + pub fn ty(&self) -> &MemoryType { + &self.ty } fn wasmtime_memory_definition(&self) -> *mut wasmtime_runtime::VMMemoryDefinition { @@ -453,12 +465,15 @@ impl Memory { (self.data_size() / wasmtime_environ::WASM_PAGE_SIZE as usize) as u32 } - pub fn grow(&mut self, delta: u32) -> bool { + pub fn grow(&self, delta: u32) -> bool { match self.wasmtime_export { wasmtime_runtime::Export::Memory { definition, .. } => { let definition = unsafe { &(*definition) }; let index = self.wasmtime_handle.memory_index(definition); - self.wasmtime_handle.memory_grow(index, delta).is_some() + self.wasmtime_handle + .clone() + .memory_grow(index, delta) + .is_some() } _ => panic!("memory definition not found"), } @@ -481,7 +496,7 @@ impl Memory { let ty = MemoryType::from_wasmtime_memory(&memory.memory); Memory { _store: store.clone(), - r#type: ty, + ty: ty, wasmtime_handle: instance_handle, wasmtime_export: export, } diff --git a/crates/api/src/instance.rs b/crates/api/src/instance.rs index 166848cb12..b78048b892 100644 --- a/crates/api/src/instance.rs +++ b/crates/api/src/instance.rs @@ -167,29 +167,29 @@ cfg_if::cfg_if! { impl Instance { /// The signal handler must be /// [async-signal-safe](http://man7.org/linux/man-pages/man7/signal-safety.7.html). - pub fn set_signal_handler(&mut self, handler: H) + pub fn set_signal_handler(&self, handler: H) where H: 'static + Fn(libc::c_int, *const libc::siginfo_t, *const libc::c_void) -> bool, { - self.instance_handle.set_signal_handler(handler); + self.instance_handle.clone().set_signal_handler(handler); } } } else if #[cfg(target_os = "windows")] { impl Instance { - pub fn set_signal_handler(&mut self, handler: H) + pub fn set_signal_handler(&self, handler: H) where H: 'static + Fn(winapi::um::winnt::EXCEPTION_POINTERS) -> bool, { - self.instance_handle.set_signal_handler(handler); + self.instance_handle.clone().set_signal_handler(handler); } } } else if #[cfg(target_os = "macos")] { impl Instance { - pub fn set_signal_handler(&mut self, handler: H) + pub fn set_signal_handler(&self, handler: H) where H: 'static + Fn(libc::c_int, *const libc::siginfo_t, *const libc::c_void) -> bool, { - self.instance_handle.set_signal_handler(handler); + self.instance_handle.clone().set_signal_handler(handler); } } } diff --git a/crates/api/src/values.rs b/crates/api/src/values.rs index 419f4534f9..4d470a2e23 100644 --- a/crates/api/src/values.rs +++ b/crates/api/src/values.rs @@ -1,5 +1,5 @@ use crate::externals::Func; -use crate::r#ref::{AnyRef, HostRef}; +use crate::r#ref::AnyRef; use crate::runtime::Store; use crate::types::ValType; use std::ptr; @@ -34,7 +34,7 @@ pub enum Val { AnyRef(AnyRef), /// A first-class reference to a WebAssembly function. - FuncRef(HostRef), + FuncRef(Func), /// A 128-bit number V128(u128), @@ -71,7 +71,7 @@ impl Val { } /// Returns the corresponding [`ValType`] for this `Val`. - pub fn r#type(&self) -> ValType { + pub fn ty(&self) -> ValType { match self { Val::I32(_) => ValType::I32, Val::I64(_) => ValType::I64, @@ -111,7 +111,7 @@ impl Val { (I64(i64) i64 unwrap_i64 *e) (F32(f32) f32 unwrap_f32 f32::from_bits(*e)) (F64(f64) f64 unwrap_f64 f64::from_bits(*e)) - (FuncRef(&HostRef) funcref unwrap_funcref e) + (FuncRef(&Func) funcref unwrap_funcref e) (V128(u128) v128 unwrap_v128 *e) } @@ -122,7 +122,6 @@ impl Val { pub fn anyref(&self) -> Option { match self { Val::AnyRef(e) => Some(e.clone()), - Val::FuncRef(e) => Some(e.anyref()), _ => None, } } @@ -164,21 +163,12 @@ impl From for Val { impl From for Val { fn from(val: AnyRef) -> Val { - match &val { - AnyRef::Ref(r) => { - if r.is_ref::() { - Val::FuncRef(r.get_ref()) - } else { - Val::AnyRef(val) - } - } - _ => unimplemented!("AnyRef::Other"), - } + Val::AnyRef(val) } } -impl From> for Val { - fn from(val: HostRef) -> Val { +impl From for Val { + fn from(val: Func) -> Val { Val::FuncRef(val) } } @@ -206,7 +196,6 @@ pub(crate) fn into_checked_anyfunc( vmctx: ptr::null_mut(), }, Val::FuncRef(f) => { - let f = f.borrow(); let (vmctx, func_ptr, signature) = match f.wasmtime_export() { wasmtime_runtime::Export::Function { vmctx, @@ -243,5 +232,5 @@ pub(crate) fn from_checked_anyfunc( vmctx: item.vmctx, }; let f = Func::from_wasmtime_function(export, store, instance_handle); - Val::FuncRef(HostRef::new(f)) + Val::FuncRef(f) } diff --git a/crates/api/src/wasm.rs b/crates/api/src/wasm.rs index 1776eb06ec..f5591ece5b 100644 --- a/crates/api/src/wasm.rs +++ b/crates/api/src/wasm.rs @@ -10,6 +10,7 @@ use super::{ HostInfo, HostRef, ImportType, Instance, Limits, Memory, MemoryType, Module, Store, Table, TableType, Trap, Val, ValType, }; +use std::cell::RefCell; use std::rc::Rc; use std::{mem, ptr, slice}; @@ -243,6 +244,12 @@ enum wasm_externtype_t_type_cache { declare_vec!(wasm_externtype_vec_t, *mut wasm_externtype_t); pub type wasm_externkind_t = u8; + +const WASM_EXTERN_FUNC: wasm_externkind_t = 0; +const WASM_EXTERN_GLOBAL: wasm_externkind_t = 1; +const WASM_EXTERN_TABLE: wasm_externkind_t = 2; +const WASM_EXTERN_MEMORY: wasm_externkind_t = 3; + #[repr(C)] #[derive(Clone)] pub struct wasm_importtype_t { @@ -312,6 +319,7 @@ declare_vec!(wasm_frame_vec_t, *mut wasm_frame_t); #[derive(Clone)] pub struct wasm_instance_t { instance: HostRef, + exports_cache: RefCell>>, } pub type wasm_message_t = wasm_name_t; #[repr(C)] @@ -336,12 +344,22 @@ pub struct wasm_module_t { pub struct wasm_shared_module_t { _unused: [u8; 0], } -#[repr(C)] + #[derive(Clone)] +#[repr(transparent)] pub struct wasm_func_t { - func: HostRef, - ext: Option>, + ext: wasm_extern_t, } + +impl wasm_func_t { + fn func(&self) -> &HostRef { + match &self.ext.which { + ExternHost::Func(f) => f, + _ => unsafe { std::hint::unreachable_unchecked() }, + } + } +} + pub type wasm_func_callback_t = std::option::Option< unsafe extern "C" fn(args: *const wasm_val_t, results: *mut wasm_val_t) -> *mut wasm_trap_t, >; @@ -352,40 +370,67 @@ pub type wasm_func_callback_with_env_t = std::option::Option< results: *mut wasm_val_t, ) -> *mut wasm_trap_t, >; -#[repr(C)] + #[derive(Clone)] +#[repr(transparent)] pub struct wasm_global_t { - global: HostRef, - ext: Option>, + ext: wasm_extern_t, } -#[repr(C)] -#[derive(Clone)] -pub struct wasm_table_t { - table: HostRef
, - ext: Option>, -} -pub type wasm_table_size_t = u32; -#[repr(C)] -#[derive(Clone)] -pub struct wasm_memory_t { - memory: HostRef, - ext: Option>, -} -pub type wasm_memory_pages_t = u32; -#[repr(C)] -#[derive(Clone)] -pub struct wasm_extern_t { - ext: Extern, - cache: wasm_extern_t_type_cache, + +impl wasm_global_t { + fn global(&self) -> &HostRef { + match &self.ext.which { + ExternHost::Global(g) => g, + _ => unsafe { std::hint::unreachable_unchecked() }, + } + } } #[derive(Clone)] -enum wasm_extern_t_type_cache { - Empty, - Func(wasm_func_t), - Global(wasm_global_t), - Memory(wasm_memory_t), - Table(wasm_table_t), +#[repr(transparent)] +pub struct wasm_table_t { + ext: wasm_extern_t, +} + +impl wasm_table_t { + fn table(&self) -> &HostRef
{ + match &self.ext.which { + ExternHost::Table(t) => t, + _ => unsafe { std::hint::unreachable_unchecked() }, + } + } +} + +pub type wasm_table_size_t = u32; + +#[derive(Clone)] +#[repr(transparent)] +pub struct wasm_memory_t { + ext: wasm_extern_t, +} + +impl wasm_memory_t { + fn memory(&self) -> &HostRef { + match &self.ext.which { + ExternHost::Memory(m) => m, + _ => unsafe { std::hint::unreachable_unchecked() }, + } + } +} + +pub type wasm_memory_pages_t = u32; + +#[derive(Clone)] +pub struct wasm_extern_t { + which: ExternHost, +} + +#[derive(Clone)] +enum ExternHost { + Func(HostRef), + Global(HostRef), + Memory(HostRef), + Table(HostRef
), } declare_vec!(wasm_extern_vec_t, *mut wasm_extern_t); @@ -415,16 +460,9 @@ pub unsafe extern "C" fn wasm_engine_new() -> *mut wasm_engine_t { #[no_mangle] pub unsafe extern "C" fn wasm_extern_as_func(e: *mut wasm_extern_t) -> *mut wasm_func_t { - if let wasm_extern_t_type_cache::Empty = (*e).cache { - (*e).cache = wasm_extern_t_type_cache::Func(wasm_func_t { - func: (*e).ext.func().unwrap().clone(), - ext: None, - }); - } - - match &mut (*e).cache { - wasm_extern_t_type_cache::Func(f) => f, - _ => panic!("wasm_extern_as_func"), + match &(*e).which { + ExternHost::Func(_) => e.cast(), + _ => ptr::null_mut(), } } @@ -435,17 +473,7 @@ pub unsafe extern "C" fn wasm_extern_vec_delete(v: *mut wasm_extern_vec_t) { #[no_mangle] pub unsafe extern "C" fn wasm_func_as_extern(f: *mut wasm_func_t) -> *mut wasm_extern_t { - if (*f).ext.is_none() { - (*f).ext = Some(Box::new(wasm_extern_t { - ext: Extern::Func((*f).func.clone()), - cache: wasm_extern_t_type_cache::Empty, - })); - } - - match &mut (*f).ext { - Some(e) => e.as_mut(), - _ => panic!("wasm_func_as_extern"), - } + &mut (*f).ext } #[no_mangle] @@ -454,7 +482,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 = (*func).func.borrow(); + let func = (*func).func().borrow(); let mut params = Vec::with_capacity(func.param_arity()); for i in 0..func.param_arity() { let val = &(*args.add(i)); @@ -606,8 +634,9 @@ pub unsafe extern "C" fn wasm_func_new( let ty = (*ty).functype.clone(); let callback = Rc::new(callback); let func = Box::new(wasm_func_t { - func: HostRef::new(Func::new(store, ty, callback)), - ext: None, + ext: wasm_extern_t { + which: ExternHost::Func(HostRef::new(Func::new(store, ty, callback))), + }, }); Box::into_raw(func) } @@ -660,13 +689,19 @@ pub unsafe extern "C" fn wasm_instance_new( let mut externs: Vec = Vec::with_capacity((*module).imports.len()); for i in 0..(*module).imports.len() { let import = *imports.add(i); - externs.push((*import).ext.clone()); + externs.push(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()), + }); } let module = &(*module).module.borrow(); match Instance::new(store, module, &externs) { Ok(instance) => { let instance = Box::new(wasm_instance_t { instance: HostRef::new(instance), + exports_cache: RefCell::new(None), }); if !result.is_null() { (*result) = ptr::null_mut(); @@ -694,14 +729,23 @@ pub unsafe extern "C" fn wasm_instance_exports( instance: *const wasm_instance_t, out: *mut wasm_extern_vec_t, ) { - let instance = &(*instance).instance.borrow(); - let exports = instance.exports(); + let mut cache = (*instance).exports_cache.borrow_mut(); + let exports = cache.get_or_insert_with(|| { + let instance = &(*instance).instance.borrow(); + instance + .exports() + .iter() + .map(|e| match e { + Extern::Func(f) => ExternHost::Func(HostRef::new(f.clone())), + Extern::Global(f) => ExternHost::Global(HostRef::new(f.clone())), + Extern::Memory(f) => ExternHost::Memory(HostRef::new(f.clone())), + Extern::Table(f) => ExternHost::Table(HostRef::new(f.clone())), + }) + .collect() + }); let mut buffer = Vec::with_capacity(exports.len()); - for e in exports.iter() { - let ext = Box::new(wasm_extern_t { - ext: e.clone(), - cache: wasm_extern_t_type_cache::Empty, - }); + for e in exports { + let ext = Box::new(wasm_extern_t { which: e.clone() }); buffer.push(Box::into_raw(ext)); } (*out).set_buffer(buffer); @@ -817,8 +861,9 @@ pub unsafe extern "C" fn wasm_func_new_with_env( finalizer, }); let func = Box::new(wasm_func_t { - func: HostRef::new(Func::new(store, ty, callback)), - ext: None, + ext: wasm_extern_t { + which: ExternHost::Func(HostRef::new(Func::new(store, ty, callback))), + }, }); Box::into_raw(func) } @@ -1012,24 +1057,25 @@ pub unsafe extern "C" fn wasm_exporttype_vec_delete(et: *mut wasm_exporttype_vec (*et).uninitialize(); } -fn from_externtype(ty: &ExternType) -> wasm_externkind_t { - match ty { - ExternType::Func(_) => 0, - ExternType::Global(_) => 1, - ExternType::Table(_) => 2, - ExternType::Memory(_) => 3, - } -} - #[no_mangle] pub unsafe extern "C" fn wasm_extern_kind(e: *const wasm_extern_t) -> wasm_externkind_t { - from_externtype(&(*e).ext.r#type()) + match (*e).which { + ExternHost::Func(_) => WASM_EXTERN_FUNC, + ExternHost::Global(_) => WASM_EXTERN_GLOBAL, + ExternHost::Table(_) => WASM_EXTERN_TABLE, + ExternHost::Memory(_) => WASM_EXTERN_MEMORY, + } } #[no_mangle] pub unsafe extern "C" fn wasm_extern_type(e: *const wasm_extern_t) -> *mut wasm_externtype_t { let et = Box::new(wasm_externtype_t { - ty: (*e).ext.r#type(), + ty: match &(*e).which { + ExternHost::Func(f) => ExternType::Func(f.borrow().ty().clone()), + ExternHost::Global(f) => ExternType::Global(f.borrow().ty().clone()), + ExternHost::Table(f) => ExternType::Table(f.borrow().ty().clone()), + ExternHost::Memory(f) => ExternType::Memory(f.borrow().ty().clone()), + }, cache: wasm_externtype_t_type_cache::Empty, }); Box::into_raw(et) @@ -1120,17 +1166,22 @@ pub unsafe extern "C" fn wasm_externtype_delete(et: *mut wasm_externtype_t) { #[no_mangle] pub unsafe extern "C" fn wasm_externtype_kind(et: *const wasm_externtype_t) -> wasm_externkind_t { - from_externtype(&(*et).ty) + match &(*et).ty { + ExternType::Func(_) => WASM_EXTERN_FUNC, + ExternType::Table(_) => WASM_EXTERN_TABLE, + ExternType::Global(_) => WASM_EXTERN_GLOBAL, + ExternType::Memory(_) => WASM_EXTERN_MEMORY, + } } #[no_mangle] pub unsafe extern "C" fn wasm_func_param_arity(f: *const wasm_func_t) -> usize { - (*f).func.borrow().param_arity() + (*f).func().borrow().param_arity() } #[no_mangle] pub unsafe extern "C" fn wasm_func_result_arity(f: *const wasm_func_t) -> usize { - (*f).func.borrow().result_arity() + (*f).func().borrow().result_arity() } #[no_mangle] @@ -1279,32 +1330,15 @@ pub unsafe extern "C" fn wasm_valtype_kind(vt: *const wasm_valtype_t) -> wasm_va #[no_mangle] pub unsafe extern "C" fn wasm_extern_as_global(e: *mut wasm_extern_t) -> *mut wasm_global_t { - if let wasm_extern_t_type_cache::Empty = (*e).cache { - (*e).cache = wasm_extern_t_type_cache::Global(wasm_global_t { - global: (*e).ext.global().unwrap().clone(), - ext: None, - }); - } - - match &mut (*e).cache { - wasm_extern_t_type_cache::Global(g) => g, - _ => panic!("wasm_extern_as_global"), + match &(*e).which { + ExternHost::Global(_) => e.cast(), + _ => ptr::null_mut(), } } #[no_mangle] pub unsafe extern "C" fn wasm_global_as_extern(g: *mut wasm_global_t) -> *mut wasm_extern_t { - if (*g).ext.is_none() { - (*g).ext = Some(Box::new(wasm_extern_t { - ext: Extern::Global((*g).global.clone()), - cache: wasm_extern_t_type_cache::Empty, - })); - } - - match &mut (*g).ext { - Some(e) => e.as_mut(), - _ => panic!("wasm_global_as_extern"), - } + &mut (*g).ext } #[no_mangle] @@ -1322,7 +1356,7 @@ pub unsafe extern "C" fn wasm_global_same( g1: *const wasm_global_t, g2: *const wasm_global_t, ) -> bool { - (*g1).global.ptr_eq(&(*g2).global) + (*g1).global().ptr_eq(&(*g2).global()) } #[no_mangle] @@ -1336,18 +1370,22 @@ pub unsafe extern "C" fn wasm_global_new( (*gt).globaltype.clone(), (*val).val(), )); - let g = Box::new(wasm_global_t { global, ext: None }); + let g = Box::new(wasm_global_t { + ext: wasm_extern_t { + which: ExternHost::Global(global), + }, + }); Box::into_raw(g) } #[no_mangle] pub unsafe extern "C" fn wasm_global_get(g: *const wasm_global_t, out: *mut wasm_val_t) { - (*out).set((*g).global.borrow_mut().get()); + (*out).set((*g).global().borrow().get()); } #[no_mangle] pub unsafe extern "C" fn wasm_global_set(g: *mut wasm_global_t, val: *const wasm_val_t) { - (*g).global.borrow_mut().set((*val).val()) + (*g).global().borrow().set((*val).val()) } #[no_mangle] @@ -1377,32 +1415,15 @@ pub unsafe extern "C" fn wasm_globaltype_new( #[no_mangle] pub unsafe extern "C" fn wasm_extern_as_memory(e: *mut wasm_extern_t) -> *mut wasm_memory_t { - if let wasm_extern_t_type_cache::Empty = (*e).cache { - (*e).cache = wasm_extern_t_type_cache::Memory(wasm_memory_t { - memory: (*e).ext.memory().unwrap().clone(), - ext: None, - }); - } - - match &mut (*e).cache { - wasm_extern_t_type_cache::Memory(m) => m, - _ => panic!("wasm_extern_as_memory"), + match &(*e).which { + ExternHost::Memory(_) => e.cast(), + _ => ptr::null_mut(), } } #[no_mangle] pub unsafe extern "C" fn wasm_memory_as_extern(m: *mut wasm_memory_t) -> *mut wasm_extern_t { - if (*m).ext.is_none() { - (*m).ext = Some(Box::new(wasm_extern_t { - ext: Extern::Memory((*m).memory.clone()), - cache: wasm_extern_t_type_cache::Empty, - })); - } - - match &mut (*m).ext { - Some(e) => e.as_mut(), - _ => panic!("wasm_global_as_extern"), - } + &mut (*m).ext } #[no_mangle] @@ -1420,22 +1441,22 @@ pub unsafe extern "C" fn wasm_memory_same( m1: *const wasm_memory_t, m2: *const wasm_memory_t, ) -> bool { - (*m1).memory.ptr_eq(&(*m2).memory) + (*m1).memory().ptr_eq(&(*m2).memory()) } #[no_mangle] pub unsafe extern "C" fn wasm_memory_data(m: *mut wasm_memory_t) -> *mut u8 { - (*m).memory.borrow().data_ptr() + (*m).memory().borrow().data_ptr() } #[no_mangle] pub unsafe extern "C" fn wasm_memory_data_size(m: *const wasm_memory_t) -> usize { - (*m).memory.borrow().data_size() + (*m).memory().borrow().data_size() } #[no_mangle] pub unsafe extern "C" fn wasm_memory_size(m: *const wasm_memory_t) -> wasm_memory_pages_t { - (*m).memory.borrow().size() + (*m).memory().borrow().size() } #[no_mangle] @@ -1443,7 +1464,7 @@ pub unsafe extern "C" fn wasm_memory_grow( m: *mut wasm_memory_t, delta: wasm_memory_pages_t, ) -> bool { - (*m).memory.borrow_mut().grow(delta) + (*m).memory().borrow().grow(delta) } #[no_mangle] @@ -1455,7 +1476,11 @@ pub unsafe extern "C" fn wasm_memory_new( &(*store).store.borrow(), (*mt).memorytype.clone(), )); - let m = Box::new(wasm_memory_t { memory, ext: None }); + let m = Box::new(wasm_memory_t { + ext: wasm_extern_t { + which: ExternHost::Memory(memory), + }, + }); Box::into_raw(m) } @@ -1483,37 +1508,20 @@ pub unsafe extern "C" fn wasm_memorytype_new( #[no_mangle] pub unsafe extern "C" fn wasm_extern_as_table(e: *mut wasm_extern_t) -> *mut wasm_table_t { - if let wasm_extern_t_type_cache::Empty = (*e).cache { - (*e).cache = wasm_extern_t_type_cache::Table(wasm_table_t { - table: (*e).ext.table().unwrap().clone(), - ext: None, - }); - } - - match &mut (*e).cache { - wasm_extern_t_type_cache::Table(t) => t, - _ => panic!("wasm_extern_as_table"), + match &(*e).which { + ExternHost::Table(_) => e.cast(), + _ => ptr::null_mut(), } } #[no_mangle] pub unsafe extern "C" fn wasm_table_as_extern(t: *mut wasm_table_t) -> *mut wasm_extern_t { - if (*t).ext.is_none() { - (*t).ext = Some(Box::new(wasm_extern_t { - ext: Extern::Table((*t).table.clone()), - cache: wasm_extern_t_type_cache::Empty, - })); - } - - match &mut (*t).ext { - Some(e) => e.as_mut(), - _ => panic!("wasm_table_as_extern"), - } + &mut (*t).ext } #[no_mangle] pub unsafe extern "C" fn wasm_func_as_ref(f: *mut wasm_func_t) -> *mut wasm_ref_t { - let r = (*f).func.anyref(); + let r = (*f).func().anyref(); let f = Box::new(wasm_ref_t { r }); Box::into_raw(f) } @@ -1547,12 +1555,13 @@ pub unsafe extern "C" fn wasm_table_new( Val::AnyRef(AnyRef::Null) }; let t = Box::new(wasm_table_t { - table: HostRef::new(Table::new( - &(*store).store.borrow(), - (*tt).tabletype.clone(), - init, - )), - ext: None, + ext: wasm_extern_t { + which: ExternHost::Table(HostRef::new(Table::new( + &(*store).store.borrow(), + (*tt).tabletype.clone(), + init, + ))), + }, }); Box::into_raw(t) } @@ -1582,7 +1591,7 @@ pub unsafe extern "C" fn wasm_table_get( t: *const wasm_table_t, index: wasm_table_size_t, ) -> *mut wasm_ref_t { - let val = (*t).table.borrow().get(index); + let val = (*t).table().borrow().get(index); into_funcref(val) } @@ -1593,12 +1602,12 @@ 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) + (*t).table().borrow().set(index, val) } #[no_mangle] pub unsafe extern "C" fn wasm_table_size(t: *const wasm_table_t) -> wasm_table_size_t { - (*t).table.borrow().size() + (*t).table().borrow().size() } #[no_mangle] @@ -1608,12 +1617,12 @@ pub unsafe extern "C" fn wasm_table_grow( init: *mut wasm_ref_t, ) -> bool { let init = from_funcref(init); - (*t).table.borrow_mut().grow(delta, init) + (*t).table().borrow().grow(delta, init) } #[no_mangle] pub unsafe extern "C" fn wasm_table_same(t1: *const wasm_table_t, t2: *const wasm_table_t) -> bool { - (*t1).table.ptr_eq(&(*t2).table) + (*t1).table().ptr_eq((*t2).table()) } #[no_mangle] diff --git a/crates/api/tests/import-indexes.rs b/crates/api/tests/import-indexes.rs index 8e35f6cbf6..18847da8e6 100644 --- a/crates/api/tests/import-indexes.rs +++ b/crates/api/tests/import-indexes.rs @@ -42,23 +42,23 @@ fn same_import_names_still_distinct() -> anyhow::Result<()> { let module = Module::new(&store, &wasm)?; let imports = [ - HostRef::new(Func::new( + Func::new( &store, FuncType::new(Box::new([]), Box::new([ValType::I32])), Rc::new(Ret1), - )) + ) .into(), - HostRef::new(Func::new( + Func::new( &store, FuncType::new(Box::new([]), Box::new([ValType::F32])), Rc::new(Ret2), - )) + ) .into(), ]; let instance = Instance::new(&store, &module, &imports)?; let func = instance.find_export_by_name("foo").unwrap().func().unwrap(); - let results = func.borrow().call(&[])?; + let results = func.call(&[])?; assert_eq!(results.len(), 1); match results[0] { Val::I32(n) => assert_eq!(n, 3), diff --git a/crates/api/tests/import_calling_export.rs b/crates/api/tests/import_calling_export.rs index e8d94e6e25..71991ae09b 100644 --- a/crates/api/tests/import_calling_export.rs +++ b/crates/api/tests/import_calling_export.rs @@ -1,4 +1,4 @@ -use std::cell::{Ref, RefCell}; +use std::cell::RefCell; use std::rc::Rc; use wasmtime::*; @@ -16,7 +16,7 @@ fn test_import_calling_export() { "#; struct Callback { - pub other: RefCell>>, + pub other: RefCell>, } impl Callable for Callback { @@ -25,7 +25,6 @@ fn test_import_calling_export() { .borrow() .as_ref() .expect("expected a function ref") - .borrow() .call(&[]) .expect("expected function not to trap"); Ok(()) @@ -40,18 +39,17 @@ fn test_import_calling_export() { other: RefCell::new(None), }); - let callback_func = HostRef::new(Func::new( + let callback_func = Func::new( &store, FuncType::new(Box::new([]), Box::new([])), callback.clone(), - )); - - let imports = vec![callback_func.into()]; - let instance = HostRef::new( - Instance::new(&store, &module, imports.as_slice()).expect("failed to instantiate module"), ); - let exports = Ref::map(instance.borrow(), |instance| instance.exports()); + let imports = vec![callback_func.into()]; + let instance = + Instance::new(&store, &module, imports.as_slice()).expect("failed to instantiate module"); + + let exports = instance.exports(); assert!(!exports.is_empty()); let run_func = exports[0] @@ -65,8 +63,5 @@ fn test_import_calling_export() { .clone(), ); - run_func - .borrow() - .call(&[]) - .expect("expected function not to trap"); + run_func.call(&[]).expect("expected function not to trap"); } diff --git a/crates/api/tests/traps.rs b/crates/api/tests/traps.rs index a5b8cc9caf..9973236578 100644 --- a/crates/api/tests/traps.rs +++ b/crates/api/tests/traps.rs @@ -26,20 +26,16 @@ fn test_trap_return() -> Result<(), String> { let module = Module::new(&store, &binary).map_err(|e| format!("failed to compile module: {}", e))?; let hello_type = FuncType::new(Box::new([]), Box::new([])); - let hello_func = HostRef::new(Func::new(&store, hello_type, Rc::new(HelloCallback))); + let hello_func = Func::new(&store, hello_type, Rc::new(HelloCallback)); let imports = vec![hello_func.into()]; - let instance = Instance::new(&store, &module, imports.as_slice()) + let instance = Instance::new(&store, &module, &imports) .map_err(|e| format!("failed to instantiate module: {:?}", e))?; let run_func = instance.exports()[0] .func() .expect("expected function export"); - let e = run_func - .borrow() - .call(&[]) - .err() - .expect("error calling function"); + let e = run_func.call(&[]).err().expect("error calling function"); assert_eq!(e.message(), "test 123"); diff --git a/crates/fuzzing/src/oracles.rs b/crates/fuzzing/src/oracles.rs index 1afd7467aa..2dab05f457 100644 --- a/crates/fuzzing/src/oracles.rs +++ b/crates/fuzzing/src/oracles.rs @@ -96,7 +96,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) { let mut engine: Option = None; let mut store: Option = None; let mut modules: HashMap = Default::default(); - let mut instances: HashMap> = Default::default(); + let mut instances: HashMap = Default::default(); for call in api.calls { match call { @@ -153,7 +153,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) { // table might not have room for an element segment that we want to // initialize into it. if let Ok(instance) = Instance::new(store.as_ref().unwrap(), &module, &imports) { - instances.insert(id, HostRef::new(instance)); + instances.insert(id, instance); } } @@ -175,25 +175,22 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) { } }; - let funcs = { - let instance = instance.borrow(); - instance - .exports() - .iter() - .filter_map(|e| match e { - Extern::Func(f) => Some(f.clone()), - _ => None, - }) - .collect::>() - }; + let funcs = instance + .exports() + .iter() + .filter_map(|e| match e { + Extern::Func(f) => Some(f.clone()), + _ => None, + }) + .collect::>(); if funcs.is_empty() { continue; } let nth = nth % funcs.len(); - let f = funcs[nth].borrow(); - let ty = f.r#type(); + let f = &funcs[nth]; + let ty = f.ty(); let params = match ty .params() .iter() diff --git a/crates/fuzzing/src/oracles/dummy.rs b/crates/fuzzing/src/oracles/dummy.rs index f72cd4858f..0a0b06b69b 100644 --- a/crates/fuzzing/src/oracles/dummy.rs +++ b/crates/fuzzing/src/oracles/dummy.rs @@ -2,7 +2,7 @@ use std::rc::Rc; use wasmtime::{ - Callable, Extern, ExternType, Func, FuncType, Global, GlobalType, HostRef, ImportType, Memory, + Callable, Extern, ExternType, Func, FuncType, Global, GlobalType, ImportType, Memory, MemoryType, Store, Table, TableType, Trap, Val, ValType, }; @@ -11,18 +11,12 @@ pub fn dummy_imports(store: &Store, import_tys: &[ImportType]) -> Result { - Extern::Func(HostRef::new(DummyFunc::new(&store, func_ty.clone()))) - } + ExternType::Func(func_ty) => Extern::Func(DummyFunc::new(&store, func_ty.clone())), ExternType::Global(global_ty) => { - Extern::Global(HostRef::new(dummy_global(&store, global_ty.clone())?)) - } - ExternType::Table(table_ty) => { - Extern::Table(HostRef::new(dummy_table(&store, table_ty.clone())?)) - } - ExternType::Memory(mem_ty) => { - Extern::Memory(HostRef::new(dummy_memory(&store, mem_ty.clone()))) + Extern::Global(dummy_global(&store, global_ty.clone())?) } + ExternType::Table(table_ty) => Extern::Table(dummy_table(&store, table_ty.clone())?), + ExternType::Memory(mem_ty) => Extern::Memory(dummy_memory(&store, mem_ty.clone())), }); } Ok(imports) diff --git a/crates/interface-types/src/lib.rs b/crates/interface-types/src/lib.rs index 62122b62ac..4934e7370c 100644 --- a/crates/interface-types/src/lib.rs +++ b/crates/interface-types/src/lib.rs @@ -125,18 +125,17 @@ impl ModuleData { /// wasm interface types. pub fn invoke_export( &self, - instance: &wasmtime::HostRef, + instance: &wasmtime::Instance, export: &str, args: &[Value], ) -> Result> { - let mut handle = instance.borrow().handle().clone(); + let mut handle = instance.handle().clone(); let binding = self.binding_for_export(&mut handle, export)?; let incoming = binding.param_bindings()?; let outgoing = binding.result_bindings()?; let f = instance - .borrow() .find_export_by_name(export) .ok_or_else(|| format_err!("failed to find export `{}`", export))? .func() @@ -148,7 +147,7 @@ impl ModuleData { .into_iter() .map(|rv| rv.into()) .collect::>(); - let wasm_results = match f.borrow().call(&wasm_args) { + let wasm_results = match f.call(&wasm_args) { Ok(values) => values .to_vec() .into_iter() @@ -322,20 +321,19 @@ trait TranslateContext { unsafe fn get_memory(&mut self) -> Result<&mut [u8]>; } -struct InstanceTranslateContext(pub wasmtime::HostRef); +struct InstanceTranslateContext(pub wasmtime::Instance); impl TranslateContext for InstanceTranslateContext { fn invoke_alloc(&mut self, alloc_func_name: &str, len: i32) -> Result { let alloc = self .0 - .borrow() .find_export_by_name(alloc_func_name) .ok_or_else(|| format_err!("failed to find alloc function `{}`", alloc_func_name))? .func() .ok_or_else(|| format_err!("`{}` is not a (alloc) function", alloc_func_name))? .clone(); let alloc_args = vec![wasmtime::Val::I32(len)]; - let results = match alloc.borrow().call(&alloc_args) { + let results = match alloc.call(&alloc_args) { Ok(values) => values, Err(trap) => bail!("trapped: {:?}", trap), }; @@ -350,14 +348,13 @@ impl TranslateContext for InstanceTranslateContext { unsafe fn get_memory(&mut self) -> Result<&mut [u8]> { let memory = self .0 - .borrow() .find_export_by_name("memory") .ok_or_else(|| format_err!("failed to find `memory` export"))? .memory() .ok_or_else(|| format_err!("`memory` is not a memory"))? .clone(); - let ptr = memory.borrow().data_ptr(); - let len = memory.borrow().data_size(); + let ptr = memory.data_ptr(); + let len = memory.data_size(); Ok(std::slice::from_raw_parts_mut(ptr, len)) } } diff --git a/crates/misc/py/src/function.rs b/crates/misc/py/src/function.rs index 3b88dcccf0..8227394c7a 100644 --- a/crates/misc/py/src/function.rs +++ b/crates/misc/py/src/function.rs @@ -10,17 +10,16 @@ use wasmtime_interface_types::ModuleData; // TODO support non-export functions #[pyclass] pub struct Function { - pub instance: wasmtime::HostRef, + pub instance: wasmtime::Instance, pub export_name: String, pub args_types: Vec, pub data: Rc, } impl Function { - pub fn func(&self) -> wasmtime::HostRef { + 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> { +pub fn wrap_into_pyfunction(store: &wasmtime::Store, callable: &PyAny) -> PyResult { if !callable.hasattr("__annotations__")? { // TODO support calls without annotations? return Err(PyErr::new::( @@ -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))) } diff --git a/crates/misc/py/src/instance.rs b/crates/misc/py/src/instance.rs index f5c0480885..717d24aa2a 100644 --- a/crates/misc/py/src/instance.rs +++ b/crates/misc/py/src/instance.rs @@ -9,7 +9,7 @@ use wasmtime_interface_types::ModuleData; #[pyclass] pub struct Instance { - pub instance: wasmtime::HostRef, + pub instance: wasmtime::Instance, pub data: Rc, } @@ -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)?; diff --git a/crates/misc/py/src/lib.rs b/crates/misc/py/src/lib.rs index 7247b1e867..2bb164ddd2 100644 --- a/crates/misc/py/src/lib.rs +++ b/crates/misc/py/src/lib.rs @@ -122,10 +122,8 @@ pub fn instantiate( } } - let instance = wasmtime::HostRef::new( - wasmtime::Instance::new(&store, &module, &imports) - .map_err(|t| PyErr::new::(format!("instantiated with trap {:?}", t)))?, - ); + let instance = wasmtime::Instance::new(&store, &module, &imports) + .map_err(|t| PyErr::new::(format!("instantiated with trap {:?}", t)))?; let module = Py::new(py, Module { module })?; diff --git a/crates/misc/py/src/memory.rs b/crates/misc/py/src/memory.rs index c6e8430ebe..1a43c82d84 100644 --- a/crates/misc/py/src/memory.rs +++ b/crates/misc/py/src/memory.rs @@ -10,14 +10,14 @@ use std::ptr; #[pyclass] pub struct Memory { - pub memory: wasmtime::HostRef, + 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; diff --git a/crates/misc/rust/macro/src/lib.rs b/crates/misc/rust/macro/src/lib.rs index b70cccfa61..2d91664dd5 100644 --- a/crates/misc/rust/macro/src/lib.rs +++ b/crates/misc/rust/macro/src/lib.rs @@ -34,7 +34,7 @@ fn generate_struct(item: &syn::ItemTrait) -> syn::Result { 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 { #vis fn load_file(path: impl AsRef) -> #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 { } } } - 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 }) } diff --git a/crates/test-programs/tests/wasm_tests/runtime.rs b/crates/test-programs/tests/wasm_tests/runtime.rs index 0970d31f26..c24ce862c3 100644 --- a/crates/test-programs/tests/wasm_tests/runtime.rs +++ b/crates/test-programs/tests/wasm_tests/runtime.rs @@ -1,7 +1,7 @@ use anyhow::{bail, Context}; use std::fs::File; use std::path::Path; -use wasmtime::{HostRef, Instance, Module, Store}; +use wasmtime::{Instance, Module, Store}; pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> anyhow::Result<()> { let store = Store::default(); @@ -61,13 +61,12 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any }) .collect::, _>>()?; - let instance = HostRef::new(Instance::new(&store, &module, &imports).context(format!( + let instance = Instance::new(&store, &module, &imports).context(format!( "error while instantiating Wasm module '{}'", bin_name, - ))?); + ))?; let export = instance - .borrow() .find_export_by_name("_start") .context("expected a _start export")? .clone(); @@ -75,7 +74,6 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any if let Err(trap) = export .func() .context("expected export to be a func")? - .borrow() .call(&[]) { bail!("trapped: {:?}", trap); diff --git a/crates/wast/src/spectest.rs b/crates/wast/src/spectest.rs index 8d906f56c6..fb2cb96de6 100644 --- a/crates/wast/src/spectest.rs +++ b/crates/wast/src/spectest.rs @@ -31,35 +31,35 @@ pub fn instantiate_spectest(store: &Store) -> HashMap<&'static str, Extern> { let ty = FuncType::new(Box::new([]), Box::new([])); let func = wrap(store, ty, |_params, _results| Ok(())); - ret.insert("print", Extern::Func(HostRef::new(func))); + ret.insert("print", Extern::Func(func)); let ty = FuncType::new(Box::new([ValType::I32]), Box::new([])); let func = wrap(store, ty, |params, _results| { println!("{}: i32", params[0].unwrap_i32()); Ok(()) }); - ret.insert("print_i32", Extern::Func(HostRef::new(func))); + ret.insert("print_i32", Extern::Func(func)); let ty = FuncType::new(Box::new([ValType::I64]), Box::new([])); let func = wrap(store, ty, |params, _results| { println!("{}: i64", params[0].unwrap_i64()); Ok(()) }); - ret.insert("print_i64", Extern::Func(HostRef::new(func))); + ret.insert("print_i64", Extern::Func(func)); let ty = FuncType::new(Box::new([ValType::F32]), Box::new([])); let func = wrap(store, ty, |params, _results| { println!("{}: f32", params[0].unwrap_f32()); Ok(()) }); - ret.insert("print_f32", Extern::Func(HostRef::new(func))); + ret.insert("print_f32", Extern::Func(func)); let ty = FuncType::new(Box::new([ValType::F64]), Box::new([])); let func = wrap(store, ty, |params, _results| { println!("{}: f64", params[0].unwrap_f64()); Ok(()) }); - ret.insert("print_f64", Extern::Func(HostRef::new(func))); + ret.insert("print_f64", Extern::Func(func)); let ty = FuncType::new(Box::new([ValType::I32, ValType::F32]), Box::new([])); let func = wrap(store, ty, |params, _results| { @@ -67,7 +67,7 @@ pub fn instantiate_spectest(store: &Store) -> HashMap<&'static str, Extern> { println!("{}: f32", params[1].unwrap_f32()); Ok(()) }); - ret.insert("print_i32_f32", Extern::Func(HostRef::new(func))); + ret.insert("print_i32_f32", Extern::Func(func)); let ty = FuncType::new(Box::new([ValType::F64, ValType::F64]), Box::new([])); let func = wrap(store, ty, |params, _results| { @@ -75,31 +75,31 @@ pub fn instantiate_spectest(store: &Store) -> HashMap<&'static str, Extern> { println!("{}: f64", params[1].unwrap_f64()); Ok(()) }); - ret.insert("print_f64_f64", Extern::Func(HostRef::new(func))); + ret.insert("print_f64_f64", Extern::Func(func)); let ty = GlobalType::new(ValType::I32, Mutability::Const); let g = Global::new(store, ty, Val::I32(666)); - ret.insert("global_i32", Extern::Global(HostRef::new(g))); + ret.insert("global_i32", Extern::Global(g)); let ty = GlobalType::new(ValType::I64, Mutability::Const); let g = Global::new(store, ty, Val::I64(666)); - ret.insert("global_i64", Extern::Global(HostRef::new(g))); + ret.insert("global_i64", Extern::Global(g)); let ty = GlobalType::new(ValType::F32, Mutability::Const); let g = Global::new(store, ty, Val::F32(0x4426_8000)); - ret.insert("global_f32", Extern::Global(HostRef::new(g))); + ret.insert("global_f32", Extern::Global(g)); let ty = GlobalType::new(ValType::F64, Mutability::Const); let g = Global::new(store, ty, Val::F64(0x4084_d000_0000_0000)); - ret.insert("global_f64", Extern::Global(HostRef::new(g))); + ret.insert("global_f64", Extern::Global(g)); let ty = TableType::new(ValType::FuncRef, Limits::new(10, Some(20))); let table = Table::new(store, ty, Val::AnyRef(AnyRef::Null)); - ret.insert("table", Extern::Table(HostRef::new(table))); + ret.insert("table", Extern::Table(table)); let ty = MemoryType::new(Limits::new(1, Some(2))); let memory = Memory::new(store, ty); - ret.insert("memory", Extern::Memory(HostRef::new(memory))); + ret.insert("memory", Extern::Memory(memory)); return ret; } diff --git a/crates/wast/src/wast.rs b/crates/wast/src/wast.rs index 4f8f2ba0c6..3299b4f67f 100644 --- a/crates/wast/src/wast.rs +++ b/crates/wast/src/wast.rs @@ -27,9 +27,9 @@ fn runtime_value(v: &wast::Expression<'_>) -> Result { pub struct WastContext { /// Wast files have a concept of a "current" module, which is the most /// recently defined. - current: Option>, + current: Option, - instances: HashMap>, + instances: HashMap, store: Store, spectest: Option>, } @@ -50,7 +50,7 @@ impl WastContext { } } - fn get_instance(&self, instance_name: Option<&str>) -> Result> { + fn get_instance(&self, instance_name: Option<&str>) -> Result { match instance_name { Some(name) => self .instances @@ -64,7 +64,7 @@ impl WastContext { } } - fn instantiate(&self, module: &[u8]) -> Result>> { + fn instantiate(&self, module: &[u8]) -> Result> { let module = Module::new(&self.store, module)?; let mut imports = Vec::new(); for import in module.imports() { @@ -85,7 +85,6 @@ impl WastContext { .get(import.module()) .ok_or_else(|| anyhow!("no module named `{}`", import.module()))?; let export = instance - .borrow() .find_export_by_name(import.name()) .ok_or_else(|| anyhow!("unknown import `{}::{}`", import.name(), import.module()))? .clone(); @@ -101,7 +100,7 @@ impl WastContext { return Err(e); } }; - Ok(Outcome::Ok(HostRef::new(instance))) + Ok(Outcome::Ok(instance)) } /// Register "spectest" which is used by the spec testsuite. @@ -159,12 +158,11 @@ impl WastContext { ) -> Result { let values = args.iter().map(runtime_value).collect::>>()?; let instance = self.get_instance(instance_name.as_ref().map(|x| &**x))?; - let instance = instance.borrow(); let export = instance .find_export_by_name(field) .ok_or_else(|| anyhow!("no global named `{}`", field))?; let func = match export { - Extern::Func(f) => f.borrow(), + Extern::Func(f) => f, _ => bail!("export of `{}` wasn't a global", field), }; Ok(match func.call(&values) { @@ -176,12 +174,11 @@ impl WastContext { /// Get the value of an exported global from an instance. fn get(&mut self, instance_name: Option<&str>, field: &str) -> Result { let instance = self.get_instance(instance_name.as_ref().map(|x| &**x))?; - let instance = instance.borrow(); let export = instance .find_export_by_name(field) .ok_or_else(|| anyhow!("no global named `{}`", field))?; let global = match export { - Extern::Global(g) => g.borrow(), + Extern::Global(g) => g, _ => bail!("export of `{}` wasn't a global", field), }; Ok(Outcome::Ok(vec![global.get()])) diff --git a/src/commands/run.rs b/src/commands/run.rs index 3a71dc1900..3dd9a48033 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -11,7 +11,7 @@ use std::{ }; use structopt::{clap::AppSettings, StructOpt}; use wasi_common::preopen_dir; -use wasmtime::{Config, Engine, HostRef, Instance, Module, Store}; +use wasmtime::{Config, Engine, Instance, Module, Store}; use wasmtime_environ::cache_init; use wasmtime_interface_types::ModuleData; use wasmtime_wasi::{ @@ -148,7 +148,7 @@ impl RunCommand { let preopen_dirs = self.compute_preopen_dirs()?; let argv = self.compute_argv(); - let wasi_unstable = HostRef::new(if self.enable_wasi_c { + let wasi_unstable = if self.enable_wasi_c { #[cfg(feature = "wasi-c")] { let global_exports = store.global_exports().clone(); @@ -161,14 +161,10 @@ impl RunCommand { } } else { create_wasi_instance_snapshot_0(&store, &preopen_dirs, &argv, &self.vars)? - }); + }; - let wasi_snapshot_preview1 = HostRef::new(create_wasi_instance( - &store, - &preopen_dirs, - &argv, - &self.vars, - )?); + let wasi_snapshot_preview1 = + create_wasi_instance(&store, &preopen_dirs, &argv, &self.vars)?; module_registry.insert("wasi_unstable".to_owned(), wasi_unstable); module_registry.insert("wasi_snapshot_preview1".to_owned(), wasi_snapshot_preview1); @@ -232,9 +228,9 @@ impl RunCommand { fn instantiate_module( store: &Store, - module_registry: &HashMap>, + module_registry: &HashMap, path: &Path, - ) -> Result<(HostRef, Module, Vec)> { + ) -> Result<(Instance, Module, Vec)> { // Read the wasm module binary either as `*.wat` or a raw binary let data = wat::parse_file(path)?; @@ -248,7 +244,7 @@ impl RunCommand { let module_name = i.module(); if let Some(instance) = module_registry.get(module_name) { let field_name = i.name(); - if let Some(export) = instance.borrow().find_export_by_name(field_name) { + if let Some(export) = instance.find_export_by_name(field_name) { Ok(export.clone()) } else { bail!( @@ -263,10 +259,8 @@ impl RunCommand { }) .collect::, _>>()?; - let instance = HostRef::new( - Instance::new(store, &module, &imports) - .context(format!("failed to instantiate {:?}", path))?, - ); + let instance = Instance::new(store, &module, &imports) + .context(format!("failed to instantiate {:?}", path))?; Ok((instance, module, data)) } @@ -274,7 +268,7 @@ impl RunCommand { fn handle_module( &self, store: &Store, - module_registry: &HashMap>, + module_registry: &HashMap, ) -> Result<()> { let (instance, module, data) = Self::instantiate_module(store, module_registry, &self.module)?; @@ -301,16 +295,11 @@ impl RunCommand { Ok(()) } - fn invoke_export( - &self, - instance: HostRef, - data: &ModuleData, - name: &str, - ) -> Result<()> { + fn invoke_export(&self, instance: Instance, data: &ModuleData, name: &str) -> Result<()> { use wasm_webidl_bindings::ast; use wasmtime_interface_types::Value; - let mut handle = instance.borrow().handle().clone(); + let mut handle = instance.handle().clone(); // Use the binding information in `ModuleData` to figure out what arguments // need to be passed to the function that we're invoking. Currently we take diff --git a/tests/custom_signal_handler.rs b/tests/custom_signal_handler.rs index 613bb2db04..66a449fb22 100644 --- a/tests/custom_signal_handler.rs +++ b/tests/custom_signal_handler.rs @@ -1,6 +1,5 @@ #[cfg(not(target_os = "windows"))] mod tests { - use core::cell::Ref; use std::rc::Rc; use std::sync::atomic::{AtomicBool, Ordering}; use wasmtime::*; @@ -38,7 +37,7 @@ mod tests { "#; fn invoke_export( - instance: &HostRef, + instance: &Instance, data: &[u8], func_name: &str, ) -> Result, anyhow::Error> { @@ -46,8 +45,8 @@ mod tests { } // Locate "memory" export, get base address and size and set memory protection to PROT_NONE - fn set_up_memory(instance: &HostRef) -> (*mut u8, usize) { - let mem_export = instance.borrow().get_wasmtime_memory().expect("memory"); + fn set_up_memory(instance: &Instance) -> (*mut u8, usize) { + let mem_export = instance.get_wasmtime_memory().expect("memory"); let (base, length) = if let wasmtime_runtime::Export::Memory { definition, @@ -107,16 +106,14 @@ mod tests { let store = Store::new(&engine); let data = wat::parse_str(WAT1)?; let module = Module::new(&store, &data)?; - let instance = HostRef::new(Instance::new(&store, &module, &[])?); + let instance = Instance::new(&store, &module, &[])?; let (base, length) = set_up_memory(&instance); - instance - .borrow_mut() - .set_signal_handler(move |signum, siginfo, _| { - handle_sigsegv(base, length, signum, siginfo) - }); + instance.set_signal_handler(move |signum, siginfo, _| { + handle_sigsegv(base, length, signum, siginfo) + }); - let exports = Ref::map(instance.borrow(), |instance| instance.exports()); + let exports = instance.exports(); assert!(!exports.is_empty()); // these invoke wasmtime_call_trampoline from action.rs @@ -140,10 +137,7 @@ mod tests { .func() .expect("expected a 'read' func in the module"); println!("calling read..."); - let result = read_func - .borrow() - .call(&[]) - .expect("expected function not to trap"); + let result = read_func.call(&[]).expect("expected function not to trap"); assert_eq!(123i32, result[0].clone().unwrap_i32()); } @@ -152,7 +146,7 @@ mod tests { .func() .expect("expected a 'read_out_of_bounds' func in the module"); println!("calling read_out_of_bounds..."); - let trap = read_out_of_bounds_func.borrow().call(&[]).unwrap_err(); + let trap = read_out_of_bounds_func.call(&[]).unwrap_err(); assert!(trap .message() .starts_with("call error: wasm trap: out of bounds memory access")); @@ -169,13 +163,13 @@ mod tests { // Set up multiple instances - let instance1 = HostRef::new(Instance::new(&store, &module, &[])?); + let instance1 = Instance::new(&store, &module, &[])?; let instance1_handler_triggered = Rc::new(AtomicBool::new(false)); { let (base1, length1) = set_up_memory(&instance1); - instance1.borrow_mut().set_signal_handler({ + instance1.set_signal_handler({ let instance1_handler_triggered = instance1_handler_triggered.clone(); move |_signum, _siginfo, _context| { // Remove protections so the execution may resume @@ -196,15 +190,13 @@ mod tests { }); } - let instance2 = HostRef::new( - Instance::new(&store, &module, &[]).expect("failed to instantiate module"), - ); + let instance2 = Instance::new(&store, &module, &[]).expect("failed to instantiate module"); let instance2_handler_triggered = Rc::new(AtomicBool::new(false)); { let (base2, length2) = set_up_memory(&instance2); - instance2.borrow_mut().set_signal_handler({ + instance2.set_signal_handler({ let instance2_handler_triggered = instance2_handler_triggered.clone(); move |_signum, _siginfo, _context| { // Remove protections so the execution may resume @@ -229,7 +221,7 @@ mod tests { // First instance1 { - let exports1 = Ref::map(instance1.borrow(), |i| i.exports()); + let exports1 = instance1.exports(); assert!(!exports1.is_empty()); println!("calling instance1.read..."); @@ -244,7 +236,7 @@ mod tests { // And then instance2 { - let exports2 = Ref::map(instance2.borrow(), |i| i.exports()); + let exports2 = instance2.exports(); assert!(!exports2.is_empty()); println!("calling instance2.read..."); @@ -267,30 +259,26 @@ mod tests { // instance1 which defines 'read' let data1 = wat::parse_str(WAT1)?; let module1 = Module::new(&store, &data1)?; - let instance1: HostRef = HostRef::new(Instance::new(&store, &module1, &[])?); + let instance1 = Instance::new(&store, &module1, &[])?; let (base1, length1) = set_up_memory(&instance1); - instance1 - .borrow_mut() - .set_signal_handler(move |signum, siginfo, _| { - println!("instance1"); - handle_sigsegv(base1, length1, signum, siginfo) - }); + instance1.set_signal_handler(move |signum, siginfo, _| { + println!("instance1"); + handle_sigsegv(base1, length1, signum, siginfo) + }); - let instance1_exports = Ref::map(instance1.borrow(), |i| i.exports()); + let instance1_exports = instance1.exports(); assert!(!instance1_exports.is_empty()); let instance1_read = instance1_exports[0].clone(); // instance2 wich calls 'instance1.read' let data2 = wat::parse_str(WAT2)?; let module2 = Module::new(&store, &data2)?; - let instance2 = HostRef::new(Instance::new(&store, &module2, &[instance1_read])?); + let instance2 = Instance::new(&store, &module2, &[instance1_read])?; // since 'instance2.run' calls 'instance1.read' we need to set up the signal handler to handle // SIGSEGV originating from within the memory of instance1 - instance2 - .borrow_mut() - .set_signal_handler(move |signum, siginfo, _| { - handle_sigsegv(base1, length1, signum, siginfo) - }); + instance2.set_signal_handler(move |signum, siginfo, _| { + handle_sigsegv(base1, length1, signum, siginfo) + }); println!("calling instance2.run"); let result = invoke_export(&instance2, &data2, "run")?;