add support for symbol maps

This commit is contained in:
Mark McCaskey
2019-03-26 16:41:40 -07:00
parent ad897b2076
commit 9c58bed344
9 changed files with 85 additions and 10 deletions

1
Cargo.lock generated
View File

@ -1330,6 +1330,7 @@ name = "wasmer"
version = "0.2.1" version = "0.2.1"
dependencies = [ dependencies = [
"glob 0.2.11 (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.8 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.2.15 (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)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-clif-backend 0.2.0", "wasmer-clif-backend 0.2.0",

View File

@ -21,6 +21,7 @@ include = [
[dependencies] [dependencies]
structopt = "0.2.11" structopt = "0.2.11"
wabt = "0.7.2" wabt = "0.7.2"
hashbrown = "0.1.8"
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-runtime-core = { path = "lib/runtime-core" } wasmer-runtime-core = { path = "lib/runtime-core" }

View File

@ -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) { extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) {
print!(" f64: {},", n); 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); print!("func ({}), args: [", func_index);
} }
extern "C" fn end_debug(_ctx: &mut vm::Ctx) { extern "C" fn end_debug(_ctx: &mut vm::Ctx) {

View File

@ -13,6 +13,7 @@ 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 {
@ -39,12 +40,16 @@ impl Drop for InstanceInner {
pub struct Instance { pub struct Instance {
module: Arc<ModuleInner>, module: Arc<ModuleInner>,
inner: Box<InstanceInner>, inner: Box<InstanceInner>,
#[allow(dead_code)]
import_object: ImportObject, import_object: ImportObject,
} }
impl Instance { impl Instance {
pub(crate) fn new(module: Arc<ModuleInner>, imports: &ImportObject) -> Result<Instance> { pub(crate) fn new(
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.
@ -63,7 +68,12 @@ 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(&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 { let instance = Instance {

View File

@ -100,8 +100,12 @@ impl Module {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
pub fn instantiate(&self, import_object: &ImportObject) -> error::Result<Instance> { pub fn instantiate(
Instance::new(Arc::clone(&self.inner), import_object) &self,
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,6 +5,7 @@ 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};
/// The context of the currently running WebAssembly instance. /// The context of the currently running WebAssembly instance.
@ -24,6 +25,8 @@ 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.
@ -67,6 +70,7 @@ 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 {
@ -89,6 +93,7 @@ impl Ctx {
data: ptr::null_mut(), data: ptr::null_mut(),
data_finalizer: None, data_finalizer: None,
maybe_symbol_map,
} }
} }
@ -121,6 +126,7 @@ impl Ctx {
data, data,
data_finalizer: Some(data_finalizer), data_finalizer: Some(data_finalizer),
maybe_symbol_map: None,
} }
} }

View File

@ -149,7 +149,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) module.instantiate(import_object, None)
} }
/// Get a single instance of the default compiler to use. /// Get a single instance of the default compiler to use.

View File

@ -1,12 +1,13 @@
extern crate structopt; extern crate structopt;
use std::env; use std::env;
use std::fs::File; use std::fs::{read_to_string, File};
use std::io; use std::io;
use std::io::Read; use std::io::Read;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::exit; use std::process::exit;
use hashbrown::HashMap;
use structopt::StructOpt; use structopt::StructOpt;
use wasmer::webassembly::InstanceABI; use wasmer::webassembly::InstanceABI;
@ -44,6 +45,10 @@ struct Run {
/// Application arguments /// Application arguments
#[structopt(name = "--", raw(multiple = "true"))] #[structopt(name = "--", raw(multiple = "true"))]
args: Vec<String>, args: Vec<String>,
/// Symbol map
#[structopt(long = "symbol-map", parse(from_os_str))]
symbol_map: Option<PathBuf>,
} }
#[derive(Debug, StructOpt)] #[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::<u32>().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) { if !utils::is_wasm_binary(&wasm_binary) {
wasm_binary = wabt::wat2wasm(wasm_binary) wasm_binary = wabt::wat2wasm(wasm_binary)
.map_err(|e| format!("Can't convert from wast to wasm: {:?}", e))?; .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 let mut instance = module
.instantiate(&import_object) .instantiate(&import_object, maybe_symbol_map)
.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

@ -42,7 +42,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)?; let instance = module.instantiate(&import_object, None)?;
debug!("webassembly - instance created"); debug!("webassembly - instance created");
Ok(ResultObject { Ok(ResultObject {