mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-21 10:41:54 +00:00
Clean module stuff
This commit is contained in:
@ -130,7 +130,6 @@ impl From<common::stack::Error> 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};
|
||||
|
@ -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<RuntimeValue>,
|
||||
}
|
||||
|
||||
/// 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<usize, usize>,
|
||||
}
|
||||
|
||||
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<RuntimeValue>) -> 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<ValueType> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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<Option<RuntimeValue>, Error>;
|
||||
}
|
||||
|
||||
/// User function descriptor
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum UserFunctionDescriptor {
|
||||
/// Static function definition
|
||||
Static(&'static str, &'static [ValueType], Option<ValueType>),
|
||||
/// Dynamic heap function definition
|
||||
Heap(String, Vec<ValueType>, Option<ValueType>),
|
||||
}
|
||||
|
||||
impl UserFunctionDescriptor {
|
||||
/// New function with statically known params
|
||||
pub fn statik(name: &'static str, params: &'static [ValueType], result: Option<ValueType>) -> Self {
|
||||
UserFunctionDescriptor::Static(name, params, result)
|
||||
}
|
||||
|
||||
/// New function with statically unknown params
|
||||
pub fn heap(name: String, params: Vec<ValueType>, result: Option<ValueType>) -> 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<ValueType> {
|
||||
match self {
|
||||
&UserFunctionDescriptor::Static(_, _, result) => result,
|
||||
&UserFunctionDescriptor::Heap(_, _, result) => result,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Set of user-defined module elements.
|
||||
pub struct UserDefinedElements<E: UserFunctionExecutor> {
|
||||
/// User globals list.
|
||||
pub globals: HashMap<String, Arc<VariableInstance>>,
|
||||
/// User functions list.
|
||||
pub functions: Cow<'static, [UserFunctionDescriptor]>,
|
||||
/// Functions executor.
|
||||
pub executor: Option<E>,
|
||||
}
|
||||
|
||||
/// Native module instance.
|
||||
pub struct NativeModuleInstance<E: UserFunctionExecutor> {
|
||||
/// User function executor.
|
||||
executor: RwLock<Option<E>>,
|
||||
/// By-name functions index.
|
||||
functions_by_name: HashMap<String, u32>,
|
||||
/// User functions list.
|
||||
functions: Cow<'static, [UserFunctionDescriptor]>,
|
||||
/// By-name functions index.
|
||||
globals_by_name: HashMap<String, u32>,
|
||||
/// User globals list.
|
||||
globals: Vec<Arc<VariableInstance>>,
|
||||
}
|
||||
|
||||
impl<'a> PartialEq for UserFunctionDescriptor {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.params() == other.params()
|
||||
&& self.return_type() == other.return_type()
|
||||
}
|
||||
}
|
@ -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<RuntimeValue>) -> Self {
|
||||
pub fn new<'store>(store: &'store Store, function: FuncId, value_stack_limit: usize, frame_stack_limit: usize, function_type: &FunctionType, args: Vec<RuntimeValue>) -> 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<u32, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prepare_function_args(function_type: &FunctionSignature, caller_stack: &mut StackWithLimit<RuntimeValue>) -> Result<Vec<RuntimeValue>, Error> {
|
||||
pub fn prepare_function_args(function_type: &FunctionType, caller_stack: &mut StackWithLimit<RuntimeValue>) -> Result<Vec<RuntimeValue>, 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();
|
||||
|
@ -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,
|
||||
);
|
||||
|
Reference in New Issue
Block a user