This commit is contained in:
Heyang Zhou 2019-05-04 09:56:52 -07:00
parent c4e4efc694
commit a590d7cd07
5 changed files with 65 additions and 13 deletions

View File

@ -3,12 +3,12 @@ pub mod service;
use wasmer_runtime_core::{
loader::{self, Loader, Instance},
backend::RunnableModule,
vm::{InternalCtx, LocalGlobal},
vm::{Ctx, LocalGlobal, SigId, Anyfunc},
module::ModuleInfo,
types::{Value, LocalMemoryIndex, ImportedMemoryIndex},
types::{Value, LocalMemoryIndex, LocalTableIndex, ImportedMemoryIndex, ImportedTableIndex},
structures::TypedIndex,
};
use service::{ServiceContext, RunProfile};
use service::{ServiceContext, RunProfile, TableEntryRequest};
pub struct KernelLoader;
@ -16,7 +16,8 @@ impl Loader for KernelLoader {
type Instance = KernelInstance;
type Error = String;
fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &InternalCtx) -> Result<Self::Instance, Self::Error> {
fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, full_ctx: &Ctx) -> Result<Self::Instance, Self::Error> {
let ctx = &full_ctx.internal;
let code = rm.get_code().unwrap();
let memory = if let Some(_) = module.memories.get(LocalMemoryIndex::new(0)) {
Some(unsafe {
@ -27,6 +28,29 @@ impl Loader for KernelLoader {
} else {
None
};
let table: Option<Vec<TableEntryRequest>> = if let Some(_) = module.tables.get(LocalTableIndex::new(0)) {
Some(unsafe {
let table = &**ctx.tables;
let elements: &[Anyfunc] = ::std::slice::from_raw_parts(table.base as *const Anyfunc, table.count);
let base_addr = code.as_ptr() as usize;
let end_addr = base_addr + code.len();
elements.iter().map(|x| {
let func_addr = x.func as usize;
TableEntryRequest {
offset: if x.func.is_null() || func_addr < base_addr || func_addr >= end_addr {
::std::usize::MAX
} else {
x.func as usize - base_addr
},
sig_id: x.sig_id.0,
}
}).collect()
})
} else if let Some(_) = module.imported_tables.get(ImportedTableIndex::new(0)) {
return Err("imported table is not supported".into());
} else {
None
};
if module.imported_globals.len() > 0 {
return Err("imported globals are not supported".into());
}
@ -43,9 +67,13 @@ impl Loader for KernelLoader {
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 {
::std::slice::from_raw_parts(ctx.dynamic_sigindices, full_ctx.dynamic_sigindice_count())
}.iter().map(|x| x.0).collect(),
})
}
}
@ -54,9 +82,11 @@ pub struct KernelInstance {
context: ServiceContext,
code: Vec<u8>,
memory: Option<Vec<u8>>,
table: Option<Vec<TableEntryRequest>>,
globals: Vec<u64>,
offsets: Vec<usize>,
import_names: Vec<String>,
dynamic_sigindices: Vec<u32>,
}
impl Instance for KernelInstance {
@ -72,6 +102,8 @@ impl Instance for KernelInstance {
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()),
}).map_err(|x| format!("{:?}", x))?;
Ok(ret as u64)
}

View File

@ -48,7 +48,7 @@ struct RunCodeRequest {
memory: *const u8,
memory_len: u32,
memory_max: u32,
table: *const u32,
table: *const TableEntryRequest,
table_count: u32,
globals: *const u64,
global_count: u32,
@ -56,6 +56,9 @@ struct RunCodeRequest {
imported_funcs: *const ImportRequest,
imported_func_count: u32,
dynamic_sigindices: *const u32,
dynamic_sigindice_count: u32,
entry_offset: u32,
params: *const u64,
param_count: u32,
@ -66,6 +69,12 @@ struct ImportRequest {
name: [u8; 64],
}
#[repr(C)]
pub struct TableEntryRequest {
pub offset: usize,
pub sig_id: u32,
}
pub struct RunProfile<'a> {
pub code: &'a [u8],
pub memory: Option<&'a [u8]>,
@ -73,7 +82,9 @@ pub struct RunProfile<'a> {
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 table: Option<&'a [TableEntryRequest]>,
}
pub struct ServiceContext {
@ -104,12 +115,14 @@ impl ServiceContext {
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: ::std::ptr::null(),
table_count: 0,
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,
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,
params: run.params.as_ptr(),
param_count: run.params.len() as u32,
entry_offset: run.entry_offset,

View File

@ -130,7 +130,7 @@ impl Instance {
}
pub fn load<T: Loader>(&self, loader: T) -> ::std::result::Result<T::Instance, T::Error> {
loader.load(&*self.module.runnable_module, &self.module.info, unsafe { &(*self.inner.vmctx).internal })
loader.load(&*self.module.runnable_module, &self.module.info, unsafe { &*self.inner.vmctx })
}
/// Through generic magic and the awe-inspiring power of traits, we bring you...

View File

@ -4,7 +4,7 @@ use std::{
};
use crate::{
backend::RunnableModule,
vm::InternalCtx,
vm::Ctx,
module::ModuleInfo,
types::Value,
};
@ -17,7 +17,7 @@ pub trait Loader {
type Instance: Instance;
type Error: Debug;
fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &InternalCtx) -> Result<Self::Instance, Self::Error>;
fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &Ctx) -> Result<Self::Instance, Self::Error>;
}
pub trait Instance {
@ -31,7 +31,7 @@ impl Loader for LocalLoader {
type Instance = LocalInstance;
type Error = String;
fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &InternalCtx) -> Result<Self::Instance, Self::Error> {
fn load(&self, rm: &dyn RunnableModule, module: &ModuleInfo, ctx: &Ctx) -> Result<Self::Instance, Self::Error> {
let code = rm.get_code().unwrap();
let mut code_mem = CodeMemory::new(code.len());
code_mem[..code.len()].copy_from_slice(code);

View File

@ -16,7 +16,7 @@ use hashbrown::HashMap;
#[repr(C)]
pub struct Ctx {
// `internal` must be the first field of `Ctx`.
pub(crate) internal: InternalCtx,
pub internal: InternalCtx,
pub(crate) local_functions: *const *const Func,
@ -163,6 +163,13 @@ impl Ctx {
pub unsafe fn borrow_symbol_map(&self) -> &Option<HashMap<u32, String>> {
&(*self.module).info.em_symbol_map
}
/// Returns the number of dynamic sigindices.
pub fn dynamic_sigindice_count(&self) -> usize {
unsafe {
(*self.local_backing).dynamic_sigindices.len()
}
}
}
#[doc(hidden)]