diff --git a/lib/wasm/src/module_translator.rs b/lib/wasm/src/module_translator.rs index 2715aeb394..e3395c0b9b 100644 --- a/lib/wasm/src/module_translator.rs +++ b/lib/wasm/src/module_translator.rs @@ -5,7 +5,7 @@ use sections_translator::{SectionParsingError, parse_function_signatures, parse_ parse_function_section, parse_export_section, parse_memory_section, parse_global_section, parse_table_section, parse_elements_section, parse_data_section}; -use translation_utils::{Import, FunctionIndex}; +use translation_utils::FunctionIndex; use cretonne::ir::{Function, FunctionName}; use func_translator::FuncTranslator; use std::collections::HashMap; @@ -39,7 +39,6 @@ pub fn translate_module( } ref s => panic!("modules should begin properly: {:?}", s), } - let mut globals = Vec::new(); let mut exports: HashMap = HashMap::new(); let mut next_input = ParserInput::Default; let mut function_index: FunctionIndex = 0; @@ -56,26 +55,8 @@ pub fn translate_module( next_input = ParserInput::Default; } ParserState::BeginSection { code: SectionCode::Import, .. } => { - match parse_import_section(&mut parser, runtime) { - Ok(imps) => { - for import in imps { - match import { - Import::Function { sig_index } => { - function_index += 1; - } - Import::Memory(mem) => { - runtime.declare_memory(mem); - } - Import::Global(glob) => { - runtime.declare_global(glob); - globals.push(glob); - } - Import::Table(tab) => { - runtime.declare_table(tab); - } - } - } - } + match parse_import_section(&mut parser, runtime, &mut function_index) { + Ok(()) => {} Err(SectionParsingError::WrongSectionContent(s)) => { return Err(format!("wrong content in the import section: {}", s)) } @@ -100,12 +81,8 @@ pub fn translate_module( } } ParserState::BeginSection { code: SectionCode::Memory, .. } => { - match parse_memory_section(&mut parser) { - Ok(mems) => { - for mem in mems { - runtime.declare_memory(mem); - } - } + match parse_memory_section(&mut parser, runtime) { + Ok(()) => {} Err(SectionParsingError::WrongSectionContent(s)) => { return Err(format!("wrong content in the memory section: {}", s)) } @@ -114,7 +91,7 @@ pub fn translate_module( } ParserState::BeginSection { code: SectionCode::Global, .. } => { match parse_global_section(&mut parser, runtime) { - Ok(mut globs) => globals.append(&mut globs), + Ok(()) => {} Err(SectionParsingError::WrongSectionContent(s)) => { return Err(format!("wrong content in the global section: {}", s)) } @@ -144,7 +121,7 @@ pub fn translate_module( next_input = ParserInput::Default; } ParserState::BeginSection { code: SectionCode::Element, .. } => { - match parse_elements_section(&mut parser, runtime, &globals) { + match parse_elements_section(&mut parser, runtime) { Ok(()) => (), Err(SectionParsingError::WrongSectionContent(s)) => { return Err(format!("wrong content in the element section: {}", s)) @@ -166,7 +143,7 @@ pub fn translate_module( }) } ParserState::BeginSection { code: SectionCode::Data, .. } => { - match parse_data_section(&mut parser, runtime, &globals) { + match parse_data_section(&mut parser, runtime) { Ok(()) => (), Err(SectionParsingError::WrongSectionContent(s)) => { return Err(format!("wrong content in the data section: {}", s)) @@ -204,7 +181,7 @@ pub fn translate_module( loop { match *parser.read() { ParserState::BeginSection { code: SectionCode::Data, .. } => { - match parse_data_section(&mut parser, runtime, &globals) { + match parse_data_section(&mut parser, runtime) { Ok(()) => (), Err(SectionParsingError::WrongSectionContent(s)) => { return Err(format!("wrong content in the data section: {}", s)) diff --git a/lib/wasm/src/runtime/dummy.rs b/lib/wasm/src/runtime/dummy.rs index 79921b7101..6ecbce6cd7 100644 --- a/lib/wasm/src/runtime/dummy.rs +++ b/lib/wasm/src/runtime/dummy.rs @@ -153,6 +153,11 @@ impl WasmRuntime for DummyRuntime { fn declare_global(&mut self, global: Global) { self.globals.push(global); } + + fn get_global(&self, global_index: GlobalIndex) -> &Global { + &self.globals[global_index] + } + fn declare_table(&mut self, _: Table) { //We do nothing } diff --git a/lib/wasm/src/runtime/spec.rs b/lib/wasm/src/runtime/spec.rs index 5a67980d1b..8d92dd9ed3 100644 --- a/lib/wasm/src/runtime/spec.rs +++ b/lib/wasm/src/runtime/spec.rs @@ -167,6 +167,10 @@ pub trait WasmRuntime: FuncEnvironment { /// Declares a global to the runtime. fn declare_global(&mut self, global: Global); + + /// Return the global for the given global index. + fn get_global(&self, global_index: GlobalIndex) -> &Global; + /// Declares a table to the runtime. fn declare_table(&mut self, table: Table); /// Fills a declared table with references to functions in the module. diff --git a/lib/wasm/src/sections_translator.rs b/lib/wasm/src/sections_translator.rs index ea3c0e97d7..b6feca54e4 100644 --- a/lib/wasm/src/sections_translator.rs +++ b/lib/wasm/src/sections_translator.rs @@ -7,9 +7,8 @@ //! The special case of the initialize expressions for table elements offsets or global variables //! is handled, according to the semantics of WebAssembly, to only specific expressions that are //! interpreted on the fly. -use translation_utils::{type_to_type, Import, TableIndex, FunctionIndex, GlobalIndex, - SignatureIndex, MemoryIndex, Global, GlobalInit, Table, TableElementType, - Memory}; +use translation_utils::{type_to_type, TableIndex, FunctionIndex, GlobalIndex, SignatureIndex, + MemoryIndex, Global, GlobalInit, Table, TableElementType, Memory}; use cretonne::ir::{Signature, ArgumentType, CallConv}; use cretonne; use wasmparser::{Parser, ParserState, FuncType, ImportSectionEntryType, ExternalKind, WasmDecoder, @@ -61,8 +60,8 @@ pub fn parse_function_signatures( pub fn parse_import_section( parser: &mut Parser, runtime: &mut WasmRuntime, -) -> Result, SectionParsingError> { - let mut imports = Vec::new(); + function_index: &mut FunctionIndex, +) -> Result<(), SectionParsingError> { loop { match *parser.read() { ParserState::ImportSectionEntry { @@ -71,42 +70,42 @@ pub fn parse_import_section( field, } => { runtime.declare_func_import(sig as SignatureIndex, module, field); - imports.push(Import::Function { sig_index: sig }); + *function_index += 1; } ParserState::ImportSectionEntry { ty: ImportSectionEntryType::Memory(MemoryType { limits: ref memlimits }), .. } => { - imports.push(Import::Memory(Memory { + runtime.declare_memory(Memory { pages_count: memlimits.initial as usize, maximum: memlimits.maximum.map(|x| x as usize), - })) + }); } ParserState::ImportSectionEntry { ty: ImportSectionEntryType::Global(ref ty), .. } => { - imports.push(Import::Global(Global { + runtime.declare_global(Global { ty: type_to_type(&ty.content_type).unwrap(), mutability: ty.mutable, initializer: GlobalInit::Import(), - })); + }); } ParserState::ImportSectionEntry { ty: ImportSectionEntryType::Table(ref tab), .. } => { - imports.push(Import::Table(Table { + runtime.declare_table(Table { ty: match type_to_type(&tab.element_type) { Ok(t) => TableElementType::Val(t), Err(()) => TableElementType::Func(), }, size: tab.limits.initial as usize, maximum: tab.limits.maximum.map(|x| x as usize), - })); + }); } ParserState::EndSection => break, ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), }; } - Ok(imports) + Ok(()) } /// Retrieves the correspondances between functions and signatures from the function section @@ -156,29 +155,30 @@ pub fn parse_export_section( } /// Retrieves the size and maximum fields of memories from the memory section -pub fn parse_memory_section(parser: &mut Parser) -> Result, SectionParsingError> { - let mut memories: Vec = Vec::new(); +pub fn parse_memory_section( + parser: &mut Parser, + runtime: &mut WasmRuntime, +) -> Result<(), SectionParsingError> { loop { match *parser.read() { ParserState::MemorySectionEntry(ref ty) => { - memories.push(Memory { + runtime.declare_memory(Memory { pages_count: ty.limits.initial as usize, maximum: ty.limits.maximum.map(|x| x as usize), - }) + }); } ParserState::EndSection => break, ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), }; } - Ok(memories) + Ok(()) } /// Retrieves the size and maximum fields of memories from the memory section pub fn parse_global_section( parser: &mut Parser, runtime: &mut WasmRuntime, -) -> Result, SectionParsingError> { - let mut globals = Vec::new(); +) -> Result<(), SectionParsingError> { loop { let (content_type, mutability) = match *parser.read() { ParserState::BeginGlobalSectionEntry(ref ty) => (ty.content_type, ty.mutable), @@ -218,19 +218,17 @@ pub fn parse_global_section( initializer: initializer, }; runtime.declare_global(global); - globals.push(global); match *parser.read() { ParserState::EndGlobalSectionEntry => (), ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), } } - Ok(globals) + Ok(()) } pub fn parse_data_section( parser: &mut Parser, runtime: &mut WasmRuntime, - globals: &[Global], ) -> Result<(), SectionParsingError> { loop { let memory_index = match *parser.read() { @@ -254,7 +252,7 @@ pub fn parse_data_section( } } ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => { - match globals[global_index as usize].initializer { + match runtime.get_global(global_index as GlobalIndex).initializer { GlobalInit::I32Const(value) => { if value < 0 { return Err(SectionParsingError::WrongSectionContent(String::from( @@ -332,7 +330,6 @@ pub fn parse_table_section( pub fn parse_elements_section( parser: &mut Parser, runtime: &mut WasmRuntime, - globals: &[Global], ) -> Result<(), SectionParsingError> { loop { let table_index = match *parser.read() { @@ -356,7 +353,7 @@ pub fn parse_elements_section( } } ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => { - match globals[global_index as usize].initializer { + match runtime.get_global(global_index as GlobalIndex).initializer { GlobalInit::I32Const(value) => { if value < 0 { return Err(SectionParsingError::WrongSectionContent(String::from( diff --git a/lib/wasm/src/translation_utils.rs b/lib/wasm/src/translation_utils.rs index c21b580b29..1f99287b32 100644 --- a/lib/wasm/src/translation_utils.rs +++ b/lib/wasm/src/translation_utils.rs @@ -14,15 +14,6 @@ pub type MemoryIndex = usize; /// Index of a signature (imported or defined) inside the WebAssembly module. pub type SignatureIndex = usize; -/// WebAssembly import. -#[derive(Debug, Clone, Copy)] -pub enum Import { - Function { sig_index: u32 }, - Memory(Memory), - Global(Global), - Table(Table), -} - /// WebAssembly global. #[derive(Debug, Clone, Copy)] pub struct Global {