Merge branch 'feature/vm_refactor' of github.com:wasmerio/wasmer into feature/vm_refactor

# Conflicts:
#	Makefile
This commit is contained in:
Syrus 2019-01-18 10:11:14 -08:00
commit a24f7b7ebb
31 changed files with 1587 additions and 1370 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
**/*.rs.bk **/*.rs.bk
/artifacts /artifacts
.DS_Store .DS_Store
.idea

15
Cargo.lock generated
View File

@ -1098,6 +1098,7 @@ dependencies = [
"time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.1.0", "wasmer-clif-backend 0.1.0",
"wasmer-emscripten 0.1.1",
"wasmer-runtime 0.1.0", "wasmer-runtime 0.1.0",
"wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1118,6 +1119,20 @@ dependencies = [
"wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "wasmer-emscripten"
version = "0.1.1"
dependencies = [
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.44 (git+https://github.com/rust-lang/libc)",
"time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.1.0",
"wasmer-runtime 0.1.0",
]
[[package]] [[package]]
name = "wasmer-runtime" name = "wasmer-runtime"
version = "0.1.0" version = "0.1.0"

View File

@ -52,11 +52,11 @@ libffi = "0.6.4"
time = "0.1.41" time = "0.1.41"
wasmer-clif-backend = { path = "lib/clif-backend" } wasmer-clif-backend = { path = "lib/clif-backend" }
wasmer-runtime = { path = "lib/runtime" } wasmer-runtime = { path = "lib/runtime" }
# wasmer-emscripten = { path = "lib/emscripten" } wasmer-emscripten = { path = "lib/emscripten" }
libc = { git = "https://github.com/rust-lang/libc" } libc = { git = "https://github.com/rust-lang/libc" }
[workspace] [workspace]
members = ["lib/clif-backend", "lib/runtime"] # "lib/emscripten" members = ["lib/clif-backend", "lib/runtime", "lib/emscripten"]
[build-dependencies] [build-dependencies]
wabt = "0.7.2" wabt = "0.7.2"

View File

@ -30,6 +30,7 @@ precommit: lint test
test: test:
# We use one thread so the emscripten stdouts doesn't collide # We use one thread so the emscripten stdouts doesn't collide
# cargo test --all -- --test-threads=1 $(runargs) # cargo test --all -- --test-threads=1 $(runargs)
# cargo test --all --exclude wasmer-emscripten -- --test-threads=1 $(runargs)
cargo test -p wasmer-runtime -- --test-threads=1 $(runargs) cargo test -p wasmer-runtime -- --test-threads=1 $(runargs)
release: release:

View File

@ -32,7 +32,7 @@ impl FuncResolver for PlaceholderFuncResolver {
/// This contains all of the items in a `ModuleInner` except the `func_resolver`. /// This contains all of the items in a `ModuleInner` except the `func_resolver`.
pub struct Module { pub struct Module {
module: ModuleInner, pub module: ModuleInner,
} }
impl Module { impl Module {

View File

@ -6,6 +6,7 @@ edition = "2018"
build = "build/mod.rs" build = "build/mod.rs"
[dependencies] [dependencies]
hashbrown = "0.1"
wasmer-runtime = { path = "../runtime" } wasmer-runtime = { path = "../runtime" }
libc = { git = "https://github.com/rust-lang/libc" } libc = { git = "https://github.com/rust-lang/libc" }
byteorder = "1" byteorder = "1"

View File

@ -8,8 +8,8 @@ use std::mem;
use std::os::raw::c_char; use std::os::raw::c_char;
use super::utils::{allocate_on_stack, copy_cstr_into_wasm, copy_terminated_array_of_cstrs}; use super::utils::{allocate_on_stack, copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
use super::EmscriptenData;
use wasmer_runtime::{types::Value, Instance}; use wasmer_runtime::{types::Value, Instance};
//use super::EmscriptenData;
//impl Instance { //impl Instance {
// pub fn memory_offset_addr(&self, index: usize, offset: usize) -> *const usize { // pub fn memory_offset_addr(&self, index: usize, offset: usize) -> *const usize {
@ -73,6 +73,7 @@ pub extern "C" fn _unsetenv(name: c_int, instance: &mut Instance) {
unsafe { unsetenv(name_addr) }; unsafe { unsetenv(name_addr) };
} }
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int { pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
debug!("emscripten::_getpwnam {}", name_ptr); debug!("emscripten::_getpwnam {}", name_ptr);
@ -110,6 +111,7 @@ pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
} }
} }
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn _getgrnam(name_ptr: c_int, instance: &mut Instance) -> c_int { pub extern "C" fn _getgrnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
debug!("emscripten::_getgrnam {}", name_ptr); debug!("emscripten::_getgrnam {}", name_ptr);
@ -189,6 +191,7 @@ pub extern "C" fn _getpagesize() -> u32 {
16384 16384
} }
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn ___build_environment(environ: c_int, instance: &mut Instance) { pub extern "C" fn ___build_environment(environ: c_int, instance: &mut Instance) {
debug!("emscripten::___build_environment {}", environ); debug!("emscripten::___build_environment {}", environ);
const MAX_ENV_VALUES: u32 = 64; const MAX_ENV_VALUES: u32 = 64;

View File

@ -1,5 +1,5 @@
use super::process::_abort;
use super::env; use super::env;
use super::process::_abort;
use wasmer_runtime::Instance; use wasmer_runtime::Instance;
/// emscripten: ___cxa_allocate_exception /// emscripten: ___cxa_allocate_exception

View File

@ -1,6 +1,6 @@
use wasmer_runtime::Instance;
use libc::{c_int, c_void}; use libc::{c_int, c_void};
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use wasmer_runtime::Instance;
/// setjmp /// setjmp
pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int { pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int {

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
use wasmer_runtime::Instance;
use libc::c_int; use libc::c_int;
use wasmer_runtime::Instance;
// NOTE: Not implemented by Emscripten // NOTE: Not implemented by Emscripten
pub extern "C" fn ___lock(which: c_int, varargs: c_int, _instance: &mut Instance) { pub extern "C" fn ___lock(which: c_int, varargs: c_int, _instance: &mut Instance) {

View File

@ -1,6 +1,6 @@
use super::process::abort_with_message; use super::process::abort_with_message;
use wasmer_runtime::Instance;
use libc::{c_int, c_void, memcpy, size_t}; use libc::{c_int, c_void, memcpy, size_t};
use wasmer_runtime::Instance;
/// emscripten: _emscripten_memcpy_big /// emscripten: _emscripten_memcpy_big
pub extern "C" fn _emscripten_memcpy_big( pub extern "C" fn _emscripten_memcpy_big(

View File

@ -1,7 +1,7 @@
use libc::{abort, c_char, c_int, exit, pid_t, EAGAIN}; use libc::{abort, c_char, c_int, exit, pid_t, EAGAIN};
use wasmer_runtime::Instance;
use std::ffi::CStr; use std::ffi::CStr;
use wasmer_runtime::Instance;
pub extern "C" fn abort_with_message(message: &str) { pub extern "C" fn abort_with_message(message: &str) {
debug!("emscripten::abort_with_message"); debug!("emscripten::abort_with_message");

View File

@ -1,6 +1,7 @@
// use super::varargs::VarArgs; // use super::varargs::VarArgs;
use wasmer_runtime::Instance; use wasmer_runtime::Instance;
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn _sigemptyset(set: u32, instance: &mut Instance) -> i32 { pub extern "C" fn _sigemptyset(set: u32, instance: &mut Instance) -> i32 {
debug!("emscripten::_sigemptyset"); debug!("emscripten::_sigemptyset");
let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32; let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32;
@ -15,6 +16,7 @@ pub extern "C" fn _sigaction(signum: u32, act: u32, oldact: u32, _instance: &mut
0 0
} }
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn _sigaddset(set: u32, signum: u32, instance: &mut Instance) -> i32 { pub extern "C" fn _sigaddset(set: u32, signum: u32, instance: &mut Instance) -> i32 {
debug!("emscripten::_sigaddset {}, {}", set, signum); debug!("emscripten::_sigaddset {}, {}", set, signum);
let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32; let set_addr = instance.memory_offset_addr(0, set as _) as *mut u32;

View File

@ -1,6 +1,5 @@
use super::utils::copy_stat_into_wasm; use super::utils::copy_stat_into_wasm;
use super::varargs::VarArgs; use super::varargs::VarArgs;
use wasmer_runtime::Instance;
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32 /// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
/// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html /// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html
@ -68,8 +67,10 @@ use libc::{
F_GETFD, F_GETFD,
F_SETFD, F_SETFD,
SOL_SOCKET, SOL_SOCKET,
SO_REUSEADDR,
TIOCGWINSZ, TIOCGWINSZ,
}; };
use wasmer_runtime::Instance;
use super::env; use super::env;
use std::mem; use std::mem;
@ -294,6 +295,7 @@ pub extern "C" fn ___syscall64() -> pid_t {
} }
// socketcall // socketcall
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn ___syscall102( pub extern "C" fn ___syscall102(
which: c_int, which: c_int,
mut varargs: VarArgs, mut varargs: VarArgs,
@ -336,7 +338,7 @@ pub extern "C" fn ___syscall102(
unsafe { unsafe {
ioctl(fd, FIOCLEX); ioctl(fd, FIOCLEX);
}; };
if cfg!(target_os = "darwin") {
type T = u32; type T = u32;
let payload = 1 as *const T as *const c_void; let payload = 1 as *const T as *const c_void;
unsafe { unsafe {
@ -348,7 +350,6 @@ pub extern "C" fn ___syscall102(
mem::size_of::<T>() as socklen_t, mem::size_of::<T>() as socklen_t,
); );
}; };
};
debug!( debug!(
"=> domain: {} (AF_INET/2), type: {} (SOCK_STREAM/1), protocol: {} = fd: {}", "=> domain: {} (AF_INET/2), type: {} (SOCK_STREAM/1), protocol: {} = fd: {}",
@ -364,12 +365,7 @@ pub extern "C" fn ___syscall102(
let address: u32 = socket_varargs.get(instance); let address: u32 = socket_varargs.get(instance);
let address_len: u32 = socket_varargs.get(instance); let address_len: u32 = socket_varargs.get(instance);
let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr; let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr;
// unsafe {
// debug!(
// "=> address.sin_family: {:?}, address.sin_port: {:?}, address.sin_addr.s_addr: {:?}",
// (*address).sin_family, (*address).sin_port, (*address).sin_addr.s_addr
// );
// }
// we convert address as a sockaddr (even if this is incorrect), to bypass the type // we convert address as a sockaddr (even if this is incorrect), to bypass the type
// issue with libc bind // issue with libc bind
@ -437,25 +433,13 @@ pub extern "C" fn ___syscall102(
(*address_linux).sa_family = (*address).sa_family as u16; (*address_linux).sa_family = (*address).sa_family as u16;
(*address_linux).sa_data = (*address).sa_data; (*address_linux).sa_data = (*address).sa_data;
}; };
// // Debug received address
// unsafe {
// let proper_address = address as *const GuestSockaddrIn;
// debug!(
// "=> address.sin_family: {:?}, address.sin_port: {:?}, address.sin_addr.s_addr: {:?}",
// (*proper_address).sin_family, (*proper_address).sin_port, (*proper_address).sin_addr.s_addr
// );
// debug!(
// "=> address.sa_family: {:?}",
// (*address).sa_family
// );
// }
// set_cloexec // set_cloexec
unsafe { unsafe {
ioctl(fd, FIOCLEX); ioctl(fd, FIOCLEX);
}; };
debug!("fd: {}", fd); debug!("fd: {}", fd);
// nix::unistd::write(fd, "Hello, World!".as_bytes()).unwrap();
// nix::unistd::fsync(fd).unwrap();
fd fd
} }
6 => { 6 => {
@ -515,20 +499,19 @@ pub extern "C" fn ___syscall102(
// name: Em passes SO_ACCEPTCONN, but Nginx complains about REUSEADDR // name: Em passes SO_ACCEPTCONN, but Nginx complains about REUSEADDR
// https://github.com/openbsd/src/blob/master/sys/sys/socket.h#L156 // https://github.com/openbsd/src/blob/master/sys/sys/socket.h#L156
// setsockopt (socket: c_int, level: c_int, name: c_int, value: *const c_void, option_len: socklen_t) -> c_int // setsockopt (socket: c_int, level: c_int, name: c_int, value: *const c_void, option_len: socklen_t) -> c_int
let socket: i32 = socket_varargs.get(instance); let socket: i32 = socket_varargs.get(instance);
// SOL_SOCKET = 0xffff in BSD // SOL_SOCKET = 0xffff (BSD, Linux)
let level: i32 = 0xffff; let level: i32 = SOL_SOCKET;
let _: u32 = socket_varargs.get(instance); let _: u32 = socket_varargs.get(instance);
// SO_ACCEPTCONN = 0x4 // SO_REUSEADDR = 0x4 (BSD, Linux)
let name: i32 = 0x4; let name: i32 = SO_REUSEADDR;
let _: u32 = socket_varargs.get(instance); let _: u32 = socket_varargs.get(instance);
let value: u32 = socket_varargs.get(instance); let value: u32 = socket_varargs.get(instance);
let option_len: u32 = socket_varargs.get(instance); let option_len: u32 = socket_varargs.get(instance);
let value_addr = instance.memory_offset_addr(0, value as usize) as *mut c_void; // Endian problem let value_addr = instance.memory_offset_addr(0, value as usize) as *mut c_void; // Endian problem
let ret = unsafe { setsockopt(socket, level, name, value_addr, option_len) }; let ret = unsafe { setsockopt(socket, level, name, value_addr, option_len) };
// debug!("option_value = {:?}", unsafe { *(value_addr as *const u32) });
debug!("=> socketfd: {}, level: {} (SOL_SOCKET/0xffff), name: {} (SO_REUSEADDR/4), value_addr: {:?}, option_len: {} = status: {}", socket, level, name, value_addr, option_len, ret); debug!("=> socketfd: {}, level: {} (SOL_SOCKET/0xffff), name: {} (SO_REUSEADDR/4), value_addr: {:?}, option_len: {} = status: {}", socket, level, name, value_addr, option_len, ret);
ret ret
} }
@ -571,6 +554,7 @@ pub extern "C" fn ___syscall102(
} }
/// wait4 /// wait4
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn ___syscall114( pub extern "C" fn ___syscall114(
_which: c_int, _which: c_int,
mut varargs: VarArgs, mut varargs: VarArgs,
@ -606,6 +590,7 @@ pub extern "C" fn ___syscall122(
} }
// select // select
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn ___syscall142( pub extern "C" fn ___syscall142(
which: c_int, which: c_int,
mut varargs: VarArgs, mut varargs: VarArgs,
@ -673,6 +658,7 @@ pub extern "C" fn ___syscall140(
} }
/// readv /// readv
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn ___syscall145( pub extern "C" fn ___syscall145(
which: c_int, which: c_int,
mut varargs: VarArgs, mut varargs: VarArgs,
@ -718,6 +704,7 @@ pub extern "C" fn ___syscall145(
} }
// writev // writev
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn ___syscall146( pub extern "C" fn ___syscall146(
which: c_int, which: c_int,
mut varargs: VarArgs, mut varargs: VarArgs,

View File

@ -25,6 +25,7 @@ const CLOCK_MONOTONIC: libc::clockid_t = 1;
const CLOCK_MONOTONIC_COARSE: libc::clockid_t = 6; const CLOCK_MONOTONIC_COARSE: libc::clockid_t = 6;
/// emscripten: _gettimeofday /// emscripten: _gettimeofday
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) -> c_int { pub extern "C" fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) -> c_int {
debug!("emscripten::_gettimeofday {} {}", tp, tz); debug!("emscripten::_gettimeofday {} {}", tp, tz);
#[repr(C)] #[repr(C)]
@ -49,6 +50,7 @@ pub extern "C" fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) -
} }
/// emscripten: _clock_gettime /// emscripten: _clock_gettime
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn _clock_gettime( pub extern "C" fn _clock_gettime(
clk_id: libc::clockid_t, clk_id: libc::clockid_t,
tp: c_int, tp: c_int,
@ -124,6 +126,7 @@ pub extern "C" fn _tvset() {
} }
/// formats time as a C string /// formats time as a C string
#[allow(clippy::cast_ptr_alignment)]
unsafe extern "C" fn fmt_time(time: u32, instance: &Instance) -> *const c_char { unsafe extern "C" fn fmt_time(time: u32, instance: &Instance) -> *const c_char {
let date = &*(instance.memory_offset_addr(0, time as _) as *mut guest_tm); let date = &*(instance.memory_offset_addr(0, time as _) as *mut guest_tm);
@ -181,6 +184,7 @@ pub extern "C" fn _asctime_r(time: u32, buf: u32, instance: &mut Instance) -> u3
} }
/// emscripten: _localtime /// emscripten: _localtime
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int { pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int {
debug!("emscripten::_localtime {}", time_p); debug!("emscripten::_localtime {}", time_p);
// NOTE: emscripten seems to want tzset() called in this function // NOTE: emscripten seems to want tzset() called in this function
@ -217,6 +221,7 @@ pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int {
} }
} }
/// emscripten: _localtime_r /// emscripten: _localtime_r
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn _localtime_r(time_p: u32, result: u32, instance: &mut Instance) -> c_int { pub extern "C" fn _localtime_r(time_p: u32, result: u32, instance: &mut Instance) -> c_int {
debug!("emscripten::_localtime_r {}", time_p); debug!("emscripten::_localtime_r {}", time_p);
@ -253,6 +258,7 @@ pub extern "C" fn _localtime_r(time_p: u32, result: u32, instance: &mut Instance
} }
/// emscripten: _time /// emscripten: _time
#[allow(clippy::cast_ptr_alignment)]
pub extern "C" fn _time(time_p: u32, instance: &mut Instance) -> time_t { pub extern "C" fn _time(time_p: u32, instance: &mut Instance) -> time_t {
debug!("emscripten::_time {}", time_p); debug!("emscripten::_time {}", time_p);

View File

@ -1,4 +1,4 @@
use wasmer_runtime::{Instance, module::Module}; use wasmer_runtime::{module::Module, Instance};
//use wasmer_runtime::Instance; //use wasmer_runtime::Instance;
use super::env; use super::env;
use libc::stat; use libc::stat;
@ -6,10 +6,11 @@ use std::ffi::CStr;
use std::mem::size_of; use std::mem::size_of;
use std::os::raw::c_char; use std::os::raw::c_char;
use std::slice; use std::slice;
use std::sync::Arc;
/// We check if a provided module is an Emscripten generated one /// We check if a provided module is an Emscripten generated one
pub fn is_emscripten_module(module: &Module) -> bool { pub fn is_emscripten_module(module: &Arc<Module>) -> bool {
for (_, import_name) in &module.imported_functions { for (_, import_name) in &module.0.imported_functions {
if import_name.name == "_emscripten_memcpy_big" && import_name.module == "env" { if import_name.name == "_emscripten_memcpy_big" && import_name.namespace == "env" {
return true; return true;
} }
} }
@ -111,6 +112,7 @@ pub struct GuestStat {
st_ino: u64, st_ino: u64,
} }
#[allow(clippy::cast_ptr_alignment)]
pub unsafe fn copy_stat_into_wasm(instance: &mut Instance, buf: u32, stat: &stat) { pub unsafe fn copy_stat_into_wasm(instance: &mut Instance, buf: u32, stat: &stat) {
let stat_ptr = instance.memory_offset_addr(0, buf as _) as *mut GuestStat; let stat_ptr = instance.memory_offset_addr(0, buf as _) as *mut GuestStat;
(*stat_ptr).st_dev = stat.st_dev as _; (*stat_ptr).st_dev = stat.st_dev as _;
@ -141,14 +143,18 @@ pub unsafe fn copy_stat_into_wasm(instance: &mut Instance, buf: u32, stat: &stat
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::is_emscripten_module; use super::is_emscripten_module;
use wasmer_clif_backend::CraneliftCompiler; use std::sync::Arc;
use wabt::wat2wasm; use wabt::wat2wasm;
use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime::{compile, module::Module};
#[test] #[test]
fn should_detect_emscripten_files() { fn should_detect_emscripten_files() {
const wast_bytes: &[u8] = include_bytes!("tests/is_emscripten_true.wast"); const wast_bytes: &[u8] = include_bytes!("tests/is_emscripten_true.wast");
let wasm_binary = wat2wasm(wast_bytes.to_vec()).expect("Can't convert to wasm"); let wasm_binary = wat2wasm(wast_bytes.to_vec()).expect("Can't convert to wasm");
let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new()).expect("WASM can't be compiled"); let module =
compile(&wasm_binary[..], &CraneliftCompiler::new()).expect("WASM can't be compiled");
let module = Arc::new(module);
assert!(is_emscripten_module(&module)); assert!(is_emscripten_module(&module));
} }
@ -156,7 +162,9 @@ mod tests {
fn should_detect_non_emscripten_files() { fn should_detect_non_emscripten_files() {
const wast_bytes: &[u8] = include_bytes!("tests/is_emscripten_false.wast"); const wast_bytes: &[u8] = include_bytes!("tests/is_emscripten_false.wast");
let wasm_binary = wat2wasm(wast_bytes.to_vec()).expect("Can't convert to wasm"); let wasm_binary = wat2wasm(wast_bytes.to_vec()).expect("Can't convert to wasm");
let module = wasmer_runtime::compile(&wasm_binary[..], &CraneliftCompiler::new()).expect("WASM can't be compiled"); let module =
compile(&wasm_binary[..], &CraneliftCompiler::new()).expect("WASM can't be compiled");
let module = Arc::new(module);
assert!(!is_emscripten_module(&module)); assert!(!is_emscripten_module(&module));
} }
} }

View File

@ -1,5 +1,5 @@
use wasmer_runtime::Instance;
use std::mem; use std::mem;
use wasmer_runtime::Instance;
#[repr(transparent)] #[repr(transparent)]
pub struct VarArgs { pub struct VarArgs {

View File

@ -1,31 +1,40 @@
macro_rules! assert_emscripten_output { macro_rules! assert_emscripten_output {
($file:expr, $name:expr, $args:expr, $expected:expr) => {{ ($file:expr, $name:expr, $args:expr, $expected:expr) => {{
use wasmer_emscripten::generate_emscripten_env;
// use wasmer::common::stdio::StdioCapturer;
use wasmer_runtime::{Import, Imports, FuncRef};
use wasmer_runtime::table::TableBacking;
use wasmer_runtime::{Instance, module::Module};
use wasmer_clif_backend::CraneliftCompiler;
use std::sync::Arc; use wasmer_clif_backend::CraneliftCompiler;
use wasmer_emscripten::{
EmscriptenGlobals,
generate_emscripten_env,
stdio::StdioCapturer
};
let wasm_bytes = include_bytes!($file); let wasm_bytes = include_bytes!($file);
let import_object = generate_emscripten_env();
// let options = Some(InstanceOptions {
// mock_missing_imports: true,
// mock_missing_globals: true,
// mock_missing_tables: true,
// abi: InstanceABI::Emscripten,
// show_progressbar: false,
// // isa: get_isa(),
// });
// let mut result_object = instantiate(&wasm_bytes.to_vec(), &import_object, options)
// .expect("Not compiled properly");
let module = wasmer_runtime::compile(&wasm_bytes[..], &CraneliftCompiler::new()).expect("WASM can't be compiled"); let module = wasmer_runtime::compile(&wasm_bytes[..], &CraneliftCompiler::new())
let instance = module.instantiate(&import_object).expect("WASM can't be instantiated"); .expect("WASM can't be compiled");
// let capturer = StdioCapturer::new(); // let module = compile(&wasm_bytes[..])
// .map_err(|err| format!("Can't create the WebAssembly module: {}", err)).unwrap(); // NOTE: Need to figure what the unwrap is for ??
let emscripten_globals = EmscriptenGlobals::new();
let import_object = generate_emscripten_env(&emscripten_globals);
let mut instance = module.instantiate(import_object)
.map_err(|err| format!("Can't instantiate the WebAssembly module: {}", err)).unwrap(); // NOTE: Need to figure what the unwrap is for ??
// start_instance(
// Arc::clone(&module),
// &mut instance,
// $name,
// $args,
// );
assert!(false, "Emscripten tests are mocked");
let capturer = StdioCapturer::new();
instance.call("_main", &[]).map(|_o| ()).unwrap();
// TODO handle start instance logic
// start_instance( // start_instance(
// Arc::clone(&result_object.module), // Arc::clone(&result_object.module),
// &mut result_object.instance, // &mut result_object.instance,
@ -33,14 +42,14 @@ macro_rules! assert_emscripten_output {
// $args, // $args,
// ) // )
// .unwrap(); // .unwrap();
// let output = capturer.end().unwrap().0; let output = capturer.end().unwrap().0;
// let expected_output = include_str!($expected); let expected_output = include_str!($expected);
assert!(false, "Emscripten tests are mocked"); assert!(false, "Emscripten tests are mocked");
// assert!( assert!(
// output.contains(expected_output), output.contains(expected_output),
// "Output: `{}` does not contain expected output: `{}`", "Output: `{}` does not contain expected output: `{}`",
// output, output,
// expected_output expected_output
// ); );
}}; }};
} }

View File

@ -142,6 +142,7 @@ impl LocalBacking {
tables.into_boxed_map() tables.into_boxed_map()
} }
#[allow(clippy::cast_ptr_alignment)]
fn finalize_tables( fn finalize_tables(
module: &ModuleInner, module: &ModuleInner,
imports: &ImportBacking, imports: &ImportBacking,

View File

@ -24,7 +24,7 @@ pub(crate) struct InstanceInner {
} }
pub struct Instance { pub struct Instance {
pub(crate) module: Rc<ModuleInner>, pub module: Rc<ModuleInner>,
inner: Box<InstanceInner>, inner: Box<InstanceInner>,
#[allow(dead_code)] #[allow(dead_code)]
imports: Box<Imports>, imports: Box<Imports>,
@ -344,7 +344,7 @@ impl Namespace for Instance {
// TODO Remove this later, only needed for compilation till emscripten is updated // TODO Remove this later, only needed for compilation till emscripten is updated
impl Instance { impl Instance {
pub fn memory_offset_addr(&self, _index: usize, _offset: usize) -> *const usize { pub fn memory_offset_addr(&self, index: usize, offset: usize) -> *const u8 {
unimplemented!("TODO replace this emscripten stub") unimplemented!()
} }
} }

View File

@ -3,13 +3,13 @@
extern crate field_offset; extern crate field_offset;
#[macro_use] #[macro_use]
mod macros; pub mod macros;
#[doc(hidden)] #[doc(hidden)]
pub mod backend; pub mod backend;
mod backing; mod backing;
pub mod export; pub mod export;
pub mod import; pub mod import;
mod instance; pub mod instance;
pub mod memory; pub mod memory;
mod mmap; mod mmap;
pub mod module; pub mod module;

View File

@ -1,3 +1,4 @@
#[macro_export]
macro_rules! debug { macro_rules! debug {
($fmt:expr) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt), line!()) }); ($fmt:expr) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt), line!()) });
($fmt:expr, $($arg:tt)*) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt, "\n"), line!(), $($arg)*) }); ($fmt:expr, $($arg:tt)*) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt, "\n"), line!(), $($arg)*) });

View File

@ -39,7 +39,7 @@ pub struct ModuleInner {
pub sig_registry: SigRegistry, pub sig_registry: SigRegistry,
} }
pub struct Module(Rc<ModuleInner>); pub struct Module(pub Rc<ModuleInner>);
impl Module { impl Module {
pub(crate) fn new(inner: Rc<ModuleInner>) -> Self { pub(crate) fn new(inner: Rc<ModuleInner>) -> Self {

View File

@ -84,6 +84,7 @@ impl Ctx {
} }
} }
#[allow(clippy::erasing_op)] // TODO
pub fn offset_memories() -> u8 { pub fn offset_memories() -> u8 {
0 * (mem::size_of::<usize>() as u8) 0 * (mem::size_of::<usize>() as u8)
} }
@ -131,6 +132,7 @@ pub struct ImportedFunc {
} }
impl ImportedFunc { impl ImportedFunc {
#[allow(clippy::erasing_op)] // TODO
pub fn offset_func() -> u8 { pub fn offset_func() -> u8 {
0 * (mem::size_of::<usize>() as u8) 0 * (mem::size_of::<usize>() as u8)
} }
@ -157,6 +159,7 @@ pub struct LocalTable {
} }
impl LocalTable { impl LocalTable {
#[allow(clippy::erasing_op)] // TODO
pub fn offset_base() -> u8 { pub fn offset_base() -> u8 {
0 * (mem::size_of::<usize>() as u8) 0 * (mem::size_of::<usize>() as u8)
} }
@ -180,6 +183,7 @@ pub struct ImportedTable {
} }
impl ImportedTable { impl ImportedTable {
#[allow(clippy::erasing_op)] // TODO
pub fn offset_table() -> u8 { pub fn offset_table() -> u8 {
0 * (mem::size_of::<usize>() as u8) 0 * (mem::size_of::<usize>() as u8)
} }
@ -206,6 +210,7 @@ pub struct LocalMemory {
} }
impl LocalMemory { impl LocalMemory {
#[allow(clippy::erasing_op)] // TODO
pub fn offset_base() -> u8 { pub fn offset_base() -> u8 {
0 * (mem::size_of::<usize>() as u8) 0 * (mem::size_of::<usize>() as u8)
} }
@ -228,6 +233,7 @@ pub struct ImportedMemory {
} }
impl ImportedMemory { impl ImportedMemory {
#[allow(clippy::erasing_op)] // TODO
pub fn offset_memory() -> u8 { pub fn offset_memory() -> u8 {
0 * (mem::size_of::<usize>() as u8) 0 * (mem::size_of::<usize>() as u8)
} }
@ -249,6 +255,7 @@ pub struct LocalGlobal {
} }
impl LocalGlobal { impl LocalGlobal {
#[allow(clippy::erasing_op)] // TODO
pub fn offset_data() -> u8 { pub fn offset_data() -> u8 {
0 * (mem::size_of::<usize>() as u8) 0 * (mem::size_of::<usize>() as u8)
} }
@ -269,6 +276,7 @@ pub struct ImportedGlobal {
} }
impl ImportedGlobal { impl ImportedGlobal {
#[allow(clippy::erasing_op)] // TODO
pub fn offset_global() -> u8 { pub fn offset_global() -> u8 {
0 * (mem::size_of::<usize>() as u8) 0 * (mem::size_of::<usize>() as u8)
} }
@ -301,6 +309,7 @@ impl Anyfunc {
} }
} }
#[allow(clippy::erasing_op)] // TODO
pub fn offset_func() -> u8 { pub fn offset_func() -> u8 {
0 * (mem::size_of::<usize>() as u8) 0 * (mem::size_of::<usize>() as u8)
} }

View File

@ -11,8 +11,8 @@ use std::sync::Arc;
use structopt::StructOpt; use structopt::StructOpt;
use wasmer::*; use wasmer::*;
use wasmer_emscripten;
use wasmer_runtime; use wasmer_runtime;
// use wasmer_emscripten;
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]
#[structopt(name = "wasmer", about = "WASM execution runtime.")] #[structopt(name = "wasmer", about = "WASM execution runtime.")]
@ -74,18 +74,18 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
let module = webassembly::compile(&wasm_binary[..]) let module = webassembly::compile(&wasm_binary[..])
.map_err(|err| format!("Can't create the WebAssembly module: {}", err))?; .map_err(|err| format!("Can't create the WebAssembly module: {}", err))?;
let (abi, import_object) = if false { let abi = if wasmer_emscripten::is_emscripten_module(&module) {
// wasmer_emscripten::is_emscripten_module(&module) webassembly::InstanceABI::Emscripten
// (webassembly::InstanceABI::Emscripten, wasmer_emscripten::generate_emscripten_env())
(
webassembly::InstanceABI::None,
wasmer_runtime::Imports::new(),
)
} else { } else {
( webassembly::InstanceABI::None
webassembly::InstanceABI::None, };
wasmer_runtime::Imports::new(),
) let emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new();
let mut import_object = if abi == webassembly::InstanceABI::Emscripten {
wasmer_emscripten::generate_emscripten_env(&emscripten_globals)
} else {
wasmer_runtime::import::Imports::new()
}; };
let instance_options = webassembly::InstanceOptions { let instance_options = webassembly::InstanceOptions {
@ -94,7 +94,6 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
mock_missing_tables: true, mock_missing_tables: true,
abi: abi, abi: abi,
show_progressbar: true, show_progressbar: true,
// isa: isa,
}; };
debug!("webassembly - creating instance"); debug!("webassembly - creating instance");

View File

@ -1,6 +1,2 @@
pub mod mmap; pub mod mmap;
pub mod slice; pub mod slice;
mod file_descriptor;
#[cfg(test)]
pub mod stdio;

View File

@ -4,15 +4,19 @@ pub mod relocation;
pub mod utils; pub mod utils;
use wasmer_clif_backend::CraneliftCompiler; use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime; use wasmer_runtime::{
use wasmer_runtime::{backend::Compiler, module::Module}; backend::Compiler,
use wasmer_runtime::{Imports, Instance}; import::Imports,
instance::Instance,
module::{Module, ModuleInner},
};
use cranelift_codegen::{ use cranelift_codegen::{
isa, isa,
settings::{self, Configurable}, settings::{self, Configurable},
}; };
use std::panic; use std::panic;
use std::rc::Rc;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
use target_lexicon; use target_lexicon;
@ -21,7 +25,7 @@ use wasmparser::WasmDecoder;
pub use self::errors::{Error, ErrorKind}; pub use self::errors::{Error, ErrorKind};
// use wasmer_emscripten::{allocate_cstr_on_stack, allocate_on_stack, is_emscripten_module}; use wasmer_emscripten::{allocate_cstr_on_stack, allocate_on_stack, is_emscripten_module};
pub struct ResultObject { pub struct ResultObject {
/// A webassembly::Module object representing the compiled WebAssembly module. /// A webassembly::Module object representing the compiled WebAssembly module.
@ -118,10 +122,12 @@ pub fn instantiate_streaming(
/// If the operation fails, the Result rejects with a /// If the operation fails, the Result rejects with a
/// webassembly::CompileError. /// webassembly::CompileError.
pub fn compile(buffer_source: &[u8]) -> Result<Arc<Module>, ErrorKind> { pub fn compile(buffer_source: &[u8]) -> Result<Arc<Module>, ErrorKind> {
let module = wasmer_runtime::compile(&buffer_source, &CraneliftCompiler::new()) let compiler = &CraneliftCompiler {};
let module_inner = compiler
.compile(buffer_source)
.map_err(|e| ErrorKind::CompileError(e))?; .map_err(|e| ErrorKind::CompileError(e))?;
Ok(Arc::new(module)) Ok(Arc::new(Module(Rc::new(module_inner))))
} }
/// The webassembly::validate() function validates a given typed /// The webassembly::validate() function validates a given typed
@ -225,8 +231,7 @@ pub fn start_instance(
path: &str, path: &str,
args: Vec<&str>, args: Vec<&str>,
) -> Result<(), String> { ) -> Result<(), String> {
let main_name = if false { let main_name = if is_emscripten_module(&module) {
// is_emscripten_module(&instance.module)
"_main" "_main"
} else { } else {
"main" "main"