diff --git a/lib/clif-backend/src/codegen.rs b/lib/clif-backend/src/codegen.rs index d237ab1c2..22f522e19 100644 --- a/lib/clif-backend/src/codegen.rs +++ b/lib/clif-backend/src/codegen.rs @@ -148,8 +148,8 @@ pub mod converter { F64Const(val) => Const(f64::from_bits(val).into()), GlobalInit::GetGlobal(index) => { WasmerInitializer::GetGlobal(WasmerGlobalIndex::new(index.index())) - } - Import => unimplemented!("TODO: imported globals are not supported yet!"), + }, + GlobalInit::Import => WasmerInitializer::Import }; WasmerGlobal { desc, init } diff --git a/lib/runtime/src/backing.rs b/lib/runtime/src/backing.rs index 12ffc3bba..b0c1efd22 100644 --- a/lib/runtime/src/backing.rs +++ b/lib/runtime/src/backing.rs @@ -158,7 +158,7 @@ impl LocalBacking { imports: &ImportBacking, mut globals: Box<[vm::LocalGlobal]>, ) -> Box<[vm::LocalGlobal]> { - for (to, (_, from)) in globals.iter_mut().zip(module.globals.into_iter()) { + for (to, (global_index, from)) in globals.iter_mut().zip(module.globals.into_iter()) { to.data = match from.init { Initializer::Const(Value::I32(x)) => x as u64, Initializer::Const(Value::I64(x)) => x as u64, @@ -167,6 +167,9 @@ impl LocalBacking { Initializer::GetGlobal(index) => unsafe { (*imports.globals[index.index()].global).data }, + Initializer::Import => unsafe { + (*imports.globals[global_index.index()].global).data + }, }; } diff --git a/lib/runtime/src/instance.rs b/lib/runtime/src/instance.rs index 80d448cdf..c4c139ce3 100644 --- a/lib/runtime/src/instance.rs +++ b/lib/runtime/src/instance.rs @@ -1,10 +1,15 @@ use crate::recovery::call_protected; use crate::{ backing::{ImportBacking, LocalBacking}, - export::{Context, Export, ExportIter, FuncPointer, MemoryPointer, TablePointer}, + export::{ + Context, Export, ExportIter, FuncPointer, GlobalPointer, MemoryPointer, TablePointer, + }, import::{Imports, Namespace}, module::{ExportIndex, Module, ModuleInner}, - types::{FuncIndex, FuncSig, MapIndex, Memory, MemoryIndex, Table, TableIndex, Type, Value}, + types::{ + FuncIndex, FuncSig, GlobalDesc, GlobalIndex, MapIndex, Memory, MemoryIndex, Table, + TableIndex, Type, Value, + }, vm, }; use libffi::high::{arg as libffi_arg, call as libffi_call, CodePtr}; @@ -169,7 +174,10 @@ impl InstanceInner { memory, } } - ExportIndex::Global(_global_index) => unimplemented!(), + ExportIndex::Global(global_index) => { + let (local, global) = self.get_global_from_index(module, *global_index); + Export::Global { local, global } + } ExportIndex::Table(table_index) => { let (local, ctx, table) = self.get_table_from_index(module, *table_index); Export::Table { @@ -247,6 +255,31 @@ impl InstanceInner { } } + fn get_global_from_index( + &mut self, + module: &ModuleInner, + global_index: GlobalIndex, + ) -> (GlobalPointer, GlobalDesc) { + if module.is_imported_global(global_index) { + let &(_, desc) = &module + .imported_globals + .get(global_index) + .expect("missing imported global index"); + let vm::ImportedGlobal { global } = &self.import_backing.globals[global_index.index()]; + (unsafe { GlobalPointer::new(*global) }, *desc) + } else { + let vm_global = &mut self.backing.vm_globals[global_index.index() as usize]; + ( + unsafe { GlobalPointer::new(vm_global) }, + module + .globals + .get(global_index) + .expect("broken invariant, globals") + .desc, + ) + } + } + fn get_table_from_index( &mut self, module: &ModuleInner, diff --git a/lib/runtime/src/module.rs b/lib/runtime/src/module.rs index 8395c3b03..bed4acbb0 100644 --- a/lib/runtime/src/module.rs +++ b/lib/runtime/src/module.rs @@ -59,6 +59,10 @@ impl ModuleInner { 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)] diff --git a/lib/runtime/src/types.rs b/lib/runtime/src/types.rs index 4e93fbd61..d0834721a 100644 --- a/lib/runtime/src/types.rs +++ b/lib/runtime/src/types.rs @@ -95,6 +95,8 @@ pub enum Initializer { Const(Value), /// Corresponds to a `get_global` instruction. GetGlobal(GlobalIndex), + /// Initialized externally + Import, } #[derive(Debug, Clone, Copy, PartialEq, Eq)]