Split load/run

This commit is contained in:
Heyang Zhou 2019-05-05 05:03:07 -07:00
parent 3c64bd009e
commit cc01e40dc5
2 changed files with 69 additions and 52 deletions

View File

@ -8,7 +8,7 @@ use wasmer_runtime_core::{
types::{Value, LocalMemoryIndex, LocalTableIndex, ImportedMemoryIndex, ImportedTableIndex}, types::{Value, LocalMemoryIndex, LocalTableIndex, ImportedMemoryIndex, ImportedTableIndex},
structures::TypedIndex, structures::TypedIndex,
}; };
use service::{ServiceContext, RunProfile, TableEntryRequest}; use service::{ServiceContext, LoadProfile, RunProfile, TableEntryRequest};
pub struct KernelLoader; pub struct KernelLoader;
@ -22,7 +22,7 @@ impl Loader for KernelLoader {
let memory = if let Some(_) = module.memories.get(LocalMemoryIndex::new(0)) { let memory = if let Some(_) = module.memories.get(LocalMemoryIndex::new(0)) {
Some(unsafe { Some(unsafe {
::std::slice::from_raw_parts((**ctx.memories).base, (**ctx.memories).bound) ::std::slice::from_raw_parts((**ctx.memories).base, (**ctx.memories).bound)
}.to_vec()) })
} else if let Some(_) = module.imported_memories.get(ImportedMemoryIndex::new(0)) { } else if let Some(_) = module.imported_memories.get(ImportedMemoryIndex::new(0)) {
return Err("imported memory is not supported".into()); return Err("imported memory is not supported".into());
} else { } 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)); let name = format!("{}##{}", module.namespace_table.get(import.namespace_index), module.name_table.get(import.name_index));
import_names.push(name); import_names.push(name);
} }
Ok(KernelInstance { let dynamic_sigindices: &[u32] = unsafe {
context: ServiceContext::connect().map_err(|x| format!("{:?}", x))?, ::std::mem::transmute::<&[SigId], &[u32]>(
code: code.to_vec(),
memory: memory,
table: table,
globals: globals,
offsets: rm.get_offsets().unwrap(),
import_names: import_names,
dynamic_sigindices: unsafe {
::std::slice::from_raw_parts(ctx.dynamic_sigindices, full_ctx.dynamic_sigindice_count()) ::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 { pub struct KernelInstance {
context: ServiceContext, context: ServiceContext,
code: Vec<u8>,
memory: Option<Vec<u8>>,
table: Option<Vec<TableEntryRequest>>,
globals: Vec<u64>,
offsets: Vec<usize>, offsets: Vec<usize>,
import_names: Vec<String>,
dynamic_sigindices: Vec<u32>,
} }
impl Instance for KernelInstance { impl Instance for KernelInstance {
@ -95,15 +96,8 @@ impl Instance for KernelInstance {
let args: Vec<u64> = args.iter().map(|x| x.to_u64()).collect(); let args: Vec<u64> = args.iter().map(|x| x.to_u64()).collect();
let ret = self.context.run_code(RunProfile { 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, entry_offset: self.offsets[id] as u32,
imports: &self.import_names, params: &args,
dynamic_sigindices: &self.dynamic_sigindices,
table: self.table.as_ref().map(|x| x.as_slice()),
}).map_err(|x| format!("{:?}", x))?; }).map_err(|x| format!("{:?}", x))?;
Ok(ret as u64) Ok(ret as u64)
} }

View File

@ -15,12 +15,14 @@ macro_rules! impl_debug_display {
#[repr(i32)] #[repr(i32)]
pub enum Command { pub enum Command {
RunCode = 0x1001, LoadCode = 0x1001,
RunCode = 0x1002,
} }
#[derive(Debug)] #[derive(Debug)]
pub enum ServiceError { pub enum ServiceError {
Io(io::Error), Io(io::Error),
Code(i32),
InvalidInput, InvalidInput,
Rejected Rejected
} }
@ -42,7 +44,7 @@ impl From<io::Error> for ServiceError {
} }
#[repr(C)] #[repr(C)]
struct RunCodeRequest { struct LoadCodeRequest {
code: *const u8, code: *const u8,
code_len: u32, code_len: u32,
memory: *const u8, memory: *const u8,
@ -58,7 +60,10 @@ struct RunCodeRequest {
dynamic_sigindices: *const u32, dynamic_sigindices: *const u32,
dynamic_sigindice_count: u32, dynamic_sigindice_count: u32,
}
#[repr(C)]
struct RunCodeRequest {
entry_offset: u32, entry_offset: u32,
params: *const u64, params: *const u64,
param_count: u32, param_count: u32,
@ -75,31 +80,29 @@ pub struct TableEntryRequest {
pub sig_id: u32, pub sig_id: u32,
} }
pub struct RunProfile<'a> { pub struct LoadProfile<'a> {
pub code: &'a [u8], pub code: &'a [u8],
pub memory: Option<&'a [u8]>, pub memory: Option<&'a [u8]>,
pub memory_max: usize, pub memory_max: usize,
pub globals: &'a [u64], pub globals: &'a [u64],
pub params: &'a [u64],
pub entry_offset: u32,
pub imports: &'a [String], pub imports: &'a [String],
pub dynamic_sigindices: &'a [u32], pub dynamic_sigindices: &'a [u32],
pub table: Option<&'a [TableEntryRequest]>, pub table: Option<&'a [TableEntryRequest]>,
} }
pub struct RunProfile<'a> {
pub entry_offset: u32,
pub params: &'a [u64],
}
pub struct ServiceContext { pub struct ServiceContext {
dev: File dev: File
} }
impl ServiceContext { impl ServiceContext {
pub fn connect() -> ServiceResult<ServiceContext> { pub fn new(load: LoadProfile) -> ServiceResult<ServiceContext> {
Ok(ServiceContext { let dev = File::open("/dev/wasmctl")?;
dev: File::open("/dev/wasmctl")? let imports: Vec<ImportRequest> = load.imports.iter().map(|x| {
})
}
pub fn run_code(&mut self, run: RunProfile) -> ServiceResult<i32> {
let imports: Vec<ImportRequest> = run.imports.iter().map(|x| {
let mut req: ImportRequest = unsafe { ::std::mem::zeroed() }; let mut req: ImportRequest = unsafe { ::std::mem::zeroed() };
let x = x.as_bytes(); let x = x.as_bytes();
let mut count = req.name.len() - 1; let mut count = req.name.len() - 1;
@ -109,23 +112,43 @@ impl ServiceContext {
req.name[..count].copy_from_slice(&x[..count]); req.name[..count].copy_from_slice(&x[..count]);
req req
}).collect(); }).collect();
let req = RunCodeRequest { let req = LoadCodeRequest {
code: run.code.as_ptr(), code: load.code.as_ptr(),
code_len: run.code.len() as u32, code_len: load.code.len() as u32,
memory: run.memory.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()), memory: load.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_len: load.memory.map(|x| x.len() as u32).unwrap_or(0),
memory_max: run.memory_max as u32, memory_max: load.memory_max as u32,
table: run.table.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()), table: load.table.map(|x| x.as_ptr()).unwrap_or(::std::ptr::null()),
table_count: run.table.map(|x| x.len() as u32).unwrap_or(0), table_count: load.table.map(|x| x.len() as u32).unwrap_or(0),
globals: run.globals.as_ptr(), globals: load.globals.as_ptr(),
global_count: run.globals.len() as u32, global_count: load.globals.len() as u32,
imported_funcs: imports.as_ptr(), imported_funcs: imports.as_ptr(),
imported_func_count: imports.len() as u32, imported_func_count: imports.len() as u32,
dynamic_sigindices: run.dynamic_sigindices.as_ptr(), dynamic_sigindices: load.dynamic_sigindices.as_ptr(),
dynamic_sigindice_count: run.dynamic_sigindices.len() as u32, 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<i32> {
let req = RunCodeRequest {
entry_offset: run.entry_offset,
params: run.params.as_ptr(), params: run.params.as_ptr(),
param_count: run.params.len() as u32, param_count: run.params.len() as u32,
entry_offset: run.entry_offset,
}; };
let fd = self.dev.as_raw_fd(); let fd = self.dev.as_raw_fd();
let ret = unsafe { let ret = unsafe {