Merge remote-tracking branch 'origin/master' into feature/add-mapdir-for-emscripten

This commit is contained in:
Mark McCaskey
2019-05-28 13:48:12 -07:00
19 changed files with 224 additions and 1194 deletions

View File

@ -10,6 +10,8 @@ pub use self::unix::*;
#[cfg(windows)]
pub use self::windows::*;
use libc::c_char;
use crate::{allocate_on_stack, EmscriptenData};
use std::os::raw::c_int;
use wasmer_runtime_core::vm::Ctx;
@ -112,3 +114,41 @@ pub fn ___assert_fail(_ctx: &mut Ctx, _a: c_int, _b: c_int, _c: c_int, _d: c_int
// TODO: Implement like emscripten expects regarding memory/page size
// TODO raise an error
}
pub fn _pathconf(ctx: &mut Ctx, path_addr: c_int, name: c_int) -> c_int {
debug!(
"emscripten::_pathconf {} {} - UNIMPLEMENTED",
path_addr, name
);
let _path = emscripten_memory_pointer!(ctx.memory(0), path_addr) as *const c_char;
match name {
0 => 32000,
1 | 2 | 3 => 255,
4 | 5 | 16 | 17 | 18 => 4096,
6 | 7 | 20 => 1,
8 => 0,
9 | 10 | 11 | 12 | 14 | 15 | 19 => -1,
13 => 64,
_ => {
// ___setErrNo(22);
-1
}
}
}
pub fn _fpathconf(_ctx: &mut Ctx, _fildes: c_int, name: c_int) -> c_int {
debug!("emscripten::_fpathconf {} {}", _fildes, name);
match name {
0 => 32000,
1 | 2 | 3 => 255,
4 | 5 | 16 | 17 | 18 => 4096,
6 | 7 | 20 => 1,
8 => 0,
9 | 10 | 11 | 12 | 14 | 15 | 19 => -1,
13 => 64,
_ => {
// ___setErrNo(22);
-1
}
}
}

View File

@ -553,6 +553,8 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"_sysconf" => func!(crate::env::_sysconf),
"_getaddrinfo" => func!(crate::env::_getaddrinfo),
"_times" => func!(crate::env::_times),
"_pathconf" => func!(crate::env::_pathconf),
"_fpathconf" => func!(crate::env::_fpathconf),
// Syscalls
"___syscall1" => func!(crate::syscalls::___syscall1),
@ -695,6 +697,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"_asctime_r" => func!(crate::time::_asctime_r),
"_localtime" => func!(crate::time::_localtime),
"_time" => func!(crate::time::_time),
"_timegm" => func!(crate::time::_timegm),
"_strftime" => func!(crate::time::_strftime),
"_strftime_l" => func!(crate::time::_strftime_l),
"_localtime_r" => func!(crate::time::_localtime_r),
@ -713,6 +716,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"_llvm_exp2_f32" => func!(crate::math::_llvm_exp2_f32),
"_llvm_exp2_f64" => func!(crate::math::_llvm_exp2_f64),
"_llvm_trunc_f64" => func!(crate::math::_llvm_trunc_f64),
"_llvm_fma_f64" => func!(crate::math::_llvm_fma_f64),
"_emscripten_random" => func!(crate::math::_emscripten_random),
// Jump

View File

@ -49,6 +49,11 @@ pub fn _llvm_trunc_f64(_ctx: &mut Ctx, value: f64) -> f64 {
value.trunc()
}
pub fn _llvm_fma_f64(_ctx: &mut Ctx, value: f64, a: f64, b: f64) -> f64 {
debug!("emscripten::_llvm_fma_f64");
value.mul_add(a, b)
}
pub fn _emscripten_random(_ctx: &mut Ctx) -> f64 {
debug!("emscripten::_emscripten_random");
-1.0

View File

@ -39,6 +39,7 @@ use libc::{
// writev,
stat,
write,
// readlink,
};
use wasmer_runtime_core::vm::Ctx;
@ -94,8 +95,7 @@ pub fn ___syscall6(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
// chdir
pub fn ___syscall12(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall12 (chdir) {}", _which);
let path_addr: i32 = varargs.get(ctx);
let path_ptr = emscripten_memory_pointer!(ctx.memory(0), path_addr) as *const i8;
let path_ptr = varargs.get_str(ctx);
let real_path = get_cstr_path(ctx, path_ptr)
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
.unwrap_or(path_ptr);
@ -127,10 +127,8 @@ pub fn ___syscall20(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
// rename
pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall38 (rename)");
let old_path_addr: u32 = varargs.get(ctx);
let new_path_addr: u32 = varargs.get(ctx);
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 old_path = varargs.get_str(ctx);
let new_path = varargs.get_str(ctx);
let real_old_path = get_cstr_path(ctx, old_path)
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
.unwrap_or(old_path);
@ -150,8 +148,7 @@ pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
// rmdir
pub fn ___syscall40(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall40 (rmdir)");
let pathname: u32 = varargs.get(ctx);
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
let pathname_addr = varargs.get_str(ctx);
let real_path = get_cstr_path(ctx, pathname_addr)
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
.unwrap_or(pathname_addr);
@ -215,9 +212,32 @@ pub fn ___syscall75(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
-1
}
pub fn ___syscall85(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
debug!("emscripten::___syscall85");
-1
// readlink
pub fn ___syscall85(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall85 (readlink)");
let _path = varargs.get_str(ctx);
let buf = varargs.get_str(ctx);
// let buf_addr: i32 = varargs.get(ctx);
let buf_size: i32 = varargs.get(ctx);
let fd = 3;
let ret = unsafe { read(fd, buf as _, buf_size as _) as i32 };
debug!(
"=> buf: {}, buf_size: {}, return: {} ",
unsafe { std::ffi::CStr::from_ptr(buf as _).to_str().unwrap() },
buf_size,
ret
);
// let ret = unsafe {
// readlink(path, buf as _, buf_size as _) as i32
// };
// debug!("=> path: {}, buf: {}, buf_size: {}, return: {} ",
// unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() },
// unsafe { std::ffi::CStr::from_ptr(buf as _).to_str().unwrap() },
// // std::ffi::CStr::from_ptr(buf).to_str().unwrap(),
// // buf,
// buf_size,
// ret);
ret
}
pub fn ___syscall91(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
@ -410,10 +430,9 @@ pub fn ___syscall199(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
// stat64
pub fn ___syscall195(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall195 (stat64) {}", _which);
let pathname: u32 = varargs.get(ctx);
let pathname_addr = varargs.get_str(ctx);
let buf: u32 = varargs.get(ctx);
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
let real_path = get_cstr_path(ctx, pathname_addr)
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
.unwrap_or(pathname_addr);
@ -422,10 +441,9 @@ pub fn ___syscall195(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
let mut _stat: stat = std::mem::zeroed();
let ret = stat(real_path, &mut _stat);
debug!(
"=> pathname: {}, buf: {}, path: {} = {}\nlast os error: {}",
pathname,
"=> pathname: {}, buf: {} = {}, last os error: {}",
std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap(),
buf,
std::ffi::CStr::from_ptr(real_path).to_str().unwrap(),
ret,
Error::last_os_error()
);

View File

@ -105,22 +105,20 @@ const SO_NOSIGPIPE: c_int = 0;
/// open
pub fn ___syscall5(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall5 (open) {}", _which);
let pathname: u32 = varargs.get(ctx);
let pathname_addr = varargs.get_str(ctx);
let flags: i32 = varargs.get(ctx);
let mode: u32 = varargs.get(ctx);
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
let real_path = utils::get_cstr_path(ctx, pathname_addr)
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
.unwrap_or(pathname_addr);
let _path_str = unsafe { std::ffi::CStr::from_ptr(real_path).to_str().unwrap() };
let fd = unsafe { open(real_path, flags, mode) };
debug!(
"=> pathname: {}, flags: {}, mode: {} = fd: {}\npath: {}\nlast os error: {}",
pathname,
"=> path: {}, flags: {}, mode: {} = fd: {}, last os error: {}",
_path_str,
flags,
mode,
fd,
_path_str,
Error::last_os_error(),
);
fd
@ -130,10 +128,8 @@ pub fn ___syscall5(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
pub fn ___syscall9(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall9 (link) {}", _which);
let oldname: c_int = varargs.get(ctx);
let newname: c_int = varargs.get(ctx);
let oldname_ptr = emscripten_memory_pointer!(ctx.memory(0), oldname) as *const i8;
let newname_ptr = emscripten_memory_pointer!(ctx.memory(0), newname) as *const i8;
let oldname_ptr = varargs.get_str(ctx);
let newname_ptr = varargs.get_str(ctx);
let result = unsafe { link(oldname_ptr, newname_ptr) };
debug!(
"=> oldname: {}, newname: {}, result: {}",
@ -160,10 +156,8 @@ pub fn ___syscall77(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
pub fn ___syscall83(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall83 (symlink) {}", _which);
let path1_ptr: c_int = varargs.get(ctx);
let path2_ptr: c_int = varargs.get(ctx);
let path1 = emscripten_memory_pointer!(ctx.memory(0), path1_ptr) as *mut i8;
let path2 = emscripten_memory_pointer!(ctx.memory(0), path2_ptr) as *mut i8;
let path1 = varargs.get_str(ctx);
let path2 = varargs.get_str(ctx);
let real_path1 = utils::get_cstr_path(ctx, path1)
.map(|cstr| cstr.as_c_str() as *const _ as *const i8)
.unwrap_or(path1);
@ -196,10 +190,9 @@ pub fn ___syscall194(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
/// lchown
pub fn ___syscall198(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall198 (lchown) {}", _which);
let path: c_int = varargs.get(ctx);
let path_ptr = varargs.get_str(ctx);
let uid: uid_t = varargs.get(ctx);
let gid: gid_t = varargs.get(ctx);
let path_ptr = emscripten_memory_pointer!(ctx.memory(0), path) as *const i8;
let result = unsafe { lchown(path_ptr, uid, gid) };
debug!(
"=> path: {}, uid: {}, gid: {}, result: {}",
@ -232,12 +225,10 @@ pub fn ___syscall205(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
pub fn ___syscall212(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall212 (chown) {}", _which);
let pathname: u32 = varargs.get(ctx);
let pathname_addr = varargs.get_str(ctx);
let owner: u32 = varargs.get(ctx);
let group: u32 = varargs.get(ctx);
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
unsafe { chown(pathname_addr, owner, group) }
}
@ -257,9 +248,8 @@ pub fn ___syscall219(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
/// access
pub fn ___syscall33(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall33 (access) {}", _which);
let path_ptr: c_int = varargs.get(ctx);
let path = varargs.get_str(ctx);
let amode: c_int = varargs.get(ctx);
let path = emscripten_memory_pointer!(ctx.memory(0), path_ptr) as *const i8;
let result = unsafe { access(path, amode) };
debug!(
"=> path: {}, amode: {}, result: {}",
@ -280,9 +270,8 @@ pub fn ___syscall34(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
// mkdir
pub fn ___syscall39(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall39 (mkdir) {}", _which);
let pathname: u32 = varargs.get(ctx);
let pathname_addr = varargs.get_str(ctx);
let mode: u32 = varargs.get(ctx);
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
unsafe { mkdir(pathname_addr, mode as _) }
}
@ -781,9 +770,8 @@ pub fn ___syscall122(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
/// lstat64
pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall196 (lstat64) {}", _which);
let path_ptr: c_int = varargs.get(ctx);
let path = varargs.get_str(ctx);
let buf_ptr: u32 = varargs.get(ctx);
let path = emscripten_memory_pointer!(ctx.memory(0), path_ptr) as *const i8;
unsafe {
let mut stat: stat = std::mem::zeroed();

View File

@ -18,10 +18,9 @@ pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall5 (open) {}", which);
#[cfg(not(feature = "debug"))]
let _ = which;
let pathname: u32 = varargs.get(ctx);
let pathname_addr = varargs.get_str(ctx);
let flags: i32 = varargs.get(ctx);
let mode: u32 = varargs.get(ctx);
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
let path_str = unsafe { std::ffi::CStr::from_ptr(pathname_addr).to_str().unwrap() };
match path_str {
"/dev/urandom" => {
@ -43,7 +42,7 @@ pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int {
let fd = unsafe { open(raw_pointer_to_urandom_file, flags, mode) };
debug!(
"=> pathname: {}, flags: {}, mode: {} = fd: {}",
pathname, flags, mode, fd
path_str, flags, mode, fd
);
fd
}
@ -51,7 +50,7 @@ pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int {
let fd = unsafe { open(pathname_addr, flags, mode) };
debug!(
"=> pathname: {}, flags: {}, mode: {} = fd: {}\npath: {}",
pathname, flags, mode, fd, path_str
path_str, flags, mode, fd, path_str
);
fd
}
@ -95,8 +94,7 @@ pub fn ___syscall39(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int
debug!("emscripten::___syscall39 (mkdir) {}", which);
#[cfg(not(feature = "debug"))]
let _ = which;
let pathname: u32 = varargs.get(ctx);
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
let pathname_addr = varargs.get_str(ctx);
unsafe { mkdir(pathname_addr) }
}

View File

@ -4,7 +4,9 @@ use std::mem;
use std::time::SystemTime;
#[cfg(not(target_os = "windows"))]
use libc::{clockid_t, time as libc_time};
use libc::{clockid_t, time as libc_time, timegm as libc_timegm, tm as libc_tm};
#[cfg(not(target_os = "windows"))]
use std::ffi::CString;
#[cfg(target_os = "windows")]
use libc::time_t;
@ -298,6 +300,57 @@ pub fn _time(ctx: &mut Ctx, time_p: u32) -> i32 {
}
}
/// emscripten: _timegm
#[cfg(not(target_os = "windows"))]
#[allow(clippy::cast_ptr_alignment)]
pub fn _timegm(ctx: &mut Ctx, time_ptr: u32) -> i32 {
debug!("emscripten::_timegm {}", time_ptr);
unsafe {
let time_p_addr = emscripten_memory_pointer!(ctx.memory(0), time_ptr) as *mut guest_tm;
let x: *mut c_char = CString::new("").expect("CString::new failed").into_raw();
let mut rust_tm = libc_tm {
tm_sec: 0,
tm_min: 0,
tm_hour: 0,
tm_mday: 0,
tm_mon: 0,
tm_year: 0,
tm_wday: 0,
tm_yday: 0,
tm_isdst: 0,
tm_gmtoff: 0,
tm_zone: x,
};
let result = libc_timegm(&mut rust_tm) as i32;
if result != 0 {
(*time_p_addr).tm_sec = rust_tm.tm_sec;
(*time_p_addr).tm_min = rust_tm.tm_min;
(*time_p_addr).tm_hour = rust_tm.tm_hour;
(*time_p_addr).tm_mday = rust_tm.tm_mday;
(*time_p_addr).tm_mon = rust_tm.tm_mon;
(*time_p_addr).tm_year = rust_tm.tm_year;
(*time_p_addr).tm_wday = rust_tm.tm_wday;
(*time_p_addr).tm_yday = rust_tm.tm_yday;
(*time_p_addr).tm_isdst = rust_tm.tm_isdst;
(*time_p_addr).tm_gmtoff = rust_tm.tm_gmtoff as _;
(*time_p_addr).tm_zone = 0;
}
result
}
}
#[cfg(target_os = "windows")]
pub fn _timegm(_ctx: &mut Ctx, _time_ptr: c_int) -> i32 {
debug!(
"emscripten::_timegm - UNIMPLEMENTED IN WINDOWS {}",
_time_ptr
);
-1
}
/// emscripten: _strftime
pub fn _strftime(
ctx: &mut Ctx,

View File

@ -1,5 +1,7 @@
use std::mem;
use wasmer_runtime_core::{types::WasmExternType, vm::Ctx};
// use std::ffi::CStr;
use std::os::raw::c_char;
#[repr(transparent)]
#[derive(Copy, Clone)]
@ -13,6 +15,14 @@ impl VarArgs {
self.pointer += mem::size_of::<T>() as u32;
unsafe { (ptr as *const T).read() }
}
// pub fn getStr<'a>(&mut self, ctx: &mut Ctx) -> &'a CStr {
pub fn get_str(&mut self, ctx: &mut Ctx) -> *const c_char {
let ptr_addr: u32 = self.get(ctx);
let ptr = emscripten_memory_pointer!(ctx.memory(0), ptr_addr) as *const c_char;
ptr
// unsafe { CStr::from_ptr(ptr) }
}
}
unsafe impl WasmExternType for VarArgs {