mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 22:25:40 +00:00
Stack allocate arguments
This commit is contained in:
parent
266ced4311
commit
28a668f38c
@ -17,30 +17,41 @@ pub fn is_emscripten_module(module: &Module) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn copy_cstr_into_wasm(instance: &Instance, cstr: *const c_char) -> u32 {
|
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 s = CStr::from_ptr(cstr).to_str().unwrap();
|
||||||
let space_offset = (instance.emscripten_data.as_ref().unwrap().malloc)(s.len() as _, instance);
|
let cstr_len = s.len();
|
||||||
|
let space_offset = (instance.emscripten_data.as_ref().unwrap().stack_alloc)((cstr_len as u32) + 1, instance);
|
||||||
let raw_memory = instance.memory_offset_addr(0, space_offset as _) as *mut u8;
|
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());
|
let slice = slice::from_raw_parts_mut(raw_memory, cstr_len);
|
||||||
|
|
||||||
for (byte, loc) in s.bytes().zip(slice.iter_mut()) {
|
for (byte, loc) in s.bytes().zip(slice.iter_mut()) {
|
||||||
*loc = byte;
|
*loc = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*raw_memory.add(cstr_len) = 0;
|
||||||
|
|
||||||
space_offset
|
space_offset
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn copy_cstr_array_into_wasm(array_count: u32, array: *mut *mut c_char, instance: &Instance) -> u32 {
|
pub unsafe fn copy_cstr_array_into_wasm(array_count: u32, array: *mut *mut c_char, instance: &mut Instance) -> u32 {
|
||||||
let array_offset = (instance.emscripten_data.as_ref().unwrap().malloc)((array_count as usize * size_of::<u32>()) as _, instance);
|
let array_offset = (instance.emscripten_data.as_ref().unwrap().stack_alloc)((array_count as usize * size_of::<u32>()) as _, instance);
|
||||||
|
|
||||||
let array_addr = instance.memory_offset_addr(0, array_offset as _) as *mut u32;
|
let array_addr = instance.memory_offset_addr(0, array_offset as _) as *mut u32;
|
||||||
for i in 0..array_count {
|
let array_slice = slice::from_raw_parts_mut(array_addr, array_count as usize);
|
||||||
let offset = copy_cstr_into_wasm(
|
|
||||||
instance,
|
for (i, ptr) in array_slice.iter_mut().enumerate() {
|
||||||
*array.offset(i as isize)
|
let offset = copy_cstr_into_wasm(instance, *array.add(i));
|
||||||
);
|
*ptr = offset;
|
||||||
*array_addr.offset(i as isize) = offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for i in 0..array_count {
|
||||||
|
// let offset = copy_cstr_into_wasm(
|
||||||
|
// instance,
|
||||||
|
// *array.offset(i as isize)
|
||||||
|
// );
|
||||||
|
// *array_addr.offset(i as isize) = offset;
|
||||||
|
// }
|
||||||
|
|
||||||
// let first_arg_addr = instance.memory_offset_addr(0, *array_addr.offset(0) as _) as *const i8;
|
// let first_arg_addr = instance.memory_offset_addr(0, *array_addr.offset(0) as _) as *const i8;
|
||||||
// debug!("###### argv[0] = {:?}", CStr::from_ptr(first_arg_addr));
|
// debug!("###### argv[0] = {:?}", CStr::from_ptr(first_arg_addr));
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
// TODO: We should instantiate after compilation, so we provide the
|
// TODO: We should instantiate after compilation, so we provide the
|
||||||
// emscripten environment conditionally based on the module
|
// emscripten environment conditionally based on the module
|
||||||
let import_object = apis::generate_emscripten_env();
|
let import_object = apis::generate_emscripten_env();
|
||||||
let webassembly::ResultObject { module, instance } =
|
let webassembly::ResultObject { module, mut instance } =
|
||||||
webassembly::instantiate(wasm_binary, import_object)
|
webassembly::instantiate(wasm_binary, import_object)
|
||||||
.map_err(|err| format!("Can't instantiate the WebAssembly module: {}", err))?;
|
.map_err(|err| format!("Can't instantiate the WebAssembly module: {}", err))?;
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
let main: extern "C" fn(u32, u32, &webassembly::Instance) =
|
let main: extern "C" fn(u32, u32, &webassembly::Instance) =
|
||||||
get_instance_function!(instance, func_index);
|
get_instance_function!(instance, func_index);
|
||||||
|
|
||||||
let (argc, argv) = get_module_arguments(options, &instance);
|
let (argc, argv) = get_module_arguments(options, &mut instance);
|
||||||
|
|
||||||
return call_protected!(main(argc, argv, &instance)).map_err(|err| format!("{}", err));
|
return call_protected!(main(argc, argv, &instance)).map_err(|err| format!("{}", err));
|
||||||
// TODO: We should implement emscripten __ATEXIT__
|
// TODO: We should implement emscripten __ATEXIT__
|
||||||
@ -128,7 +128,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_module_arguments(options: &Run, instance: &webassembly::Instance) -> (u32, u32) {
|
fn get_module_arguments(options: &Run, instance: &mut webassembly::Instance) -> (u32, u32) {
|
||||||
// Application Arguments
|
// Application Arguments
|
||||||
let mut arg_values: Vec<String> = Vec::new();
|
let mut arg_values: Vec<String> = Vec::new();
|
||||||
let mut arg_addrs: Vec<*const u8> = Vec::new();
|
let mut arg_addrs: Vec<*const u8> = Vec::new();
|
||||||
@ -153,7 +153,7 @@ fn get_module_arguments(options: &Run, instance: &webassembly::Instance) -> (u32
|
|||||||
|
|
||||||
// Copy the the arguments into the wasm memory and get offset
|
// Copy the the arguments into the wasm memory and get offset
|
||||||
let argv_offset = unsafe {
|
let argv_offset = unsafe {
|
||||||
copy_cstr_array_into_wasm(argc, argv, &instance)
|
copy_cstr_array_into_wasm(argc, argv, instance)
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("argc = {:?}", argc);
|
debug!("argc = {:?}", argc);
|
||||||
|
@ -74,6 +74,7 @@ pub struct EmscriptenData {
|
|||||||
pub free: extern "C" fn(i32, &mut Instance),
|
pub free: extern "C" fn(i32, &mut Instance),
|
||||||
pub memalign: extern "C" fn (u32, u32, &mut Instance) -> u32,
|
pub memalign: extern "C" fn (u32, u32, &mut Instance) -> u32,
|
||||||
pub memset: extern "C" fn(u32, i32, u32, &mut Instance) -> u32,
|
pub memset: extern "C" fn(u32, i32, u32, &mut Instance) -> u32,
|
||||||
|
pub stack_alloc: extern "C" fn (u32, &mut Instance) -> u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for EmscriptenData {
|
impl fmt::Debug for EmscriptenData {
|
||||||
@ -550,11 +551,13 @@ impl Instance {
|
|||||||
let free_export = module.info.exports.get("_free");
|
let free_export = module.info.exports.get("_free");
|
||||||
let memalign_export = module.info.exports.get("_memalign");
|
let memalign_export = module.info.exports.get("_memalign");
|
||||||
let memset_export = module.info.exports.get("_memset");
|
let memset_export = module.info.exports.get("_memset");
|
||||||
|
let stack_alloc_export = module.info.exports.get("stackAlloc");
|
||||||
|
|
||||||
let mut malloc_addr = 0 as *const u8;
|
let mut malloc_addr = 0 as *const u8;
|
||||||
let mut free_addr = 0 as *const u8;
|
let mut free_addr = 0 as *const u8;
|
||||||
let mut memalign_addr = 0 as *const u8;
|
let mut memalign_addr = 0 as *const u8;
|
||||||
let mut memset_addr = 0 as *const u8;
|
let mut memset_addr = 0 as *const u8;
|
||||||
|
let mut stack_alloc_addr = 0 as _;
|
||||||
|
|
||||||
if malloc_export.is_none() && free_export.is_none() && memalign_export.is_none() && memset_export.is_none() {
|
if malloc_export.is_none() && free_export.is_none() && memalign_export.is_none() && memset_export.is_none() {
|
||||||
None
|
None
|
||||||
@ -575,11 +578,16 @@ impl Instance {
|
|||||||
memset_addr = get_function_addr(&memset_index, &import_functions, &functions);
|
memset_addr = get_function_addr(&memset_index, &import_functions, &functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(Export::Function(stack_alloc_index)) = stack_alloc_export {
|
||||||
|
stack_alloc_addr = get_function_addr(&stack_alloc_index, &import_functions, &functions);
|
||||||
|
}
|
||||||
|
|
||||||
Some(EmscriptenData {
|
Some(EmscriptenData {
|
||||||
malloc: mem::transmute(malloc_addr),
|
malloc: mem::transmute(malloc_addr),
|
||||||
free: mem::transmute(free_addr),
|
free: mem::transmute(free_addr),
|
||||||
memalign: mem::transmute(memalign_addr),
|
memalign: mem::transmute(memalign_addr),
|
||||||
memset: mem::transmute(memset_addr),
|
memset: mem::transmute(memset_addr),
|
||||||
|
stack_alloc: mem::transmute(stack_alloc_addr),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user