Refactor instance accessor routines.
This helps localize the unsafe code needed to access these fields.
This commit is contained in:
@@ -4,8 +4,8 @@
|
|||||||
use cranelift_entity::EntityRef;
|
use cranelift_entity::EntityRef;
|
||||||
use cranelift_entity::{BoxedSlice, PrimaryMap};
|
use cranelift_entity::{BoxedSlice, PrimaryMap};
|
||||||
use cranelift_wasm::{
|
use cranelift_wasm::{
|
||||||
DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, GlobalInit,
|
DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, FuncIndex,
|
||||||
SignatureIndex,
|
GlobalIndex, GlobalInit, MemoryIndex, SignatureIndex, TableIndex,
|
||||||
};
|
};
|
||||||
use export::Export;
|
use export::Export;
|
||||||
use imports::Imports;
|
use imports::Imports;
|
||||||
@@ -17,20 +17,15 @@ use std::string::String;
|
|||||||
use table::Table;
|
use table::Table;
|
||||||
use traphandlers::wasmtime_call;
|
use traphandlers::wasmtime_call;
|
||||||
use vmcontext::{
|
use vmcontext::{
|
||||||
VMCallerCheckedAnyfunc, VMContext, VMFunctionBody, VMGlobalDefinition, VMMemoryDefinition,
|
VMCallerCheckedAnyfunc, VMContext, VMFunctionBody, VMFunctionImport, VMGlobalDefinition,
|
||||||
VMSharedSignatureIndex, VMTableDefinition,
|
VMGlobalImport, VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition,
|
||||||
|
VMTableImport,
|
||||||
};
|
};
|
||||||
use wasmtime_environ::{DataInitializer, Module};
|
use wasmtime_environ::{DataInitializer, Module};
|
||||||
|
|
||||||
/// An Instance of a WebAssemby module.
|
/// The runtime state of an `Instance`.
|
||||||
///
|
|
||||||
/// Note that compiled wasm code passes around raw pointers to `Instance`, so
|
|
||||||
/// this shouldn't be moved.
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Instance {
|
struct State {
|
||||||
/// The `Module` this `Instance` was instantiated from.
|
|
||||||
module: Rc<Module>,
|
|
||||||
|
|
||||||
/// WebAssembly linear memory data.
|
/// WebAssembly linear memory data.
|
||||||
memories: BoxedSlice<DefinedMemoryIndex, LinearMemory>,
|
memories: BoxedSlice<DefinedMemoryIndex, LinearMemory>,
|
||||||
|
|
||||||
@@ -59,6 +54,83 @@ pub struct Instance {
|
|||||||
vmctx: VMContext,
|
vmctx: VMContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
/// Return the indexed `VMFunctionImport`.
|
||||||
|
fn imported_function(&self, index: FuncIndex) -> &VMFunctionImport {
|
||||||
|
assert!(index.index() < self.vmctx_imports.functions.len());
|
||||||
|
unsafe { self.vmctx.imported_function(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a reference to imported table `index`.
|
||||||
|
fn imported_table(&self, index: TableIndex) -> &VMTableImport {
|
||||||
|
assert!(index.index() < self.vmctx_imports.tables.len());
|
||||||
|
unsafe { self.vmctx.imported_table(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a reference to imported memory `index`.
|
||||||
|
fn imported_memory(&self, index: MemoryIndex) -> &VMMemoryImport {
|
||||||
|
assert!(index.index() < self.vmctx_imports.memories.len());
|
||||||
|
unsafe { self.vmctx.imported_memory(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a reference to imported global `index`.
|
||||||
|
fn imported_global(&self, index: GlobalIndex) -> &VMGlobalImport {
|
||||||
|
assert!(index.index() < self.vmctx_imports.globals.len());
|
||||||
|
unsafe { self.vmctx.imported_global(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a reference to locally-defined table `index`.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn table(&self, index: DefinedTableIndex) -> &VMTableDefinition {
|
||||||
|
assert!(index.index() < self.tables.len());
|
||||||
|
unsafe { self.vmctx.table(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a mutable reference to locally-defined table `index`.
|
||||||
|
fn table_mut(&mut self, index: DefinedTableIndex) -> &mut VMTableDefinition {
|
||||||
|
assert!(index.index() < self.tables.len());
|
||||||
|
unsafe { self.vmctx.table_mut(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a reference to locally-defined linear memory `index`.
|
||||||
|
fn memory(&self, index: DefinedMemoryIndex) -> &VMMemoryDefinition {
|
||||||
|
assert!(index.index() < self.memories.len());
|
||||||
|
unsafe { self.vmctx.memory(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a mutable reference to locally-defined linear memory `index`.
|
||||||
|
fn memory_mut(&mut self, index: DefinedMemoryIndex) -> &mut VMMemoryDefinition {
|
||||||
|
assert!(index.index() < self.memories.len());
|
||||||
|
unsafe { self.vmctx.memory_mut(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a reference to locally-defined global variable `index`.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn global(&self, index: DefinedGlobalIndex) -> &VMGlobalDefinition {
|
||||||
|
assert!(index.index() < self.vmctx_globals.len());
|
||||||
|
unsafe { self.vmctx.global(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a mutable reference to locally-defined global variable `index`.
|
||||||
|
fn global_mut(&mut self, index: DefinedGlobalIndex) -> &mut VMGlobalDefinition {
|
||||||
|
assert!(index.index() < self.vmctx_globals.len());
|
||||||
|
unsafe { self.vmctx.global_mut(index) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An Instance of a WebAssemby module.
|
||||||
|
///
|
||||||
|
/// Note that compiled wasm code passes around raw pointers to `Instance`, so
|
||||||
|
/// this shouldn't be moved.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Instance {
|
||||||
|
/// The `Module` this `Instance` was instantiated from.
|
||||||
|
module: Rc<Module>,
|
||||||
|
|
||||||
|
/// The runtime state of this instance.
|
||||||
|
state: State,
|
||||||
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
/// Create a new `Instance`.
|
/// Create a new `Instance`.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
@@ -106,6 +178,7 @@ impl Instance {
|
|||||||
|
|
||||||
let mut result = Box::new(Self {
|
let mut result = Box::new(Self {
|
||||||
module,
|
module,
|
||||||
|
state: State {
|
||||||
memories,
|
memories,
|
||||||
tables,
|
tables,
|
||||||
vmshared_signatures,
|
vmshared_signatures,
|
||||||
@@ -124,6 +197,7 @@ impl Instance {
|
|||||||
vmctx_globals_ptr,
|
vmctx_globals_ptr,
|
||||||
vmctx_shared_signatures_ptr,
|
vmctx_shared_signatures_ptr,
|
||||||
),
|
),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check initializer bounds before initializing anything.
|
// Check initializer bounds before initializing anything.
|
||||||
@@ -153,7 +227,7 @@ impl 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.vmctx
|
&self.state.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.
|
||||||
@@ -163,7 +237,7 @@ impl Instance {
|
|||||||
|
|
||||||
/// 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 {
|
||||||
&mut self.vmctx
|
&mut self.state.vmctx
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
@@ -173,7 +247,7 @@ impl Instance {
|
|||||||
|
|
||||||
/// Return the offset from the vmctx pointer to its containing Instance.
|
/// 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, state) + offset_of!(State, vmctx)) as isize
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Grow memory by the specified amount of pages.
|
/// Grow memory by the specified amount of pages.
|
||||||
@@ -182,20 +256,22 @@ impl Instance {
|
|||||||
/// of pages.
|
/// of pages.
|
||||||
pub fn memory_grow(&mut self, memory_index: DefinedMemoryIndex, delta: u32) -> Option<u32> {
|
pub fn memory_grow(&mut self, memory_index: DefinedMemoryIndex, delta: u32) -> Option<u32> {
|
||||||
let result = self
|
let result = self
|
||||||
|
.state
|
||||||
.memories
|
.memories
|
||||||
.get_mut(memory_index)
|
.get_mut(memory_index)
|
||||||
.unwrap_or_else(|| panic!("no memory for index {}", memory_index.index()))
|
.unwrap_or_else(|| panic!("no memory for index {}", memory_index.index()))
|
||||||
.grow(delta);
|
.grow(delta);
|
||||||
|
|
||||||
// Keep current the VMContext pointers used by compiled wasm code.
|
// Keep current the VMContext pointers used by compiled wasm code.
|
||||||
self.vmctx_memories[memory_index] = self.memories[memory_index].vmmemory();
|
self.state.vmctx_memories[memory_index] = self.state.memories[memory_index].vmmemory();
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of allocated wasm pages.
|
/// Returns the number of allocated wasm pages.
|
||||||
pub fn memory_size(&mut self, memory_index: DefinedMemoryIndex) -> u32 {
|
pub fn memory_size(&mut self, memory_index: DefinedMemoryIndex) -> u32 {
|
||||||
self.memories
|
self.state
|
||||||
|
.memories
|
||||||
.get(memory_index)
|
.get(memory_index)
|
||||||
.unwrap_or_else(|| panic!("no memory for index {}", memory_index.index()))
|
.unwrap_or_else(|| panic!("no memory for index {}", memory_index.index()))
|
||||||
.size()
|
.size()
|
||||||
@@ -204,14 +280,15 @@ impl Instance {
|
|||||||
/// Test whether any of the objects inside this instance require signal
|
/// Test whether any of the objects inside this instance require signal
|
||||||
/// handlers to catch out of bounds accesses.
|
/// handlers to catch out of bounds accesses.
|
||||||
pub(crate) fn needs_signal_handlers(&self) -> bool {
|
pub(crate) fn needs_signal_handlers(&self) -> bool {
|
||||||
self.memories
|
self.state
|
||||||
|
.memories
|
||||||
.values()
|
.values()
|
||||||
.any(|memory| memory.needs_signal_handlers)
|
.any(|memory| memory.needs_signal_handlers)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the number of imported memories.
|
/// Return the number of imported memories.
|
||||||
pub(crate) fn num_imported_memories(&self) -> usize {
|
pub(crate) fn num_imported_memories(&self) -> usize {
|
||||||
self.vmctx_imports.memories.len()
|
self.state.vmctx_imports.memories.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invoke the WebAssembly start function of the instance, if one is present.
|
/// Invoke the WebAssembly start function of the instance, if one is present.
|
||||||
@@ -220,6 +297,7 @@ impl Instance {
|
|||||||
let (callee_address, callee_vmctx) = match self.module.defined_func_index(start_index) {
|
let (callee_address, callee_vmctx) = match self.module.defined_func_index(start_index) {
|
||||||
Some(defined_start_index) => {
|
Some(defined_start_index) => {
|
||||||
let body = *self
|
let body = *self
|
||||||
|
.state
|
||||||
.finished_functions
|
.finished_functions
|
||||||
.get(defined_start_index)
|
.get(defined_start_index)
|
||||||
.expect("start function index is out of bounds");
|
.expect("start function index is out of bounds");
|
||||||
@@ -227,7 +305,7 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(start_index.index() < self.module.imported_funcs.len());
|
assert!(start_index.index() < self.module.imported_funcs.len());
|
||||||
let import = unsafe { self.vmctx.imported_function(start_index) };
|
let import = self.state.imported_function(start_index);
|
||||||
(import.body, import.vmctx)
|
(import.body, import.vmctx)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -249,11 +327,11 @@ impl Instance {
|
|||||||
let (address, vmctx) =
|
let (address, vmctx) =
|
||||||
if let Some(def_index) = self.module.defined_func_index(*index) {
|
if let Some(def_index) = self.module.defined_func_index(*index) {
|
||||||
(
|
(
|
||||||
self.finished_functions[def_index],
|
self.state.finished_functions[def_index],
|
||||||
&mut self.vmctx as *mut VMContext,
|
&mut self.state.vmctx as *mut VMContext,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let import = unsafe { self.vmctx.imported_function(*index) };
|
let import = self.state.imported_function(*index);
|
||||||
(import.body, import.vmctx)
|
(import.body, import.vmctx)
|
||||||
};
|
};
|
||||||
Export::Function {
|
Export::Function {
|
||||||
@@ -263,15 +341,14 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
wasmtime_environ::Export::Table(index) => {
|
wasmtime_environ::Export::Table(index) => {
|
||||||
let (definition, vmctx) = if let Some(def_index) =
|
let (definition, vmctx) =
|
||||||
self.module.defined_table_index(*index)
|
if let Some(def_index) = self.module.defined_table_index(*index) {
|
||||||
{
|
|
||||||
(
|
(
|
||||||
unsafe { self.vmctx.table_mut(def_index) } as *mut VMTableDefinition,
|
self.state.table_mut(def_index) as *mut VMTableDefinition,
|
||||||
&mut self.vmctx as *mut VMContext,
|
&mut self.state.vmctx as *mut VMContext,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let import = unsafe { self.vmctx.imported_table(*index) };
|
let import = self.state.imported_table(*index);
|
||||||
(import.from, import.vmctx)
|
(import.from, import.vmctx)
|
||||||
};
|
};
|
||||||
Export::Table {
|
Export::Table {
|
||||||
@@ -281,15 +358,14 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
wasmtime_environ::Export::Memory(index) => {
|
wasmtime_environ::Export::Memory(index) => {
|
||||||
let (definition, vmctx) = if let Some(def_index) =
|
let (definition, vmctx) =
|
||||||
self.module.defined_memory_index(*index)
|
if let Some(def_index) = self.module.defined_memory_index(*index) {
|
||||||
{
|
|
||||||
(
|
(
|
||||||
unsafe { self.vmctx.memory_mut(def_index) } as *mut VMMemoryDefinition,
|
self.state.memory_mut(def_index) as *mut VMMemoryDefinition,
|
||||||
&mut self.vmctx as *mut VMContext,
|
&mut self.state.vmctx as *mut VMContext,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let import = unsafe { self.vmctx.imported_memory(*index) };
|
let import = self.state.imported_memory(*index);
|
||||||
(import.from, import.vmctx)
|
(import.from, import.vmctx)
|
||||||
};
|
};
|
||||||
Export::Memory {
|
Export::Memory {
|
||||||
@@ -300,9 +376,9 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
wasmtime_environ::Export::Global(index) => Export::Global {
|
wasmtime_environ::Export::Global(index) => Export::Global {
|
||||||
definition: if let Some(def_index) = self.module.defined_global_index(*index) {
|
definition: if let Some(def_index) = self.module.defined_global_index(*index) {
|
||||||
unsafe { self.vmctx.global_mut(def_index) }
|
self.state.global_mut(def_index)
|
||||||
} else {
|
} else {
|
||||||
unsafe { self.vmctx.imported_global(*index).from }
|
self.state.imported_global(*index).from
|
||||||
},
|
},
|
||||||
global: self.module.globals[*index],
|
global: self.module.globals[*index],
|
||||||
},
|
},
|
||||||
@@ -328,9 +404,9 @@ fn check_table_init_bounds(instance: &mut Instance) -> Result<(), InstantiationE
|
|||||||
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) = instance.module.defined_global_index(base) {
|
let global = if let Some(def_index) = instance.module.defined_global_index(base) {
|
||||||
unsafe { instance.vmctx.global_mut(def_index) }
|
instance.state.global_mut(def_index)
|
||||||
} else {
|
} else {
|
||||||
unsafe { instance.vmctx.imported_global(base).from }
|
instance.state.imported_global(base).from
|
||||||
};
|
};
|
||||||
start += unsafe { *(&*global).as_u32() } as usize;
|
start += unsafe { *(&*global).as_u32() } as usize;
|
||||||
}
|
}
|
||||||
@@ -339,13 +415,13 @@ fn check_table_init_bounds(instance: &mut Instance) -> Result<(), InstantiationE
|
|||||||
let slice = if let Some(defined_table_index) =
|
let slice = if let Some(defined_table_index) =
|
||||||
instance.module.defined_table_index(init.table_index)
|
instance.module.defined_table_index(init.table_index)
|
||||||
{
|
{
|
||||||
instance.tables[defined_table_index].as_mut()
|
instance.state.tables[defined_table_index].as_mut()
|
||||||
} else {
|
} else {
|
||||||
let import = &instance.vmctx_imports.tables[init.table_index];
|
let import = &instance.state.vmctx_imports.tables[init.table_index];
|
||||||
let foreign_instance = unsafe { (&mut *(import).vmctx).instance() };
|
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_instance.vmctx().table_index(foreign_table);
|
let foreign_index = foreign_instance.vmctx().table_index(foreign_table);
|
||||||
foreign_instance.tables[foreign_index].as_mut()
|
foreign_instance.state.tables[foreign_index].as_mut()
|
||||||
};
|
};
|
||||||
|
|
||||||
if slice.get_mut(start..start + init.elements.len()).is_none() {
|
if slice.get_mut(start..start + init.elements.len()).is_none() {
|
||||||
@@ -367,9 +443,9 @@ fn check_memory_init_bounds(
|
|||||||
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) = instance.module.defined_global_index(base) {
|
let global = if let Some(def_index) = instance.module.defined_global_index(base) {
|
||||||
unsafe { instance.vmctx.global_mut(def_index) }
|
instance.state.global_mut(def_index)
|
||||||
} else {
|
} else {
|
||||||
unsafe { instance.vmctx.imported_global(base).from }
|
instance.state.imported_global(base).from
|
||||||
};
|
};
|
||||||
start += unsafe { *(&*global).as_u32() } as usize;
|
start += unsafe { *(&*global).as_u32() } as usize;
|
||||||
}
|
}
|
||||||
@@ -379,13 +455,13 @@ fn check_memory_init_bounds(
|
|||||||
.module
|
.module
|
||||||
.defined_memory_index(init.location.memory_index)
|
.defined_memory_index(init.location.memory_index)
|
||||||
{
|
{
|
||||||
unsafe { instance.vmctx.memory(defined_memory_index) }
|
instance.state.memory(defined_memory_index)
|
||||||
} else {
|
} else {
|
||||||
let import = &instance.vmctx_imports.memories[init.location.memory_index];
|
let import = &instance.state.vmctx_imports.memories[init.location.memory_index];
|
||||||
let foreign_instance = unsafe { (&mut *(import).vmctx).instance() };
|
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_instance.vmctx().memory_index(foreign_memory);
|
let foreign_index = foreign_instance.vmctx().memory_index(foreign_memory);
|
||||||
unsafe { foreign_instance.vmctx.memory(foreign_index) }
|
foreign_instance.state.memory(foreign_index)
|
||||||
};
|
};
|
||||||
let mem_slice = unsafe { slice::from_raw_parts_mut(memory.base, memory.current_length) };
|
let mem_slice = unsafe { slice::from_raw_parts_mut(memory.base, memory.current_length) };
|
||||||
|
|
||||||
@@ -417,9 +493,9 @@ fn initialize_tables(instance: &mut Instance) -> Result<(), InstantiationError>
|
|||||||
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) = instance.module.defined_global_index(base) {
|
let global = if let Some(def_index) = instance.module.defined_global_index(base) {
|
||||||
unsafe { instance.vmctx.global_mut(def_index) }
|
instance.state.global_mut(def_index)
|
||||||
} else {
|
} else {
|
||||||
unsafe { instance.vmctx.imported_global(base).from }
|
instance.state.imported_global(base).from
|
||||||
};
|
};
|
||||||
start += unsafe { *(&*global).as_i32() } as u32 as usize;
|
start += unsafe { *(&*global).as_i32() } as u32 as usize;
|
||||||
}
|
}
|
||||||
@@ -427,25 +503,25 @@ fn initialize_tables(instance: &mut Instance) -> Result<(), InstantiationError>
|
|||||||
let slice = if let Some(defined_table_index) =
|
let slice = if let Some(defined_table_index) =
|
||||||
instance.module.defined_table_index(init.table_index)
|
instance.module.defined_table_index(init.table_index)
|
||||||
{
|
{
|
||||||
instance.tables[defined_table_index].as_mut()
|
instance.state.tables[defined_table_index].as_mut()
|
||||||
} else {
|
} else {
|
||||||
let import = &instance.vmctx_imports.tables[init.table_index];
|
let import = &instance.state.vmctx_imports.tables[init.table_index];
|
||||||
let foreign_instance = unsafe { (&mut *(import).vmctx).instance() };
|
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_instance.vmctx().table_index(foreign_table);
|
let foreign_index = foreign_instance.vmctx().table_index(foreign_table);
|
||||||
foreign_instance.tables[foreign_index].as_mut()
|
foreign_instance.state.tables[foreign_index].as_mut()
|
||||||
};
|
};
|
||||||
if let Some(subslice) = slice.get_mut(start..start + init.elements.len()) {
|
if let Some(subslice) = slice.get_mut(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 = instance.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) = instance.module.defined_func_index(*func_idx) {
|
if let Some(index) = instance.module.defined_func_index(*func_idx) {
|
||||||
(instance.finished_functions[index], vmctx)
|
(instance.state.finished_functions[index], vmctx)
|
||||||
} else {
|
} else {
|
||||||
let imported_func = &instance.vmctx_imports.functions[*func_idx];
|
let imported_func = &instance.state.vmctx_imports.functions[*func_idx];
|
||||||
(imported_func.body, imported_func.vmctx)
|
(imported_func.body, imported_func.vmctx)
|
||||||
};
|
};
|
||||||
let type_index = instance.vmshared_signatures[callee_sig];
|
let type_index = instance.state.vmshared_signatures[callee_sig];
|
||||||
subslice[i] = VMCallerCheckedAnyfunc {
|
subslice[i] = VMCallerCheckedAnyfunc {
|
||||||
func_ptr: callee_ptr,
|
func_ptr: callee_ptr,
|
||||||
type_index,
|
type_index,
|
||||||
@@ -484,9 +560,9 @@ fn initialize_memories(
|
|||||||
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) = instance.module.defined_global_index(base) {
|
let global = if let Some(def_index) = instance.module.defined_global_index(base) {
|
||||||
unsafe { instance.vmctx.global_mut(def_index) }
|
instance.state.global_mut(def_index)
|
||||||
} else {
|
} else {
|
||||||
unsafe { instance.vmctx.imported_global(base).from }
|
instance.state.imported_global(base).from
|
||||||
};
|
};
|
||||||
start += unsafe { *(&*global).as_i32() } as u32 as usize;
|
start += unsafe { *(&*global).as_i32() } as u32 as usize;
|
||||||
}
|
}
|
||||||
@@ -495,13 +571,13 @@ fn initialize_memories(
|
|||||||
.module
|
.module
|
||||||
.defined_memory_index(init.location.memory_index)
|
.defined_memory_index(init.location.memory_index)
|
||||||
{
|
{
|
||||||
unsafe { instance.vmctx.memory(defined_memory_index) }
|
instance.state.memory(defined_memory_index)
|
||||||
} else {
|
} else {
|
||||||
let import = &instance.vmctx_imports.memories[init.location.memory_index];
|
let import = &instance.state.vmctx_imports.memories[init.location.memory_index];
|
||||||
let foreign_instance = unsafe { (&mut *(import).vmctx).instance() };
|
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_instance.vmctx().memory_index(foreign_memory);
|
let foreign_index = foreign_instance.vmctx().memory_index(foreign_memory);
|
||||||
unsafe { foreign_instance.vmctx.memory(foreign_index) }
|
foreign_instance.state.memory(foreign_index)
|
||||||
};
|
};
|
||||||
let mem_slice = unsafe { slice::from_raw_parts_mut(memory.base, memory.current_length) };
|
let mem_slice = unsafe { slice::from_raw_parts_mut(memory.base, memory.current_length) };
|
||||||
if let Some(to_init) = mem_slice.get_mut(start..start + init.data.len()) {
|
if let Some(to_init) = mem_slice.get_mut(start..start + init.data.len()) {
|
||||||
@@ -533,7 +609,7 @@ fn initialize_globals(instance: &mut Instance) {
|
|||||||
let num_imports = instance.module.imported_globals.len();
|
let num_imports = instance.module.imported_globals.len();
|
||||||
for (index, global) in instance.module.globals.iter().skip(num_imports) {
|
for (index, global) in instance.module.globals.iter().skip(num_imports) {
|
||||||
let def_index = instance.module.defined_global_index(index).unwrap();
|
let def_index = instance.module.defined_global_index(index).unwrap();
|
||||||
let to: *mut VMGlobalDefinition = unsafe { instance.vmctx.global_mut(def_index) };
|
let to: *mut VMGlobalDefinition = instance.state.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,
|
||||||
@@ -541,9 +617,9 @@ fn initialize_globals(instance: &mut Instance) {
|
|||||||
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) = instance.module.defined_global_index(x) {
|
let from = if let Some(def_x) = instance.module.defined_global_index(x) {
|
||||||
unsafe { instance.vmctx.global_mut(def_x) }
|
instance.state.global_mut(def_x)
|
||||||
} else {
|
} else {
|
||||||
unsafe { instance.vmctx.imported_global(x).from }
|
instance.state.imported_global(x).from
|
||||||
};
|
};
|
||||||
unsafe { *to = *from };
|
unsafe { *to = *from };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user