diff --git a/src/apis/emscripten/env.rs b/src/apis/emscripten/env.rs index 3fc257f21..4db47ed99 100644 --- a/src/apis/emscripten/env.rs +++ b/src/apis/emscripten/env.rs @@ -1,20 +1,10 @@ -/// NOTE: These syscalls only support wasm_32 for now because they take u32 offset - -use libc::{ - c_int, - c_void, - size_t, - ssize_t, - exit, - read, - open, - close, -}; -use std::os::raw::c_char; -use std::ffi::CStr; use super::super::host; +/// NOTE: These syscalls only support wasm_32 for now because they take u32 offset +use libc::{c_int, c_void, close, exit, open, read, size_t, ssize_t}; +use std::ffi::CStr; +use std::os::raw::c_char; -use crate::webassembly::{Instance}; +use crate::webassembly::Instance; /// emscripten: _getenv pub extern "C" fn _getenv(name_ptr: c_int, instance: &mut Instance) -> c_int { @@ -27,8 +17,6 @@ pub extern "C" fn _getenv(name_ptr: c_int, instance: &mut Instance) -> c_int { Ok(_) => { unimplemented!(); } - Err(_) => { - 0 - } + Err(_) => 0, } } diff --git a/src/apis/emscripten/memory.rs b/src/apis/emscripten/memory.rs index 8a9181a59..e9a39f96d 100644 --- a/src/apis/emscripten/memory.rs +++ b/src/apis/emscripten/memory.rs @@ -1,17 +1,20 @@ -use libc::{ - c_void, - size_t, - memcpy, -}; +use libc::{c_void, memcpy, size_t}; -use crate::webassembly::{Instance}; +use crate::webassembly::Instance; /// emscripten: _emscripten_memcpy_big -pub extern "C" fn _emscripten_memcpy_big(dest: u32, src: u32, len: u32, instance: &mut Instance) -> u32 { +pub extern "C" fn _emscripten_memcpy_big( + dest: u32, + src: u32, + len: u32, + instance: &mut Instance, +) -> u32 { debug!("emscripten::_emscripten_memcpy_big"); let dest_addr = instance.memory_offset_addr(0, dest as usize) as *mut c_void; let src_addr = instance.memory_offset_addr(0, src as usize) as *mut c_void; - unsafe { memcpy(dest_addr, src_addr, len as size_t); } + unsafe { + memcpy(dest_addr, src_addr, len as size_t); + } dest } diff --git a/src/apis/emscripten/mod.rs b/src/apis/emscripten/mod.rs index 4ff3b1699..121ff9504 100644 --- a/src/apis/emscripten/mod.rs +++ b/src/apis/emscripten/mod.rs @@ -2,35 +2,87 @@ use crate::webassembly::{ImportObject, ImportValue}; // EMSCRIPTEN APIS mod env; +mod io; mod memory; mod process; -mod io; -mod utils; mod syscalls; +mod utils; // SYSCALLS -use super::host; pub use self::utils::is_emscripten_module; +use super::host; pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> { let mut import_object = ImportObject::new(); import_object.set("env", "printf", ImportValue::Func(io::printf as *const u8)); - import_object.set("env", "putchar", ImportValue::Func(io::putchar as *const u8)); + import_object.set( + "env", + "putchar", + ImportValue::Func(io::putchar as *const u8), + ); // Emscripten Env - import_object.set("env", "_getenv", ImportValue::Func(env::_getenv as *const u8)); + import_object.set( + "env", + "_getenv", + ImportValue::Func(env::_getenv as *const u8), + ); // Emscripten syscalls - import_object.set("env", "___syscall3", ImportValue::Func(syscalls::___syscall3 as *const u8)); - import_object.set("env", "___syscall4", ImportValue::Func(syscalls::___syscall4 as *const u8)); - import_object.set("env", "___syscall5", ImportValue::Func(syscalls::___syscall5 as *const u8)); - import_object.set("env", "___syscall54", ImportValue::Func(syscalls::___syscall54 as *const u8)); - import_object.set("env", "___syscall122", ImportValue::Func(syscalls::___syscall122 as *const u8)); + import_object.set( + "env", + "___syscall3", + ImportValue::Func(syscalls::___syscall3 as *const u8), + ); + import_object.set( + "env", + "___syscall4", + ImportValue::Func(syscalls::___syscall4 as *const u8), + ); + import_object.set( + "env", + "___syscall5", + ImportValue::Func(syscalls::___syscall5 as *const u8), + ); + import_object.set( + "env", + "___syscall54", + ImportValue::Func(syscalls::___syscall54 as *const u8), + ); + import_object.set( + "env", + "___syscall122", + ImportValue::Func(syscalls::___syscall122 as *const u8), + ); // Emscripten other APIs - import_object.set("env", "abort", ImportValue::Func(process::em_abort as *const u8)); - import_object.set("env", "_abort", ImportValue::Func(process::_abort as *const u8)); - import_object.set("env", "abortOnCannotGrowMemory", ImportValue::Func(process::abort_on_cannot_grow_memory as *const u8)); - import_object.set("env", "_emscripten_memcpy_big", ImportValue::Func(memory::_emscripten_memcpy_big as *const u8)); - import_object.set("env", "enlargeMemory", ImportValue::Func(memory::enlarge_memory as *const u8)); - import_object.set("env", "getTotalMemory", ImportValue::Func(memory::get_total_memory as *const u8)); + import_object.set( + "env", + "abort", + ImportValue::Func(process::em_abort as *const u8), + ); + import_object.set( + "env", + "_abort", + ImportValue::Func(process::_abort as *const u8), + ); + import_object.set( + "env", + "abortOnCannotGrowMemory", + ImportValue::Func(process::abort_on_cannot_grow_memory as *const u8), + ); + import_object.set( + "env", + "_emscripten_memcpy_big", + ImportValue::Func(memory::_emscripten_memcpy_big as *const u8), + ); + import_object.set( + "env", + "enlargeMemory", + ImportValue::Func(memory::enlarge_memory as *const u8), + ); + import_object.set( + "env", + "getTotalMemory", + ImportValue::Func(memory::get_total_memory as *const u8), + ); import_object } diff --git a/src/apis/emscripten/process.rs b/src/apis/emscripten/process.rs index 750bc9f69..89ebffade 100644 --- a/src/apis/emscripten/process.rs +++ b/src/apis/emscripten/process.rs @@ -1,14 +1,14 @@ use libc::{ - // c_int, - // c_void, - c_char, // size_t, // ssize_t, abort, + // c_int, + // c_void, + c_char, }; +use crate::webassembly::Instance; use std::ffi::CStr; -use crate::webassembly::{Instance}; extern "C" fn abort_with_message(message: &str) { debug!("emscripten::abort_with_message"); @@ -19,7 +19,9 @@ extern "C" fn abort_with_message(message: &str) { /// emscripten: _abort pub extern "C" fn _abort() { debug!("emscripten::_abort"); - unsafe { abort(); } + unsafe { + abort(); + } } /// emscripten: abort @@ -40,4 +42,3 @@ pub extern "C" fn abort_on_cannot_grow_memory() { debug!("emscripten::abort_on_cannot_grow_memory"); abort_with_message("Cannot enlarge memory arrays!"); } - diff --git a/src/apis/emscripten/syscalls.rs b/src/apis/emscripten/syscalls.rs index 6b572f76f..59c27b794 100644 --- a/src/apis/emscripten/syscalls.rs +++ b/src/apis/emscripten/syscalls.rs @@ -1,23 +1,12 @@ /// NOTE: These syscalls only support wasm_32 for now because they take u32 offset /// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html - -use libc::{ - c_int, - c_void, - size_t, - ssize_t, - exit, - read, - write, - open, - close, -}; +use libc::{c_int, c_void, close, exit, open, read, size_t, ssize_t, write}; use std::{mem, ptr}; -use std::os::raw::c_char; use std::ffi::CStr; +use std::os::raw::c_char; -use crate::webassembly::{Instance}; +use crate::webassembly::Instance; // A macro to retrieve variadic arguments given a varargs offset macro_rules! vararg { @@ -58,7 +47,6 @@ pub extern "C" fn ___syscall5(which: c_int, varargs: c_int, instance: &mut Insta -2 } - // sys_ioctl #[no_mangle] pub extern "C" fn ___syscall54(which: c_int, varargs: c_int, instance: &mut Instance) -> c_int { diff --git a/src/apis/emscripten/utils.rs b/src/apis/emscripten/utils.rs index b6a18ccfb..e28ab26e2 100644 --- a/src/apis/emscripten/utils.rs +++ b/src/apis/emscripten/utils.rs @@ -10,12 +10,11 @@ pub fn is_emscripten_module(module: &Module) -> bool { return false; } - #[cfg(test)] mod tests { - use crate::webassembly::instantiate; - use super::is_emscripten_module; use super::super::generate_emscripten_env; + use super::is_emscripten_module; + use crate::webassembly::instantiate; #[test] fn should_detect_emscripten_files() { @@ -32,4 +31,4 @@ mod tests { let result_object = instantiate(wasm_bytes, import_object).expect("Not compiled properly"); assert!(!is_emscripten_module(&result_object.module)); } -} \ No newline at end of file +} diff --git a/src/apis/host/posix/env.rs b/src/apis/host/posix/env.rs index ea6142f26..00830a796 100644 --- a/src/apis/host/posix/env.rs +++ b/src/apis/host/posix/env.rs @@ -1,19 +1,9 @@ /// NOTE: These syscalls only support wasm_32 for now because they take u32 offset - -use libc::{ - c_int, - c_void, - size_t, - ssize_t, - exit, - read, - open, - close, -}; -use std::os::raw::c_char; +use libc::{c_int, c_void, close, exit, open, read, size_t, ssize_t}; use std::ffi::CStr; +use std::os::raw::c_char; -use crate::webassembly::{Instance}; +use crate::webassembly::Instance; use std::env; pub extern "C" fn get_env(name: &str, instance: &mut Instance) -> Result { diff --git a/src/apis/host/posix/mod.rs b/src/apis/host/posix/mod.rs index eb75190ec..68c341cc6 100644 --- a/src/apis/host/posix/mod.rs +++ b/src/apis/host/posix/mod.rs @@ -1,5 +1,5 @@ -pub mod syscalls; pub mod env; +pub mod syscalls; -pub use self::syscalls::*; pub use self::env::*; +pub use self::syscalls::*; diff --git a/src/common/slice.rs b/src/common/slice.rs index 8ad5611fc..2fef84959 100644 --- a/src/common/slice.rs +++ b/src/common/slice.rs @@ -11,17 +11,13 @@ impl UncheckedSlice { #[inline] pub fn get_unchecked(&self, index: usize) -> &T { let ptr = self.ptr.as_ptr(); - unsafe { - &*ptr.add(index) - } + unsafe { &*ptr.add(index) } } #[inline] pub fn get_unchecked_mut(&mut self, index: usize) -> &mut T { let ptr = self.ptr.as_ptr(); - unsafe { - &mut *(ptr.add(index) as *mut _) - } + unsafe { &mut *(ptr.add(index) as *mut _) } } pub unsafe fn dangling() -> UncheckedSlice { diff --git a/src/main.rs b/src/main.rs index 7670b29ae..a79ca5538 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,8 +25,8 @@ use structopt::StructOpt; #[macro_use] mod macros; -pub mod common; pub mod apis; +pub mod common; pub mod sighandler; #[cfg(test)] mod spectests; @@ -83,17 +83,19 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { Some(&webassembly::Export::Function(index)) => index, _ => panic!("_main emscripten function not found"), }; - let main: extern fn(u32, u32, &webassembly::Instance) = get_instance_function!(instance, func_index); + let main: extern "C" fn(u32, u32, &webassembly::Instance) = + get_instance_function!(instance, func_index); main(0, 0, &instance); - } - else { - let func_index = instance - .start_func - .unwrap_or_else(|| match module.info.exports.get("main") { - Some(&webassembly::Export::Function(index)) => index, - _ => panic!("Main function not found"), - }); - let main: extern fn(&webassembly::Instance) = get_instance_function!(instance, func_index); + } else { + let func_index = + instance + .start_func + .unwrap_or_else(|| match module.info.exports.get("main") { + Some(&webassembly::Export::Function(index)) => index, + _ => panic!("Main function not found"), + }); + let main: extern "C" fn(&webassembly::Instance) = + get_instance_function!(instance, func_index); main(&instance); } diff --git a/src/webassembly/import_object.rs b/src/webassembly/import_object.rs index 7d78dab59..9d8f7308a 100644 --- a/src/webassembly/import_object.rs +++ b/src/webassembly/import_object.rs @@ -3,10 +3,10 @@ //! or webassembly::Memory objects. // Code inspired from: https://stackoverflow.com/a/45795699/1072990 // Adapted to the Webassembly use case +use crate::webassembly::LinearMemory; use std::borrow::Borrow; use std::collections::HashMap; use std::hash::{Hash, Hasher}; -use crate::webassembly::LinearMemory; // We introduced the Pair and BorrowedPair types. We can't use (A, B) // directly due to the orphan rule E0210. This is fine since the map @@ -75,8 +75,7 @@ impl ImportObject { } pub fn get(&self, a: &A, b: &B) -> Option<&ImportValue> { - self.map - .get(&BorrowedPair(a, b) as &KeyPair) + self.map.get(&BorrowedPair(a, b) as &KeyPair) } pub fn set(&mut self, a: A, b: B, v: ImportValue) { @@ -127,6 +126,9 @@ mod tests { fn x() {} let mut import_object = ImportObject::new(); import_object.set("abc", "def", ImportValue::Func(x as *const u8)); - assert_eq!(*import_object.get(&"abc", &"def").unwrap(), ImportValue::Func(x as *const u8)); + assert_eq!( + *import_object.get(&"abc", &"def").unwrap(), + ImportValue::Func(x as *const u8) + ); } } diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index 01d229eed..62a458c0c 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -6,28 +6,28 @@ //! synchronously instantiate a given webassembly::Module object. However, the //! primary way to get an Instance is through the asynchronous //! webassembly::instantiate_streaming() function. -use cranelift_codegen::ir::{LibCall, Function}; -use cranelift_codegen::{binemit, Context}; +use cranelift_codegen::ir::{Function, LibCall}; use cranelift_codegen::isa::TargetIsa; +use cranelift_codegen::{binemit, Context}; use cranelift_entity::EntityRef; use cranelift_wasm::{FuncIndex, GlobalInit}; use rayon::prelude::*; use region; +use std::iter::FromIterator; use std::iter::Iterator; +use std::mem::size_of; use std::ptr::write_unaligned; use std::slice; use std::sync::Arc; -use std::iter::FromIterator; -use std::mem::size_of; use super::super::common::slice::{BoundedSlice, UncheckedSlice}; use super::errors::ErrorKind; use super::import_object::{ImportObject, ImportValue}; +use super::math_intrinsics; use super::memory::LinearMemory; use super::module::{Export, ImportableExportable, Module}; use super::relocation::{Reloc, RelocSink, RelocationType}; -use super::math_intrinsics; type TablesSlice = UncheckedSlice>; type MemoriesSlice = UncheckedSlice>; @@ -114,7 +114,6 @@ pub struct DataPointers { // Pointer to globals pub globals: GlobalsSlice, - } pub struct InstanceOptions { @@ -125,7 +124,7 @@ pub struct InstanceOptions { pub isa: Box, } -extern fn mock_fn() -> i32 { +extern "C" fn mock_fn() -> i32 { return 0; } @@ -135,7 +134,10 @@ struct CompiledFunction { trap_sink: binemit::NullTrapSink, } -fn compile_function(isa: &TargetIsa, function_body: &Function) -> Result { +fn compile_function( + isa: &TargetIsa, + function_body: &Function, +) -> Result { let mut func_context = Context::for_function(function_body.to_owned()); let mut code_buf: Vec = Vec::new(); @@ -152,7 +154,7 @@ fn compile_function(isa: &TargetIsa, function_body: &Function) -> Result f, None => { if options.mock_missing_imports { - debug!("The import {}.{} is not provided, therefore will be mocked.", module, field); + debug!( + "The import {}.{} is not provided, therefore will be mocked.", + module, field + ); &(mock_fn as *const u8) - } - else { + } else { return Err(ErrorKind::LinkError(format!( "Imported function {}.{} was not provided in the import_functions", module, field ))); } - }, - other => panic!("Expected function import, received {:?}", other) + } + other => panic!("Expected function import, received {:?}", other), }; // println!("GET FUNC {:?}", function); import_functions.push(*function); @@ -218,15 +221,20 @@ impl Instance { // Compile the functions (from cranelift IR to machine code) let values: Vec<&Function> = Vec::from_iter(module.info.function_bodies.values()); // let isa: &TargetIsa = &*options.isa; - let compiled_funcs: Vec = values.par_iter().map(|function_body| -> CompiledFunction { - // let r = *Arc::from_raw(isa_ptr); - compile_function(&*options.isa, function_body).unwrap() - // unimplemented!() - }).collect(); + let compiled_funcs: Vec = values + .par_iter() + .map(|function_body| -> CompiledFunction { + // let r = *Arc::from_raw(isa_ptr); + compile_function(&*options.isa, function_body).unwrap() + // unimplemented!() + }).collect(); for compiled_func in compiled_funcs.into_iter() { - let CompiledFunction {code_buf, reloc_sink, ..} = compiled_func; - + let CompiledFunction { + code_buf, + reloc_sink, + .. + } = compiled_func; // let func_offset = code_buf; protect_codebuf(&code_buf).unwrap(); @@ -322,33 +330,39 @@ impl Instance { }; for (i, global) in module.info.globals.iter().enumerate() { - let ImportableExportable {entity, import_name, ..} = global; + let ImportableExportable { + entity, + import_name, + .. + } = global; let value: i64 = match entity.initializer { GlobalInit::I32Const(n) => n as _, GlobalInit::I64Const(n) => n, GlobalInit::F32Const(f) => f as _, // unsafe { mem::transmute(f as f64) }, GlobalInit::F64Const(f) => f as _, // unsafe { mem::transmute(f) }, - GlobalInit::GlobalRef(global_index) => { - globals_data[global_index.index()] - } + GlobalInit::GlobalRef(global_index) => globals_data[global_index.index()], GlobalInit::Import() => { - let (module_name, field_name) = import_name.as_ref().expect("Expected a import name for the global import"); - let imported = import_object.get(&module_name.as_str(), &field_name.as_str()); + let (module_name, field_name) = import_name + .as_ref() + .expect("Expected a import name for the global import"); + let imported = + import_object.get(&module_name.as_str(), &field_name.as_str()); match imported { - Some(ImportValue::Global(value)) => { - *value - }, + Some(ImportValue::Global(value)) => *value, None => { if options.mock_missing_globals { 0 + } else { + panic!( + "Imported global value was not provided ({}.{})", + module_name, field_name + ) } - else { - panic!("Imported global value was not provided ({}.{})", module_name, field_name) - } - }, - _ => { - panic!("Expected global import, but received {:?} ({}.{})", imported, module_name, field_name) } + _ => panic!( + "Expected global import, but received {:?} ({}.{})", + imported, module_name, field_name + ), } } }; @@ -367,27 +381,29 @@ impl Instance { for table in &module.info.tables { let table: Vec = match table.import_name.as_ref() { Some((module_name, field_name)) => { - let imported = import_object.get(&module_name.as_str(), &field_name.as_str()); + let imported = + import_object.get(&module_name.as_str(), &field_name.as_str()); match imported { - Some(ImportValue::Table(t)) => { - t.to_vec() - }, + Some(ImportValue::Table(t)) => t.to_vec(), None => { if options.mock_missing_tables { let len = table.entity.size; let mut v = Vec::with_capacity(len); v.resize(len, 0); v + } else { + panic!( + "Imported table value was not provided ({}.{})", + module_name, field_name + ) } - else { - panic!("Imported table value was not provided ({}.{})", module_name, field_name) - } - }, - _ => { - panic!("Expected global table, but received {:?} ({}.{})", imported, module_name, field_name) } + _ => panic!( + "Expected global table, but received {:?} ({}.{})", + imported, module_name, field_name + ), } - }, + } None => { let len = table.entity.size; let mut v = Vec::with_capacity(len); @@ -401,10 +417,8 @@ impl Instance { // instantiate tables for table_element in &module.info.table_elements { let base = match table_element.base { - Some(global_index) => { - globals_data[global_index.index()] as usize - }, - None => 0 + Some(global_index) => globals_data[global_index.index()] as usize, + None => 0, }; let table = &mut tables[table_element.table_index.index()]; @@ -430,10 +444,8 @@ impl Instance { // Get memories in module 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); } @@ -458,10 +470,14 @@ impl Instance { // TODO: Refactor repetitive code let tables_pointer: Vec> = tables.iter().map(|table| table[..].into()).collect(); - let memories_pointer: Vec> = - memories.iter().map( - |mem| BoundedSlice::new(&mem[..], mem.current as usize * LinearMemory::WASM_PAGE_SIZE), - ).collect(); + let memories_pointer: Vec> = memories + .iter() + .map(|mem| { + BoundedSlice::new( + &mem[..], + mem.current as usize * LinearMemory::WASM_PAGE_SIZE, + ) + }).collect(); let globals_pointer: GlobalsSlice = globals[..].into(); let data_pointers = DataPointers { @@ -518,9 +534,7 @@ impl Instance { pub fn memory_offset_addr(&self, index: usize, offset: usize) -> *const usize { let mem = &self.memories[index]; - unsafe { - mem.mmap.as_ptr().offset(offset as isize) as *const usize - } + unsafe { mem.mmap.as_ptr().offset(offset as isize) as *const usize } } // Shows the value of a global variable. @@ -550,9 +564,13 @@ extern "C" fn grow_memory(size: u32, memory_index: u32, instance: &mut Instance) if old_mem_size != -1 { // Get new memory bytes - let new_mem_bytes = (old_mem_size as usize + size as usize) * LinearMemory::WASM_PAGE_SIZE; + let new_mem_bytes = (old_mem_size as usize + size as usize) * LinearMemory::WASM_PAGE_SIZE; // Update data_pointer - instance.data_pointers.memories.get_unchecked_mut(memory_index as usize).len = new_mem_bytes; + instance + .data_pointers + .memories + .get_unchecked_mut(memory_index as usize) + .len = new_mem_bytes; } old_mem_size diff --git a/src/webassembly/memory.rs b/src/webassembly/memory.rs index 7c6910b4a..dc50eba91 100644 --- a/src/webassembly/memory.rs +++ b/src/webassembly/memory.rs @@ -132,8 +132,7 @@ impl fmt::Debug for LinearMemory { // Not comparing based on memory content. That would be inefficient. impl PartialEq for LinearMemory { fn eq(&self, other: &LinearMemory) -> bool { - self.current == other.current && - self.maximum == other.maximum + self.current == other.current && self.maximum == other.maximum } } diff --git a/src/webassembly/mod.rs b/src/webassembly/mod.rs index f60d67861..c985f1ff0 100644 --- a/src/webassembly/mod.rs +++ b/src/webassembly/mod.rs @@ -1,19 +1,19 @@ pub mod errors; pub mod import_object; pub mod instance; +pub mod math_intrinsics; pub mod memory; pub mod module; pub mod relocation; pub mod utils; -pub mod math_intrinsics; +use cranelift_codegen::isa::TargetIsa; +use cranelift_codegen::{isa, settings}; use std::panic; use std::str::FromStr; use target_lexicon; use wasmparser; use wasmparser::WasmDecoder; -use cranelift_codegen::{isa, settings}; -use cranelift_codegen::isa::TargetIsa; pub use self::errors::{Error, ErrorKind}; pub use self::import_object::{ImportObject, ImportValue}; @@ -60,7 +60,7 @@ pub fn instantiate( mock_missing_imports: true, mock_missing_globals: true, mock_missing_tables: true, - isa: isa + isa: isa, }, )?; debug!("webassembly - instance created"); diff --git a/src/webassembly/module.rs b/src/webassembly/module.rs index bd31b060b..f3fc0ea55 100644 --- a/src/webassembly/module.rs +++ b/src/webassembly/module.rs @@ -15,27 +15,14 @@ use cranelift_codegen::isa::{CallConv, TargetFrontendConfig}; use cranelift_entity::{EntityRef, PrimaryMap}; use cranelift_wasm::{ - translate_module, - ReturnMode, - DefinedFuncIndex, - FuncEnvironment as FuncEnvironmentTrait, - FuncIndex, - FuncTranslator, - Global, - GlobalIndex, - GlobalVariable, - Memory, - MemoryIndex, - ModuleEnvironment, - SignatureIndex, - Table, - TableIndex, - WasmResult, + translate_module, DefinedFuncIndex, FuncEnvironment as FuncEnvironmentTrait, FuncIndex, + FuncTranslator, Global, GlobalIndex, GlobalVariable, Memory, MemoryIndex, ModuleEnvironment, + ReturnMode, SignatureIndex, Table, TableIndex, WasmResult, }; use super::errors::ErrorKind; -use super::memory::LinearMemory; use super::instance::Instance; +use super::memory::LinearMemory; /// Get the integer type used for representing pointers on this platform. fn native_pointer_type() -> ir::Type { @@ -89,7 +76,7 @@ impl ImportableExportable { Self { entity, export_names: Vec::new(), - import_name: import_name + import_name: import_name, } } } @@ -245,7 +232,6 @@ pub struct Module { // return_mode: ReturnMode, } - impl Module { /// Instantiate a Module given WASM bytecode pub fn from_bytes( @@ -365,7 +351,11 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { // however the 32-bit wasmer may be running on 64-bit arch, which means ptr_size here will // be 8 bytes. That will definitely gove the wrong offset values fn make_table(&mut self, func: &mut ir::Function, table_index: TableIndex) -> ir::Table { - assert_eq!(table_index.index(), 0, "Only one WebAssembly memory supported"); + assert_eq!( + table_index.index(), + 0, + "Only one WebAssembly memory supported" + ); let instance = func.create_global_value(ir::GlobalValueData::VMContext); let ptr_size = native_pointer_size(); // Load value at (instance + TABLES_OFFSET) @@ -415,7 +405,11 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { // however the 32-bit wasmer may be running on 64-bit arch, which means ptr_size here will // be 8 bytes. That will definitely gove the wrong offset values fn make_heap(&mut self, func: &mut ir::Function, memory_index: MemoryIndex) -> ir::Heap { - debug_assert_eq!(memory_index.index(), 0, "Only one WebAssembly memory supported"); + debug_assert_eq!( + memory_index.index(), + 0, + "Only one WebAssembly memory supported" + ); let instance = func.create_global_value(ir::GlobalValueData::VMContext); let ptr_size = native_pointer_size(); @@ -438,7 +432,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { base, offset: Offset32::new(memory_data_offset), global_type: self.pointer_type(), - readonly: true + readonly: true, }); // Load value at the (base + memory_data_offset) @@ -455,16 +449,18 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { base: heap_base, min_size: 0.into(), guard_size: (LinearMemory::DEFAULT_GUARD_SIZE as i64).into(), - style: ir::HeapStyle::Dynamic { - bound_gv, - }, - index_type: I32 + style: ir::HeapStyle::Dynamic { bound_gv }, + index_type: I32, }); heap } - fn make_global(&mut self, func: &mut ir::Function, global_index: GlobalIndex) -> GlobalVariable { + fn make_global( + &mut self, + func: &mut ir::Function, + global_index: GlobalIndex, + ) -> GlobalVariable { let ptr_size = native_pointer_size(); let instance = func.create_global_value(ir::GlobalValueData::VMContext); @@ -525,7 +521,6 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { .special_param(ir::ArgumentPurpose::VMContext) .expect("Missing vmctx parameter"); - // The `callee` value is an index into a table of function pointers. // Apparently, that table is stored at absolute address 0 in this dummy environment. // TODO: Generate bounds checking code. @@ -541,9 +536,7 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { // let entry_size = native_pointer_size() as i64 * 2; // let callee_scaled = pos.ins().imul_imm(callee_offset, entry_size); - let entry_addr = pos - .ins() - .table_addr(ptr, table, callee_offset, 0); + let entry_addr = pos.ins().table_addr(ptr, table, callee_offset, 0); let mut mflags = ir::MemFlags::new(); mflags.set_notrap(); @@ -597,7 +590,11 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { _heap: ir::Heap, val: ir::Value, ) -> WasmResult { - debug_assert_eq!(memory_index.index(), 0, "non-default memories not supported yet"); + debug_assert_eq!( + memory_index.index(), + 0, + "non-default memories not supported yet" + ); let grow_mem_func = self.mod_info.grow_memory_extfunc.unwrap_or_else(|| { let sig_ref = pos.func.import_signature(Signature { call_conv: CallConv::SystemV, @@ -624,7 +621,9 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { let memory_index_value = pos.ins().iconst(I32, imm64(memory_index.index())); let vmctx = pos.func.special_param(ArgumentPurpose::VMContext).unwrap(); - let call_inst = pos.ins().call(grow_mem_func, &[val, memory_index_value, vmctx]); + let call_inst = pos + .ins() + .call(grow_mem_func, &[val, memory_index_value, vmctx]); Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap()) } @@ -634,7 +633,11 @@ impl<'environment> FuncEnvironmentTrait for FuncEnvironment<'environment> { memory_index: MemoryIndex, _heap: ir::Heap, ) -> WasmResult { - debug_assert_eq!(memory_index.index(), 0, "non-default memories not supported yet"); + debug_assert_eq!( + memory_index.index(), + 0, + "non-default memories not supported yet" + ); let cur_mem_func = self.mod_info.current_memory_extfunc.unwrap_or_else(|| { let sig_ref = pos.func.import_signature(Signature { call_conv: CallConv::SystemV, @@ -712,7 +715,9 @@ impl<'data> ModuleEnvironment<'data> for Module { self.info.imported_funcs.len(), "Imported functions must be declared first" ); - self.info.functions.push(ImportableExportable::new(sig_index, None)); + self.info + .functions + .push(ImportableExportable::new(sig_index, None)); self.info .imported_funcs .push((String::from(module), String::from(field))); @@ -723,7 +728,9 @@ impl<'data> ModuleEnvironment<'data> for Module { } fn declare_func_type(&mut self, sig_index: SignatureIndex) { - self.info.functions.push(ImportableExportable::new(sig_index, None)); + self.info + .functions + .push(ImportableExportable::new(sig_index, None)); } fn get_func_type(&self, func_index: FuncIndex) -> SignatureIndex { @@ -731,16 +738,16 @@ impl<'data> ModuleEnvironment<'data> for Module { } fn declare_global(&mut self, global: Global) { - self.info.globals.push(ImportableExportable::new(global, None)); + self.info + .globals + .push(ImportableExportable::new(global, None)); } - fn declare_global_import( - &mut self, - global: Global, - module: &'data str, - field: &'data str, - ) { - self.info.globals.push(ImportableExportable::new(global, Some((String::from(module), String::from(field))))); + fn declare_global_import(&mut self, global: Global, module: &'data str, field: &'data str) { + self.info.globals.push(ImportableExportable::new( + global, + Some((String::from(module), String::from(field))), + )); } fn get_global(&self, global_index: GlobalIndex) -> &Global { @@ -748,16 +755,16 @@ impl<'data> ModuleEnvironment<'data> for Module { } fn declare_table(&mut self, table: Table) { - self.info.tables.push(ImportableExportable::new(table, None)); + self.info + .tables + .push(ImportableExportable::new(table, None)); } - fn declare_table_import( - &mut self, - table: Table, - module: &'data str, - field: &'data str, - ) { - self.info.tables.push(ImportableExportable::new(table, Some((String::from(module), String::from(field))))); + fn declare_table_import(&mut self, table: Table, module: &'data str, field: &'data str) { + self.info.tables.push(ImportableExportable::new( + table, + Some((String::from(module), String::from(field))), + )); } fn declare_table_elements( @@ -776,16 +783,16 @@ impl<'data> ModuleEnvironment<'data> for Module { } fn declare_memory(&mut self, memory: Memory) { - self.info.memories.push(ImportableExportable::new(memory, None)); + self.info + .memories + .push(ImportableExportable::new(memory, None)); } - fn declare_memory_import( - &mut self, - memory: Memory, - module: &'data str, - field: &'data str, - ) { - self.info.memories.push(ImportableExportable::new(memory, Some((String::from(module), String::from(field))))); + fn declare_memory_import(&mut self, memory: Memory, module: &'data str, field: &'data str) { + self.info.memories.push(ImportableExportable::new( + memory, + Some((String::from(module), String::from(field))), + )); } fn declare_data_initialization( diff --git a/src/webassembly/utils.rs b/src/webassembly/utils.rs index f481ecc93..2388eec48 100644 --- a/src/webassembly/utils.rs +++ b/src/webassembly/utils.rs @@ -11,12 +11,10 @@ pub fn print_instance_offsets(instance: &Instance) { let instance_address = instance as *const _ as usize; let data_ptr = &instance.data_pointers; - let tables_pointer_address_ptr: *const usize = - unsafe { transmute(&data_ptr.tables) }; + let tables_pointer_address_ptr: *const usize = unsafe { transmute(&data_ptr.tables) }; let tables_pointer_address = tables_pointer_address_ptr as usize; - let memories_pointer_address_ptr: *const usize = - unsafe { transmute(&data_ptr.memories) }; + let memories_pointer_address_ptr: *const usize = unsafe { transmute(&data_ptr.memories) }; let memories_pointer_address = memories_pointer_address_ptr as usize; let memories_pointer_address_ptr_0: *const usize = @@ -31,8 +29,7 @@ pub fn print_instance_offsets(instance: &Instance) { unsafe { transmute(&data_ptr.memories.get_unchecked(0).len) }; let memories_pointer_address_0_len = memories_pointer_address_ptr_0_len as usize; - let globals_pointer_address_ptr: *const usize = - unsafe { transmute(&data_ptr.globals) }; + let globals_pointer_address_ptr: *const usize = unsafe { transmute(&data_ptr.globals) }; let globals_pointer_address = globals_pointer_address_ptr as usize; println!( @@ -53,7 +50,6 @@ instance.data_pointers.globals \t- {:X} | offset - {:?} tables_pointer_address - instance_address, memories_pointer_address, memories_pointer_address - instance_address, - memories_pointer_address_0, 0, memories_pointer_address_0_data, @@ -61,7 +57,6 @@ instance.data_pointers.globals \t- {:X} | offset - {:?} data_ptr.memories.get_unchecked(0).len, memories_pointer_address_0_len, memories_pointer_address_0_len - memories_pointer_address_0_data, - globals_pointer_address, globals_pointer_address - instance_address, );