clean up implementation

This commit is contained in:
Mark McCaskey
2019-03-27 14:01:27 -07:00
parent f9a29445ca
commit 09068c1a74
11 changed files with 109 additions and 58 deletions

View File

@ -16,7 +16,7 @@ use target_lexicon::Triple;
use wasmer_runtime_core::cache::{Artifact, Error as CacheError}; use wasmer_runtime_core::cache::{Artifact, Error as CacheError};
use wasmer_runtime_core::{ use wasmer_runtime_core::{
backend::{Compiler, Token}, backend::{Compiler, CompilerConfig, Token},
error::{CompileError, CompileResult}, error::{CompileError, CompileResult},
module::ModuleInner, module::ModuleInner,
}; };
@ -39,12 +39,17 @@ impl CraneliftCompiler {
impl Compiler for CraneliftCompiler { impl Compiler for CraneliftCompiler {
/// Compiles wasm binary to a wasmer module. /// Compiles wasm binary to a wasmer module.
fn compile(&self, wasm: &[u8], _: Token) -> CompileResult<ModuleInner> { fn compile(
&self,
wasm: &[u8],
compiler_config: CompilerConfig,
_: Token,
) -> CompileResult<ModuleInner> {
validate(wasm)?; validate(wasm)?;
let isa = get_isa(); let isa = get_isa();
let mut module = module::Module::new(); let mut module = module::Module::new(&compiler_config);
let module_env = module_env::ModuleEnv::new(&mut module, &*isa); let module_env = module_env::ModuleEnv::new(&mut module, &*isa);
let func_bodies = module_env.translate(wasm)?; let func_bodies = module_env.translate(wasm)?;

View File

@ -10,7 +10,7 @@ use std::sync::Arc;
use wasmer_runtime_core::cache::{Artifact, Error as CacheError}; use wasmer_runtime_core::cache::{Artifact, Error as CacheError};
use wasmer_runtime_core::{ use wasmer_runtime_core::{
backend::Backend, backend::{Backend, CompilerConfig},
error::CompileResult, error::CompileResult,
module::{ModuleInfo, ModuleInner, StringTable}, module::{ModuleInfo, ModuleInner, StringTable},
structures::{Map, TypedIndex}, structures::{Map, TypedIndex},
@ -25,7 +25,7 @@ pub struct Module {
} }
impl Module { impl Module {
pub fn new() -> Self { pub fn new(compiler_config: &CompilerConfig) -> Self {
Self { Self {
info: ModuleInfo { info: ModuleInfo {
memories: Map::new(), memories: Map::new(),
@ -50,6 +50,7 @@ impl Module {
namespace_table: StringTable::new(), namespace_table: StringTable::new(),
name_table: StringTable::new(), name_table: StringTable::new(),
em_symbol_map: compiler_config.symbol_map.clone(),
}, },
} }
} }

View File

@ -374,26 +374,26 @@ fn round_up(n: usize, multiple: usize) -> usize {
} }
extern "C" fn i32_print(_ctx: &mut vm::Ctx, n: i32) { extern "C" fn i32_print(_ctx: &mut vm::Ctx, n: i32) {
print!(" i32: {},", n); eprint!(" i32: {},", n);
} }
extern "C" fn i64_print(_ctx: &mut vm::Ctx, n: i64) { extern "C" fn i64_print(_ctx: &mut vm::Ctx, n: i64) {
print!(" i64: {},", n); eprint!(" i64: {},", n);
} }
extern "C" fn f32_print(_ctx: &mut vm::Ctx, n: f32) { extern "C" fn f32_print(_ctx: &mut vm::Ctx, n: f32) {
print!(" f32: {},", n); eprint!(" f32: {},", n);
} }
extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) { extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) {
print!(" f64: {},", n); eprint!(" f64: {},", n);
} }
extern "C" fn start_debug(ctx: &mut vm::Ctx, func_index: u32) { extern "C" fn start_debug(ctx: &mut vm::Ctx, func_index: u32) {
if let Some(symbol_map) = &ctx.maybe_symbol_map { if let Some(symbol_map) = unsafe { ctx.borrow_symbol_map() } {
if let Some(fn_name) = symbol_map.get(&func_index) { if let Some(fn_name) = symbol_map.get(&func_index) {
print!("func ({} ({})), args: [", fn_name, func_index); eprint!("func ({} ({})), args: [", fn_name, func_index);
return; return;
} }
} }
print!("func ({}), args: [", func_index); eprint!("func ({}), args: [", func_index);
} }
extern "C" fn end_debug(_ctx: &mut vm::Ctx) { extern "C" fn end_debug(_ctx: &mut vm::Ctx) {
println!(" ]"); eprintln!(" ]");
} }

View File

@ -14,6 +14,8 @@ use crate::{
}; };
use std::{any::Any, ptr::NonNull}; use std::{any::Any, ptr::NonNull};
use hashbrown::HashMap;
pub mod sys { pub mod sys {
pub use crate::sys::*; pub use crate::sys::*;
} }
@ -38,11 +40,28 @@ impl Token {
} }
} }
/// Configuration data for the compiler
pub struct CompilerConfig {
/// Symbol information generated from emscripten; used for more detailed debug messages
pub symbol_map: Option<HashMap<u32, String>>,
}
impl Default for CompilerConfig {
fn default() -> CompilerConfig {
CompilerConfig { symbol_map: None }
}
}
pub trait Compiler { pub trait Compiler {
/// Compiles a `Module` from WebAssembly binary format. /// Compiles a `Module` from WebAssembly binary format.
/// The `CompileToken` parameter ensures that this can only /// The `CompileToken` parameter ensures that this can only
/// be called from inside the runtime. /// be called from inside the runtime.
fn compile(&self, wasm: &[u8], _: Token) -> CompileResult<ModuleInner>; fn compile(
&self,
wasm: &[u8],
comp_conf: CompilerConfig,
_: Token,
) -> CompileResult<ModuleInner>;
unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>; unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>;
} }

View File

@ -13,7 +13,6 @@ use crate::{
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value}, types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value},
vm, vm,
}; };
use hashbrown::HashMap;
use std::{mem, sync::Arc}; use std::{mem, sync::Arc};
pub(crate) struct InstanceInner { pub(crate) struct InstanceInner {
@ -45,11 +44,7 @@ pub struct Instance {
} }
impl Instance { impl Instance {
pub(crate) fn new( pub(crate) fn new(module: Arc<ModuleInner>, imports: &ImportObject) -> Result<Instance> {
module: Arc<ModuleInner>,
imports: &ImportObject,
maybe_symbol_map: Option<HashMap<u32, String>>,
) -> Result<Instance> {
// We need the backing and import_backing to create a vm::Ctx, but we need // We need the backing and import_backing to create a vm::Ctx, but we need
// a vm::Ctx to create a backing and an import_backing. The solution is to create an // a vm::Ctx to create a backing and an import_backing. The solution is to create an
// uninitialized vm::Ctx and then initialize it in-place. // uninitialized vm::Ctx and then initialize it in-place.
@ -68,12 +63,7 @@ impl Instance {
// Initialize the vm::Ctx in-place after the backing // Initialize the vm::Ctx in-place after the backing
// has been boxed. // has been boxed.
unsafe { unsafe {
*inner.vmctx = vm::Ctx::new( *inner.vmctx = vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module)
&mut inner.backing,
&mut inner.import_backing,
&module,
maybe_symbol_map,
)
}; };
let instance = Instance { let instance = Instance {

View File

@ -68,7 +68,19 @@ pub fn compile_with(
) -> CompileResult<module::Module> { ) -> CompileResult<module::Module> {
let token = backend::Token::generate(); let token = backend::Token::generate();
compiler compiler
.compile(wasm, token) .compile(wasm, Default::default(), token)
.map(|inner| module::Module::new(Arc::new(inner)))
}
/// The same as `compile_with` but takes a symbol map for use with debugging
pub fn compile_with_config(
wasm: &[u8],
compiler: &dyn backend::Compiler,
compiler_config: backend::CompilerConfig,
) -> CompileResult<module::Module> {
let token = backend::Token::generate();
compiler
.compile(wasm, compiler_config, token)
.map(|inner| module::Module::new(Arc::new(inner))) .map(|inner| module::Module::new(Arc::new(inner)))
} }

View File

@ -56,6 +56,8 @@ pub struct ModuleInfo {
pub namespace_table: StringTable<NamespaceIndex>, pub namespace_table: StringTable<NamespaceIndex>,
pub name_table: StringTable<NameIndex>, pub name_table: StringTable<NameIndex>,
pub em_symbol_map: Option<HashMap<u32, String>>,
} }
/// A compiled WebAssembly module. /// A compiled WebAssembly module.
@ -100,12 +102,8 @@ impl Module {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
pub fn instantiate( pub fn instantiate(&self, import_object: &ImportObject) -> error::Result<Instance> {
&self, Instance::new(Arc::clone(&self.inner), import_object)
import_object: &ImportObject,
maybe_symbol_map: Option<HashMap<u32, String>>,
) -> error::Result<Instance> {
Instance::new(Arc::clone(&self.inner), import_object, maybe_symbol_map)
} }
pub fn cache(&self) -> Result<Artifact, CacheError> { pub fn cache(&self) -> Result<Artifact, CacheError> {

View File

@ -5,9 +5,10 @@ use crate::{
structures::TypedIndex, structures::TypedIndex,
types::{LocalOrImport, MemoryIndex}, types::{LocalOrImport, MemoryIndex},
}; };
use hashbrown::HashMap;
use std::{ffi::c_void, mem, ptr}; use std::{ffi::c_void, mem, ptr};
use hashbrown::HashMap;
/// The context of the currently running WebAssembly instance. /// The context of the currently running WebAssembly instance.
/// ///
/// ///
@ -25,8 +26,6 @@ pub struct Ctx {
pub data: *mut c_void, pub data: *mut c_void,
pub data_finalizer: Option<extern "C" fn(data: *mut c_void)>, pub data_finalizer: Option<extern "C" fn(data: *mut c_void)>,
pub maybe_symbol_map: Option<HashMap<u32, String>>,
} }
/// The internal context of the currently running WebAssembly instance. /// The internal context of the currently running WebAssembly instance.
@ -70,7 +69,6 @@ impl Ctx {
local_backing: &mut LocalBacking, local_backing: &mut LocalBacking,
import_backing: &mut ImportBacking, import_backing: &mut ImportBacking,
module: &ModuleInner, module: &ModuleInner,
maybe_symbol_map: Option<HashMap<u32, String>>,
) -> Self { ) -> Self {
Self { Self {
internal: InternalCtx { internal: InternalCtx {
@ -93,7 +91,6 @@ impl Ctx {
data: ptr::null_mut(), data: ptr::null_mut(),
data_finalizer: None, data_finalizer: None,
maybe_symbol_map,
} }
} }
@ -126,7 +123,6 @@ impl Ctx {
data, data,
data_finalizer: Some(data_finalizer), data_finalizer: Some(data_finalizer),
maybe_symbol_map: None,
} }
} }
@ -162,6 +158,10 @@ impl Ctx {
}, },
} }
} }
pub unsafe fn borrow_symbol_map(&self) -> &Option<HashMap<u32, String>> {
&(*self.module).info.em_symbol_map
}
} }
#[doc(hidden)] #[doc(hidden)]

View File

@ -110,7 +110,7 @@ pub mod units {
pub mod cache; pub mod cache;
use wasmer_runtime_core::backend::Compiler; use wasmer_runtime_core::backend::{Compiler, CompilerConfig};
/// Compile WebAssembly binary code into a [`Module`]. /// Compile WebAssembly binary code into a [`Module`].
/// This function is useful if it is necessary to /// This function is useful if it is necessary to
@ -129,6 +129,13 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult<Module> {
wasmer_runtime_core::compile_with(&wasm[..], default_compiler()) wasmer_runtime_core::compile_with(&wasm[..], default_compiler())
} }
pub fn compile_with_config(
wasm: &[u8],
compiler_config: CompilerConfig,
) -> error::CompileResult<Module> {
wasmer_runtime_core::compile_with_config(&wasm[..], default_compiler(), compiler_config)
}
/// Compile and instantiate WebAssembly code without /// Compile and instantiate WebAssembly code without
/// creating a [`Module`]. /// creating a [`Module`].
/// ///
@ -149,7 +156,7 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult<Module> {
/// depending on the cause of the failure. /// depending on the cause of the failure.
pub fn instantiate(wasm: &[u8], import_object: &ImportObject) -> error::Result<Instance> { pub fn instantiate(wasm: &[u8], import_object: &ImportObject) -> error::Result<Instance> {
let module = compile(wasm)?; let module = compile(wasm)?;
module.instantiate(import_object, None) module.instantiate(import_object)
} }
/// Get a single instance of the default compiler to use. /// Get a single instance of the default compiler to use.

View File

@ -14,6 +14,7 @@ use wasmer::webassembly::InstanceABI;
use wasmer::*; use wasmer::*;
use wasmer_emscripten; use wasmer_emscripten;
use wasmer_runtime::cache::{Cache as BaseCache, FileSystemCache, WasmHash, WASMER_VERSION_HASH}; use wasmer_runtime::cache::{Cache as BaseCache, FileSystemCache, WasmHash, WASMER_VERSION_HASH};
use wasmer_runtime_core::backend::CompilerConfig;
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]
#[structopt(name = "wasmer", about = "Wasm execution runtime.")] #[structopt(name = "wasmer", about = "Wasm execution runtime.")]
@ -46,9 +47,9 @@ struct Run {
#[structopt(name = "--", raw(multiple = "true"))] #[structopt(name = "--", raw(multiple = "true"))]
args: Vec<String>, args: Vec<String>,
/// Symbol map /// Emscripten symbol map
#[structopt(long = "symbol-map", parse(from_os_str))] #[structopt(long = "em-symbol-map", parse(from_os_str))]
symbol_map: Option<PathBuf>, em_symbol_map: Option<PathBuf>,
} }
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]
@ -103,18 +104,18 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
) )
})?; })?;
let maybe_symbol_map = if let Some(symbol_map_path) = options.symbol_map.clone() { let em_symbol_map = if let Some(em_symbol_map_path) = options.em_symbol_map.clone() {
let symbol_map_content: String = read_to_string(&symbol_map_path) let em_symbol_map_content: String = read_to_string(&em_symbol_map_path)
.map_err(|err| { .map_err(|err| {
format!( format!(
"Can't read symbol map file {}: {}", "Can't read symbol map file {}: {}",
symbol_map_path.as_os_str().to_string_lossy(), em_symbol_map_path.as_os_str().to_string_lossy(),
err, err,
) )
})? })?
.to_owned(); .to_owned();
let mut symbol_map = HashMap::new(); let mut em_symbol_map = HashMap::new();
for line in symbol_map_content.lines() { for line in em_symbol_map_content.lines() {
let mut split = line.split(':'); let mut split = line.split(':');
let num_str = if let Some(ns) = split.next() { let num_str = if let Some(ns) = split.next() {
ns ns
@ -138,9 +139,9 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
} }
.to_owned(); .to_owned();
symbol_map.insert(num, name_str); em_symbol_map.insert(num, name_str);
} }
Some(symbol_map) Some(em_symbol_map)
} else { } else {
None None
}; };
@ -175,9 +176,13 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
module module
} }
Err(_) => { Err(_) => {
let module = webassembly::compile(&wasm_binary[..]) let module = webassembly::compile_with_config(
.map_err(|e| format!("Can't compile module: {:?}", e))?; &wasm_binary[..],
CompilerConfig {
symbol_map: em_symbol_map,
},
)
.map_err(|e| format!("Can't compile module: {:?}", e))?;
// We try to save the module into a cache file // We try to save the module into a cache file
cache.store(hash, module.clone()).unwrap_or_default(); cache.store(hash, module.clone()).unwrap_or_default();
@ -186,8 +191,13 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
}; };
module module
} else { } else {
webassembly::compile(&wasm_binary[..]) webassembly::compile_with_config(
.map_err(|e| format!("Can't compile module: {:?}", e))? &wasm_binary[..],
CompilerConfig {
symbol_map: em_symbol_map,
},
)
.map_err(|e| format!("Can't compile module: {:?}", e))?
}; };
let (_abi, import_object, _em_globals) = if wasmer_emscripten::is_emscripten_module(&module) { let (_abi, import_object, _em_globals) = if wasmer_emscripten::is_emscripten_module(&module) {
@ -206,7 +216,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
}; };
let mut instance = module let mut instance = module
.instantiate(&import_object, maybe_symbol_map) .instantiate(&import_object)
.map_err(|e| format!("Can't instantiate module: {:?}", e))?; .map_err(|e| format!("Can't instantiate module: {:?}", e))?;
webassembly::run_instance( webassembly::run_instance(

View File

@ -4,6 +4,7 @@ use wasmer_runtime::{
error::{CallResult, Result}, error::{CallResult, Result},
ImportObject, Instance, Module, ImportObject, Instance, Module,
}; };
use wasmer_runtime_core::backend::CompilerConfig;
use wasmer_runtime_core::types::Value; use wasmer_runtime_core::types::Value;
use wasmer_emscripten::{is_emscripten_module, run_emscripten_instance}; use wasmer_emscripten::{is_emscripten_module, run_emscripten_instance};
@ -42,7 +43,7 @@ pub fn instantiate(buffer_source: &[u8], import_object: ImportObject) -> Result<
let module = compile(&buffer_source[..])?; let module = compile(&buffer_source[..])?;
debug!("webassembly - instantiating"); debug!("webassembly - instantiating");
let instance = module.instantiate(&import_object, None)?; let instance = module.instantiate(&import_object)?;
debug!("webassembly - instance created"); debug!("webassembly - instance created");
Ok(ResultObject { Ok(ResultObject {
@ -76,6 +77,14 @@ pub fn compile(buffer_source: &[u8]) -> Result<Module> {
Ok(module) Ok(module)
} }
pub fn compile_with_config(
buffer_source: &[u8],
compiler_config: CompilerConfig,
) -> Result<Module> {
let module = runtime::compile_with_config(buffer_source, compiler_config)?;
Ok(module)
}
/// Performs common instance operations needed when an instance is first run /// Performs common instance operations needed when an instance is first run
/// including data setup, handling arguments and calling a main function /// including data setup, handling arguments and calling a main function
pub fn run_instance( pub fn run_instance(