use crate::{ backend::FuncResolver, import::Imports, sig_registry::SigRegistry, types::{ FuncIndex, Global, GlobalDesc, GlobalIndex, Map, MapIndex, Memory, MemoryIndex, SigIndex, Table, TableIndex, }, Instance, }; use hashbrown::HashMap; use std::rc::Rc; /// This is used to instantiate a new webassembly module. #[doc(hidden)] pub struct ModuleInner { pub func_resolver: Box<dyn FuncResolver>, pub memories: Map<MemoryIndex, Memory>, pub globals: Map<GlobalIndex, Global>, pub tables: Map<TableIndex, Table>, pub imported_functions: Map<FuncIndex, ImportName>, pub imported_memories: Map<MemoryIndex, (ImportName, Memory)>, pub imported_tables: Map<TableIndex, (ImportName, Table)>, pub imported_globals: Map<GlobalIndex, (ImportName, GlobalDesc)>, pub exports: HashMap<String, ExportIndex>, pub data_initializers: Vec<DataInitializer>, pub table_initializers: Vec<TableInitializer>, pub start_func: Option<FuncIndex>, pub func_assoc: Map<FuncIndex, SigIndex>, pub sig_registry: SigRegistry, } pub struct Module(Rc<ModuleInner>); impl Module { pub(crate) fn new(inner: Rc<ModuleInner>) -> Self { Module(inner) } /// Instantiate a webassembly module with the provided imports. pub fn instantiate(&self, imports: &mut Imports) -> Result<Instance, String> { Instance::new(Rc::clone(&self.0), imports) } } impl ModuleInner { pub(crate) fn is_imported_function(&self, func_index: FuncIndex) -> bool { func_index.index() < self.imported_functions.len() } pub(crate) fn is_imported_memory(&self, memory_index: MemoryIndex) -> bool { memory_index.index() < self.imported_memories.len() } pub(crate) fn is_imported_table(&self, table_index: TableIndex) -> bool { table_index.index() < self.imported_tables.len() } pub(crate) fn is_imported_global(&self, global_index: GlobalIndex) -> bool { global_index.index() < self.imported_globals.len() } } #[doc(hidden)] #[derive(Debug, Clone)] pub struct ImportName { pub namespace: String, pub name: String, } impl From<(String, String)> for ImportName { fn from(n: (String, String)) -> Self { ImportName { namespace: n.0, name: n.1, } } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ExportIndex { Func(FuncIndex), Memory(MemoryIndex), Global(GlobalIndex), Table(TableIndex), } /// A data initializer for linear memory. #[derive(Debug)] pub struct DataInitializer { /// The index of the memory to initialize. pub memory_index: MemoryIndex, /// Optionally a globalvalue base to initialize at. pub base: Option<GlobalIndex>, /// A constant offset to initialize at. pub offset: usize, /// The initialization data. pub data: Vec<u8>, } /// A WebAssembly table initializer. #[derive(Clone, Debug)] pub struct TableInitializer { /// The index of a table to initialize. pub table_index: TableIndex, /// Optionally, a global variable giving a base index. pub base: Option<GlobalIndex>, /// The offset to add to the base. pub offset: usize, /// The values to write into the table elements. pub elements: Vec<FuncIndex>, }