From e5838d8ccba00a75b944d772afa2d11b5823b2db Mon Sep 17 00:00:00 2001 From: Syrus Date: Sat, 13 Jun 2020 15:52:42 -0700 Subject: [PATCH] Added full support for dynamic functions with env --- lib/api/src/native.rs | 30 +++++++++++++----------- tests/compilers/functions.rs | 44 ++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/lib/api/src/native.rs b/lib/api/src/native.rs index 61750d93c..b7bfa62b5 100644 --- a/lib/api/src/native.rs +++ b/lib/api/src/native.rs @@ -10,7 +10,8 @@ use std::marker::PhantomData; use crate::externals::function::{ - FunctionDefinition, VMDynamicFunction, VMDynamicFunctionWithoutEnv, WasmFunctionDefinition, + FunctionDefinition, VMDynamicFunction, VMDynamicFunctionWithEnv, VMDynamicFunctionWithoutEnv, + WasmFunctionDefinition, }; use crate::{Function, FunctionType, RuntimeError, Store}; use wasm_common::{NativeWasmType, WasmExternType, WasmTypeList}; @@ -177,20 +178,23 @@ macro_rules! impl_native_traits { } } else { // Is a dynamic function - if !self.has_env { + let params_list = [ $( $x.to_native().to_value() ),* ]; + let results = if !self.has_env { let ctx = self.vmctx as *mut VMDynamicFunctionContext; - let params_list = [ $( $x.to_native().to_value() ),* ]; - let results = unsafe { (*ctx).ctx.call(¶ms_list)? }; - let mut rets_list_array = Rets::empty_array(); - let mut_rets = rets_list_array.as_mut() as *mut [i128] as *mut i128; - for (i, ret) in results.iter().enumerate() { - unsafe { - ret.write_value_to(mut_rets.add(i)); - } - } - return Ok(Rets::from_array(rets_list_array)); + unsafe { (*ctx).ctx.call(¶ms_list)? } } - unimplemented!("native calls to dynamic function with env not yet implemented"); + else { + let ctx = self.vmctx as *mut VMDynamicFunctionContext>; + unsafe { (*ctx).ctx.call(¶ms_list)? } + }; + let mut rets_list_array = Rets::empty_array(); + let mut_rets = rets_list_array.as_mut() as *mut [i128] as *mut i128; + for (i, ret) in results.iter().enumerate() { + unsafe { + ret.write_value_to(mut_rets.add(i)); + } + } + return Ok(Rets::from_array(rets_list_array)); } }, } diff --git a/tests/compilers/functions.rs b/tests/compilers/functions.rs index f8daaf06a..6c47738ad 100644 --- a/tests/compilers/functions.rs +++ b/tests/compilers/functions.rs @@ -74,3 +74,47 @@ fn dynamic_raw_call_no_env() -> anyhow::Result<()> { assert_eq!(result, (28.0, 15.0, 6, 1)); Ok(()) } + +#[test] +fn dynamic_raw_call_with_env() -> anyhow::Result<()> { + let store = get_store(); + struct Env { + val: i32, + }; + let mut env = Env { val: 100 }; + let reverse_duplicate = wasmer::Function::new_dynamic_env( + &store, + &wasmer::FunctionType::new( + vec![ + wasmer::ValType::I32, + wasmer::ValType::I64, + wasmer::ValType::F32, + wasmer::ValType::F64, + ], + vec![ + wasmer::ValType::F64, + wasmer::ValType::F32, + wasmer::ValType::I64, + wasmer::ValType::I32, + ], + ), + &mut env, + |env, values| { + assert_eq!(env.val, 100); + env.val = 101; + Ok(vec![ + Value::F64(values[3].unwrap_f64() * 4.0), + Value::F32(values[2].unwrap_f32() * 3.0), + Value::I64(values[1].unwrap_i64() * 2), + Value::I32(values[0].unwrap_i32() * 1), + ]) + }, + ); + let reverse_duplicate_native: NativeFunc<(i32, i64, f32, f64), (f64, f32, i64, i32)> = + reverse_duplicate.native().unwrap(); + assert_eq!(env.val, 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); + Ok(()) +}