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:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"))]
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user