Formatted files

This commit is contained in:
Syrus Akbary
2018-10-14 23:48:59 +02:00
parent 48fbc850ea
commit a9a580acee
8 changed files with 182 additions and 140 deletions

View File

@ -1,5 +1,5 @@
use core::ptr::NonNull;
use core::ops::{Index, IndexMut};
use core::ptr::NonNull;
#[derive(Copy, Clone)]
#[repr(transparent)]
@ -17,7 +17,7 @@ impl<T> UncheckedSlice<T> {
#[inline]
unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
let ptr = self.ptr.as_ptr();
&mut*(ptr.add(index) as *mut _)
&mut *(ptr.add(index) as *mut _)
}
pub unsafe fn dangling() -> UncheckedSlice<T> {
@ -38,9 +38,7 @@ impl<T> UncheckedSlice<T> {
impl<'a, T> From<&'a [T]> for UncheckedSlice<T> {
fn from(slice: &[T]) -> UncheckedSlice<T> {
let ptr: NonNull<[T]> = slice.into();
UncheckedSlice {
ptr: ptr.cast(),
}
UncheckedSlice { ptr: ptr.cast() }
}
}
@ -52,9 +50,7 @@ pub struct BoundedSlice<T> {
impl<T> BoundedSlice<T> {
pub fn get(&self, index: usize) -> Option<&T> {
if index < self.len {
unsafe {
Some(self.data.get_unchecked(index))
}
unsafe { Some(self.data.get_unchecked(index)) }
} else {
None
}
@ -62,9 +58,7 @@ impl<T> BoundedSlice<T> {
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
if index < self.len {
unsafe {
Some(self.data.get_unchecked_mut(index))
}
unsafe { Some(self.data.get_unchecked_mut(index)) }
} else {
None
}

View File

@ -2,29 +2,28 @@
extern crate error_chain;
#[macro_use]
extern crate structopt;
extern crate wabt;
extern crate cranelift_codegen;
extern crate cranelift_entity;
extern crate cranelift_native;
extern crate cranelift_wasm;
extern crate cranelift_entity;
extern crate wabt;
#[macro_use]
extern crate target_lexicon;
extern crate spin;
use std::path::PathBuf;
use std::error::Error;
use std::fs::File;
use std::io;
use std::io::Read;
use std::path::PathBuf;
use std::process::exit;
use std::error::Error;
use structopt::StructOpt;
use wabt::wat2wasm;
pub mod webassembly;
pub mod spec;
pub mod common;
pub mod spec;
pub mod webassembly;
#[derive(Debug, StructOpt)]
#[structopt(name = "wasmer", about = "WASM execution runtime.")]
@ -32,7 +31,7 @@ pub mod common;
enum CLIOptions {
/// Run a WebAssembly file. Formats accepted: wasm, wast
#[structopt(name = "run")]
Run(Run)
Run(Run),
}
#[derive(Debug, StructOpt)]
@ -44,7 +43,7 @@ struct Run {
path: PathBuf,
}
/// Read the contents of a file
/// Read the contents of a file
fn read_file_contents(path: PathBuf) -> Result<Vec<u8>, io::Error> {
let mut buffer: Vec<u8> = Vec::new();
let mut file = File::open(path)?;
@ -53,12 +52,11 @@ fn read_file_contents(path: PathBuf) -> Result<Vec<u8>, io::Error> {
}
/// Execute a WASM/WAT file
fn execute_wasm(wasm_path: PathBuf) -> Result<(), String>{
let mut wasm_binary: Vec<u8> = read_file_contents(wasm_path).map_err(|err| String::from(err.description()))?;
fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> {
let mut wasm_binary: Vec<u8> =
read_file_contents(wasm_path).map_err(|err| String::from(err.description()))?;
if !webassembly::utils::is_wasm_binary(&wasm_binary) {
wasm_binary = wat2wasm(
wasm_binary
).map_err(|err| String::from(err.description()))?;
wasm_binary = wat2wasm(wasm_binary).map_err(|err| String::from(err.description()))?;
}
webassembly::instantiate(wasm_binary, None).map_err(|err| String::from(err.description()))?;

View File

@ -70,9 +70,9 @@ wast total: 0 passed; 17955 failed
//! ```
pub extern crate wabt;
pub use wabt::script::Value;
pub use wabt::script::Action;
pub use wabt::script::CommandKind;
pub use wabt::script::Value;
use std::path::Path;
use wabt::script::*;
@ -93,7 +93,12 @@ pub trait ScriptHandler {
///
/// Targets either the last loaded module if `module` is None, or
/// the module registered with the given name otherwise.
fn action_invoke(&mut self, module: Option<String>, field: String, args: Vec<Value>) -> InvokationResult;
fn action_invoke(
&mut self,
module: Option<String>,
field: String,
args: Vec<Value>,
) -> InvokationResult;
/// Handles an `get` action.
///
@ -110,16 +115,18 @@ pub trait ScriptHandler {
/// if a function call trapped or exhausted the stack.
fn action(&mut self, action: Action) -> Vec<Value> {
match action {
Action::Invoke { module, field, args } => {
Action::Invoke {
module,
field,
args,
} => {
if let InvokationResult::Vals(v) = self.action_invoke(module, field, args) {
v
} else {
panic!("invokation returned Trap or exhausted the stack");
}
}
Action::Get { module, field } => {
vec![self.action_get(module, field)]
}
Action::Get { module, field } => vec![self.action_get(module, field)],
}
}
@ -151,14 +158,16 @@ pub trait ScriptHandler {
/// does not trap, or refers to an global.
fn assert_trap(&mut self, action: Action) {
match action {
Action::Invoke { module, field, args } => {
Action::Invoke {
module,
field,
args,
} => {
if let InvokationResult::Vals(results) = self.action_invoke(module, field, args) {
panic!("invokation did not trap, but returned {:?}", results);
}
}
Action::Get { .. } => {
panic!("a global access can not trap!")
}
Action::Get { .. } => panic!("a global access can not trap!"),
}
}
@ -267,27 +276,26 @@ impl<'a> ::std::cmp::PartialEq for NanCompare<'a> {
if self.0.len() != other.0.len() {
return false;
}
self.0.iter().zip(other.0.iter()).all(|pair| {
match pair {
(Value::I32(l), Value::I32(r)) => l == r,
(Value::I64(l), Value::I64(r)) => l == r,
(Value::F32(l), Value::F32(r)) if l.is_nan() && r.is_nan() => {
l.payload() == r.payload()
},
(Value::F64(l), Value::F64(r)) if l.is_nan() && r.is_nan() => {
l.payload() == r.payload()
},
(Value::F32(l), Value::F32(r)) => l == r,
(Value::F64(l), Value::F64(r)) => l == r,
_ => false,
self.0.iter().zip(other.0.iter()).all(|pair| match pair {
(Value::I32(l), Value::I32(r)) => l == r,
(Value::I64(l), Value::I64(r)) => l == r,
(Value::F32(l), Value::F32(r)) if l.is_nan() && r.is_nan() => {
l.payload() == r.payload()
}
(Value::F64(l), Value::F64(r)) if l.is_nan() && r.is_nan() => {
l.payload() == r.payload()
}
(Value::F32(l), Value::F32(r)) => l == r,
(Value::F64(l), Value::F64(r)) => l == r,
_ => false,
})
}
}
impl<'a> ::std::fmt::Debug for NanCompare<'a> {
fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
formatter.debug_list().entries(self.0.iter().map(|e| {
match e {
formatter
.debug_list()
.entries(self.0.iter().map(|e| match e {
Value::F32(v) if v.is_nan() => {
let p = v.payload();
format!("F32(NaN:0x{:x})", p)
@ -296,9 +304,9 @@ impl<'a> ::std::fmt::Debug for NanCompare<'a> {
let p = v.payload();
format!("F64(NaN:0x{:x})", p)
}
_ => format!("{:?}", e)
}
})).finish()
_ => format!("{:?}", e),
}))
.finish()
}
}
@ -344,8 +352,12 @@ impl NanPayload for f32 {
let p = bits & mask;
p as u64
}
fn signif() -> u32 { 23 }
fn infinite() -> Self { 1.0 / 0.0 }
fn signif() -> u32 {
23
}
fn infinite() -> Self {
1.0 / 0.0
}
fn canonical_payload() -> u64 {
1u64 << (Self::signif() - 1)
}
@ -374,8 +386,12 @@ impl NanPayload for f64 {
let p = bits & mask;
p
}
fn signif() -> u32 { 52 }
fn infinite() -> Self { 1.0 / 0.0 }
fn signif() -> u32 {
52
}
fn infinite() -> Self {
1.0 / 0.0
}
fn canonical_payload() -> u64 {
1u64 << (Self::signif() - 1)
}
@ -423,24 +439,38 @@ impl SpectestResult {
break;
}
}
println!("wast total: {} passed; {} failed", self.successes, self.failures.len());
println!(
"wast total: {} passed; {} failed",
self.successes,
self.failures.len()
);
panic!("some wast commands failed");
} else {
println!("wast total: {} passed; {} failed", self.successes, self.failures.len());
println!(
"wast total: {} passed; {} failed",
self.successes,
self.failures.len()
);
}
}
}
/// Run all scripts of the bundled webassembly testsuite on `handler`.
pub fn run_mvp_spectest<T: ScriptHandler>(handler: &mut T) -> SpectestResult {
run_all_in_directory(format!("{}/testsuite", env!("CARGO_MANIFEST_DIR")).as_ref(), handler)
run_all_in_directory(
format!("{}/testsuite", env!("CARGO_MANIFEST_DIR")).as_ref(),
handler,
)
}
/// Module that is expected under the name "spectest" by all spectest testcases.
///
/// This is automatically registered by all `run_` functions in this modules
/// that work at file granularity or higher.
pub const SPECTEST_MODULE: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/spec/spectest.wasm"));
pub const SPECTEST_MODULE: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/src/spec/spectest.wasm"
));
/// Run all scripts in a given directory on `handler`.
pub fn run_all_in_directory<T: ScriptHandler>(path: &Path, handler: &mut T) -> SpectestResult {
@ -480,7 +510,7 @@ pub fn run_single_file<T: ScriptHandler>(path: &Path, handler: &mut T) -> Specte
let filename = path.file_name().unwrap().to_str().unwrap();
let source = fs::read(&path).unwrap();
let mut script = ScriptParser::<>::from_source_and_name(&source, filename).unwrap();
let mut script = ScriptParser::from_source_and_name(&source, filename).unwrap();
let mut fatal = false;
handler.reset();
@ -507,7 +537,8 @@ pub fn run_single_file<T: ScriptHandler>(path: &Path, handler: &mut T) -> Specte
match r {
Err(msg) => {
res.failures.push(("<internal spectest module>".to_owned(), 0, msg));
res.failures
.push(("<internal spectest module>".to_owned(), 0, msg));
fatal = true;
}
Ok(()) => {
@ -518,7 +549,8 @@ pub fn run_single_file<T: ScriptHandler>(path: &Path, handler: &mut T) -> Specte
while let Some(Command { line, kind }) = script.next().unwrap() {
if fatal {
res.failures.push((filename.to_owned(), line, "<not attempted>".to_string()));
res.failures
.push((filename.to_owned(), line, "<not attempted>".to_string()));
continue;
}
match run_single_command(kind, handler) {
@ -541,7 +573,10 @@ pub fn run_single_file<T: ScriptHandler>(path: &Path, handler: &mut T) -> Specte
/// Note that `T` needs to be exception safe, in the sense that any
/// panic that happened during a method call should not affect it beyond
/// a subsequent `reset()` call.
pub fn run_single_command<T: ScriptHandler>(kind: CommandKind, handler: &mut T) -> Result<(), String> {
pub fn run_single_command<T: ScriptHandler>(
kind: CommandKind,
handler: &mut T,
) -> Result<(), String> {
use std::panic::*;
if let Err(msg) = catch_unwind(AssertUnwindSafe(|| {

View File

@ -1,15 +1,15 @@
use std::path::Path;
use std::collections::HashMap;
use std::path::Path;
use std::rc::Rc;
use wabt::script::{Value, Action};
use super::{InvokationResult, ScriptHandler, run_single_file};
use super::{run_single_file, InvokationResult, ScriptHandler};
use crate::webassembly::{compile, instantiate, Error, ErrorKind, Module};
use wabt::script::{Action, Value};
// use crate::webassembly::instance::InvokeResult;
struct StoreCtrl<'module> {
last_module: Option<Module>,
modules: HashMap<String, Rc<&'module Module>>
modules: HashMap<String, Rc<&'module Module>>,
}
impl<'module> StoreCtrl<'module> {
@ -112,8 +112,7 @@ impl<'module> ScriptHandler for StoreCtrl<'module> {
// println!("action invoke {}", module.unwrap_or("as".to_string()));
// let modul = &self.last_module;
// modul.expect("a");
//
//
}
fn action_get(&mut self, module: Option<String>, field: String) -> Value {
// println!("action get");
@ -131,7 +130,7 @@ impl<'module> ScriptHandler for StoreCtrl<'module> {
let module_wrapped = instantiate(bytes, None);
match module_wrapped {
Err(ErrorKind::CompileError(v)) => {}
_ => panic!("Module compilation should have failed")
_ => panic!("Module compilation should have failed"),
}
}
fn assert_invalid(&mut self, bytes: Vec<u8>) {
@ -140,7 +139,7 @@ impl<'module> ScriptHandler for StoreCtrl<'module> {
// print!("IS INVALID?? {:?}", module_wrapped);
match module_wrapped {
Err(ErrorKind::CompileError(v)) => {}
_ => assert!(false, "Module compilation should have failed")
_ => assert!(false, "Module compilation should have failed"),
}
}
fn assert_uninstantiable(&mut self, bytes: Vec<u8>) {
@ -157,7 +156,11 @@ impl<'module> ScriptHandler for StoreCtrl<'module> {
fn do_test(test_name: String) {
let mut handler = &mut StoreCtrl::new();
let test_path_str = format!("{}/src/spec/tests/{}.wast", env!("CARGO_MANIFEST_DIR"), test_name);
let test_path_str = format!(
"{}/src/spec/tests/{}.wast",
env!("CARGO_MANIFEST_DIR"),
test_name
);
let test_path = Path::new(&test_path_str);
let res = run_single_file(&test_path, handler);
res.present()

View File

@ -6,20 +6,24 @@
//! synchronously instantiate a given webassembly::Module object. However, the
//! primary way to get an Instance is through the asynchronous
//! webassembly::instantiateStreaming() function.
use cranelift_wasm::{GlobalInit, FuncIndex};
use super::module::Module;
use super::module::{DataInitializer, Exportable};
use cranelift_entity::EntityRef;
use cranelift_wasm::{FuncIndex, GlobalInit};
use super::memory::LinearMemory;
use std::marker::PhantomData;
use std::{slice, mem};
use std::sync::Arc;
use std::{mem, slice};
use spin::RwLock;
use super::super::common::slice::{BoundedSlice, UncheckedSlice};
use spin::RwLock;
pub fn get_function_addr(base: *const (), functions: &[usize], func_index: &FuncIndex) -> *const () {
pub fn get_function_addr(
base: *const (),
functions: &[usize],
func_index: &FuncIndex,
) -> *const () {
let offset = functions[func_index.index()];
(base as usize + offset) as _
}
@ -30,18 +34,14 @@ pub enum VmCtx {}
impl VmCtx {
pub fn data(&self) -> &VmCtxData {
let heap_ptr = self as *const _ as *const VmCtxData;
unsafe {
&*heap_ptr.sub(1)
}
unsafe { &*heap_ptr.sub(1) }
}
/// This is safe because the offset is 32 bits and thus
/// cannot extend out of the guarded wasm memory.
pub fn fastpath_offset_ptr<T>(&self, offset: u32) -> *const T {
let heap_ptr = self as *const _ as *const u8;
unsafe {
heap_ptr.add(offset as usize) as *const T
}
unsafe { heap_ptr.add(offset as usize) as *const T }
}
}
@ -60,7 +60,6 @@ pub struct UserData {
pub instance: Instance,
}
/// An Instance of a WebAssembly module
#[derive(Debug)]
pub struct Instance {
@ -93,7 +92,10 @@ impl Instance {
}
// instantiate tables
for table_element in &module.info.table_elements {
assert!(table_element.base.is_none(), "globalvalue base not supported yet.");
assert!(
table_element.base.is_none(),
"globalvalue base not supported yet."
);
let base = 0;
let table = &mut tables[table_element.table_index];
@ -116,7 +118,8 @@ impl Instance {
memories.reserve_exact(module.info.memories.len());
for memory in &module.info.memories {
let memory = memory.entity;
let v = LinearMemory::new(memory.pages_count as u32, memory.maximum.map(|m| m as u32));
let v =
LinearMemory::new(memory.pages_count as u32, memory.maximum.map(|m| m as u32));
memories.push(v);
}
for init in &module.info.data_initializers {
@ -135,7 +138,9 @@ impl Instance {
globals.resize(globals_data_size, 0);
// cast the globals slice to a slice of i64.
let globals_data = unsafe { slice::from_raw_parts_mut(globals.as_mut_ptr() as *mut i64, globals_count) };
let globals_data = unsafe {
slice::from_raw_parts_mut(globals.as_mut_ptr() as *mut i64, globals_count)
};
for (i, global) in module.info.globals.iter().enumerate() {
let value: i64 = match global.entity.initializer {
GlobalInit::I32Const(n) => n as _,
@ -144,7 +149,7 @@ impl Instance {
GlobalInit::F64Const(f) => unsafe { mem::transmute(f) },
_ => unimplemented!(),
};
globals_data[i] = value;
}
};
@ -167,7 +172,6 @@ impl Instance {
// pub fn start_func(&self) -> extern fn(&VmCtx) {
// self.start_func
// }
}
impl Clone for Instance {

View File

@ -1,24 +1,24 @@
pub mod errors;
pub mod utils;
pub mod module;
pub mod memory;
pub mod instance;
pub mod memory;
pub mod module;
pub mod utils;
use std::str::FromStr;
use std::time::{Duration, Instant};
use cranelift_codegen::isa;
use cranelift_native;
use std::panic;
use std::ptr;
use cranelift_native;
use std::str::FromStr;
use std::time::{Duration, Instant};
use target_lexicon::{self, Triple};
use wasmparser;
use cranelift_codegen::isa;
// use cranelift_codegen::print_errors::pretty_verifier_error;
// use cranelift_codegen::verifier;
pub use self::module::Module;
pub use self::instance::Instance;
pub use self::errors::{Error, ErrorKind};
pub use self::instance::Instance;
pub use self::memory::LinearMemory;
pub use self::module::Module;
pub struct ResultObject {
/// A webassembly::Module object representing the compiled WebAssembly module.
@ -29,13 +29,12 @@ pub struct ResultObject {
pub instance: Instance,
}
pub struct ImportObject {
}
pub struct ImportObject {}
/// The webassembly::instantiate() function allows you to compile and
/// instantiate WebAssembly code
/// Params:
/// Params:
/// * `buffer_source`: A `Vec<u8>` containing the
/// binary code of the .wasm module you want to compile.
@ -46,16 +45,16 @@ pub struct ImportObject {
/// webassembly::LinkError is thrown.
/// Errors:
/// If the operation fails, the Result rejects with a
/// If the operation fails, the Result rejects with a
/// webassembly::CompileError, webassembly::LinkError, or
/// webassembly::RuntimeError, depending on the cause of the failure.
pub fn instantiate(buffer_source: Vec<u8>, import_object: Option<ImportObject>) -> Result<ResultObject, ErrorKind> {
pub fn instantiate(
buffer_source: Vec<u8>,
import_object: Option<ImportObject>,
) -> Result<ResultObject, ErrorKind> {
let module = compile(buffer_source)?;
let instance = Instance::new(&module, ptr::null(), &vec![]);
Ok(ResultObject{
module,
instance
})
Ok(ResultObject { module, instance })
}
/// The webassembly::compile() function compiles a webassembly::Module
@ -63,19 +62,19 @@ pub fn instantiate(buffer_source: Vec<u8>, import_object: Option<ImportObject>)
/// is necessary to a compile a module before it can be instantiated
/// (otherwise, the webassembly::instantiate() function should be used).
/// Params:
/// Params:
/// * `buffer_source`: A `Vec<u8>` containing the
/// binary code of the .wasm module you want to compile.
/// Errors:
/// If the operation fails, the Result rejects with a
/// If the operation fails, the Result rejects with a
/// webassembly::CompileError.
pub fn compile(buffer_source: Vec<u8>) -> Result<Module, ErrorKind> {
// TODO: This should be automatically validated when creating the Module
if !validate(&buffer_source) {
return Err(ErrorKind::CompileError("Module not valid".to_string()));
}
let module = Module::from_bytes(buffer_source, triple!("riscv64"), None)?;
// let isa = isa::lookup(module.info.triple)
@ -87,7 +86,7 @@ pub fn compile(buffer_source: Vec<u8>) -> Result<Module, ErrorKind> {
// .map_err(|errors| panic!(pretty_verifier_error(func, Some(&*isa), None, errors)))
// .unwrap();
// };
Ok(module)
}
@ -95,7 +94,7 @@ pub fn compile(buffer_source: Vec<u8>) -> Result<Module, ErrorKind> {
/// array of WebAssembly binary code, returning whether the bytes
/// form a valid wasm module (true) or not (false).
/// Params:
/// Params:
/// * `buffer_source`: A `Vec<u8>` containing the
/// binary code of the .wasm module you want to compile.
pub fn validate(buffer_source: &Vec<u8>) -> bool {

View File

@ -4,27 +4,39 @@
use cranelift_codegen::cursor::FuncCursor;
use cranelift_codegen::ir::immediates::{Imm64, Offset32};
use cranelift_codegen::ir::types::*;
use cranelift_codegen::ir::{self, InstBuilder, FuncRef, ExtFuncData, ExternalName, Signature, AbiParam,
ArgumentPurpose, ArgumentLoc, ArgumentExtension, Function};
use cranelift_codegen::ir::{
self, AbiParam, ArgumentExtension, ArgumentLoc, ArgumentPurpose, ExtFuncData, ExternalName,
FuncRef, Function, InstBuilder, Signature,
};
use cranelift_codegen::settings;
use cranelift_entity::{EntityRef, PrimaryMap};
use super::errors::ErrorKind;
use super::memory::LinearMemory;
use cranelift_wasm::{
translate_module, // ReturnMode,
DefinedFuncIndex,
FuncEnvironment as FuncEnvironmentTrait,
FuncIndex,
FuncTranslator,
Global,
GlobalIndex,
GlobalVariable,
Memory,
MemoryIndex,
ModuleEnvironment,
SignatureIndex,
Table,
TableIndex,
WasmResult,
};
use std::string::String;
use std::vec::Vec;
use target_lexicon::{Triple, PointerWidth};
use cranelift_wasm::{
FuncTranslator,
FuncEnvironment as FuncEnvironmentTrait, GlobalVariable, ModuleEnvironment, WasmResult,
DefinedFuncIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, Table,
TableIndex, translate_module, // ReturnMode,
};
use super::memory::LinearMemory;
use target_lexicon::{PointerWidth, Triple};
// use alloc::vec::Vec;
// use alloc::string::String;
/// Compute a `ir::ExternalName` for a given wasm function index.
fn get_func_name(func_index: FuncIndex) -> ir::ExternalName {
ir::ExternalName::user(0, func_index.index() as u32)
@ -124,7 +136,6 @@ impl ModuleInfo {
}
}
/// A data initializer for linear memory.
#[derive(Debug)]
pub struct DataInitializer {
@ -138,7 +149,6 @@ pub struct DataInitializer {
pub data: Vec<u8>,
}
/// Possible values for a WebAssembly table element.
#[derive(Clone, Debug)]
pub enum TableElement {
@ -161,7 +171,6 @@ pub struct TableElements {
pub elements: Vec<FuncIndex>,
}
/// This `ModuleEnvironment` implementation is a "naïve" one, doing essentially nothing and
/// emitting placeholders when forced to. Don't try to execute code translated for this
/// environment, essentially here for translation debug purposes.
@ -174,7 +183,6 @@ pub struct Module {
/// Vector of wasm bytecode size for each function.
pub func_bytecode_sizes: Vec<usize>,
// How to return from functions.
// return_mode: ReturnMode,
}
@ -204,11 +212,13 @@ impl Module {
// }
// }
pub fn from_bytes(buffer_source: Vec<u8>, triple: Triple, flags: Option<settings::Flags>) -> Result<Self, ErrorKind> {
pub fn from_bytes(
buffer_source: Vec<u8>,
triple: Triple,
flags: Option<settings::Flags>,
) -> Result<Self, ErrorKind> {
// let return_mode = ReturnMode::NormalReturns;
let flags = flags.unwrap_or_else(|| {
settings::Flags::new(settings::builder())
});
let flags = flags.unwrap_or_else(|| settings::Flags::new(settings::builder()));
let mut module = Self {
info: ModuleInfo::with_triple_flags(triple, flags),
trans: FuncTranslator::new(),
@ -216,7 +226,8 @@ impl Module {
// return_mode,
};
// We iterate through the source bytes, generating the compiled module
translate_module(&buffer_source, &mut module).map_err(|e| ErrorKind::CompileError(e.to_string()))?;
translate_module(&buffer_source, &mut module)
.map_err(|e| ErrorKind::CompileError(e.to_string()))?;
Ok(module)
}
@ -247,18 +258,17 @@ impl Module {
))
}
}
}
/// The `FuncEnvironment` implementation for use by the `Module`.
pub struct FuncEnvironment<'environment> {
pub mod_info: &'environment ModuleInfo,
// return_mode: ReturnMode,
}
impl<'environment> FuncEnvironment<'environment> {
pub fn new(mod_info: &'environment ModuleInfo) -> Self { // , return_mode: ReturnMode
pub fn new(mod_info: &'environment ModuleInfo) -> Self {
// , return_mode: ReturnMode
Self {
mod_info,
// return_mode,
@ -406,7 +416,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> {
let base = self.mod_info.tables_base.unwrap_or_else(|| {
let tables_offset = self.ptr_size() as i32 * -1;
let new_base = func.create_global_value(ir::GlobalValueData::VMContext { });
let new_base = func.create_global_value(ir::GlobalValueData::VMContext {});
// {
// offset: tables_offset.into(),
// });
@ -435,7 +445,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> {
let new_table_bounds = func.create_global_value(ir::GlobalValueData::Load {
base: new_table_bounds_addr,
offset: 0.into(),
global_type: I32, // Might be self.pointer_type()
global_type: I32, // Might be self.pointer_type()
});
let table = func.create_table(ir::TableData {
@ -444,7 +454,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> {
// min_size: (self.mod_info.tables[table_index].size as i64).into(),
bound_gv: new_table_bounds,
element_size: (ptr_size as i64).into(),
index_type: I32
index_type: I32,
});
table

View File

@ -1,4 +1,3 @@
/// Detect if a provided binary is a WASM file
pub fn is_wasm_binary(binary: &Vec<u8>) -> bool {
binary.starts_with(&[b'\0', b'a', b's', b'm'])