Improved imports (#612)

* Impoved support for wasm global imports

* Refactored parse_import_section improving readability

* Improved support for wasm table imports

* Improved support for wasm memory imports

* Improved formatting

* Added DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex structs
This commit is contained in:
Syrus Akbary
2018-11-25 05:10:58 -08:00
committed by Dan Gohman
parent b11646aba3
commit 737fde04a8
5 changed files with 110 additions and 45 deletions

View File

@@ -52,6 +52,15 @@ pub struct DummyModuleInfo {
/// Module and field names of imported functions as provided by `declare_func_import`. /// Module and field names of imported functions as provided by `declare_func_import`.
pub imported_funcs: Vec<(String, String)>, pub imported_funcs: Vec<(String, String)>,
/// Module and field names of imported globals as provided by `declare_global_import`.
pub imported_globals: Vec<(String, String)>,
/// Module and field names of imported tables as provided by `declare_table_import`.
pub imported_tables: Vec<(String, String)>,
/// Module and field names of imported memories as provided by `declare_memory_import`.
pub imported_memories: Vec<(String, String)>,
/// Functions, imported and local. /// Functions, imported and local.
pub functions: PrimaryMap<FuncIndex, Exportable<SignatureIndex>>, pub functions: PrimaryMap<FuncIndex, Exportable<SignatureIndex>>,
@@ -78,6 +87,9 @@ impl DummyModuleInfo {
config, config,
signatures: PrimaryMap::new(), signatures: PrimaryMap::new(),
imported_funcs: Vec::new(), imported_funcs: Vec::new(),
imported_globals: Vec::new(),
imported_tables: Vec::new(),
imported_memories: Vec::new(),
functions: PrimaryMap::new(), functions: PrimaryMap::new(),
function_bodies: PrimaryMap::new(), function_bodies: PrimaryMap::new(),
tables: PrimaryMap::new(), tables: PrimaryMap::new(),
@@ -375,6 +387,13 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
self.info.globals.push(Exportable::new(global)); self.info.globals.push(Exportable::new(global));
} }
fn declare_global_import(&mut self, global: Global, module: &'data str, field: &'data str) {
self.info.globals.push(Exportable::new(global));
self.info
.imported_globals
.push((String::from(module), String::from(field)));
}
fn get_global(&self, global_index: GlobalIndex) -> &Global { fn get_global(&self, global_index: GlobalIndex) -> &Global {
&self.info.globals[global_index].entity &self.info.globals[global_index].entity
} }
@@ -382,6 +401,14 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
fn declare_table(&mut self, table: Table) { fn declare_table(&mut self, table: Table) {
self.info.tables.push(Exportable::new(table)); self.info.tables.push(Exportable::new(table));
} }
fn declare_table_import(&mut self, table: Table, module: &'data str, field: &'data str) {
self.info.tables.push(Exportable::new(table));
self.info
.imported_tables
.push((String::from(module), String::from(field)));
}
fn declare_table_elements( fn declare_table_elements(
&mut self, &mut self,
_table_index: TableIndex, _table_index: TableIndex,
@@ -391,9 +418,18 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
) { ) {
// We do nothing // We do nothing
} }
fn declare_memory(&mut self, memory: Memory) { fn declare_memory(&mut self, memory: Memory) {
self.info.memories.push(Exportable::new(memory)); self.info.memories.push(Exportable::new(memory));
} }
fn declare_memory_import(&mut self, memory: Memory, module: &'data str, field: &'data str) {
self.info.memories.push(Exportable::new(memory));
self.info
.imported_memories
.push((String::from(module), String::from(field)));
}
fn declare_data_initialization( fn declare_data_initialization(
&mut self, &mut self,
_memory_index: MemoryIndex, _memory_index: MemoryIndex,

View File

@@ -268,11 +268,18 @@ pub trait ModuleEnvironment<'data> {
/// Declares a global to the environment. /// Declares a global to the environment.
fn declare_global(&mut self, global: Global); fn declare_global(&mut self, global: Global);
/// Declares a global import to the environment.
fn declare_global_import(&mut self, global: Global, module: &'data str, field: &'data str);
/// Return the global for the given global index. /// Return the global for the given global index.
fn get_global(&self, global_index: GlobalIndex) -> &Global; fn get_global(&self, global_index: GlobalIndex) -> &Global;
/// Declares a table to the environment. /// Declares a table to the environment.
fn declare_table(&mut self, table: Table); fn declare_table(&mut self, table: Table);
/// Declares a table import to the environment.
fn declare_table_import(&mut self, table: Table, module: &'data str, field: &'data str);
/// Fills a declared table with references to functions in the module. /// Fills a declared table with references to functions in the module.
fn declare_table_elements( fn declare_table_elements(
&mut self, &mut self,
@@ -283,6 +290,10 @@ pub trait ModuleEnvironment<'data> {
); );
/// Declares a memory to the environment /// Declares a memory to the environment
fn declare_memory(&mut self, memory: Memory); fn declare_memory(&mut self, memory: Memory);
/// Declares a memory import to the environment.
fn declare_memory_import(&mut self, memory: Memory, module: &'data str, field: &'data str);
/// Fills a declared memory with bytes at module instantiation. /// Fills a declared memory with bytes at module instantiation.
fn declare_data_initialization( fn declare_data_initialization(
&mut self, &mut self,

View File

@@ -66,8 +66,8 @@ pub use environ::{
pub use func_translator::FuncTranslator; pub use func_translator::FuncTranslator;
pub use module_translator::translate_module; pub use module_translator::translate_module;
pub use translation_utils::{ pub use translation_utils::{
DefinedFuncIndex, FuncIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex, DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, FuncIndex, Global,
SignatureIndex, Table, TableIndex, GlobalIndex, GlobalInit, Memory, MemoryIndex, SignatureIndex, Table, TableIndex,
}; };
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]

View File

@@ -60,58 +60,61 @@ pub fn parse_import_section<'data>(
environ: &mut ModuleEnvironment<'data>, environ: &mut ModuleEnvironment<'data>,
) -> WasmResult<()> { ) -> WasmResult<()> {
for entry in imports { for entry in imports {
match entry? { let import = entry?;
Import {
module, // The input has already been validated, so we should be able to
field, // assume valid UTF-8 and use `from_utf8_unchecked` if performance
ty: ImportSectionEntryType::Function(sig), // becomes a concern here.
} => { let module_name = from_utf8(import.module).unwrap();
// The input has already been validated, so we should be able to let field_name = from_utf8(import.field).unwrap();
// assume valid UTF-8 and use `from_utf8_unchecked` if performance
// becomes a concern here. match import.ty {
let module_name = from_utf8(module).unwrap(); ImportSectionEntryType::Function(sig) => {
let field_name = from_utf8(field).unwrap();
environ.declare_func_import( environ.declare_func_import(
SignatureIndex::new(sig as usize), SignatureIndex::new(sig as usize),
module_name, module_name,
field_name, field_name,
); );
} }
Import { ImportSectionEntryType::Memory(MemoryType {
ty: limits: ref memlimits,
ImportSectionEntryType::Memory(MemoryType { shared,
limits: ref memlimits, }) => {
environ.declare_memory_import(
Memory {
pages_count: memlimits.initial as usize,
maximum: memlimits.maximum.map(|x| x as usize),
shared, shared,
}), },
.. module_name,
} => { field_name,
environ.declare_memory(Memory { );
pages_count: memlimits.initial as usize,
maximum: memlimits.maximum.map(|x| x as usize),
shared,
});
} }
Import { ImportSectionEntryType::Global(ref ty) => {
ty: ImportSectionEntryType::Global(ref ty), environ.declare_global_import(
.. Global {
} => { ty: type_to_type(ty.content_type).unwrap(),
environ.declare_global(Global { mutability: ty.mutable,
ty: type_to_type(ty.content_type).unwrap(), initializer: GlobalInit::Import(),
mutability: ty.mutable, },
initializer: GlobalInit::Import(), module_name,
}); field_name,
);
}
ImportSectionEntryType::Table(ref tab) => {
environ.declare_table_import(
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),
},
module_name,
field_name,
);
} }
Import {
ty: ImportSectionEntryType::Table(ref tab),
..
} => environ.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),
}),
} }
} }
Ok(()) Ok(())

View File

@@ -13,6 +13,21 @@ entity_impl!(FuncIndex);
pub struct DefinedFuncIndex(u32); pub struct DefinedFuncIndex(u32);
entity_impl!(DefinedFuncIndex); entity_impl!(DefinedFuncIndex);
/// Index type of a defined table inside the WebAssembly module.
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct DefinedTableIndex(u32);
entity_impl!(DefinedTableIndex);
/// Index type of a defined memory inside the WebAssembly module.
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct DefinedMemoryIndex(u32);
entity_impl!(DefinedMemoryIndex);
/// Index type of a defined global inside the WebAssembly module.
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct DefinedGlobalIndex(u32);
entity_impl!(DefinedGlobalIndex);
/// Index type of a table (imported or defined) inside the WebAssembly module. /// Index type of a table (imported or defined) inside the WebAssembly module.
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct TableIndex(u32); pub struct TableIndex(u32);