From 9c58bed344d3c5a84855db1b8fe8c9e4e4d1f192 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Tue, 26 Mar 2019 16:41:40 -0700 Subject: [PATCH 01/10] add support for symbol maps --- Cargo.lock | 1 + Cargo.toml | 1 + lib/clif-backend/src/resolver.rs | 8 ++++- lib/runtime-core/src/instance.rs | 16 ++++++++-- lib/runtime-core/src/module.rs | 8 +++-- lib/runtime-core/src/vm.rs | 6 ++++ lib/runtime/src/lib.rs | 2 +- src/bin/wasmer.rs | 51 ++++++++++++++++++++++++++++++-- src/webassembly.rs | 2 +- 9 files changed, 85 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d21f0a4e1..6e8811b53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1330,6 +1330,7 @@ name = "wasmer" version = "0.2.1" dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-backend 0.2.0", diff --git a/Cargo.toml b/Cargo.toml index e0d9a91d2..a3b2066ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ include = [ [dependencies] structopt = "0.2.11" wabt = "0.7.2" +hashbrown = "0.1.8" wasmer-clif-backend = { path = "lib/clif-backend" } wasmer-runtime = { path = "lib/runtime" } wasmer-runtime-core = { path = "lib/runtime-core" } diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index 94713e0b2..80122cc8f 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -385,7 +385,13 @@ extern "C" fn f32_print(_ctx: &mut vm::Ctx, n: f32) { extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) { print!(" 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(fn_name) = symbol_map.get(&func_index) { + print!("func ({} - {}), args: [", fn_name, func_index); + return; + } + } print!("func ({}), args: [", func_index); } extern "C" fn end_debug(_ctx: &mut vm::Ctx) { diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index ba1dcba37..f2b48f983 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -13,6 +13,7 @@ use crate::{ types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value}, vm, }; +use hashbrown::HashMap; use std::{mem, sync::Arc}; pub(crate) struct InstanceInner { @@ -39,12 +40,16 @@ impl Drop for InstanceInner { pub struct Instance { module: Arc, inner: Box, - #[allow(dead_code)] + import_object: ImportObject, } impl Instance { - pub(crate) fn new(module: Arc, imports: &ImportObject) -> Result { + pub(crate) fn new( + module: Arc, + imports: &ImportObject, + maybe_symbol_map: Option>, + ) -> Result { // 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 // uninitialized vm::Ctx and then initialize it in-place. @@ -63,7 +68,12 @@ impl Instance { // Initialize the vm::Ctx in-place after the backing // has been boxed. unsafe { - *inner.vmctx = vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module) + *inner.vmctx = vm::Ctx::new( + &mut inner.backing, + &mut inner.import_backing, + &module, + maybe_symbol_map, + ) }; let instance = Instance { diff --git a/lib/runtime-core/src/module.rs b/lib/runtime-core/src/module.rs index 212c197c3..a7fe31412 100644 --- a/lib/runtime-core/src/module.rs +++ b/lib/runtime-core/src/module.rs @@ -100,8 +100,12 @@ impl Module { /// # Ok(()) /// # } /// ``` - pub fn instantiate(&self, import_object: &ImportObject) -> error::Result { - Instance::new(Arc::clone(&self.inner), import_object) + pub fn instantiate( + &self, + import_object: &ImportObject, + maybe_symbol_map: Option>, + ) -> error::Result { + Instance::new(Arc::clone(&self.inner), import_object, maybe_symbol_map) } pub fn cache(&self) -> Result { diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 9a4d332bd..d78bd09fc 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -5,6 +5,7 @@ use crate::{ structures::TypedIndex, types::{LocalOrImport, MemoryIndex}, }; +use hashbrown::HashMap; use std::{ffi::c_void, mem, ptr}; /// The context of the currently running WebAssembly instance. @@ -24,6 +25,8 @@ pub struct Ctx { pub data: *mut c_void, pub data_finalizer: Option, + + pub maybe_symbol_map: Option>, } /// The internal context of the currently running WebAssembly instance. @@ -67,6 +70,7 @@ impl Ctx { local_backing: &mut LocalBacking, import_backing: &mut ImportBacking, module: &ModuleInner, + maybe_symbol_map: Option>, ) -> Self { Self { internal: InternalCtx { @@ -89,6 +93,7 @@ impl Ctx { data: ptr::null_mut(), data_finalizer: None, + maybe_symbol_map, } } @@ -121,6 +126,7 @@ impl Ctx { data, data_finalizer: Some(data_finalizer), + maybe_symbol_map: None, } } diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index 27945aa10..bcd8cf710 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -149,7 +149,7 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult { /// depending on the cause of the failure. pub fn instantiate(wasm: &[u8], import_object: &ImportObject) -> error::Result { let module = compile(wasm)?; - module.instantiate(import_object) + module.instantiate(import_object, None) } /// Get a single instance of the default compiler to use. diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 34064f833..14989effb 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -1,12 +1,13 @@ extern crate structopt; use std::env; -use std::fs::File; +use std::fs::{read_to_string, File}; use std::io; use std::io::Read; use std::path::PathBuf; use std::process::exit; +use hashbrown::HashMap; use structopt::StructOpt; use wasmer::webassembly::InstanceABI; @@ -44,6 +45,10 @@ struct Run { /// Application arguments #[structopt(name = "--", raw(multiple = "true"))] args: Vec, + + /// Symbol map + #[structopt(long = "symbol-map", parse(from_os_str))] + symbol_map: Option, } #[derive(Debug, StructOpt)] @@ -98,6 +103,48 @@ fn execute_wasm(options: &Run) -> Result<(), String> { ) })?; + let maybe_symbol_map = if let Some(symbol_map_path) = options.symbol_map.clone() { + let symbol_map_content: String = read_to_string(&symbol_map_path) + .map_err(|err| { + format!( + "Can't read symbol map file {}: {}", + symbol_map_path.as_os_str().to_string_lossy(), + err, + ) + })? + .to_owned(); + let mut symbol_map = HashMap::new(); + for line in symbol_map_content.lines() { + let mut split = line.split(':'); + let num_str = if let Some(ns) = split.next() { + ns + } else { + return Err(format!( + "Can't parse symbol map (expected each entry to be of the form: `0:func_name`)" + )); + }; + let num: u32 = num_str.parse::().map_err(|err| { + format!( + "Failed to parse {} as a number in symbol map: {}", + num_str, err + ) + })?; + let name_str: String = if let Some(name_str) = split.next() { + name_str + } else { + return Err(format!( + "Can't parse symbol map (expected each entry to be of the form: `0:func_name`)" + )); + } + .to_owned(); + + symbol_map.insert(num, name_str); + } + Some(symbol_map) + } else { + None + }; + if !utils::is_wasm_binary(&wasm_binary) { wasm_binary = wabt::wat2wasm(wasm_binary) .map_err(|e| format!("Can't convert from wast to wasm: {:?}", e))?; @@ -159,7 +206,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> { }; let mut instance = module - .instantiate(&import_object) + .instantiate(&import_object, maybe_symbol_map) .map_err(|e| format!("Can't instantiate module: {:?}", e))?; webassembly::run_instance( diff --git a/src/webassembly.rs b/src/webassembly.rs index 8ae38935b..542a5be9d 100644 --- a/src/webassembly.rs +++ b/src/webassembly.rs @@ -42,7 +42,7 @@ pub fn instantiate(buffer_source: &[u8], import_object: ImportObject) -> Result< let module = compile(&buffer_source[..])?; debug!("webassembly - instantiating"); - let instance = module.instantiate(&import_object)?; + let instance = module.instantiate(&import_object, None)?; debug!("webassembly - instance created"); Ok(ResultObject { From a0809dedbf6297ee03a73dca0075a6087a2cb881 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Tue, 26 Mar 2019 16:57:58 -0700 Subject: [PATCH 02/10] change formatting to match syscalls --- lib/clif-backend/src/resolver.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index 80122cc8f..5a3763827 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -388,7 +388,7 @@ extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) { extern "C" fn start_debug(ctx: &mut vm::Ctx, func_index: u32) { if let Some(symbol_map) = &ctx.maybe_symbol_map { if let Some(fn_name) = symbol_map.get(&func_index) { - print!("func ({} - {}), args: [", fn_name, func_index); + print!("func ({} ({})), args: [", fn_name, func_index); return; } } From f9a29445ca22411456cae1056eecd2534a89618e Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Tue, 26 Mar 2019 17:00:51 -0700 Subject: [PATCH 03/10] fix instatiate calli n c-api --- lib/runtime-c-api/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runtime-c-api/src/lib.rs b/lib/runtime-c-api/src/lib.rs index e83d54bf3..12ca2572b 100644 --- a/lib/runtime-c-api/src/lib.rs +++ b/lib/runtime-c-api/src/lib.rs @@ -481,7 +481,7 @@ pub unsafe extern "C" fn wasmer_module_instantiate( } let module = &*(module as *const Module); - let new_instance = if let Ok(res) = module.instantiate(&import_object) { + let new_instance = if let Ok(res) = module.instantiate(&import_object, None) { res } else { update_last_error(CApiError { From 09068c1a74d6351bc768e9193eea4374fbf2b2a5 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 27 Mar 2019 14:01:27 -0700 Subject: [PATCH 04/10] clean up implementation --- lib/clif-backend/src/lib.rs | 11 ++++++--- lib/clif-backend/src/module.rs | 5 ++-- lib/clif-backend/src/resolver.rs | 16 ++++++------ lib/runtime-core/src/backend.rs | 21 +++++++++++++++- lib/runtime-core/src/instance.rs | 14 ++--------- lib/runtime-core/src/lib.rs | 14 ++++++++++- lib/runtime-core/src/module.rs | 10 +++----- lib/runtime-core/src/vm.rs | 12 ++++----- lib/runtime/src/lib.rs | 11 +++++++-- src/bin/wasmer.rs | 42 ++++++++++++++++++++------------ src/webassembly.rs | 11 ++++++++- 11 files changed, 109 insertions(+), 58 deletions(-) diff --git a/lib/clif-backend/src/lib.rs b/lib/clif-backend/src/lib.rs index 88de51e12..d09da6812 100644 --- a/lib/clif-backend/src/lib.rs +++ b/lib/clif-backend/src/lib.rs @@ -16,7 +16,7 @@ use target_lexicon::Triple; use wasmer_runtime_core::cache::{Artifact, Error as CacheError}; use wasmer_runtime_core::{ - backend::{Compiler, Token}, + backend::{Compiler, CompilerConfig, Token}, error::{CompileError, CompileResult}, module::ModuleInner, }; @@ -39,12 +39,17 @@ impl CraneliftCompiler { impl Compiler for CraneliftCompiler { /// Compiles wasm binary to a wasmer module. - fn compile(&self, wasm: &[u8], _: Token) -> CompileResult { + fn compile( + &self, + wasm: &[u8], + compiler_config: CompilerConfig, + _: Token, + ) -> CompileResult { validate(wasm)?; 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 func_bodies = module_env.translate(wasm)?; diff --git a/lib/clif-backend/src/module.rs b/lib/clif-backend/src/module.rs index 9e934ee0a..2ae495acd 100644 --- a/lib/clif-backend/src/module.rs +++ b/lib/clif-backend/src/module.rs @@ -10,7 +10,7 @@ use std::sync::Arc; use wasmer_runtime_core::cache::{Artifact, Error as CacheError}; use wasmer_runtime_core::{ - backend::Backend, + backend::{Backend, CompilerConfig}, error::CompileResult, module::{ModuleInfo, ModuleInner, StringTable}, structures::{Map, TypedIndex}, @@ -25,7 +25,7 @@ pub struct Module { } impl Module { - pub fn new() -> Self { + pub fn new(compiler_config: &CompilerConfig) -> Self { Self { info: ModuleInfo { memories: Map::new(), @@ -50,6 +50,7 @@ impl Module { namespace_table: StringTable::new(), name_table: StringTable::new(), + em_symbol_map: compiler_config.symbol_map.clone(), }, } } diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index 5a3763827..e2706b6e1 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -374,26 +374,26 @@ fn round_up(n: usize, multiple: usize) -> usize { } 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) { - print!(" i64: {},", n); + eprint!(" i64: {},", n); } 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) { - print!(" f64: {},", n); + eprint!(" f64: {},", n); } 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) { - print!("func ({} ({})), args: [", fn_name, func_index); + eprint!("func ({} ({})), args: [", fn_name, func_index); return; } } - print!("func ({}), args: [", func_index); + eprint!("func ({}), args: [", func_index); } extern "C" fn end_debug(_ctx: &mut vm::Ctx) { - println!(" ]"); + eprintln!(" ]"); } diff --git a/lib/runtime-core/src/backend.rs b/lib/runtime-core/src/backend.rs index a09909ebe..94c5c87e3 100644 --- a/lib/runtime-core/src/backend.rs +++ b/lib/runtime-core/src/backend.rs @@ -14,6 +14,8 @@ use crate::{ }; use std::{any::Any, ptr::NonNull}; +use hashbrown::HashMap; + pub mod 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>, +} + +impl Default for CompilerConfig { + fn default() -> CompilerConfig { + CompilerConfig { symbol_map: None } + } +} + pub trait Compiler { /// Compiles a `Module` from WebAssembly binary format. /// The `CompileToken` parameter ensures that this can only /// be called from inside the runtime. - fn compile(&self, wasm: &[u8], _: Token) -> CompileResult; + fn compile( + &self, + wasm: &[u8], + comp_conf: CompilerConfig, + _: Token, + ) -> CompileResult; unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result; } diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index f2b48f983..0d34bb5a5 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -13,7 +13,6 @@ use crate::{ types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value}, vm, }; -use hashbrown::HashMap; use std::{mem, sync::Arc}; pub(crate) struct InstanceInner { @@ -45,11 +44,7 @@ pub struct Instance { } impl Instance { - pub(crate) fn new( - module: Arc, - imports: &ImportObject, - maybe_symbol_map: Option>, - ) -> Result { + pub(crate) fn new(module: Arc, imports: &ImportObject) -> Result { // 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 // uninitialized vm::Ctx and then initialize it in-place. @@ -68,12 +63,7 @@ impl Instance { // Initialize the vm::Ctx in-place after the backing // has been boxed. unsafe { - *inner.vmctx = vm::Ctx::new( - &mut inner.backing, - &mut inner.import_backing, - &module, - maybe_symbol_map, - ) + *inner.vmctx = vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module) }; let instance = Instance { diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index 663e17534..1565ed621 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -68,7 +68,19 @@ pub fn compile_with( ) -> CompileResult { let token = backend::Token::generate(); 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 { + let token = backend::Token::generate(); + compiler + .compile(wasm, compiler_config, token) .map(|inner| module::Module::new(Arc::new(inner))) } diff --git a/lib/runtime-core/src/module.rs b/lib/runtime-core/src/module.rs index a7fe31412..361ffde7d 100644 --- a/lib/runtime-core/src/module.rs +++ b/lib/runtime-core/src/module.rs @@ -56,6 +56,8 @@ pub struct ModuleInfo { pub namespace_table: StringTable, pub name_table: StringTable, + + pub em_symbol_map: Option>, } /// A compiled WebAssembly module. @@ -100,12 +102,8 @@ impl Module { /// # Ok(()) /// # } /// ``` - pub fn instantiate( - &self, - import_object: &ImportObject, - maybe_symbol_map: Option>, - ) -> error::Result { - Instance::new(Arc::clone(&self.inner), import_object, maybe_symbol_map) + pub fn instantiate(&self, import_object: &ImportObject) -> error::Result { + Instance::new(Arc::clone(&self.inner), import_object) } pub fn cache(&self) -> Result { diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index d78bd09fc..394966d79 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -5,9 +5,10 @@ use crate::{ structures::TypedIndex, types::{LocalOrImport, MemoryIndex}, }; -use hashbrown::HashMap; use std::{ffi::c_void, mem, ptr}; +use hashbrown::HashMap; + /// The context of the currently running WebAssembly instance. /// /// @@ -25,8 +26,6 @@ pub struct Ctx { pub data: *mut c_void, pub data_finalizer: Option, - - pub maybe_symbol_map: Option>, } /// The internal context of the currently running WebAssembly instance. @@ -70,7 +69,6 @@ impl Ctx { local_backing: &mut LocalBacking, import_backing: &mut ImportBacking, module: &ModuleInner, - maybe_symbol_map: Option>, ) -> Self { Self { internal: InternalCtx { @@ -93,7 +91,6 @@ impl Ctx { data: ptr::null_mut(), data_finalizer: None, - maybe_symbol_map, } } @@ -126,7 +123,6 @@ impl Ctx { data, data_finalizer: Some(data_finalizer), - maybe_symbol_map: None, } } @@ -162,6 +158,10 @@ impl Ctx { }, } } + + pub unsafe fn borrow_symbol_map(&self) -> &Option> { + &(*self.module).info.em_symbol_map + } } #[doc(hidden)] diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index bcd8cf710..b589aa28b 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -110,7 +110,7 @@ pub mod units { pub mod cache; -use wasmer_runtime_core::backend::Compiler; +use wasmer_runtime_core::backend::{Compiler, CompilerConfig}; /// Compile WebAssembly binary code into a [`Module`]. /// This function is useful if it is necessary to @@ -129,6 +129,13 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult { wasmer_runtime_core::compile_with(&wasm[..], default_compiler()) } +pub fn compile_with_config( + wasm: &[u8], + compiler_config: CompilerConfig, +) -> error::CompileResult { + wasmer_runtime_core::compile_with_config(&wasm[..], default_compiler(), compiler_config) +} + /// Compile and instantiate WebAssembly code without /// creating a [`Module`]. /// @@ -149,7 +156,7 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult { /// depending on the cause of the failure. pub fn instantiate(wasm: &[u8], import_object: &ImportObject) -> error::Result { let module = compile(wasm)?; - module.instantiate(import_object, None) + module.instantiate(import_object) } /// Get a single instance of the default compiler to use. diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 14989effb..61bd50dac 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -14,6 +14,7 @@ use wasmer::webassembly::InstanceABI; use wasmer::*; use wasmer_emscripten; use wasmer_runtime::cache::{Cache as BaseCache, FileSystemCache, WasmHash, WASMER_VERSION_HASH}; +use wasmer_runtime_core::backend::CompilerConfig; #[derive(Debug, StructOpt)] #[structopt(name = "wasmer", about = "Wasm execution runtime.")] @@ -46,9 +47,9 @@ struct Run { #[structopt(name = "--", raw(multiple = "true"))] args: Vec, - /// Symbol map - #[structopt(long = "symbol-map", parse(from_os_str))] - symbol_map: Option, + /// Emscripten symbol map + #[structopt(long = "em-symbol-map", parse(from_os_str))] + em_symbol_map: Option, } #[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 symbol_map_content: String = read_to_string(&symbol_map_path) + let em_symbol_map = if let Some(em_symbol_map_path) = options.em_symbol_map.clone() { + let em_symbol_map_content: String = read_to_string(&em_symbol_map_path) .map_err(|err| { format!( "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, ) })? .to_owned(); - let mut symbol_map = HashMap::new(); - for line in symbol_map_content.lines() { + let mut em_symbol_map = HashMap::new(); + for line in em_symbol_map_content.lines() { let mut split = line.split(':'); let num_str = if let Some(ns) = split.next() { ns @@ -138,9 +139,9 @@ fn execute_wasm(options: &Run) -> Result<(), String> { } .to_owned(); - symbol_map.insert(num, name_str); + em_symbol_map.insert(num, name_str); } - Some(symbol_map) + Some(em_symbol_map) } else { None }; @@ -175,9 +176,13 @@ fn execute_wasm(options: &Run) -> Result<(), String> { module } Err(_) => { - let module = webassembly::compile(&wasm_binary[..]) - .map_err(|e| format!("Can't compile module: {:?}", e))?; - + let module = webassembly::compile_with_config( + &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 cache.store(hash, module.clone()).unwrap_or_default(); @@ -186,8 +191,13 @@ fn execute_wasm(options: &Run) -> Result<(), String> { }; module } else { - webassembly::compile(&wasm_binary[..]) - .map_err(|e| format!("Can't compile module: {:?}", e))? + webassembly::compile_with_config( + &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) { @@ -206,7 +216,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> { }; let mut instance = module - .instantiate(&import_object, maybe_symbol_map) + .instantiate(&import_object) .map_err(|e| format!("Can't instantiate module: {:?}", e))?; webassembly::run_instance( diff --git a/src/webassembly.rs b/src/webassembly.rs index 542a5be9d..3b7aeaf8f 100644 --- a/src/webassembly.rs +++ b/src/webassembly.rs @@ -4,6 +4,7 @@ use wasmer_runtime::{ error::{CallResult, Result}, ImportObject, Instance, Module, }; +use wasmer_runtime_core::backend::CompilerConfig; use wasmer_runtime_core::types::Value; 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[..])?; debug!("webassembly - instantiating"); - let instance = module.instantiate(&import_object, None)?; + let instance = module.instantiate(&import_object)?; debug!("webassembly - instance created"); Ok(ResultObject { @@ -76,6 +77,14 @@ pub fn compile(buffer_source: &[u8]) -> Result { Ok(module) } +pub fn compile_with_config( + buffer_source: &[u8], + compiler_config: CompilerConfig, +) -> Result { + let module = runtime::compile_with_config(buffer_source, compiler_config)?; + Ok(module) +} + /// Performs common instance operations needed when an instance is first run /// including data setup, handling arguments and calling a main function pub fn run_instance( From 315d8286c438138b7fae0107fdcbc29c118d069f Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 27 Mar 2019 14:08:17 -0700 Subject: [PATCH 05/10] clean up (second pass) --- lib/runtime-core/src/instance.rs | 2 +- lib/runtime-core/src/lib.rs | 3 ++- lib/runtime-core/src/module.rs | 1 + lib/runtime-core/src/vm.rs | 1 + lib/runtime/src/lib.rs | 2 ++ src/webassembly.rs | 2 ++ 6 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index 0d34bb5a5..ba1dcba37 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -39,7 +39,7 @@ impl Drop for InstanceInner { pub struct Instance { module: Arc, inner: Box, - + #[allow(dead_code)] import_object: ImportObject, } diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index 1565ed621..ea20204e4 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -72,7 +72,8 @@ pub fn compile_with( .map(|inner| module::Module::new(Arc::new(inner))) } -/// The same as `compile_with` but takes a symbol map for use with debugging +/// The same as `compile_with` but changes the compiler behavior +/// with the values in the `CompilerConfig` pub fn compile_with_config( wasm: &[u8], compiler: &dyn backend::Compiler, diff --git a/lib/runtime-core/src/module.rs b/lib/runtime-core/src/module.rs index 361ffde7d..3dcc6b7d8 100644 --- a/lib/runtime-core/src/module.rs +++ b/lib/runtime-core/src/module.rs @@ -57,6 +57,7 @@ pub struct ModuleInfo { pub namespace_table: StringTable, pub name_table: StringTable, + /// Symbol information from emscripten pub em_symbol_map: Option>, } diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 394966d79..9fc92abaa 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -159,6 +159,7 @@ impl Ctx { } } + /// Gives access to the emscripten symbol map, used for debugging pub unsafe fn borrow_symbol_map(&self) -> &Option> { &(*self.module).info.em_symbol_map } diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index b589aa28b..66d9c6ace 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -129,6 +129,8 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult { wasmer_runtime_core::compile_with(&wasm[..], default_compiler()) } +/// The same as `compile` but takes a `CompilerConfig` for the purpose of +/// changing the compiler's behavior pub fn compile_with_config( wasm: &[u8], compiler_config: CompilerConfig, diff --git a/src/webassembly.rs b/src/webassembly.rs index 3b7aeaf8f..d34966060 100644 --- a/src/webassembly.rs +++ b/src/webassembly.rs @@ -77,6 +77,8 @@ pub fn compile(buffer_source: &[u8]) -> Result { Ok(module) } +/// The same as `compile` but takes a `CompilerConfig` for the purpose of +/// changing the compiler's behavior pub fn compile_with_config( buffer_source: &[u8], compiler_config: CompilerConfig, From 51c2111d53b36100067df0c9e8591c5e2ec26058 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 27 Mar 2019 14:18:34 -0700 Subject: [PATCH 06/10] pass compiler_config along to other backends --- lib/dynasm-backend/src/lib.rs | 11 ++++++++--- lib/dynasm-backend/src/parse.rs | 3 +++ lib/llvm-backend/src/lib.rs | 11 ++++++++--- lib/llvm-backend/src/read_info.rs | 9 +++++++-- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/lib/dynasm-backend/src/lib.rs b/lib/dynasm-backend/src/lib.rs index 1647611bb..5d1aa5f96 100644 --- a/lib/dynasm-backend/src/lib.rs +++ b/lib/dynasm-backend/src/lib.rs @@ -25,7 +25,7 @@ mod stack; use crate::codegen::{CodegenError, ModuleCodeGenerator}; use crate::parse::LoadError; use wasmer_runtime_core::{ - backend::{sys::Memory, Backend, CacheGen, Compiler, Token}, + backend::{sys::Memory, Backend, CacheGen, Compiler, CompilerConfig, Token}, cache::{Artifact, Error as CacheError}, error::{CompileError, CompileResult}, module::{ModuleInfo, ModuleInner}, @@ -51,9 +51,14 @@ impl SinglePassCompiler { } impl Compiler for SinglePassCompiler { - fn compile(&self, wasm: &[u8], _: Token) -> CompileResult { + fn compile( + &self, + wasm: &[u8], + compiler_config: CompilerConfig, + _: Token, + ) -> CompileResult { let mut mcg = codegen_x64::X64ModuleCodeGenerator::new(); - let info = parse::read_module(wasm, Backend::Dynasm, &mut mcg)?; + let info = parse::read_module(wasm, Backend::Dynasm, &mut mcg, &compiler_config)?; let (ec, resolver) = mcg.finalize(&info)?; Ok(ModuleInner { cache_gen: Box::new(Placeholder), diff --git a/lib/dynasm-backend/src/parse.rs b/lib/dynasm-backend/src/parse.rs index 7e918e942..02de6f067 100644 --- a/lib/dynasm-backend/src/parse.rs +++ b/lib/dynasm-backend/src/parse.rs @@ -70,6 +70,7 @@ pub fn read_module< wasm: &[u8], backend: Backend, mcg: &mut MCG, + compiler_config: &CompilerConfig, ) -> Result { validate(wasm)?; let mut info = ModuleInfo { @@ -95,6 +96,8 @@ pub fn read_module< namespace_table: StringTable::new(), name_table: StringTable::new(), + + em_symbol_map: compiler_config.symbol_map.clone(), }; let mut reader = ModuleReader::new(wasm)?; diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index 85bcc7e19..edb54d28e 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -6,7 +6,7 @@ use inkwell::{ OptimizationLevel, }; use wasmer_runtime_core::{ - backend::{Compiler, Token}, + backend::{Compiler, CompilerConfig, Token}, cache::{Artifact, Error as CacheError}, error::CompileError, module::ModuleInner, @@ -32,10 +32,15 @@ impl LLVMCompiler { } impl Compiler for LLVMCompiler { - fn compile(&self, wasm: &[u8], _: Token) -> Result { + fn compile( + &self, + wasm: &[u8], + compiler_config: CompilerConfig, + _: Token, + ) -> Result { validate(wasm)?; - let (info, code_reader) = read_info::read_module(wasm).unwrap(); + let (info, code_reader) = read_info::read_module(wasm, &compiler_config).unwrap(); let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap(); let (backend, protected_caller) = backend::LLVMBackend::new(module, intrinsics); diff --git a/lib/llvm-backend/src/read_info.rs b/lib/llvm-backend/src/read_info.rs index a974beb59..785359628 100644 --- a/lib/llvm-backend/src/read_info.rs +++ b/lib/llvm-backend/src/read_info.rs @@ -1,5 +1,5 @@ use wasmer_runtime_core::{ - backend::Backend, + backend::{Backend, CompilerConfig}, module::{ DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder, TableInitializer, @@ -18,7 +18,10 @@ use wasmparser::{ SectionCode, Type as WpType, }; -pub fn read_module(wasm: &[u8]) -> Result<(ModuleInfo, CodeSectionReader), BinaryReaderError> { +pub fn read_module( + wasm: &[u8], + compiler_config: &CompilerConfig, +) -> Result<(ModuleInfo, CodeSectionReader), BinaryReaderError> { let mut info = ModuleInfo { memories: Map::new(), globals: Map::new(), @@ -42,6 +45,8 @@ pub fn read_module(wasm: &[u8]) -> Result<(ModuleInfo, CodeSectionReader), Binar namespace_table: StringTable::new(), name_table: StringTable::new(), + + em_symbol_map: compiler_config.symbol_map.clone(), }; let mut reader = ModuleReader::new(wasm)?; From c51d44578df4620246b1d062032a13e1b608da31 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 27 Mar 2019 14:25:29 -0700 Subject: [PATCH 07/10] simplify borrowing inference of compiler config in llvm backend --- lib/llvm-backend/src/lib.rs | 2 +- lib/llvm-backend/src/read_info.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index edb54d28e..c590e2129 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -40,7 +40,7 @@ impl Compiler for LLVMCompiler { ) -> Result { validate(wasm)?; - let (info, code_reader) = read_info::read_module(wasm, &compiler_config).unwrap(); + let (info, code_reader) = read_info::read_module(wasm, compiler_config).unwrap(); let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap(); let (backend, protected_caller) = backend::LLVMBackend::new(module, intrinsics); diff --git a/lib/llvm-backend/src/read_info.rs b/lib/llvm-backend/src/read_info.rs index 785359628..87b44572f 100644 --- a/lib/llvm-backend/src/read_info.rs +++ b/lib/llvm-backend/src/read_info.rs @@ -20,7 +20,7 @@ use wasmparser::{ pub fn read_module( wasm: &[u8], - compiler_config: &CompilerConfig, + compiler_config: CompilerConfig, ) -> Result<(ModuleInfo, CodeSectionReader), BinaryReaderError> { let mut info = ModuleInfo { memories: Map::new(), From 580a153821fa26eb9a0e9c03f9be54c3bcd89dfc Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 27 Mar 2019 14:30:57 -0700 Subject: [PATCH 08/10] fix lint errors --- lib/dynasm-backend/src/parse.rs | 2 +- lib/runtime-c-api/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/dynasm-backend/src/parse.rs b/lib/dynasm-backend/src/parse.rs index 02de6f067..dc4a484d8 100644 --- a/lib/dynasm-backend/src/parse.rs +++ b/lib/dynasm-backend/src/parse.rs @@ -1,6 +1,6 @@ use crate::codegen::{CodegenError, FunctionCodeGenerator, ModuleCodeGenerator}; use wasmer_runtime_core::{ - backend::{Backend, FuncResolver, ProtectedCaller}, + backend::{Backend, CompilerConfig, FuncResolver, ProtectedCaller}, module::{ DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder, TableInitializer, diff --git a/lib/runtime-c-api/src/lib.rs b/lib/runtime-c-api/src/lib.rs index 12ca2572b..e83d54bf3 100644 --- a/lib/runtime-c-api/src/lib.rs +++ b/lib/runtime-c-api/src/lib.rs @@ -481,7 +481,7 @@ pub unsafe extern "C" fn wasmer_module_instantiate( } let module = &*(module as *const Module); - let new_instance = if let Ok(res) = module.instantiate(&import_object, None) { + let new_instance = if let Ok(res) = module.instantiate(&import_object) { res } else { update_last_error(CApiError { From 764ec96ad1ea1e868ccf3bbfdc64aac7309dc679 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 28 Mar 2019 09:20:54 -0700 Subject: [PATCH 09/10] fix compilation error --- lib/runtime-core/src/vm.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 9fc92abaa..8b970587e 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -615,6 +615,8 @@ mod vm_ctx_tests { namespace_table: StringTable::new(), name_table: StringTable::new(), + + em_symbol_map: None, }, } } From a0e20667b53812af8956613c4811ae71685e8696 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 28 Mar 2019 10:08:41 -0700 Subject: [PATCH 10/10] add small fix --- lib/llvm-backend/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index c590e2129..ee4e02bbc 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -126,7 +126,7 @@ fn test_read_module() { "#; let wasm = wat2wasm(wat).unwrap(); - let (info, code_reader) = read_info::read_module(&wasm).unwrap(); + let (info, code_reader) = read_info::read_module(&wasm, Default::default()).unwrap(); let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap();