diff --git a/lib/runtime/src/backing.rs b/lib/runtime/src/backing.rs index 35f92865b..f23bb2e63 100644 --- a/lib/runtime/src/backing.rs +++ b/lib/runtime/src/backing.rs @@ -175,10 +175,6 @@ impl ImportBacking { imports: &dyn ImportResolver, vmctx: *mut vm::Ctx, ) -> Result { - assert!( - module.imported_memories.len() == 0, - "imported memories not yet supported" - ); assert!( module.imported_tables.len() == 0, "imported tables not yet supported" @@ -186,16 +182,48 @@ impl ImportBacking { Ok(ImportBacking { functions: import_functions(module, imports, vmctx)?, - memories: vec![].into_boxed_slice(), + memories: import_memories(module, imports, vmctx)?, tables: vec![].into_boxed_slice(), globals: import_globals(module, imports)?, }) } } -// fn import_memories(module: &Module, imports: &dyn ImportResolver) -> Result, String> { - -// } +fn import_memories( + module: &Module, + imports: &dyn ImportResolver, + vmctx: *mut vm::Ctx, +) -> Result, String> { + let mut memories = Vec::with_capacity(module.imported_memories.len()); + for (_index, (ImportName { namespace, name }, _memory)) in &module.imported_memories { + let memory_import = imports.get(namespace, name); + match memory_import { + Some(Export::Memory { + local, + ctx, + memory: _, + }) => { + memories.push(vm::ImportedMemory { + memory: local, + vmctx: match ctx { + Context::External(ctx) => ctx, + Context::Internal => vmctx, + }, + }); + } + Some(_) => { + return Err(format!( + "incorrect import memory type for {}:{}", + namespace, name + )); + } + None => { + return Err(format!("memory not found: {}:{}", namespace, name)); + } + } + } + Ok(memories.into_boxed_slice()) +} fn import_functions( module: &Module, diff --git a/lib/runtime/src/instance.rs b/lib/runtime/src/instance.rs index 280a381a2..c47578fda 100644 --- a/lib/runtime/src/instance.rs +++ b/lib/runtime/src/instance.rs @@ -4,7 +4,7 @@ use crate::{ export::{Context, Export}, import::ImportResolver, module::{ExportIndex, Module}, - types::{FuncIndex, FuncSig, MapIndex, Type, Value}, + types::{FuncIndex, FuncSig, MapIndex, Memory, MemoryIndex, Type, Value}, vm, }; use hashbrown::hash_map; @@ -160,7 +160,19 @@ impl Instance { signature, } } - ExportIndex::Memory(_memory_index) => unimplemented!(), + ExportIndex::Memory(memory_index) => { + let (local, ctx, memory) = self.get_memory_from_index(*memory_index); + Export::Memory { + local, + ctx: match ctx { + Context::Internal => { + Context::External(&*self.vmctx as *const vm::Ctx as *mut vm::Ctx) + } + ctx @ Context::External(_) => ctx, + }, + memory, + } + } ExportIndex::Global(_global_index) => unimplemented!(), ExportIndex::Table(_table_index) => unimplemented!(), } @@ -195,6 +207,35 @@ impl Instance { (FuncRef(func_ptr), ctx, signature) } + + fn get_memory_from_index( + &self, + mem_index: MemoryIndex, + ) -> (*mut vm::LocalMemory, Context, Memory) { + if self.module.is_imported_memory(mem_index) { + let &(_, mem) = &self + .module + .imported_memories + .get(mem_index) + .expect("missing imported memory index"); + let vm::ImportedMemory { memory, vmctx } = + &self.import_backing.memories[mem_index.index()]; + (*memory, Context::External(*vmctx), *mem) + } else { + // let vm_mem = .memories[mem_index.index() as usize]; + let vm_mem = + unsafe { &mut (*self.vmctx.local_backing).memories[mem_index.index() as usize] }; + ( + &mut vm_mem.into_vm_memory(), + Context::Internal, + *self + .module + .memories + .get(mem_index) + .expect("broken invariant, memories"), + ) + } + } } #[derive(Debug, Clone)] diff --git a/lib/runtime/src/module.rs b/lib/runtime/src/module.rs index 31c086425..cc668514f 100644 --- a/lib/runtime/src/module.rs +++ b/lib/runtime/src/module.rs @@ -52,6 +52,10 @@ 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() + } } impl Deref for Module {