diff --git a/spec/src/run.rs b/spec/src/run.rs index 142bbc1..bd4c968 100644 --- a/spec/src/run.rs +++ b/spec/src/run.rs @@ -104,7 +104,7 @@ fn run_action(program: &ProgramInstance, action: &test::Action) let module = module.trim_left_matches('$'); let module = program.module(&module).expect(&format!("Expected program to have loaded module {}", module)); - module.export_entry(field.as_ref(), None, &ExportEntryType::Any) + module.export_entry(field.as_ref(), &ExportEntryType::Any) .and_then(|i| match i { elements::Internal::Global(global_index) => Ok(ItemIndex::IndexSpace(global_index)), _ => Err(InterpreterError::Global(format!("Expected to have exported global with name {}", field))), diff --git a/src/interpreter/env.rs b/src/interpreter/env.rs index b3e36ea..ec6ead8 100644 --- a/src/interpreter/env.rs +++ b/src/interpreter/env.rs @@ -104,8 +104,8 @@ impl ModuleInstanceInterface for EnvModuleInstance { self.instance.execute_export(name, params) } - fn export_entry<'a>(&self, name: &str, externals: Option<&'a HashMap>>, required_type: &ExportEntryType) -> Result { - self.instance.export_entry(name, externals, required_type) + fn export_entry<'a>(&self, name: &str, required_type: &ExportEntryType) -> Result { + self.instance.export_entry(name, required_type) } fn table(&self, index: ItemIndex) -> Result, Error> { @@ -120,11 +120,11 @@ impl ModuleInstanceInterface for EnvModuleInstance { self.instance.global(index, variable_type) } - fn function_type<'a>(&self, function_index: ItemIndex, externals: Option<&'a HashMap>>) -> Result { - self.instance.function_type(function_index, externals) + fn function_type(&self, function_index: ItemIndex) -> Result { + self.instance.function_type(function_index) } - fn function_type_by_index<'a>(&self, type_index: u32) -> Result { + fn function_type_by_index(&self, type_index: u32) -> Result { self.instance.function_type_by_index(type_index) } diff --git a/src/interpreter/env_native.rs b/src/interpreter/env_native.rs index 9c6ff7d..b4b18db 100644 --- a/src/interpreter/env_native.rs +++ b/src/interpreter/env_native.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use std::collections::HashMap; use parking_lot::RwLock; -use elements::{FunctionType, Internal, ValueType, Opcode}; +use elements::{FunctionType, Internal, ValueType}; use interpreter::Error; use interpreter::module::{ModuleInstanceInterface, ExecutionParams, ItemIndex, CallerContext, ExportEntryType, InternalFunctionReference, InternalFunction}; @@ -74,12 +74,13 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> { self.env.execute_export(name, params) } - fn export_entry<'b>(&self, name: &str, externals: Option<&'b HashMap>>, required_type: &ExportEntryType) -> Result { + fn export_entry<'b>(&self, name: &str, required_type: &ExportEntryType) -> Result { if let Some(index) = self.by_name.get(name) { + // TODO: check type return Ok(Internal::Function(NATIVE_INDEX_FUNC_MIN + *index)); } - self.env.export_entry(name, externals, required_type) + self.env.export_entry(name, required_type) } fn table(&self, index: ItemIndex) -> Result, Error> { @@ -94,14 +95,14 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> { self.env.global(index, variable_type) } - fn function_type<'b>(&self, function_index: ItemIndex, externals: Option<&'b HashMap>>) -> Result { + fn function_type(&self, function_index: ItemIndex) -> Result { let index = match function_index { ItemIndex::IndexSpace(index) | ItemIndex::Internal(index) => index, ItemIndex::External(_) => unreachable!("trying to call function, exported by native env module"), }; if index < NATIVE_INDEX_FUNC_MIN { - return self.env.function_type(function_index, externals); + return self.env.function_type(function_index); } self.functions @@ -110,8 +111,8 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> { .map(|f| FunctionType::new(f.params.clone(), f.result.clone())) } - fn function_type_by_index<'b>(&self, type_index: u32) -> Result { - self.function_type(ItemIndex::Internal(type_index), None) + fn function_type_by_index(&self, type_index: u32) -> Result { + self.function_type(ItemIndex::Internal(type_index)) } fn function_reference<'b>(&self, index: ItemIndex, externals: Option<&'b HashMap>>) -> Result, Error> { @@ -139,6 +140,6 @@ impl<'a> ModuleInstanceInterface for NativeModuleInstance<'a> { } /// Create wrapper for env module with given native user functions. -pub fn env_native_module(env: Arc, user_functions: UserFunctions) -> Result { +pub fn env_native_module<'a>(env: Arc, user_functions: UserFunctions<'a>) -> Result { NativeModuleInstance::new(env, user_functions) } diff --git a/src/interpreter/imports.rs b/src/interpreter/imports.rs index 8703333..a21774d 100644 --- a/src/interpreter/imports.rs +++ b/src/interpreter/imports.rs @@ -161,7 +161,7 @@ impl ModuleImports { fn external_export<'a>(&self, externals: Option<&'a HashMap>>, import: &ImportEntry, required_type: &ExportEntryType) -> Result<(Arc, Internal), Error> { self.module(externals, import.module()) .and_then(|m| - m.export_entry(import.field(), externals, required_type) + m.export_entry(import.field(), required_type) .map(|e| (m, e))) } } diff --git a/src/interpreter/module.rs b/src/interpreter/module.rs index 43248ec..a100a1f 100644 --- a/src/interpreter/module.rs +++ b/src/interpreter/module.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::iter::repeat; use std::sync::{Arc, Weak}; use std::fmt; -use elements::{Module, InitExpr, Opcode, Type, FunctionType, FuncBody, Internal, External, BlockType, ResizableLimits, Local}; +use elements::{Module, InitExpr, Opcode, Type, FunctionType, Internal, External, BlockType, ResizableLimits, Local}; use interpreter::Error; use interpreter::imports::ModuleImports; use interpreter::memory::MemoryInstance; @@ -48,7 +48,7 @@ pub trait ModuleInstanceInterface { /// Execute function with the given export name. fn execute_export(&self, name: &str, params: ExecutionParams) -> Result, Error>; /// Get export entry. - fn export_entry<'a>(&self, name: &str, externals: Option<&'a HashMap>>, required_type: &ExportEntryType) -> Result; + fn export_entry<'a>(&self, name: &str, required_type: &ExportEntryType) -> Result; /// Get table reference. fn table(&self, index: ItemIndex) -> Result, Error>; /// Get memory reference. @@ -56,9 +56,9 @@ pub trait ModuleInstanceInterface { /// Get global reference. fn global(&self, index: ItemIndex, variable_type: Option) -> Result, Error>; /// Get function type for given function index. - fn function_type<'a>(&self, function_index: ItemIndex, externals: Option<&'a HashMap>>) -> Result; + fn function_type(&self, function_index: ItemIndex) -> Result; /// Get function type for given function index. - fn function_type_by_index<'a>(&self, type_index: u32) -> Result; + fn function_type_by_index(&self, type_index: u32) -> Result; /// Get function reference. fn function_reference<'a>(&self, index: ItemIndex, externals: Option<&'a HashMap>>) -> Result, Error>; /// Get function indirect reference. @@ -66,7 +66,7 @@ pub trait ModuleInstanceInterface { /// Get internal function for interpretation. fn function_body<'a>(&'a self, internal_index: u32) -> Result>, Error>; /// Call function with given internal index. - fn call_internal_function<'a>(&self, outer: CallerContext, index: u32) -> Result, Error>; + fn call_internal_function(&self, outer: CallerContext, index: u32) -> Result, Error>; } /// Item index in items index space. @@ -227,19 +227,6 @@ impl ModuleInstance { }), } } - - fn check_function_type(&self, function_index: ItemIndex, required_function_type: Option<&FunctionType>, externals: Option<&HashMap>>) -> Result<(), Error> { - if let Some(ref required_function_type) = required_function_type { - let actual_function_type = self.function_type(function_index, externals)?; - if **required_function_type != actual_function_type { - return Err(Error::Function(format!("expected function with signature ({:?}) -> {:?} when got with ({:?}) -> {:?}", - required_function_type.params(), required_function_type.return_type(), - actual_function_type.params(), actual_function_type.return_type()))); - } - } - - Ok(()) - } } impl ModuleInstanceInterface for ModuleInstance { @@ -289,12 +276,12 @@ impl ModuleInstanceInterface for ModuleInstance { // get export entry in external module let external_module = self.imports.module(externals, import.module())?; - let export_entry = external_module.export_entry(import.field(), externals, &ExportEntryType::Function(import_function_type.clone()))?; + let export_entry = external_module.export_entry(import.field(), &ExportEntryType::Function(import_function_type.clone()))?; // export entry points to function in function index space // and Internal::Function points to type in type section let export_function_type = match export_entry { - Internal::Function(function_index) => external_module.function_type(ItemIndex::IndexSpace(function_index), externals)?, + Internal::Function(function_index) => external_module.function_type(ItemIndex::IndexSpace(function_index))?, _ => return Err(Error::Validation(format!("Export with name {} from module {} is not a function", import.field(), import.module()))), }; @@ -413,7 +400,7 @@ impl ModuleInstanceInterface for ModuleInstance { self.execute_index(index, params) } - fn export_entry<'a>(&self, name: &str, externals: Option<&'a HashMap>>, required_type: &ExportEntryType) -> Result { + fn export_entry<'a>(&self, name: &str, required_type: &ExportEntryType) -> Result { self.module.export_section() .ok_or(Error::Program(format!("trying to import {} from module without export section", name))) .and_then(|s| s.entries().iter() @@ -425,7 +412,7 @@ impl ModuleInstanceInterface for ModuleInstance { }, &ExportEntryType::Function(ref required_type) => match e.internal() { &Internal::Function(function_index) => - self.function_type(ItemIndex::IndexSpace(function_index), externals) + self.function_type(ItemIndex::IndexSpace(function_index)) .map(|ft| &ft == required_type) .unwrap_or(false), _ => false, @@ -474,7 +461,7 @@ impl ModuleInstanceInterface for ModuleInstance { } } - fn function_type<'a>(&self, function_index: ItemIndex, externals: Option<&'a HashMap>>) -> Result { + fn function_type(&self, function_index: ItemIndex) -> Result { 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)) @@ -490,7 +477,7 @@ impl ModuleInstanceInterface for ModuleInstance { } } - fn function_type_by_index<'a>(&self, type_index: u32) -> Result { + fn function_type_by_index(&self, type_index: u32) -> Result { 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) { @@ -512,7 +499,7 @@ impl ModuleInstanceInterface for ModuleInstance { .expect("parse_function_index has returned External(index); it is only returned when import section exists; qed") .entries().get(index as usize) .expect("parse_function_index has returned External(index); it is only returned when entry with index exists in import section exists; qed"); - let required_function_type = self.function_type(ItemIndex::External(index), externals)?; + let required_function_type = self.function_type(ItemIndex::External(index))?; let internal_function_index = self.imports.function(externals, import_entry, Some(&required_function_type))?; Ok(InternalFunctionReference { module: self.imports.module(externals, import_entry.module())?, @@ -531,7 +518,7 @@ impl ModuleInstanceInterface for ModuleInstance { let module = self.imports.module(externals, &module)?; let required_function_type = self.function_type_by_index(type_idx)?; - let actual_function_type = module.function_type(ItemIndex::IndexSpace(index), externals)?; + let actual_function_type = module.function_type(ItemIndex::IndexSpace(index))?; if required_function_type != actual_function_type { return Err(Error::Function(format!("expected indirect function with signature ({:?}) -> {:?} when got with ({:?}) -> {:?}", required_function_type.params(), required_function_type.return_type(), @@ -556,8 +543,8 @@ impl ModuleInstanceInterface for ModuleInstance { } fn call_internal_function(&self, mut outer: CallerContext, index: u32) -> Result, Error> { - let function_type = self.function_type(ItemIndex::Internal(index), None)?; - let mut args = prepare_function_args(&function_type, outer.value_stack)?; + 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 }; let inner = FunctionContext::new(function_ref, outer.externals, outer.value_stack_limit, outer.frame_stack_limit, &function_type, args); Interpreter::run_function(inner) diff --git a/src/interpreter/runner.rs b/src/interpreter/runner.rs index 610a31e..093c718 100644 --- a/src/interpreter/runner.rs +++ b/src/interpreter/runner.rs @@ -7,7 +7,7 @@ use std::iter::repeat; use std::collections::{HashMap, VecDeque}; use elements::{Opcode, BlockType, FunctionType, Local}; use interpreter::Error; -use interpreter::module::{ModuleInstance, ModuleInstanceInterface, CallerContext, ItemIndex, InternalFunctionReference}; +use interpreter::module::{ModuleInstanceInterface, CallerContext, ItemIndex, InternalFunctionReference}; use interpreter::stack::StackWithLimit; use interpreter::value::{ RuntimeValue, TryInto, WrapInto, TryTruncateInto, ExtendInto, @@ -220,8 +220,8 @@ impl Interpreter { match opcode { &Opcode::Unreachable => Interpreter::run_unreachable(context), &Opcode::Nop => Interpreter::run_nop(context), - &Opcode::Block(block_type, ref ops) => Interpreter::run_block(context, block_type, ops.elements()), - &Opcode::Loop(block_type, ref ops) => Interpreter::run_loop(context, block_type, ops.elements()), + &Opcode::Block(block_type, _) => Interpreter::run_block(context, block_type), + &Opcode::Loop(block_type, _) => Interpreter::run_loop(context, block_type), &Opcode::If(block_type, ref ops) => Interpreter::run_if(context, block_type, ops.elements()), &Opcode::Else => Interpreter::run_else(context), &Opcode::End => Interpreter::run_end(context), @@ -438,13 +438,13 @@ impl Interpreter { Ok(InstructionOutcome::RunNextInstruction) } - fn run_block<'a, 'b>(context: &'b mut FunctionContext<'a>, block_type: BlockType, body: &[Opcode]) -> Result, Error> { + fn run_block<'a, 'b>(context: &'b mut FunctionContext<'a>, block_type: BlockType) -> Result, Error> { let frame_position = context.position; context.push_frame(BlockFrameType::Block, frame_position, frame_position + 1, frame_position + 1, block_type)?; Ok(InstructionOutcome::ExecuteBlock) } - fn run_loop<'a, 'b>(context: &'b mut FunctionContext<'a>, block_type: BlockType, body: &[Opcode]) -> Result, Error> { + fn run_loop<'a, 'b>(context: &'b mut FunctionContext<'a>, block_type: BlockType) -> Result, Error> { let frame_position = context.position; context.push_frame(BlockFrameType::Loop, frame_position, frame_position, frame_position + 1, block_type)?; Ok(InstructionOutcome::ExecuteBlock) @@ -501,7 +501,7 @@ impl Interpreter { let table_func_idx: u32 = context.value_stack_mut().pop_as()?; let function_reference = context.module().function_reference_indirect(DEFAULT_TABLE_INDEX, type_idx, table_func_idx, Some(context.externals))?; let required_function_type = context.module().function_type_by_index(type_idx)?; - let actual_function_type = function_reference.module.function_type(ItemIndex::Internal(function_reference.internal_index), Some(context.externals))?; + let actual_function_type = function_reference.module.function_type(ItemIndex::Internal(function_reference.internal_index))?; if required_function_type != actual_function_type { return Err(Error::Function(format!("expected function with signature ({:?}) -> {:?} when got with ({:?}) -> {:?}", required_function_type.params(), required_function_type.return_type(), @@ -1022,7 +1022,7 @@ impl<'a> FunctionContext<'a> { } pub fn nested(&mut self, function: InternalFunctionReference<'a>) -> Result { - let function_type = function.module.function_type(ItemIndex::Internal(function.internal_index), Some(self.externals))?; + let function_type = function.module.function_type(ItemIndex::Internal(function.internal_index))?; let function_return_type = function_type.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult); let function_locals = prepare_function_args(&function_type, &mut self.value_stack)?; diff --git a/src/interpreter/stack.rs b/src/interpreter/stack.rs index 603f8d8..78d1093 100644 --- a/src/interpreter/stack.rs +++ b/src/interpreter/stack.rs @@ -46,14 +46,12 @@ impl StackWithLimit where T: Clone { self.values .back() .ok_or(Error::Stack("non-empty stack expected".into())) -.map_err(|e| { panic!("1") }) } pub fn top_mut(&mut self) -> Result<&mut T, Error> { self.values .back_mut() .ok_or(Error::Stack("non-empty stack expected".into())) -.map_err(|e| { panic!("2") }) } pub fn get(&self, index: usize) -> Result<&T, Error> { @@ -90,7 +88,6 @@ impl StackWithLimit where T: Clone { self.values .pop_back() .ok_or(Error::Stack("non-empty stack expected".into())) -.map_err(|e| { panic!("3") }) } pub fn resize(&mut self, new_size: usize, dummy: T) { diff --git a/src/interpreter/tests/wabt.rs b/src/interpreter/tests/wabt.rs index de56d04..a93f3eb 100644 --- a/src/interpreter/tests/wabt.rs +++ b/src/interpreter/tests/wabt.rs @@ -807,7 +807,7 @@ fn callindirect_2() { assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(0)].into()).unwrap().unwrap(), RuntimeValue::I32(14)); assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(1)].into()).unwrap().unwrap(), RuntimeValue::I32(6)); assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(2)].into()).unwrap_err(), - Error::Function("expected function with signature ([I32, I32]) -> Some(I32) when got with ([I32]) -> Some(I32)".into())); + Error::Function("expected indirect function with signature ([I32, I32]) -> Some(I32) when got with ([I32]) -> Some(I32)".into())); assert_eq!(module.execute_index(3, vec![RuntimeValue::I32(10), RuntimeValue::I32(4), RuntimeValue::I32(3)].into()).unwrap_err(), Error::Table("trying to read table item with index 3 when there are only 3 items".into())); }