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`.
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.
pub functions: PrimaryMap<FuncIndex, Exportable<SignatureIndex>>,
@@ -78,6 +87,9 @@ impl DummyModuleInfo {
config,
signatures: PrimaryMap::new(),
imported_funcs: Vec::new(),
imported_globals: Vec::new(),
imported_tables: Vec::new(),
imported_memories: Vec::new(),
functions: PrimaryMap::new(),
function_bodies: PrimaryMap::new(),
tables: PrimaryMap::new(),
@@ -375,6 +387,13 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
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 {
&self.info.globals[global_index].entity
}
@@ -382,6 +401,14 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
fn declare_table(&mut self, table: 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(
&mut self,
_table_index: TableIndex,
@@ -391,9 +418,18 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
) {
// We do nothing
}
fn declare_memory(&mut self, memory: 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(
&mut self,
_memory_index: MemoryIndex,

View File

@@ -268,11 +268,18 @@ pub trait ModuleEnvironment<'data> {
/// Declares a global to the environment.
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.
fn get_global(&self, global_index: GlobalIndex) -> &Global;
/// Declares a table to the environment.
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.
fn declare_table_elements(
&mut self,
@@ -283,6 +290,10 @@ pub trait ModuleEnvironment<'data> {
);
/// Declares a memory to the environment
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.
fn declare_data_initialization(
&mut self,

View File

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

View File

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

View File

@@ -13,6 +13,21 @@ entity_impl!(FuncIndex);
pub struct DefinedFuncIndex(u32);
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.
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct TableIndex(u32);