merge 2 error enums

This commit is contained in:
Svyatoslav Nikolsky
2017-08-01 14:44:33 +03:00
parent a02fdf5836
commit 9437b7bdfc
20 changed files with 457 additions and 475 deletions

View File

@ -3,7 +3,7 @@ use std::iter::repeat;
use std::sync::{Arc, Weak};
use std::fmt;
use elements::{Module, InitExpr, Opcode, Type, FunctionType, Internal, External, BlockType, ResizableLimits, Local, ValueType};
use interpreter::{Error, CustomUserError, InterpreterError};
use interpreter::{Error, CustomUserError};
use interpreter::env_native::UserFunctionDescriptor;
use interpreter::imports::ModuleImports;
use interpreter::memory::MemoryInstance;
@ -52,29 +52,29 @@ pub enum FunctionSignature<'a> {
/// Module instance API.
pub trait ModuleInstanceInterface<E: CustomUserError> {
/// Execute function with the given index.
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, InterpreterError<E>>;
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>>;
/// Execute function with the given export name.
fn execute_export(&self, name: &str, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, InterpreterError<E>>;
fn execute_export(&self, name: &str, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>>;
/// Get export entry.
fn export_entry<'a>(&self, name: &str, required_type: &ExportEntryType) -> Result<Internal, Error>;
fn export_entry<'a>(&self, name: &str, required_type: &ExportEntryType) -> Result<Internal, Error<E>>;
/// Get table reference.
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error>;
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance<E>>, Error<E>>;
/// Get memory reference.
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance>, Error>;
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance<E>>, Error<E>>;
/// Get global reference.
fn global<'a>(&self, index: ItemIndex, variable_type: Option<VariableType>, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<Arc<VariableInstance>, Error>;
fn global<'a>(&self, index: ItemIndex, variable_type: Option<VariableType>, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<Arc<VariableInstance<E>>, Error<E>>;
/// Get function type for given function index.
fn function_type(&self, function_index: ItemIndex) -> Result<FunctionSignature, Error>;
fn function_type(&self, function_index: ItemIndex) -> Result<FunctionSignature, Error<E>>;
/// Get function type for given function index.
fn function_type_by_index(&self, type_index: u32) -> Result<FunctionSignature, Error>;
fn function_type_by_index(&self, type_index: u32) -> Result<FunctionSignature, Error<E>>;
/// Get function reference.
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<InternalFunctionReference<'a, E>, Error>;
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<InternalFunctionReference<'a, E>, Error<E>>;
/// Get function indirect reference.
fn function_reference_indirect<'a>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<InternalFunctionReference<'a, E>, Error>;
fn function_reference_indirect<'a>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<InternalFunctionReference<'a, E>, Error<E>>;
/// Get internal function for interpretation.
fn function_body<'a>(&'a self, internal_index: u32) -> Result<Option<InternalFunction<'a>>, Error>;
fn function_body<'a>(&'a self, internal_index: u32) -> Result<Option<InternalFunction<'a>>, Error<E>>;
/// Call function with given internal index.
fn call_internal_function(&self, outer: CallerContext<E>, index: u32) -> Result<Option<RuntimeValue>, InterpreterError<E>>;
fn call_internal_function(&self, outer: CallerContext<E>, index: u32) -> Result<Option<RuntimeValue>, Error<E>>;
}
/// Item index in items index space.
@ -101,11 +101,11 @@ pub struct ModuleInstance<E: CustomUserError> {
/// Module exports.
exports: HashMap<String, Vec<Internal>>,
/// Tables.
tables: Vec<Arc<TableInstance>>,
tables: Vec<Arc<TableInstance<E>>>,
/// Linear memory regions.
memory: Vec<Arc<MemoryInstance>>,
memory: Vec<Arc<MemoryInstance<E>>>,
/// Globals.
globals: Vec<Arc<VariableInstance>>,
globals: Vec<Arc<VariableInstance<E>>>,
}
/// Caller context.
@ -115,7 +115,7 @@ pub struct CallerContext<'a, E: 'a + CustomUserError> {
/// Frame stack limit
pub frame_stack_limit: usize,
/// Stack of the input parameters
pub value_stack: &'a mut StackWithLimit<RuntimeValue>,
pub value_stack: &'a mut StackWithLimit<RuntimeValue, E>,
/// Execution-local external modules.
pub externals: &'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>,
}
@ -183,7 +183,7 @@ impl<'a, E> From<Vec<RuntimeValue>> for ExecutionParams<'a, E> where E: CustomUs
impl<E> ModuleInstance<E> where E: CustomUserError {
/// Instantiate given module within program context.
pub fn new<'a>(program: Weak<ProgramInstanceEssence<E>>, name: String, module: Module) -> Result<Self, Error> {
pub fn new<'a>(program: Weak<ProgramInstanceEssence<E>>, name: String, module: Module) -> Result<Self, Error<E>> {
// load entries from import section
let imports = ModuleImports::new(program, module.import_section());
@ -231,7 +231,7 @@ impl<E> ModuleInstance<E> where E: CustomUserError {
}
/// Run instantiation-time procedures (validation). Module is not completely validated until this call.
pub fn instantiate<'a>(&mut self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<(), Error> {
pub fn instantiate<'a>(&mut self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<(), Error<E>> {
// validate start section
if let Some(start_function) = self.module.start_section() {
let func_type_index = self.require_function(ItemIndex::IndexSpace(start_function))?;
@ -397,7 +397,7 @@ impl<E> ModuleInstance<E> where E: CustomUserError {
}
/// Run start function [if any].
pub fn run_start_function(&self) -> Result<(), InterpreterError<E>> {
pub fn run_start_function(&self) -> Result<(), Error<E>> {
// execute start function (if any)
if let Some(start_function) = self.module.start_section() {
self.execute_index(start_function, ExecutionParams::default())?;
@ -405,11 +405,11 @@ impl<E> ModuleInstance<E> where E: CustomUserError {
Ok(())
}
fn self_ref<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<Arc<ModuleInstanceInterface<E> + 'a>, Error> {
fn self_ref<'a>(&self, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<Arc<ModuleInstanceInterface<E> + 'a>, Error<E>> {
self.imports.module(externals, &self.name)
}
fn require_function(&self, index: ItemIndex) -> Result<u32, Error> {
fn require_function(&self, index: ItemIndex) -> Result<u32, Error<E>> {
match self.imports.parse_function_index(index) {
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
ItemIndex::Internal(index) => self.module.function_section()
@ -430,7 +430,7 @@ impl<E> ModuleInstance<E> where E: CustomUserError {
}
impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserError {
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, InterpreterError<E>> {
fn execute_index(&self, index: u32, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>> {
let ExecutionParams { args, externals } = params;
let mut args = StackWithLimit::with_data(args, DEFAULT_VALUE_STACK_LIMIT);
let function_reference = self.function_reference(ItemIndex::IndexSpace(index), Some(&externals))?;
@ -438,7 +438,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
function_reference.module.call_internal_function(function_context, function_reference.internal_index)
}
fn execute_export(&self, name: &str, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, InterpreterError<E>> {
fn execute_export(&self, name: &str, params: ExecutionParams<E>) -> Result<Option<RuntimeValue>, Error<E>> {
let index = self.exports.get(name)
.ok_or(Error::Function(format!("missing executable export with name {}", name)))
.and_then(|l| l.iter()
@ -455,7 +455,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
self.execute_index(index, params)
}
fn export_entry<'a>(&self, name: &str, required_type: &ExportEntryType) -> Result<Internal, Error> {
fn export_entry<'a>(&self, name: &str, required_type: &ExportEntryType) -> Result<Internal, Error<E>> {
self.exports.get(name)
.ok_or(Error::Function(format!("missing export entry with name {}", name)))
.and_then(|l| l.iter()
@ -477,7 +477,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
.ok_or(Error::Program(format!("unresolved import {}", name))))
}
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance>, Error> {
fn table(&self, index: ItemIndex) -> Result<Arc<TableInstance<E>>, Error<E>> {
match self.imports.parse_table_index(index) {
ItemIndex::IndexSpace(_) => unreachable!("parse_table_index resolves IndexSpace option"),
ItemIndex::Internal(index) => self.tables.get(index as usize).cloned()
@ -490,7 +490,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
}
}
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance>, Error> {
fn memory(&self, index: ItemIndex) -> Result<Arc<MemoryInstance<E>>, Error<E>> {
match self.imports.parse_memory_index(index) {
ItemIndex::IndexSpace(_) => unreachable!("parse_memory_index resolves IndexSpace option"),
ItemIndex::Internal(index) => self.memory.get(index as usize).cloned()
@ -503,7 +503,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
}
}
fn global<'a>(&self, index: ItemIndex, variable_type: Option<VariableType>, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<Arc<VariableInstance>, Error> {
fn global<'a>(&self, index: ItemIndex, variable_type: Option<VariableType>, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<Arc<VariableInstance<E>>, Error<E>> {
match self.imports.parse_global_index(index) {
ItemIndex::IndexSpace(_) => unreachable!("parse_global_index resolves IndexSpace option"),
ItemIndex::Internal(index) => self.globals.get(index as usize).cloned()
@ -516,7 +516,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
}
}
fn function_type(&self, function_index: ItemIndex) -> Result<FunctionSignature, Error> {
fn function_type(&self, function_index: ItemIndex) -> Result<FunctionSignature, Error<E>> {
match self.imports.parse_function_index(function_index) {
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
ItemIndex::Internal(index) => self.require_function(ItemIndex::Internal(index))
@ -532,7 +532,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
}
}
fn function_type_by_index(&self, type_index: u32) -> Result<FunctionSignature, Error> {
fn function_type_by_index(&self, type_index: u32) -> Result<FunctionSignature, Error<E>> {
self.module.type_section()
.ok_or(Error::Validation(format!("type reference {} exists in module without type section", type_index)))
.and_then(|s| match s.types().get(type_index as usize) {
@ -542,7 +542,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
.map(FunctionSignature::Module)
}
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<InternalFunctionReference<'a, E>, Error> {
fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<InternalFunctionReference<'a, E>, Error<E>> {
match self.imports.parse_function_index(index) {
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
ItemIndex::Internal(index) => Ok(InternalFunctionReference {
@ -564,7 +564,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
}
}
fn function_reference_indirect<'a>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<InternalFunctionReference<'a, E>, Error> {
fn function_reference_indirect<'a>(&self, table_idx: u32, type_idx: u32, func_idx: u32, externals: Option<&'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>>) -> Result<InternalFunctionReference<'a, E>, Error<E>> {
let table = self.table(ItemIndex::IndexSpace(table_idx))?;
let (module, index) = match table.get(func_idx)? {
RuntimeValue::AnyFunc(module, index) => (module.clone(), index),
@ -583,7 +583,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
module.function_reference(ItemIndex::IndexSpace(index), externals)
}
fn function_body<'a>(&'a self, internal_index: u32) -> Result<Option<InternalFunction<'a>>, Error> {
fn function_body<'a>(&'a self, internal_index: u32) -> Result<Option<InternalFunction<'a>>, Error<E>> {
let function_body = self.module
.code_section()
.ok_or(Error::Function(format!("trying to call function with index {} in module without code section", internal_index)))
@ -600,7 +600,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
}))
}
fn call_internal_function(&self, mut outer: CallerContext<E>, index: u32) -> Result<Option<RuntimeValue>, InterpreterError<E>> {
fn call_internal_function(&self, mut outer: CallerContext<E>, index: u32) -> Result<Option<RuntimeValue>, Error<E>> {
let function_type = self.function_type(ItemIndex::Internal(index))?;
let args = prepare_function_args(&function_type, outer.value_stack)?;
let function_ref = InternalFunctionReference { module: self.self_ref(Some(outer.externals))?, internal_index: index };
@ -611,7 +611,7 @@ impl<E> ModuleInstanceInterface<E> for ModuleInstance<E> where E: CustomUserErro
impl<'a, E> CallerContext<'a, E> where E: CustomUserError {
/// Top most args
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>) -> Self {
pub fn topmost(args: &'a mut StackWithLimit<RuntimeValue, E>, externals: &'a HashMap<String, Arc<ModuleInstanceInterface<E> + 'a>>) -> Self {
CallerContext {
value_stack_limit: DEFAULT_VALUE_STACK_LIMIT,
frame_stack_limit: DEFAULT_FRAME_STACK_LIMIT,
@ -631,7 +631,7 @@ impl<'a, E> CallerContext<'a, E> where E: CustomUserError {
}
}
pub fn check_limits(limits: &ResizableLimits) -> Result<(), Error> {
pub fn check_limits<E: CustomUserError>(limits: &ResizableLimits) -> Result<(), Error<E>> {
if let Some(maximum) = limits.maximum() {
if maximum < limits.initial() {
return Err(Error::Validation(format!("maximum limit {} is lesser than minimum {}", maximum, limits.initial())));
@ -641,7 +641,7 @@ pub fn check_limits(limits: &ResizableLimits) -> Result<(), Error> {
Ok(())
}
fn get_initializer<E: CustomUserError>(expr: &InitExpr, module: &Module, imports: &ModuleImports<E>, expected_type: VariableType) -> Result<RuntimeValue, Error> {
fn get_initializer<E: CustomUserError>(expr: &InitExpr, module: &Module, imports: &ModuleImports<E>, expected_type: VariableType) -> Result<RuntimeValue, Error<E>> {
let first_opcode = match expr.code().len() {
1 => &expr.code()[0],
2 if expr.code().len() == 2 && expr.code()[1] == Opcode::End => &expr.code()[0],