pub mod service; use wasmer_runtime_core::{ loader::{self, Loader, Instance}, backend::RunnableModule, vm::{InternalCtx, LocalGlobal}, module::ModuleInfo, types::{Value, LocalMemoryIndex, ImportedMemoryIndex}, structures::TypedIndex, }; use service::{ServiceContext, RunProfile}; pub struct KernelLoader; impl Loader for KernelLoader { type Instance = KernelInstance; type Error = String; fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &InternalCtx) -> Result { let code = rm.get_code().unwrap(); let memory = if let Some(_) = module.memories.get(LocalMemoryIndex::new(0)) { Some(unsafe { ::std::slice::from_raw_parts((**ctx.memories).base, (**ctx.memories).bound) }.to_vec()) } else if let Some(_) = module.imported_memories.get(ImportedMemoryIndex::new(0)) { return Err("imported memory is not supported".into()); } else { None }; if module.imported_globals.len() > 0 { return Err("imported globals are not supported".into()); } let globals: Vec = unsafe { let globals: &[*mut LocalGlobal] = ::std::slice::from_raw_parts(ctx.globals, module.globals.len()); globals.iter().map(|x| (**x).data).collect() }; Ok(KernelInstance { context: ServiceContext::connect().map_err(|x| format!("{:?}", x))?, code: code.to_vec(), memory: memory, globals: globals, offsets: rm.get_offsets().unwrap(), }) } } pub struct KernelInstance { context: ServiceContext, code: Vec, memory: Option>, globals: Vec, offsets: Vec, } impl Instance for KernelInstance { type Error = String; fn call(&mut self, id: usize, args: &[Value]) -> Result { let args: Vec = args.iter().map(|x| x.to_u64()).collect(); let ret = self.context.run_code(RunProfile { code: &self.code, memory: if let Some(ref x) = self.memory { Some(&*x) } else { None }, memory_max: 0, globals: &self.globals, params: &args, entry_offset: self.offsets[id] as u32, }).map_err(|x| format!("{:?}", x))?; Ok(ret as u64) } }