From 8e1ba080c0203b955c354e19eb2b35af83519633 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 10 Oct 2017 09:35:10 -0700 Subject: [PATCH] Complete support for global init expressions. --- lib/wasm/src/runtime/dummy.rs | 5 +- lib/wasm/src/runtime/spec.rs | 4 +- lib/wasm/src/sections_translator.rs | 73 ++++++++--------------------- 3 files changed, 25 insertions(+), 57 deletions(-) diff --git a/lib/wasm/src/runtime/dummy.rs b/lib/wasm/src/runtime/dummy.rs index 09a985a087..4ebbdd39d3 100644 --- a/lib/wasm/src/runtime/dummy.rs +++ b/lib/wasm/src/runtime/dummy.rs @@ -197,6 +197,7 @@ impl WasmRuntime for DummyRuntime { fn declare_table_elements( &mut self, _table_index: TableIndex, + _base: Option, _offset: usize, _elements: &[FunctionIndex], ) { @@ -208,11 +209,11 @@ impl WasmRuntime for DummyRuntime { fn declare_data_initialization( &mut self, _memory_index: MemoryIndex, + _base: Option, _offset: usize, _data: &[u8], - ) -> Result<(), String> { + ) { // We do nothing - Ok(()) } fn declare_func_export(&mut self, func_index: FunctionIndex, name: &str) { diff --git a/lib/wasm/src/runtime/spec.rs b/lib/wasm/src/runtime/spec.rs index 0eb74de809..dc51a20d8e 100644 --- a/lib/wasm/src/runtime/spec.rs +++ b/lib/wasm/src/runtime/spec.rs @@ -183,6 +183,7 @@ pub trait WasmRuntime: FuncEnvironment { fn declare_table_elements( &mut self, table_index: TableIndex, + base: Option, offset: usize, elements: &[FunctionIndex], ); @@ -192,9 +193,10 @@ pub trait WasmRuntime: FuncEnvironment { fn declare_data_initialization( &mut self, memory_index: MemoryIndex, + base: Option, offset: usize, data: &[u8], - ) -> Result<(), String>; + ); /// Declares a function export to the runtime. fn declare_func_export(&mut self, func_index: FunctionIndex, name: &str); diff --git a/lib/wasm/src/sections_translator.rs b/lib/wasm/src/sections_translator.rs index a63bad8e05..5641312440 100644 --- a/lib/wasm/src/sections_translator.rs +++ b/lib/wasm/src/sections_translator.rs @@ -101,7 +101,7 @@ pub fn parse_import_section( }, 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))), @@ -227,7 +227,6 @@ pub fn parse_global_section( GlobalInit::GlobalRef(global_index as GlobalIndex) } ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), - }; match *parser.read() { ParserState::EndInitExpressionBody => (), @@ -261,35 +260,14 @@ pub fn parse_data_section( ParserState::BeginInitExpressionBody => (), ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), }; - let mut offset = match *parser.read() { + let (base, offset) = match *parser.read() { ParserState::InitExpressionOperator(Operator::I32Const { value }) => { - if value < 0 { - return Err(SectionParsingError::WrongSectionContent(String::from( - "negative \ - offset value", - ))); - } else { - value as usize - } + (None, value as u32 as usize) } ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => { match runtime.get_global(global_index as GlobalIndex).initializer { - GlobalInit::I32Const(value) => { - if value < 0 { - return Err(SectionParsingError::WrongSectionContent(String::from( - "\ - negative offset value", - ))); - } else { - value as usize - } - } - GlobalInit::Import() => { - return Err(SectionParsingError::WrongSectionContent(String::from( - "\ - imported globals not supported", - ))) - } // TODO: add runtime support + GlobalInit::I32Const(value) => (None, value as u32 as usize), + GlobalInit::Import() => (Some(global_index as GlobalIndex), 0), _ => panic!("should not happen"), } } @@ -303,17 +281,20 @@ pub fn parse_data_section( ParserState::BeginDataSectionEntryBody(_) => (), ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), }; + let mut running_offset = offset; loop { let data = match *parser.read() { ParserState::DataSectionEntryBodyChunk(data) => data, ParserState::EndDataSectionEntryBody => break, ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), }; - match runtime.declare_data_initialization(memory_index as MemoryIndex, offset, data) { - Ok(()) => (), - Err(s) => return Err(SectionParsingError::WrongSectionContent(s)), - }; - offset += data.len(); + runtime.declare_data_initialization( + memory_index as MemoryIndex, + base, + running_offset, + data, + ); + running_offset += data.len(); } match *parser.read() { ParserState::EndDataSectionEntry => (), @@ -354,7 +335,7 @@ pub fn parse_elements_section( ) -> Result<(), SectionParsingError> { loop { let table_index = match *parser.read() { - ParserState::BeginElementSectionEntry(ref table_index) => *table_index as TableIndex, + ParserState::BeginElementSectionEntry(table_index) => table_index as TableIndex, ParserState::EndSection => break, ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), }; @@ -362,30 +343,14 @@ pub fn parse_elements_section( ParserState::BeginInitExpressionBody => (), ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), }; - let offset = match *parser.read() { + let (base, offset) = match *parser.read() { ParserState::InitExpressionOperator(Operator::I32Const { value }) => { - if value < 0 { - return Err(SectionParsingError::WrongSectionContent(String::from( - "negative \ - offset value", - ))); - } else { - value as usize - } + (None, value as u32 as usize) } ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => { match runtime.get_global(global_index as GlobalIndex).initializer { - GlobalInit::I32Const(value) => { - if value < 0 { - return Err(SectionParsingError::WrongSectionContent(String::from( - "\ - negative offset value", - ))); - } else { - value as usize - } - } - GlobalInit::Import() => 0, // TODO: add runtime support + GlobalInit::I32Const(value) => (None, value as u32 as usize), + GlobalInit::Import() => (Some(global_index as GlobalIndex), 0), _ => panic!("should not happen"), } } @@ -399,7 +364,7 @@ pub fn parse_elements_section( ParserState::ElementSectionEntryBody(ref elements) => { let elems: Vec = elements.iter().map(|&x| x as FunctionIndex).collect(); - runtime.declare_table_elements(table_index, offset, &elems) + runtime.declare_table_elements(table_index, base, offset, &elems) } ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), };