Added support for conditional emscripten

This commit is contained in:
Syrus Akbary 2018-11-28 13:25:08 -08:00
parent 1f49f0358f
commit 02477b6e5e
7 changed files with 48 additions and 25 deletions

View File

@ -45,7 +45,7 @@ pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
unsafe {
let passwd = &*libc_getpwnam(name.as_ptr());
let passwd_struct_offset =
(instance.emscripten_data.malloc)(mem::size_of::<GuestPasswd>() as _, instance);
(instance.emscripten_data.as_ref().unwrap().malloc)(mem::size_of::<GuestPasswd>() as _, instance);
let passwd_struct_ptr =
instance.memory_offset_addr(0, passwd_struct_offset as _) as *mut GuestPasswd;
@ -80,7 +80,7 @@ pub extern "C" fn _getgrnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
unsafe {
let group = &*libc_getgrnam(name.as_ptr());
let group_struct_offset =
(instance.emscripten_data.malloc)(mem::size_of::<GuestGroup>() as _, instance);
(instance.emscripten_data.as_ref().unwrap().malloc)(mem::size_of::<GuestGroup>() as _, instance);
let group_struct_ptr =
instance.memory_offset_addr(0, group_struct_offset as _) as *mut GuestGroup;

View File

@ -52,6 +52,10 @@ fn dynamictop_ptr(static_bump: u32) -> u32 {
pub fn emscripten_set_up_memory(memory: &mut LinearMemory) {
let dynamictop_ptr = dynamictop_ptr(STATIC_BUMP) as usize;
// We avoid failures of setting the u32
if (dynamictop_ptr > memory.len()) {
return;
}
let mem = &mut memory[dynamictop_ptr..dynamictop_ptr + mem::size_of::<u32>()];
LittleEndian::write_u32(mem, dynamic_base(STATIC_BUMP));
}

View File

@ -87,7 +87,7 @@ pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int {
// Webassembly allocation
let tm_struct_offset =
(instance.emscripten_data.malloc)(mem::size_of::<GuestTm>() as _, instance);
(instance.emscripten_data.as_ref().unwrap().malloc)(mem::size_of::<GuestTm>() as _, instance);
let tm_struct_ptr = instance.memory_offset_addr(0, tm_struct_offset as _) as *mut GuestTm;
// Initializing

View File

@ -18,7 +18,7 @@ pub fn is_emscripten_module(module: &Module) -> bool {
pub unsafe fn copy_cstr_into_wasm(instance: &mut Instance, cstr: *const c_char) -> u32 {
let s = CStr::from_ptr(cstr).to_str().unwrap();
let space_offset = (instance.emscripten_data.malloc)(s.len() as _, instance);
let space_offset = (instance.emscripten_data.as_ref().unwrap().malloc)(s.len() as _, instance);
let raw_memory = instance.memory_offset_addr(0, space_offset as _) as *mut u8;
let slice = slice::from_raw_parts_mut(raw_memory, s.len());

View File

@ -61,7 +61,7 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> {
webassembly::instantiate(wasm_binary, import_object)
.map_err(|err| format!("Can't instantiate the WebAssembly module: {}", err))?;
if apis::is_emscripten_module(&module) {
if instance.emscripten_data.as_ref().is_some() {
let func_index = match module.info.exports.get("_main") {
Some(&webassembly::Export::Function(index)) => index,
_ => panic!("_main emscripten function not found"),

View File

@ -111,7 +111,7 @@ pub struct Instance {
pub start_func: Option<FuncIndex>,
// Region start memory location
// code_base: *const (),
pub emscripten_data: EmscriptenData,
pub emscripten_data: Option<EmscriptenData>,
}
/// Contains pointers to data (heaps, globals, tables) needed
@ -135,6 +135,7 @@ pub struct InstanceOptions {
pub mock_missing_imports: bool,
pub mock_missing_globals: bool,
pub mock_missing_tables: bool,
pub use_emscripten: bool,
pub isa: Box<TargetIsa>,
}
@ -478,7 +479,11 @@ impl Instance {
let to_init = &mut mem[offset..offset + init.data.len()];
to_init.copy_from_slice(&init.data);
}
crate::apis::emscripten::emscripten_set_up_memory(&mut memories[0]);
if options.use_emscripten {
debug!("emscripten::setup memory");
crate::apis::emscripten::emscripten_set_up_memory(&mut memories[0]);
debug!("emscripten::finish setup memory");
}
}
let start_func: Option<FuncIndex> =
@ -504,27 +509,39 @@ impl Instance {
tables: tables_pointer[..].into(),
};
let emscripten_data = unsafe {
let malloc_index =
if let Some(Export::Function(index)) = module.info.exports.get("_malloc") {
index
} else {
panic!("Unable to find _malloc export")
};
let malloc_addr = get_function_addr(&malloc_index, &import_functions, &functions);
let emscripten_data = if options.use_emscripten {
unsafe {
debug!("emscripten::initiating data");
let malloc_export = module.info.exports.get("_malloc");
let free_export = module.info.exports.get("_free");
if malloc_export.is_none() || free_export.is_none() {
None
}
else {
let malloc_index = if let Some(Export::Function(malloc_index)) = malloc_export {
malloc_index
}
else {
panic!("Expected malloc function")
};
let malloc_addr = get_function_addr(&malloc_index, &import_functions, &functions);
let free_index = if let Some(Export::Function(index)) = module.info.exports.get("_free")
{
index
} else {
panic!("Unable to find _free export")
};
let free_addr = get_function_addr(&free_index, &import_functions, &functions);
let free_index = if let Some(Export::Function(free_index)) = free_export {
free_index
}
else {
panic!("Expected free export function")
};
let free_addr = get_function_addr(&free_index, &import_functions, &functions);
EmscriptenData {
malloc: mem::transmute(malloc_addr),
free: mem::transmute(free_addr),
Some(EmscriptenData {
malloc: mem::transmute(malloc_addr),
free: mem::transmute(free_addr),
})
}
}
} else {
None
};
Ok(Instance {

View File

@ -22,6 +22,7 @@ pub use self::import_object::{ImportObject, ImportValue};
pub use self::instance::{Instance, InstanceOptions};
pub use self::memory::LinearMemory;
pub use self::module::{Export, Module, ModuleInfo};
use crate::apis::is_emscripten_module;
pub struct ResultObject {
/// A webassembly::Module object representing the compiled WebAssembly module.
@ -69,6 +70,7 @@ pub fn instantiate(
mock_missing_imports: true,
mock_missing_globals: true,
mock_missing_tables: true,
use_emscripten: is_emscripten_module(&module),
isa: isa,
},
)?;