run cargo fmt

This commit is contained in:
Syrus Akbary 2018-11-21 20:59:23 -08:00
parent ccdabd26b5
commit 38f045da3c
16 changed files with 283 additions and 243 deletions

View File

@ -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,
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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!");
}

View File

@ -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 {

View File

@ -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() {

View File

@ -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<String, env::VarError> {

View File

@ -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::*;

View File

@ -11,17 +11,13 @@ impl<T> UncheckedSlice<T> {
#[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<T> {

View File

@ -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
} 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);
let main: extern "C" fn(&webassembly::Instance) =
get_instance_function!(instance, func_index);
main(&instance);
}

View File

@ -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<A: Eq + Hash, B: Eq + Hash> ImportObject<A, B> {
}
pub fn get(&self, a: &A, b: &B) -> Option<&ImportValue> {
self.map
.get(&BorrowedPair(a, b) as &KeyPair<A, B>)
self.map.get(&BorrowedPair(a, b) as &KeyPair<A, B>)
}
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)
);
}
}

View File

@ -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<BoundedSlice<usize>>;
type MemoriesSlice = UncheckedSlice<BoundedSlice<u8>>;
@ -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<TargetIsa>,
}
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<CompiledFunction, ErrorKind> {
fn compile_function(
isa: &TargetIsa,
function_body: &Function,
) -> Result<CompiledFunction, ErrorKind> {
let mut func_context = Context::for_function(function_body.to_owned());
let mut code_buf: Vec<u8> = Vec::new();
@ -152,7 +154,7 @@ fn compile_function(isa: &TargetIsa, function_body: &Function) -> Result<Compile
Ok(CompiledFunction {
code_buf,
reloc_sink,
trap_sink
trap_sink,
})
}
@ -191,23 +193,24 @@ impl Instance {
// We walk through the imported functions and set the relocations
// for each of this functions to be an empty vector (as is defined outside of wasm)
for (module, field) in module.info.imported_funcs.iter() {
let imported = import_object
.get(&module.as_str(), &field.as_str());
let imported = import_object.get(&module.as_str(), &field.as_str());
let function: &*const u8 = match imported {
Some(ImportValue::Func(f)) => 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<CompiledFunction> = values.par_iter().map(|function_body| -> CompiledFunction {
let compiled_funcs: Vec<CompiledFunction> = 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<usize> = 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)
}
},
_ => {
panic!("Expected global table, but received {:?} ({}.{})", imported, 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
),
}
}
},
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<BoundedSlice<usize>> =
tables.iter().map(|table| table[..].into()).collect();
let memories_pointer: Vec<BoundedSlice<u8>> =
memories.iter().map(
|mem| BoundedSlice::new(&mem[..], mem.current as usize * LinearMemory::WASM_PAGE_SIZE),
).collect();
let memories_pointer: Vec<BoundedSlice<u8>> = 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.
@ -552,7 +566,11 @@ extern "C" fn grow_memory(size: u32, memory_index: u32, instance: &mut Instance)
// Get new memory bytes
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

View File

@ -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
}
}

View File

@ -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");

View File

@ -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<T> ImportableExportable<T> {
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<ir::Value> {
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<ir::Value> {
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(

View File

@ -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,
);