Begin internal reorganization.
This begins reorganizing how translation and compilation occur, and setting up infrastructure for imports/exports and relocations. It splits parts out of StandaloneRuntime, forming Module, Compilation, and Instance structs, which can be used more independently. It also simplifies the command-line interface, in a step towards making simple tools that just expose the functionality of the libraries.
This commit is contained in:
90
lib/runtime/src/instance.rs
Normal file
90
lib/runtime/src/instance.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
//! An `Instance` contains all the runtime state used by execution of a wasm
|
||||
//! module.
|
||||
|
||||
use cretonne::ir;
|
||||
use cton_wasm::GlobalIndex;
|
||||
use module::Module;
|
||||
|
||||
const PAGE_SIZE: usize = 65536;
|
||||
|
||||
/// An Instance of a WebAssemby module.
|
||||
#[derive(Debug)]
|
||||
pub struct Instance {
|
||||
/// WebAssembly table data.
|
||||
pub tables: Vec<Vec<usize>>,
|
||||
|
||||
/// WebAssembly linear memory data.
|
||||
pub memories: Vec<Vec<u8>>,
|
||||
|
||||
/// WebAssembly global variable data.
|
||||
pub globals: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
/// Create a new `Instance`.
|
||||
pub fn new(module: &Module) -> Self {
|
||||
let mut result = Self {
|
||||
tables: Vec::new(),
|
||||
memories: Vec::new(),
|
||||
globals: Vec::new(),
|
||||
};
|
||||
result.instantiate_tables(module);
|
||||
result.instantiate_memories(module);
|
||||
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) {
|
||||
debug_assert!(self.tables.is_empty());
|
||||
self.tables.reserve(module.tables.len());
|
||||
for table in &module.tables {
|
||||
let len = table.size;
|
||||
let mut v = Vec::with_capacity(len);
|
||||
v.resize(len, 0);
|
||||
self.tables.push(v);
|
||||
}
|
||||
}
|
||||
|
||||
/// Allocate memory in `instance` for just the memories of the current module,
|
||||
/// without any initializers applied yet.
|
||||
fn instantiate_memories(&mut self, module: &Module) {
|
||||
debug_assert!(self.memories.is_empty());
|
||||
// Allocate the underlying memory and initialize it to all zeros.
|
||||
self.memories.reserve(module.memories.len());
|
||||
for memory in &module.memories {
|
||||
let len = memory.pages_count * PAGE_SIZE;
|
||||
let mut v = Vec::with_capacity(len);
|
||||
v.resize(len, 0);
|
||||
self.memories.push(v);
|
||||
}
|
||||
}
|
||||
|
||||
/// Allocate memory in `instance` for just the globals of the current module,
|
||||
/// without any initializers applied yet.
|
||||
fn instantiate_globals(&mut self, module: &Module) {
|
||||
debug_assert!(self.globals.is_empty());
|
||||
// Allocate the underlying memory and initialize it to all zeros.
|
||||
let globals_data_size = module.globals.len() * 8;
|
||||
self.globals.resize(globals_data_size, 0);
|
||||
}
|
||||
|
||||
/// 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(),
|
||||
)
|
||||
[address..address + len]
|
||||
}
|
||||
|
||||
/// Shows the value of a global variable.
|
||||
pub fn inspect_global(&self, global_index: GlobalIndex, ty: ir::Type) -> &[u8] {
|
||||
let offset = global_index * 8;
|
||||
let len = ty.bytes() as usize;
|
||||
&self.globals[offset..offset + len]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user