diff --git a/lib/execute/src/lib.rs b/lib/execute/src/lib.rs index af7ab95352..f77781da01 100644 --- a/lib/execute/src/lib.rs +++ b/lib/execute/src/lib.rs @@ -7,11 +7,11 @@ extern crate cretonne_wasm; extern crate region; extern crate wasmstandalone_runtime; -use cretonne_codegen::isa::TargetIsa; use cretonne_codegen::binemit::Reloc; -use std::mem::transmute; -use region::Protection; +use cretonne_codegen::isa::TargetIsa; use region::protect; +use region::Protection; +use std::mem::transmute; use std::ptr::write_unaligned; use wasmstandalone_runtime::Compilation; @@ -21,8 +21,8 @@ pub fn compile_module<'data, 'module>( translation: &wasmstandalone_runtime::ModuleTranslation<'data, 'module>, ) -> Result, String> { debug_assert!( - translation.module.start_func.is_none() || - translation.module.start_func.unwrap() >= translation.module.imported_funcs.len(), + translation.module.start_func.is_none() + || translation.module.start_func.unwrap() >= translation.module.imported_funcs.len(), "imported start functions not supported yet" ); @@ -53,8 +53,8 @@ fn relocate(compilation: &mut Compilation, relocations: &wasmstandalone_runtime: let reloc_address = body.as_mut_ptr().offset(r.offset as isize) as isize; let reloc_addend = r.addend as isize; // TODO: Handle overflow. - let reloc_delta_i32 = (target_func_address - reloc_address + reloc_addend) as - i32; + let reloc_delta_i32 = + (target_func_address - reloc_address + reloc_addend) as i32; write_unaligned(reloc_address as *mut i32, reloc_delta_i32); }, _ => panic!("unsupported reloc kind"), @@ -81,9 +81,10 @@ pub fn execute( compilation: &wasmstandalone_runtime::Compilation, instance: &mut wasmstandalone_runtime::Instance, ) -> Result<(), String> { - let start_index = compilation.module.start_func.ok_or_else(|| { - String::from("No start function defined, aborting execution") - })?; + let start_index = compilation + .module + .start_func + .ok_or_else(|| String::from("No start function defined, aborting execution"))?; // TODO: Put all the function bodies into a page-aligned memory region, and // then make them ReadExecute rather than ReadWriteExecute. for code_buf in &compilation.functions { diff --git a/lib/obj/src/emit_module.rs b/lib/obj/src/emit_module.rs index 429d60ae45..7c3f01264a 100644 --- a/lib/obj/src/emit_module.rs +++ b/lib/obj/src/emit_module.rs @@ -11,15 +11,15 @@ pub fn emit_module<'module>( relocations: &wasmstandalone_runtime::Relocations, ) -> Result<(), String> { debug_assert!( - compilation.module.start_func.is_none() || - compilation.module.start_func.unwrap() >= compilation.module.imported_funcs.len(), + compilation.module.start_func.is_none() + || compilation.module.start_func.unwrap() >= compilation.module.imported_funcs.len(), "imported start functions not supported yet" ); let mut shared_builder = settings::builder(); - shared_builder.enable("enable_verifier").expect( - "Missing enable_verifier setting", - ); + shared_builder + .enable("enable_verifier") + .expect("Missing enable_verifier setting"); for (i, function_relocs) in relocations.iter().enumerate() { assert!(function_relocs.is_empty(), "relocations not supported yet"); @@ -27,9 +27,8 @@ pub fn emit_module<'module>( let func_index = compilation.module.imported_funcs.len() + i; let string_name = format!("wasm_function[{}]", func_index); - obj.define(string_name, body.clone()).map_err(|err| { - format!("{}", err) - })?; + obj.define(string_name, body.clone()) + .map_err(|err| format!("{}", err))?; } Ok(()) diff --git a/lib/runtime/src/instance.rs b/lib/runtime/src/instance.rs index edea184a52..fdc4e5993f 100644 --- a/lib/runtime/src/instance.rs +++ b/lib/runtime/src/instance.rs @@ -3,7 +3,7 @@ use cretonne_codegen::ir; use cretonne_wasm::GlobalIndex; -use module::Module; +use module::{Module, TableElements}; use DataInitializer; const PAGE_SIZE: usize = 65536; @@ -29,15 +29,14 @@ impl Instance { memories: Vec::new(), globals: Vec::new(), }; - result.instantiate_tables(module); + result.instantiate_tables(module, &module.table_elements); result.instantiate_memories(module, data_initializers); result.instantiate_globals(module); result } - /// Allocate memory in `self` for just the tables of the current module, - /// without any initializers applied yet. - fn instantiate_tables(&mut self, module: &Module) { + /// Allocate memory in `self` for just the tables of the current module. + fn instantiate_tables(&mut self, module: &Module, table_initializers: &[TableElements]) { debug_assert!(self.tables.is_empty()); self.tables.reserve_exact(module.tables.len()); for table in &module.tables { @@ -46,10 +45,15 @@ impl Instance { v.resize(len, 0); self.tables.push(v); } + for init in table_initializers { + debug_assert!(init.base.is_none(), "globalvar base not supported yet"); + let to_init = + &mut self.tables[init.table_index][init.offset..init.offset + init.elements.len()]; + to_init.copy_from_slice(&init.elements); + } } - /// Allocate memory in `instance` for just the memories of the current module, - /// without any initializers applied yet. + /// Allocate memory in `instance` for just the memories of the current module. fn instantiate_memories(&mut self, module: &Module, data_initializers: &[DataInitializer]) { debug_assert!(self.memories.is_empty()); // Allocate the underlying memory and initialize it to all zeros. @@ -62,8 +66,8 @@ impl Instance { } for init in data_initializers { debug_assert!(init.base.is_none(), "globalvar base not supported yet"); - let to_init = &mut self.memories[init.memory_index][init.offset.. - init.offset + init.data.len()]; + let to_init = + &mut self.memories[init.memory_index][init.offset..init.offset + init.data.len()]; to_init.copy_from_slice(init.data); } } @@ -79,12 +83,9 @@ impl Instance { /// Returns a slice of the contents of allocated linear memory. pub fn inspect_memory(&self, memory_index: usize, address: usize, len: usize) -> &[u8] { - &self.memories.get(memory_index).expect( - format!( - "no memory for index {}", - memory_index - ).as_str(), - ) + &self.memories + .get(memory_index) + .expect(format!("no memory for index {}", memory_index).as_str()) [address..address + len] } diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index e8e5d54600..b1e72fa4ba 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -9,25 +9,25 @@ extern crate cretonne_codegen; extern crate cretonne_wasm; extern crate wasmparser; -pub mod module; pub mod compilation; pub mod instance; +pub mod module; -pub use module::Module; pub use compilation::Compilation; pub use instance::Instance; +pub use module::Module; -use cretonne_wasm::{FunctionIndex, GlobalIndex, TableIndex, MemoryIndex, Global, Table, Memory, - GlobalValue, SignatureIndex, FuncTranslator}; -use cretonne_codegen::ir::{InstBuilder, FuncRef, ExtFuncData, ExternalName, Signature, AbiParam, - ArgumentPurpose, ArgumentLoc, ArgumentExtension, Function}; -use cretonne_codegen::ir::types::*; -use cretonne_codegen::ir::immediates::Offset32; +use cretonne_codegen::binemit; use cretonne_codegen::cursor::FuncCursor; use cretonne_codegen::ir; +use cretonne_codegen::ir::immediates::Offset32; +use cretonne_codegen::ir::types::*; +use cretonne_codegen::ir::{AbiParam, ArgumentExtension, ArgumentLoc, ArgumentPurpose, ExtFuncData, + ExternalName, FuncRef, Function, InstBuilder, Signature}; use cretonne_codegen::isa; use cretonne_codegen::settings; -use cretonne_codegen::binemit; +use cretonne_wasm::{FuncTranslator, FunctionIndex, Global, GlobalIndex, GlobalValue, Memory, + MemoryIndex, SignatureIndex, Table, TableIndex}; /// Compute a `ir::ExternalName` for a given wasm function index. pub fn get_func_name(func_index: FunctionIndex) -> cretonne_codegen::ir::ExternalName { @@ -96,7 +96,9 @@ impl binemit::RelocSink for RelocSink { impl RelocSink { fn new() -> RelocSink { - RelocSink { func_relocs: Vec::new() } + RelocSink { + func_relocs: Vec::new(), + } } } @@ -221,7 +223,11 @@ impl<'module_environment> FuncEnvironment<'module_environment> { } fn ptr_size(&self) -> usize { - if self.settings_flags.is_64bit() { 8 } else { 4 } + if self.settings_flags.is_64bit() { + 8 + } else { + 4 + } } } @@ -275,7 +281,9 @@ impl<'module_environment> cretonne_wasm::FuncEnvironment for FuncEnvironment<'mo base: ir::HeapBase::GlobalVar(heap_base), min_size: 0.into(), guard_size: 0x8000_0000.into(), - style: ir::HeapStyle::Static { bound: 0x1_0000_0000.into() }, + style: ir::HeapStyle::Static { + bound: 0x1_0000_0000.into(), + }, }); h } @@ -422,10 +430,9 @@ impl<'data, 'module> cretonne_wasm::ModuleEnvironment<'data> for ModuleEnvironme ); self.module.functions.push(sig_index); - self.module.imported_funcs.push(( - String::from(module), - String::from(field), - )); + self.module + .imported_funcs + .push((String::from(module), String::from(field))); } fn get_num_func_imports(&self) -> usize { @@ -489,31 +496,27 @@ impl<'data, 'module> cretonne_wasm::ModuleEnvironment<'data> for ModuleEnvironme } fn declare_func_export(&mut self, func_index: FunctionIndex, name: &str) { - self.module.exports.insert( - String::from(name), - module::Export::Function(func_index), - ); + self.module + .exports + .insert(String::from(name), module::Export::Function(func_index)); } fn declare_table_export(&mut self, table_index: TableIndex, name: &str) { - self.module.exports.insert( - String::from(name), - module::Export::Table(table_index), - ); + self.module + .exports + .insert(String::from(name), module::Export::Table(table_index)); } fn declare_memory_export(&mut self, memory_index: MemoryIndex, name: &str) { - self.module.exports.insert( - String::from(name), - module::Export::Memory(memory_index), - ); + self.module + .exports + .insert(String::from(name), module::Export::Memory(memory_index)); } fn declare_global_export(&mut self, global_index: GlobalIndex, name: &str) { - self.module.exports.insert( - String::from(name), - module::Export::Global(global_index), - ); + self.module + .exports + .insert(String::from(name), module::Export::Global(global_index)); } fn declare_start_func(&mut self, func_index: FunctionIndex) { @@ -573,8 +576,8 @@ impl<'data, 'module> ModuleTranslation<'data, 'module> { let func_index = i + self.module.imported_funcs.len(); let mut context = cretonne_codegen::Context::new(); context.func.name = get_func_name(func_index); - context.func.signature = self.module.signatures[self.module.functions[func_index]] - .clone(); + context.func.signature = + self.module.signatures[self.module.functions[func_index]].clone(); let mut trans = FuncTranslator::new(); let reader = wasmparser::BinaryReader::new(input); diff --git a/lib/runtime/src/module.rs b/lib/runtime/src/module.rs index d4ffefa0e0..3b33c6b3b3 100644 --- a/lib/runtime/src/module.rs +++ b/lib/runtime/src/module.rs @@ -1,9 +1,9 @@ //! A `Module` contains all the relevant information translated from a //! WebAssembly module. -use cretonne_wasm::{FunctionIndex, GlobalIndex, TableIndex, MemoryIndex, Global, Table, Memory, - SignatureIndex}; use cretonne_codegen::ir; +use cretonne_wasm::{FunctionIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, + Table, TableIndex}; use std::collections::HashMap; /// Possible values for a WebAssembly table element. diff --git a/src/main.rs b/src/main.rs index 2a84ba0ba3..7280d29b0b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,31 +6,31 @@ //! and tables, then emitting the translated code with hardcoded addresses to memory. extern crate cretonne_codegen; -extern crate cretonne_wasm; extern crate cretonne_native; -extern crate wasmstandalone_runtime; -extern crate wasmstandalone_execute; +extern crate cretonne_wasm; extern crate docopt; +extern crate wasmstandalone_execute; +extern crate wasmstandalone_runtime; #[macro_use] extern crate serde_derive; extern crate tempdir; -use cretonne_wasm::translate_module; -use wasmstandalone_execute::{compile_module, execute}; -use wasmstandalone_runtime::{Instance, Module, ModuleEnvironment}; -use std::path::PathBuf; use cretonne_codegen::isa::TargetIsa; use cretonne_codegen::settings; -use std::fs::File; -use std::error::Error; -use std::io; -use std::io::stdout; -use std::io::prelude::*; +use cretonne_codegen::settings::Configurable; +use cretonne_wasm::translate_module; use docopt::Docopt; +use std::error::Error; +use std::fs::File; +use std::io; +use std::io::prelude::*; +use std::io::stdout; use std::path::Path; +use std::path::PathBuf; use std::process::{exit, Command}; use tempdir::TempDir; -use cretonne_codegen::settings::Configurable; +use wasmstandalone_execute::{compile_module, execute}; +use wasmstandalone_runtime::{Instance, Module, ModuleEnvironment}; const USAGE: &str = " Wasm to Cretonne IL translation utility. @@ -99,9 +99,7 @@ fn main() { } fn handle_module(args: &Args, path: PathBuf, isa: &TargetIsa) -> Result<(), String> { - let mut data = read_to_end(path.clone()).map_err(|err| { - String::from(err.description()) - })?; + let mut data = read_to_end(path.clone()).map_err(|err| String::from(err.description()))?; if !data.starts_with(&[b'\0', b'a', b's', b'm']) { let tmp_dir = TempDir::new("cretonne-wasm").unwrap(); let file_path = tmp_dir.path().join("module.wasm"); @@ -111,14 +109,14 @@ fn handle_module(args: &Args, path: PathBuf, isa: &TargetIsa) -> Result<(), Stri .arg("-o") .arg(file_path.to_str().unwrap()) .output() - .or_else(|e| if let io::ErrorKind::NotFound = e.kind() { - return Err(String::from("wat2wasm not found")); - } else { - return Err(String::from(e.description())); + .or_else(|e| { + if let io::ErrorKind::NotFound = e.kind() { + return Err(String::from("wat2wasm not found")); + } else { + return Err(String::from(e.description())); + } })?; - data = read_to_end(file_path).map_err( - |err| String::from(err.description()), - )?; + data = read_to_end(file_path).map_err(|err| String::from(err.description()))?; } let mut module = Module::new(); let mut environ = ModuleEnvironment::new(isa.flags(), &mut module); diff --git a/src/wasm2obj.rs b/src/wasm2obj.rs index 2693666f6c..156a7c92cb 100644 --- a/src/wasm2obj.rs +++ b/src/wasm2obj.rs @@ -7,27 +7,27 @@ extern crate cretonne_codegen; extern crate cretonne_native; extern crate cretonne_wasm; +extern crate docopt; extern crate wasmstandalone_obj; extern crate wasmstandalone_runtime; -extern crate docopt; #[macro_use] extern crate serde_derive; extern crate faerie; -use cretonne_wasm::translate_module; -use cretonne_codegen::settings; use cretonne_codegen::isa; -use wasmstandalone_obj::emit_module; -use std::path::PathBuf; -use std::fs::File; +use cretonne_codegen::settings; +use cretonne_wasm::translate_module; +use docopt::Docopt; +use faerie::{Artifact, Elf, Target}; use std::error::Error; +use std::fmt::format; +use std::fs::File; use std::io; use std::io::prelude::*; -use docopt::Docopt; use std::path::Path; +use std::path::PathBuf; use std::process; -use std::fmt::format; -use faerie::{Artifact, Elf, Target}; +use wasmstandalone_obj::emit_module; const USAGE: &str = " Wasm to native object translation utility. @@ -100,9 +100,8 @@ fn handle_module(path: PathBuf, output: &str) -> Result<(), String> { // FIXME: We need to initialize memory in a way that supports alternate // memory spaces, imported base addresses, and offsets. for init in &environ.lazy.data_initializers { - obj.define("memory", Vec::from(init.data)).map_err(|err| { - format!("{}", err) - })?; + obj.define("memory", Vec::from(init.data)) + .map_err(|err| format!("{}", err))?; } let translation = environ.finish_translation(); @@ -119,12 +118,10 @@ fn handle_module(path: PathBuf, output: &str) -> Result<(), String> { } // FIXME: Make the format a parameter. - let file = ::std::fs::File::create(Path::new(output)).map_err(|x| { - format(format_args!("{}", x)) - })?; - obj.write::(file).map_err( - |x| format(format_args!("{}", x)), - )?; + let file = + ::std::fs::File::create(Path::new(output)).map_err(|x| format(format_args!("{}", x)))?; + obj.write::(file) + .map_err(|x| format(format_args!("{}", x)))?; Ok(()) }