Move out func

This commit is contained in:
Sergey Pepyakin
2017-12-13 18:28:34 +01:00
parent 075ed7d369
commit 11e2683069
8 changed files with 121 additions and 110 deletions

106
src/interpreter/func.rs Normal file
View File

@ -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<FunctionType>,
module: Rc<ModuleInstance>,
body: Rc<FuncBody>,
},
Host {
func_type: Rc<FunctionType>,
host_func: Rc<AnyFunc>,
},
}
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<FunctionType> {
match *self {
FuncInstance::Internal { ref func_type, .. } |
FuncInstance::Host { ref func_type, .. } => Rc::clone(func_type),
}
}
pub fn body(&self) -> Option<Rc<FuncBody>> {
match *self {
FuncInstance::Internal { ref body, .. } => Some(Rc::clone(body)),
FuncInstance::Host { .. } => None,
}
}
}
impl FuncInstance {
pub fn invoke<St: 'static>(
func: Rc<FuncInstance>,
args: Vec<RuntimeValue>,
state: &mut St,
) -> Result<Option<RuntimeValue>, Error> {
enum InvokeKind {
Internal(FunctionContext),
Host(Rc<AnyFunc>, Vec<RuntimeValue>),
}
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<Local>,
pub opcodes: Opcodes,
pub labels: HashMap<usize, usize>,
}

View File

@ -3,7 +3,8 @@ use std::rc::Rc;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::collections::HashMap; use std::collections::HashMap;
use elements::{FunctionType, ValueType, GlobalType, MemoryType, TableType}; 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::global::GlobalInstance;
use interpreter::memory::MemoryInstance; use interpreter::memory::MemoryInstance;
use interpreter::table::TableInstance; use interpreter::table::TableInstance;

View File

@ -1,7 +1,7 @@
use std::rc::Rc; use std::rc::Rc;
use std::collections::HashMap; use std::collections::HashMap;
use elements::{FunctionType, GlobalType, MemoryType, TableType}; use elements::{FunctionType, GlobalType, MemoryType, TableType};
use interpreter::store::FuncInstance; use interpreter::func::FuncInstance;
use interpreter::global::GlobalInstance; use interpreter::global::GlobalInstance;
use interpreter::memory::MemoryInstance; use interpreter::memory::MemoryInstance;
use interpreter::table::TableInstance; use interpreter::table::TableInstance;

View File

@ -141,6 +141,7 @@ mod store;
mod host; mod host;
mod imports; mod imports;
mod global; mod global;
mod func;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
@ -152,5 +153,6 @@ pub use self::program::ProgramInstance;
pub use self::value::RuntimeValue; pub use self::value::RuntimeValue;
pub use self::host::{HostModule, HostModuleBuilder, Func1, AnyFunc, AsReturnVal, FromArg}; pub use self::host::{HostModule, HostModuleBuilder, Func1, AnyFunc, AsReturnVal, FromArg};
pub use self::imports::{ImportResolver, Imports}; 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::global::GlobalInstance;
pub use self::func::FuncInstance;

View File

@ -2,7 +2,8 @@ use std::rc::Rc;
use std::collections::HashMap; use std::collections::HashMap;
use elements::Module; use elements::Module;
use interpreter::Error; use interpreter::Error;
use interpreter::store::{FuncInstance, ModuleInstance}; use interpreter::store::{ModuleInstance};
use interpreter::func::FuncInstance;
use interpreter::host::HostModule; use interpreter::host::HostModule;
use interpreter::value::RuntimeValue; use interpreter::value::RuntimeValue;
use interpreter::imports::{Imports, ImportResolver}; use interpreter::imports::{Imports, ImportResolver};

View File

@ -7,7 +7,8 @@ use std::iter::repeat;
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use elements::{Opcode, BlockType, Local, FunctionType}; use elements::{Opcode, BlockType, Local, FunctionType};
use interpreter::Error; use interpreter::Error;
use interpreter::store::{FuncInstance, ModuleInstance}; use interpreter::store::ModuleInstance;
use interpreter::func::FuncInstance;
use interpreter::value::{ use interpreter::value::{
RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto, RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto,
ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto, ArithmeticOps, Integer, Float, LittleEndianConvert, TransmuteInto,

View File

@ -1,19 +1,14 @@
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
use std::any::Any;
use std::fmt;
use std::collections::HashMap; use std::collections::HashMap;
use elements::{External, FunctionType, GlobalType, InitExpr, Internal, Local, MemoryType, Module, use elements::{External, FunctionType, GlobalType, InitExpr, Internal, MemoryType, Module,
Opcode, Opcodes, ResizableLimits, TableType, Type}; Opcode, ResizableLimits, TableType, Type};
use interpreter::{Error, MemoryInstance, RuntimeValue, TableInstance}; 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::imports::{ImportResolver, Imports};
use interpreter::global::GlobalInstance; use interpreter::global::GlobalInstance;
use interpreter::func::{FuncInstance, FuncBody};
use validation::validate_module; use validation::validate_module;
use common::{DEFAULT_FRAME_STACK_LIMIT, DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX, use common::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX};
DEFAULT_VALUE_STACK_LIMIT};
use common::stack::StackWithLimit;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum ExternVal { pub enum ExternVal {
@ -53,101 +48,6 @@ impl ExternVal {
} }
} }
#[derive(Clone)]
pub enum FuncInstance {
Internal {
func_type: Rc<FunctionType>,
module: Rc<ModuleInstance>,
body: Rc<FuncBody>,
},
Host {
func_type: Rc<FunctionType>,
host_func: Rc<AnyFunc>,
},
}
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<FunctionType> {
match *self {
FuncInstance::Internal { ref func_type, .. } |
FuncInstance::Host { ref func_type, .. } => Rc::clone(func_type),
}
}
pub fn body(&self) -> Option<Rc<FuncBody>> {
match *self {
FuncInstance::Internal { ref body, .. } => Some(Rc::clone(body)),
FuncInstance::Host { .. } => None,
}
}
}
impl FuncInstance {
pub fn invoke<St: 'static>(
func: Rc<FuncInstance>,
args: Vec<RuntimeValue>,
state: &mut St,
) -> Result<Option<RuntimeValue>, Error> {
enum InvokeKind {
Internal(FunctionContext),
Host(Rc<AnyFunc>, Vec<RuntimeValue>),
}
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<Local>,
pub opcodes: Opcodes,
pub labels: HashMap<usize, usize>,
}
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct ModuleInstance { pub struct ModuleInstance {
types: RefCell<Vec<Rc<FunctionType>>>, types: RefCell<Vec<Rc<FunctionType>>>,

View File

@ -5,7 +5,7 @@ use parking_lot::RwLock;
use elements::{TableType, ResizableLimits}; use elements::{TableType, ResizableLimits};
use interpreter::Error; use interpreter::Error;
use interpreter::module::check_limits; use interpreter::module::check_limits;
use interpreter::store::FuncInstance; use interpreter::func::FuncInstance;
/// Table instance. /// Table instance.
pub struct TableInstance { pub struct TableInstance {