module reference in user functions closures

This commit is contained in:
NikVolf 2017-05-15 19:03:49 +03:00
parent 429e54d928
commit fa86543fbb
2 changed files with 10 additions and 10 deletions

View File

@ -78,12 +78,12 @@ pub type UserFunctionClosure = Box<UserFunctionInterface>;
/// User-defined function execution interface /// User-defined function execution interface
pub trait UserFunctionInterface { pub trait UserFunctionInterface {
/// Handles the user function invocation /// Handles the user function invocation
fn call(&mut self, context: CallerContext) -> Result<Option<RuntimeValue>, Error>; fn call(&mut self, module: &ModuleInstance, context: CallerContext) -> Result<Option<RuntimeValue>, Error>;
} }
impl<T> UserFunctionInterface for T where T: FnMut(CallerContext) -> Result<Option<RuntimeValue>, Error> { impl<T> UserFunctionInterface for T where T: FnMut(&ModuleInstance, CallerContext) -> Result<Option<RuntimeValue>, Error> {
fn call(&mut self, context: CallerContext) -> Result<Option<RuntimeValue>, Error> { fn call(&mut self, module: &ModuleInstance, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
(&mut *self)(context) (&mut *self)(module, context)
} }
} }
@ -187,7 +187,7 @@ impl ModuleInstanceInterface for EnvModuleInstance {
// user-defined function // user-defined function
let user_index = idx - (INDEX_FUNC_MAX+1); let user_index = idx - (INDEX_FUNC_MAX+1);
let func = self.user_functions.get(user_index as usize).ok_or(Error::Trap(format!("Trying to invoke user-defined function {}", user_index)))?; let func = self.user_functions.get(user_index as usize).ok_or(Error::Trap(format!("Trying to invoke user-defined function {}", user_index)))?;
func.borrow_mut().call(outer) func.borrow_mut().call(&self.instance, outer)
}, },
// idx @ _ if idx == INDEX_FUNC_MAX + 1 => outer.value_stack.pop().map(|_| None), // TODO: `gas(i32) -> None` function // idx @ _ if idx == INDEX_FUNC_MAX + 1 => outer.value_stack.pop().map(|_| None), // TODO: `gas(i32) -> None` function
// idx @ _ if idx == INDEX_FUNC_MAX + 2 => Ok(Some(RuntimeValue::I32(0))), // TODO: `_storage_size() -> i32` function // idx @ _ if idx == INDEX_FUNC_MAX + 2 => Ok(Some(RuntimeValue::I32(0))), // TODO: `_storage_size() -> i32` function

View File

@ -122,7 +122,7 @@ fn global_get_set() {
#[test] #[test]
fn with_user_functions() { fn with_user_functions() {
use interpreter::{UserFunction, UserFunctions}; use interpreter::{UserFunction, UserFunctions, ModuleInstance};
let module = module() let module = module()
.with_import(ImportEntry::new("env".into(), "custom_alloc".into(), External::Function(0))) .with_import(ImportEntry::new("env".into(), "custom_alloc".into(), External::Function(0)))
@ -144,7 +144,7 @@ fn with_user_functions() {
UserFunction { UserFunction {
params: vec![ValueType::I32], params: vec![ValueType::I32],
result: Some(ValueType::I32), result: Some(ValueType::I32),
closure: Box::new(move |context: CallerContext| { closure: Box::new(move |_module: &ModuleInstance, context: CallerContext| {
let prev = top; let prev = top;
top = top + context.value_stack.pop_as::<i32>()?; top = top + context.value_stack.pop_as::<i32>()?;
Ok(Some(prev.into())) Ok(Some(prev.into()))
@ -158,7 +158,7 @@ fn with_user_functions() {
UserFunction { UserFunction {
params: vec![ValueType::I32], params: vec![ValueType::I32],
result: Some(ValueType::I32), result: Some(ValueType::I32),
closure: Box::new(move |_: CallerContext| { closure: Box::new(move |_module: &ModuleInstance, _context: CallerContext| {
rolling = rolling + 1; rolling = rolling + 1;
Ok(Some(rolling.into())) Ok(Some(rolling.into()))
}), }),
@ -180,14 +180,14 @@ fn with_user_functions() {
#[test] #[test]
fn with_user_functions_extended() { fn with_user_functions_extended() {
use interpreter::{UserFunction, UserFunctions, UserFunctionInterface}; use interpreter::{UserFunction, UserFunctions, UserFunctionInterface, ModuleInstance};
struct UserMAlloc { struct UserMAlloc {
top: i32, top: i32,
} }
impl UserFunctionInterface for UserMAlloc { impl UserFunctionInterface for UserMAlloc {
fn call(&mut self, context: CallerContext) -> Result<Option<RuntimeValue>, Error> { fn call(&mut self, _module: &ModuleInstance, context: CallerContext) -> Result<Option<RuntimeValue>, Error> {
let prev = self.top; let prev = self.top;
self.top += context.value_stack.pop_as::<i32>()?; self.top += context.value_stack.pop_as::<i32>()?;
Ok(Some(prev.into())) Ok(Some(prev.into()))