diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index e02cdbc..b9b74d7 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -130,7 +130,6 @@ impl From for Error { } } -mod native; mod memory; mod module; mod program; @@ -146,9 +145,8 @@ mod host; mod tests; pub use self::memory::MemoryInstance; -pub use self::module::{ItemIndex, ExportEntryType, CallerContext, ExecutionParams, FunctionSignature}; +pub use self::module::{ItemIndex, ExportEntryType, ExecutionParams}; pub use self::table::TableInstance; pub use self::program::ProgramInstance; pub use self::value::RuntimeValue; pub use self::variable::{VariableInstance, VariableType, ExternalVariableValue}; -pub use self::native::{UserDefinedElements, UserFunctionExecutor, UserFunctionDescriptor}; diff --git a/src/interpreter/module.rs b/src/interpreter/module.rs index 22a6570..8390ebf 100644 --- a/src/interpreter/module.rs +++ b/src/interpreter/module.rs @@ -1,17 +1,9 @@ -use std::collections::HashMap; -use std::iter::repeat; -use std::sync::{Arc, Weak}; -use std::fmt; -use elements::{Module, InitExpr, Opcode, Type, FunctionType, Internal, External, ResizableLimits, Local, ValueType, BlockType}; +use elements::{InitExpr, Opcode, Type, FunctionType, Internal, External, ResizableLimits, Local, ValueType, BlockType}; use interpreter::Error; -use interpreter::native::UserFunctionDescriptor; -use interpreter::memory::MemoryInstance; -use interpreter::runner::{FunctionContext, prepare_function_args}; -use interpreter::table::TableInstance; -use interpreter::value::{RuntimeValue, TryInto}; -use interpreter::variable::{VariableInstance, VariableType}; +use interpreter::runner::{FunctionContext}; +use interpreter::VariableType; +use interpreter::RuntimeValue; use common::stack::StackWithLimit; -use interpreter::store::FuncId; /// Maximum number of entries in value stack. const DEFAULT_VALUE_STACK_LIMIT: usize = 16384; @@ -26,24 +18,13 @@ pub struct ExecutionParams<'a, St: 'static> { /// Export type. #[derive(Debug, Clone)] -pub enum ExportEntryType<'a> { +pub enum ExportEntryType { /// Any type. Any, - /// Type of function. - Function(FunctionSignature<'a>), /// Type of global. Global(VariableType), } -/// Function signature. -#[derive(Debug, Clone)] -pub enum FunctionSignature<'a> { - /// Module function reference. - Module(&'a FunctionType), - /// Native user function refrence. - User(&'a UserFunctionDescriptor), -} - /// Item index in items index space. #[derive(Debug, Clone, Copy)] pub enum ItemIndex { @@ -65,23 +46,6 @@ pub struct CallerContext<'a> { pub value_stack: &'a mut StackWithLimit, } -/// Internal function ready for interpretation. -pub struct InternalFunction<'a> { - /// Function locals. - pub locals: &'a [Local], - /// Function body. - pub body: &'a [Opcode], - /// Function labels. - pub labels: &'a HashMap, -} - -impl<'a, St> ExecutionParams<'a, St> { - /// Add argument. - pub fn add_argument(mut self, arg: RuntimeValue) -> Self { - self - } -} - impl<'a> CallerContext<'a> { /// Top most args pub fn topmost(args: &'a mut StackWithLimit) -> Self { @@ -111,41 +75,3 @@ pub fn check_limits(limits: &ResizableLimits) -> Result<(), Error> { Ok(()) } - -impl<'a> FunctionSignature<'a> { - /// Get return type of this function. - pub fn return_type(&self) -> Option { - match self { - &FunctionSignature::Module(ft) => ft.return_type(), - &FunctionSignature::User(fd) => fd.return_type(), - } - } - - /// Get parameters of this function. - pub fn params(&self) -> &[ValueType] { - match self { - &FunctionSignature::Module(ft) => ft.params(), - &FunctionSignature::User(fd) => fd.params(), - } - } -} - -impl<'a> PartialEq for FunctionSignature<'a> { - fn eq<'b>(&self, other: &FunctionSignature<'b>) -> bool { - match self { - &FunctionSignature::Module(ft1) => match other { - &FunctionSignature::Module(ft2) => ft1 == ft2, - &FunctionSignature::User(ft2) => ft1.params() == ft2.params() && ft1.return_type() == ft2.return_type(), - }, - &FunctionSignature::User(ft1) => match other { - &FunctionSignature::User(ft2) => ft1 == ft2, - &FunctionSignature::Module(ft2) => ft1.params() == ft2.params() && ft1.return_type() == ft2.return_type(), - }, - } - } -} -impl<'a> From<&'a FunctionType> for FunctionSignature<'a> { - fn from(other: &'a FunctionType) -> Self { - FunctionSignature::Module(other) - } -} diff --git a/src/interpreter/native.rs b/src/interpreter/native.rs deleted file mode 100644 index b21452b..0000000 --- a/src/interpreter/native.rs +++ /dev/null @@ -1,100 +0,0 @@ - -use std::sync::Arc; -use std::collections::HashMap; -use std::borrow::Cow; -use parking_lot::RwLock; -use elements::{Internal, ValueType}; -use interpreter::Error; -use interpreter::module::{ExecutionParams, ItemIndex, - CallerContext, ExportEntryType, InternalFunction, FunctionSignature}; -use interpreter::memory::MemoryInstance; -use interpreter::table::TableInstance; -use interpreter::value::RuntimeValue; -use interpreter::variable::{VariableInstance, VariableType}; - -/// Min index of native function. -pub const NATIVE_INDEX_FUNC_MIN: u32 = 10001; -/// Min index of native global. -pub const NATIVE_INDEX_GLOBAL_MIN: u32 = 20001; - -/// User functions executor. -pub trait UserFunctionExecutor { - /// Execute function with given name. - fn execute(&mut self, name: &str, context: CallerContext) -> Result, Error>; -} - -/// User function descriptor -#[derive(Debug, Clone)] -pub enum UserFunctionDescriptor { - /// Static function definition - Static(&'static str, &'static [ValueType], Option), - /// Dynamic heap function definition - Heap(String, Vec, Option), -} - -impl UserFunctionDescriptor { - /// New function with statically known params - pub fn statik(name: &'static str, params: &'static [ValueType], result: Option) -> Self { - UserFunctionDescriptor::Static(name, params, result) - } - - /// New function with statically unknown params - pub fn heap(name: String, params: Vec, result: Option) -> Self { - UserFunctionDescriptor::Heap(name, params, result) - } - - /// Name of the function - pub fn name(&self) -> &str { - match self { - &UserFunctionDescriptor::Static(name, _, _) => name, - &UserFunctionDescriptor::Heap(ref name, _, _) => name, - } - } - - /// Arguments of the function - pub fn params(&self) -> &[ValueType] { - match self { - &UserFunctionDescriptor::Static(_, params, _) => params, - &UserFunctionDescriptor::Heap(_, ref params, _) => params, - } - } - - /// Return type of the function - pub fn return_type(&self) -> Option { - match self { - &UserFunctionDescriptor::Static(_, _, result) => result, - &UserFunctionDescriptor::Heap(_, _, result) => result, - } - } -} - -/// Set of user-defined module elements. -pub struct UserDefinedElements { - /// User globals list. - pub globals: HashMap>, - /// User functions list. - pub functions: Cow<'static, [UserFunctionDescriptor]>, - /// Functions executor. - pub executor: Option, -} - -/// Native module instance. -pub struct NativeModuleInstance { - /// User function executor. - executor: RwLock>, - /// By-name functions index. - functions_by_name: HashMap, - /// User functions list. - functions: Cow<'static, [UserFunctionDescriptor]>, - /// By-name functions index. - globals_by_name: HashMap, - /// User globals list. - globals: Vec>, -} - -impl<'a> PartialEq for UserFunctionDescriptor { - fn eq(&self, other: &Self) -> bool { - self.params() == other.params() - && self.return_type() == other.return_type() - } -} diff --git a/src/interpreter/runner.rs b/src/interpreter/runner.rs index 3640fdd..7e3ca63 100644 --- a/src/interpreter/runner.rs +++ b/src/interpreter/runner.rs @@ -5,10 +5,10 @@ use std::{u32, usize}; use std::fmt::{self, Display}; use std::iter::repeat; use std::collections::{HashMap, VecDeque}; -use elements::{Opcode, BlockType, Local}; +use elements::{Opcode, BlockType, Local, FunctionType}; use interpreter::Error; use interpreter::store::{Store, FuncId, ModuleId, FuncInstance}; -use interpreter::module::{CallerContext, FunctionSignature, ExecutionParams}; +use interpreter::module::{CallerContext, ExecutionParams}; use interpreter::value::{ RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto, ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto, @@ -970,7 +970,7 @@ impl<'store, St: 'static> Interpreter<'store, St> { } impl<'a> FunctionContext { - pub fn new<'store>(store: &'store Store, function: FuncId, value_stack_limit: usize, frame_stack_limit: usize, function_type: &FunctionSignature, args: Vec) -> Self { + pub fn new<'store>(store: &'store Store, function: FuncId, value_stack_limit: usize, frame_stack_limit: usize, function_type: &FunctionType, args: Vec) -> Self { let func_instance = function.resolve(store); let module = match *func_instance { FuncInstance::Internal { module, .. } => module, @@ -996,10 +996,8 @@ impl<'a> FunctionContext { FuncInstance::Host { .. } => panic!("Host functions can't be called as internally defined functions; Thus FunctionContext can be created only with internally defined functions; qed"), }; let function_type = func_instance.func_type().resolve(store); - // TODO: function_signature - let function_signature = FunctionSignature::Module(&function_type); let function_return_type = function_type.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult); - let function_locals = prepare_function_args(&function_signature, &mut self.value_stack)?; + let function_locals = prepare_function_args(function_type, &mut self.value_stack)?; (function_locals, module, function_return_type) }; @@ -1129,7 +1127,7 @@ fn effective_address(address: u32, offset: u32) -> Result { } } -pub fn prepare_function_args(function_type: &FunctionSignature, caller_stack: &mut StackWithLimit) -> Result, Error> { +pub fn prepare_function_args(function_type: &FunctionType, caller_stack: &mut StackWithLimit) -> Result, Error> { let mut args = function_type.params().iter().rev().map(|param_type| { let param_value = caller_stack.pop()?; let actual_type = param_value.variable_type(); diff --git a/src/interpreter/store.rs b/src/interpreter/store.rs index 1f47c5f..170df48 100644 --- a/src/interpreter/store.rs +++ b/src/interpreter/store.rs @@ -6,7 +6,7 @@ use std::any::Any; use std::collections::HashMap; use elements::{FunctionType, GlobalEntry, GlobalType, InitExpr, Internal, Local, MemoryType, Module, Opcode, Opcodes, TableType, Type}; -use interpreter::{CallerContext, Error, ExecutionParams, FunctionSignature, MemoryInstance, +use interpreter::{Error, ExecutionParams, MemoryInstance, RuntimeValue, TableInstance}; use interpreter::runner::{prepare_function_args, FunctionContext, Interpreter}; use interpreter::host::AnyFunc; @@ -488,14 +488,13 @@ impl Store { let result = match *func.resolve(self) { FuncInstance::Internal { func_type, .. } => { let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT); - let outer = CallerContext::topmost(&mut args); - let func_signature = FunctionSignature::Module(func_type.resolve(self)); - let args = prepare_function_args(&func_signature, outer.value_stack)?; + let func_signature = func_type.resolve(self); + let args = prepare_function_args(&func_signature, &mut args)?; let context = FunctionContext::new( self, func, - outer.value_stack_limit, - outer.frame_stack_limit, + DEFAULT_VALUE_STACK_LIMIT, + DEFAULT_FRAME_STACK_LIMIT, &func_signature, args, );