Use the WasmRuntime's global list rather than keeping a separate list.
This commit is contained in:
@@ -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))
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user