From cc01e40dc52d07cc05fabcf6ecbfb1439bccc3bf Mon Sep 17 00:00:00 2001 From: Heyang Zhou Date: Sun, 5 May 2019 05:03:07 -0700 Subject: [PATCH] Split load/run --- lib/kwasm-loader/src/lib.rs | 46 +++++++++----------- lib/kwasm-loader/src/service.rs | 75 +++++++++++++++++++++------------ 2 files changed, 69 insertions(+), 52 deletions(-) diff --git a/lib/kwasm-loader/src/lib.rs b/lib/kwasm-loader/src/lib.rs index 2afea2ce7..0acd356ff 100644 --- a/lib/kwasm-loader/src/lib.rs +++ b/lib/kwasm-loader/src/lib.rs @@ -8,7 +8,7 @@ use wasmer_runtime_core::{ types::{Value, LocalMemoryIndex, LocalTableIndex, ImportedMemoryIndex, ImportedTableIndex}, structures::TypedIndex, }; -use service::{ServiceContext, RunProfile, TableEntryRequest}; +use service::{ServiceContext, LoadProfile, RunProfile, TableEntryRequest}; pub struct KernelLoader; @@ -22,7 +22,7 @@ impl Loader for KernelLoader { 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 { @@ -63,30 +63,31 @@ impl Loader for KernelLoader { let name = format!("{}##{}", module.namespace_table.get(import.namespace_index), module.name_table.get(import.name_index)); import_names.push(name); } - Ok(KernelInstance { - context: ServiceContext::connect().map_err(|x| format!("{:?}", x))?, - code: code.to_vec(), - memory: memory, - table: table, - globals: globals, - offsets: rm.get_offsets().unwrap(), - import_names: import_names, - dynamic_sigindices: unsafe { + let dynamic_sigindices: &[u32] = unsafe { + ::std::mem::transmute::<&[SigId], &[u32]>( ::std::slice::from_raw_parts(ctx.dynamic_sigindices, full_ctx.dynamic_sigindice_count()) - }.iter().map(|x| x.0).collect(), + ) + }; + let profile = LoadProfile { + code: code, + memory: memory, + memory_max: 0, + globals: &globals, + imports: &import_names, + dynamic_sigindices: dynamic_sigindices, + table: table.as_ref().map(|x| x.as_slice()), + }; + let sc = ServiceContext::new(profile).map_err(|x| format!("{:?}", x))?; + Ok(KernelInstance { + context: sc, + offsets: rm.get_offsets().unwrap(), }) } } pub struct KernelInstance { context: ServiceContext, - code: Vec, - memory: Option>, - table: Option>, - globals: Vec, offsets: Vec, - import_names: Vec, - dynamic_sigindices: Vec, } impl Instance for KernelInstance { @@ -95,15 +96,8 @@ impl Instance for KernelInstance { 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, - imports: &self.import_names, - dynamic_sigindices: &self.dynamic_sigindices, - table: self.table.as_ref().map(|x| x.as_slice()), + params: &args, }).map_err(|x| format!("{:?}", x))?; Ok(ret as u64) } diff --git a/lib/kwasm-loader/src/service.rs b/lib/kwasm-loader/src/service.rs index 8cac49c8e..eaa8230a9 100644 --- a/lib/kwasm-loader/src/service.rs +++ b/lib/kwasm-loader/src/service.rs @@ -15,12 +15,14 @@ macro_rules! impl_debug_display { #[repr(i32)] pub enum Command { - RunCode = 0x1001, + LoadCode = 0x1001, + RunCode = 0x1002, } #[derive(Debug)] pub enum ServiceError { Io(io::Error), + Code(i32), InvalidInput, Rejected } @@ -42,7 +44,7 @@ impl From for ServiceError { } #[repr(C)] -struct RunCodeRequest { +struct LoadCodeRequest { code: *const u8, code_len: u32, memory: *const u8, @@ -58,7 +60,10 @@ struct RunCodeRequest { dynamic_sigindices: *const u32, dynamic_sigindice_count: u32, +} +#[repr(C)] +struct RunCodeRequest { entry_offset: u32, params: *const u64, param_count: u32, @@ -75,31 +80,29 @@ pub struct TableEntryRequest { pub sig_id: u32, } -pub struct RunProfile<'a> { +pub struct LoadProfile<'a> { pub code: &'a [u8], pub memory: Option<&'a [u8]>, pub memory_max: usize, pub globals: &'a [u64], - pub params: &'a [u64], - pub entry_offset: u32, pub imports: &'a [String], pub dynamic_sigindices: &'a [u32], pub table: Option<&'a [TableEntryRequest]>, } +pub struct RunProfile<'a> { + pub entry_offset: u32, + pub params: &'a [u64], +} + pub struct ServiceContext { dev: File } impl ServiceContext { - pub fn connect() -> ServiceResult { - Ok(ServiceContext { - dev: File::open("/dev/wasmctl")? - }) - } - - pub fn run_code(&mut self, run: RunProfile) -> ServiceResult { - let imports: Vec = run.imports.iter().map(|x| { + pub fn new(load: LoadProfile) -> ServiceResult { + let dev = File::open("/dev/wasmctl")?; + let imports: Vec = load.imports.iter().map(|x| { let mut req: ImportRequest = unsafe { ::std::mem::zeroed() }; let x = x.as_bytes(); let mut count = req.name.len() - 1; @@ -109,23 +112,43 @@ impl ServiceContext { req.name[..count].copy_from_slice(&x[..count]); req }).collect(); - let req = RunCodeRequest { - code: run.code.as_ptr(), - code_len: run.code.len() as u32, - memory: run.memory.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()), - memory_len: run.memory.map(|x| x.len() as u32).unwrap_or(0), - memory_max: run.memory_max as u32, - table: run.table.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()), - table_count: run.table.map(|x| x.len() as u32).unwrap_or(0), - globals: run.globals.as_ptr(), - global_count: run.globals.len() as u32, + let req = LoadCodeRequest { + code: load.code.as_ptr(), + code_len: load.code.len() as u32, + memory: load.memory.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()), + memory_len: load.memory.map(|x| x.len() as u32).unwrap_or(0), + memory_max: load.memory_max as u32, + table: load.table.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()), + table_count: load.table.map(|x| x.len() as u32).unwrap_or(0), + globals: load.globals.as_ptr(), + global_count: load.globals.len() as u32, imported_funcs: imports.as_ptr(), imported_func_count: imports.len() as u32, - dynamic_sigindices: run.dynamic_sigindices.as_ptr(), - dynamic_sigindice_count: run.dynamic_sigindices.len() as u32, + dynamic_sigindices: load.dynamic_sigindices.as_ptr(), + dynamic_sigindice_count: load.dynamic_sigindices.len() as u32, + }; + let fd = dev.as_raw_fd(); + let ret = unsafe { + ::libc::ioctl( + fd, + Command::LoadCode as i32 as ::libc::c_ulong, + &req as *const _ as ::libc::c_ulong + ) + }; + if ret != 0 { + Err(ServiceError::Code(ret)) + } else { + Ok(ServiceContext { + dev: dev, + }) + } + } + + pub fn run_code(&mut self, run: RunProfile) -> ServiceResult { + let req = RunCodeRequest { + entry_offset: run.entry_offset, params: run.params.as_ptr(), param_count: run.params.len() as u32, - entry_offset: run.entry_offset, }; let fd = self.dev.as_raw_fd(); let ret = unsafe {