152 lines
4.2 KiB
Rust
Raw Normal View History

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)
}
}