Factor out functions for working with table and memory initializers.
This commit is contained in:
@@ -23,7 +23,7 @@ use vmcontext::{
|
||||
VMGlobalImport, VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition,
|
||||
VMTableImport,
|
||||
};
|
||||
use wasmtime_environ::{DataInitializer, Module, VMOffsets};
|
||||
use wasmtime_environ::{DataInitializer, Module, TableElements, VMOffsets};
|
||||
|
||||
fn signature_id(
|
||||
vmctx: &VMContext,
|
||||
@@ -51,6 +51,19 @@ fn imported_function<'vmctx>(
|
||||
}
|
||||
}
|
||||
|
||||
fn imported_table<'vmctx>(
|
||||
vmctx: &'vmctx VMContext,
|
||||
offsets: &VMOffsets,
|
||||
index: TableIndex,
|
||||
) -> &'vmctx VMTableImport {
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
unsafe {
|
||||
let ptr = (vmctx as *const VMContext as *const u8)
|
||||
.add(cast::usize(offsets.vmctx_vmtable_import(index)));
|
||||
&*(ptr as *const VMTableImport)
|
||||
}
|
||||
}
|
||||
|
||||
/// The actual contents of an instance.
|
||||
///
|
||||
/// `Instance` is just a handle containing a pointer to an `InstanceContents`,
|
||||
@@ -108,11 +121,7 @@ impl InstanceContents {
|
||||
|
||||
/// Return the index `VMTableImport`.
|
||||
fn imported_table(&self, index: TableIndex) -> &VMTableImport {
|
||||
unsafe {
|
||||
let ptr = (&self.vmctx as *const VMContext as *const u8)
|
||||
.add(cast::usize(self.offsets.vmctx_vmtable_import(index)));
|
||||
&*(ptr as *const VMTableImport)
|
||||
}
|
||||
imported_table(&self.vmctx, &self.offsets, index)
|
||||
}
|
||||
|
||||
/// Return a pointer to the `VMTableImports`s.
|
||||
@@ -475,7 +484,7 @@ impl Instance {
|
||||
|
||||
let mut contents_mmap = Mmap::with_size(
|
||||
mem::size_of::<InstanceContents>()
|
||||
.checked_add(cast::usize(offsets.size_of_vmctx()).unwrap())
|
||||
.checked_add(cast::usize(offsets.size_of_vmctx()))
|
||||
.unwrap(),
|
||||
)
|
||||
.map_err(InstantiationError::Resource)?;
|
||||
@@ -675,28 +684,14 @@ fn check_table_init_bounds(
|
||||
contents: &mut InstanceContents,
|
||||
) -> Result<(), InstantiationError> {
|
||||
for init in &module.table_elements {
|
||||
// TODO: Refactor this.
|
||||
let mut start = init.offset;
|
||||
if let Some(base) = init.base {
|
||||
let global = if let Some(def_index) = module.defined_global_index(base) {
|
||||
contents.global_mut(def_index)
|
||||
} else {
|
||||
contents.imported_global(base).from
|
||||
};
|
||||
start += cast::usize(unsafe { *(&*global).as_u32() });
|
||||
}
|
||||
|
||||
// TODO: Refactor this.
|
||||
let slice = if let Some(defined_table_index) = module.defined_table_index(init.table_index)
|
||||
{
|
||||
contents.tables[defined_table_index].as_mut()
|
||||
} else {
|
||||
let import = contents.imported_table(init.table_index);
|
||||
let foreign_contents = unsafe { (&mut *(import).vmctx).instance_contents() };
|
||||
let foreign_table = unsafe { &mut *(import).from };
|
||||
let foreign_index = foreign_contents.table_index(foreign_table);
|
||||
foreign_contents.tables[foreign_index].as_mut()
|
||||
};
|
||||
let start = get_table_init_start(init, module, contents);
|
||||
let slice = get_table_slice(
|
||||
init,
|
||||
module,
|
||||
&mut contents.tables,
|
||||
&contents.vmctx,
|
||||
&contents.offsets,
|
||||
);
|
||||
|
||||
if slice.get_mut(start..start + init.elements.len()).is_none() {
|
||||
return Err(InstantiationError::Link(LinkError(
|
||||
@@ -708,14 +703,14 @@ fn check_table_init_bounds(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_memory_init_bounds(
|
||||
/// Compute the offset for a memory data initializer.
|
||||
fn get_memory_init_start(
|
||||
init: &DataInitializer,
|
||||
module: &Module,
|
||||
contents: &mut InstanceContents,
|
||||
data_initializers: &[DataInitializer],
|
||||
) -> Result<(), InstantiationError> {
|
||||
for init in data_initializers {
|
||||
// TODO: Refactor this.
|
||||
) -> usize {
|
||||
let mut start = init.location.offset;
|
||||
|
||||
if let Some(base) = init.location.base {
|
||||
let global = if let Some(def_index) = module.defined_global_index(base) {
|
||||
contents.global_mut(def_index)
|
||||
@@ -725,7 +720,15 @@ fn check_memory_init_bounds(
|
||||
start += cast::usize(unsafe { *(&*global).as_u32() });
|
||||
}
|
||||
|
||||
// TODO: Refactor this.
|
||||
start
|
||||
}
|
||||
|
||||
/// Return a byte-slice view of a memory's data.
|
||||
fn get_memory_slice<'contents>(
|
||||
init: &DataInitializer,
|
||||
module: &Module,
|
||||
contents: &'contents mut InstanceContents,
|
||||
) -> &'contents mut [u8] {
|
||||
let memory = if let Some(defined_memory_index) =
|
||||
module.defined_memory_index(init.location.memory_index)
|
||||
{
|
||||
@@ -737,7 +740,17 @@ fn check_memory_init_bounds(
|
||||
let foreign_index = foreign_contents.memory_index(foreign_memory);
|
||||
foreign_contents.memory(foreign_index)
|
||||
};
|
||||
let mem_slice = 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(
|
||||
module: &Module,
|
||||
contents: &mut InstanceContents,
|
||||
data_initializers: &[DataInitializer],
|
||||
) -> Result<(), InstantiationError> {
|
||||
for init in data_initializers {
|
||||
let start = get_memory_init_start(init, module, contents);
|
||||
let mem_slice = get_memory_slice(init, module, contents);
|
||||
|
||||
if mem_slice.get_mut(start..start + init.data.len()).is_none() {
|
||||
return Err(InstantiationError::Link(LinkError(
|
||||
@@ -760,14 +773,14 @@ fn create_tables(module: &Module) -> BoxedSlice<DefinedTableIndex, Table> {
|
||||
tables.into_boxed_slice()
|
||||
}
|
||||
|
||||
/// Initialize the table memory from the provided initializers.
|
||||
fn initialize_tables(
|
||||
/// Compute the offset for a table element initializer.
|
||||
fn get_table_init_start(
|
||||
init: &TableElements,
|
||||
module: &Module,
|
||||
contents: &mut InstanceContents,
|
||||
) -> Result<(), InstantiationError> {
|
||||
let vmctx: *mut VMContext = contents.vmctx_mut();
|
||||
for init in &module.table_elements {
|
||||
) -> usize {
|
||||
let mut start = init.offset;
|
||||
|
||||
if let Some(base) = init.base {
|
||||
let global = if let Some(def_index) = module.defined_global_index(base) {
|
||||
contents.global_mut(def_index)
|
||||
@@ -777,16 +790,43 @@ fn initialize_tables(
|
||||
start += cast::usize(unsafe { *(&*global).as_u32() });
|
||||
}
|
||||
|
||||
let slice = if let Some(defined_table_index) = module.defined_table_index(init.table_index)
|
||||
{
|
||||
contents.tables[defined_table_index].as_mut()
|
||||
start
|
||||
}
|
||||
|
||||
/// Return a byte-slice view of a table's data.
|
||||
fn get_table_slice<'contents>(
|
||||
init: &TableElements,
|
||||
module: &Module,
|
||||
tables: &'contents mut BoxedSlice<DefinedTableIndex, Table>,
|
||||
vmctx: &VMContext,
|
||||
offsets: &VMOffsets,
|
||||
) -> &'contents mut [VMCallerCheckedAnyfunc] {
|
||||
if let Some(defined_table_index) = module.defined_table_index(init.table_index) {
|
||||
tables[defined_table_index].as_mut()
|
||||
} else {
|
||||
let import = contents.imported_table(init.table_index);
|
||||
let import = imported_table(vmctx, offsets, init.table_index);
|
||||
let foreign_contents = unsafe { (&mut *(import).vmctx).instance_contents() };
|
||||
let foreign_table = unsafe { &mut *(import).from };
|
||||
let foreign_index = foreign_contents.table_index(foreign_table);
|
||||
foreign_contents.tables[foreign_index].as_mut()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the table memory from the provided initializers.
|
||||
fn initialize_tables(
|
||||
module: &Module,
|
||||
contents: &mut InstanceContents,
|
||||
) -> Result<(), InstantiationError> {
|
||||
let vmctx: *mut VMContext = contents.vmctx_mut();
|
||||
for init in &module.table_elements {
|
||||
let start = get_table_init_start(init, module, contents);
|
||||
let slice = get_table_slice(
|
||||
init,
|
||||
module,
|
||||
&mut contents.tables,
|
||||
&contents.vmctx,
|
||||
&contents.offsets,
|
||||
);
|
||||
|
||||
let subslice = &mut slice[start..start + init.elements.len()];
|
||||
for (i, func_idx) in init.elements.iter().enumerate() {
|
||||
@@ -831,28 +871,9 @@ fn initialize_memories(
|
||||
data_initializers: &[DataInitializer],
|
||||
) -> Result<(), InstantiationError> {
|
||||
for init in data_initializers {
|
||||
let mut start = init.location.offset;
|
||||
if let Some(base) = init.location.base {
|
||||
let global = if let Some(def_index) = module.defined_global_index(base) {
|
||||
contents.global_mut(def_index)
|
||||
} else {
|
||||
contents.imported_global(base).from
|
||||
};
|
||||
start += cast::usize(unsafe { *(&*global).as_u32() });
|
||||
}
|
||||
let start = get_memory_init_start(init, module, contents);
|
||||
let mem_slice = get_memory_slice(init, module, contents);
|
||||
|
||||
let memory = if let Some(defined_memory_index) =
|
||||
module.defined_memory_index(init.location.memory_index)
|
||||
{
|
||||
contents.memory(defined_memory_index)
|
||||
} else {
|
||||
let import = contents.imported_memory(init.location.memory_index);
|
||||
let foreign_contents = unsafe { (&mut *(import).vmctx).instance_contents() };
|
||||
let foreign_memory = unsafe { &mut *(import).from };
|
||||
let foreign_index = foreign_contents.memory_index(foreign_memory);
|
||||
foreign_contents.memory(foreign_index)
|
||||
};
|
||||
let mem_slice = unsafe { slice::from_raw_parts_mut(memory.base, memory.current_length) };
|
||||
let to_init = &mut mem_slice[start..start + init.data.len()];
|
||||
to_init.copy_from_slice(init.data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user