diff --git a/src/main.rs b/src/bin/wasmer.rs similarity index 86% rename from src/main.rs rename to src/bin/wasmer.rs index d68417f94..682132856 100644 --- a/src/main.rs +++ b/src/bin/wasmer.rs @@ -1,19 +1,5 @@ -#[macro_use] -extern crate error_chain; -extern crate cranelift_codegen; -extern crate cranelift_entity; -extern crate cranelift_native; -extern crate cranelift_wasm; -extern crate libc; -extern crate memmap; -extern crate region; extern crate structopt; -extern crate wabt; -extern crate wasmparser; -#[macro_use] -extern crate target_lexicon; -extern crate nix; -extern crate rayon; +extern crate wasmer; use std::fs::File; use std::io; @@ -23,16 +9,7 @@ use std::process::exit; use structopt::StructOpt; -#[macro_use] -mod macros; -#[macro_use] -mod recovery; -pub mod apis; -pub mod common; -pub mod sighandler; -#[cfg(test)] -mod spectests; -pub mod webassembly; +use wasmer::*; #[derive(Debug, StructOpt)] #[structopt(name = "wasmer", about = "WASM execution runtime.")] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 000000000..efad3bcac --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,27 @@ +#[macro_use] +extern crate error_chain; +extern crate cranelift_codegen; +extern crate cranelift_entity; +extern crate cranelift_native; +extern crate cranelift_wasm; +extern crate libc; +extern crate memmap; +extern crate region; +extern crate structopt; +extern crate wabt; +extern crate wasmparser; +#[macro_use] +extern crate target_lexicon; +pub extern crate nix; // re-exported for usage in macros +extern crate rayon; + +#[macro_use] +mod macros; +#[macro_use] +pub mod recovery; +pub mod apis; +pub mod common; +pub mod sighandler; +#[cfg(test)] +mod spectests; +pub mod webassembly; diff --git a/src/recovery.rs b/src/recovery.rs index b685bf12d..e644b9b06 100644 --- a/src/recovery.rs +++ b/src/recovery.rs @@ -5,9 +5,7 @@ //! unless you have memory unsafety elsewhere in your code. use std::cell::UnsafeCell; -use nix::sys::signal::{Signal, SIGFPE, SIGILL, SIGSEGV, SIGBUS}; -use super::webassembly::ErrorKind; -use super::sighandler::install_sighandler; +use std::sync::Once; extern "C" { pub fn setjmp(env: *mut ::nix::libc::c_void) -> ::nix::libc::c_int; @@ -15,6 +13,7 @@ extern "C" { } const SETJMP_BUFFER_LEN: usize = 27; +pub static SIGHANDLER_INIT: Once = Once::new(); thread_local! { pub static SETJMP_BUFFER: UnsafeCell<[::nix::libc::c_int; SETJMP_BUFFER_LEN]> = UnsafeCell::new([0; SETJMP_BUFFER_LEN]); @@ -29,39 +28,42 @@ thread_local! { /// the behavior of call_protected is undefined. #[macro_export] macro_rules! call_protected { - ($x:expr) => {unsafe { - use crate::webassembly::ErrorKind; - use crate::recovery::{SETJMP_BUFFER, setjmp}; - use crate::sighandler::install_sighandler; + ($x:expr) => { + unsafe { + use crate::recovery::{setjmp, SETJMP_BUFFER, SIGHANDLER_INIT}; + use crate::sighandler::install_sighandler; + use crate::webassembly::ErrorKind; - use nix::sys::signal::{Signal, SIGFPE, SIGILL, SIGSEGV, SIGBUS}; + use crate::nix::sys::signal::{Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV}; - let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get()); - let prev_jmp_buf = *jmp_buf; + let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get()); + let prev_jmp_buf = *jmp_buf; - install_sighandler(); + SIGHANDLER_INIT.call_once(|| { + install_sighandler(); + }); - let signum = setjmp(jmp_buf as *mut ::nix::libc::c_void); - if signum != 0 { - *jmp_buf = prev_jmp_buf; - let signal = match Signal::from_c_int(signum) { - Ok(SIGFPE) => "floating-point exception", - Ok(SIGILL) => "illegal instruction", - Ok(SIGSEGV) => "segmentation violation", - Ok(SIGBUS) => "bus error", - Err(_) => "error while getting the Signal", - _ => "unkown trapped signal", - }; - Err(ErrorKind::RuntimeError(format!("trap - {}", signal))) - } else { - let ret = $x; // TODO: Switch stack? - *jmp_buf = prev_jmp_buf; - Ok(ret) + let signum = setjmp(jmp_buf as *mut ::nix::libc::c_void); + if signum != 0 { + *jmp_buf = prev_jmp_buf; + let signal = match Signal::from_c_int(signum) { + Ok(SIGFPE) => "floating-point exception", + Ok(SIGILL) => "illegal instruction", + Ok(SIGSEGV) => "segmentation violation", + Ok(SIGBUS) => "bus error", + Err(_) => "error while getting the Signal", + _ => "unkown trapped signal", + }; + Err(ErrorKind::RuntimeError(format!("trap - {}", signal))) + } else { + let ret = $x; // TODO: Switch stack? + *jmp_buf = prev_jmp_buf; + Ok(ret) + } } - }} + }; } - /// Unwinds to last protected_call. pub unsafe fn do_unwind(signum: i32) -> ! { // Since do_unwind is only expected to get called from WebAssembly code which doesn't hold any host resources (locks etc.) diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index 63b1d8b91..ec53ab7eb 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -22,7 +22,6 @@ use std::slice; use std::sync::Arc; use super::super::common::slice::{BoundedSlice, UncheckedSlice}; -use super::super::recovery; use super::errors::ErrorKind; use super::import_object::{ImportObject, ImportValue}; use super::math_intrinsics; @@ -481,12 +480,7 @@ impl Instance { tables.iter().map(|table| table[..].into()).collect(); let memories_pointer: Vec> = memories .iter() - .map(|mem| { - BoundedSlice::new( - &mem[..], - mem.current_size(), - ) - }) + .map(|mem| BoundedSlice::new(&mem[..], mem.current_size())) .collect(); let globals_pointer: GlobalsSlice = globals[..].into(); @@ -530,8 +524,7 @@ impl Instance { if let Some(func_index) = self.start_func { let func: fn(&Instance) = get_instance_function!(&self, func_index); call_protected!(func(self)) - } - else { + } else { Ok(()) } }