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`.
|
/// 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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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"))]
|
||||||
|
|||||||
@@ -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,
|
|
||||||
field,
|
|
||||||
ty: ImportSectionEntryType::Function(sig),
|
|
||||||
} => {
|
|
||||||
// The input has already been validated, so we should be able to
|
// The input has already been validated, so we should be able to
|
||||||
// assume valid UTF-8 and use `from_utf8_unchecked` if performance
|
// assume valid UTF-8 and use `from_utf8_unchecked` if performance
|
||||||
// becomes a concern here.
|
// becomes a concern here.
|
||||||
let module_name = from_utf8(module).unwrap();
|
let module_name = from_utf8(import.module).unwrap();
|
||||||
let field_name = from_utf8(field).unwrap();
|
let field_name = from_utf8(import.field).unwrap();
|
||||||
|
|
||||||
|
match import.ty {
|
||||||
|
ImportSectionEntryType::Function(sig) => {
|
||||||
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 {
|
|
||||||
ty:
|
|
||||||
ImportSectionEntryType::Memory(MemoryType {
|
ImportSectionEntryType::Memory(MemoryType {
|
||||||
limits: ref memlimits,
|
limits: ref memlimits,
|
||||||
shared,
|
shared,
|
||||||
}),
|
}) => {
|
||||||
..
|
environ.declare_memory_import(
|
||||||
} => {
|
Memory {
|
||||||
environ.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),
|
||||||
shared,
|
shared,
|
||||||
});
|
},
|
||||||
|
module_name,
|
||||||
|
field_name,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Import {
|
ImportSectionEntryType::Global(ref ty) => {
|
||||||
ty: ImportSectionEntryType::Global(ref ty),
|
environ.declare_global_import(
|
||||||
..
|
Global {
|
||||||
} => {
|
|
||||||
environ.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(),
|
||||||
});
|
},
|
||||||
|
module_name,
|
||||||
|
field_name,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Import {
|
ImportSectionEntryType::Table(ref tab) => {
|
||||||
ty: ImportSectionEntryType::Table(ref tab),
|
environ.declare_table_import(
|
||||||
..
|
Table {
|
||||||
} => environ.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),
|
||||||
}),
|
},
|
||||||
|
module_name,
|
||||||
|
field_name,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user