From 429e54d9284ad36e1922576cc416783abbdbcb84 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Mon, 15 May 2017 16:15:05 +0300 Subject: [PATCH] another extension of user functions tests --- src/interpreter/env.rs | 1 + src/interpreter/mod.rs | 2 +- src/interpreter/tests/basics.rs | 47 +++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/interpreter/env.rs b/src/interpreter/env.rs index 3414355..951b022 100644 --- a/src/interpreter/env.rs +++ b/src/interpreter/env.rs @@ -77,6 +77,7 @@ pub type UserFunctionClosure = Box; /// User-defined function execution interface pub trait UserFunctionInterface { + /// Handles the user function invocation fn call(&mut self, context: CallerContext) -> Result, Error>; } diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 9067b7e..3d8fcc0 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -68,4 +68,4 @@ mod tests; pub use self::module::{ModuleInstance, ModuleInstanceInterface, ItemIndex, CallerContext}; pub use self::program::ProgramInstance; pub use self::value::RuntimeValue; -pub use self::env::{UserFunctions, UserFunction}; \ No newline at end of file +pub use self::env::{UserFunctions, UserFunction, UserFunctionInterface}; \ No newline at end of file diff --git a/src/interpreter/tests/basics.rs b/src/interpreter/tests/basics.rs index 05688d8..8fef569 100644 --- a/src/interpreter/tests/basics.rs +++ b/src/interpreter/tests/basics.rs @@ -177,3 +177,50 @@ fn with_user_functions() { assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10000)); assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10001)); } + +#[test] +fn with_user_functions_extended() { + use interpreter::{UserFunction, UserFunctions, UserFunctionInterface}; + + struct UserMAlloc { + top: i32, + } + + impl UserFunctionInterface for UserMAlloc { + fn call(&mut self, context: CallerContext) -> Result, Error> { + let prev = self.top; + self.top += context.value_stack.pop_as::()?; + Ok(Some(prev.into())) + } + } + + let module = module() + .with_import(ImportEntry::new("env".into(), "_malloc".into(), External::Function(0))) + .function() + .signature().return_type().i32().build() + .body().with_opcodes(Opcodes::new(vec![ + Opcode::I32Const(32), + Opcode::Call(0), + Opcode::End, + ])).build() + .build() + .build(); + + let mut user_functions = UserFunctions::new(); + user_functions.insert( + "_malloc".to_owned(), + UserFunction { + params: vec![ValueType::I32], + result: Some(ValueType::I32), + closure: Box::new(UserMAlloc { top: 0 }), + } + ); + + let program = ProgramInstance::with_functions(user_functions).unwrap(); + let module_instance = program.add_module("main", module).unwrap(); + + // internal function using first import + assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(0)); + assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(32)); + assert_eq!(module_instance.execute_index(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(64)); +} \ No newline at end of file