From 63f0f028948c9e5a0c156d9aabf00f3e26be9ada Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 3 Nov 2020 13:07:30 -0800 Subject: [PATCH] Store `WasmFuncType` in `FuncType` This commit updates `wasmtime::FuncType` to exactly store an internal `WasmFuncType` from the cranelift crates. This allows us to remove a translation layer when we are given a `FuncType` and want to get an internal cranelift type out as a result. The other major change from this commit was changing the constructor and accessors of `FuncType` to be iterator-based instead of exposing implementation details. --- crates/c-api/src/types/func.rs | 16 +----- crates/fuzzing/src/oracles/dummy.rs | 12 ++-- crates/wasmtime/src/func.rs | 78 +++++++++++++------------- crates/wasmtime/src/linker.rs | 2 +- crates/wasmtime/src/trampoline/func.rs | 8 +-- crates/wasmtime/src/types.rs | 60 ++++++++------------ crates/wasmtime/src/values.rs | 2 +- examples/multi.rs | 4 +- examples/threads.rs | 10 +--- tests/all/func.rs | 34 +++++------ tests/all/import_calling_export.rs | 28 ++++----- tests/all/import_indexes.rs | 4 +- tests/all/traps.rs | 10 ++-- 13 files changed, 118 insertions(+), 150 deletions(-) diff --git a/crates/c-api/src/types/func.rs b/crates/c-api/src/types/func.rs index 0417e3ac32dd..1b4ca752febf 100644 --- a/crates/c-api/src/types/func.rs +++ b/crates/c-api/src/types/func.rs @@ -54,17 +54,9 @@ pub extern "C" fn wasm_functype_new( params: &mut wasm_valtype_vec_t, results: &mut wasm_valtype_vec_t, ) -> Box { - let params = params - .take() - .into_iter() - .map(|vt| vt.unwrap().ty.clone()) - .collect::>(); - let results = results - .take() - .into_iter() - .map(|vt| vt.unwrap().ty.clone()) - .collect::>(); - let functype = FuncType::new(params.into_boxed_slice(), results.into_boxed_slice()); + let params = params.take().into_iter().map(|vt| vt.unwrap().ty.clone()); + let results = results.take().into_iter().map(|vt| vt.unwrap().ty.clone()); + let functype = FuncType::new(params, results); Box::new(wasm_functype_t::new(functype)) } @@ -74,7 +66,6 @@ pub extern "C" fn wasm_functype_params(ft: &wasm_functype_t) -> &wasm_valtype_ve ft.params_cache.get_or_init(|| { ft.ty .params() - .iter() .map(|p| Some(Box::new(wasm_valtype_t { ty: p.clone() }))) .collect::>() .into() @@ -87,7 +78,6 @@ pub extern "C" fn wasm_functype_results(ft: &wasm_functype_t) -> &wasm_valtype_v ft.returns_cache.get_or_init(|| { ft.ty .results() - .iter() .map(|p| Some(Box::new(wasm_valtype_t { ty: p.clone() }))) .collect::>() .into() diff --git a/crates/fuzzing/src/oracles/dummy.rs b/crates/fuzzing/src/oracles/dummy.rs index 1dc35ed3ad78..e58dc371d3be 100644 --- a/crates/fuzzing/src/oracles/dummy.rs +++ b/crates/fuzzing/src/oracles/dummy.rs @@ -25,7 +25,7 @@ pub fn dummy_imports<'module>( /// Construct a dummy function for the given function type pub fn dummy_func(store: &Store, ty: FuncType) -> Func { Func::new(store, ty.clone(), move |_, _, results| { - for (ret_ty, result) in ty.results().iter().zip(results) { + for (ret_ty, result) in ty.results().zip(results) { *result = dummy_value(ret_ty)?; } Ok(()) @@ -33,7 +33,7 @@ pub fn dummy_func(store: &Store, ty: FuncType) -> Func { } /// Construct a dummy value for the given value type. -pub fn dummy_value(val_ty: &ValType) -> Result { +pub fn dummy_value(val_ty: ValType) -> Result { Ok(match val_ty { ValType::I32 => Val::I32(0), ValType::I64 => Val::I64(0), @@ -58,19 +58,19 @@ pub fn dummy_value(val_ty: &ValType) -> Result { } /// Construct a sequence of dummy values for the given types. -pub fn dummy_values(val_tys: &[ValType]) -> Result, Trap> { - val_tys.iter().map(dummy_value).collect() +pub fn dummy_values(val_tys: impl IntoIterator) -> Result, Trap> { + val_tys.into_iter().map(dummy_value).collect() } /// Construct a dummy global for the given global type. pub fn dummy_global(store: &Store, ty: GlobalType) -> Result { - let val = dummy_value(ty.content())?; + let val = dummy_value(ty.content().clone())?; Ok(Global::new(store, ty, val).unwrap()) } /// Construct a dummy table for the given table type. pub fn dummy_table(store: &Store, ty: TableType) -> Result { - let init_val = dummy_value(&ty.element())?; + let init_val = dummy_value(ty.element().clone())?; Ok(Table::new(store, ty, init_val).unwrap()) } diff --git a/crates/wasmtime/src/func.rs b/crates/wasmtime/src/func.rs index 7b7153002442..c053432a3890 100644 --- a/crates/wasmtime/src/func.rs +++ b/crates/wasmtime/src/func.rs @@ -113,8 +113,8 @@ use wasmtime_runtime::{ /// // Here we need to define the type signature of our `Double` function and /// // then wrap it up in a `Func` /// let double_type = wasmtime::FuncType::new( -/// Box::new([wasmtime::ValType::I32]), -/// Box::new([wasmtime::ValType::I32]) +/// [wasmtime::ValType::I32].iter().cloned(), +/// [wasmtime::ValType::I32].iter().cloned(), /// ); /// let double = Func::new(&store, double_type, |_, params, results| { /// let mut value = params[0].unwrap_i32(); @@ -163,7 +163,7 @@ macro_rules! getters { // Verify all the paramers match the expected parameters, and that // there are no extra parameters... let ty = self.ty(); - let mut params = ty.params().iter().cloned(); + let mut params = ty.params(); let n = 0; $( let n = n + 1; @@ -173,7 +173,7 @@ macro_rules! getters { ensure!(params.next().is_none(), "Type mismatch: too many arguments (expected {})", n); // ... then do the same for the results... - let mut results = ty.results().iter().cloned(); + let mut results = ty.results(); R::matches(&mut results) .context("Type mismatch in return type")?; ensure!(results.next().is_none(), "Type mismatch: too many return values (expected 1)"); @@ -274,7 +274,7 @@ impl Func { let mut args: SmallVec<[Val; STACK_ARGS]> = SmallVec::with_capacity(ty_clone.params().len()); let store = Store::upgrade(&store_weak).unwrap(); - for (i, ty) in ty_clone.params().iter().enumerate() { + for (i, ty) in ty_clone.params().enumerate() { unsafe { let val = Val::read_value_from(&store, values_vec.add(i), ty); args.push(val); @@ -298,7 +298,7 @@ impl Func { // produces the wrong number or wrong types of values, and we need // to catch that here. for (i, (ret, ty)) in returns.into_iter().zip(ty_clone.results()).enumerate() { - if ret.ty() != *ty { + if ret.ty() != ty { return Err(Trap::new( "function attempted to return an incompatible value", )); @@ -596,9 +596,9 @@ impl Func { let mut values_vec = vec![0; max(params.len(), my_ty.results().len())]; // Store the argument values into `values_vec`. - let param_tys = my_ty.params().iter(); + let param_tys = my_ty.params(); for ((arg, slot), ty) in params.iter().cloned().zip(&mut values_vec).zip(param_tys) { - if arg.ty() != *ty { + if arg.ty() != ty { bail!( "argument type mismatch: found {} but expected {}", arg.ty(), @@ -628,7 +628,7 @@ impl Func { // Load the return values out of `values_vec`. let mut results = Vec::with_capacity(my_ty.results().len()); - for (index, ty) in my_ty.results().iter().enumerate() { + for (index, ty) in my_ty.results().enumerate() { unsafe { let ptr = values_vec.as_ptr().add(index); results.push(Val::read_value_from(&self.instance.store, ptr, ty)); @@ -876,7 +876,7 @@ pub unsafe trait WasmTy { // Add this type to the given vec of expected valtypes. #[doc(hidden)] - fn push(dst: &mut Vec); + fn valtype() -> Option; // Does the next valtype(s) match this type? #[doc(hidden)] @@ -923,7 +923,7 @@ pub unsafe trait WasmRet { // Same as `WasmTy::push`. #[doc(hidden)] - fn push(dst: &mut Vec); + fn valtype() -> Option; // Same as `WasmTy::matches`. #[doc(hidden)] @@ -952,7 +952,9 @@ unsafe impl WasmTy for () { #[inline] unsafe fn from_abi<'a>(_abi: Self::Abi, _store: WeakStore<'a>) -> Self {} - fn push(_dst: &mut Vec) {} + fn valtype() -> Option { + None + } fn matches(_tys: impl Iterator) -> anyhow::Result<()> { Ok(()) @@ -983,8 +985,8 @@ unsafe impl WasmTy for i32 { abi } - fn push(dst: &mut Vec) { - dst.push(ValType::I32); + fn valtype() -> Option { + Some(ValType::I32) } fn matches(mut tys: impl Iterator) -> anyhow::Result<()> { @@ -1028,8 +1030,8 @@ unsafe impl WasmTy for u32 { abi as Self } - fn push(dst: &mut Vec) { - ::push(dst) + fn valtype() -> Option { + ::valtype() } fn matches(tys: impl Iterator) -> anyhow::Result<()> { @@ -1065,8 +1067,8 @@ unsafe impl WasmTy for i64 { abi } - fn push(dst: &mut Vec) { - dst.push(ValType::I64); + fn valtype() -> Option { + Some(ValType::I64) } fn matches(mut tys: impl Iterator) -> anyhow::Result<()> { @@ -1110,8 +1112,8 @@ unsafe impl WasmTy for u64 { abi as Self } - fn push(dst: &mut Vec) { - ::push(dst) + fn valtype() -> Option { + ::valtype() } fn matches(tys: impl Iterator) -> anyhow::Result<()> { @@ -1147,8 +1149,8 @@ unsafe impl WasmTy for f32 { abi } - fn push(dst: &mut Vec) { - dst.push(ValType::F32); + fn valtype() -> Option { + Some(ValType::F32) } fn matches(mut tys: impl Iterator) -> anyhow::Result<()> { @@ -1192,8 +1194,8 @@ unsafe impl WasmTy for f64 { abi } - fn push(dst: &mut Vec) { - dst.push(ValType::F64); + fn valtype() -> Option { + Some(ValType::F64) } fn matches(mut tys: impl Iterator) -> anyhow::Result<()> { @@ -1254,8 +1256,8 @@ unsafe impl WasmTy for Option { } } - fn push(dst: &mut Vec) { - dst.push(ValType::ExternRef); + fn valtype() -> Option { + Some(ValType::ExternRef) } fn matches(mut tys: impl Iterator) -> anyhow::Result<()> { @@ -1307,8 +1309,8 @@ unsafe impl WasmTy for Option { Func::from_caller_checked_anyfunc(&store, abi) } - fn push(dst: &mut Vec) { - dst.push(ValType::FuncRef); + fn valtype() -> Option { + Some(ValType::FuncRef) } fn matches(mut tys: impl Iterator) -> anyhow::Result<()> { @@ -1353,9 +1355,8 @@ where ::from_abi(abi, store) } - #[inline] - fn push(dst: &mut Vec) { - ::push(dst) + fn valtype() -> Option { + ::valtype() } #[inline] @@ -1405,8 +1406,8 @@ where Ok(::from_abi(abi, store)) } - fn push(dst: &mut Vec) { - ::push(dst) + fn valtype() -> Option { + ::valtype() } fn matches(tys: impl Iterator) -> anyhow::Result<()> { @@ -1657,11 +1658,12 @@ macro_rules! impl_into_func { R::store_to_args(ret, args); } - let mut _args = Vec::new(); - $($args::push(&mut _args);)* - let mut ret = Vec::new(); - R::push(&mut ret); - let ty = FuncType::new(_args.into(), ret.into()); + let ty = FuncType::new( + None::.into_iter() + $(.chain($args::valtype()))* + , + R::valtype(), + ); let store_weak = store.weak(); let trampoline = host_trampoline::<$($args,)* R>; diff --git a/crates/wasmtime/src/linker.rs b/crates/wasmtime/src/linker.rs index c22b89bf41b6..1fb4b626382a 100644 --- a/crates/wasmtime/src/linker.rs +++ b/crates/wasmtime/src/linker.rs @@ -716,7 +716,7 @@ impl Linker { // Otherwise return a no-op function. Ok(Func::new( &self.store, - FuncType::new(Vec::new().into_boxed_slice(), Vec::new().into_boxed_slice()), + FuncType::new(None, None), move |_, _, _| Ok(()), )) } diff --git a/crates/wasmtime/src/trampoline/func.rs b/crates/wasmtime/src/trampoline/func.rs index 25a433385413..04a62db37970 100644 --- a/crates/wasmtime/src/trampoline/func.rs +++ b/crates/wasmtime/src/trampoline/func.rs @@ -214,7 +214,7 @@ pub fn create_handle_with_function( let pointer_type = isa.pointer_type(); let sig = ft.get_wasmtime_signature(pointer_type); - let wft = ft.to_wasm_func_type(); + let wft = ft.as_wasm_func_type(); let mut fn_builder_ctx = FunctionBuilderContext::new(); let mut module = Module::new(); @@ -241,7 +241,7 @@ pub fn create_handle_with_function( &sig, mem::size_of::(), )?; - store.signatures().borrow_mut().register(&wft, trampoline); + store.signatures().borrow_mut().register(wft, trampoline); // Next up we wrap everything up into an `InstanceHandle` by publishing our // code memory (makes it executable) and ensuring all our various bits of @@ -265,7 +265,7 @@ pub unsafe fn create_handle_with_raw_function( store: &Store, state: Box, ) -> Result { - let wft = ft.to_wasm_func_type(); + let wft = ft.as_wasm_func_type(); let mut module = Module::new(); let mut finished_functions = PrimaryMap::new(); @@ -276,7 +276,7 @@ pub unsafe fn create_handle_with_raw_function( .exports .insert(String::new(), EntityIndex::Function(func_id)); finished_functions.push(func); - store.signatures().borrow_mut().register(&wft, trampoline); + store.signatures().borrow_mut().register(wft, trampoline); create_handle(module, store, finished_functions, state, &[]) } diff --git a/crates/wasmtime/src/types.rs b/crates/wasmtime/src/types.rs index d8a3ad27b624..d859dd5883f6 100644 --- a/crates/wasmtime/src/types.rs +++ b/crates/wasmtime/src/types.rs @@ -1,4 +1,5 @@ use std::fmt; +use wasmtime_environ::wasm::WasmFuncType; use wasmtime_environ::{ir, wasm, EntityIndex}; // Type Representations @@ -217,8 +218,7 @@ impl From for ExternType { /// WebAssembly functions can have 0 or more parameters and results. #[derive(Debug, Clone, Hash, Eq, PartialEq)] pub struct FuncType { - params: Box<[ValType]>, - results: Box<[ValType]>, + sig: WasmFuncType, } impl FuncType { @@ -226,25 +226,30 @@ impl FuncType { /// /// The function descriptor returned will represent a function which takes /// `params` as arguments and returns `results` when it is finished. - pub fn new(params: Box<[ValType]>, results: Box<[ValType]>) -> FuncType { - FuncType { params, results } + pub fn new( + params: impl IntoIterator, + results: impl IntoIterator, + ) -> FuncType { + FuncType { + sig: WasmFuncType { + params: params.into_iter().map(|t| t.to_wasm_type()).collect(), + returns: results.into_iter().map(|t| t.to_wasm_type()).collect(), + }, + } } /// Returns the list of parameter types for this function. - pub fn params(&self) -> &[ValType] { - &self.params + pub fn params(&self) -> impl ExactSizeIterator + '_ { + self.sig.params.iter().map(ValType::from_wasm_type) } /// Returns the list of result types for this function. - pub fn results(&self) -> &[ValType] { - &self.results + pub fn results(&self) -> impl ExactSizeIterator + '_ { + self.sig.returns.iter().map(ValType::from_wasm_type) } - pub(crate) fn to_wasm_func_type(&self) -> wasm::WasmFuncType { - wasm::WasmFuncType { - params: self.params.iter().map(|p| p.to_wasm_type()).collect(), - returns: self.results.iter().map(|r| r.to_wasm_type()).collect(), - } + pub(crate) fn as_wasm_func_type(&self) -> &wasm::WasmFuncType { + &self.sig } /// Get the Cranelift-compatible function signature. @@ -256,14 +261,9 @@ impl FuncType { AbiParam::special(pointer_type, ArgumentPurpose::VMContext), AbiParam::new(pointer_type), ]; - params.extend( - self.params - .iter() - .map(|p| AbiParam::new(p.get_wasmtime_type())), - ); + params.extend(self.params().map(|p| AbiParam::new(p.get_wasmtime_type()))); let returns = self - .results - .iter() + .results() .map(|p| AbiParam::new(p.get_wasmtime_type())) .collect::>(); @@ -274,24 +274,8 @@ impl FuncType { } } - /// Returns `None` if any types in the signature can't be converted to the - /// types in this crate, but that should very rarely happen and largely only - /// indicate a bug in our cranelift integration. - pub(crate) fn from_wasm_func_type(signature: &wasm::WasmFuncType) -> FuncType { - let params = signature - .params - .iter() - .map(|p| ValType::from_wasm_type(p)) - .collect::>(); - let results = signature - .returns - .iter() - .map(|r| ValType::from_wasm_type(r)) - .collect::>(); - FuncType { - params: params.into_boxed_slice(), - results: results.into_boxed_slice(), - } + pub(crate) fn from_wasm_func_type(sig: &wasm::WasmFuncType) -> FuncType { + FuncType { sig: sig.clone() } } } diff --git a/crates/wasmtime/src/values.rs b/crates/wasmtime/src/values.rs index 2ec507a03777..4dc6474513e3 100644 --- a/crates/wasmtime/src/values.rs +++ b/crates/wasmtime/src/values.rs @@ -112,7 +112,7 @@ impl Val { } } - pub(crate) unsafe fn read_value_from(store: &Store, p: *const u128, ty: &ValType) -> Val { + pub(crate) unsafe fn read_value_from(store: &Store, p: *const u128, ty: ValType) -> Val { match ty { ValType::I32 => Val::I32(ptr::read(p as *const i32)), ValType::I64 => Val::I64(ptr::read(p as *const i64)), diff --git a/examples/multi.rs b/examples/multi.rs index f39fd27985cf..67f1c4b6ee5a 100644 --- a/examples/multi.rs +++ b/examples/multi.rs @@ -22,8 +22,8 @@ fn main() -> Result<()> { // Create external print functions. println!("Creating callback..."); let callback_type = FuncType::new( - Box::new([ValType::I32, ValType::I64]), - Box::new([ValType::I64, ValType::I32]), + [ValType::I32, ValType::I64].iter().cloned(), + [ValType::I64, ValType::I32].iter().cloned(), ); let callback_func = Func::new(&store, callback_type, |_, args, results| { println!("Calling back..."); diff --git a/examples/threads.rs b/examples/threads.rs index 3d3ffe8e573a..5bef1f9540bf 100644 --- a/examples/threads.rs +++ b/examples/threads.rs @@ -8,18 +8,14 @@ use wasmtime::*; const N_THREADS: i32 = 10; const N_REPS: i32 = 3; -fn print_message(_: Caller<'_>, args: &[Val], _: &mut [Val]) -> Result<(), Trap> { - println!("> Thread {} is running", args[0].unwrap_i32()); - Ok(()) -} - fn run(engine: &Engine, module: Module, id: i32) -> Result<()> { let store = Store::new(&engine); // Create external print functions. println!("Creating callback..."); - let callback_type = FuncType::new(Box::new([ValType::I32]), Box::new([])); - let callback_func = Func::new(&store, callback_type, print_message); + let callback_func = Func::wrap(&store, |arg: i32| { + println!("> Thread {} is running", arg); + }); let id_type = GlobalType::new(ValType::I32, Mutability::Const); let id_global = Global::new(&store, id_type, Val::I32(id))?; diff --git a/tests/all/func.rs b/tests/all/func.rs index 953976e1e4d6..fca6aed8149a 100644 --- a/tests/all/func.rs +++ b/tests/all/func.rs @@ -78,26 +78,26 @@ fn signatures_match() { let store = Store::default(); let f = Func::wrap(&store, || {}); - assert_eq!(f.ty().params(), &[]); + assert_eq!(f.ty().params().collect::>(), &[]); assert_eq!(f.param_arity(), 0); - assert_eq!(f.ty().results(), &[]); + assert_eq!(f.ty().results().collect::>(), &[]); assert_eq!(f.result_arity(), 0); let f = Func::wrap(&store, || -> i32 { loop {} }); - assert_eq!(f.ty().params(), &[]); - assert_eq!(f.ty().results(), &[ValType::I32]); + assert_eq!(f.ty().params().collect::>(), &[]); + assert_eq!(f.ty().results().collect::>(), &[ValType::I32]); let f = Func::wrap(&store, || -> i64 { loop {} }); - assert_eq!(f.ty().params(), &[]); - assert_eq!(f.ty().results(), &[ValType::I64]); + assert_eq!(f.ty().params().collect::>(), &[]); + assert_eq!(f.ty().results().collect::>(), &[ValType::I64]); let f = Func::wrap(&store, || -> f32 { loop {} }); - assert_eq!(f.ty().params(), &[]); - assert_eq!(f.ty().results(), &[ValType::F32]); + assert_eq!(f.ty().params().collect::>(), &[]); + assert_eq!(f.ty().results().collect::>(), &[ValType::F32]); let f = Func::wrap(&store, || -> f64 { loop {} }); - assert_eq!(f.ty().params(), &[]); - assert_eq!(f.ty().results(), &[ValType::F64]); + assert_eq!(f.ty().params().collect::>(), &[]); + assert_eq!(f.ty().results().collect::>(), &[ValType::F64]); let f = Func::wrap( &store, @@ -106,7 +106,7 @@ fn signatures_match() { }, ); assert_eq!( - f.ty().params(), + f.ty().params().collect::>(), &[ ValType::F32, ValType::F64, @@ -117,7 +117,7 @@ fn signatures_match() { ValType::FuncRef, ] ); - assert_eq!(f.ty().results(), &[ValType::F64]); + assert_eq!(f.ty().results().collect::>(), &[ValType::F64]); } #[test] @@ -283,13 +283,13 @@ fn get_from_wrapper() { #[test] fn get_from_signature() { let store = Store::default(); - let ty = FuncType::new(Box::new([]), Box::new([])); + let ty = FuncType::new(None, None); let f = Func::new(&store, ty, |_, _, _| panic!()); assert!(f.get0::<()>().is_ok()); assert!(f.get0::().is_err()); assert!(f.get1::().is_err()); - let ty = FuncType::new(Box::new([ValType::I32]), Box::new([ValType::F64])); + let ty = FuncType::new(Some(ValType::I32), Some(ValType::F64)); let f = Func::new(&store, ty, |_, _, _| panic!()); assert!(f.get0::<()>().is_err()); assert!(f.get0::().is_err()); @@ -434,7 +434,7 @@ fn caller_memory() -> anyhow::Result<()> { #[test] fn func_write_nothing() -> anyhow::Result<()> { let store = Store::default(); - let ty = FuncType::new(Box::new([]), Box::new([ValType::I32])); + let ty = FuncType::new(None, Some(ValType::I32)); let f = Func::new(&store, ty, |_, _, _| Ok(())); let err = f.call(&[]).unwrap_err().downcast::()?; assert!(err @@ -515,8 +515,8 @@ fn externref_signature_no_reference_types() -> anyhow::Result<()> { Func::new( &store, FuncType::new( - Box::new([ValType::FuncRef, ValType::ExternRef]), - Box::new([ValType::FuncRef, ValType::ExternRef]), + [ValType::FuncRef, ValType::ExternRef].iter().cloned(), + [ValType::FuncRef, ValType::ExternRef].iter().cloned(), ), |_, _, _| Ok(()), ); diff --git a/tests/all/import_calling_export.rs b/tests/all/import_calling_export.rs index 09eb80979f6b..3fc87e2d4663 100644 --- a/tests/all/import_calling_export.rs +++ b/tests/all/import_calling_export.rs @@ -22,21 +22,17 @@ fn test_import_calling_export() { let other = Rc::new(RefCell::new(None::)); let other2 = Rc::downgrade(&other); - let callback_func = Func::new( - &store, - FuncType::new(Box::new([]), Box::new([])), - move |_, _, _| { - other2 - .upgrade() - .unwrap() - .borrow() - .as_ref() - .expect("expected a function ref") - .call(&[]) - .expect("expected function not to trap"); - Ok(()) - }, - ); + let callback_func = Func::new(&store, FuncType::new(None, None), move |_, _, _| { + other2 + .upgrade() + .unwrap() + .borrow() + .as_ref() + .expect("expected a function ref") + .call(&[]) + .expect("expected function not to trap"); + Ok(()) + }); let imports = vec![callback_func.into()]; let instance = @@ -71,7 +67,7 @@ fn test_returns_incorrect_type() -> Result<()> { let callback_func = Func::new( &store, - FuncType::new(Box::new([]), Box::new([ValType::I32])), + FuncType::new(None, Some(ValType::I32)), |_, _, results| { // Evil! Returns I64 here instead of promised in the signature I32. results[0] = Val::I64(228); diff --git a/tests/all/import_indexes.rs b/tests/all/import_indexes.rs index d9cd06cd6694..3577467c3b07 100644 --- a/tests/all/import_indexes.rs +++ b/tests/all/import_indexes.rs @@ -20,7 +20,7 @@ fn same_import_names_still_distinct() -> anyhow::Result<()> { let imports = [ Func::new( &store, - FuncType::new(Box::new([]), Box::new([ValType::I32])), + FuncType::new(None, Some(ValType::I32)), |_, params, results| { assert!(params.is_empty()); assert_eq!(results.len(), 1); @@ -31,7 +31,7 @@ fn same_import_names_still_distinct() -> anyhow::Result<()> { .into(), Func::new( &store, - FuncType::new(Box::new([]), Box::new([ValType::F32])), + FuncType::new(None, Some(ValType::F32)), |_, params, results| { assert!(params.is_empty()); assert_eq!(results.len(), 1); diff --git a/tests/all/traps.rs b/tests/all/traps.rs index 8919bd123fa0..0a8196a0d408 100644 --- a/tests/all/traps.rs +++ b/tests/all/traps.rs @@ -13,7 +13,7 @@ fn test_trap_return() -> Result<()> { "#; let module = Module::new(store.engine(), wat)?; - let hello_type = FuncType::new(Box::new([]), Box::new([])); + let hello_type = FuncType::new(None, None); let hello_func = Func::new(&store, hello_type, |_, _, _| Err(Trap::new("test 123"))); let instance = Instance::new(&store, &module, &[hello_func.into()])?; @@ -86,7 +86,7 @@ fn test_trap_trace_cb() -> Result<()> { ) "#; - let fn_type = FuncType::new(Box::new([]), Box::new([])); + let fn_type = FuncType::new(None, None); let fn_func = Func::new(&store, fn_type, |_, _, _| Err(Trap::new("cb throw"))); let module = Module::new(store.engine(), wat)?; @@ -237,7 +237,7 @@ fn trap_start_function_import() -> Result<()> { )?; let module = Module::new(store.engine(), &binary)?; - let sig = FuncType::new(Box::new([]), Box::new([])); + let sig = FuncType::new(None, None); let func = Func::new(&store, sig, |_, _, _| Err(Trap::new("user trap"))); let err = Instance::new(&store, &module, &[func.into()]) .err() @@ -267,7 +267,7 @@ fn rust_panic_import() -> Result<()> { )?; let module = Module::new(store.engine(), &binary)?; - let sig = FuncType::new(Box::new([]), Box::new([])); + let sig = FuncType::new(None, None); let func = Func::new(&store, sig, |_, _, _| panic!("this is a panic")); let instance = Instance::new( &store, @@ -311,7 +311,7 @@ fn rust_panic_start_function() -> Result<()> { )?; let module = Module::new(store.engine(), &binary)?; - let sig = FuncType::new(Box::new([]), Box::new([])); + let sig = FuncType::new(None, None); let func = Func::new(&store, sig, |_, _, _| panic!("this is a panic")); let err = panic::catch_unwind(AssertUnwindSafe(|| { drop(Instance::new(&store, &module, &[func.into()]));