mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 06:15:33 +00:00
Fix crashing cli args
This commit is contained in:
parent
485da4c701
commit
0e024aa722
@ -19,7 +19,7 @@ mod utils;
|
||||
mod varargs;
|
||||
|
||||
pub use self::storage::{align_memory, static_alloc};
|
||||
pub use self::utils::{is_emscripten_module, copy_cstr_array_into_wasm_stack};
|
||||
pub use self::utils::{is_emscripten_module, copy_cstr_array_into_wasm, allocate_on_stack, allocate_cstr_on_stack};
|
||||
|
||||
// TODO: Magic number - how is this calculated?
|
||||
const TOTAL_STACK: u32 = 5242880;
|
||||
|
@ -20,7 +20,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 cstr_len = s.len();
|
||||
let space_offset = (instance.emscripten_data.as_ref().unwrap().malloc)(cstr_len as _, instance);
|
||||
let space_offset = (instance.emscripten_data.as_ref().unwrap().malloc)((cstr_len as i32) + 1, instance);
|
||||
let raw_memory = instance.memory_offset_addr(0, space_offset as _) as *mut u8;
|
||||
let slice = slice::from_raw_parts_mut(raw_memory, cstr_len);
|
||||
|
||||
@ -33,18 +33,8 @@ pub unsafe fn copy_cstr_into_wasm(instance: &mut Instance, cstr: *const c_char)
|
||||
space_offset
|
||||
}
|
||||
|
||||
pub unsafe fn copy_cstr_into_wasm_stack(instance: &mut Instance, cstr: *const c_char) -> u32 {
|
||||
let s = CStr::from_ptr(cstr).to_str().unwrap();
|
||||
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 slice = slice::from_raw_parts_mut(raw_memory, cstr_len);
|
||||
|
||||
for (byte, loc) in s.bytes().zip(slice.iter_mut()) {
|
||||
*loc = byte;
|
||||
}
|
||||
|
||||
*raw_memory.add(cstr_len) = 0;
|
||||
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);
|
||||
|
||||
space_offset
|
||||
}
|
||||
@ -69,6 +59,25 @@ pub unsafe fn copy_cstr_array_into_wasm_stack(array_count: u32, array: *mut *mut
|
||||
array_offset
|
||||
}
|
||||
|
||||
pub unsafe fn allocate_on_stack<'a, T: Copy>(count: u32, instance: &'a Instance) -> (u32, &'a mut [T]) {
|
||||
let offset = (instance.emscripten_data.as_ref().unwrap().stack_alloc)(count * (size_of::<T>() as u32), instance);
|
||||
let addr = instance.memory_offset_addr(0, offset as _) as *mut T;
|
||||
let slice = slice::from_raw_parts_mut(addr, count as usize);
|
||||
|
||||
(offset, slice)
|
||||
}
|
||||
|
||||
pub unsafe fn allocate_cstr_on_stack<'a>(s: &str, instance: &'a Instance) -> (u32, &'a [u8]) {
|
||||
let (offset, slice) = allocate_on_stack((s.len() + 1) as u32, instance);
|
||||
|
||||
use std::iter;
|
||||
for (byte, loc) in s.bytes().chain(iter::once(0)).zip(slice.iter_mut()) {
|
||||
*loc = byte;
|
||||
}
|
||||
|
||||
(offset, slice)
|
||||
}
|
||||
|
||||
pub unsafe fn copy_terminated_array_of_cstrs(
|
||||
_instance: &mut Instance,
|
||||
cstrs: *mut *mut c_char,
|
||||
|
@ -7,7 +7,7 @@ use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
use std::process::exit;
|
||||
|
||||
use apis::emscripten::copy_cstr_array_into_wasm_stack;
|
||||
use apis::emscripten::{allocate_on_stack, allocate_cstr_on_stack};
|
||||
use structopt::StructOpt;
|
||||
|
||||
use wasmer::*;
|
||||
@ -91,7 +91,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
let main: extern "C" fn(u32, u32, &webassembly::Instance) =
|
||||
get_instance_function!(instance, func_index);
|
||||
|
||||
let (argc, argv) = get_module_arguments(options, &mut instance);
|
||||
let (argc, argv) = store_module_arguments(options, &mut instance);
|
||||
|
||||
return call_protected!(main(argc, argv, &instance)).map_err(|err| format!("{}", err));
|
||||
// TODO: We should implement emscripten __ATEXIT__
|
||||
@ -128,36 +128,53 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_module_arguments(options: &Run, instance: &mut webassembly::Instance) -> (u32, u32) {
|
||||
// Application Arguments
|
||||
let mut arg_values: Vec<String> = Vec::new();
|
||||
let mut arg_addrs: Vec<*const u8> = Vec::new();
|
||||
let arg_length = options.args.len() + 1;
|
||||
fn store_module_arguments(options: &Run, instance: &mut webassembly::Instance) -> (u32, u32) {
|
||||
let argc = options.args.len() + 1;
|
||||
|
||||
arg_values.reserve_exact(arg_length);
|
||||
arg_addrs.reserve_exact(arg_length);
|
||||
let (argv_offset, argv_slice): (_, &mut [u32]) = unsafe { allocate_on_stack(((argc + 1) * 4) as u32, instance) };
|
||||
assert!(argv_slice.len() >= 1);
|
||||
|
||||
// Push name of wasm file
|
||||
arg_values.push(format!("{}\0", options.path.to_str().unwrap()));
|
||||
arg_addrs.push(arg_values[0].as_ptr());
|
||||
argv_slice[0] = unsafe { allocate_cstr_on_stack(options.path.to_str().unwrap(), instance).0 };
|
||||
|
||||
// Push additional arguments
|
||||
for (i, arg) in options.args.iter().enumerate() {
|
||||
arg_values.push(format!("{}\0", arg));
|
||||
arg_addrs.push(arg_values[i + 1].as_ptr());
|
||||
for (slot, arg) in argv_slice[1..argc].iter_mut().zip(options.args.iter()) {
|
||||
*slot = unsafe { allocate_cstr_on_stack(&arg, instance).0 };
|
||||
}
|
||||
|
||||
// Get argument count and pointer to addresses
|
||||
let argv = arg_addrs.as_ptr() as *mut *mut i8;
|
||||
let argc = arg_length as u32;
|
||||
argv_slice[argc] = 0;
|
||||
|
||||
// Copy the the arguments into the wasm memory and get offset
|
||||
let argv_offset = unsafe {
|
||||
copy_cstr_array_into_wasm_stack(argc, argv, instance)
|
||||
};
|
||||
|
||||
debug!("argc = {:?}", argc);
|
||||
debug!("argv = {:?}", arg_addrs);
|
||||
|
||||
(argc, argv_offset)
|
||||
(argc as u32, argv_offset)
|
||||
}
|
||||
|
||||
// fn get_module_arguments(options: &Run, instance: &mut webassembly::Instance) -> (u32, u32) {
|
||||
// // Application Arguments
|
||||
// let mut arg_values: Vec<String> = Vec::new();
|
||||
// let mut arg_addrs: Vec<*const u8> = Vec::new();
|
||||
// let arg_length = options.args.len() + 1;
|
||||
|
||||
// arg_values.reserve_exact(arg_length);
|
||||
// arg_addrs.reserve_exact(arg_length);
|
||||
|
||||
// // Push name of wasm file
|
||||
// arg_values.push(format!("{}\0", options.path.to_str().unwrap()));
|
||||
// arg_addrs.push(arg_values[0].as_ptr());
|
||||
|
||||
// // Push additional arguments
|
||||
// for (i, arg) in options.args.iter().enumerate() {
|
||||
// arg_values.push(format!("{}\0", arg));
|
||||
// arg_addrs.push(arg_values[i + 1].as_ptr());
|
||||
// }
|
||||
|
||||
// // Get argument count and pointer to addresses
|
||||
// let argv = arg_addrs.as_ptr() as *mut *mut i8;
|
||||
// let argc = arg_length as u32;
|
||||
|
||||
// // Copy the the arguments into the wasm memory and get offset
|
||||
// let argv_offset = unsafe {
|
||||
// copy_cstr_array_into_wasm(argc, argv, instance)
|
||||
// };
|
||||
|
||||
// debug!("argc = {:?}", argc);
|
||||
// debug!("argv = {:?}", arg_addrs);
|
||||
|
||||
// (argc, argv_offset)
|
||||
// }
|
||||
|
@ -74,7 +74,7 @@ pub struct EmscriptenData {
|
||||
pub free: extern "C" fn(i32, &mut Instance),
|
||||
pub memalign: extern "C" fn (u32, 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,
|
||||
pub stack_alloc: extern "C" fn (u32, &Instance) -> u32,
|
||||
}
|
||||
|
||||
impl fmt::Debug for EmscriptenData {
|
||||
|
@ -9,7 +9,7 @@ use cranelift_codegen::cursor::FuncCursor;
|
||||
use cranelift_codegen::ir::immediates::{Imm64, Offset32};
|
||||
use cranelift_codegen::ir::types::*;
|
||||
use cranelift_codegen::ir::{
|
||||
self, AbiParam, ArgumentPurpose, ExtFuncData, ExternalName, FuncRef, InstBuilder, Signature,
|
||||
self, AbiParam, ArgumentPurpose, ExtFuncData, ExternalName, FuncRef, InstBuilder, Signature, TrapCode,
|
||||
};
|
||||
use cranelift_codegen::isa::{CallConv, TargetFrontendConfig};
|
||||
use cranelift_entity::{EntityRef, PrimaryMap};
|
||||
@ -532,6 +532,8 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> {
|
||||
mflags.set_aligned();
|
||||
let func_ptr = pos.ins().load(ptr, mflags, entry_addr, 0);
|
||||
|
||||
pos.ins().trapz(func_ptr, TrapCode::IndirectCallToNull);
|
||||
|
||||
// Build a value list for the indirect call instruction containing the callee, call_args,
|
||||
// and the vmctx parameter.
|
||||
let mut args = ir::ValueList::default();
|
||||
|
Loading…
Reference in New Issue
Block a user