diff --git a/src/interpreter/func.rs b/src/interpreter/func.rs new file mode 100644 index 0000000..1b098d8 --- /dev/null +++ b/src/interpreter/func.rs @@ -0,0 +1,106 @@ +use std::rc::Rc; +use std::fmt; +use std::collections::HashMap; +use std::any::Any; +use elements::{FunctionType, Opcodes, Local}; +use interpreter::{Error, ModuleInstance}; +use interpreter::runner::{prepare_function_args, FunctionContext, Interpreter}; +use interpreter::host::AnyFunc; +use interpreter::value::RuntimeValue; +use common::stack::StackWithLimit; +use common::{DEFAULT_FRAME_STACK_LIMIT, DEFAULT_VALUE_STACK_LIMIT}; + +#[derive(Clone)] +pub enum FuncInstance { + Internal { + func_type: Rc, + module: Rc, + body: Rc, + }, + Host { + func_type: Rc, + host_func: Rc, + }, +} + +impl fmt::Debug for FuncInstance { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + &FuncInstance::Internal { + ref func_type, + ref module, + .. + } => write!( + f, + "Internal {{ type={:?}, module={:?} }}", + func_type, + module + ), + &FuncInstance::Host { ref func_type, .. } => { + write!(f, "Host {{ type={:?} }}", func_type) + } + } + } +} + +impl FuncInstance { + pub fn func_type(&self) -> Rc { + match *self { + FuncInstance::Internal { ref func_type, .. } | + FuncInstance::Host { ref func_type, .. } => Rc::clone(func_type), + } + } + + pub fn body(&self) -> Option> { + match *self { + FuncInstance::Internal { ref body, .. } => Some(Rc::clone(body)), + FuncInstance::Host { .. } => None, + } + } +} + +impl FuncInstance { + pub fn invoke( + func: Rc, + args: Vec, + state: &mut St, + ) -> Result, Error> { + enum InvokeKind { + Internal(FunctionContext), + Host(Rc, Vec), + } + + let result = match *func { + FuncInstance::Internal { ref func_type, .. } => { + let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT); + let args = prepare_function_args(func_type, &mut args)?; + let context = FunctionContext::new( + Rc::clone(&func), + DEFAULT_VALUE_STACK_LIMIT, + DEFAULT_FRAME_STACK_LIMIT, + func_type, + args, + ); + InvokeKind::Internal(context) + } + FuncInstance::Host { ref host_func, .. } => { + InvokeKind::Host(Rc::clone(host_func), args) + } + }; + + match result { + InvokeKind::Internal(ctx) => { + let mut interpreter = Interpreter::new(state); + interpreter.run_function(ctx) + } + InvokeKind::Host(host_func, args) => host_func.call_as_any(state as &mut Any, &args), + } + } +} + +#[derive(Clone, Debug)] +pub struct FuncBody { + pub locals: Vec, + pub opcodes: Opcodes, + pub labels: HashMap, +} diff --git a/src/interpreter/host.rs b/src/interpreter/host.rs index 0c1add7..49539fc 100644 --- a/src/interpreter/host.rs +++ b/src/interpreter/host.rs @@ -3,7 +3,8 @@ use std::rc::Rc; use std::marker::PhantomData; use std::collections::HashMap; use elements::{FunctionType, ValueType, GlobalType, MemoryType, TableType}; -use interpreter::store::{ExternVal, ModuleInstance, FuncInstance}; +use interpreter::store::{ExternVal, ModuleInstance}; +use interpreter::func::FuncInstance; use interpreter::global::GlobalInstance; use interpreter::memory::MemoryInstance; use interpreter::table::TableInstance; diff --git a/src/interpreter/imports.rs b/src/interpreter/imports.rs index 70e3c1d..1f94688 100644 --- a/src/interpreter/imports.rs +++ b/src/interpreter/imports.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use std::collections::HashMap; use elements::{FunctionType, GlobalType, MemoryType, TableType}; -use interpreter::store::FuncInstance; +use interpreter::func::FuncInstance; use interpreter::global::GlobalInstance; use interpreter::memory::MemoryInstance; use interpreter::table::TableInstance; diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index ffafe4b..00f528f 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -141,6 +141,7 @@ mod store; mod host; mod imports; mod global; +mod func; #[cfg(test)] mod tests; @@ -152,5 +153,6 @@ pub use self::program::ProgramInstance; pub use self::value::RuntimeValue; pub use self::host::{HostModule, HostModuleBuilder, Func1, AnyFunc, AsReturnVal, FromArg}; pub use self::imports::{ImportResolver, Imports}; -pub use self::store::{FuncInstance, ModuleInstance}; +pub use self::store::{ModuleInstance}; pub use self::global::GlobalInstance; +pub use self::func::FuncInstance; diff --git a/src/interpreter/program.rs b/src/interpreter/program.rs index 9d37104..7e46aec 100644 --- a/src/interpreter/program.rs +++ b/src/interpreter/program.rs @@ -2,7 +2,8 @@ use std::rc::Rc; use std::collections::HashMap; use elements::Module; use interpreter::Error; -use interpreter::store::{FuncInstance, ModuleInstance}; +use interpreter::store::{ModuleInstance}; +use interpreter::func::FuncInstance; use interpreter::host::HostModule; use interpreter::value::RuntimeValue; use interpreter::imports::{Imports, ImportResolver}; diff --git a/src/interpreter/runner.rs b/src/interpreter/runner.rs index 77552b1..4c13908 100644 --- a/src/interpreter/runner.rs +++ b/src/interpreter/runner.rs @@ -7,7 +7,8 @@ use std::iter::repeat; use std::collections::{HashMap, VecDeque}; use elements::{Opcode, BlockType, Local, FunctionType}; use interpreter::Error; -use interpreter::store::{FuncInstance, ModuleInstance}; +use interpreter::store::ModuleInstance; +use interpreter::func::FuncInstance; use interpreter::value::{ RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto, ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto, diff --git a/src/interpreter/store.rs b/src/interpreter/store.rs index 931d3e2..fa3d26d 100644 --- a/src/interpreter/store.rs +++ b/src/interpreter/store.rs @@ -1,19 +1,14 @@ use std::rc::Rc; use std::cell::RefCell; -use std::any::Any; -use std::fmt; use std::collections::HashMap; -use elements::{External, FunctionType, GlobalType, InitExpr, Internal, Local, MemoryType, Module, - Opcode, Opcodes, ResizableLimits, TableType, Type}; +use elements::{External, FunctionType, GlobalType, InitExpr, Internal, MemoryType, Module, + Opcode, ResizableLimits, TableType, Type}; use interpreter::{Error, MemoryInstance, RuntimeValue, TableInstance}; -use interpreter::runner::{prepare_function_args, FunctionContext, Interpreter}; -use interpreter::host::AnyFunc; use interpreter::imports::{ImportResolver, Imports}; use interpreter::global::GlobalInstance; +use interpreter::func::{FuncInstance, FuncBody}; use validation::validate_module; -use common::{DEFAULT_FRAME_STACK_LIMIT, DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX, - DEFAULT_VALUE_STACK_LIMIT}; -use common::stack::StackWithLimit; +use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX}; #[derive(Clone, Debug)] pub enum ExternVal { @@ -53,101 +48,6 @@ impl ExternVal { } } -#[derive(Clone)] -pub enum FuncInstance { - Internal { - func_type: Rc, - module: Rc, - body: Rc, - }, - Host { - func_type: Rc, - host_func: Rc, - }, -} - -impl fmt::Debug for FuncInstance { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - &FuncInstance::Internal { - ref func_type, - ref module, - .. - } => write!( - f, - "Internal {{ type={:?}, module={:?} }}", - func_type, - module - ), - &FuncInstance::Host { ref func_type, .. } => { - write!(f, "Host {{ type={:?} }}", func_type) - } - } - } -} - -impl FuncInstance { - pub fn func_type(&self) -> Rc { - match *self { - FuncInstance::Internal { ref func_type, .. } | - FuncInstance::Host { ref func_type, .. } => Rc::clone(func_type), - } - } - - pub fn body(&self) -> Option> { - match *self { - FuncInstance::Internal { ref body, .. } => Some(Rc::clone(body)), - FuncInstance::Host { .. } => None, - } - } -} - -impl FuncInstance { - pub fn invoke( - func: Rc, - args: Vec, - state: &mut St, - ) -> Result, Error> { - enum InvokeKind { - Internal(FunctionContext), - Host(Rc, Vec), - } - - let result = match *func { - FuncInstance::Internal { ref func_type, .. } => { - let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT); - let args = prepare_function_args(func_type, &mut args)?; - let context = FunctionContext::new( - Rc::clone(&func), - DEFAULT_VALUE_STACK_LIMIT, - DEFAULT_FRAME_STACK_LIMIT, - func_type, - args, - ); - InvokeKind::Internal(context) - } - FuncInstance::Host { ref host_func, .. } => { - InvokeKind::Host(Rc::clone(host_func), args) - } - }; - - match result { - InvokeKind::Internal(ctx) => { - let mut interpreter = Interpreter::new(state); - interpreter.run_function(ctx) - } - InvokeKind::Host(host_func, args) => host_func.call_as_any(state as &mut Any, &args), - } - } -} - -#[derive(Clone, Debug)] -pub struct FuncBody { - pub locals: Vec, - pub opcodes: Opcodes, - pub labels: HashMap, -} - #[derive(Default, Debug)] pub struct ModuleInstance { types: RefCell>>, diff --git a/src/interpreter/table.rs b/src/interpreter/table.rs index 03b3609..2ac3180 100644 --- a/src/interpreter/table.rs +++ b/src/interpreter/table.rs @@ -5,7 +5,7 @@ use parking_lot::RwLock; use elements::{TableType, ResizableLimits}; use interpreter::Error; use interpreter::module::check_limits; -use interpreter::store::FuncInstance; +use interpreter::func::FuncInstance; /// Table instance. pub struct TableInstance {