Move start_index out of TranslationResult and into the WasmRuntime.

This makes it more consistent with how all the rest of the content of
a wasm module is handled. And, now TranslationResult just has a Vec
of translated functions, which will make it easier to refactor further.
This commit is contained in:
Dan Gohman
2017-10-09 08:37:04 -07:00
parent ef5ad630c8
commit e74bc06380
4 changed files with 39 additions and 29 deletions

View File

@@ -2,9 +2,9 @@
//! to deal with each part of it. //! to deal with each part of it.
use wasmparser::{ParserState, SectionCode, ParserInput, Parser, WasmDecoder, BinaryReaderError}; use wasmparser::{ParserState, SectionCode, ParserInput, Parser, WasmDecoder, BinaryReaderError};
use sections_translator::{SectionParsingError, parse_function_signatures, parse_import_section, use sections_translator::{SectionParsingError, parse_function_signatures, parse_import_section,
parse_function_section, parse_export_section, parse_memory_section, parse_function_section, parse_export_section, parse_start_section,
parse_global_section, parse_table_section, parse_elements_section, parse_memory_section, parse_global_section, parse_table_section,
parse_data_section}; parse_elements_section, parse_data_section};
use translation_utils::FunctionIndex; use translation_utils::FunctionIndex;
use cretonne::ir::{Function, FunctionName}; use cretonne::ir::{Function, FunctionName};
use func_translator::FuncTranslator; use func_translator::FuncTranslator;
@@ -16,11 +16,6 @@ use runtime::WasmRuntime;
pub struct TranslationResult { pub struct TranslationResult {
/// The translated functions. /// The translated functions.
pub functions: Vec<Function>, pub functions: Vec<Function>,
/// When present, the index of the function defined as `start` of the module.
///
/// Note that this is a WebAssembly function index and not an index into the `functions` vector
/// above. The imported functions are numbered before the local functions.
pub start_index: Option<FunctionIndex>,
} }
/// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cretonne IL /// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cretonne IL
@@ -42,7 +37,6 @@ pub fn translate_module(
let mut exports: HashMap<FunctionIndex, String> = HashMap::new(); let mut exports: HashMap<FunctionIndex, String> = HashMap::new();
let mut next_input = ParserInput::Default; let mut next_input = ParserInput::Default;
let mut function_index: FunctionIndex = 0; let mut function_index: FunctionIndex = 0;
let mut start_index: Option<FunctionIndex> = None;
loop { loop {
match *parser.read_with_input(next_input) { match *parser.read_with_input(next_input) {
ParserState::BeginSection { code: SectionCode::Type, .. } => { ParserState::BeginSection { code: SectionCode::Type, .. } => {
@@ -108,15 +102,11 @@ pub fn translate_module(
next_input = ParserInput::Default; next_input = ParserInput::Default;
} }
ParserState::BeginSection { code: SectionCode::Start, .. } => { ParserState::BeginSection { code: SectionCode::Start, .. } => {
match *parser.read() { match parse_start_section(&mut parser, runtime) {
ParserState::StartSectionEntry(index) => { Ok(()) => (),
start_index = Some(index as FunctionIndex) Err(SectionParsingError::WrongSectionContent(s)) => {
return Err(format!("wrong content in the start section: {}", s))
} }
_ => return Err(String::from("wrong content in the start section")),
}
match *parser.read() {
ParserState::EndSection => {}
_ => return Err(String::from("wrong content in the start section")),
} }
next_input = ParserInput::Default; next_input = ParserInput::Default;
} }
@@ -136,12 +126,7 @@ pub fn translate_module(
ParserState::EndSection => { ParserState::EndSection => {
next_input = ParserInput::Default; next_input = ParserInput::Default;
} }
ParserState::EndWasm => { ParserState::EndWasm => return Ok(TranslationResult { functions: Vec::new() }),
return Ok(TranslationResult {
functions: Vec::new(),
start_index: None,
})
}
ParserState::BeginSection { code: SectionCode::Data, .. } => { ParserState::BeginSection { code: SectionCode::Data, .. } => {
match parse_data_section(&mut parser, runtime) { match parse_data_section(&mut parser, runtime) {
Ok(()) => (), Ok(()) => (),
@@ -188,12 +173,7 @@ pub fn translate_module(
} }
} }
} }
ParserState::EndWasm => { ParserState::EndWasm => return Ok(TranslationResult { functions: il_functions }),
return Ok(TranslationResult {
functions: il_functions,
start_index,
})
}
_ => (), _ => (),
} }
} }

View File

@@ -22,6 +22,9 @@ pub struct DummyRuntime {
// Compilation setting flags. // Compilation setting flags.
flags: settings::Flags, flags: settings::Flags,
// The start function.
start_func: Option<FunctionIndex>,
} }
impl DummyRuntime { impl DummyRuntime {
@@ -38,6 +41,7 @@ impl DummyRuntime {
func_types: Vec::new(), func_types: Vec::new(),
imported_funcs: Vec::new(), imported_funcs: Vec::new(),
flags, flags,
start_func: None,
} }
} }
} }
@@ -177,6 +181,11 @@ impl WasmRuntime for DummyRuntime {
Ok(()) Ok(())
} }
fn declare_start_func(&mut self, func_index: FunctionIndex) {
debug_assert!(self.start_func.is_none());
self.start_func = Some(func_index);
}
fn begin_translation(&mut self) { fn begin_translation(&mut self) {
// We do nothing // We do nothing
} }

View File

@@ -189,6 +189,10 @@ pub trait WasmRuntime: FuncEnvironment {
offset: usize, offset: usize,
data: &[u8], data: &[u8],
) -> Result<(), String>; ) -> Result<(), String>;
/// Declares a start function.
fn declare_start_func(&mut self, index: FunctionIndex);
/// Call this function after having declared all the runtime elements but prior to the /// Call this function after having declared all the runtime elements but prior to the
/// function body translation. /// function body translation.
fn begin_translation(&mut self); fn begin_translation(&mut self);

View File

@@ -154,6 +154,23 @@ pub fn parse_export_section(
Ok(exports) Ok(exports)
} }
/// Retrieves the start function index from the start section
pub fn parse_start_section(
parser: &mut Parser,
runtime: &mut WasmRuntime,
) -> Result<(), SectionParsingError> {
loop {
match *parser.read() {
ParserState::StartSectionEntry(index) => {
runtime.declare_start_func(index as FunctionIndex);
}
ParserState::EndSection => break,
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
};
}
Ok(())
}
/// Retrieves the size and maximum fields of memories from the memory section /// Retrieves the size and maximum fields of memories from the memory section
pub fn parse_memory_section( pub fn parse_memory_section(
parser: &mut Parser, parser: &mut Parser,