diff --git a/lib/api/src/externals/function.rs b/lib/api/src/externals/function.rs index 3f723460e..7d57748dc 100644 --- a/lib/api/src/externals/function.rs +++ b/lib/api/src/externals/function.rs @@ -56,7 +56,7 @@ impl Function { F: HostFunction, Args: WasmTypeList, Rets: WasmTypeList, - Env: Sized, + Env: Clone + Sized, { let func: wasm_common::Func = wasm_common::Func::new(func); let address = func.address() as *const VMFunctionBody; @@ -106,7 +106,7 @@ impl Function { pub fn new_dynamic_env(store: &Store, ty: &FunctionType, env: Env, func: F) -> Self where F: Fn(&mut Env, &[Val]) -> Result, RuntimeError> + 'static, - Env: Sized, + Env: Clone + Sized, { let dynamic_ctx = VMDynamicFunctionContext::from_context(VMDynamicFunctionWithEnv { env: Cell::new(env), @@ -141,7 +141,7 @@ impl Function { F: HostFunction, Args: WasmTypeList, Rets: WasmTypeList, - Env: Sized, + Env: Clone + Sized, { let func: wasm_common::Func = wasm_common::Func::new(func); let address = func.address() as *const VMFunctionBody; diff --git a/tests/compilers/functions.rs b/tests/compilers/functions.rs index bfa3a91c3..9b2a94acf 100644 --- a/tests/compilers/functions.rs +++ b/tests/compilers/functions.rs @@ -1,5 +1,7 @@ use crate::utils::get_store; use anyhow::Result; +use std::cell::RefCell; +use std::rc::Rc; use wasmer::*; @@ -57,10 +59,13 @@ fn static_raw_call_no_env() -> anyhow::Result<()> { #[test] fn static_raw_call_with_env() -> anyhow::Result<()> { let store = get_store(); + #[derive(Clone)] struct Env { - val: i32, + val: Rc>, + }; + let env = Env { + val: Rc::new(RefCell::new(100)), }; - let mut env = Env { val: 100 }; fn reverse_duplicate_host( env: &mut Env, a: i32, @@ -68,17 +73,17 @@ fn static_raw_call_with_env() -> anyhow::Result<()> { c: f32, d: f64, ) -> (f64, f32, i64, i32) { - assert_eq!(env.val, 100); - env.val = 101; + assert_eq!(*env.val.borrow(), 100); + env.val.replace(101); (d * 4.0, c * 3.0, b * 2, a * 1) } - let reverse_duplicate = wasmer::Function::new_env(&store, &mut env, reverse_duplicate_host); + let reverse_duplicate = wasmer::Function::new_env(&store, env.clone(), reverse_duplicate_host); let reverse_duplicate_native: NativeFunc<(i32, i64, f32, f64), (f64, f32, i64, i32)> = reverse_duplicate.native().unwrap(); - assert_eq!(env.val, 100); + assert_eq!(*env.val.borrow(), 100); let result = reverse_duplicate_native.call(1, 3, 5.0, 7.0)?; assert_eq!(result, (28.0, 15.0, 6, 1)); - assert_eq!(env.val, 101); + assert_eq!(*env.val.borrow(), 101); Ok(()) } @@ -120,10 +125,13 @@ fn dynamic_raw_call_no_env() -> anyhow::Result<()> { #[test] fn dynamic_raw_call_with_env() -> anyhow::Result<()> { let store = get_store(); + #[derive(Clone)] struct Env { - val: i32, + val: Rc>, + }; + let env = Env { + val: Rc::new(RefCell::new(100)), }; - let mut env = Env { val: 100 }; let reverse_duplicate = wasmer::Function::new_dynamic_env( &store, &wasmer::FunctionType::new( @@ -140,10 +148,10 @@ fn dynamic_raw_call_with_env() -> anyhow::Result<()> { wasmer::ValType::I32, ], ), - &mut env, + env.clone(), |env, values| { - assert_eq!(env.val, 100); - env.val = 101; + assert_eq!(*env.val.borrow(), 100); + env.val.replace(101); Ok(vec![ Value::F64(values[3].unwrap_f64() * 4.0), Value::F32(values[2].unwrap_f32() * 3.0), @@ -154,9 +162,9 @@ fn dynamic_raw_call_with_env() -> anyhow::Result<()> { ); let reverse_duplicate_native: NativeFunc<(i32, i64, f32, f64), (f64, f32, i64, i32)> = reverse_duplicate.native().unwrap(); - assert_eq!(env.val, 100); + assert_eq!(*env.val.borrow(), 100); let result = reverse_duplicate_native.call(1, 3, 5.0, 7.0)?; assert_eq!(result, (28.0, 15.0, 6, 1)); - assert_eq!(env.val, 101); + assert_eq!(*env.val.borrow(), 101); Ok(()) } diff --git a/tests/compilers/imports.rs b/tests/compilers/imports.rs index 669d224c6..d15462f68 100644 --- a/tests/compilers/imports.rs +++ b/tests/compilers/imports.rs @@ -82,27 +82,27 @@ fn dynamic_function_with_env() -> Result<()> { let store = get_store(); let module = get_module(&store)?; - let mut env: AtomicUsize = AtomicUsize::new(0); + let env: AtomicUsize = AtomicUsize::new(0); Instance::new( &module, &imports! { "host" => { - "0" => Function::new_dynamic_env(&store, &FunctionType::new(vec![], vec![]), &mut env, |env, _values| { + "0" => Function::new_dynamic_env(&store, &FunctionType::new(vec![], vec![]), &env, |env, _values| { assert_eq!(env.fetch_add(1, SeqCst), 0); Ok(vec![]) }), - "1" => Function::new_dynamic_env(&store, &FunctionType::new(vec![ValType::I32], vec![ValType::I32]), &mut env, |env, values| { + "1" => Function::new_dynamic_env(&store, &FunctionType::new(vec![ValType::I32], vec![ValType::I32]), &env, |env, values| { assert_eq!(values[0], Value::I32(0)); assert_eq!(env.fetch_add(1, SeqCst), 1); Ok(vec![Value::I32(1)]) }), - "2" => Function::new_dynamic_env(&store, &FunctionType::new(vec![ValType::I32, ValType::I64], vec![]), &mut env, |env, values| { + "2" => Function::new_dynamic_env(&store, &FunctionType::new(vec![ValType::I32, ValType::I64], vec![]), &env, |env, values| { assert_eq!(values[0], Value::I32(2)); assert_eq!(values[1], Value::I64(3)); assert_eq!(env.fetch_add(1, SeqCst), 2); Ok(vec![]) }), - "3" => Function::new_dynamic_env(&store, &FunctionType::new(vec![ValType::I32, ValType::I64, ValType::I32, ValType::F32, ValType::F64], vec![]), &mut env, |env, values| { + "3" => Function::new_dynamic_env(&store, &FunctionType::new(vec![ValType::I32, ValType::I64, ValType::I32, ValType::F32, ValType::F64], vec![]), &env, |env, values| { assert_eq!(values[0], Value::I32(100)); assert_eq!(values[1], Value::I64(200)); assert_eq!(values[2], Value::I32(300));