mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 06:08:29 +00:00
Rename InstanceAllocator -> InstanceRef, use alloc name for builder
This commit is contained in:
@@ -12,7 +12,7 @@ use wasmer_types::{
|
||||
SignatureIndex, TableIndex,
|
||||
};
|
||||
use wasmer_vm::{
|
||||
FunctionBodyPtr, InstanceBuilder, InstanceHandle, MemoryStyle, ModuleInfo, TableStyle,
|
||||
FunctionBodyPtr, InstanceAllocator, InstanceHandle, MemoryStyle, ModuleInfo, TableStyle,
|
||||
VMSharedSignatureIndex, VMTrampoline,
|
||||
};
|
||||
|
||||
@@ -115,8 +115,8 @@ 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 tables should live in VM memory.
|
||||
|
||||
let (unprepared, memory_definition_locations, table_definition_locations) =
|
||||
InstanceBuilder::new(&*module);
|
||||
let (allocator, memory_definition_locations, table_definition_locations) =
|
||||
InstanceAllocator::new(&*module);
|
||||
let finished_memories = tunables
|
||||
.create_memories(&module, self.memory_styles(), &memory_definition_locations)
|
||||
.map_err(InstantiationError::Link)?
|
||||
@@ -133,7 +133,7 @@ pub trait Artifact: Send + Sync + Upcastable {
|
||||
self.register_frame_info();
|
||||
|
||||
let handle = InstanceHandle::new(
|
||||
unprepared,
|
||||
allocator,
|
||||
module,
|
||||
self.finished_functions().clone(),
|
||||
self.finished_function_call_trampolines().clone(),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md
|
||||
|
||||
use crate::global::Global;
|
||||
use crate::instance::InstanceAllocator;
|
||||
use crate::instance::InstanceRef;
|
||||
use crate::memory::{Memory, MemoryStyle};
|
||||
use crate::table::{Table, TableStyle};
|
||||
use crate::vmcontext::{VMFunctionBody, VMFunctionEnvironment, VMFunctionKind, VMTrampoline};
|
||||
@@ -49,8 +49,8 @@ pub struct VMExportFunction {
|
||||
pub call_trampoline: Option<VMTrampoline>,
|
||||
|
||||
/// A “reference” to the instance through the
|
||||
/// `InstanceAllocator`. `None` if it is a host function.
|
||||
pub instance_allocator: Option<InstanceAllocator>,
|
||||
/// `InstanceRef`. `None` if it is a host function.
|
||||
pub instance_allocator: Option<InstanceRef>,
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
@@ -74,8 +74,8 @@ pub struct VMExportTable {
|
||||
pub from: Arc<dyn Table>,
|
||||
|
||||
/// A “reference” to the instance through the
|
||||
/// `InstanceAllocator`. `None` if it is a host function.
|
||||
pub instance_allocator: Option<InstanceAllocator>,
|
||||
/// `InstanceRef`. `None` if it is a host function.
|
||||
pub instance_allocator: Option<InstanceRef>,
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
@@ -120,8 +120,8 @@ pub struct VMExportMemory {
|
||||
pub from: Arc<dyn Memory>,
|
||||
|
||||
/// A “reference” to the instance through the
|
||||
/// `InstanceAllocator`. `None` if it is a host function.
|
||||
pub instance_allocator: Option<InstanceAllocator>,
|
||||
/// `InstanceRef`. `None` if it is a host function.
|
||||
pub instance_allocator: Option<InstanceRef>,
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
@@ -166,8 +166,8 @@ pub struct VMExportGlobal {
|
||||
pub from: Arc<Global>,
|
||||
|
||||
/// A “reference” to the instance through the
|
||||
/// `InstanceAllocator`. `None` if it is a host function.
|
||||
pub instance_allocator: Option<InstanceAllocator>,
|
||||
/// `InstanceRef`. `None` if it is a host function.
|
||||
pub instance_allocator: Option<InstanceRef>,
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{Instance, InstanceAllocator};
|
||||
use super::{Instance, InstanceRef};
|
||||
use crate::vmcontext::{VMMemoryDefinition, VMTableDefinition};
|
||||
use crate::{ModuleInfo, VMOffsets};
|
||||
use std::alloc::{self, Layout};
|
||||
@@ -14,11 +14,11 @@ use wasmer_types::{LocalMemoryIndex, LocalTableIndex};
|
||||
/// This type will free the allocated memory if it's dropped before
|
||||
/// being used.
|
||||
///
|
||||
/// The [`InstanceBuilder::instance_layout`] computes the correct
|
||||
/// The [`InstanceAllocator::instance_layout`] computes the correct
|
||||
/// layout to represent the wanted [`Instance`].
|
||||
///
|
||||
/// Then we use this layout to allocate an empty `Instance` properly.
|
||||
pub struct InstanceBuilder {
|
||||
pub struct InstanceAllocator {
|
||||
/// The buffer that will contain the [`Instance`] and dynamic fields.
|
||||
instance_ptr: NonNull<Instance>,
|
||||
/// The layout of the `instance_ptr` buffer.
|
||||
@@ -32,7 +32,7 @@ pub struct InstanceBuilder {
|
||||
consumed: bool,
|
||||
}
|
||||
|
||||
impl Drop for InstanceBuilder {
|
||||
impl Drop for InstanceAllocator {
|
||||
fn drop(&mut self) {
|
||||
if !self.consumed {
|
||||
// If `consumed` has not been set, then we still have ownership
|
||||
@@ -45,7 +45,7 @@ impl Drop for InstanceBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
impl InstanceBuilder {
|
||||
impl InstanceAllocator {
|
||||
/// Allocates instance data for use with [`InstanceHandle::new`].
|
||||
///
|
||||
/// Returns a wrapper type around the allocation and 2 vectors of
|
||||
@@ -56,7 +56,7 @@ impl InstanceBuilder {
|
||||
pub fn new(
|
||||
module: &ModuleInfo,
|
||||
) -> (
|
||||
InstanceBuilder,
|
||||
InstanceAllocator,
|
||||
Vec<NonNull<VMMemoryDefinition>>,
|
||||
Vec<NonNull<VMTableDefinition>>,
|
||||
) {
|
||||
@@ -72,7 +72,7 @@ impl InstanceBuilder {
|
||||
alloc::handle_alloc_error(instance_layout);
|
||||
};
|
||||
|
||||
let unprepared = Self {
|
||||
let allocator = Self {
|
||||
instance_ptr,
|
||||
instance_layout,
|
||||
offsets,
|
||||
@@ -83,10 +83,10 @@ impl InstanceBuilder {
|
||||
// Both of these calls are safe because we allocate the pointer
|
||||
// above with the same `offsets` that these functions use.
|
||||
// Thus there will be enough valid memory for both of them.
|
||||
let memories = unsafe { unprepared.memory_definition_locations() };
|
||||
let tables = unsafe { unprepared.table_definition_locations() };
|
||||
let memories = unsafe { allocator.memory_definition_locations() };
|
||||
let tables = unsafe { allocator.table_definition_locations() };
|
||||
|
||||
(unprepared, memories, tables)
|
||||
(allocator, memories, tables)
|
||||
}
|
||||
|
||||
/// Calculate the appropriate layout for the [`Instance`].
|
||||
@@ -170,7 +170,7 @@ impl InstanceBuilder {
|
||||
}
|
||||
|
||||
/// Finish preparing by writing the [`Instance`] into memory.
|
||||
pub(crate) fn write_instance(mut self, instance: Instance) -> InstanceAllocator {
|
||||
pub(crate) fn write_instance(mut self, instance: Instance) -> InstanceRef {
|
||||
// prevent the old state's drop logic from being called as we
|
||||
// transition into the new state.
|
||||
self.consumed = true;
|
||||
@@ -178,7 +178,7 @@ impl InstanceBuilder {
|
||||
unsafe {
|
||||
// `instance` is moved at `instance_ptr`. This pointer has
|
||||
// been allocated by `Self::allocate_instance` (so by
|
||||
// `InstanceAllocator::allocate_instance`.
|
||||
// `InstanceRef::allocate_instance`.
|
||||
ptr::write(self.instance_ptr.as_ptr(), instance);
|
||||
// Now `instance_ptr` is correctly initialized!
|
||||
}
|
||||
@@ -187,7 +187,7 @@ impl InstanceBuilder {
|
||||
|
||||
// This is correct because of the invariants of `Self` and
|
||||
// because we write `Instance` to the pointer in this function.
|
||||
unsafe { InstanceAllocator::new(instance, instance_layout) }
|
||||
unsafe { InstanceRef::new(instance, instance_layout) }
|
||||
}
|
||||
|
||||
/// Get the [`VMOffsets`] for the allocated buffer.
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
//! An `Instance` contains all the runtime state used by execution of
|
||||
//! a WebAssembly module (except its callstack and register state). An
|
||||
//! `InstanceAllocator` is a wrapper around `Instance` that manages
|
||||
//! `InstanceRef` is a wrapper around `Instance` that manages
|
||||
//! how it is allocated and deallocated. An `InstanceHandle` is a
|
||||
//! wrapper around an `InstanceAllocator`.
|
||||
//! wrapper around an `InstanceRef`.
|
||||
|
||||
mod builder;
|
||||
mod allocator;
|
||||
|
||||
pub use builder::InstanceBuilder;
|
||||
pub use allocator::InstanceAllocator;
|
||||
|
||||
use crate::export::VMExport;
|
||||
use crate::global::Global;
|
||||
@@ -693,15 +693,15 @@ impl Instance {
|
||||
}
|
||||
|
||||
/// TODO: update these docs
|
||||
/// An `InstanceAllocator` is responsible to allocate, to deallocate,
|
||||
/// An `InstanceRef` is responsible to allocate, to deallocate,
|
||||
/// and to give access to an `Instance`, in such a way that `Instance`
|
||||
/// is unique, can be shared, safely, across threads, without
|
||||
/// duplicating the pointer in multiple locations. `InstanceAllocator`
|
||||
/// duplicating the pointer in multiple locations. `InstanceRef`
|
||||
/// must be the only “owner” of an `Instance`.
|
||||
///
|
||||
/// Consequently, one must not share `Instance` but
|
||||
/// `InstanceAllocator`. It acts like an Atomically Reference Counted
|
||||
/// to `Instance`. In short, `InstanceAllocator` is roughly a
|
||||
/// `InstanceRef`. It acts like an Atomically Reference Counted
|
||||
/// to `Instance`. In short, `InstanceRef` is roughly a
|
||||
/// simplified version of `std::sync::Arc`.
|
||||
///
|
||||
/// It is important to remind that `Instance` is dynamically-sized
|
||||
@@ -712,12 +712,12 @@ impl Instance {
|
||||
/// 1. Define the correct layout for `Instance` (size and alignment),
|
||||
/// 2. Allocate it properly.
|
||||
///
|
||||
/// This allocation must be freed with [`InstanceAllocator::deallocate_instance`]
|
||||
/// This allocation must be freed with [`InstanceRef::deallocate_instance`]
|
||||
/// if and only if it has been set correctly. The `Drop` implementation of
|
||||
/// [`InstanceAllocator`] calls its `deallocate_instance` method without
|
||||
/// [`InstanceRef`] calls its `deallocate_instance` method without
|
||||
/// checking if this property holds, only when `Self.strong` is equal to 1.
|
||||
///
|
||||
/// Note for the curious reader: [`InstanceBuilder::new`]
|
||||
/// Note for the curious reader: [`InstanceAllocator::new`]
|
||||
/// and [`InstanceHandle::new`] will respectively allocate a proper
|
||||
/// `Instance` and will fill it correctly.
|
||||
///
|
||||
@@ -730,7 +730,7 @@ impl Instance {
|
||||
/// dynamically-sized, and the `instance` field must be last.
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
pub struct InstanceAllocator {
|
||||
pub struct InstanceRef {
|
||||
/// Number of `Self` in the nature. It increases when `Self` is
|
||||
/// cloned, and it decreases when `Self` is dropped.
|
||||
strong: Arc<atomic::AtomicUsize>,
|
||||
@@ -739,7 +739,7 @@ pub struct InstanceAllocator {
|
||||
instance_layout: Layout,
|
||||
|
||||
/// The `Instance` itself. It must be the last field of
|
||||
/// `InstanceAllocator` since `Instance` is dyamically-sized.
|
||||
/// `InstanceRef` since `Instance` is dyamically-sized.
|
||||
///
|
||||
/// `Instance` must not be dropped manually by Rust, because it's
|
||||
/// allocated manually with `alloc` and a specific layout (Rust
|
||||
@@ -751,8 +751,8 @@ pub struct InstanceAllocator {
|
||||
instance: NonNull<Instance>,
|
||||
}
|
||||
|
||||
impl InstanceAllocator {
|
||||
/// Create a new `InstanceAllocator`. It allocates nothing. It
|
||||
impl InstanceRef {
|
||||
/// Create a new `InstanceRef`. It allocates nothing. It
|
||||
/// fills nothing. The `Instance` must be already valid and
|
||||
/// filled. `self_ptr` and `self_layout` must be the pointer and
|
||||
/// the layout returned by `Self::allocate_self` used to build
|
||||
@@ -762,7 +762,7 @@ impl InstanceAllocator {
|
||||
///
|
||||
/// `instance` must a non-null, non-dangling, properly aligned,
|
||||
/// and correctly initialized pointer to `Instance`. See
|
||||
/// [`InstanceBuilder::new`] for an example of how to correctly use
|
||||
/// [`InstanceAllocator::new`] for an example of how to correctly use
|
||||
/// this API.
|
||||
/// TODO: update docs
|
||||
pub(crate) unsafe fn new(instance: NonNull<Instance>, instance_layout: Layout) -> Self {
|
||||
@@ -773,7 +773,7 @@ impl InstanceAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
/// A soft limit on the amount of references that may be made to an `InstanceAllocator`.
|
||||
/// A soft limit on the amount of references that may be made to an `InstanceRef`.
|
||||
///
|
||||
/// Going above this limit will make the program to panic at exactly
|
||||
/// `MAX_REFCOUNT` references.
|
||||
@@ -793,7 +793,7 @@ impl InstanceAllocator {
|
||||
}
|
||||
|
||||
/// Get the number of strong references pointing to this
|
||||
/// `InstanceAllocator`.
|
||||
/// `InstanceRef`.
|
||||
pub fn strong_count(&self) -> usize {
|
||||
self.strong.load(atomic::Ordering::SeqCst)
|
||||
}
|
||||
@@ -814,13 +814,13 @@ impl InstanceAllocator {
|
||||
}
|
||||
|
||||
/// TODO: Review this super carefully.
|
||||
unsafe impl Send for InstanceAllocator {}
|
||||
unsafe impl Sync for InstanceAllocator {}
|
||||
unsafe impl Send for InstanceRef {}
|
||||
unsafe impl Sync for InstanceRef {}
|
||||
|
||||
impl Clone for InstanceAllocator {
|
||||
/// Makes a clone of `InstanceAllocator`.
|
||||
impl Clone for InstanceRef {
|
||||
/// Makes a clone of `InstanceRef`.
|
||||
///
|
||||
/// This creates another `InstanceAllocator` using the same
|
||||
/// This creates another `InstanceRef` using the same
|
||||
/// `instance` pointer, increasing the strong reference count.
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
@@ -840,7 +840,7 @@ impl Clone for InstanceAllocator {
|
||||
let old_size = self.strong.fetch_add(1, atomic::Ordering::Relaxed);
|
||||
|
||||
// However we need to guard against massive refcounts in case
|
||||
// someone is `mem::forget`ing `InstanceAllocator`. If we
|
||||
// someone is `mem::forget`ing `InstanceRef`. If we
|
||||
// don't do this the count can overflow and users will
|
||||
// use-after free. We racily saturate to `isize::MAX` on the
|
||||
// assumption that there aren't ~2 billion threads
|
||||
@@ -851,7 +851,7 @@ impl Clone for InstanceAllocator {
|
||||
// and we don't care to support it.
|
||||
|
||||
if old_size > Self::MAX_REFCOUNT {
|
||||
panic!("Too many references of `InstanceAllocator`");
|
||||
panic!("Too many references of `InstanceRef`");
|
||||
}
|
||||
|
||||
Self {
|
||||
@@ -862,16 +862,16 @@ impl Clone for InstanceAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for InstanceAllocator {
|
||||
/// Two `InstanceAllocator` are equal if and only if
|
||||
impl PartialEq for InstanceRef {
|
||||
/// Two `InstanceRef` are equal if and only if
|
||||
/// `Self.instance` points to the same location.
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.instance == other.instance
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for InstanceAllocator {
|
||||
/// Drop the `InstanceAllocator`.
|
||||
impl Drop for InstanceRef {
|
||||
/// Drop the `InstanceRef`.
|
||||
///
|
||||
/// This will decrement the strong reference count. If it reaches
|
||||
/// 1, then the `Self.instance` will be deallocated with
|
||||
@@ -905,24 +905,24 @@ impl Drop for InstanceAllocator {
|
||||
// Now we can deallocate the instance. Note that we don't
|
||||
// check the pointer to `Instance` is correctly initialized,
|
||||
// but the way `InstanceHandle` creates the
|
||||
// `InstanceAllocator` ensures that.
|
||||
// `InstanceRef` ensures that.
|
||||
unsafe { Self::deallocate_instance(self) };
|
||||
}
|
||||
}
|
||||
|
||||
/// A handle holding an `InstanceAllocator`, which holds an `Instance`
|
||||
/// A handle holding an `InstanceRef`, which holds an `Instance`
|
||||
/// of a WebAssembly module.
|
||||
///
|
||||
/// This is more or less a public facade of the private `Instance`,
|
||||
/// providing useful higher-level API.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct InstanceHandle {
|
||||
/// The `InstanceAllocator`. See its documentation to learn more.
|
||||
instance: InstanceAllocator,
|
||||
/// The `InstanceRef`. See its documentation to learn more.
|
||||
instance: InstanceRef,
|
||||
}
|
||||
|
||||
impl InstanceHandle {
|
||||
/// Create a new `InstanceHandle` pointing at a new `InstanceAllocator`.
|
||||
/// Create a new `InstanceHandle` pointing at a new `InstanceRef`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
@@ -945,7 +945,7 @@ impl InstanceHandle {
|
||||
/// all the local memories.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub unsafe fn new(
|
||||
unprepared: InstanceBuilder,
|
||||
allocator: InstanceAllocator,
|
||||
module: Arc<ModuleInfo>,
|
||||
finished_functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,
|
||||
finished_function_call_trampolines: BoxedSlice<SignatureIndex, VMTrampoline>,
|
||||
@@ -965,7 +965,7 @@ impl InstanceHandle {
|
||||
let passive_data = RefCell::new(module.passive_data.clone());
|
||||
|
||||
let handle = {
|
||||
let offsets = unprepared.offsets().clone();
|
||||
let offsets = allocator.offsets().clone();
|
||||
// Create the `Instance`. The unique, the One.
|
||||
let instance = Instance {
|
||||
module,
|
||||
@@ -983,7 +983,7 @@ impl InstanceHandle {
|
||||
vmctx: VMContext {},
|
||||
};
|
||||
|
||||
let instance_allocator = unprepared.write_instance(instance);
|
||||
let instance_allocator = allocator.write_instance(instance);
|
||||
|
||||
Self {
|
||||
instance: instance_allocator,
|
||||
@@ -1041,7 +1041,7 @@ impl InstanceHandle {
|
||||
}
|
||||
|
||||
/// Return a reference to the contained `Instance`.
|
||||
pub(crate) fn instance(&self) -> &InstanceAllocator {
|
||||
pub(crate) fn instance(&self) -> &InstanceRef {
|
||||
&self.instance
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ pub mod libcalls;
|
||||
pub use crate::export::*;
|
||||
pub use crate::global::*;
|
||||
pub use crate::imports::Imports;
|
||||
pub use crate::instance::{ImportInitializerFuncPtr, InstanceBuilder, InstanceHandle};
|
||||
pub use crate::instance::{ImportInitializerFuncPtr, InstanceAllocator, InstanceHandle};
|
||||
pub use crate::memory::{LinearMemory, Memory, MemoryError, MemoryStyle};
|
||||
pub use crate::mmap::Mmap;
|
||||
pub use crate::module::{ExportsIterator, ImportsIterator, ModuleInfo};
|
||||
|
||||
Reference in New Issue
Block a user