Rename InstanceContents to Instance.

This commit is contained in:
Dan Gohman
2019-02-22 14:29:11 -08:00
parent 5f201f6d73
commit 3cc113482d
5 changed files with 147 additions and 150 deletions

View File

@@ -160,7 +160,7 @@ impl CompiledModule {
} }
} }
/// Crate an `InstanceContents` from this `CompiledModule`. /// Crate an `Instance` from this `CompiledModule`.
/// ///
/// Note that if only one instance of this module is needed, it may be more /// Note that if only one instance of this module is needed, it may be more
/// efficient to call the top-level `instantiate`, since that avoids copying /// efficient to call the top-level `instantiate`, since that avoids copying

View File

@@ -1,6 +1,6 @@
//! An `InstanceContents` contains all the runtime state used by execution //! An `Instance` contains all the runtime state used by execution of a
//! of a wasm module. An `InstanceHandle` is a reference-counting handle //! wasm module (except its callstack and register state). An
//! for an `InstanceContents`. //! `InstanceHandle` is a reference-counting handle for an `Instance`.
use crate::export::Export; use crate::export::Export;
use crate::imports::Imports; use crate::imports::Imports;
@@ -176,25 +176,23 @@ fn global_mut<'vmctx>(
} }
} }
/// The actual contents of an instance. /// A WebAssembly instance.
///
/// `InstanceContents` instances are specially allocated.
/// ///
/// This is repr(C) to ensure that the vmctx field is last. /// This is repr(C) to ensure that the vmctx field is last.
#[repr(C)] #[repr(C)]
pub(crate) struct InstanceContents { pub(crate) struct Instance {
/// The number of references to this `InstanceContents`. /// The number of references to this `Instance`.
refcount: usize, refcount: usize,
/// Instances from which this `InstanceContents` imports. These won't /// `Instance`s from which this `Instance` imports. These won't
/// create reference cycles because wasm instances can't cyclically /// create reference cycles because wasm instances can't cyclically
/// import from each other. /// import from each other.
dependencies: HashSet<InstanceHandle>, dependencies: HashSet<InstanceHandle>,
/// The allocated contents. /// The underlying mmap that holds this `Instance`.
mmap: Mmap, mmap: Mmap,
/// The `Module` this `InstanceContents` was instantiated from. /// The `Module` this `Instance` was instantiated from.
module: Rc<Module>, module: Rc<Module>,
/// Offsets in the `vmctx` region. /// Offsets in the `vmctx` region.
@@ -224,7 +222,7 @@ pub(crate) struct InstanceContents {
} }
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
impl InstanceContents { impl Instance {
/// Return the indexed `VMSharedSignatureIndex`. /// Return the indexed `VMSharedSignatureIndex`.
#[allow(dead_code)] #[allow(dead_code)]
fn signature_id(&self, index: SignatureIndex) -> VMSharedSignatureIndex { fn signature_id(&self, index: SignatureIndex) -> VMSharedSignatureIndex {
@@ -496,7 +494,7 @@ impl InstanceContents {
} }
} }
/// Return the offset from the vmctx pointer to its containing InstanceContents. /// Return the offset from the vmctx pointer to its containing Instance.
pub(crate) fn vmctx_offset() -> isize { pub(crate) fn vmctx_offset() -> isize {
offset_of!(Self, vmctx) as isize offset_of!(Self, vmctx) as isize
} }
@@ -573,11 +571,11 @@ impl InstanceContents {
delta: u32, delta: u32,
) -> Option<u32> { ) -> Option<u32> {
let import = self.imported_memory(memory_index); let import = self.imported_memory(memory_index);
let foreign_instance_contents = (&mut *import.vmctx).instance_contents(); let foreign_instance = (&mut *import.vmctx).instance();
let foreign_memory = &mut *import.from; let foreign_memory = &mut *import.from;
let foreign_index = foreign_instance_contents.memory_index(foreign_memory); let foreign_index = foreign_instance.memory_index(foreign_memory);
foreign_instance_contents.memory_grow(foreign_index, delta) foreign_instance.memory_grow(foreign_index, delta)
} }
/// Returns the number of allocated wasm pages. /// Returns the number of allocated wasm pages.
@@ -591,11 +589,11 @@ impl InstanceContents {
/// Returns the number of allocated wasm pages in an imported memory. /// Returns the number of allocated wasm pages in an imported memory.
pub(crate) unsafe fn imported_memory_size(&mut self, memory_index: MemoryIndex) -> u32 { pub(crate) unsafe fn imported_memory_size(&mut self, memory_index: MemoryIndex) -> u32 {
let import = self.imported_memory(memory_index); let import = self.imported_memory(memory_index);
let foreign_instance_contents = (&mut *import.vmctx).instance_contents(); let foreign_instance = (&mut *import.vmctx).instance();
let foreign_memory = &mut *import.from; let foreign_memory = &mut *import.from;
let foreign_index = foreign_instance_contents.memory_index(foreign_memory); let foreign_index = foreign_instance.memory_index(foreign_memory);
foreign_instance_contents.memory_size(foreign_index) foreign_instance.memory_size(foreign_index)
} }
pub(crate) fn lookup_global_export(&self, field: &str) -> Option<Export> { pub(crate) fn lookup_global_export(&self, field: &str) -> Option<Export> {
@@ -610,14 +608,14 @@ impl InstanceContents {
} }
} }
/// A handle holding an `InstanceContents` of a WebAssembly module. /// A handle holding an `Instance` of a WebAssembly module.
#[derive(Hash, PartialEq, Eq)] #[derive(Hash, PartialEq, Eq)]
pub struct InstanceHandle { pub struct InstanceHandle {
instance: *mut InstanceContents, instance: *mut Instance,
} }
impl InstanceHandle { impl InstanceHandle {
/// Create a new `InstanceHandle` pointing at a new `InstanceContents`. /// Create a new `InstanceHandle` pointing at a new `Instance`.
pub fn new( pub fn new(
module: Rc<Module>, module: Rc<Module>,
global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>, global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>,
@@ -646,20 +644,20 @@ impl InstanceHandle {
let offsets = VMOffsets::new(mem::size_of::<*const u8>() as u8, &module); let offsets = VMOffsets::new(mem::size_of::<*const u8>() as u8, &module);
let mut contents_mmap = Mmap::with_at_least( let mut instance_mmap = Mmap::with_at_least(
mem::size_of::<InstanceContents>() mem::size_of::<Instance>()
.checked_add(cast::usize(offsets.size_of_vmctx())) .checked_add(cast::usize(offsets.size_of_vmctx()))
.unwrap(), .unwrap(),
) )
.map_err(InstantiationError::Resource)?; .map_err(InstantiationError::Resource)?;
let contents = { let instance = {
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
let contents_ptr = contents_mmap.as_mut_ptr() as *mut InstanceContents; let instance_ptr = instance_mmap.as_mut_ptr() as *mut Instance;
let contents = InstanceContents { let instance = Instance {
refcount: 1, refcount: 1,
dependencies: imports.dependencies, dependencies: imports.dependencies,
mmap: contents_mmap, mmap: instance_mmap,
module, module,
global_exports, global_exports,
offsets, offsets,
@@ -670,77 +668,77 @@ impl InstanceHandle {
vmctx: VMContext {}, vmctx: VMContext {},
}; };
unsafe { unsafe {
ptr::write(contents_ptr, contents); ptr::write(instance_ptr, instance);
&mut *contents_ptr &mut *instance_ptr
} }
}; };
unsafe { unsafe {
ptr::copy( ptr::copy(
vmshared_signatures.values().as_slice().as_ptr(), vmshared_signatures.values().as_slice().as_ptr(),
contents.signature_ids_ptr() as *mut VMSharedSignatureIndex, instance.signature_ids_ptr() as *mut VMSharedSignatureIndex,
vmshared_signatures.len(), vmshared_signatures.len(),
); );
ptr::copy( ptr::copy(
imports.functions.values().as_slice().as_ptr(), imports.functions.values().as_slice().as_ptr(),
contents.imported_functions_ptr() as *mut VMFunctionImport, instance.imported_functions_ptr() as *mut VMFunctionImport,
imports.functions.len(), imports.functions.len(),
); );
ptr::copy( ptr::copy(
imports.tables.values().as_slice().as_ptr(), imports.tables.values().as_slice().as_ptr(),
contents.imported_tables_ptr() as *mut VMTableImport, instance.imported_tables_ptr() as *mut VMTableImport,
imports.tables.len(), imports.tables.len(),
); );
ptr::copy( ptr::copy(
imports.memories.values().as_slice().as_ptr(), imports.memories.values().as_slice().as_ptr(),
contents.imported_memories_ptr() as *mut VMMemoryImport, instance.imported_memories_ptr() as *mut VMMemoryImport,
imports.memories.len(), imports.memories.len(),
); );
ptr::copy( ptr::copy(
imports.globals.values().as_slice().as_ptr(), imports.globals.values().as_slice().as_ptr(),
contents.imported_globals_ptr() as *mut VMGlobalImport, instance.imported_globals_ptr() as *mut VMGlobalImport,
imports.globals.len(), imports.globals.len(),
); );
ptr::copy( ptr::copy(
vmctx_tables.values().as_slice().as_ptr(), vmctx_tables.values().as_slice().as_ptr(),
contents.tables_ptr() as *mut VMTableDefinition, instance.tables_ptr() as *mut VMTableDefinition,
vmctx_tables.len(), vmctx_tables.len(),
); );
ptr::copy( ptr::copy(
vmctx_memories.values().as_slice().as_ptr(), vmctx_memories.values().as_slice().as_ptr(),
contents.memories_ptr() as *mut VMMemoryDefinition, instance.memories_ptr() as *mut VMMemoryDefinition,
vmctx_memories.len(), vmctx_memories.len(),
); );
ptr::copy( ptr::copy(
vmctx_globals.values().as_slice().as_ptr(), vmctx_globals.values().as_slice().as_ptr(),
contents.globals_ptr() as *mut VMGlobalDefinition, instance.globals_ptr() as *mut VMGlobalDefinition,
vmctx_globals.len(), vmctx_globals.len(),
); );
} }
// Check initializer bounds before initializing anything. // Check initializer bounds before initializing anything.
check_table_init_bounds(contents)?; check_table_init_bounds(instance)?;
check_memory_init_bounds(contents, data_initializers)?; check_memory_init_bounds(instance, data_initializers)?;
// Apply the initializers. // Apply the initializers.
initialize_tables(contents)?; initialize_tables(instance)?;
initialize_memories(contents, data_initializers)?; initialize_memories(instance, data_initializers)?;
initialize_globals(contents); initialize_globals(instance);
// Collect the exports for the global export map. // Collect the exports for the global export map.
for (field, decl) in &contents.module.exports { for (field, decl) in &instance.module.exports {
use std::collections::hash_map::Entry::*; use std::collections::hash_map::Entry::*;
let cell: &RefCell<HashMap<std::string::String, core::option::Option<Export>>> = let cell: &RefCell<HashMap<std::string::String, core::option::Option<Export>>> =
contents.global_exports.borrow(); instance.global_exports.borrow();
let map: &mut HashMap<std::string::String, core::option::Option<Export>> = let map: &mut HashMap<std::string::String, core::option::Option<Export>> =
&mut cell.borrow_mut(); &mut cell.borrow_mut();
match map.entry(field.to_string()) { match map.entry(field.to_string()) {
Vacant(entry) => { Vacant(entry) => {
entry.insert(Some(lookup_by_declaration( entry.insert(Some(lookup_by_declaration(
&contents.module, &instance.module,
&mut contents.vmctx, &mut instance.vmctx,
&contents.offsets, &instance.offsets,
&contents.finished_functions, &instance.finished_functions,
&decl, &decl,
))); )));
} }
@@ -751,58 +749,58 @@ impl InstanceHandle {
// Ensure that our signal handlers are ready for action. // Ensure that our signal handlers are ready for action.
// TODO: Move these calls out of `InstanceHandle`. // TODO: Move these calls out of `InstanceHandle`.
wasmtime_init_eager(); wasmtime_init_eager();
wasmtime_init_finish(contents.vmctx_mut()); wasmtime_init_finish(instance.vmctx_mut());
// The WebAssembly spec specifies that the start function is // The WebAssembly spec specifies that the start function is
// invoked automatically at instantiation time. // invoked automatically at instantiation time.
contents.invoke_start_function()?; instance.invoke_start_function()?;
Ok(Self { instance: contents }) Ok(Self { instance: instance })
} }
/// Create a new `InstanceHandle` pointing at the instance /// Create a new `InstanceHandle` pointing at the instance
/// pointed to by the given `VMContext` pointer. /// pointed to by the given `VMContext` pointer.
pub fn from_vmctx(vmctx: *mut VMContext) -> Self { pub fn from_vmctx(vmctx: *mut VMContext) -> Self {
let instance = unsafe { (&mut *vmctx).instance_contents() }; let instance = unsafe { (&mut *vmctx).instance() };
instance.refcount += 1; instance.refcount += 1;
Self { instance } Self { instance }
} }
/// Return a reference to the vmctx used by compiled wasm code. /// Return a reference to the vmctx used by compiled wasm code.
pub fn vmctx(&self) -> &VMContext { pub fn vmctx(&self) -> &VMContext {
self.contents().vmctx() self.instance().vmctx()
} }
/// Return a raw pointer to the vmctx used by compiled wasm code. /// Return a raw pointer to the vmctx used by compiled wasm code.
pub fn vmctx_ptr(&self) -> *const VMContext { pub fn vmctx_ptr(&self) -> *const VMContext {
self.contents().vmctx_ptr() self.instance().vmctx_ptr()
} }
/// Return a mutable reference to the vmctx used by compiled wasm code. /// Return a mutable reference to the vmctx used by compiled wasm code.
pub fn vmctx_mut(&mut self) -> &mut VMContext { pub fn vmctx_mut(&mut self) -> &mut VMContext {
self.contents_mut().vmctx_mut() self.instance_mut().vmctx_mut()
} }
/// Return a mutable raw pointer to the vmctx used by compiled wasm code. /// Return a mutable raw pointer to the vmctx used by compiled wasm code.
pub fn vmctx_mut_ptr(&mut self) -> *mut VMContext { pub fn vmctx_mut_ptr(&mut self) -> *mut VMContext {
self.contents_mut().vmctx_mut_ptr() self.instance_mut().vmctx_mut_ptr()
} }
/// Lookup an export with the given name. /// Lookup an export with the given name.
pub fn lookup(&mut self, field: &str) -> Option<Export> { pub fn lookup(&mut self, field: &str) -> Option<Export> {
self.contents_mut().lookup(field) self.instance_mut().lookup(field)
} }
/// Lookup an export with the given name. This takes an immutable reference, /// Lookup an export with the given name. This takes an immutable reference,
/// and the result is an `Export` that the type system doesn't prevent from /// and the result is an `Export` that the type system doesn't prevent from
/// being used to mutate the instance, so this function is unsafe. /// being used to mutate the instance, so this function is unsafe.
pub unsafe fn lookup_immutable(&self, field: &str) -> Option<Export> { pub unsafe fn lookup_immutable(&self, field: &str) -> Option<Export> {
self.contents().lookup_immutable(field) self.instance().lookup_immutable(field)
} }
/// Lookup an export with the given export declaration. /// Lookup an export with the given export declaration.
pub fn lookup_by_declaration(&mut self, export: &wasmtime_environ::Export) -> Export { pub fn lookup_by_declaration(&mut self, export: &wasmtime_environ::Export) -> Export {
self.contents_mut().lookup_by_declaration(export) self.instance_mut().lookup_by_declaration(export)
} }
/// Lookup an export with the given export declaration. This takes an immutable /// Lookup an export with the given export declaration. This takes an immutable
@@ -812,7 +810,7 @@ impl InstanceHandle {
&self, &self,
export: &wasmtime_environ::Export, export: &wasmtime_environ::Export,
) -> Export { ) -> Export {
self.contents().lookup_immutable_by_declaration(export) self.instance().lookup_immutable_by_declaration(export)
} }
/// Return an iterator over the exports of this instance. /// Return an iterator over the exports of this instance.
@@ -821,30 +819,30 @@ impl InstanceHandle {
/// are export names, and the values are export declarations which can be /// are export names, and the values are export declarations which can be
/// resolved `lookup_by_declaration`. /// resolved `lookup_by_declaration`.
pub fn exports(&self) -> indexmap::map::Iter<String, wasmtime_environ::Export> { pub fn exports(&self) -> indexmap::map::Iter<String, wasmtime_environ::Export> {
self.contents().exports() self.instance().exports()
} }
/// Return a reference to the custom state attached to this instance. /// Return a reference to the custom state attached to this instance.
pub fn host_state(&mut self) -> &mut Any { pub fn host_state(&mut self) -> &mut Any {
self.contents_mut().host_state() self.instance_mut().host_state()
} }
} }
impl InstanceHandle { impl InstanceHandle {
/// Return the contained contents. /// Return a reference to the contained `Instance`.
fn contents(&self) -> &InstanceContents { fn instance(&self) -> &Instance {
unsafe { &*(self.instance as *const InstanceContents) } unsafe { &*(self.instance as *const Instance) }
} }
/// Return the contained contents. /// Return a mutable reference to the contained `Instance`.
fn contents_mut(&mut self) -> &mut InstanceContents { fn instance_mut(&mut self) -> &mut Instance {
unsafe { &mut *(self.instance as *mut InstanceContents) } unsafe { &mut *(self.instance as *mut Instance) }
} }
} }
impl Clone for InstanceHandle { impl Clone for InstanceHandle {
fn clone(&self) -> Self { fn clone(&self) -> Self {
unsafe { &mut *(self.instance as *mut InstanceContents) }.refcount += 1; unsafe { &mut *(self.instance as *mut Instance) }.refcount += 1;
InstanceHandle { InstanceHandle {
instance: self.instance, instance: self.instance,
} }
@@ -853,11 +851,11 @@ impl Clone for InstanceHandle {
impl Drop for InstanceHandle { impl Drop for InstanceHandle {
fn drop(&mut self) { fn drop(&mut self) {
let contents = self.contents_mut(); let instance = self.instance_mut();
contents.refcount -= 1; instance.refcount -= 1;
if contents.refcount == 0 { if instance.refcount == 0 {
let mmap = mem::replace(&mut contents.mmap, Mmap::new()); let mmap = mem::replace(&mut instance.mmap, Mmap::new());
unsafe { ptr::drop_in_place(contents) }; unsafe { ptr::drop_in_place(instance) };
mem::drop(mmap); mem::drop(mmap);
} }
} }
@@ -929,16 +927,16 @@ fn lookup_by_declaration(
} }
} }
fn check_table_init_bounds(contents: &mut InstanceContents) -> Result<(), InstantiationError> { fn check_table_init_bounds(instance: &mut Instance) -> Result<(), InstantiationError> {
let module = Rc::clone(&contents.module); let module = Rc::clone(&instance.module);
for init in &module.table_elements { for init in &module.table_elements {
let start = get_table_init_start(init, contents); let start = get_table_init_start(init, instance);
let slice = get_table_slice( let slice = get_table_slice(
init, init,
&contents.module, &instance.module,
&mut contents.tables, &mut instance.tables,
&contents.vmctx, &instance.vmctx,
&contents.offsets, &instance.offsets,
); );
if slice.get_mut(start..start + init.elements.len()).is_none() { if slice.get_mut(start..start + init.elements.len()).is_none() {
@@ -952,14 +950,14 @@ fn check_table_init_bounds(contents: &mut InstanceContents) -> Result<(), Instan
} }
/// Compute the offset for a memory data initializer. /// Compute the offset for a memory data initializer.
fn get_memory_init_start(init: &DataInitializer<'_>, contents: &mut InstanceContents) -> usize { fn get_memory_init_start(init: &DataInitializer<'_>, instance: &mut Instance) -> usize {
let mut start = init.location.offset; let mut start = init.location.offset;
if let Some(base) = init.location.base { if let Some(base) = init.location.base {
let global = if let Some(def_index) = contents.module.defined_global_index(base) { let global = if let Some(def_index) = instance.module.defined_global_index(base) {
contents.global_mut(def_index) instance.global_mut(def_index)
} else { } else {
contents.imported_global(base).from instance.imported_global(base).from
}; };
start += cast::usize(*unsafe { (*global).as_u32() }); start += cast::usize(*unsafe { (*global).as_u32() });
} }
@@ -968,32 +966,32 @@ fn get_memory_init_start(init: &DataInitializer<'_>, contents: &mut InstanceCont
} }
/// Return a byte-slice view of a memory's data. /// Return a byte-slice view of a memory's data.
fn get_memory_slice<'contents>( fn get_memory_slice<'instance>(
init: &DataInitializer<'_>, init: &DataInitializer<'_>,
contents: &'contents mut InstanceContents, instance: &'instance mut Instance,
) -> &'contents mut [u8] { ) -> &'instance mut [u8] {
let memory = if let Some(defined_memory_index) = contents let memory = if let Some(defined_memory_index) = instance
.module .module
.defined_memory_index(init.location.memory_index) .defined_memory_index(init.location.memory_index)
{ {
contents.memory(defined_memory_index) instance.memory(defined_memory_index)
} else { } else {
let import = contents.imported_memory(init.location.memory_index); let import = instance.imported_memory(init.location.memory_index);
let foreign_contents = unsafe { (&mut *(import).vmctx).instance_contents() }; let foreign_instance = unsafe { (&mut *(import).vmctx).instance() };
let foreign_memory = unsafe { &mut *(import).from }; let foreign_memory = unsafe { &mut *(import).from };
let foreign_index = foreign_contents.memory_index(foreign_memory); let foreign_index = foreign_instance.memory_index(foreign_memory);
foreign_contents.memory(foreign_index) foreign_instance.memory(foreign_index)
}; };
unsafe { slice::from_raw_parts_mut(memory.base, memory.current_length) } unsafe { slice::from_raw_parts_mut(memory.base, memory.current_length) }
} }
fn check_memory_init_bounds( fn check_memory_init_bounds(
contents: &mut InstanceContents, instance: &mut Instance,
data_initializers: &[DataInitializer<'_>], data_initializers: &[DataInitializer<'_>],
) -> Result<(), InstantiationError> { ) -> Result<(), InstantiationError> {
for init in data_initializers { for init in data_initializers {
let start = get_memory_init_start(init, contents); let start = get_memory_init_start(init, instance);
let mem_slice = get_memory_slice(init, contents); let mem_slice = get_memory_slice(init, instance);
if mem_slice.get_mut(start..start + init.data.len()).is_none() { if mem_slice.get_mut(start..start + init.data.len()).is_none() {
return Err(InstantiationError::Link(LinkError( return Err(InstantiationError::Link(LinkError(
@@ -1017,14 +1015,14 @@ fn create_tables(module: &Module) -> BoxedSlice<DefinedTableIndex, Table> {
} }
/// Compute the offset for a table element initializer. /// Compute the offset for a table element initializer.
fn get_table_init_start(init: &TableElements, contents: &mut InstanceContents) -> usize { fn get_table_init_start(init: &TableElements, instance: &mut Instance) -> usize {
let mut start = init.offset; let mut start = init.offset;
if let Some(base) = init.base { if let Some(base) = init.base {
let global = if let Some(def_index) = contents.module.defined_global_index(base) { let global = if let Some(def_index) = instance.module.defined_global_index(base) {
contents.global_mut(def_index) instance.global_mut(def_index)
} else { } else {
contents.imported_global(base).from instance.imported_global(base).from
}; };
start += cast::usize(*unsafe { (*global).as_u32() }); start += cast::usize(*unsafe { (*global).as_u32() });
} }
@@ -1033,50 +1031,50 @@ fn get_table_init_start(init: &TableElements, contents: &mut InstanceContents) -
} }
/// Return a byte-slice view of a table's data. /// Return a byte-slice view of a table's data.
fn get_table_slice<'contents>( fn get_table_slice<'instance>(
init: &TableElements, init: &TableElements,
module: &Module, module: &Module,
tables: &'contents mut BoxedSlice<DefinedTableIndex, Table>, tables: &'instance mut BoxedSlice<DefinedTableIndex, Table>,
vmctx: &VMContext, vmctx: &VMContext,
offsets: &VMOffsets, offsets: &VMOffsets,
) -> &'contents mut [VMCallerCheckedAnyfunc] { ) -> &'instance mut [VMCallerCheckedAnyfunc] {
if let Some(defined_table_index) = module.defined_table_index(init.table_index) { if let Some(defined_table_index) = module.defined_table_index(init.table_index) {
tables[defined_table_index].as_mut() tables[defined_table_index].as_mut()
} else { } else {
let import = imported_table(vmctx, offsets, init.table_index); let import = imported_table(vmctx, offsets, init.table_index);
let foreign_contents = unsafe { (&mut *(import).vmctx).instance_contents() }; let foreign_instance = unsafe { (&mut *(import).vmctx).instance() };
let foreign_table = unsafe { &mut *(import).from }; let foreign_table = unsafe { &mut *(import).from };
let foreign_index = foreign_contents.table_index(foreign_table); let foreign_index = foreign_instance.table_index(foreign_table);
foreign_contents.tables[foreign_index].as_mut() foreign_instance.tables[foreign_index].as_mut()
} }
} }
/// Initialize the table memory from the provided initializers. /// Initialize the table memory from the provided initializers.
fn initialize_tables(contents: &mut InstanceContents) -> Result<(), InstantiationError> { fn initialize_tables(instance: &mut Instance) -> Result<(), InstantiationError> {
let vmctx: *mut VMContext = contents.vmctx_mut(); let vmctx: *mut VMContext = instance.vmctx_mut();
let module = Rc::clone(&contents.module); let module = Rc::clone(&instance.module);
for init in &module.table_elements { for init in &module.table_elements {
let start = get_table_init_start(init, contents); let start = get_table_init_start(init, instance);
let slice = get_table_slice( let slice = get_table_slice(
init, init,
&contents.module, &instance.module,
&mut contents.tables, &mut instance.tables,
&contents.vmctx, &instance.vmctx,
&contents.offsets, &instance.offsets,
); );
let subslice = &mut slice[start..start + init.elements.len()]; let subslice = &mut slice[start..start + init.elements.len()];
for (i, func_idx) in init.elements.iter().enumerate() { for (i, func_idx) in init.elements.iter().enumerate() {
let callee_sig = contents.module.functions[*func_idx]; let callee_sig = instance.module.functions[*func_idx];
let (callee_ptr, callee_vmctx) = let (callee_ptr, callee_vmctx) =
if let Some(index) = contents.module.defined_func_index(*func_idx) { if let Some(index) = instance.module.defined_func_index(*func_idx) {
(contents.finished_functions[index], vmctx) (instance.finished_functions[index], vmctx)
} else { } else {
let imported_func = let imported_func =
imported_function(&contents.vmctx, &contents.offsets, *func_idx); imported_function(&instance.vmctx, &instance.offsets, *func_idx);
(imported_func.body, imported_func.vmctx) (imported_func.body, imported_func.vmctx)
}; };
let type_index = signature_id(&contents.vmctx, &contents.offsets, callee_sig); let type_index = signature_id(&instance.vmctx, &instance.offsets, callee_sig);
subslice[i] = VMCallerCheckedAnyfunc { subslice[i] = VMCallerCheckedAnyfunc {
func_ptr: callee_ptr, func_ptr: callee_ptr,
type_index, type_index,
@@ -1103,12 +1101,12 @@ fn create_memories(
/// Initialize the table memory from the provided initializers. /// Initialize the table memory from the provided initializers.
fn initialize_memories( fn initialize_memories(
contents: &mut InstanceContents, instance: &mut Instance,
data_initializers: &[DataInitializer<'_>], data_initializers: &[DataInitializer<'_>],
) -> Result<(), InstantiationError> { ) -> Result<(), InstantiationError> {
for init in data_initializers { for init in data_initializers {
let start = get_memory_init_start(init, contents); let start = get_memory_init_start(init, instance);
let mem_slice = get_memory_slice(init, contents); let mem_slice = get_memory_slice(init, instance);
let to_init = &mut mem_slice[start..start + init.data.len()]; let to_init = &mut mem_slice[start..start + init.data.len()];
to_init.copy_from_slice(init.data); to_init.copy_from_slice(init.data);
@@ -1130,12 +1128,12 @@ fn create_globals(module: &Module) -> BoxedSlice<DefinedGlobalIndex, VMGlobalDef
vmctx_globals.into_boxed_slice() vmctx_globals.into_boxed_slice()
} }
fn initialize_globals(contents: &mut InstanceContents) { fn initialize_globals(instance: &mut Instance) {
let module = Rc::clone(&contents.module); let module = Rc::clone(&instance.module);
let num_imports = module.imported_globals.len(); let num_imports = module.imported_globals.len();
for (index, global) in module.globals.iter().skip(num_imports) { for (index, global) in module.globals.iter().skip(num_imports) {
let def_index = module.defined_global_index(index).unwrap(); let def_index = module.defined_global_index(index).unwrap();
let to: *mut VMGlobalDefinition = contents.global_mut(def_index); let to: *mut VMGlobalDefinition = instance.global_mut(def_index);
match global.initializer { match global.initializer {
GlobalInit::I32Const(x) => *unsafe { (*to).as_i32_mut() } = x, GlobalInit::I32Const(x) => *unsafe { (*to).as_i32_mut() } = x,
GlobalInit::I64Const(x) => *unsafe { (*to).as_i64_mut() } = x, GlobalInit::I64Const(x) => *unsafe { (*to).as_i64_mut() } = x,
@@ -1143,9 +1141,9 @@ fn initialize_globals(contents: &mut InstanceContents) {
GlobalInit::F64Const(x) => *unsafe { (*to).as_f64_bits_mut() } = x, GlobalInit::F64Const(x) => *unsafe { (*to).as_f64_bits_mut() } = x,
GlobalInit::GetGlobal(x) => { GlobalInit::GetGlobal(x) => {
let from = if let Some(def_x) = module.defined_global_index(x) { let from = if let Some(def_x) = module.defined_global_index(x) {
contents.global_mut(def_x) instance.global_mut(def_x)
} else { } else {
contents.imported_global(x).from instance.imported_global(x).from
}; };
unsafe { *to = *from }; unsafe { *to = *from };
} }

View File

@@ -94,10 +94,10 @@ pub unsafe extern "C" fn wasmtime_memory32_grow(
delta: u32, delta: u32,
memory_index: u32, memory_index: u32,
) -> u32 { ) -> u32 {
let instance_contents = (&mut *vmctx).instance_contents(); let instance = (&mut *vmctx).instance();
let memory_index = DefinedMemoryIndex::from_u32(memory_index); let memory_index = DefinedMemoryIndex::from_u32(memory_index);
instance_contents instance
.memory_grow(memory_index, delta) .memory_grow(memory_index, delta)
.unwrap_or(u32::max_value()) .unwrap_or(u32::max_value())
} }
@@ -109,10 +109,10 @@ pub unsafe extern "C" fn wasmtime_imported_memory32_grow(
delta: u32, delta: u32,
memory_index: u32, memory_index: u32,
) -> u32 { ) -> u32 {
let instance_contents = (&mut *vmctx).instance_contents(); let instance = (&mut *vmctx).instance();
let memory_index = MemoryIndex::from_u32(memory_index); let memory_index = MemoryIndex::from_u32(memory_index);
instance_contents instance
.imported_memory_grow(memory_index, delta) .imported_memory_grow(memory_index, delta)
.unwrap_or(u32::max_value()) .unwrap_or(u32::max_value())
} }
@@ -120,10 +120,10 @@ pub unsafe extern "C" fn wasmtime_imported_memory32_grow(
/// Implementation of memory.size for locally-defined 32-bit memories. /// Implementation of memory.size for locally-defined 32-bit memories.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn wasmtime_memory32_size(vmctx: *mut VMContext, memory_index: u32) -> u32 { pub unsafe extern "C" fn wasmtime_memory32_size(vmctx: *mut VMContext, memory_index: u32) -> u32 {
let instance_contents = (&mut *vmctx).instance_contents(); let instance = (&mut *vmctx).instance();
let memory_index = DefinedMemoryIndex::from_u32(memory_index); let memory_index = DefinedMemoryIndex::from_u32(memory_index);
instance_contents.memory_size(memory_index) instance.memory_size(memory_index)
} }
/// Implementation of memory.size for imported 32-bit memories. /// Implementation of memory.size for imported 32-bit memories.
@@ -132,8 +132,8 @@ pub unsafe extern "C" fn wasmtime_imported_memory32_size(
vmctx: *mut VMContext, vmctx: *mut VMContext,
memory_index: u32, memory_index: u32,
) -> u32 { ) -> u32 {
let instance_contents = (&mut *vmctx).instance_contents(); let instance = (&mut *vmctx).instance();
let memory_index = MemoryIndex::from_u32(memory_index); let memory_index = MemoryIndex::from_u32(memory_index);
instance_contents.imported_memory_size(memory_index) instance.imported_memory_size(memory_index)
} }

View File

@@ -94,9 +94,9 @@ pub extern "C" fn wasmtime_init_finish(vmctx: &mut VMContext) {
}) })
} }
let instance_contents = unsafe { vmctx.instance_contents() }; let instance = unsafe { vmctx.instance() };
let have_signal_handlers = TRAP_CONTEXT.with(|cx| cx.borrow().haveSignalHandlers); let have_signal_handlers = TRAP_CONTEXT.with(|cx| cx.borrow().haveSignalHandlers);
if !have_signal_handlers && instance_contents.needs_signal_handlers() { if !have_signal_handlers && instance.needs_signal_handlers() {
panic!("failed to install signal handlers"); panic!("failed to install signal handlers");
} }
} }

View File

@@ -1,7 +1,7 @@
//! This file declares `VMContext` and several related structs which contain //! This file declares `VMContext` and several related structs which contain
//! fields that compiled wasm code accesses directly. //! fields that compiled wasm code accesses directly.
use crate::instance::InstanceContents; use crate::instance::Instance;
use core::any::Any; use core::any::Any;
use core::{ptr, u32}; use core::{ptr, u32};
@@ -478,26 +478,25 @@ impl Default for VMCallerCheckedAnyfunc {
pub struct VMContext {} pub struct VMContext {}
impl VMContext { impl VMContext {
/// Return a mutable reference to the associated `InstanceContents`. /// Return a mutable reference to the associated `Instance`.
/// ///
/// This is unsafe because it doesn't work on just any `VMContext`, it must /// This is unsafe because it doesn't work on just any `VMContext`, it must
/// be a `VMContext` allocated as part of an `InstanceContents`. /// be a `VMContext` allocated as part of an `Instance`.
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub(crate) unsafe fn instance_contents(&mut self) -> &mut InstanceContents { pub(crate) unsafe fn instance(&mut self) -> &mut Instance {
&mut *((self as *mut Self as *mut u8).offset(-InstanceContents::vmctx_offset()) &mut *((self as *mut Self as *mut u8).offset(-Instance::vmctx_offset()) as *mut Instance)
as *mut InstanceContents)
} }
/// Return a mutable reference to the host state associated with `InstanceContents`. /// Return a mutable reference to the host state associated with this `Instance`.
/// ///
/// This is unsafe because it doesn't work on just any `VMContext`, it must /// This is unsafe because it doesn't work on just any `VMContext`, it must
/// be a `VMContext` allocated as part of an `InstanceContents`. /// be a `VMContext` allocated as part of an `Instance`.
pub unsafe fn host_state(&mut self) -> &mut Any { pub unsafe fn host_state(&mut self) -> &mut Any {
self.instance_contents().host_state() self.instance().host_state()
} }
/// Lookup an export in the global exports namespace. /// Lookup an export in the global exports namespace.
pub unsafe fn lookup_global_export(&mut self, field: &str) -> Option<crate::export::Export> { pub unsafe fn lookup_global_export(&mut self, field: &str) -> Option<crate::export::Export> {
self.instance_contents().lookup_global_export(field) self.instance().lookup_global_export(field)
} }
} }