Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Emscripten debugging + optipng #422

Merged
merged 13 commits into from
May 6, 2019
42 changes: 36 additions & 6 deletions lib/emscripten/src/env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,51 @@ pub fn ___build_environment(ctx: &mut Ctx, environ: c_int) {
const MAX_ENV_VALUES: u32 = 64;
const TOTAL_ENV_SIZE: u32 = 1024;
let environment = emscripten_memory_pointer!(ctx.memory(0), environ) as *mut c_int;
unsafe {
let (mut pool_offset, env_ptr, mut pool_ptr) = unsafe {
let (pool_offset, _pool_slice): (u32, &mut [u8]) =
allocate_on_stack(ctx, TOTAL_ENV_SIZE as u32);
let (env_offset, _env_slice): (u32, &mut [u8]) =
allocate_on_stack(ctx, (MAX_ENV_VALUES * 4) as u32);
let env_ptr = emscripten_memory_pointer!(ctx.memory(0), env_offset) as *mut c_int;
let mut _pool_ptr = emscripten_memory_pointer!(ctx.memory(0), pool_offset) as *mut c_int;
let pool_ptr = emscripten_memory_pointer!(ctx.memory(0), pool_offset) as *mut u8;
*env_ptr = pool_offset as i32;
*environment = env_offset as i32;

// *env_ptr = 0;
(pool_offset, env_ptr, pool_ptr)
};
// unsafe {
// *env_ptr = 0;
// };

// *env_ptr = 0;
let default_vars = vec![
["USER", "web_user"],
["LOGNAME", "web_user"],
["PATH", "/"],
["PWD", "/"],
["HOME", "/home/web_user"],
["LANG", "C.UTF-8"],
["_", "thisProgram"],
];
let mut strings = vec![];
let mut total_size = 0;
for [key, val] in &default_vars {
let line = key.to_string() + "=" + val;
total_size += line.len();
strings.push(line);
}
if total_size as u32 > TOTAL_ENV_SIZE {
panic!("Environment size exceeded TOTAL_ENV_SIZE!");
}
unsafe {
for (i, s) in strings.iter().enumerate() {
for (j, c) in s.chars().enumerate() {
debug_assert!(c < u8::max_value() as char);
*pool_ptr.add(j) = c as u8;
}
*env_ptr.add(i * 4) = pool_offset as i32;
pool_offset += s.len() as u32 + 1;
pool_ptr = pool_ptr.add(s.len() + 1);
}
*env_ptr.add(strings.len() * 4) = 0;
}
}

pub fn ___assert_fail(_ctx: &mut Ctx, _a: c_int, _b: c_int, _c: c_int, _d: c_int) {
Expand Down
2 changes: 1 addition & 1 deletion lib/emscripten/src/jmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use wasmer_runtime_core::vm::Ctx;
/// setjmp
pub fn __setjmp(ctx: &mut Ctx, _env_addr: u32) -> c_int {
debug!("emscripten::__setjmp (setjmp)");
abort_with_message(ctx, "missing function: _longjmp");
abort_with_message(ctx, "missing function: _setjmp");
unreachable!()
// unsafe {
// // Rather than using the env as the holder of the jump buffer pointer,
Expand Down
39 changes: 24 additions & 15 deletions lib/emscripten/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ pub fn run_emscripten_instance(
instance: &mut Instance,
path: &str,
args: Vec<&str>,
entrypoint: Option<String>,
) -> CallResult<()> {
let mut data = EmscriptenData::new(instance);
let data_ptr = &mut data as *mut _ as *mut c_void;
Expand All @@ -299,21 +300,29 @@ pub fn run_emscripten_instance(

// println!("running emscripten instance");

let main_func = instance.dyn_func("_main")?;
let num_params = main_func.signature().params().len();
let _result = match num_params {
2 => {
let (argc, argv) = store_module_arguments(instance.context_mut(), path, args);
instance.call("_main", &[Value::I32(argc as i32), Value::I32(argv as i32)])?;
}
0 => {
instance.call("_main", &[])?;
}
_ => panic!(
"The emscripten main function has received an incorrect number of params {}",
num_params
),
};
if let Some(ep) = entrypoint {
println!("RUnning entry point: {}", &ep);
let ep_fn = instance.dyn_func(&ep)?;
let arg = unsafe { allocate_cstr_on_stack(instance.context_mut(), args[0]).0 };
//let (argc, argv) = store_module_arguments(instance.context_mut(), path, args);
instance.call(&ep, &[Value::I32(arg as i32)])?;
} else {
let main_func = instance.dyn_func("_main")?;
let num_params = main_func.signature().params().len();
let _result = match num_params {
2 => {
let (argc, argv) = store_module_arguments(instance.context_mut(), path, args);
instance.call("_main", &[Value::I32(argc as i32), Value::I32(argv as i32)])?;
}
0 => {
instance.call("_main", &[])?;
}
_ => panic!(
"The emscripten main function has received an incorrect number of params {}",
num_params
),
};
}

// TODO atexit for emscripten
// println!("{:?}", data);
Expand Down
7 changes: 5 additions & 2 deletions lib/emscripten/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ pub fn _emscripten_memcpy_big(ctx: &mut Ctx, dest: u32, src: u32, len: u32) -> u

/// emscripten: _emscripten_get_heap_size
pub fn _emscripten_get_heap_size(ctx: &mut Ctx) -> u32 {
debug!("emscripten::_emscripten_get_heap_size",);
ctx.memory(0).size().bytes().0 as u32
debug!("emscripten::_emscripten_get_heap_size");
let result = ctx.memory(0).size().bytes().0 as u32;
debug!("=> {}", result);

result
}

// From emscripten implementation
Expand Down
2 changes: 1 addition & 1 deletion lib/emscripten/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub fn _raise(_ctx: &mut Ctx, _one: i32) -> i32 {
}

pub fn _sem_init(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32) -> i32 {
debug!("emscripten::_sem_init");
debug!("emscripten::_sem_init: {}, {}, {}", _one, _two, _three);
0
}

Expand Down
16 changes: 13 additions & 3 deletions lib/emscripten/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,22 @@ pub fn ___syscall192(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
if fd == -1 {
let ptr = env::call_memalign(ctx, 16384, len);
if ptr == 0 {
return -1;
// ENOMEM
return -12;
}
let real_ptr = emscripten_memory_pointer!(ctx.memory(0), ptr) as *const u8;
env::call_memset(ctx, ptr, 0, len);
ptr as _
for i in 0..(len as usize) {
unsafe {
assert_eq!(*real_ptr.add(i), 0);
}
}
debug!("=> ptr: {}", ptr);
return ptr as i32;
} else {
-1
unimplemented!("temp during dev");
// return ENODEV
return -19;
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/bin/wasmer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ struct Run {
#[structopt(long = "em-symbol-map", parse(from_os_str), group = "emscripten")]
em_symbol_map: Option<PathBuf>,

/// Begin execution at the specified symbol
#[structopt(long = "with-entry-point")]
syrusakbary marked this conversation as resolved.
Show resolved Hide resolved
entrypoint: Option<String>,

/// WASI pre-opened directory
#[structopt(long = "dir", multiple = true, group = "wasi")]
pre_opened_directories: Vec<String>,
Expand Down Expand Up @@ -320,6 +324,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
options.path.to_str().unwrap()
},
options.args.iter().map(|arg| arg.as_str()).collect(),
options.entrypoint.clone(),
)
.map_err(|e| format!("{:?}", e))?;
} else {
Expand Down