This commit is contained in:
Mark McCaskey
2020-06-15 18:05:59 -07:00
parent 0f0a8dde34
commit 0191ffe598
3 changed files with 30 additions and 22 deletions

View File

@@ -56,7 +56,7 @@ impl Function {
F: HostFunction<Args, Rets, WithoutEnv, Env>, F: HostFunction<Args, Rets, WithoutEnv, Env>,
Args: WasmTypeList, Args: WasmTypeList,
Rets: WasmTypeList, Rets: WasmTypeList,
Env: Sized, Env: Clone + Sized,
{ {
let func: wasm_common::Func<Args, Rets> = wasm_common::Func::new(func); let func: wasm_common::Func<Args, Rets> = wasm_common::Func::new(func);
let address = func.address() as *const VMFunctionBody; let address = func.address() as *const VMFunctionBody;
@@ -106,7 +106,7 @@ impl Function {
pub fn new_dynamic_env<F, Env>(store: &Store, ty: &FunctionType, env: Env, func: F) -> Self pub fn new_dynamic_env<F, Env>(store: &Store, ty: &FunctionType, env: Env, func: F) -> Self
where where
F: Fn(&mut Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static, F: Fn(&mut Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
Env: Sized, Env: Clone + Sized,
{ {
let dynamic_ctx = VMDynamicFunctionContext::from_context(VMDynamicFunctionWithEnv { let dynamic_ctx = VMDynamicFunctionContext::from_context(VMDynamicFunctionWithEnv {
env: Cell::new(env), env: Cell::new(env),
@@ -141,7 +141,7 @@ impl Function {
F: HostFunction<Args, Rets, WithEnv, Env>, F: HostFunction<Args, Rets, WithEnv, Env>,
Args: WasmTypeList, Args: WasmTypeList,
Rets: WasmTypeList, Rets: WasmTypeList,
Env: Sized, Env: Clone + Sized,
{ {
let func: wasm_common::Func<Args, Rets> = wasm_common::Func::new(func); let func: wasm_common::Func<Args, Rets> = wasm_common::Func::new(func);
let address = func.address() as *const VMFunctionBody; let address = func.address() as *const VMFunctionBody;

View File

@@ -1,5 +1,7 @@
use crate::utils::get_store; use crate::utils::get_store;
use anyhow::Result; use anyhow::Result;
use std::cell::RefCell;
use std::rc::Rc;
use wasmer::*; use wasmer::*;
@@ -57,10 +59,13 @@ fn static_raw_call_no_env() -> anyhow::Result<()> {
#[test] #[test]
fn static_raw_call_with_env() -> anyhow::Result<()> { fn static_raw_call_with_env() -> anyhow::Result<()> {
let store = get_store(); let store = get_store();
#[derive(Clone)]
struct Env { struct Env {
val: i32, val: Rc<RefCell<i32>>,
};
let env = Env {
val: Rc::new(RefCell::new(100)),
}; };
let mut env = Env { val: 100 };
fn reverse_duplicate_host( fn reverse_duplicate_host(
env: &mut Env, env: &mut Env,
a: i32, a: i32,
@@ -68,17 +73,17 @@ fn static_raw_call_with_env() -> anyhow::Result<()> {
c: f32, c: f32,
d: f64, d: f64,
) -> (f64, f32, i64, i32) { ) -> (f64, f32, i64, i32) {
assert_eq!(env.val, 100); assert_eq!(*env.val.borrow(), 100);
env.val = 101; env.val.replace(101);
(d * 4.0, c * 3.0, b * 2, a * 1) (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)> = let reverse_duplicate_native: NativeFunc<(i32, i64, f32, f64), (f64, f32, i64, i32)> =
reverse_duplicate.native().unwrap(); 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)?; let result = reverse_duplicate_native.call(1, 3, 5.0, 7.0)?;
assert_eq!(result, (28.0, 15.0, 6, 1)); assert_eq!(result, (28.0, 15.0, 6, 1));
assert_eq!(env.val, 101); assert_eq!(*env.val.borrow(), 101);
Ok(()) Ok(())
} }
@@ -120,10 +125,13 @@ fn dynamic_raw_call_no_env() -> anyhow::Result<()> {
#[test] #[test]
fn dynamic_raw_call_with_env() -> anyhow::Result<()> { fn dynamic_raw_call_with_env() -> anyhow::Result<()> {
let store = get_store(); let store = get_store();
#[derive(Clone)]
struct Env { struct Env {
val: i32, val: Rc<RefCell<i32>>,
};
let env = Env {
val: Rc::new(RefCell::new(100)),
}; };
let mut env = Env { val: 100 };
let reverse_duplicate = wasmer::Function::new_dynamic_env( let reverse_duplicate = wasmer::Function::new_dynamic_env(
&store, &store,
&wasmer::FunctionType::new( &wasmer::FunctionType::new(
@@ -140,10 +148,10 @@ fn dynamic_raw_call_with_env() -> anyhow::Result<()> {
wasmer::ValType::I32, wasmer::ValType::I32,
], ],
), ),
&mut env, env.clone(),
|env, values| { |env, values| {
assert_eq!(env.val, 100); assert_eq!(*env.val.borrow(), 100);
env.val = 101; env.val.replace(101);
Ok(vec![ Ok(vec![
Value::F64(values[3].unwrap_f64() * 4.0), Value::F64(values[3].unwrap_f64() * 4.0),
Value::F32(values[2].unwrap_f32() * 3.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)> = let reverse_duplicate_native: NativeFunc<(i32, i64, f32, f64), (f64, f32, i64, i32)> =
reverse_duplicate.native().unwrap(); 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)?; let result = reverse_duplicate_native.call(1, 3, 5.0, 7.0)?;
assert_eq!(result, (28.0, 15.0, 6, 1)); assert_eq!(result, (28.0, 15.0, 6, 1));
assert_eq!(env.val, 101); assert_eq!(*env.val.borrow(), 101);
Ok(()) Ok(())
} }

View File

@@ -82,27 +82,27 @@ fn dynamic_function_with_env() -> Result<()> {
let store = get_store(); let store = get_store();
let module = get_module(&store)?; let module = get_module(&store)?;
let mut env: AtomicUsize = AtomicUsize::new(0); let env: AtomicUsize = AtomicUsize::new(0);
Instance::new( Instance::new(
&module, &module,
&imports! { &imports! {
"host" => { "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); assert_eq!(env.fetch_add(1, SeqCst), 0);
Ok(vec![]) 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!(values[0], Value::I32(0));
assert_eq!(env.fetch_add(1, SeqCst), 1); assert_eq!(env.fetch_add(1, SeqCst), 1);
Ok(vec![Value::I32(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[0], Value::I32(2));
assert_eq!(values[1], Value::I64(3)); assert_eq!(values[1], Value::I64(3));
assert_eq!(env.fetch_add(1, SeqCst), 2); assert_eq!(env.fetch_add(1, SeqCst), 2);
Ok(vec![]) 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[0], Value::I32(100));
assert_eq!(values[1], Value::I64(200)); assert_eq!(values[1], Value::I64(200));
assert_eq!(values[2], Value::I32(300)); assert_eq!(values[2], Value::I32(300));