From f2ba42b7b2cf3d8475bf338dcf4f162ca2cd9e63 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 29 Jun 2022 16:49:51 +0200 Subject: [PATCH] Intermediary work on internal tests --- lib/api/src/sys/externals/function.rs | 178 +++---- lib/api/src/sys/imports.rs | 66 +-- lib/api/src/sys/native_type.rs | 3 +- lib/api/src/sys/value.rs | 52 +- lib/api/tests/sys_export.rs | 334 ------------- lib/api/tests/sys_externals.rs | 374 ++++++++------ lib/api/tests/sys_instance.rs | 26 +- lib/api/tests/sys_module.rs | 68 ++- lib/api/tests/sys_reference_types.rs | 681 +++++++++++++------------- lib/derive/tests/basic.rs | 119 ----- lib/middlewares/src/metering.rs | 25 +- lib/types/src/value.rs | 27 + tests/compilers/imports.rs | 87 ++-- tests/compilers/issues.rs | 20 +- tests/compilers/metering.rs | 16 +- tests/compilers/middlewares.rs | 21 +- tests/compilers/native_functions.rs | 10 +- tests/compilers/traps.rs | 12 +- 18 files changed, 871 insertions(+), 1248 deletions(-) delete mode 100644 lib/api/tests/sys_export.rs delete mode 100644 lib/derive/tests/basic.rs diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index cdb0d0ad641..9d6e2d64481 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -1229,19 +1229,23 @@ mod inner { #[cfg(test)] mod test_wasm_type_list { use super::*; + use crate::Context as WasmerContext; + use crate::Store; use wasmer_types::Type; - + /* #[test] fn test_from_array() { - assert_eq!(<()>::from_array([]), ()); - assert_eq!(::from_array([1]), (1i32)); - assert_eq!(<(i32, i64)>::from_array([1, 2]), (1i32, 2i64)); + let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); + assert_eq!(<()>::from_array(&mut ctx, []), ()); + assert_eq!(::from_array(&mut ctx, [RawValue{i32: 1}]), (1i32)); + assert_eq!(<(i32, i64)>::from_array(&mut ctx, [RawValue{i32:1}, RawValue{i64:2}]), (1i32, 2i64)); assert_eq!( - <(i32, i64, f32, f64)>::from_array([ - 1, - 2, - (3.1f32).to_bits().into(), - (4.2f64).to_bits().into() + <(i32, i64, f32, f64)>::from_array(&mut ctx, [ + RawValue{i32:1}, + RawValue{i64:2}, + RawValue{f32: 3.1f32}, + RawValue{f64: 4.2f64} ]), (1, 2, 3.1f32, 4.2f64) ); @@ -1249,33 +1253,37 @@ mod inner { #[test] fn test_into_array() { - assert_eq!(().into_array(), [0i128; 0]); - assert_eq!((1).into_array(), [1]); - assert_eq!((1i32, 2i64).into_array(), [1, 2]); + let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); + assert_eq!(().into_array(&mut ctx), [0i128; 0]); + assert_eq!((1i32).into_array(&mut ctx), [1i32]); + assert_eq!((1i32, 2i64).into_array(&mut ctx), [RawValue{i32: 1}, RawValue{i64: 2}]); assert_eq!( - (1i32, 2i32, 3.1f32, 4.2f64).into_array(), - [1, 2, (3.1f32).to_bits().into(), (4.2f64).to_bits().into()] + (1i32, 2i32, 3.1f32, 4.2f64).into_array(&mut ctx), + [RawValue{i32: 1}, RawValue{i32: 2}, RawValue{ f32: 3.1f32}, RawValue{f64: 4.2f64}] ); } - + */ #[test] fn test_empty_array() { assert_eq!(<()>::empty_array().len(), 0); assert_eq!(::empty_array().len(), 1); assert_eq!(<(i32, i64)>::empty_array().len(), 2); } - + /* #[test] fn test_from_c_struct() { - assert_eq!(<()>::from_c_struct(S0()), ()); - assert_eq!(::from_c_struct(S1(1)), (1i32)); - assert_eq!(<(i32, i64)>::from_c_struct(S2(1, 2)), (1i32, 2i64)); + let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); + assert_eq!(<()>::from_c_struct(&mut ctx, S0()), ()); + assert_eq!(::from_c_struct(&mut ctx, S1(1)), (1i32)); + assert_eq!(<(i32, i64)>::from_c_struct(&mut ctx, S2(1, 2)), (1i32, 2i64)); assert_eq!( - <(i32, i64, f32, f64)>::from_c_struct(S4(1, 2, 3.1, 4.2)), + <(i32, i64, f32, f64)>::from_c_struct(&mut ctx, S4(1, 2, 3.1, 4.2)), (1i32, 2i64, 3.1f32, 4.2f64) ); } - + */ #[test] fn test_wasm_types_for_uni_values() { assert_eq!(::wasm_types(), [Type::I32]); @@ -1297,68 +1305,74 @@ mod inner { ); } } + /* + #[allow(non_snake_case)] + #[cfg(test)] + mod test_function { + use super::*; + use crate::Store; + use crate::Context as WasmerContext; + use wasmer_types::Type; + + fn func() {} + fn func__i32() -> i32 { + 0 + } + fn func_i32( _a: i32) {} + fn func_i32__i32( a: i32) -> i32 { + a * 2 + } + fn func_i32_i32__i32( a: i32, b: i32) -> i32 { + a + b + } + fn func_i32_i32__i32_i32( a: i32, b: i32) -> (i32, i32) { + (a, b) + } + fn func_f32_i32__i32_f32( a: f32, b: i32) -> (i32, f32) { + (b, a) + } - #[allow(non_snake_case)] - #[cfg(test)] - mod test_function { - use super::*; - use wasmer_types::Type; - - fn func() {} - fn func__i32() -> i32 { - 0 - } - fn func_i32(_a: i32) {} - fn func_i32__i32(a: i32) -> i32 { - a * 2 - } - fn func_i32_i32__i32(a: i32, b: i32) -> i32 { - a + b - } - fn func_i32_i32__i32_i32(a: i32, b: i32) -> (i32, i32) { - (a, b) - } - fn func_f32_i32__i32_f32(a: f32, b: i32) -> (i32, f32) { - (b, a) - } - - #[test] - fn test_function_types() { - assert_eq!( - StaticFunction::new(func).ty(), - FunctionType::new(vec![], vec![]) - ); - assert_eq!( - StaticFunction::new(func__i32).ty(), - FunctionType::new(vec![], vec![Type::I32]) - ); - assert_eq!( - StaticFunction::new(func_i32).ty(), - FunctionType::new(vec![Type::I32], vec![]) - ); - assert_eq!( - StaticFunction::new(func_i32__i32).ty(), - FunctionType::new(vec![Type::I32], vec![Type::I32]) - ); - assert_eq!( - StaticFunction::new(func_i32_i32__i32).ty(), - FunctionType::new(vec![Type::I32, Type::I32], vec![Type::I32]) - ); - assert_eq!( - StaticFunction::new(func_i32_i32__i32_i32).ty(), - FunctionType::new(vec![Type::I32, Type::I32], vec![Type::I32, Type::I32]) - ); - assert_eq!( - StaticFunction::new(func_f32_i32__i32_f32).ty(), - FunctionType::new(vec![Type::F32, Type::I32], vec![Type::I32, Type::F32]) - ); - } + #[test] + fn test_function_types() { + let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); + use wasmer_types::FunctionType; + assert_eq!( + StaticFunction::new(func).ty(&mut ctx), + FunctionType::new(vec![], vec![]) + ); + assert_eq!( + StaticFunction::new(func__i32).ty(&mut ctx), + FunctionType::new(vec![], vec![Type::I32]) + ); + assert_eq!( + StaticFunction::new(func_i32).ty(), + FunctionType::new(vec![Type::I32], vec![]) + ); + assert_eq!( + StaticFunction::new(func_i32__i32).ty(), + FunctionType::new(vec![Type::I32], vec![Type::I32]) + ); + assert_eq!( + StaticFunction::new(func_i32_i32__i32).ty(), + FunctionType::new(vec![Type::I32, Type::I32], vec![Type::I32]) + ); + assert_eq!( + StaticFunction::new(func_i32_i32__i32_i32).ty(), + FunctionType::new(vec![Type::I32, Type::I32], vec![Type::I32, Type::I32]) + ); + assert_eq!( + StaticFunction::new(func_f32_i32__i32_f32).ty(), + FunctionType::new(vec![Type::F32, Type::I32], vec![Type::I32, Type::F32]) + ); + } - #[test] - fn test_function_pointer() { - let f = StaticFunction::new(func_i32__i32); - let function = unsafe { std::mem::transmute::<_, fn(usize, i32) -> i32>(f.address) }; - assert_eq!(function(0, 3), 6); + #[test] + fn test_function_pointer() { + let f = StaticFunction::new(func_i32__i32); + let function = unsafe { std::mem::transmute::<_, fn(usize, i32) -> i32>(f.address) }; + assert_eq!(function(0, 3), 6); + } } - } + */ } diff --git a/lib/api/src/sys/imports.rs b/lib/api/src/sys/imports.rs index 458108a852f..df5ee00c440 100644 --- a/lib/api/src/sys/imports.rs +++ b/lib/api/src/sys/imports.rs @@ -268,14 +268,17 @@ macro_rules! import_namespace { #[cfg(test)] mod test { use crate::sys::exports::Exportable; - use crate::sys::Export; - use crate::sys::{Global, Store, Val}; + use crate::sys::Context as WasmerContext; + use crate::sys::Exports; + use crate::sys::{Global, Store, Value}; use wasmer_types::Type; - + use wasmer_vm::VMExtern; + /* #[test] fn namespace() { let store = Store::default(); - let g1 = Global::new(&store, Val::I32(0)); + let mut ctx = WasmerContext::new(&store, ()); + let g1 = Global::new(&mut ctx, Value::I32(0)); let namespace = namespace! { "happy" => g1 }; @@ -286,62 +289,64 @@ mod test { let happy_dog_entry = imports1.get_export("dog", "happy").unwrap(); assert!( - if let Export::Global(happy_dog_global) = happy_dog_entry.to_vm_extern() { - happy_dog_global.from.ty().ty == Type::I32 + if let VMExtern::Global(happy_dog_global) = happy_dog_entry.to_vm_extern() { + happy_dog_global.get(&mut ctx).ty == Type::I32 } else { false } ); } - + */ #[test] fn imports_macro_allows_trailing_comma_and_none() { + use crate::sys::ContextMut; use crate::sys::Function; let store = Default::default(); + let mut ctx = WasmerContext::new(&store, ()); - fn func(arg: i32) -> i32 { + fn func(_ctx: ContextMut<()>, arg: i32) -> i32 { arg + 1 } let _ = imports! { "env" => { - "func" => Function::new_native(&store, func), + "func" => Function::new_native(&mut ctx, func), }, }; let _ = imports! { "env" => { - "func" => Function::new_native(&store, func), + "func" => Function::new_native(&mut ctx, func), } }; let _ = imports! { "env" => { - "func" => Function::new_native(&store, func), + "func" => Function::new_native(&mut ctx, func), }, "abc" => { - "def" => Function::new_native(&store, func), + "def" => Function::new_native(&mut ctx, func), } }; let _ = imports! { "env" => { - "func" => Function::new_native(&store, func) + "func" => Function::new_native(&mut ctx, func) }, }; let _ = imports! { "env" => { - "func" => Function::new_native(&store, func) + "func" => Function::new_native(&mut ctx, func) } }; let _ = imports! { "env" => { - "func1" => Function::new_native(&store, func), - "func2" => Function::new_native(&store, func) + "func1" => Function::new_native(&mut ctx, func), + "func2" => Function::new_native(&mut ctx, func) } }; let _ = imports! { "env" => { - "func1" => Function::new_native(&store, func), - "func2" => Function::new_native(&store, func), + "func1" => Function::new_native(&mut ctx, func), + "func2" => Function::new_native(&mut ctx, func), } }; } @@ -349,7 +354,9 @@ mod test { #[test] fn chaining_works() { let store = Store::default(); - let g = Global::new(&store, Val::I32(0)); + let mut ctx = WasmerContext::new(&store, ()); + + let g = Global::new(&mut ctx, Value::I32(0)); let mut imports1 = imports! { "dog" => { @@ -380,8 +387,9 @@ mod test { #[test] fn extending_conflict_overwrites() { let store = Store::default(); - let g1 = Global::new(&store, Val::I32(0)); - let g2 = Global::new(&store, Val::I64(0)); + let mut ctx = WasmerContext::new(&store, ()); + let g1 = Global::new(&mut ctx, Value::I32(0)); + let g2 = Global::new(&mut ctx, Value::I64(0)); let mut imports1 = imports! { "dog" => { @@ -397,19 +405,20 @@ mod test { imports1.extend(&imports2); let happy_dog_entry = imports1.get_export("dog", "happy").unwrap(); - + /* assert!( - if let Export::Global(happy_dog_global) = happy_dog_entry.to_vm_extern() { + if let Exports::Global(happy_dog_global) = happy_dog_entry.to_vm_extern() { happy_dog_global.from.ty().ty == Type::I64 } else { false } ); - + */ // now test it in reverse let store = Store::default(); - let g1 = Global::new(&store, Val::I32(0)); - let g2 = Global::new(&store, Val::I64(0)); + let mut ctx = WasmerContext::new(&store, ()); + let g1 = Global::new(&mut ctx, Value::I32(0)); + let g2 = Global::new(&mut ctx, Value::I64(0)); let imports1 = imports! { "dog" => { @@ -425,13 +434,14 @@ mod test { imports2.extend(&imports1); let happy_dog_entry = imports2.get_export("dog", "happy").unwrap(); - + /* assert!( - if let Export::Global(happy_dog_global) = happy_dog_entry.to_vm_extern() { + if let Exports::Global(happy_dog_global) = happy_dog_entry.to_vm_extern() { happy_dog_global.from.ty().ty == Type::I32 } else { false } ); + */ } } diff --git a/lib/api/src/sys/native_type.rs b/lib/api/src/sys/native_type.rs index 4429f9d7e43..746c3b21585 100644 --- a/lib/api/src/sys/native_type.rs +++ b/lib/api/src/sys/native_type.rs @@ -205,7 +205,7 @@ mod test_native_type { assert_eq!(f64::WASM_TYPE, Type::F64); assert_eq!(u128::WASM_TYPE, Type::V128); } - + /* #[test] fn test_roundtrip() { unsafe { @@ -216,6 +216,7 @@ mod test_native_type { assert_eq!(u128::from_raw(42u128.into_raw()), 42u128); } } + */ } // pub trait IntegerAtomic diff --git a/lib/api/src/sys/value.rs b/lib/api/src/sys/value.rs index cadd7adea53..03414a70483 100644 --- a/lib/api/src/sys/value.rs +++ b/lib/api/src/sys/value.rs @@ -349,127 +349,127 @@ mod tests { #[test] fn test_value_i32_from_u32() { let bytes = [0x00, 0x00, 0x00, 0x00]; - let v = Value::<()>::from(u32::from_be_bytes(bytes)); + let v = Value::from(u32::from_be_bytes(bytes)); assert_eq!(v, Value::I32(i32::from_be_bytes(bytes))); let bytes = [0x00, 0x00, 0x00, 0x01]; - let v = Value::<()>::from(u32::from_be_bytes(bytes)); + let v = Value::from(u32::from_be_bytes(bytes)); assert_eq!(v, Value::I32(i32::from_be_bytes(bytes))); let bytes = [0xAA, 0xBB, 0xCC, 0xDD]; - let v = Value::<()>::from(u32::from_be_bytes(bytes)); + let v = Value::from(u32::from_be_bytes(bytes)); assert_eq!(v, Value::I32(i32::from_be_bytes(bytes))); let bytes = [0xFF, 0xFF, 0xFF, 0xFF]; - let v = Value::<()>::from(u32::from_be_bytes(bytes)); + let v = Value::from(u32::from_be_bytes(bytes)); assert_eq!(v, Value::I32(i32::from_be_bytes(bytes))); } #[test] fn test_value_i64_from_u64() { let bytes = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; - let v = Value::<()>::from(u64::from_be_bytes(bytes)); + let v = Value::from(u64::from_be_bytes(bytes)); assert_eq!(v, Value::I64(i64::from_be_bytes(bytes))); let bytes = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]; - let v = Value::<()>::from(u64::from_be_bytes(bytes)); + let v = Value::from(u64::from_be_bytes(bytes)); assert_eq!(v, Value::I64(i64::from_be_bytes(bytes))); let bytes = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11]; - let v = Value::<()>::from(u64::from_be_bytes(bytes)); + let v = Value::from(u64::from_be_bytes(bytes)); assert_eq!(v, Value::I64(i64::from_be_bytes(bytes))); let bytes = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; - let v = Value::<()>::from(u64::from_be_bytes(bytes)); + let v = Value::from(u64::from_be_bytes(bytes)); assert_eq!(v, Value::I64(i64::from_be_bytes(bytes))); } #[test] fn convert_value_to_i32() { - let value = Value::<()>::I32(5678); + let value = Value::I32(5678); let result = i32::try_from(value); assert_eq!(result.unwrap(), 5678); - let value = Value::<()>::from(u32::MAX); + let value = Value::from(u32::MAX); let result = i32::try_from(value); assert_eq!(result.unwrap(), -1); - let value = Value::<()>::V128(42); + let value = Value::V128(42); let result = i32::try_from(value); assert_eq!(result.unwrap_err(), "Value is not of Wasm type i32"); } #[test] fn convert_value_to_u32() { - let value = Value::<()>::from(u32::MAX); + let value = Value::from(u32::MAX); let result = u32::try_from(value); assert_eq!(result.unwrap(), u32::MAX); - let value = Value::<()>::I32(-1); + let value = Value::I32(-1); let result = u32::try_from(value); assert_eq!(result.unwrap(), u32::MAX); - let value = Value::<()>::V128(42); + let value = Value::V128(42); let result = u32::try_from(value); assert_eq!(result.unwrap_err(), "Value is not of Wasm type i32"); } #[test] fn convert_value_to_i64() { - let value = Value::<()>::I64(5678); + let value = Value::I64(5678); let result = i64::try_from(value); assert_eq!(result.unwrap(), 5678); - let value = Value::<()>::from(u64::MAX); + let value = Value::from(u64::MAX); let result = i64::try_from(value); assert_eq!(result.unwrap(), -1); - let value = Value::<()>::V128(42); + let value = Value::V128(42); let result = i64::try_from(value); assert_eq!(result.unwrap_err(), "Value is not of Wasm type i64"); } #[test] fn convert_value_to_u64() { - let value = Value::<()>::from(u64::MAX); + let value = Value::from(u64::MAX); let result = u64::try_from(value); assert_eq!(result.unwrap(), u64::MAX); - let value = Value::<()>::I64(-1); + let value = Value::I64(-1); let result = u64::try_from(value); assert_eq!(result.unwrap(), u64::MAX); - let value = Value::<()>::V128(42); + let value = Value::V128(42); let result = u64::try_from(value); assert_eq!(result.unwrap_err(), "Value is not of Wasm type i64"); } #[test] fn convert_value_to_f32() { - let value = Value::<()>::F32(1.234); + let value = Value::F32(1.234); let result = f32::try_from(value); assert_eq!(result.unwrap(), 1.234); - let value = Value::<()>::V128(42); + let value = Value::V128(42); let result = f32::try_from(value); assert_eq!(result.unwrap_err(), "Value is not of Wasm type f32"); - let value = Value::<()>::F64(1.234); + let value = Value::F64(1.234); let result = f32::try_from(value); assert_eq!(result.unwrap_err(), "Value is not of Wasm type f32"); } #[test] fn convert_value_to_f64() { - let value = Value::<()>::F64(1.234); + let value = Value::F64(1.234); let result = f64::try_from(value); assert_eq!(result.unwrap(), 1.234); - let value = Value::<()>::V128(42); + let value = Value::V128(42); let result = f64::try_from(value); assert_eq!(result.unwrap_err(), "Value is not of Wasm type f64"); - let value = Value::<()>::F32(1.234); + let value = Value::F32(1.234); let result = f64::try_from(value); assert_eq!(result.unwrap_err(), "Value is not of Wasm type f64"); } diff --git a/lib/api/tests/sys_export.rs b/lib/api/tests/sys_export.rs deleted file mode 100644 index b9c20988922..00000000000 --- a/lib/api/tests/sys_export.rs +++ /dev/null @@ -1,334 +0,0 @@ -#[cfg(feature = "sys")] -mod sys { - use anyhow::Result; - use wasmer::*; - use wasmer_vm::WeakOrStrongInstanceRef; - - const MEM_WAT: &str = " - (module - (func $host_fn (import \"env\" \"host_fn\") (param) (result)) - (func (export \"call_host_fn\") (param) (result) - (call $host_fn)) - - (memory $mem 0) - (export \"memory\" (memory $mem)) - ) -"; - - const GLOBAL_WAT: &str = " - (module - (func $host_fn (import \"env\" \"host_fn\") (param) (result)) - (func (export \"call_host_fn\") (param) (result) - (call $host_fn)) - - (global $global i32 (i32.const 11)) - (export \"global\" (global $global)) - ) -"; - - const TABLE_WAT: &str = " - (module - (func $host_fn (import \"env\" \"host_fn\") (param) (result)) - (func (export \"call_host_fn\") (param) (result) - (call $host_fn)) - - (table $table 4 4 funcref) - (export \"table\" (table $table)) - ) -"; - - const FUNCTION_WAT: &str = " - (module - (func $host_fn (import \"env\" \"host_fn\") (param) (result)) - (func (export \"call_host_fn\") (param) (result) - (call $host_fn)) - ) -"; - - fn is_memory_instance_ref_strong(memory: &Memory) -> Option { - // This is safe because we're calling it from a test to test the internals - unsafe { - memory - .get_vm_memory() - .instance_ref - .as_ref() - .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) - } - } - - fn is_table_instance_ref_strong(table: &Table) -> Option { - // This is safe because we're calling it from a test to test the internals - unsafe { - table - .get_vm_table() - .instance_ref - .as_ref() - .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) - } - } - - fn is_global_instance_ref_strong(global: &Global) -> Option { - // This is safe because we're calling it from a test to test the internals - unsafe { - global - .get_vm_global() - .instance_ref - .as_ref() - .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) - } - } - - fn is_function_instance_ref_strong(f: &Function) -> Option { - // This is safe because we're calling it from a test to test the internals - unsafe { - f.get_vm_function() - .instance_ref - .as_ref() - .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) - } - } - - fn is_native_function_instance_ref_strong( - f: &TypedFunction, - ) -> Option - where - Args: WasmTypeList, - Rets: WasmTypeList, - { - // This is safe because we're calling it from a test to test the internals - unsafe { - f.get_vm_function() - .instance_ref - .as_ref() - .map(|v| matches!(v, WeakOrStrongInstanceRef::Strong(_))) - } - } - - #[test] - fn strong_weak_behavior_works_memory() -> Result<()> { - #[derive(Clone, Debug, Default)] - struct MemEnv { - memory: Option, - } - - let host_fn = |env: &MemEnv| { - let mem = env.memory_ref().unwrap(); - assert_eq!(is_memory_instance_ref_strong(mem), Some(false)); - let mem_clone = mem.clone(); - assert_eq!(is_memory_instance_ref_strong(&mem_clone), Some(true)); - assert_eq!(is_memory_instance_ref_strong(mem), Some(false)); - }; - - let f: TypedFunction<(), ()> = { - let store = Store::default(); - let module = Module::new(&store, MEM_WAT)?; - let env = MemEnv::default(); - - let instance = Instance::new( - &module, - &imports! { - "env" => { - "host_fn" => Function::new_native(&store, env, host_fn) - } - }, - )?; - - { - let mem = instance.exports.get_memory("memory")?; - assert_eq!(is_memory_instance_ref_strong(mem), Some(true)); - } - - let f: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_fn")?; - f.call()?; - f - }; - f.call()?; - - Ok(()) - } - - #[test] - fn strong_weak_behavior_works_global() -> Result<()> { - #[derive(Clone, Debug, Default)] - struct GlobalEnv { - global: Option, - } - - let host_fn = |env: &GlobalEnv| { - let global = env.global_ref().unwrap(); - assert_eq!(is_global_instance_ref_strong(global), Some(false)); - let global_clone = global.clone(); - assert_eq!(is_global_instance_ref_strong(&global_clone), Some(true)); - assert_eq!(is_global_instance_ref_strong(global), Some(false)); - }; - - let f: TypedFunction<(), ()> = { - let store = Store::default(); - let module = Module::new(&store, GLOBAL_WAT)?; - let env = GlobalEnv::default(); - - let instance = Instance::new( - &module, - &imports! { - "env" => { - "host_fn" => Function::new_native(&store, env, host_fn) - } - }, - )?; - - { - let global = instance.exports.get_global("global")?; - assert_eq!(is_global_instance_ref_strong(global), Some(true)); - } - - let f: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_fn")?; - f.call()?; - f - }; - f.call()?; - - Ok(()) - } - - #[test] - fn strong_weak_behavior_works_table() -> Result<()> { - #[derive(Clone, Default)] - struct TableEnv { - table: Option, - } - - let host_fn = |env: &TableEnv| { - let table = env.table_ref().unwrap(); - assert_eq!(is_table_instance_ref_strong(table), Some(false)); - let table_clone = table.clone(); - assert_eq!(is_table_instance_ref_strong(&table_clone), Some(true)); - assert_eq!(is_table_instance_ref_strong(table), Some(false)); - }; - - let f: TypedFunction<(), ()> = { - let store = Store::default(); - let module = Module::new(&store, TABLE_WAT)?; - let env = TableEnv::default(); - - let instance = Instance::new( - &module, - &imports! { - "env" => { - "host_fn" => Function::new_native(&store, env, host_fn) - } - }, - )?; - - { - let table = instance.exports.get_table("table")?; - assert_eq!(is_table_instance_ref_strong(table), Some(true)); - } - - let f: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_fn")?; - f.call()?; - f - }; - f.call()?; - - Ok(()) - } - - #[test] - fn strong_weak_behavior_works_function() -> Result<()> { - #[derive(Clone, Default)] - struct FunctionEnv { - call_host_fn: Option, - } - - let host_fn = |env: &FunctionEnv| { - let function = env.call_host_fn_ref().unwrap(); - assert_eq!(is_function_instance_ref_strong(function), Some(false)); - let function_clone = function.clone(); - assert_eq!(is_function_instance_ref_strong(&function_clone), Some(true)); - assert_eq!(is_function_instance_ref_strong(function), Some(false)); - }; - - let f: TypedFunction<(), ()> = { - let store = Store::default(); - let module = Module::new(&store, FUNCTION_WAT)?; - let env = FunctionEnv::default(); - - let instance = Instance::new( - &module, - &imports! { - "env" => { - "host_fn" => Function::new_native(&store, env, host_fn) - } - }, - )?; - - { - let function = instance.exports.get_function("call_host_fn")?; - assert_eq!(is_function_instance_ref_strong(function), Some(true)); - } - - let f: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_fn")?; - f.call()?; - f - }; - f.call()?; - - Ok(()) - } - - #[test] - fn strong_weak_behavior_works_native_function() -> Result<()> { - #[derive(Clone, Default)] - struct FunctionEnv { - call_host_fn: Option>, - } - - let host_fn = |env: &FunctionEnv| { - let function = env.call_host_fn_ref().unwrap(); - assert_eq!( - is_native_function_instance_ref_strong(function), - Some(false) - ); - let function_clone = function.clone(); - assert_eq!( - is_native_function_instance_ref_strong(&function_clone), - Some(true) - ); - assert_eq!( - is_native_function_instance_ref_strong(function), - Some(false) - ); - }; - - let f: TypedFunction<(), ()> = { - let store = Store::default(); - let module = Module::new(&store, FUNCTION_WAT)?; - let env = FunctionEnv::default(); - - let instance = Instance::new( - &module, - &imports! { - "env" => { - "host_fn" => Function::new_native(&store, env, host_fn) - } - }, - )?; - - { - let function: TypedFunction<(), ()> = - instance.exports.get_typed_function("call_host_fn")?; - assert_eq!( - is_native_function_instance_ref_strong(&function), - Some(true) - ); - } - - let f: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_fn")?; - f.call()?; - f - }; - f.call()?; - - Ok(()) - } -} diff --git a/lib/api/tests/sys_externals.rs b/lib/api/tests/sys_externals.rs index fffa9b62e59..d23ab50eeed 100644 --- a/lib/api/tests/sys_externals.rs +++ b/lib/api/tests/sys_externals.rs @@ -1,23 +1,25 @@ #[cfg(feature = "sys")] mod sys { use anyhow::Result; + use wasmer::Context as WasmerContext; use wasmer::*; #[test] fn global_new() -> Result<()> { let store = Store::default(); - let global = Global::new(&store, Value::I32(10)); + let mut ctx = WasmerContext::new(&store, ()); + let global = Global::new(&mut ctx, Value::I32(10)); assert_eq!( - *global.ty(), + global.ty(&mut ctx), GlobalType { ty: Type::I32, mutability: Mutability::Const } ); - let global_mut = Global::new_mut(&store, Value::I32(10)); + let global_mut = Global::new_mut(&mut ctx, Value::I32(10)); assert_eq!( - *global_mut.ty(), + global_mut.ty(&mut ctx), GlobalType { ty: Type::I32, mutability: Mutability::Var @@ -30,14 +32,15 @@ mod sys { #[test] fn global_get() -> Result<()> { let store = Store::default(); - let global_i32 = Global::new(&store, Value::I32(10)); - assert_eq!(global_i32.get(), Value::I32(10)); - let global_i64 = Global::new(&store, Value::I64(20)); - assert_eq!(global_i64.get(), Value::I64(20)); - let global_f32 = Global::new(&store, Value::F32(10.0)); - assert_eq!(global_f32.get(), Value::F32(10.0)); - let global_f64 = Global::new(&store, Value::F64(20.0)); - assert_eq!(global_f64.get(), Value::F64(20.0)); + let mut ctx = WasmerContext::new(&store, ()); + let global_i32 = Global::new(&mut ctx, Value::I32(10)); + assert_eq!(global_i32.get(&mut ctx), Value::I32(10)); + let global_i64 = Global::new(&mut ctx, Value::I64(20)); + assert_eq!(global_i64.get(&mut ctx), Value::I64(20)); + let global_f32 = Global::new(&mut ctx, Value::F32(10.0)); + assert_eq!(global_f32.get(&mut ctx), Value::F32(10.0)); + let global_f64 = Global::new(&mut ctx, Value::F64(20.0)); + assert_eq!(global_f64.get(&mut ctx), Value::F64(20.0)); Ok(()) } @@ -45,17 +48,18 @@ mod sys { #[test] fn global_set() -> Result<()> { let store = Store::default(); - let global_i32 = Global::new(&store, Value::I32(10)); + let mut ctx = WasmerContext::new(&store, ()); + let global_i32 = Global::new(&mut ctx, Value::I32(10)); // Set on a constant should error - assert!(global_i32.set(Value::I32(20)).is_err()); + assert!(global_i32.set(&mut ctx, Value::I32(20)).is_err()); - let global_i32_mut = Global::new_mut(&store, Value::I32(10)); + let global_i32_mut = Global::new_mut(&mut ctx, Value::I32(10)); // Set on different type should error - assert!(global_i32_mut.set(Value::I64(20)).is_err()); + assert!(global_i32_mut.set(&mut ctx, Value::I64(20)).is_err()); // Set on same type should succeed - global_i32_mut.set(Value::I32(20))?; - assert_eq!(global_i32_mut.get(), Value::I32(20)); + global_i32_mut.set(&mut ctx, Value::I32(20))?; + assert_eq!(global_i32_mut.get(&mut ctx), Value::I32(20)); Ok(()) } @@ -63,14 +67,15 @@ mod sys { #[test] fn table_new() -> Result<()> { let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); let table_type = TableType { ty: Type::FuncRef, minimum: 0, maximum: None, }; - let f = Function::new_native(&store, || {}); - let table = Table::new(&store, table_type, Value::FuncRef(Some(f)))?; - assert_eq!(*table.ty(), table_type); + let f = Function::new_native(&mut ctx, |_ctx: ContextMut<()>| {}); + let table = Table::new(&mut ctx, table_type, Value::FuncRef(Some(f)))?; + assert_eq!(table.ty(&mut ctx), table_type); // Anyrefs not yet supported // let table_type = TableType { @@ -88,15 +93,16 @@ mod sys { #[ignore] fn table_get() -> Result<()> { let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); let table_type = TableType { ty: Type::FuncRef, minimum: 0, maximum: Some(1), }; - let f = Function::new_native(&store, |num: i32| num + 1); - let table = Table::new(&store, table_type, Value::FuncRef(Some(f)))?; - assert_eq!(*table.ty(), table_type); - let _elem = table.get(0).unwrap(); + let f = Function::new_native(&mut ctx, |_ctx: ContextMut<()>, num: i32| num + 1); + let table = Table::new(&mut ctx, table_type, Value::FuncRef(Some(f)))?; + assert_eq!(table.ty(&mut ctx), table_type); + let _elem = table.get(&mut ctx, 0).unwrap(); // assert_eq!(elem.funcref().unwrap(), f); Ok(()) } @@ -111,19 +117,20 @@ mod sys { #[test] fn table_grow() -> Result<()> { let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); let table_type = TableType { ty: Type::FuncRef, minimum: 0, maximum: Some(10), }; - let f = Function::new_native(&store, |num: i32| num + 1); - let table = Table::new(&store, table_type, Value::FuncRef(Some(f.clone())))?; + let f = Function::new_native(&mut ctx, |_ctx: ContextMut<()>, num: i32| num + 1); + let table = Table::new(&mut ctx, table_type, Value::FuncRef(Some(f.clone())))?; // Growing to a bigger maximum should return None - let old_len = table.grow(12, Value::FuncRef(Some(f.clone()))); + let old_len = table.grow(&mut ctx, 12, Value::FuncRef(Some(f.clone()))); assert!(old_len.is_err()); // Growing to a bigger maximum should return None - let old_len = table.grow(5, Value::FuncRef(Some(f)))?; + let old_len = table.grow(&mut ctx, 5, Value::FuncRef(Some(f)))?; assert_eq!(old_len, 0); Ok(()) @@ -139,30 +146,31 @@ mod sys { #[test] fn memory_new() -> Result<()> { let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); let memory_type = MemoryType { shared: false, minimum: Pages(0), maximum: Some(Pages(10)), }; - let memory = Memory::new(&store, memory_type)?; - assert_eq!(memory.size(), Pages(0)); - assert_eq!(memory.ty(), memory_type); + let memory = Memory::new(&mut ctx, memory_type)?; + assert_eq!(memory.size(&mut ctx), Pages(0)); + assert_eq!(memory.ty(&mut ctx), memory_type); Ok(()) } #[test] fn memory_grow() -> Result<()> { let store = Store::default(); - + let mut ctx = WasmerContext::new(&store, ()); let desc = MemoryType::new(Pages(10), Some(Pages(16)), false); - let memory = Memory::new(&store, desc)?; - assert_eq!(memory.size(), Pages(10)); + let memory = Memory::new(&mut ctx, desc)?; + assert_eq!(memory.size(&mut ctx), Pages(10)); - let result = memory.grow(Pages(2)).unwrap(); + let result = memory.grow(&mut ctx, Pages(2)).unwrap(); assert_eq!(result, Pages(10)); - assert_eq!(memory.size(), Pages(12)); + assert_eq!(memory.size(&mut ctx), Pages(12)); - let result = memory.grow(Pages(10)); + let result = memory.grow(&mut ctx, Pages(10)); assert_eq!( result, Err(MemoryError::CouldNotGrow { @@ -172,7 +180,7 @@ mod sys { ); let bad_desc = MemoryType::new(Pages(15), Some(Pages(10)), false); - let bad_result = Memory::new(&store, bad_desc); + let bad_result = Memory::new(&mut ctx, bad_desc); assert!(matches!(bad_result, Err(MemoryError::InvalidMemory { .. }))); @@ -182,27 +190,36 @@ mod sys { #[test] fn function_new() -> Result<()> { let store = Store::default(); - let function = Function::new_native(&store, || {}); - assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![])); - let function = Function::new_native(&store, |_a: i32| {}); + let mut ctx = WasmerContext::new(&store, ()); + let function = Function::new_native(&mut ctx, |_ctx: ContextMut<_>| {}); + assert_eq!( + function.ty(&mut ctx).clone(), + FunctionType::new(vec![], vec![]) + ); + let function = Function::new_native(&mut ctx, |_ctx: ContextMut<_>, _a: i32| {}); assert_eq!( - function.ty().clone(), + function.ty(&mut ctx).clone(), FunctionType::new(vec![Type::I32], vec![]) ); - let function = Function::new_native(&store, |_a: i32, _b: i64, _c: f32, _d: f64| {}); + let function = Function::new_native( + &mut ctx, + |_ctx: ContextMut<_>, _a: i32, _b: i64, _c: f32, _d: f64| {}, + ); assert_eq!( - function.ty().clone(), + function.ty(&mut ctx).clone(), FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![]) ); - let function = Function::new_native(&store, || -> i32 { 1 }); + let function = Function::new_native(&mut ctx, |_ctx: ContextMut<_>| -> i32 { 1 }); assert_eq!( - function.ty().clone(), + function.ty(&mut ctx).clone(), FunctionType::new(vec![], vec![Type::I32]) ); let function = - Function::new_native(&store, || -> (i32, i64, f32, f64) { (1, 2, 3.0, 4.0) }); + Function::new_native(&mut ctx, |_ctx: ContextMut<_>| -> (i32, i64, f32, f64) { + (1, 2, 3.0, 4.0) + }); assert_eq!( - function.ty().clone(), + function.ty(&mut ctx).clone(), FunctionType::new(vec![], vec![Type::I32, Type::I64, Type::F32, Type::F64]) ); Ok(()) @@ -215,33 +232,36 @@ mod sys { struct MyEnv {} let my_env = MyEnv {}; - let function = Function::new_native(&store, my_env.clone(), |_env: &MyEnv| {}); - assert_eq!(function.ty().clone(), FunctionType::new(vec![], vec![])); - let function = Function::new_native(&store, my_env.clone(), |_env: &MyEnv, _a: i32| {}); + let mut ctx = WasmerContext::new(&store, my_env); + let function = Function::new_native(&mut ctx, |_ctx: ContextMut| {}); + assert_eq!( + function.ty(&mut ctx).clone(), + FunctionType::new(vec![], vec![]) + ); + let function = Function::new_native(&mut ctx, |_ctx: ContextMut, _a: i32| {}); assert_eq!( - function.ty().clone(), + function.ty(&mut ctx).clone(), FunctionType::new(vec![Type::I32], vec![]) ); let function = Function::new_native( - &store, - my_env.clone(), - |_env: &MyEnv, _a: i32, _b: i64, _c: f32, _d: f64| {}, + &mut ctx, + |_ctx: ContextMut, _a: i32, _b: i64, _c: f32, _d: f64| {}, ); assert_eq!( - function.ty().clone(), + function.ty(&mut ctx).clone(), FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![]) ); - let function = Function::new_native(&store, my_env.clone(), |_env: &MyEnv| -> i32 { 1 }); + let function = Function::new_native(&mut ctx, |_ctx: ContextMut| -> i32 { 1 }); assert_eq!( - function.ty().clone(), + function.ty(&mut ctx).clone(), FunctionType::new(vec![], vec![Type::I32]) ); - let function = - Function::new_native(&store, my_env, |_env: &MyEnv| -> (i32, i64, f32, f64) { - (1, 2, 3.0, 4.0) - }); + let function = Function::new_native( + &mut ctx, + |_ctx: ContextMut| -> (i32, i64, f32, f64) { (1, 2, 3.0, 4.0) }, + ); assert_eq!( - function.ty().clone(), + function.ty(&mut ctx).clone(), FunctionType::new(vec![], vec![Type::I32, Type::I64, Type::F32, Type::F64]) ); Ok(()) @@ -250,31 +270,59 @@ mod sys { #[test] fn function_new_dynamic() -> Result<()> { let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); // Using &FunctionType signature let function_type = FunctionType::new(vec![], vec![]); - let function = Function::new(&store, &function_type, |_values: &[Value]| unimplemented!()); - assert_eq!(function.ty().clone(), function_type); + let function = Function::new( + &mut ctx, + &function_type, + |_ctx: ContextMut<()>, _values: &[Value]| unimplemented!(), + ); + assert_eq!(function.ty(&mut ctx).clone(), function_type); let function_type = FunctionType::new(vec![Type::I32], vec![]); - let function = Function::new(&store, &function_type, |_values: &[Value]| unimplemented!()); - assert_eq!(function.ty().clone(), function_type); + let function = Function::new( + &mut ctx, + &function_type, + |_ctx: ContextMut<()>, _values: &[Value]| unimplemented!(), + ); + assert_eq!(function.ty(&mut ctx).clone(), function_type); let function_type = FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![]); - let function = Function::new(&store, &function_type, |_values: &[Value]| unimplemented!()); - assert_eq!(function.ty().clone(), function_type); + let function = Function::new( + &mut ctx, + &function_type, + |_ctx: ContextMut<()>, _values: &[Value]| unimplemented!(), + ); + assert_eq!(function.ty(&mut ctx).clone(), function_type); let function_type = FunctionType::new(vec![], vec![Type::I32]); - let function = Function::new(&store, &function_type, |_values: &[Value]| unimplemented!()); - assert_eq!(function.ty().clone(), function_type); + let function = Function::new( + &mut ctx, + &function_type, + |_ctx: ContextMut<()>, _values: &[Value]| unimplemented!(), + ); + assert_eq!(function.ty(&mut ctx).clone(), function_type); let function_type = FunctionType::new(vec![], vec![Type::I32, Type::I64, Type::F32, Type::F64]); - let function = Function::new(&store, &function_type, |_values: &[Value]| unimplemented!()); - assert_eq!(function.ty().clone(), function_type); + let function = Function::new( + &mut ctx, + &function_type, + |_ctx: ContextMut<()>, _values: &[Value]| unimplemented!(), + ); + assert_eq!(function.ty(&mut ctx).clone(), function_type); // Using array signature let function_type = ([Type::V128], [Type::I32, Type::F32, Type::F64]); - let function = Function::new(&store, function_type, |_values: &[Value]| unimplemented!()); - assert_eq!(function.ty().params(), [Type::V128]); - assert_eq!(function.ty().results(), [Type::I32, Type::F32, Type::F64]); + let function = Function::new( + &mut ctx, + function_type, + |_ctx: ContextMut<()>, _values: &[Value]| unimplemented!(), + ); + assert_eq!(function.ty(&mut ctx).params(), [Type::V128]); + assert_eq!( + function.ty(&mut ctx).results(), + [Type::I32, Type::F32, Type::F64] + ); Ok(()) } @@ -285,61 +333,59 @@ mod sys { #[derive(Clone)] struct MyEnv {} let my_env = MyEnv {}; + let mut ctx = WasmerContext::new(&store, my_env); // Using &FunctionType signature let function_type = FunctionType::new(vec![], vec![]); let function = Function::new( - &store, + &mut ctx, &function_type, - my_env.clone(), - |_env: &MyEnv, _values: &[Value]| unimplemented!(), + |_ctx: ContextMut, _values: &[Value]| unimplemented!(), ); - assert_eq!(function.ty().clone(), function_type); + assert_eq!(function.ty(&mut ctx).clone(), function_type); let function_type = FunctionType::new(vec![Type::I32], vec![]); let function = Function::new( - &store, + &mut ctx, &function_type, - my_env.clone(), - |_env: &MyEnv, _values: &[Value]| unimplemented!(), + |_ctx: ContextMut, _values: &[Value]| unimplemented!(), ); - assert_eq!(function.ty().clone(), function_type); + assert_eq!(function.ty(&mut ctx).clone(), function_type); let function_type = FunctionType::new(vec![Type::I32, Type::I64, Type::F32, Type::F64], vec![]); let function = Function::new( - &store, + &mut ctx, &function_type, - my_env.clone(), - |_env: &MyEnv, _values: &[Value]| unimplemented!(), + |_ctx: ContextMut, _values: &[Value]| unimplemented!(), ); - assert_eq!(function.ty().clone(), function_type); + assert_eq!(function.ty(&mut ctx).clone(), function_type); let function_type = FunctionType::new(vec![], vec![Type::I32]); let function = Function::new( - &store, + &mut ctx, &function_type, - my_env.clone(), - |_env: &MyEnv, _values: &[Value]| unimplemented!(), + |_ctx: ContextMut, _values: &[Value]| unimplemented!(), ); - assert_eq!(function.ty().clone(), function_type); + assert_eq!(function.ty(&mut ctx).clone(), function_type); let function_type = FunctionType::new(vec![], vec![Type::I32, Type::I64, Type::F32, Type::F64]); let function = Function::new( - &store, + &mut ctx, &function_type, - my_env.clone(), - |_env: &MyEnv, _values: &[Value]| unimplemented!(), + |_ctx: ContextMut, _values: &[Value]| unimplemented!(), ); - assert_eq!(function.ty().clone(), function_type); + assert_eq!(function.ty(&mut ctx).clone(), function_type); // Using array signature let function_type = ([Type::V128], [Type::I32, Type::F32, Type::F64]); let function = Function::new( - &store, + &mut ctx, function_type, - my_env, - |_env: &MyEnv, _values: &[Value]| unimplemented!(), + |_ctx: ContextMut, _values: &[Value]| unimplemented!(), + ); + assert_eq!(function.ty(&mut ctx).params(), [Type::V128]); + assert_eq!( + function.ty(&mut ctx).results(), + [Type::I32, Type::F32, Type::F64] ); - assert_eq!(function.ty().params(), [Type::V128]); - assert_eq!(function.ty().results(), [Type::I32, Type::F32, Type::F64]); Ok(()) } @@ -347,34 +393,40 @@ mod sys { #[test] fn native_function_works() -> Result<()> { let store = Store::default(); - let function = Function::new_native(&store, || {}); - let native_function: TypedFunction<(), ()> = function.native().unwrap(); - let result = native_function.call(); + let mut ctx = WasmerContext::new(&store, ()); + let function = Function::new_native(&mut ctx, |_ctx: ContextMut<()>| {}); + let native_function: TypedFunction<(), ()> = function.native(&mut ctx).unwrap(); + let result = native_function.call(&mut ctx); assert!(result.is_ok()); - let function = Function::new_native(&store, |a: i32| -> i32 { a + 1 }); - let native_function: TypedFunction = function.native().unwrap(); - assert_eq!(native_function.call(3).unwrap(), 4); + let function = + Function::new_native(&mut ctx, |_ctx: ContextMut<()>, a: i32| -> i32 { a + 1 }); + let native_function: TypedFunction = function.native(&mut ctx).unwrap(); + assert_eq!(native_function.call(&mut ctx, 3).unwrap(), 4); - fn rust_abi(a: i32, b: i64, c: f32, d: f64) -> u64 { + fn rust_abi(_ctx: ContextMut<()>, a: i32, b: i64, c: f32, d: f64) -> u64 { (a as u64 * 1000) + (b as u64 * 100) + (c as u64 * 10) + (d as u64) } - let function = Function::new_native(&store, rust_abi); - let native_function: TypedFunction<(i32, i64, f32, f64), u64> = function.native().unwrap(); - assert_eq!(native_function.call(8, 4, 1.5, 5.).unwrap(), 8415); + let function = Function::new_native(&mut ctx, rust_abi); + let native_function: TypedFunction<(i32, i64, f32, f64), u64> = + function.native(&mut ctx).unwrap(); + assert_eq!(native_function.call(&mut ctx, 8, 4, 1.5, 5.).unwrap(), 8415); - let function = Function::new_native(&store, || -> i32 { 1 }); - let native_function: TypedFunction<(), i32> = function.native().unwrap(); - assert_eq!(native_function.call().unwrap(), 1); + let function = Function::new_native(&mut ctx, |_ctx: ContextMut<()>| -> i32 { 1 }); + let native_function: TypedFunction<(), i32> = function.native(&mut ctx).unwrap(); + assert_eq!(native_function.call(&mut ctx).unwrap(), 1); - let function = Function::new_native(&store, |_a: i32| {}); - let native_function: TypedFunction = function.native().unwrap(); - assert!(native_function.call(4).is_ok()); + let function = Function::new_native(&mut ctx, |_ctx: ContextMut<()>, _a: i32| {}); + let native_function: TypedFunction = function.native(&mut ctx).unwrap(); + assert!(native_function.call(&mut ctx, 4).is_ok()); let function = - Function::new_native(&store, || -> (i32, i64, f32, f64) { (1, 2, 3.0, 4.0) }); - let native_function: TypedFunction<(), (i32, i64, f32, f64)> = function.native().unwrap(); - assert_eq!(native_function.call().unwrap(), (1, 2, 3.0, 4.0)); + Function::new_native(&mut ctx, |_ctx: ContextMut<()>| -> (i32, i64, f32, f64) { + (1, 2, 3.0, 4.0) + }); + let native_function: TypedFunction<(), (i32, i64, f32, f64)> = + function.native(&mut ctx).unwrap(); + assert_eq!(native_function.call(&mut ctx).unwrap(), (1, 2, 3.0, 4.0)); Ok(()) } @@ -382,6 +434,7 @@ mod sys { #[test] fn function_outlives_instance() -> Result<()> { let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); let wat = r#"(module (type $sum_t (func (param i32 i32) (result i32))) (func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) @@ -393,46 +446,48 @@ mod sys { let f = { let module = Module::new(&store, wat)?; - let instance = Instance::new(&module, &imports! {})?; - let f: TypedFunction<(i32, i32), i32> = instance.exports.get_typed_function("sum")?; - - assert_eq!(f.call(4, 5)?, 9); - f - }; - - assert_eq!(f.call(4, 5)?, 9); - - Ok(()) - } - - #[test] - fn weak_instance_ref_externs_after_instance() -> Result<()> { - let store = Store::default(); - let wat = r#"(module - (memory (export "mem") 1) - (type $sum_t (func (param i32 i32) (result i32))) - (func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) - local.get $x - local.get $y - i32.add) - (export "sum" (func $sum_f))) -"#; - - let f = { - let module = Module::new(&store, wat)?; - let instance = Instance::new(&module, &imports! {})?; + let instance = Instance::new(&mut ctx, &module, &imports! {})?; let f: TypedFunction<(i32, i32), i32> = - instance.exports.get_with_generics_weak("sum")?; + instance.exports.get_typed_function(&mut ctx, "sum")?; - assert_eq!(f.call(4, 5)?, 9); + assert_eq!(f.call(&mut ctx, 4, 5)?, 9); f }; - assert_eq!(f.call(4, 5)?, 9); + assert_eq!(f.call(&mut ctx, 4, 5)?, 9); Ok(()) } - + /* + #[test] + fn weak_instance_ref_externs_after_instance() -> Result<()> { + let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); + let wat = r#"(module + (memory (export "mem") 1) + (type $sum_t (func (param i32 i32) (result i32))) + (func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.add) + (export "sum" (func $sum_f))) + "#; + + let f = { + let module = Module::new(&store, wat)?; + let instance = Instance::new(&mut ctx, &module, &imports! {})?; + let f: TypedFunction<(i32, i32), i32> = + instance.exports.get_with_generics_weak("sum")?; + + assert_eq!(f.call(&mut ctx, 4, 5)?, 9); + f + }; + + assert_eq!(f.call(&mut ctx, 4, 5)?, 9); + + Ok(()) + } + */ #[test] fn manually_generate_wasmer_env() -> Result<()> { let store = Store::default(); @@ -442,22 +497,23 @@ mod sys { memory: Option, } - fn host_function(env: &mut MyEnv, arg1: u32, arg2: u32) -> u32 { - env.val + arg1 + arg2 + fn host_function(ctx: ContextMut, arg1: u32, arg2: u32) -> u32 { + ctx.data().val + arg1 + arg2 } let mut env = MyEnv { val: 5, memory: None, }; + let mut ctx = WasmerContext::new(&store, env); - let result = host_function(&mut env, 7, 9); + let result = host_function(ctx.as_context_mut(), 7, 9); assert_eq!(result, 21); - let memory = Memory::new(&store, MemoryType::new(0, None, false))?; - env.memory.initialize(memory); + let memory = Memory::new(&mut ctx, MemoryType::new(0, None, false))?; + ctx.data_mut().memory = Some(memory); - let result = host_function(&mut env, 1, 2); + let result = host_function(ctx.as_context_mut(), 1, 2); assert_eq!(result, 8); Ok(()) diff --git a/lib/api/tests/sys_instance.rs b/lib/api/tests/sys_instance.rs index 8fd30b66a7d..d3eac9255eb 100644 --- a/lib/api/tests/sys_instance.rs +++ b/lib/api/tests/sys_instance.rs @@ -1,11 +1,13 @@ #[cfg(feature = "sys")] mod sys { use anyhow::Result; + use wasmer::Context as WasmerContext; use wasmer::*; #[test] fn exports_work_after_multiple_instances_have_been_freed() -> Result<()> { let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); let module = Module::new( &store, " @@ -20,7 +22,7 @@ mod sys { )?; let imports = Imports::new(); - let instance = Instance::new(&module, &imports)?; + let instance = Instance::new(&mut ctx, &module, &imports)?; let instance2 = instance.clone(); let instance3 = instance.clone(); @@ -33,7 +35,8 @@ mod sys { // All instances have been dropped, but `sum` continues to work! assert_eq!( - sum.call(&[Value::I32(1), Value::I32(2)])?.into_vec(), + sum.call(&mut ctx, &[Value::I32(1), Value::I32(2)])? + .into_vec(), vec![Value::I32(3)], ); @@ -48,21 +51,18 @@ mod sys { multiplier: u32, } - fn imported_fn(env: &Env, args: &[Val]) -> Result, RuntimeError> { - let value = env.multiplier * args[0].unwrap_i32() as u32; - Ok(vec![Val::I32(value as _)]) + fn imported_fn(ctx: ContextMut, args: &[Value]) -> Result, RuntimeError> { + let value = ctx.data().multiplier * args[0].unwrap_i32() as u32; + Ok(vec![Value::I32(value as _)]) } + let env = Env { multiplier: 3 }; + let mut ctx = WasmerContext::new(&store, env); let imported_signature = FunctionType::new(vec![Type::I32], vec![Type::I32]); - let imported = Function::new( - &store, - imported_signature, - Env { multiplier: 3 }, - imported_fn, - ); + let imported = Function::new(&mut ctx, imported_signature, imported_fn); - let expected = vec![Val::I32(12)].into_boxed_slice(); - let result = imported.call(&[Val::I32(4)])?; + let expected = vec![Value::I32(12)].into_boxed_slice(); + let result = imported.call(&mut ctx, &[Value::I32(4)])?; assert_eq!(result, expected); Ok(()) diff --git a/lib/api/tests/sys_module.rs b/lib/api/tests/sys_module.rs index 1b0bbf27d71..7b5cf58f290 100644 --- a/lib/api/tests/sys_module.rs +++ b/lib/api/tests/sys_module.rs @@ -1,6 +1,7 @@ #[cfg(feature = "sys")] mod sys { use anyhow::Result; + use wasmer::Context as WasmerContext; use wasmer::*; #[test] @@ -190,61 +191,78 @@ mod sys { (call 7 (i32.const -1))) )"#; let module = Module::new(&store, wat)?; + let mut ctx = WasmerContext::new(&store, ()); let imports = imports! { "host" => { - "host_func1" => Function::new_native(&store, |p: u64| { + "host_func1" => Function::new_native(&mut ctx, |_ctx: ContextMut<()>, p: u64| { println!("host_func1: Found number {}", p); assert_eq!(p, u64::max_value()); }), - "host_func2" => Function::new_native(&store, |p: u32| { + "host_func2" => Function::new_native(&mut ctx, |_ctx: ContextMut<()>, p: u32| { println!("host_func2: Found number {}", p); assert_eq!(p, u32::max_value()); }), - "host_func3" => Function::new_native(&store, |p: i64| { + "host_func3" => Function::new_native(&mut ctx, |_ctx: ContextMut<()>, p: i64| { println!("host_func3: Found number {}", p); assert_eq!(p, -1); }), - "host_func4" => Function::new_native(&store, |p: i32| { + "host_func4" => Function::new_native(&mut ctx, |_ctx: ContextMut<()>, p: i32| { println!("host_func4: Found number {}", p); assert_eq!(p, -1); }), - "host_func5" => Function::new_native(&store, |p: i16| { + "host_func5" => Function::new_native(&mut ctx, |_ctx: ContextMut<()>, p: i16| { println!("host_func5: Found number {}", p); assert_eq!(p, -1); }), - "host_func6" => Function::new_native(&store, |p: u16| { + "host_func6" => Function::new_native(&mut ctx, |_ctx: ContextMut<()>, p: u16| { println!("host_func6: Found number {}", p); assert_eq!(p, u16::max_value()); }), - "host_func7" => Function::new_native(&store, |p: i8| { + "host_func7" => Function::new_native(&mut ctx, |_ctx: ContextMut<()>, p: i8| { println!("host_func7: Found number {}", p); assert_eq!(p, -1); }), - "host_func8" => Function::new_native(&store, |p: u8| { + "host_func8" => Function::new_native(&mut ctx, |_ctx: ContextMut<()>, p: u8| { println!("host_func8: Found number {}", p); assert_eq!(p, u8::max_value()); }), } }; - let instance = Instance::new(&module, &imports)?; + let instance = Instance::new(&mut ctx, &module, &imports)?; - let f1: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_func1")?; - let f2: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_func2")?; - let f3: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_func3")?; - let f4: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_func4")?; - let f5: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_func5")?; - let f6: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_func6")?; - let f7: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_func7")?; - let f8: TypedFunction<(), ()> = instance.exports.get_typed_function("call_host_func8")?; + let f1: TypedFunction<(), ()> = instance + .exports + .get_typed_function(&mut ctx, "call_host_func1")?; + let f2: TypedFunction<(), ()> = instance + .exports + .get_typed_function(&mut ctx, "call_host_func2")?; + let f3: TypedFunction<(), ()> = instance + .exports + .get_typed_function(&mut ctx, "call_host_func3")?; + let f4: TypedFunction<(), ()> = instance + .exports + .get_typed_function(&mut ctx, "call_host_func4")?; + let f5: TypedFunction<(), ()> = instance + .exports + .get_typed_function(&mut ctx, "call_host_func5")?; + let f6: TypedFunction<(), ()> = instance + .exports + .get_typed_function(&mut ctx, "call_host_func6")?; + let f7: TypedFunction<(), ()> = instance + .exports + .get_typed_function(&mut ctx, "call_host_func7")?; + let f8: TypedFunction<(), ()> = instance + .exports + .get_typed_function(&mut ctx, "call_host_func8")?; - f1.call()?; - f2.call()?; - f3.call()?; - f4.call()?; - f5.call()?; - f6.call()?; - f7.call()?; - f8.call()?; + f1.call(&mut ctx)?; + f2.call(&mut ctx)?; + f3.call(&mut ctx)?; + f4.call(&mut ctx)?; + f5.call(&mut ctx)?; + f6.call(&mut ctx)?; + f7.call(&mut ctx)?; + f8.call(&mut ctx)?; Ok(()) } diff --git a/lib/api/tests/sys_reference_types.rs b/lib/api/tests/sys_reference_types.rs index 0878fb2bd96..c6024d3377d 100644 --- a/lib/api/tests/sys_reference_types.rs +++ b/lib/api/tests/sys_reference_types.rs @@ -4,6 +4,7 @@ mod sys { use std::collections::HashMap; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; + use wasmer::Context as WasmerContext; use wasmer::*; #[test] @@ -21,35 +22,36 @@ mod sys { (call_indirect $table (type $ret_i32_ty) (i32.const 0))) )"#; let module = Module::new(&store, wat)?; + #[derive(Clone, Debug)] + pub struct Env(Arc); + let env = Env(Arc::new(AtomicBool::new(false))); + let mut ctx = WasmerContext::new(&store, env); let imports = imports! { "env" => { - "func_ref_identity" => Function::new(&store, FunctionType::new([Type::FuncRef], [Type::FuncRef]), |values| -> Result, _> { + "func_ref_identity" => Function::new(&mut ctx, FunctionType::new([Type::FuncRef], [Type::FuncRef]), |_ctx: ContextMut, values: &[Value]| -> Result, _> { Ok(vec![values[0].clone()]) }) }, }; - let instance = Instance::new(&module, &imports)?; + let instance = Instance::new(&mut ctx, &module, &imports)?; let f: &Function = instance.exports.get_function("run")?; - let results = f.call(&[]).unwrap(); + let results = f.call(&mut ctx, &[]).unwrap(); if let Value::FuncRef(fr) = &results[0] { assert!(fr.is_none()); } else { panic!("funcref not found!"); } - #[derive(Clone, Debug)] - pub struct Env(Arc); - let env = Env(Arc::new(AtomicBool::new(false))); - - let func_to_call = Function::new_native(&store, env.clone(), |env: &Env| -> i32 { - env.0.store(true, Ordering::SeqCst); + let func_to_call = Function::new_native(&mut ctx, |mut ctx: ContextMut| -> i32 { + ctx.data_mut().0.store(true, Ordering::SeqCst); 343 }); let call_set_value: &Function = instance.exports.get_function("call_set_value")?; - let results: Box<[Value]> = call_set_value.call(&[Value::FuncRef(Some(func_to_call))])?; - assert!(env.0.load(Ordering::SeqCst)); + let results: Box<[Value]> = + call_set_value.call(&mut ctx, &[Value::FuncRef(Some(func_to_call))])?; + assert!(ctx.data().0.load(Ordering::SeqCst)); assert_eq!(&*results, &[Value::I32(343)]); Ok(()) @@ -76,18 +78,21 @@ mod sys { (call $func_ref_call (ref.func $product))) )"#; let module = Module::new(&store, wat)?; - - fn func_ref_call(values: &[Value]) -> Result, RuntimeError> { + let mut ctx = WasmerContext::new(&store, ()); + fn func_ref_call( + mut ctx: ContextMut<()>, + values: &[Value], + ) -> Result, RuntimeError> { // TODO: look into `Box<[Value]>` being returned breakage let f = values[0].unwrap_funcref().as_ref().unwrap(); - let f: TypedFunction<(i32, i32), i32> = f.native()?; - Ok(vec![Value::I32(f.call(7, 9)?)]) + let f: TypedFunction<(i32, i32), i32> = f.native(&mut ctx)?; + Ok(vec![Value::I32(f.call(&mut ctx, 7, 9)?)]) } let imports = imports! { "env" => { "func_ref_call" => Function::new( - &store, + &mut ctx, FunctionType::new([Type::FuncRef], [Type::I32]), func_ref_call ), @@ -101,392 +106,394 @@ mod sys { }, }; - let instance = Instance::new(&module, &imports)?; + let instance = Instance::new(&mut ctx, &module, &imports)?; { - fn sum(a: i32, b: i32) -> i32 { + fn sum(ctx: ContextMut<()>, a: i32, b: i32) -> i32 { a + b } - let sum_func = Function::new_native(&store, sum); + let sum_func = Function::new_native(&mut ctx, sum); let call_func: &Function = instance.exports.get_function("call_func")?; - let result = call_func.call(&[Value::FuncRef(Some(sum_func))])?; + let result = call_func.call(&mut ctx, &[Value::FuncRef(Some(sum_func))])?; assert_eq!(result[0].unwrap_i32(), 16); } { let f: TypedFunction<(), i32> = instance .exports - .get_typed_function("call_host_func_with_wasm_func")?; - let result = f.call()?; + .get_typed_function(&mut ctx, "call_host_func_with_wasm_func")?; + let result = f.call(&mut ctx)?; assert_eq!(result, 63); } Ok(()) } + /* + #[test] + fn extern_ref_passed_and_returned() -> Result<()> { + let store = Store::default(); + let mut ctx = WasmerContext::new(&store, ()); + let wat = r#"(module + (func $extern_ref_identity (import "env" "extern_ref_identity") (param externref) (result externref)) + (func $extern_ref_identity_native (import "env" "extern_ref_identity_native") (param externref) (result externref)) + (func $get_new_extern_ref (import "env" "get_new_extern_ref") (result externref)) + (func $get_new_extern_ref_native (import "env" "get_new_extern_ref_native") (result externref)) + + (func (export "run") (param) (result externref) + (call $extern_ref_identity (ref.null extern))) + (func (export "run_native") (param) (result externref) + (call $extern_ref_identity_native (ref.null extern))) + (func (export "get_hashmap") (param) (result externref) + (call $get_new_extern_ref)) + (func (export "get_hashmap_native") (param) (result externref) + (call $get_new_extern_ref_native)) + )"#; + let module = Module::new(&store, wat)?; + let imports = imports! { + "env" => { + "extern_ref_identity" => Function::new(&mut ctx, FunctionType::new([Type::ExternRef], [Type::ExternRef]), |_ctx, values| -> Result, _> { + Ok(vec![values[0].clone()]) + }), + "extern_ref_identity_native" => Function::new_native(&mut ctx, |_ctx: ContextMut<()>, er: ExternRef| -> ExternRef { + er + }), + "get_new_extern_ref" => Function::new(&mut ctx, FunctionType::new([], [Type::ExternRef]), |_ctx, _| -> Result, _> { + let inner = + [("hello".to_string(), "world".to_string()), + ("color".to_string(), "orange".to_string())] + .iter() + .cloned() + .collect::>(); + let new_extern_ref = ExternRef::new(&mut ctx, inner); + Ok(vec![Value::ExternRef(new_extern_ref)]) + }), + "get_new_extern_ref_native" => Function::new_native(&mut ctx, |_ctx| -> ExternRef { + let inner = + [("hello".to_string(), "world".to_string()), + ("color".to_string(), "orange".to_string())] + .iter() + .cloned() + .collect::>(); + ExternRef::new(inner) + }) + }, + }; + + let instance = Instance::new(&module, &imports)?; + for run in &["run", "run_native"] { + let f: &Function = instance.exports.get_function(run)?; + let results = f.call(&[]).unwrap(); + if let Value::ExternRef(er) = &results[0] { + assert!(er.is_null()); + } else { + panic!("result is not an extern ref!"); + } - #[test] - fn extern_ref_passed_and_returned() -> Result<()> { - let store = Store::default(); - let wat = r#"(module - (func $extern_ref_identity (import "env" "extern_ref_identity") (param externref) (result externref)) - (func $extern_ref_identity_native (import "env" "extern_ref_identity_native") (param externref) (result externref)) - (func $get_new_extern_ref (import "env" "get_new_extern_ref") (result externref)) - (func $get_new_extern_ref_native (import "env" "get_new_extern_ref_native") (result externref)) - - (func (export "run") (param) (result externref) - (call $extern_ref_identity (ref.null extern))) - (func (export "run_native") (param) (result externref) - (call $extern_ref_identity_native (ref.null extern))) - (func (export "get_hashmap") (param) (result externref) - (call $get_new_extern_ref)) - (func (export "get_hashmap_native") (param) (result externref) - (call $get_new_extern_ref_native)) -)"#; - let module = Module::new(&store, wat)?; - let imports = imports! { - "env" => { - "extern_ref_identity" => Function::new(&store, FunctionType::new([Type::ExternRef], [Type::ExternRef]), |values| -> Result, _> { - Ok(vec![values[0].clone()]) - }), - "extern_ref_identity_native" => Function::new_native(&store, |er: ExternRef| -> ExternRef { - er - }), - "get_new_extern_ref" => Function::new(&store, FunctionType::new([], [Type::ExternRef]), |_| -> Result, _> { - let inner = - [("hello".to_string(), "world".to_string()), - ("color".to_string(), "orange".to_string())] - .iter() - .cloned() - .collect::>(); - let new_extern_ref = ExternRef::new(inner); - Ok(vec![Value::ExternRef(new_extern_ref)]) - }), - "get_new_extern_ref_native" => Function::new_native(&store, || -> ExternRef { - let inner = - [("hello".to_string(), "world".to_string()), - ("color".to_string(), "orange".to_string())] - .iter() - .cloned() - .collect::>(); - ExternRef::new(inner) - }) - }, - }; - - let instance = Instance::new(&module, &imports)?; - for run in &["run", "run_native"] { - let f: &Function = instance.exports.get_function(run)?; - let results = f.call(&[]).unwrap(); - if let Value::ExternRef(er) = &results[0] { - assert!(er.is_null()); - } else { - panic!("result is not an extern ref!"); + let f: TypedFunction<(), ExternRef> = instance.exports.get_typed_function(run)?; + let result: ExternRef = f.call()?; + assert!(result.is_null()); } - let f: TypedFunction<(), ExternRef> = instance.exports.get_typed_function(run)?; - let result: ExternRef = f.call()?; - assert!(result.is_null()); - } + for get_hashmap in &["get_hashmap", "get_hashmap_native"] { + let f: &Function = instance.exports.get_function(get_hashmap)?; + let results = f.call(&[]).unwrap(); + if let Value::ExternRef(er) = &results[0] { + let inner: &HashMap = er.downcast().unwrap(); + assert_eq!(inner["hello"], "world"); + assert_eq!(inner["color"], "orange"); + } else { + panic!("result is not an extern ref!"); + } - for get_hashmap in &["get_hashmap", "get_hashmap_native"] { - let f: &Function = instance.exports.get_function(get_hashmap)?; - let results = f.call(&[]).unwrap(); - if let Value::ExternRef(er) = &results[0] { - let inner: &HashMap = er.downcast().unwrap(); + let f: TypedFunction<(), ExternRef> = + instance.exports.get_typed_function(get_hashmap)?; + + let result: ExternRef = f.call()?; + let inner: &HashMap = result.downcast().unwrap(); assert_eq!(inner["hello"], "world"); assert_eq!(inner["color"], "orange"); - } else { - panic!("result is not an extern ref!"); } - let f: TypedFunction<(), ExternRef> = - instance.exports.get_typed_function(get_hashmap)?; - - let result: ExternRef = f.call()?; - let inner: &HashMap = result.downcast().unwrap(); - assert_eq!(inner["hello"], "world"); - assert_eq!(inner["color"], "orange"); + Ok(()) } - Ok(()) - } - - #[test] - // TODO(reftypes): reenable this test - #[ignore] - fn extern_ref_ref_counting_basic() -> Result<()> { - let store = Store::default(); - let wat = r#"(module - (func (export "drop") (param $er externref) (result) - (drop (local.get $er))) -)"#; - let module = Module::new(&store, wat)?; - let instance = Instance::new(&module, &imports! {})?; - let f: TypedFunction = instance.exports.get_typed_function("drop")?; - - let er = ExternRef::new(3u32); - f.call(er.clone())?; - - assert_eq!(er.downcast::().unwrap(), &3); - assert_eq!(er.strong_count(), 1); - - Ok(()) - } - - #[test] - fn refs_in_globals() -> Result<()> { - let store = Store::default(); - let wat = r#"(module - (global $er_global (export "er_global") (mut externref) (ref.null extern)) - (global $fr_global (export "fr_global") (mut funcref) (ref.null func)) - (global $fr_immutable_global (export "fr_immutable_global") funcref (ref.func $hello)) - (func $hello (param) (result i32) - (i32.const 73)) -)"#; - let module = Module::new(&store, wat)?; - let instance = Instance::new(&module, &imports! {})?; - { - let er_global: &Global = instance.exports.get_global("er_global")?; - - if let Value::ExternRef(er) = er_global.get() { - assert!(er.is_null()); - } else { - panic!("Did not find extern ref in the global"); - } - - er_global.set(Val::ExternRef(ExternRef::new(3u32)))?; - - if let Value::ExternRef(er) = er_global.get() { - assert_eq!(er.downcast::().unwrap(), &3); - assert_eq!(er.strong_count(), 1); - } else { - panic!("Did not find extern ref in the global"); - } + #[test] + // TODO(reftypes): reenable this test + #[ignore] + fn extern_ref_ref_counting_basic() -> Result<()> { + let store = Store::default(); + let wat = r#"(module + (func (export "drop") (param $er externref) (result) + (drop (local.get $er))) + )"#; + let module = Module::new(&store, wat)?; + let instance = Instance::new(&module, &imports! {})?; + let f: TypedFunction = instance.exports.get_typed_function("drop")?; + + let er = ExternRef::new(3u32); + f.call(er.clone())?; + + assert_eq!(er.downcast::().unwrap(), &3); + assert_eq!(er.strong_count(), 1); + + Ok(()) } - { - let fr_global: &Global = instance.exports.get_global("fr_immutable_global")?; - - if let Value::FuncRef(Some(f)) = fr_global.get() { - let native_func: TypedFunction<(), u32> = f.native()?; - assert_eq!(native_func.call()?, 73); - } else { - panic!("Did not find non-null func ref in the global"); - } - } + #[test] + fn refs_in_globals() -> Result<()> { + let store = Store::default(); + let wat = r#"(module + (global $er_global (export "er_global") (mut externref) (ref.null extern)) + (global $fr_global (export "fr_global") (mut funcref) (ref.null func)) + (global $fr_immutable_global (export "fr_immutable_global") funcref (ref.func $hello)) + (func $hello (param) (result i32) + (i32.const 73)) + )"#; + let module = Module::new(&store, wat)?; + let instance = Instance::new(&module, &imports! {})?; + { + let er_global: &Global = instance.exports.get_global("er_global")?; + + if let Value::ExternRef(er) = er_global.get() { + assert!(er.is_null()); + } else { + panic!("Did not find extern ref in the global"); + } - { - let fr_global: &Global = instance.exports.get_global("fr_global")?; + er_global.set(Value::ExternRef(ExternRef::new(3u32)))?; - if let Value::FuncRef(None) = fr_global.get() { - } else { - panic!("Did not find a null func ref in the global"); + if let Value::ExternRef(er) = er_global.get() { + assert_eq!(er.downcast::().unwrap(), &3); + assert_eq!(er.strong_count(), 1); + } else { + panic!("Did not find extern ref in the global"); + } } - let f = Function::new_native(&store, |arg1: i32, arg2: i32| -> i32 { arg1 + arg2 }); + { + let fr_global: &Global = instance.exports.get_global("fr_immutable_global")?; - fr_global.set(Val::FuncRef(Some(f)))?; - - if let Value::FuncRef(Some(f)) = fr_global.get() { - let native: TypedFunction<(i32, i32), i32> = f.native()?; - assert_eq!(native.call(5, 7)?, 12); - } else { - panic!("Did not find extern ref in the global"); + if let Value::FuncRef(Some(f)) = fr_global.get() { + let native_func: TypedFunction<(), u32> = f.native()?; + assert_eq!(native_func.call()?, 73); + } else { + panic!("Did not find non-null func ref in the global"); + } } - } - Ok(()) - } + { + let fr_global: &Global = instance.exports.get_global("fr_global")?; - #[test] - fn extern_ref_ref_counting_table_basic() -> Result<()> { - let store = Store::default(); - let wat = r#"(module - (global $global (export "global") (mut externref) (ref.null extern)) - (table $table (export "table") 4 4 externref) - (func $insert (param $er externref) (param $idx i32) - (table.set $table (local.get $idx) (local.get $er))) - (func $intermediate (param $er externref) (param $idx i32) - (call $insert (local.get $er) (local.get $idx))) - (func $insert_into_table (export "insert_into_table") (param $er externref) (param $idx i32) (result externref) - (call $intermediate (local.get $er) (local.get $idx)) - (local.get $er)) -)"#; - let module = Module::new(&store, wat)?; - let instance = Instance::new(&module, &imports! {})?; - - let f: TypedFunction<(ExternRef, i32), ExternRef> = - instance.exports.get_typed_function("insert_into_table")?; + if let Value::FuncRef(None) = fr_global.get() { + } else { + panic!("Did not find a null func ref in the global"); + } - let er = ExternRef::new(3usize); + let f = Function::new_native(&store, |arg1: i32, arg2: i32| -> i32 { arg1 + arg2 }); - let er = f.call(er, 1)?; - assert_eq!(er.strong_count(), 2); + fr_global.set(Value::FuncRef(Some(f)))?; - let table: &Table = instance.exports.get_table("table")?; + if let Value::FuncRef(Some(f)) = fr_global.get() { + let native: TypedFunction<(i32, i32), i32> = f.native()?; + assert_eq!(native.call(5, 7)?, 12); + } else { + panic!("Did not find extern ref in the global"); + } + } - { - let er2 = table.get(1).unwrap().externref().unwrap(); - assert_eq!(er2.strong_count(), 3); + Ok(()) } - assert_eq!(er.strong_count(), 2); - table.set(1, Val::ExternRef(ExternRef::null()))?; + #[test] + fn extern_ref_ref_counting_table_basic() -> Result<()> { + let store = Store::default(); + let wat = r#"(module + (global $global (export "global") (mut externref) (ref.null extern)) + (table $table (export "table") 4 4 externref) + (func $insert (param $er externref) (param $idx i32) + (table.set $table (local.get $idx) (local.get $er))) + (func $intermediate (param $er externref) (param $idx i32) + (call $insert (local.get $er) (local.get $idx))) + (func $insert_into_table (export "insert_into_table") (param $er externref) (param $idx i32) (result externref) + (call $intermediate (local.get $er) (local.get $idx)) + (local.get $er)) + )"#; + let module = Module::new(&store, wat)?; + let instance = Instance::new(&module, &imports! {})?; + + let f: TypedFunction<(ExternRef, i32), ExternRef> = + instance.exports.get_typed_function("insert_into_table")?; - assert_eq!(er.strong_count(), 1); + let er = ExternRef::new(3usize); - Ok(()) - } + let er = f.call(er, 1)?; + assert_eq!(er.strong_count(), 2); - #[test] - // TODO(reftypes): reenable this test - #[ignore] - fn extern_ref_ref_counting_global_basic() -> Result<()> { - let store = Store::default(); - let wat = r#"(module - (global $global (export "global") (mut externref) (ref.null extern)) - (func $get_from_global (export "get_from_global") (result externref) - (drop (global.get $global)) - (global.get $global)) -)"#; - let module = Module::new(&store, wat)?; - let instance = Instance::new(&module, &imports! {})?; + let table: &Table = instance.exports.get_table("table")?; - let global: &Global = instance.exports.get_global("global")?; - { - let er = ExternRef::new(3usize); - global.set(Val::ExternRef(er.clone()))?; - assert_eq!(er.strong_count(), 2); - } - let get_from_global: TypedFunction<(), ExternRef> = - instance.exports.get_typed_function("get_from_global")?; + { + let er2 = table.get(1).unwrap().externref().unwrap(); + assert_eq!(er2.strong_count(), 3); + } - let er = get_from_global.call()?; - assert_eq!(er.strong_count(), 2); - global.set(Val::ExternRef(ExternRef::null()))?; - assert_eq!(er.strong_count(), 1); + assert_eq!(er.strong_count(), 2); + table.set(1, Value::ExternRef(ExternRef::null()))?; - Ok(()) - } + assert_eq!(er.strong_count(), 1); - #[test] - // TODO(reftypes): reenable this test - #[ignore] - fn extern_ref_ref_counting_traps() -> Result<()> { - let store = Store::default(); - let wat = r#"(module - (func $pass_er (export "pass_extern_ref") (param externref) - (local.get 0) - (unreachable)) -)"#; - let module = Module::new(&store, wat)?; - let instance = Instance::new(&module, &imports! {})?; + Ok(()) + } - let pass_extern_ref: TypedFunction = - instance.exports.get_typed_function("pass_extern_ref")?; + #[test] + // TODO(reftypes): reenable this test + #[ignore] + fn extern_ref_ref_counting_global_basic() -> Result<()> { + let store = Store::default(); + let wat = r#"(module + (global $global (export "global") (mut externref) (ref.null extern)) + (func $get_from_global (export "get_from_global") (result externref) + (drop (global.get $global)) + (global.get $global)) + )"#; + let module = Module::new(&store, wat)?; + let instance = Instance::new(&module, &imports! {})?; + + let global: &Global = instance.exports.get_global("global")?; + { + let er = ExternRef::new(3usize); + global.set(Value::ExternRef(er.clone()))?; + assert_eq!(er.strong_count(), 2); + } + let get_from_global: TypedFunction<(), ExternRef> = + instance.exports.get_typed_function("get_from_global")?; - let er = ExternRef::new(3usize); - assert_eq!(er.strong_count(), 1); + let er = get_from_global.call()?; + assert_eq!(er.strong_count(), 2); + global.set(Value::ExternRef(ExternRef::null()))?; + assert_eq!(er.strong_count(), 1); - let result = pass_extern_ref.call(er.clone()); - assert!(result.is_err()); - assert_eq!(er.strong_count(), 1); + Ok(()) + } - Ok(()) - } + #[test] + // TODO(reftypes): reenable this test + #[ignore] + fn extern_ref_ref_counting_traps() -> Result<()> { + let store = Store::default(); + let wat = r#"(module + (func $pass_er (export "pass_extern_ref") (param externref) + (local.get 0) + (unreachable)) + )"#; + let module = Module::new(&store, wat)?; + let instance = Instance::new(&module, &imports! {})?; + + let pass_extern_ref: TypedFunction = + instance.exports.get_typed_function("pass_extern_ref")?; - #[test] - fn extern_ref_ref_counting_table_instructions() -> Result<()> { - let store = Store::default(); - let wat = r#"(module - (table $table1 (export "table1") 2 12 externref) - (table $table2 (export "table2") 6 12 externref) - (func $grow_table_with_ref (export "grow_table_with_ref") (param $er externref) (param $size i32) (result i32) - (table.grow $table1 (local.get $er) (local.get $size))) - (func $fill_table_with_ref (export "fill_table_with_ref") (param $er externref) (param $start i32) (param $end i32) - (table.fill $table1 (local.get $start) (local.get $er) (local.get $end))) - (func $copy_into_table2 (export "copy_into_table2") - (table.copy $table2 $table1 (i32.const 0) (i32.const 0) (i32.const 4))) -)"#; - let module = Module::new(&store, wat)?; - let instance = Instance::new(&module, &imports! {})?; - - let grow_table_with_ref: TypedFunction<(ExternRef, i32), i32> = - instance.exports.get_typed_function("grow_table_with_ref")?; - let fill_table_with_ref: TypedFunction<(ExternRef, i32, i32), ()> = - instance.exports.get_typed_function("fill_table_with_ref")?; - let copy_into_table2: TypedFunction<(), ()> = - instance.exports.get_typed_function("copy_into_table2")?; - let table1: &Table = instance.exports.get_table("table1")?; - let table2: &Table = instance.exports.get_table("table2")?; - - let er1 = ExternRef::new(3usize); - let er2 = ExternRef::new(5usize); - let er3 = ExternRef::new(7usize); - { - let result = grow_table_with_ref.call(er1.clone(), 0)?; - assert_eq!(result, 2); - assert_eq!(er1.strong_count(), 1); + let er = ExternRef::new(3usize); + assert_eq!(er.strong_count(), 1); - let result = grow_table_with_ref.call(er1.clone(), 10_000)?; - assert_eq!(result, -1); - assert_eq!(er1.strong_count(), 1); + let result = pass_extern_ref.call(er.clone()); + assert!(result.is_err()); + assert_eq!(er.strong_count(), 1); - let result = grow_table_with_ref.call(er1.clone(), 8)?; - assert_eq!(result, 2); - assert_eq!(er1.strong_count(), 9); + Ok(()) + } - for i in 2..10 { - let e = table1.get(i).unwrap().unwrap_externref(); - assert_eq!(*e.downcast::().unwrap(), 3); - assert_eq!(&e, &er1); + #[test] + fn extern_ref_ref_counting_table_instructions() -> Result<()> { + let store = Store::default(); + let wat = r#"(module + (table $table1 (export "table1") 2 12 externref) + (table $table2 (export "table2") 6 12 externref) + (func $grow_table_with_ref (export "grow_table_with_ref") (param $er externref) (param $size i32) (result i32) + (table.grow $table1 (local.get $er) (local.get $size))) + (func $fill_table_with_ref (export "fill_table_with_ref") (param $er externref) (param $start i32) (param $end i32) + (table.fill $table1 (local.get $start) (local.get $er) (local.get $end))) + (func $copy_into_table2 (export "copy_into_table2") + (table.copy $table2 $table1 (i32.const 0) (i32.const 0) (i32.const 4))) + )"#; + let module = Module::new(&store, wat)?; + let instance = Instance::new(&module, &imports! {})?; + + let grow_table_with_ref: TypedFunction<(ExternRef, i32), i32> = + instance.exports.get_typed_function("grow_table_with_ref")?; + let fill_table_with_ref: TypedFunction<(ExternRef, i32, i32), ()> = + instance.exports.get_typed_function("fill_table_with_ref")?; + let copy_into_table2: TypedFunction<(), ()> = + instance.exports.get_typed_function("copy_into_table2")?; + let table1: &Table = instance.exports.get_table("table1")?; + let table2: &Table = instance.exports.get_table("table2")?; + + let er1 = ExternRef::new(3usize); + let er2 = ExternRef::new(5usize); + let er3 = ExternRef::new(7usize); + { + let result = grow_table_with_ref.call(er1.clone(), 0)?; + assert_eq!(result, 2); + assert_eq!(er1.strong_count(), 1); + + let result = grow_table_with_ref.call(er1.clone(), 10_000)?; + assert_eq!(result, -1); + assert_eq!(er1.strong_count(), 1); + + let result = grow_table_with_ref.call(er1.clone(), 8)?; + assert_eq!(result, 2); + assert_eq!(er1.strong_count(), 9); + + for i in 2..10 { + let e = table1.get(i).unwrap().unwrap_externref(); + assert_eq!(*e.downcast::().unwrap(), 3); + assert_eq!(&e, &er1); + } + assert_eq!(er1.strong_count(), 9); } - assert_eq!(er1.strong_count(), 9); - } - { - fill_table_with_ref.call(er2.clone(), 0, 2)?; - assert_eq!(er2.strong_count(), 3); - } + { + fill_table_with_ref.call(er2.clone(), 0, 2)?; + assert_eq!(er2.strong_count(), 3); + } - { - table2.set(0, Val::ExternRef(er3.clone()))?; - table2.set(1, Val::ExternRef(er3.clone()))?; - table2.set(2, Val::ExternRef(er3.clone()))?; - table2.set(3, Val::ExternRef(er3.clone()))?; - table2.set(4, Val::ExternRef(er3.clone()))?; - assert_eq!(er3.strong_count(), 6); - } + { + table2.set(0, Value::ExternRef(er3.clone()))?; + table2.set(1, Value::ExternRef(er3.clone()))?; + table2.set(2, Value::ExternRef(er3.clone()))?; + table2.set(3, Value::ExternRef(er3.clone()))?; + table2.set(4, Value::ExternRef(er3.clone()))?; + assert_eq!(er3.strong_count(), 6); + } - { - copy_into_table2.call()?; - assert_eq!(er3.strong_count(), 2); - assert_eq!(er2.strong_count(), 5); - assert_eq!(er1.strong_count(), 11); - for i in 1..5 { - let e = table2.get(i).unwrap().unwrap_externref(); - let value = e.downcast::().unwrap(); - match i { - 0 | 1 => assert_eq!(*value, 5), - 4 => assert_eq!(*value, 7), - _ => assert_eq!(*value, 3), + { + copy_into_table2.call()?; + assert_eq!(er3.strong_count(), 2); + assert_eq!(er2.strong_count(), 5); + assert_eq!(er1.strong_count(), 11); + for i in 1..5 { + let e = table2.get(i).unwrap().unwrap_externref(); + let value = e.downcast::().unwrap(); + match i { + 0 | 1 => assert_eq!(*value, 5), + 4 => assert_eq!(*value, 7), + _ => assert_eq!(*value, 3), + } } } - } - { - for i in 0..table1.size() { - table1.set(i, Val::ExternRef(ExternRef::null()))?; - } - for i in 0..table2.size() { - table2.set(i, Val::ExternRef(ExternRef::null()))?; + { + for i in 0..table1.size() { + table1.set(i, Value::ExternRef(ExternRef::null()))?; + } + for i in 0..table2.size() { + table2.set(i, Value::ExternRef(ExternRef::null()))?; + } } - } - assert_eq!(er1.strong_count(), 1); - assert_eq!(er2.strong_count(), 1); - assert_eq!(er3.strong_count(), 1); + assert_eq!(er1.strong_count(), 1); + assert_eq!(er2.strong_count(), 1); + assert_eq!(er3.strong_count(), 1); - Ok(()) - } + Ok(()) + } + */ } diff --git a/lib/derive/tests/basic.rs b/lib/derive/tests/basic.rs deleted file mode 100644 index 7b15df4e3ef..00000000000 --- a/lib/derive/tests/basic.rs +++ /dev/null @@ -1,119 +0,0 @@ -#![allow(dead_code)] - -use wasmer::{Function, Global, LazyInit, Memory, Table, TypedFunction, WasmerEnv}; - -#[derive(WasmerEnv, Clone)] -struct MyEnv { - num: u32, - nums: Vec, -} - -fn impls_wasmer_env() -> bool { - true -} - -#[test] -fn test_derive() { - let _my_env = MyEnv { - num: 3, - nums: vec![1, 2, 3], - }; - assert!(impls_wasmer_env::()); -} - -#[derive(WasmerEnv, Clone)] -struct MyEnvWithMemory { - num: u32, - nums: Vec, - #[wasmer(export)] - memory: LazyInit, -} - -#[derive(WasmerEnv, Clone)] -struct MyEnvWithFuncs { - num: u32, - nums: Vec, - #[wasmer(export)] - memory: LazyInit, - #[wasmer(export)] - sum: LazyInit>, -} - -#[derive(WasmerEnv, Clone)] -struct MyEnvWithEverything { - num: u32, - nums: Vec, - #[wasmer(export)] - memory: LazyInit, - #[wasmer(export)] - sum: LazyInit>, - #[wasmer(export)] - multiply: LazyInit, - #[wasmer(export)] - counter: LazyInit, - #[wasmer(export)] - functions: LazyInit
, -} - -#[derive(WasmerEnv, Clone)] -struct MyEnvWithLifetime<'a> { - name: &'a str, - #[wasmer(export(name = "memory"))] - memory: LazyInit, -} - -#[derive(WasmerEnv, Clone)] -struct MyUnitStruct; - -#[derive(WasmerEnv, Clone)] -struct MyTupleStruct(u32); - -#[derive(WasmerEnv, Clone)] -struct MyTupleStruct2(u32, u32); - -#[derive(WasmerEnv, Clone)] -struct MyTupleStructWithAttribute(#[wasmer(export(name = "memory"))] LazyInit, u32); - -#[test] -fn test_derive_with_attribute() { - assert!(impls_wasmer_env::()); - assert!(impls_wasmer_env::()); - assert!(impls_wasmer_env::()); - assert!(impls_wasmer_env::()); - assert!(impls_wasmer_env::()); - assert!(impls_wasmer_env::()); - assert!(impls_wasmer_env::()); - assert!(impls_wasmer_env::()); -} - -#[derive(WasmerEnv, Clone)] -struct StructWithOptionalField { - #[wasmer(export(optional = true))] - memory: LazyInit, - #[wasmer(export(optional = true, name = "real_memory"))] - memory2: LazyInit, - #[wasmer(export(optional = false))] - memory3: LazyInit, -} - -#[test] -fn test_derive_with_optional() { - assert!(impls_wasmer_env::()); -} - -#[derive(WasmerEnv, Clone)] -struct StructWithAliases { - #[wasmer(export(alias = "_memory"))] - memory: LazyInit, - #[wasmer(export(alias = "_real_memory", optional = true, name = "real_memory"))] - memory2: LazyInit, - #[wasmer(export(alias = "_memory3", alias = "__memory3"))] - memory3: LazyInit, - #[wasmer(export(alias = "_memory3", name = "memory4", alias = "__memory3"))] - memory4: LazyInit, -} - -#[test] -fn test_derive_with_aliases() { - assert!(impls_wasmer_env::()); -} diff --git a/lib/middlewares/src/metering.rs b/lib/middlewares/src/metering.rs index a3fce84a8ff..5320412dcfa 100644 --- a/lib/middlewares/src/metering.rs +++ b/lib/middlewares/src/metering.rs @@ -12,6 +12,7 @@ use std::convert::TryInto; use std::fmt; use std::sync::{Arc, Mutex}; use wasmer::wasmparser::{Operator, Type as WpType, TypeOrFuncType as WpTypeOrFuncType}; +use wasmer::Context as WasmerContext; use wasmer::{ AsContextMut, ExportIndex, FunctionMiddleware, GlobalInit, GlobalType, Instance, LocalFunctionIndex, MiddlewareError, MiddlewareReaderState, ModuleMiddleware, Mutability, Type, @@ -442,7 +443,7 @@ mod tests { // Instantiate let instance = Instance::new(&mut ctx, &module, &imports! {}).unwrap(); assert_eq!( - get_remaining_points(ctx.as_context_mut(), &instance), + get_remaining_points(&mut ctx, &instance), MeteringPoints::Remaining(10) ); let add_one: TypedFunction = instance @@ -453,37 +454,37 @@ mod tests { .unwrap(); // Increase a bit to have enough for 3 calls - set_remaining_points(ctx.as_context_mut(), &instance, 12); + set_remaining_points(&mut ctx, &instance, 12); // Ensure we can use the new points now - add_one.call(&mut ctx.as_context_mut(), 1).unwrap(); + add_one.call(&mut &mut ctx, 1).unwrap(); assert_eq!( - get_remaining_points(ctx.as_context_mut(), &instance), + get_remaining_points(&mut ctx, &instance), MeteringPoints::Remaining(8) ); - add_one.call(&mut ctx.as_context_mut(), 1).unwrap(); + add_one.call(&mut &mut ctx, 1).unwrap(); assert_eq!( - get_remaining_points(ctx.as_context_mut(), &instance), + get_remaining_points(&mut ctx, &instance), MeteringPoints::Remaining(4) ); - add_one.call(&mut ctx.as_context_mut(), 1).unwrap(); + add_one.call(&mut &mut ctx, 1).unwrap(); assert_eq!( - get_remaining_points(ctx.as_context_mut(), &instance), + get_remaining_points(&mut ctx, &instance), MeteringPoints::Remaining(0) ); - assert!(add_one.call(&mut ctx.as_context_mut(), 1).is_err()); + assert!(add_one.call(&mut &mut ctx, 1).is_err()); assert_eq!( - get_remaining_points(ctx.as_context_mut(), &instance), + get_remaining_points(&mut ctx, &instance), MeteringPoints::Exhausted ); // Add some points for another call - set_remaining_points(ctx.as_context_mut(), &instance, 4); + set_remaining_points(&mut ctx, &instance, 4); assert_eq!( - get_remaining_points(ctx.as_context_mut(), &instance), + get_remaining_points(&mut ctx, &instance), MeteringPoints::Remaining(4) ); } diff --git a/lib/types/src/value.rs b/lib/types/src/value.rs index 8e822d79146..2347832cc03 100644 --- a/lib/types/src/value.rs +++ b/lib/types/src/value.rs @@ -13,6 +13,7 @@ pub union RawValue { pub u64: u64, pub f32: f32, pub f64: f64, + pub i128: i128, pub u128: u128, pub funcref: usize, pub externref: usize, @@ -33,6 +34,32 @@ impl fmt::Debug for RawValue { } } +macro_rules! partial_eq { + ($($t:ty => $f:tt),*) => ($( + impl PartialEq<$t> for RawValue { + fn eq(&self, o: &$t) -> bool { + unsafe { self.$f == *o } + } + } + )*) +} +partial_eq! { + i32 => i32, + u32 => u32, + i64 => i64, + u64 => u64, + f32 => f32, + f64 => f64, + i128 => i128, + u128 => u128 +} + +impl PartialEq for RawValue { + fn eq(&self, o: &Self) -> bool { + unsafe { self.u128 == o.u128 } + } +} + /// Trait for a Value type. A Value type is a type that is always valid and may /// be safely copied. /// diff --git a/tests/compilers/imports.rs b/tests/compilers/imports.rs index f2fa3e215ac..232103d0a86 100644 --- a/tests/compilers/imports.rs +++ b/tests/compilers/imports.rs @@ -181,22 +181,16 @@ fn static_function(config: crate::Config) -> Result<()> { let f0 = Function::new_native(&mut ctx, |_ctx: ContextMut<_>| { assert_eq!(HITS.fetch_add(1, SeqCst), 0); }); - let f1 = Function::new_native( - &mut ctx, - |_ctx: ContextMut<_>, x: i32| -> i32 { - assert_eq!(x, 0); - assert_eq!(HITS.fetch_add(1, SeqCst), 1); - 1 - }, - ); - let f2 = Function::new_native( - &mut ctx, - |_ctx: ContextMut<_>, x: i32, y: i64| { - assert_eq!(x, 2); - assert_eq!(y, 3); - assert_eq!(HITS.fetch_add(1, SeqCst), 2); - }, - ); + let f1 = Function::new_native(&mut ctx, |_ctx: ContextMut<_>, x: i32| -> i32 { + assert_eq!(x, 0); + assert_eq!(HITS.fetch_add(1, SeqCst), 1); + 1 + }); + let f2 = Function::new_native(&mut ctx, |_ctx: ContextMut<_>, x: i32, y: i64| { + assert_eq!(x, 2); + assert_eq!(y, 3); + assert_eq!(HITS.fetch_add(1, SeqCst), 2); + }); let f3 = Function::new_native( &mut ctx, |_ctx: ContextMut<_>, a: i32, b: i64, c: i32, d: f32, e: f64| { @@ -243,14 +237,11 @@ fn static_function_with_results(config: crate::Config) -> Result<()> { Ok(1) }, ); - let f2 = Function::new_native( - &mut ctx, - |_ctx: ContextMut<_>, x: i32, y: i64| { - assert_eq!(x, 2); - assert_eq!(y, 3); - assert_eq!(HITS.fetch_add(1, SeqCst), 2); - }, - ); + let f2 = Function::new_native(&mut ctx, |_ctx: ContextMut<_>, x: i32, y: i64| { + assert_eq!(x, 2); + assert_eq!(y, 3); + assert_eq!(HITS.fetch_add(1, SeqCst), 2); + }); let f3 = Function::new_native( &mut ctx, |_ctx: ContextMut<_>, a: i32, b: i64, c: i32, d: f32, e: f64| { @@ -298,22 +289,16 @@ fn static_function_with_env(config: crate::Config) -> Result<()> { let f0 = Function::new_native(&mut ctx, |ctx: ContextMut| { assert_eq!(ctx.data().fetch_add(1, SeqCst), 0); }); - let f1 = Function::new_native( - &mut ctx, - |ctx: ContextMut, x: i32| -> i32 { - assert_eq!(x, 0); - assert_eq!(ctx.data().fetch_add(1, SeqCst), 1); - 1 - }, - ); - let f2 = Function::new_native( - &mut ctx, - |ctx: ContextMut, x: i32, y: i64| { - assert_eq!(x, 2); - assert_eq!(y, 3); - assert_eq!(ctx.data().fetch_add(1, SeqCst), 2); - }, - ); + let f1 = Function::new_native(&mut ctx, |ctx: ContextMut, x: i32| -> i32 { + assert_eq!(x, 0); + assert_eq!(ctx.data().fetch_add(1, SeqCst), 1); + 1 + }); + let f2 = Function::new_native(&mut ctx, |ctx: ContextMut, x: i32, y: i64| { + assert_eq!(x, 2); + assert_eq!(y, 3); + assert_eq!(ctx.data().fetch_add(1, SeqCst), 2); + }); let f3 = Function::new_native( &mut ctx, |ctx: ContextMut, a: i32, b: i64, c: i32, d: f32, e: f64| { @@ -429,9 +414,7 @@ fn dynamic_function_with_env_wasmer_env_init_works(config: crate::Config) -> Res )?; let memory = instance.exports.get_memory("memory")?; ctx.data_mut().memory = Some(memory.clone()); - let f: TypedFunction<(), ()> = instance - .exports - .get_typed_function(&ctx, "main")?; + let f: TypedFunction<(), ()> = instance.exports.get_typed_function(&ctx, "main")?; f.call(&mut ctx)?; Ok(()) } @@ -469,18 +452,14 @@ fn multi_use_host_fn_manages_memory_correctly(config: crate::Config) -> Result<( let instance1 = Instance::new(&mut ctx, &module, &imports)?; let instance2 = Instance::new(&mut ctx, &module, &imports)?; { - let f1: TypedFunction<(), ()> = instance1 - .exports - .get_typed_function(&mut ctx, "main")?; + let f1: TypedFunction<(), ()> = instance1.exports.get_typed_function(&mut ctx, "main")?; let memory = instance1.exports.get_memory("memory")?; ctx.data_mut().memory = Some(memory.clone()); f1.call(&mut ctx)?; } drop(instance1); { - let f2: TypedFunction<(), ()> = instance2 - .exports - .get_typed_function(&mut ctx, "main")?; + let f2: TypedFunction<(), ()> = instance2.exports.get_typed_function(&mut ctx, "main")?; let memory = instance2.exports.get_memory("memory")?; ctx.data_mut().memory = Some(memory.clone()); f2.call(&mut ctx)?; @@ -521,12 +500,10 @@ fn instance_local_memory_lifetime(config: crate::Config) -> Result<()> { }, }; let instance = Instance::new(&mut ctx, &module, &imports)?; - let set_at: TypedFunction<(i32, i32), ()> = instance - .exports - .get_typed_function(&mut ctx, "set_at")?; - let get_at: TypedFunction = instance - .exports - .get_typed_function(&mut ctx, "get_at")?; + let set_at: TypedFunction<(i32, i32), ()> = + instance.exports.get_typed_function(&mut ctx, "set_at")?; + let get_at: TypedFunction = + instance.exports.get_typed_function(&mut ctx, "get_at")?; set_at.call(&mut ctx, 200, 123)?; assert_eq!(get_at.call(&mut ctx, 200)?, 123); diff --git a/tests/compilers/issues.rs b/tests/compilers/issues.rs index 1db95f4ccbd..07064cc95ca 100644 --- a/tests/compilers/issues.rs +++ b/tests/compilers/issues.rs @@ -196,22 +196,10 @@ fn call_with_static_data_pointers(mut config: crate::Config) -> Result<()> { ctx.data_mut().memory = Some(memory.clone()); let mut exports = Exports::new(); exports.insert("memory", memory); - exports.insert( - "banana", - Function::new_native(&mut ctx, banana), - ); - exports.insert( - "peach", - Function::new_native(&mut ctx, peach), - ); - exports.insert( - "chaenomeles", - Function::new_native(&mut ctx, chaenomeles), - ); - exports.insert( - "mango", - Function::new_native(&mut ctx, mango), - ); + exports.insert("banana", Function::new_native(&mut ctx, banana)); + exports.insert("peach", Function::new_native(&mut ctx, peach)); + exports.insert("chaenomeles", Function::new_native(&mut ctx, chaenomeles)); + exports.insert("mango", Function::new_native(&mut ctx, mango)); exports.insert("gas", Function::new_native(&mut ctx, gas)); let mut imports = Imports::new(); imports.register_namespace("env", exports); diff --git a/tests/compilers/metering.rs b/tests/compilers/metering.rs index aaa3aa01487..faf43e3ee55 100644 --- a/tests/compilers/metering.rs +++ b/tests/compilers/metering.rs @@ -27,9 +27,7 @@ fn run_add_with_limit(mut config: crate::Config, limit: u64) -> Result<()> { let module = Module::new(&store, wat).unwrap(); let instance = Instance::new(&mut ctx, &module, &import_object)?; - let f: TypedFunction<(i32, i32), i32> = instance - .exports - .get_typed_function(&mut ctx, "add")?; + let f: TypedFunction<(i32, i32), i32> = instance.exports.get_typed_function(&mut ctx, "add")?; f.call(&mut ctx, 4, 6)?; Ok(()) } @@ -61,9 +59,7 @@ fn run_loop(mut config: crate::Config, limit: u64, iter_count: i32) -> Result<() let instance = Instance::new(&mut ctx, &module, &import_object)?; - let f: TypedFunction = instance - .exports - .get_typed_function(&mut ctx, "test")?; + let f: TypedFunction = instance.exports.get_typed_function(&mut ctx, "test")?; f.call(&mut ctx, iter_count)?; Ok(()) } @@ -167,13 +163,11 @@ fn complex_loop(mut config: crate::Config) -> Result<()> { let instance = Instance::new(&mut ctx, &module, &import_object)?; - let f: TypedFunction<(i32, i32), i32> = instance - .exports - .get_typed_function(&mut ctx, "add_to")?; + let f: TypedFunction<(i32, i32), i32> = + instance.exports.get_typed_function(&mut ctx, "add_to")?; // FIXME: Since now a metering error is signaled with an `unreachable`, it is impossible to verify // the error type. Fix this later. - f.call(&mut ctx, 10_000_000, 4) - .unwrap_err(); + f.call(&mut ctx, 10_000_000, 4).unwrap_err(); Ok(()) } diff --git a/tests/compilers/middlewares.rs b/tests/compilers/middlewares.rs index fabb2f894d7..700051da7b7 100644 --- a/tests/compilers/middlewares.rs +++ b/tests/compilers/middlewares.rs @@ -106,9 +106,7 @@ fn middleware_basic(mut config: crate::Config) -> Result<()> { let instance = Instance::new(&mut ctx, &module, &import_object)?; - let f: TypedFunction<(i32, i32), i32> = instance - .exports - .get_typed_function(&mut ctx, "add")?; + let f: TypedFunction<(i32, i32), i32> = instance.exports.get_typed_function(&mut ctx, "add")?; let result = f.call(&mut ctx, 4, 6)?; assert_eq!(result, 24); Ok(()) @@ -131,9 +129,7 @@ fn middleware_one_to_multi(mut config: crate::Config) -> Result<()> { let instance = Instance::new(&mut ctx, &module, &import_object)?; - let f: TypedFunction<(i32, i32), i32> = instance - .exports - .get_typed_function(&mut ctx, "add")?; + let f: TypedFunction<(i32, i32), i32> = instance.exports.get_typed_function(&mut ctx, "add")?; let result = f.call(&mut ctx, 4, 6)?; assert_eq!(result, 25); Ok(()) @@ -157,9 +153,8 @@ fn middleware_multi_to_one(mut config: crate::Config) -> Result<()> { let instance = Instance::new(&mut ctx, &module, &import_object)?; - let f: TypedFunction<(i32, i32), i32> = instance - .exports - .get_typed_function(&mut ctx, "testfunc")?; + let f: TypedFunction<(i32, i32), i32> = + instance.exports.get_typed_function(&mut ctx, "testfunc")?; let result = f.call(&mut ctx, 10, 20)?; assert_eq!(result, 10); Ok(()) @@ -183,9 +178,7 @@ fn middleware_chain_order_1(mut config: crate::Config) -> Result<()> { let instance = Instance::new(&mut ctx, &module, &import_object)?; - let f: TypedFunction<(i32, i32), i32> = instance - .exports - .get_typed_function(&mut ctx, "add")?; + let f: TypedFunction<(i32, i32), i32> = instance.exports.get_typed_function(&mut ctx, "add")?; let result = f.call(&mut ctx, 4, 6)?; assert_eq!(result, 24); Ok(()) @@ -209,9 +202,7 @@ fn middleware_chain_order_2(mut config: crate::Config) -> Result<()> { let instance = Instance::new(&mut ctx, &module, &import_object)?; - let f: TypedFunction<(i32, i32), i32> = instance - .exports - .get_typed_function(&mut ctx, "add")?; + let f: TypedFunction<(i32, i32), i32> = instance.exports.get_typed_function(&mut ctx, "add")?; let result = f.call(&mut ctx, 4, 6)?; assert_eq!(result, 48); Ok(()) diff --git a/tests/compilers/native_functions.rs b/tests/compilers/native_functions.rs index 28ca6d8263d..11d1f5295dc 100644 --- a/tests/compilers/native_functions.rs +++ b/tests/compilers/native_functions.rs @@ -69,9 +69,8 @@ fn native_function_works_for_wasm(config: crate::Config) -> anyhow::Result<()> { let instance = Instance::new(&mut ctx, &module, &import_object)?; { - let f: TypedFunction<(i32, i32), i32> = instance - .exports - .get_typed_function(&mut ctx, "add")?; + let f: TypedFunction<(i32, i32), i32> = + instance.exports.get_typed_function(&mut ctx, "add")?; let result = f.call(&mut ctx, 4, 6)?; assert_eq!(result, 10); } @@ -172,9 +171,8 @@ fn non_native_functions_and_closures_with_no_env_work(config: crate::Config) -> let instance = Instance::new(&mut ctx, &module, &import_object)?; - let test: TypedFunction<(i32, i32, i32, i32, i32), i32> = instance - .exports - .get_typed_function(&mut ctx, "test")?; + let test: TypedFunction<(i32, i32, i32, i32, i32), i32> = + instance.exports.get_typed_function(&mut ctx, "test")?; let result = test.call(&mut ctx, 2, 3, 4, 5, 6)?; let manually_computed_result = 6 * (5 * (4 * (3 * 2 * 20) * 10 * 20)) * 10; diff --git a/tests/compilers/traps.rs b/tests/compilers/traps.rs index 4516ad8b4e0..4cf7d4226fb 100644 --- a/tests/compilers/traps.rs +++ b/tests/compilers/traps.rs @@ -317,9 +317,7 @@ fn rust_panic_import(config: crate::Config) -> Result<()> { let module = Module::new(&store, &binary)?; let mut ctx = WasmerContext::new(&store, ()); let sig = FunctionType::new(vec![], vec![]); - let func = Function::new(&mut ctx, &sig, |_ctx, _| { - panic!("this is a panic") - }); + let func = Function::new(&mut ctx, &sig, |_ctx, _| panic!("this is a panic")); let f0 = Function::new_native(&mut ctx, |_ctx: ContextMut<_>| { panic!("this is another panic") }); @@ -367,9 +365,7 @@ fn rust_panic_start_function(config: crate::Config) -> Result<()> { let module = Module::new(&store, &binary)?; let mut ctx = WasmerContext::new(&store, ()); let sig = FunctionType::new(vec![], vec![]); - let func = Function::new(&mut ctx, &sig, |_ctx, _| { - panic!("this is a panic") - }); + let func = Function::new(&mut ctx, &sig, |_ctx, _| panic!("this is a panic")); let err = panic::catch_unwind(AssertUnwindSafe(|| { drop(Instance::new( &mut ctx, @@ -420,9 +416,7 @@ fn mismatched_arguments(config: crate::Config) -> Result<()> { let instance = Instance::new(&mut ctx, &module, &imports! {})?; let func: &Function = instance.exports.get("foo")?; assert_eq!( - func.call(&mut ctx, &[]) - .unwrap_err() - .message(), + func.call(&mut ctx, &[]).unwrap_err().message(), "Parameters of type [] did not match signature [I32] -> []" ); assert_eq!(