kwasm imports

This commit is contained in:
Heyang Zhou 2019-05-04 08:28:13 -07:00
parent af0b1476f3
commit c4e4efc694
5 changed files with 46 additions and 5 deletions

View File

@ -34,12 +34,18 @@ impl Loader for KernelLoader {
let globals: &[*mut LocalGlobal] = ::std::slice::from_raw_parts(ctx.globals, module.globals.len()); let globals: &[*mut LocalGlobal] = ::std::slice::from_raw_parts(ctx.globals, module.globals.len());
globals.iter().map(|x| (**x).data).collect() globals.iter().map(|x| (**x).data).collect()
}; };
let mut import_names: Vec<String> = vec![];
for (_, import) in &module.imported_functions {
let name = format!("{}##{}", module.namespace_table.get(import.namespace_index), module.name_table.get(import.name_index));
import_names.push(name);
}
Ok(KernelInstance { Ok(KernelInstance {
context: ServiceContext::connect().map_err(|x| format!("{:?}", x))?, context: ServiceContext::connect().map_err(|x| format!("{:?}", x))?,
code: code.to_vec(), code: code.to_vec(),
memory: memory, memory: memory,
globals: globals, globals: globals,
offsets: rm.get_offsets().unwrap(), offsets: rm.get_offsets().unwrap(),
import_names: import_names,
}) })
} }
} }
@ -50,6 +56,7 @@ pub struct KernelInstance {
memory: Option<Vec<u8>>, memory: Option<Vec<u8>>,
globals: Vec<u64>, globals: Vec<u64>,
offsets: Vec<usize>, offsets: Vec<usize>,
import_names: Vec<String>,
} }
impl Instance for KernelInstance { impl Instance for KernelInstance {
@ -64,6 +71,7 @@ impl Instance for KernelInstance {
globals: &self.globals, globals: &self.globals,
params: &args, params: &args,
entry_offset: self.offsets[id] as u32, entry_offset: self.offsets[id] as u32,
imports: &self.import_names,
}).map_err(|x| format!("{:?}", x))?; }).map_err(|x| format!("{:?}", x))?;
Ok(ret as u64) Ok(ret as u64)
} }

View File

@ -53,11 +53,19 @@ struct RunCodeRequest {
globals: *const u64, globals: *const u64,
global_count: u32, global_count: u32,
imported_funcs: *const ImportRequest,
imported_func_count: u32,
entry_offset: u32, entry_offset: u32,
params: *const u64, params: *const u64,
param_count: u32, param_count: u32,
} }
#[repr(C)]
struct ImportRequest {
name: [u8; 64],
}
pub struct RunProfile<'a> { pub struct RunProfile<'a> {
pub code: &'a [u8], pub code: &'a [u8],
pub memory: Option<&'a [u8]>, pub memory: Option<&'a [u8]>,
@ -65,6 +73,7 @@ pub struct RunProfile<'a> {
pub globals: &'a [u64], pub globals: &'a [u64],
pub params: &'a [u64], pub params: &'a [u64],
pub entry_offset: u32, pub entry_offset: u32,
pub imports: &'a [String]
} }
pub struct ServiceContext { pub struct ServiceContext {
@ -79,6 +88,16 @@ impl ServiceContext {
} }
pub fn run_code(&mut self, run: RunProfile) -> ServiceResult<i32> { 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 x = x.as_bytes();
let mut count = req.name.len() - 1;
if x.len() < count {
count = x.len();
}
req.name[..count].copy_from_slice(&x[..count]);
req
}).collect();
let req = RunCodeRequest { let req = RunCodeRequest {
code: run.code.as_ptr(), code: run.code.as_ptr(),
code_len: run.code.len() as u32, code_len: run.code.len() as u32,
@ -89,6 +108,8 @@ impl ServiceContext {
table_count: 0, table_count: 0,
globals: run.globals.as_ptr(), globals: run.globals.as_ptr(),
global_count: run.globals.len() as u32, global_count: run.globals.len() as u32,
imported_funcs: imports.as_ptr(),
imported_func_count: imports.len() as u32,
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, entry_offset: run.entry_offset,

View File

@ -449,10 +449,17 @@ fn import_functions(
}); });
} }
None => { None => {
link_errors.push(LinkError::ImportNotFound { if imports.allow_missing_functions {
namespace: namespace.to_string(), functions.push(vm::ImportedFunc {
name: name.to_string(), func: ::std::ptr::null(),
}); vmctx: ::std::ptr::null_mut(),
});
} else {
link_errors.push(LinkError::ImportNotFound {
namespace: namespace.to_string(),
name: name.to_string(),
});
}
} }
} }
} }

View File

@ -47,6 +47,7 @@ impl IsExport for Export {
pub struct ImportObject { pub struct ImportObject {
map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>, map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>,
state_creator: Option<Rc<Fn() -> (*mut c_void, fn(*mut c_void))>>, state_creator: Option<Rc<Fn() -> (*mut c_void, fn(*mut c_void))>>,
pub allow_missing_functions: bool,
} }
impl ImportObject { impl ImportObject {
@ -55,6 +56,7 @@ impl ImportObject {
Self { Self {
map: Rc::new(RefCell::new(HashMap::new())), map: Rc::new(RefCell::new(HashMap::new())),
state_creator: None, state_creator: None,
allow_missing_functions: false,
} }
} }
@ -65,6 +67,7 @@ impl ImportObject {
Self { Self {
map: Rc::new(RefCell::new(HashMap::new())), map: Rc::new(RefCell::new(HashMap::new())),
state_creator: Some(Rc::new(state_creator)), state_creator: Some(Rc::new(state_creator)),
allow_missing_functions: false,
} }
} }
@ -116,6 +119,7 @@ impl ImportObject {
Self { Self {
map: Rc::clone(&self.map), map: Rc::clone(&self.map),
state_creator: self.state_creator.clone(), state_creator: self.state_creator.clone(),
allow_missing_functions: false,
} }
} }

View File

@ -339,7 +339,8 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
}; };
if let Some(loader) = options.loader { if let Some(loader) = options.loader {
let import_object = wasmer_runtime_core::import::ImportObject::new(); let mut import_object = wasmer_runtime_core::import::ImportObject::new();
import_object.allow_missing_functions = true; // Import initialization might be left to the loader.
let instance = module let instance = module
.instantiate(&import_object) .instantiate(&import_object)
.map_err(|e| format!("Can't instantiate module: {:?}", e))?; .map_err(|e| format!("Can't instantiate module: {:?}", e))?;