Merge pull request #33 from losfair/wasmer-lib

Allow using wasmer as a library and install signal handler only once.
This commit is contained in:
Syrus Akbary 2018-11-27 21:31:30 -08:00 committed by GitHub
commit ffe294f4f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 63 deletions

View File

@ -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 structopt;
extern crate wabt; extern crate wasmer;
extern crate wasmparser;
#[macro_use]
extern crate target_lexicon;
extern crate nix;
extern crate rayon;
use std::fs::File; use std::fs::File;
use std::io; use std::io;
@ -23,16 +9,7 @@ use std::process::exit;
use structopt::StructOpt; use structopt::StructOpt;
#[macro_use] use wasmer::*;
mod macros;
#[macro_use]
mod recovery;
pub mod apis;
pub mod common;
pub mod sighandler;
#[cfg(test)]
mod spectests;
pub mod webassembly;
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]
#[structopt(name = "wasmer", about = "WASM execution runtime.")] #[structopt(name = "wasmer", about = "WASM execution runtime.")]

27
src/lib.rs Normal file
View File

@ -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;

View File

@ -5,9 +5,7 @@
//! unless you have memory unsafety elsewhere in your code. //! unless you have memory unsafety elsewhere in your code.
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use nix::sys::signal::{Signal, SIGFPE, SIGILL, SIGSEGV, SIGBUS}; use std::sync::Once;
use super::webassembly::ErrorKind;
use super::sighandler::install_sighandler;
extern "C" { extern "C" {
pub fn setjmp(env: *mut ::nix::libc::c_void) -> ::nix::libc::c_int; 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; const SETJMP_BUFFER_LEN: usize = 27;
pub static SIGHANDLER_INIT: Once = Once::new();
thread_local! { thread_local! {
pub static SETJMP_BUFFER: UnsafeCell<[::nix::libc::c_int; SETJMP_BUFFER_LEN]> = UnsafeCell::new([0; SETJMP_BUFFER_LEN]); 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. /// the behavior of call_protected is undefined.
#[macro_export] #[macro_export]
macro_rules! call_protected { macro_rules! call_protected {
($x:expr) => {unsafe { ($x:expr) => {
use crate::webassembly::ErrorKind; unsafe {
use crate::recovery::{SETJMP_BUFFER, setjmp}; use crate::recovery::{setjmp, SETJMP_BUFFER, SIGHANDLER_INIT};
use crate::sighandler::install_sighandler; 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 jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
let prev_jmp_buf = *jmp_buf; 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); let signum = setjmp(jmp_buf as *mut ::nix::libc::c_void);
if signum != 0 { if signum != 0 {
*jmp_buf = prev_jmp_buf; *jmp_buf = prev_jmp_buf;
let signal = match Signal::from_c_int(signum) { let signal = match Signal::from_c_int(signum) {
Ok(SIGFPE) => "floating-point exception", Ok(SIGFPE) => "floating-point exception",
Ok(SIGILL) => "illegal instruction", Ok(SIGILL) => "illegal instruction",
Ok(SIGSEGV) => "segmentation violation", Ok(SIGSEGV) => "segmentation violation",
Ok(SIGBUS) => "bus error", Ok(SIGBUS) => "bus error",
Err(_) => "error while getting the Signal", Err(_) => "error while getting the Signal",
_ => "unkown trapped signal", _ => "unkown trapped signal",
}; };
Err(ErrorKind::RuntimeError(format!("trap - {}", signal))) Err(ErrorKind::RuntimeError(format!("trap - {}", signal)))
} else { } else {
let ret = $x; // TODO: Switch stack? let ret = $x; // TODO: Switch stack?
*jmp_buf = prev_jmp_buf; *jmp_buf = prev_jmp_buf;
Ok(ret) Ok(ret)
}
} }
}} };
} }
/// Unwinds to last protected_call. /// Unwinds to last protected_call.
pub unsafe fn do_unwind(signum: i32) -> ! { 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.) // Since do_unwind is only expected to get called from WebAssembly code which doesn't hold any host resources (locks etc.)

View File

@ -22,7 +22,6 @@ use std::slice;
use std::sync::Arc; use std::sync::Arc;
use super::super::common::slice::{BoundedSlice, UncheckedSlice}; use super::super::common::slice::{BoundedSlice, UncheckedSlice};
use super::super::recovery;
use super::errors::ErrorKind; use super::errors::ErrorKind;
use super::import_object::{ImportObject, ImportValue}; use super::import_object::{ImportObject, ImportValue};
use super::math_intrinsics; use super::math_intrinsics;
@ -481,12 +480,7 @@ impl Instance {
tables.iter().map(|table| table[..].into()).collect(); tables.iter().map(|table| table[..].into()).collect();
let memories_pointer: Vec<BoundedSlice<u8>> = memories let memories_pointer: Vec<BoundedSlice<u8>> = memories
.iter() .iter()
.map(|mem| { .map(|mem| BoundedSlice::new(&mem[..], mem.current_size()))
BoundedSlice::new(
&mem[..],
mem.current_size(),
)
})
.collect(); .collect();
let globals_pointer: GlobalsSlice = globals[..].into(); let globals_pointer: GlobalsSlice = globals[..].into();
@ -530,8 +524,7 @@ impl Instance {
if let Some(func_index) = self.start_func { if let Some(func_index) = self.start_func {
let func: fn(&Instance) = get_instance_function!(&self, func_index); let func: fn(&Instance) = get_instance_function!(&self, func_index);
call_protected!(func(self)) call_protected!(func(self))
} } else {
else {
Ok(()) Ok(())
} }
} }