From ab184aceeabe8e0156c7f543873eeeeacc44bbee Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Mon, 6 May 2019 14:05:04 -0700 Subject: [PATCH 1/2] Update emscripten to run JSC --- lib/emscripten/src/lib.rs | 17 +++++++++++----- lib/emscripten/src/time.rs | 4 +++- lib/emscripten/src/utils.rs | 38 +++++++++++++++++++++++++++++++++++ lib/runtime-core/src/types.rs | 2 +- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 48b970a03..e213b5048 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -50,7 +50,7 @@ mod varargs; pub use self::storage::{align_memory, static_alloc}; pub use self::utils::{ - allocate_cstr_on_stack, allocate_on_stack, get_emscripten_memory_size, + allocate_cstr_on_stack, allocate_on_stack, get_emscripten_memory_size, get_emscripten_metadata, get_emscripten_table_size, is_emscripten_module, }; @@ -351,9 +351,7 @@ fn store_module_arguments(ctx: &mut Ctx, args: Vec<&str>) -> (u32, u32) { pub fn emscripten_set_up_memory(memory: &Memory, globals: &EmscriptenGlobalsData) { let dynamictop_ptr = globals.dynamictop_ptr; - let stack_max = globals.stack_max; - - let dynamic_base = align_memory(stack_max); + let dynamic_base = globals.dynamic_base; memory.view::()[(dynamictop_ptr / 4) as usize].set(dynamic_base); } @@ -364,6 +362,7 @@ pub struct EmscriptenGlobalsData { stacktop: u32, stack_max: u32, dynamictop_ptr: u32, + dynamic_base: u32, memory_base: u32, table_base: u32, temp_double_ptr: u32, @@ -433,7 +432,14 @@ impl EmscriptenGlobals { let temp_double_ptr = static_top; static_top += 16; - let dynamictop_ptr = static_alloc(&mut static_top, 4); + let (dynamic_base, dynamictop_ptr) = + get_emscripten_metadata(&module).unwrap_or_else(|| { + let dynamictop_ptr = static_alloc(&mut static_top, 4); + ( + align_memory(align_memory(static_top) + TOTAL_STACK), + dynamictop_ptr, + ) + }); let stacktop = align_memory(static_top); let stack_max = stacktop + TOTAL_STACK; @@ -443,6 +449,7 @@ impl EmscriptenGlobals { stacktop, stack_max, dynamictop_ptr, + dynamic_base, memory_base, table_base, temp_double_ptr, diff --git a/lib/emscripten/src/time.rs b/lib/emscripten/src/time.rs index 56dfdbda8..32e7a61c6 100644 --- a/lib/emscripten/src/time.rs +++ b/lib/emscripten/src/time.rs @@ -28,7 +28,9 @@ use wasmer_runtime_core::vm::Ctx; use libc::{CLOCK_MONOTONIC, CLOCK_MONOTONIC_COARSE, CLOCK_REALTIME}; #[cfg(target_os = "macos")] -use libc::{CLOCK_MONOTONIC, CLOCK_REALTIME}; +use libc::CLOCK_REALTIME; +#[cfg(target_os = "macos")] +const CLOCK_MONOTONIC: clockid_t = 1; #[cfg(target_os = "macos")] const CLOCK_MONOTONIC_COARSE: clockid_t = 6; diff --git a/lib/emscripten/src/utils.rs b/lib/emscripten/src/utils.rs index e1cf13ef5..2ad5b9a40 100644 --- a/lib/emscripten/src/utils.rs +++ b/lib/emscripten/src/utils.rs @@ -1,5 +1,6 @@ use super::env; use super::env::get_emscripten_data; +use crate::storage::align_memory; use libc::stat; use std::ffi::CStr; use std::mem::size_of; @@ -39,6 +40,43 @@ pub fn get_emscripten_memory_size(module: &Module) -> (Pages, Option) { (memory.minimum, memory.maximum) } +/// Reads values written by `-s EMIT_EMSCRIPTEN_METADATA=1` +/// Assumes values start from the end in this order: +/// Last export: Dynamic Base +/// Second-to-Last export: Dynamic top pointer +pub fn get_emscripten_metadata(module: &Module) -> Option<(u32, u32)> { + let max_idx = &module.info().globals.iter().map(|(k, _)| k).max()?; + let snd_max_idx = &module + .info() + .globals + .iter() + .map(|(k, _)| k) + .filter(|k| k != max_idx) + .max()?; + + use wasmer_runtime_core::types::{GlobalInit, Initializer::Const, Value::I32}; + if let ( + GlobalInit { + init: Const(I32(dynamic_base)), + .. + }, + GlobalInit { + init: Const(I32(dynamictop_ptr)), + .. + }, + ) = ( + &module.info().globals[*max_idx], + &module.info().globals[*snd_max_idx], + ) { + Some(( + align_memory(*dynamic_base as u32 - 32), + align_memory(*dynamictop_ptr as u32 - 32), + )) + } else { + None + } +} + pub unsafe fn write_to_buf(ctx: &mut Ctx, string: *const c_char, buf: u32, max: u32) -> u32 { let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut c_char; diff --git a/lib/runtime-core/src/types.rs b/lib/runtime-core/src/types.rs index bf5df2183..23a1c8379 100644 --- a/lib/runtime-core/src/types.rs +++ b/lib/runtime-core/src/types.rs @@ -401,7 +401,7 @@ pub trait LocalImport { macro_rules! define_map_index { ($ty:ident) => { #[derive(Serialize, Deserialize)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct $ty (u32); impl TypedIndex for $ty { #[doc(hidden)] From 91d01d1c0521ffe3e2635593e0ad9a2f6d05bd24 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Mon, 6 May 2019 14:17:23 -0700 Subject: [PATCH 2/2] clean up warnings --- lib/emscripten/src/lib.rs | 1 - lib/emscripten/src/syscalls/mod.rs | 17 +++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index e213b5048..54cbad632 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -301,7 +301,6 @@ pub fn run_emscripten_instance( if let Some(ep) = entrypoint { debug!("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(), args); instance.call(&ep, &[Value::I32(arg as i32)])?; diff --git a/lib/emscripten/src/syscalls/mod.rs b/lib/emscripten/src/syscalls/mod.rs index a777628d3..72b04884f 100644 --- a/lib/emscripten/src/syscalls/mod.rs +++ b/lib/emscripten/src/syscalls/mod.rs @@ -127,14 +127,12 @@ pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 { let old_path = emscripten_memory_pointer!(ctx.memory(0), old_path_addr) as *const i8; let new_path = emscripten_memory_pointer!(ctx.memory(0), new_path_addr) as *const i8; let result = unsafe { rename(old_path, new_path) }; - unsafe { - debug!( - "=> old_path: {}, new_path: {}, result: {}", - std::ffi::CStr::from_ptr(old_path).to_str().unwrap(), - std::ffi::CStr::from_ptr(new_path).to_str().unwrap(), - result - ); - } + debug!( + "=> old_path: {}, new_path: {}, result: {}", + std::ffi::CStr::from_ptr(old_path).to_str().unwrap(), + std::ffi::CStr::from_ptr(new_path).to_str().unwrap(), + result + ); result } @@ -274,7 +272,6 @@ pub fn ___syscall192(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in debug!("=> ptr: {}", ptr); return ptr as i32; } else { - unimplemented!("temp during dev"); // return ENODEV return -19; } @@ -487,7 +484,7 @@ pub fn ___syscall300(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { } // utimensat -pub fn ___syscall320(ctx: &mut Ctx, _which: c_int, mut _varargs: VarArgs) -> c_int { +pub fn ___syscall320(_ctx: &mut Ctx, _which: c_int, mut _varargs: VarArgs) -> c_int { debug!("emscripten::___syscall320 (utimensat), {}", _which); 0 }