2017-06-13 12:01:59 +03:00
|
|
|
use std::collections::HashMap;
|
2017-12-01 20:06:43 +03:00
|
|
|
use std::iter::repeat;
|
2017-04-21 14:35:12 +03:00
|
|
|
use std::sync::{Arc, Weak};
|
2017-06-16 12:23:49 +03:00
|
|
|
use std::fmt;
|
2017-12-01 20:06:43 +03:00
|
|
|
use elements::{Module, InitExpr, Opcode, Type, FunctionType, Internal, External, ResizableLimits, Local, ValueType, BlockType};
|
2017-11-25 22:55:45 +03:00
|
|
|
use interpreter::Error;
|
2017-11-27 16:22:00 +03:00
|
|
|
use interpreter::native::UserFunctionDescriptor;
|
2017-04-21 14:35:12 +03:00
|
|
|
use interpreter::memory::MemoryInstance;
|
2017-12-11 13:59:54 +01:00
|
|
|
use interpreter::runner::{FunctionContext, prepare_function_args};
|
2017-04-21 14:35:12 +03:00
|
|
|
use interpreter::table::TableInstance;
|
2017-05-31 18:43:09 +02:00
|
|
|
use interpreter::value::{RuntimeValue, TryInto};
|
2017-04-26 15:41:22 +03:00
|
|
|
use interpreter::variable::{VariableInstance, VariableType};
|
2017-12-01 15:35:01 +03:00
|
|
|
use common::stack::StackWithLimit;
|
2017-12-11 13:59:54 +01:00
|
|
|
use interpreter::store::FuncId;
|
2017-04-21 14:35:12 +03:00
|
|
|
|
2017-06-07 14:48:02 +03:00
|
|
|
/// Maximum number of entries in value stack.
|
|
|
|
const DEFAULT_VALUE_STACK_LIMIT: usize = 16384;
|
|
|
|
/// Maximum number of entries in frame stack.
|
2017-06-16 12:23:49 +03:00
|
|
|
const DEFAULT_FRAME_STACK_LIMIT: usize = 1024;
|
2017-06-07 14:48:02 +03:00
|
|
|
|
2017-05-18 15:08:55 +03:00
|
|
|
/// Execution context.
|
2017-12-11 18:38:09 +01:00
|
|
|
pub struct ExecutionParams<'a, St: 'static> {
|
2017-12-11 16:38:52 +01:00
|
|
|
/// State that can be used by host functions,
|
2017-12-11 18:38:09 +01:00
|
|
|
pub state: &'a mut St,
|
2017-05-18 15:08:55 +03:00
|
|
|
}
|
|
|
|
|
2017-06-13 12:01:59 +03:00
|
|
|
/// Export type.
|
|
|
|
#[derive(Debug, Clone)]
|
2017-06-26 11:54:17 +03:00
|
|
|
pub enum ExportEntryType<'a> {
|
2017-06-13 12:01:59 +03:00
|
|
|
/// Any type.
|
|
|
|
Any,
|
|
|
|
/// Type of function.
|
2017-06-26 11:54:17 +03:00
|
|
|
Function(FunctionSignature<'a>),
|
2017-06-13 12:01:59 +03:00
|
|
|
/// Type of global.
|
|
|
|
Global(VariableType),
|
|
|
|
}
|
|
|
|
|
2017-06-26 11:54:17 +03:00
|
|
|
/// Function signature.
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum FunctionSignature<'a> {
|
|
|
|
/// Module function reference.
|
|
|
|
Module(&'a FunctionType),
|
|
|
|
/// Native user function refrence.
|
|
|
|
User(&'a UserFunctionDescriptor),
|
|
|
|
}
|
|
|
|
|
2017-04-21 14:35:12 +03:00
|
|
|
/// Item index in items index space.
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
pub enum ItemIndex {
|
|
|
|
/// Index in index space.
|
|
|
|
IndexSpace(u32),
|
|
|
|
/// Internal item index (i.e. index of item in items section).
|
|
|
|
Internal(u32),
|
2017-05-18 15:08:55 +03:00
|
|
|
/// External module item index (i.e. index of item in the import section).
|
2017-04-21 14:35:12 +03:00
|
|
|
External(u32),
|
|
|
|
}
|
|
|
|
|
2017-04-28 13:34:58 +03:00
|
|
|
/// Caller context.
|
2017-11-25 22:55:45 +03:00
|
|
|
pub struct CallerContext<'a> {
|
2017-05-15 15:40:08 +03:00
|
|
|
/// Value stack limit
|
2017-04-28 13:34:58 +03:00
|
|
|
pub value_stack_limit: usize,
|
2017-05-15 15:40:08 +03:00
|
|
|
/// Frame stack limit
|
2017-04-28 13:34:58 +03:00
|
|
|
pub frame_stack_limit: usize,
|
2017-05-15 15:40:08 +03:00
|
|
|
/// Stack of the input parameters
|
2017-11-25 22:55:45 +03:00
|
|
|
pub value_stack: &'a mut StackWithLimit<RuntimeValue>,
|
2017-05-18 15:08:55 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:23:49 +03:00
|
|
|
/// Internal function ready for interpretation.
|
|
|
|
pub struct InternalFunction<'a> {
|
|
|
|
/// Function locals.
|
|
|
|
pub locals: &'a [Local],
|
|
|
|
/// Function body.
|
|
|
|
pub body: &'a [Opcode],
|
2017-06-22 17:52:05 +03:00
|
|
|
/// Function labels.
|
|
|
|
pub labels: &'a HashMap<usize, usize>,
|
2017-06-16 12:23:49 +03:00
|
|
|
}
|
|
|
|
|
2017-12-11 18:38:09 +01:00
|
|
|
impl<'a, St> ExecutionParams<'a, St> {
|
2017-05-19 09:36:50 +03:00
|
|
|
/// Add argument.
|
|
|
|
pub fn add_argument(mut self, arg: RuntimeValue) -> Self {
|
|
|
|
self
|
|
|
|
}
|
2017-05-18 15:08:55 +03:00
|
|
|
}
|
|
|
|
|
2017-11-25 22:55:45 +03:00
|
|
|
impl<'a> CallerContext<'a> {
|
2017-05-15 15:40:08 +03:00
|
|
|
/// Top most args
|
2017-12-11 15:01:38 +01:00
|
|
|
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue>) -> Self {
|
2017-04-28 13:34:58 +03:00
|
|
|
CallerContext {
|
2017-06-07 14:48:02 +03:00
|
|
|
value_stack_limit: DEFAULT_VALUE_STACK_LIMIT,
|
|
|
|
frame_stack_limit: DEFAULT_FRAME_STACK_LIMIT,
|
2017-04-28 13:34:58 +03:00
|
|
|
value_stack: args,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-15 15:40:08 +03:00
|
|
|
/// Nested context
|
2017-11-25 22:55:45 +03:00
|
|
|
pub fn nested(outer: &'a mut FunctionContext) -> Self {
|
2017-04-28 13:34:58 +03:00
|
|
|
CallerContext {
|
|
|
|
value_stack_limit: outer.value_stack().limit() - outer.value_stack().len(),
|
|
|
|
frame_stack_limit: outer.frame_stack().limit() - outer.frame_stack().len(),
|
2017-05-18 15:08:55 +03:00
|
|
|
value_stack: &mut outer.value_stack,
|
2017-04-28 13:34:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-25 22:55:45 +03:00
|
|
|
pub fn check_limits(limits: &ResizableLimits) -> Result<(), Error> {
|
2017-06-08 10:49:32 +03:00
|
|
|
if let Some(maximum) = limits.maximum() {
|
|
|
|
if maximum < limits.initial() {
|
2017-12-01 15:36:43 +03:00
|
|
|
return Err(Error::Validation(format!("maximum limit {} is lesser than minimum {}", maximum, limits.initial())));
|
2017-06-08 10:49:32 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2017-06-26 11:54:17 +03:00
|
|
|
impl<'a> FunctionSignature<'a> {
|
2017-06-28 11:03:01 +03:00
|
|
|
/// Get return type of this function.
|
2017-06-26 11:54:17 +03:00
|
|
|
pub fn return_type(&self) -> Option<ValueType> {
|
|
|
|
match self {
|
|
|
|
&FunctionSignature::Module(ft) => ft.return_type(),
|
|
|
|
&FunctionSignature::User(fd) => fd.return_type(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-28 11:03:01 +03:00
|
|
|
/// Get parameters of this function.
|
2017-06-26 11:54:17 +03:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|