Use the WasmRuntime's global list rather than keeping a separate list.

This commit is contained in:
Dan Gohman
2017-10-07 08:12:07 -07:00
parent 3841552b7c
commit ef5ad630c8
5 changed files with 41 additions and 67 deletions

View File

@@ -5,7 +5,7 @@ use sections_translator::{SectionParsingError, parse_function_signatures, parse_
parse_function_section, parse_export_section, parse_memory_section, parse_function_section, parse_export_section, parse_memory_section,
parse_global_section, parse_table_section, parse_elements_section, parse_global_section, parse_table_section, parse_elements_section,
parse_data_section}; parse_data_section};
use translation_utils::{Import, FunctionIndex}; use translation_utils::FunctionIndex;
use cretonne::ir::{Function, FunctionName}; use cretonne::ir::{Function, FunctionName};
use func_translator::FuncTranslator; use func_translator::FuncTranslator;
use std::collections::HashMap; use std::collections::HashMap;
@@ -39,7 +39,6 @@ pub fn translate_module(
} }
ref s => panic!("modules should begin properly: {:?}", s), ref s => panic!("modules should begin properly: {:?}", s),
} }
let mut globals = Vec::new();
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;
@@ -56,26 +55,8 @@ pub fn translate_module(
next_input = ParserInput::Default; next_input = ParserInput::Default;
} }
ParserState::BeginSection { code: SectionCode::Import, .. } => { ParserState::BeginSection { code: SectionCode::Import, .. } => {
match parse_import_section(&mut parser, runtime) { match parse_import_section(&mut parser, runtime, &mut function_index) {
Ok(imps) => { Ok(()) => {}
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);
}
}
}
}
Err(SectionParsingError::WrongSectionContent(s)) => { Err(SectionParsingError::WrongSectionContent(s)) => {
return Err(format!("wrong content in the import section: {}", s)) return Err(format!("wrong content in the import section: {}", s))
} }
@@ -100,12 +81,8 @@ pub fn translate_module(
} }
} }
ParserState::BeginSection { code: SectionCode::Memory, .. } => { ParserState::BeginSection { code: SectionCode::Memory, .. } => {
match parse_memory_section(&mut parser) { match parse_memory_section(&mut parser, runtime) {
Ok(mems) => { Ok(()) => {}
for mem in mems {
runtime.declare_memory(mem);
}
}
Err(SectionParsingError::WrongSectionContent(s)) => { Err(SectionParsingError::WrongSectionContent(s)) => {
return Err(format!("wrong content in the memory section: {}", s)) return Err(format!("wrong content in the memory section: {}", s))
} }
@@ -114,7 +91,7 @@ pub fn translate_module(
} }
ParserState::BeginSection { code: SectionCode::Global, .. } => { ParserState::BeginSection { code: SectionCode::Global, .. } => {
match parse_global_section(&mut parser, runtime) { match parse_global_section(&mut parser, runtime) {
Ok(mut globs) => globals.append(&mut globs), Ok(()) => {}
Err(SectionParsingError::WrongSectionContent(s)) => { Err(SectionParsingError::WrongSectionContent(s)) => {
return Err(format!("wrong content in the global section: {}", s)) return Err(format!("wrong content in the global section: {}", s))
} }
@@ -144,7 +121,7 @@ pub fn translate_module(
next_input = ParserInput::Default; next_input = ParserInput::Default;
} }
ParserState::BeginSection { code: SectionCode::Element, .. } => { ParserState::BeginSection { code: SectionCode::Element, .. } => {
match parse_elements_section(&mut parser, runtime, &globals) { match parse_elements_section(&mut parser, runtime) {
Ok(()) => (), Ok(()) => (),
Err(SectionParsingError::WrongSectionContent(s)) => { Err(SectionParsingError::WrongSectionContent(s)) => {
return Err(format!("wrong content in the element section: {}", s)) return Err(format!("wrong content in the element section: {}", s))
@@ -166,7 +143,7 @@ pub fn translate_module(
}) })
} }
ParserState::BeginSection { code: SectionCode::Data, .. } => { ParserState::BeginSection { code: SectionCode::Data, .. } => {
match parse_data_section(&mut parser, runtime, &globals) { match parse_data_section(&mut parser, runtime) {
Ok(()) => (), Ok(()) => (),
Err(SectionParsingError::WrongSectionContent(s)) => { Err(SectionParsingError::WrongSectionContent(s)) => {
return Err(format!("wrong content in the data section: {}", s)) return Err(format!("wrong content in the data section: {}", s))
@@ -204,7 +181,7 @@ pub fn translate_module(
loop { loop {
match *parser.read() { match *parser.read() {
ParserState::BeginSection { code: SectionCode::Data, .. } => { ParserState::BeginSection { code: SectionCode::Data, .. } => {
match parse_data_section(&mut parser, runtime, &globals) { match parse_data_section(&mut parser, runtime) {
Ok(()) => (), Ok(()) => (),
Err(SectionParsingError::WrongSectionContent(s)) => { Err(SectionParsingError::WrongSectionContent(s)) => {
return Err(format!("wrong content in the data section: {}", s)) return Err(format!("wrong content in the data section: {}", s))

View File

@@ -153,6 +153,11 @@ impl WasmRuntime for DummyRuntime {
fn declare_global(&mut self, global: Global) { fn declare_global(&mut self, global: Global) {
self.globals.push(global); self.globals.push(global);
} }
fn get_global(&self, global_index: GlobalIndex) -> &Global {
&self.globals[global_index]
}
fn declare_table(&mut self, _: Table) { fn declare_table(&mut self, _: Table) {
//We do nothing //We do nothing
} }

View File

@@ -167,6 +167,10 @@ pub trait WasmRuntime: FuncEnvironment {
/// Declares a global to the runtime. /// Declares a global to the runtime.
fn declare_global(&mut self, global: Global); 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. /// Declares a table to the runtime.
fn declare_table(&mut self, table: Table); fn declare_table(&mut self, table: Table);
/// Fills a declared table with references to functions in the module. /// Fills a declared table with references to functions in the module.

View File

@@ -7,9 +7,8 @@
//! The special case of the initialize expressions for table elements offsets or global variables //! 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 //! is handled, according to the semantics of WebAssembly, to only specific expressions that are
//! interpreted on the fly. //! interpreted on the fly.
use translation_utils::{type_to_type, Import, TableIndex, FunctionIndex, GlobalIndex, use translation_utils::{type_to_type, TableIndex, FunctionIndex, GlobalIndex, SignatureIndex,
SignatureIndex, MemoryIndex, Global, GlobalInit, Table, TableElementType, MemoryIndex, Global, GlobalInit, Table, TableElementType, Memory};
Memory};
use cretonne::ir::{Signature, ArgumentType, CallConv}; use cretonne::ir::{Signature, ArgumentType, CallConv};
use cretonne; use cretonne;
use wasmparser::{Parser, ParserState, FuncType, ImportSectionEntryType, ExternalKind, WasmDecoder, use wasmparser::{Parser, ParserState, FuncType, ImportSectionEntryType, ExternalKind, WasmDecoder,
@@ -61,8 +60,8 @@ pub fn parse_function_signatures(
pub fn parse_import_section( pub fn parse_import_section(
parser: &mut Parser, parser: &mut Parser,
runtime: &mut WasmRuntime, runtime: &mut WasmRuntime,
) -> Result<Vec<Import>, SectionParsingError> { function_index: &mut FunctionIndex,
let mut imports = Vec::new(); ) -> Result<(), SectionParsingError> {
loop { loop {
match *parser.read() { match *parser.read() {
ParserState::ImportSectionEntry { ParserState::ImportSectionEntry {
@@ -71,42 +70,42 @@ pub fn parse_import_section(
field, field,
} => { } => {
runtime.declare_func_import(sig as SignatureIndex, module, field); runtime.declare_func_import(sig as SignatureIndex, module, field);
imports.push(Import::Function { sig_index: sig }); *function_index += 1;
} }
ParserState::ImportSectionEntry { ParserState::ImportSectionEntry {
ty: ImportSectionEntryType::Memory(MemoryType { limits: ref memlimits }), .. ty: ImportSectionEntryType::Memory(MemoryType { limits: ref memlimits }), ..
} => { } => {
imports.push(Import::Memory(Memory { runtime.declare_memory(Memory {
pages_count: memlimits.initial as usize, pages_count: memlimits.initial as usize,
maximum: memlimits.maximum.map(|x| x as usize), maximum: memlimits.maximum.map(|x| x as usize),
})) });
} }
ParserState::ImportSectionEntry { ParserState::ImportSectionEntry {
ty: ImportSectionEntryType::Global(ref ty), .. ty: ImportSectionEntryType::Global(ref ty), ..
} => { } => {
imports.push(Import::Global(Global { runtime.declare_global(Global {
ty: type_to_type(&ty.content_type).unwrap(), ty: type_to_type(&ty.content_type).unwrap(),
mutability: ty.mutable, mutability: ty.mutable,
initializer: GlobalInit::Import(), initializer: GlobalInit::Import(),
})); });
} }
ParserState::ImportSectionEntry { ParserState::ImportSectionEntry {
ty: ImportSectionEntryType::Table(ref tab), .. ty: ImportSectionEntryType::Table(ref tab), ..
} => { } => {
imports.push(Import::Table(Table { runtime.declare_table(Table {
ty: match type_to_type(&tab.element_type) { ty: match type_to_type(&tab.element_type) {
Ok(t) => TableElementType::Val(t), Ok(t) => TableElementType::Val(t),
Err(()) => TableElementType::Func(), Err(()) => TableElementType::Func(),
}, },
size: tab.limits.initial as usize, size: tab.limits.initial as usize,
maximum: tab.limits.maximum.map(|x| x as usize), maximum: tab.limits.maximum.map(|x| x as usize),
})); });
} }
ParserState::EndSection => break, ParserState::EndSection => break,
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
}; };
} }
Ok(imports) Ok(())
} }
/// Retrieves the correspondances between functions and signatures from the function section /// 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 /// Retrieves the size and maximum fields of memories from the memory section
pub fn parse_memory_section(parser: &mut Parser) -> Result<Vec<Memory>, SectionParsingError> { pub fn parse_memory_section(
let mut memories: Vec<Memory> = Vec::new(); parser: &mut Parser,
runtime: &mut WasmRuntime,
) -> Result<(), SectionParsingError> {
loop { loop {
match *parser.read() { match *parser.read() {
ParserState::MemorySectionEntry(ref ty) => { ParserState::MemorySectionEntry(ref ty) => {
memories.push(Memory { runtime.declare_memory(Memory {
pages_count: ty.limits.initial as usize, pages_count: ty.limits.initial as usize,
maximum: ty.limits.maximum.map(|x| x as usize), maximum: ty.limits.maximum.map(|x| x as usize),
}) });
} }
ParserState::EndSection => break, ParserState::EndSection => break,
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
}; };
} }
Ok(memories) 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_global_section( pub fn parse_global_section(
parser: &mut Parser, parser: &mut Parser,
runtime: &mut WasmRuntime, runtime: &mut WasmRuntime,
) -> Result<Vec<Global>, SectionParsingError> { ) -> Result<(), SectionParsingError> {
let mut globals = Vec::new();
loop { loop {
let (content_type, mutability) = match *parser.read() { let (content_type, mutability) = match *parser.read() {
ParserState::BeginGlobalSectionEntry(ref ty) => (ty.content_type, ty.mutable), ParserState::BeginGlobalSectionEntry(ref ty) => (ty.content_type, ty.mutable),
@@ -218,19 +218,17 @@ pub fn parse_global_section(
initializer: initializer, initializer: initializer,
}; };
runtime.declare_global(global); runtime.declare_global(global);
globals.push(global);
match *parser.read() { match *parser.read() {
ParserState::EndGlobalSectionEntry => (), ParserState::EndGlobalSectionEntry => (),
ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), ref s => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
} }
} }
Ok(globals) Ok(())
} }
pub fn parse_data_section( pub fn parse_data_section(
parser: &mut Parser, parser: &mut Parser,
runtime: &mut WasmRuntime, runtime: &mut WasmRuntime,
globals: &[Global],
) -> Result<(), SectionParsingError> { ) -> Result<(), SectionParsingError> {
loop { loop {
let memory_index = match *parser.read() { let memory_index = match *parser.read() {
@@ -254,7 +252,7 @@ pub fn parse_data_section(
} }
} }
ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => { 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) => { GlobalInit::I32Const(value) => {
if value < 0 { if value < 0 {
return Err(SectionParsingError::WrongSectionContent(String::from( return Err(SectionParsingError::WrongSectionContent(String::from(
@@ -332,7 +330,6 @@ pub fn parse_table_section(
pub fn parse_elements_section( pub fn parse_elements_section(
parser: &mut Parser, parser: &mut Parser,
runtime: &mut WasmRuntime, runtime: &mut WasmRuntime,
globals: &[Global],
) -> Result<(), SectionParsingError> { ) -> Result<(), SectionParsingError> {
loop { loop {
let table_index = match *parser.read() { let table_index = match *parser.read() {
@@ -356,7 +353,7 @@ pub fn parse_elements_section(
} }
} }
ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => { 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) => { GlobalInit::I32Const(value) => {
if value < 0 { if value < 0 {
return Err(SectionParsingError::WrongSectionContent(String::from( return Err(SectionParsingError::WrongSectionContent(String::from(

View File

@@ -14,15 +14,6 @@ pub type MemoryIndex = usize;
/// Index of a signature (imported or defined) inside the WebAssembly module. /// Index of a signature (imported or defined) inside the WebAssembly module.
pub type SignatureIndex = usize; 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. /// WebAssembly global.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Global { pub struct Global {