mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 00:00:49 +00:00
merge and respond to feedback
This commit is contained in:
commit
5294eb6b0d
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2196,6 +2196,7 @@ version = "0.2.1"
|
||||
dependencies = [
|
||||
"errno 0.2.4 (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)",
|
||||
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmer-clif-backend 0.2.0",
|
||||
|
@ -22,6 +22,7 @@ include = [
|
||||
errno = "0.2.4"
|
||||
structopt = "0.2.11"
|
||||
wabt = "0.7.2"
|
||||
hashbrown = "0.1.8"
|
||||
wasmer-clif-backend = { path = "lib/clif-backend" }
|
||||
wasmer-dynasm-backend = { path = "lib/dynasm-backend", optional = true }
|
||||
wasmer-runtime = { path = "lib/runtime" }
|
||||
|
@ -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<ModuleInner> {
|
||||
fn compile(
|
||||
&self,
|
||||
wasm: &[u8],
|
||||
compiler_config: CompilerConfig,
|
||||
_: Token,
|
||||
) -> CompileResult<ModuleInner> {
|
||||
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)?;
|
||||
|
@ -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(),
|
||||
|
||||
custom_sections: HashMap::new(),
|
||||
},
|
||||
|
@ -374,20 +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) {
|
||||
print!("func ({}), args: [", func_index);
|
||||
extern "C" fn start_debug(ctx: &mut vm::Ctx, func_index: u32) {
|
||||
if let Some(symbol_map) = unsafe { ctx.borrow_symbol_map() } {
|
||||
if let Some(fn_name) = symbol_map.get(&func_index) {
|
||||
eprint!("func ({} ({})), args: [", fn_name, func_index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
eprint!("func ({}), args: [", func_index);
|
||||
}
|
||||
extern "C" fn end_debug(_ctx: &mut vm::Ctx) {
|
||||
println!(" ]");
|
||||
eprintln!(" ]");
|
||||
}
|
||||
|
@ -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<ModuleInner> {
|
||||
fn compile(
|
||||
&self,
|
||||
wasm: &[u8],
|
||||
compiler_config: CompilerConfig,
|
||||
_: Token,
|
||||
) -> CompileResult<ModuleInner> {
|
||||
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),
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::codegen::{CodegenError, FunctionCodeGenerator, ModuleCodeGenerator};
|
||||
use hashbrown::HashMap;
|
||||
use wasmer_runtime_core::{
|
||||
backend::{Backend, FuncResolver, ProtectedCaller},
|
||||
backend::{Backend, CompilerConfig, FuncResolver, ProtectedCaller},
|
||||
module::{
|
||||
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
|
||||
TableInitializer,
|
||||
@ -71,6 +71,7 @@ pub fn read_module<
|
||||
wasm: &[u8],
|
||||
backend: Backend,
|
||||
mcg: &mut MCG,
|
||||
compiler_config: &CompilerConfig,
|
||||
) -> Result<ModuleInfo, LoadError> {
|
||||
validate(wasm)?;
|
||||
let mut info = ModuleInfo {
|
||||
@ -97,6 +98,8 @@ pub fn read_module<
|
||||
namespace_table: StringTable::new(),
|
||||
name_table: StringTable::new(),
|
||||
|
||||
em_symbol_map: compiler_config.symbol_map.clone(),
|
||||
|
||||
custom_sections: HashMap::new(),
|
||||
};
|
||||
|
||||
|
@ -123,7 +123,7 @@ impl EmscriptenVfs {
|
||||
Some(FileHandle::Vf(file)) => {
|
||||
let count = {
|
||||
let mut result = RefCell::borrow_mut(&file);
|
||||
let result = result.read(buf_slice);
|
||||
let result = result.read_file(buf_slice, 0);
|
||||
result.unwrap()
|
||||
};
|
||||
count as _
|
||||
|
@ -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<ModuleInner, CompileError> {
|
||||
fn compile(
|
||||
&self,
|
||||
wasm: &[u8],
|
||||
compiler_config: CompilerConfig,
|
||||
_: Token,
|
||||
) -> Result<ModuleInner, CompileError> {
|
||||
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);
|
||||
@ -121,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();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use wasmer_runtime_core::{
|
||||
backend::Backend,
|
||||
backend::{Backend, CompilerConfig},
|
||||
module::{
|
||||
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
|
||||
TableInitializer,
|
||||
@ -20,7 +20,10 @@ use wasmparser::{
|
||||
|
||||
use hashbrown::HashMap;
|
||||
|
||||
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(),
|
||||
@ -45,6 +48,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(),
|
||||
|
||||
custom_sections: HashMap::new(),
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::vfs::file_like::{FileLike, Metadata};
|
||||
use failure::Error;
|
||||
use std::io;
|
||||
use std::io::{Read, Write};
|
||||
use std::io::{Seek, Write};
|
||||
|
||||
pub struct Stdin;
|
||||
pub struct Stdout;
|
||||
@ -15,10 +15,18 @@ impl FileLike for Stdin {
|
||||
fn write_file(&mut self, _buf: &[u8], _offset: usize) -> Result<usize, io::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_file(&mut self, _buf: &mut [u8], _offset: usize) -> Result<usize, io::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> {
|
||||
panic!("Cannot set length of stdin");
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for Stdin {
|
||||
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, io::Error> {
|
||||
impl io::Seek for Stdin {
|
||||
fn seek(&mut self, _pos: io::SeekFrom) -> Result<u64, io::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
@ -33,10 +41,19 @@ impl FileLike for Stdout {
|
||||
let mut handle = stdout.lock();
|
||||
handle.write(buf)
|
||||
}
|
||||
|
||||
fn read_file(&mut self, _buf: &mut [u8], _offset: usize) -> Result<usize, io::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> {
|
||||
panic!("Cannot set length of stdout");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for Stdout {
|
||||
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, io::Error> {
|
||||
impl io::Seek for Stdout {
|
||||
fn seek(&mut self, _pos: io::SeekFrom) -> Result<u64, io::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
@ -51,10 +68,18 @@ impl FileLike for Stderr {
|
||||
let mut handle = stderr.lock();
|
||||
handle.write(buf)
|
||||
}
|
||||
|
||||
fn read_file(&mut self, _buf: &mut [u8], _offset: usize) -> Result<usize, io::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_file_len(&mut self, _len: usize) -> Result<(), failure::Error> {
|
||||
panic!("Cannot set length of stderr");
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for Stderr {
|
||||
fn read(&mut self, _buf: &mut [u8]) -> Result<usize, io::Error> {
|
||||
impl io::Seek for Stderr {
|
||||
fn seek(&mut self, _pos: io::SeekFrom) -> Result<u64, io::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,16 @@ pub struct Metadata {
|
||||
pub is_file: bool,
|
||||
}
|
||||
|
||||
pub trait FileLike: std::io::Read {
|
||||
pub trait FileLike: std::io::Seek {
|
||||
// get metadata
|
||||
fn metadata(&self) -> Result<Metadata, failure::Error>;
|
||||
|
||||
// write
|
||||
fn write_file(&mut self, buf: &[u8], offset: usize) -> Result<usize, io::Error>;
|
||||
|
||||
// read
|
||||
fn read_file(&mut self, buf: &mut [u8], offset: usize) -> Result<usize, io::Error>;
|
||||
|
||||
// set_file_len
|
||||
fn set_file_len(&mut self, len: usize) -> Result<(), failure::Error>;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use failure::Error;
|
||||
|
||||
use crate::vfs::file_like::{FileLike, Metadata};
|
||||
use std::io;
|
||||
use std::io::{Seek, SeekFrom, Write};
|
||||
use std::io::{Seek, SeekFrom, Write, Read};
|
||||
|
||||
impl FileLike for zbox::File {
|
||||
fn metadata(&self) -> Result<Metadata, Error> {
|
||||
@ -20,4 +20,13 @@ impl FileLike for zbox::File {
|
||||
self.finish().unwrap();
|
||||
result
|
||||
}
|
||||
|
||||
fn read_file(&mut self, buf: &mut [u8], offset: usize) -> Result<usize, io::Error> {
|
||||
self.seek(io::SeekFrom::Start(offset as u64))?;
|
||||
self.read(buf)
|
||||
}
|
||||
|
||||
fn set_file_len(&mut self, len: usize) -> Result<(), failure::Error> {
|
||||
self.set_len(len).map_err(|e| e.into())
|
||||
}
|
||||
}
|
||||
|
@ -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<HashMap<u32, String>>,
|
||||
}
|
||||
|
||||
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<ModuleInner>;
|
||||
fn compile(
|
||||
&self,
|
||||
wasm: &[u8],
|
||||
comp_conf: CompilerConfig,
|
||||
_: Token,
|
||||
) -> CompileResult<ModuleInner>;
|
||||
|
||||
unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>;
|
||||
}
|
||||
|
@ -67,13 +67,26 @@ pub fn compile_with(
|
||||
compiler: &dyn backend::Compiler,
|
||||
) -> CompileResult<module::Module> {
|
||||
let token = backend::Token::generate();
|
||||
compiler.compile(wasm, token).map(|mut inner| {
|
||||
compiler.compile(wasm, Default::default(), token).map(|mut inner| {
|
||||
let inner_info: &mut crate::module::ModuleInfo = &mut inner.info;
|
||||
inner_info.import_custom_sections(wasm).unwrap();
|
||||
module::Module::new(Arc::new(inner))
|
||||
})
|
||||
}
|
||||
|
||||
/// 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,
|
||||
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)))
|
||||
}
|
||||
|
||||
/// Perform validation as defined by the
|
||||
/// WebAssembly specification. Returns `true` if validation
|
||||
/// succeeded, `false` if validation failed.
|
||||
|
@ -57,6 +57,9 @@ pub struct ModuleInfo {
|
||||
pub namespace_table: StringTable<NamespaceIndex>,
|
||||
pub name_table: StringTable<NameIndex>,
|
||||
|
||||
/// Symbol information from emscripten
|
||||
pub em_symbol_map: Option<HashMap<u32, String>>,
|
||||
|
||||
pub custom_sections: HashMap<String, Vec<u8>>,
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@ use crate::{
|
||||
};
|
||||
use std::{ffi::c_void, mem, ptr};
|
||||
|
||||
use hashbrown::HashMap;
|
||||
|
||||
/// The context of the currently running WebAssembly instance.
|
||||
///
|
||||
///
|
||||
@ -156,6 +158,11 @@ impl Ctx {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Gives access to the emscripten symbol map, used for debugging
|
||||
pub unsafe fn borrow_symbol_map(&self) -> &Option<HashMap<u32, String>> {
|
||||
&(*self.module).info.em_symbol_map
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
@ -609,6 +616,8 @@ mod vm_ctx_tests {
|
||||
namespace_table: StringTable::new(),
|
||||
name_table: StringTable::new(),
|
||||
|
||||
em_symbol_map: None,
|
||||
|
||||
custom_sections: HashMap::new(),
|
||||
},
|
||||
}
|
||||
|
@ -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,15 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult<Module> {
|
||||
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,
|
||||
) -> error::CompileResult<Module> {
|
||||
wasmer_runtime_core::compile_with_config(&wasm[..], default_compiler(), compiler_config)
|
||||
}
|
||||
|
||||
/// Compile and instantiate WebAssembly code without
|
||||
/// creating a [`Module`].
|
||||
///
|
||||
|
@ -1,18 +1,20 @@
|
||||
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;
|
||||
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.")]
|
||||
@ -44,6 +46,10 @@ struct Run {
|
||||
/// Application arguments
|
||||
#[structopt(name = "--", raw(multiple = "true"))]
|
||||
args: Vec<String>,
|
||||
|
||||
/// Emscripten symbol map
|
||||
#[structopt(long = "em-symbol-map", parse(from_os_str))]
|
||||
em_symbol_map: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
@ -98,6 +104,48 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
)
|
||||
})?;
|
||||
|
||||
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 {}: {}",
|
||||
em_symbol_map_path.as_os_str().to_string_lossy(),
|
||||
err,
|
||||
)
|
||||
})?
|
||||
.to_owned();
|
||||
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
|
||||
} 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();
|
||||
|
||||
em_symbol_map.insert(num, name_str);
|
||||
}
|
||||
Some(em_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))?;
|
||||
@ -128,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();
|
||||
|
||||
@ -139,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) {
|
||||
|
@ -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};
|
||||
@ -76,6 +77,16 @@ pub fn compile(buffer_source: &[u8]) -> Result<Module> {
|
||||
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,
|
||||
) -> 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
|
||||
/// including data setup, handling arguments and calling a main function
|
||||
pub fn run_instance(
|
||||
|
Loading…
x
Reference in New Issue
Block a user