Remove middle step

This commit is contained in:
Mark McCaskey
2020-12-08 17:22:41 -08:00
parent e85e088cd9
commit cc5648f118
3 changed files with 30 additions and 59 deletions

View File

@@ -95,7 +95,6 @@ pub trait Artifact: Send + Sync + Upcastable {
self.preinstantiate()?; self.preinstantiate()?;
let module = self.module(); let module = self.module();
let unprepared = InstanceHandle::allocate_instance(&*module);
let (imports, import_initializers) = { let (imports, import_initializers) = {
let mut imports = resolve_imports( let mut imports = resolve_imports(
&module, &module,
@@ -115,8 +114,9 @@ pub trait Artifact: Send + Sync + Upcastable {
// Get pointers to where metadata about local memories should live in VM memory. // Get pointers to where metadata about local memories should live in VM memory.
// Get pointers to where metadata about local tables should live in VM memory. // Get pointers to where metadata about local tables should live in VM memory.
let (half_prepared, memory_definition_locations, table_definition_locations) =
unprepared.prepare(); let (unprepared, memory_definition_locations, table_definition_locations) =
InstanceHandle::allocate_instance(&*module);
let finished_memories = tunables let finished_memories = tunables
.create_memories(&module, self.memory_styles(), &memory_definition_locations) .create_memories(&module, self.memory_styles(), &memory_definition_locations)
.map_err(InstantiationError::Link)? .map_err(InstantiationError::Link)?
@@ -133,7 +133,7 @@ pub trait Artifact: Send + Sync + Upcastable {
self.register_frame_info(); self.register_frame_info();
let handle = InstanceHandle::new( let handle = InstanceHandle::new(
half_prepared, unprepared,
module, module,
self.finished_functions().clone(), self.finished_functions().clone(),
self.finished_function_call_trampolines().clone(), self.finished_function_call_trampolines().clone(),

View File

@@ -714,7 +714,13 @@ impl UnpreparedInstanceAllocatorSetter {
/// Allocate `Instance` (it is an uninitialized pointer). /// Allocate `Instance` (it is an uninitialized pointer).
/// ///
/// `offsets` is used to compute the layout with `Self::instance_layout`. /// `offsets` is used to compute the layout with `Self::instance_layout`.
pub fn new(offsets: VMOffsets) -> Self { pub fn new(
offsets: VMOffsets,
) -> (
Self,
Vec<NonNull<VMMemoryDefinition>>,
Vec<NonNull<VMTableDefinition>>,
) {
let instance_layout = Self::instance_layout(&offsets); let instance_layout = Self::instance_layout(&offsets);
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
@@ -726,12 +732,17 @@ impl UnpreparedInstanceAllocatorSetter {
alloc::handle_alloc_error(instance_layout); alloc::handle_alloc_error(instance_layout);
}; };
Self { let unprepared = Self {
instance_ptr: instance_ptr.cast(), instance_ptr: instance_ptr.cast(),
instance_layout, instance_layout,
offsets: Some(offsets), offsets: Some(offsets),
consumed: false, consumed: false,
} };
let memories = unsafe { unprepared.memory_definition_locations() };
let tables = unsafe { unprepared.table_definition_locations() };
(unprepared, memories, tables)
} }
/// Calculate the appropriate layout for `Instance`. /// Calculate the appropriate layout for `Instance`.
@@ -749,31 +760,6 @@ impl UnpreparedInstanceAllocatorSetter {
instance_layout.pad_to_align() instance_layout.pad_to_align()
} }
/// Prepare the instance allocator setter by getting pointers into key
/// locations which can be used to initialize data.
pub fn prepare(
mut self,
) -> (
HalfPreparedInstanceAllocatorSetter,
Vec<NonNull<VMMemoryDefinition>>,
Vec<NonNull<VMTableDefinition>>,
) {
let memories = unsafe { self.memory_definition_locations() };
let tables = unsafe { self.table_definition_locations() };
self.consumed = true;
let instance_ptr = self.instance_ptr;
let instance_layout = self.instance_layout;
let offsets = self.offsets.take();
let prepared = HalfPreparedInstanceAllocatorSetter {
instance_ptr,
instance_layout,
offsets,
consumed: false,
};
(prepared, memories, tables)
}
/// Get the locations of where the local `VMMemoryDefinition`s should be stored. /// Get the locations of where the local `VMMemoryDefinition`s should be stored.
/// ///
/// This function lets us create `Memory` objects on the host with backing /// This function lets us create `Memory` objects on the host with backing
@@ -818,7 +804,7 @@ impl UnpreparedInstanceAllocatorSetter {
/// offsets in `offsets` point to valid locations in memory, /// offsets in `offsets` point to valid locations in memory,
/// i.e. `instance_ptr` must have been allocated by /// i.e. `instance_ptr` must have been allocated by
/// `InstanceHandle::allocate_instance`. /// `InstanceHandle::allocate_instance`.
pub unsafe fn table_definition_locations(&self) -> Vec<NonNull<VMTableDefinition>> { unsafe fn table_definition_locations(&self) -> Vec<NonNull<VMTableDefinition>> {
let offsets = self.offsets.as_ref().unwrap(); let offsets = self.offsets.as_ref().unwrap();
let num_tables = offsets.num_local_tables; let num_tables = offsets.num_local_tables;
@@ -839,28 +825,7 @@ impl UnpreparedInstanceAllocatorSetter {
} }
out out
} }
}
/// TODO: rename
pub struct HalfPreparedInstanceAllocatorSetter {
instance_ptr: NonNull<Instance>,
instance_layout: Layout,
offsets: Option<VMOffsets>,
consumed: bool,
}
impl Drop for HalfPreparedInstanceAllocatorSetter {
fn drop(&mut self) {
if !self.consumed {
let instance_ptr = self.instance_ptr.as_ptr();
unsafe {
std::alloc::dealloc(instance_ptr as *mut u8, self.instance_layout);
}
}
}
}
impl HalfPreparedInstanceAllocatorSetter {
/// Finish preparing by writing the `Instance` into memory. /// Finish preparing by writing the `Instance` into memory.
pub(crate) fn write_instance(mut self, instance: Instance) -> PreparedInstanceAllocatorSetter { pub(crate) fn write_instance(mut self, instance: Instance) -> PreparedInstanceAllocatorSetter {
unsafe { unsafe {
@@ -880,7 +845,7 @@ impl HalfPreparedInstanceAllocatorSetter {
/// This function will return the offsets on the first time it's /// This function will return the offsets on the first time it's
/// called and `None` on all subsequent calls. /// called and `None` on all subsequent calls.
fn take_offsets(&mut self) -> Option<VMOffsets> { pub(crate) fn take_offsets(&mut self) -> Option<VMOffsets> {
self.offsets.take() self.offsets.take()
} }
} }
@@ -1152,7 +1117,13 @@ impl InstanceHandle {
/// It should ideally return `NonNull<Instance>` rather than /// It should ideally return `NonNull<Instance>` rather than
/// `NonNull<u8>`, however `Instance` is private, and we want to /// `NonNull<u8>`, however `Instance` is private, and we want to
/// keep it private. /// keep it private.
pub fn allocate_instance(module: &ModuleInfo) -> UnpreparedInstanceAllocatorSetter { pub fn allocate_instance(
module: &ModuleInfo,
) -> (
UnpreparedInstanceAllocatorSetter,
Vec<NonNull<VMMemoryDefinition>>,
Vec<NonNull<VMTableDefinition>>,
) {
let offsets = VMOffsets::new(mem::size_of::<*const u8>() as u8, module); let offsets = VMOffsets::new(mem::size_of::<*const u8>() as u8, module);
UnpreparedInstanceAllocatorSetter::new(offsets) UnpreparedInstanceAllocatorSetter::new(offsets)
} }
@@ -1183,7 +1154,7 @@ impl InstanceHandle {
/// all the local memories. /// all the local memories.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub unsafe fn new( pub unsafe fn new(
mut half_prepared: HalfPreparedInstanceAllocatorSetter, mut half_prepared: UnpreparedInstanceAllocatorSetter,
module: Arc<ModuleInfo>, module: Arc<ModuleInfo>,
finished_functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>, finished_functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,
finished_function_call_trampolines: BoxedSlice<SignatureIndex, VMTrampoline>, finished_function_call_trampolines: BoxedSlice<SignatureIndex, VMTrampoline>,

View File

@@ -40,8 +40,8 @@ pub use crate::export::*;
pub use crate::global::*; pub use crate::global::*;
pub use crate::imports::Imports; pub use crate::imports::Imports;
pub use crate::instance::{ pub use crate::instance::{
HalfPreparedInstanceAllocatorSetter, ImportInitializerFuncPtr, InstanceHandle, ImportInitializerFuncPtr, InstanceHandle, PreparedInstanceAllocatorSetter,
PreparedInstanceAllocatorSetter, UnpreparedInstanceAllocatorSetter, UnpreparedInstanceAllocatorSetter,
}; };
pub use crate::memory::{LinearMemory, Memory, MemoryError, MemoryStyle}; pub use crate::memory::{LinearMemory, Memory, MemoryError, MemoryStyle};
pub use crate::mmap::Mmap; pub use crate::mmap::Mmap;