wasmtime/runtime/vm/
instance.rs

1//! An `Instance` contains all the runtime state used by execution of a
2//! wasm module (except its callstack and register state). An
3//! `InstanceHandle` is a reference-counting handle for an `Instance`.
4
5use crate::OpaqueRootScope;
6use crate::prelude::*;
7use crate::runtime::vm::const_expr::{ConstEvalContext, ConstExprEvaluator};
8use crate::runtime::vm::export::Export;
9use crate::runtime::vm::memory::{Memory, RuntimeMemoryCreator};
10use crate::runtime::vm::table::{Table, TableElementType};
11use crate::runtime::vm::vmcontext::{
12    VMBuiltinFunctionsArray, VMContext, VMFuncRef, VMFunctionImport, VMGlobalDefinition,
13    VMGlobalImport, VMMemoryDefinition, VMMemoryImport, VMOpaqueContext, VMStoreContext,
14    VMTableDefinition, VMTableImport, VMTagDefinition, VMTagImport,
15};
16use crate::runtime::vm::{
17    GcStore, HostResult, Imports, ModuleRuntimeInfo, SendSyncPtr, VMGlobalKind, VMStore,
18    VMStoreRawPtr, VmPtr, VmSafe, WasmFault, catch_unwind_and_record_trap,
19};
20use crate::store::{InstanceId, StoreId, StoreInstanceId, StoreOpaque, StoreResourceLimiter};
21use alloc::sync::Arc;
22use core::alloc::Layout;
23use core::marker;
24use core::ops::Range;
25use core::pin::Pin;
26use core::ptr::NonNull;
27#[cfg(target_has_atomic = "64")]
28use core::sync::atomic::AtomicU64;
29use core::{mem, ptr};
30#[cfg(feature = "gc")]
31use wasmtime_environ::ModuleInternedTypeIndex;
32use wasmtime_environ::{
33    DataIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, DefinedTagIndex,
34    ElemIndex, EntityIndex, EntityRef, EntitySet, FuncIndex, GlobalIndex, HostPtr, MemoryIndex,
35    Module, PrimaryMap, PtrSize, TableIndex, TableInitialValue, TableSegmentElements, TagIndex,
36    Trap, VMCONTEXT_MAGIC, VMOffsets, VMSharedTypeIndex, packed_option::ReservedValue,
37};
38#[cfg(feature = "wmemcheck")]
39use wasmtime_wmemcheck::Wmemcheck;
40
41mod allocator;
42pub use allocator::*;
43
44/// A type that roughly corresponds to a WebAssembly instance, but is also used
45/// for host-defined objects.
46///
47/// Instances here can correspond to actual instantiated modules, but it's also
48/// used ubiquitously for host-defined objects. For example creating a
49/// host-defined memory will have a `module` that looks like it exports a single
50/// memory (and similar for other constructs).
51///
52/// This `Instance` type is used as a ubiquitous representation for WebAssembly
53/// values, whether or not they were created on the host or through a module.
54///
55/// # Ownership
56///
57/// This structure is never allocated directly but is instead managed through
58/// an `InstanceHandle`. This structure ends with a `VMContext` which has a
59/// dynamic size corresponding to the `module` configured within. Memory
60/// management of this structure is always done through `InstanceHandle` as the
61/// sole owner of an instance.
62///
63/// # `Instance` and `Pin`
64///
65/// Given an instance it is accompanied with trailing memory for the
66/// appropriate `VMContext`. The `Instance` also holds `runtime_info` and other
67/// information pointing to relevant offsets for the `VMContext`. Thus it is
68/// not sound to mutate `runtime_info` after an instance is created. More
69/// generally it's also not safe to "swap" instances, for example given two
70/// `&mut Instance` values it's not sound to swap them as then the `VMContext`
71/// values are inaccurately described.
72///
73/// To encapsulate this guarantee this type is only ever mutated through Rust's
74/// `Pin` type. All mutable methods here take `self: Pin<&mut Self>` which
75/// statically disallows safe access to `&mut Instance`. There are assorted
76/// "projection methods" to go from `Pin<&mut Instance>` to `&mut T` for
77/// individual fields, for example `memories_mut`. More methods can be added as
78/// necessary or methods may also be added to project multiple fields at a time
79/// if necessary to. The precise ergonomics around getting mutable access to
80/// some fields (but notably not `runtime_info`) is probably going to evolve
81/// over time.
82///
83/// Note that is is not sound to basically ever pass around `&mut Instance`.
84/// That should always instead be `Pin<&mut Instance>`. All usage of
85/// `Pin::new_unchecked` should be here in this module in just a few `unsafe`
86/// locations and it's recommended to use existing helpers if you can.
87#[repr(C)] // ensure that the vmctx field is last.
88pub struct Instance {
89    /// The index, within a `Store` that this instance lives at
90    id: InstanceId,
91
92    /// The runtime info (corresponding to the "compiled module"
93    /// abstraction in higher layers) that is retained and needed for
94    /// lazy initialization. This provides access to the underlying
95    /// Wasm module entities, the compiled JIT code, metadata about
96    /// functions, lazy initialization state, etc.
97    runtime_info: ModuleRuntimeInfo,
98
99    /// WebAssembly linear memory data.
100    ///
101    /// This is where all runtime information about defined linear memories in
102    /// this module lives.
103    ///
104    /// The `MemoryAllocationIndex` was given from our `InstanceAllocator` and
105    /// must be given back to the instance allocator when deallocating each
106    /// memory.
107    memories: PrimaryMap<DefinedMemoryIndex, (MemoryAllocationIndex, Memory)>,
108
109    /// WebAssembly table data.
110    ///
111    /// Like memories, this is only for defined tables in the module and
112    /// contains all of their runtime state.
113    ///
114    /// The `TableAllocationIndex` was given from our `InstanceAllocator` and
115    /// must be given back to the instance allocator when deallocating each
116    /// table.
117    tables: PrimaryMap<DefinedTableIndex, (TableAllocationIndex, Table)>,
118
119    /// Stores the dropped passive element segments in this instantiation by index.
120    /// If the index is present in the set, the segment has been dropped.
121    dropped_elements: EntitySet<ElemIndex>,
122
123    /// Stores the dropped passive data segments in this instantiation by index.
124    /// If the index is present in the set, the segment has been dropped.
125    dropped_data: EntitySet<DataIndex>,
126
127    // TODO: add support for multiple memories; `wmemcheck_state` corresponds to
128    // memory 0.
129    #[cfg(feature = "wmemcheck")]
130    pub(crate) wmemcheck_state: Option<Wmemcheck>,
131
132    /// Self-pointer back to `Store<T>` and its functions. Not present for
133    /// the brief time that `Store<T>` is itself being created. Also not
134    /// present for some niche uses that are disconnected from stores (e.g.
135    /// cross-thread stuff used in `InstancePre`)
136    store: Option<VMStoreRawPtr>,
137
138    /// Additional context used by compiled wasm code. This field is last, and
139    /// represents a dynamically-sized array that extends beyond the nominal
140    /// end of the struct (similar to a flexible array member).
141    vmctx: OwnedVMContext<VMContext>,
142}
143
144impl Instance {
145    /// Create an instance at the given memory address.
146    ///
147    /// It is assumed the memory was properly aligned and the
148    /// allocation was `alloc_size` in bytes.
149    ///
150    /// # Safety
151    ///
152    /// The `req.imports` field must be appropriately sized/typed for the module
153    /// being allocated according to `req.runtime_info`. Additionally `memories`
154    /// and `tables` must have been allocated for `req.store`.
155    unsafe fn new(
156        req: InstanceAllocationRequest,
157        memories: PrimaryMap<DefinedMemoryIndex, (MemoryAllocationIndex, Memory)>,
158        tables: PrimaryMap<DefinedTableIndex, (TableAllocationIndex, Table)>,
159        memory_tys: &PrimaryMap<MemoryIndex, wasmtime_environ::Memory>,
160    ) -> InstanceHandle {
161        let module = req.runtime_info.env_module();
162        let dropped_elements = EntitySet::with_capacity(module.passive_elements.len());
163        let dropped_data = EntitySet::with_capacity(module.passive_data_map.len());
164
165        #[cfg(not(feature = "wmemcheck"))]
166        let _ = memory_tys;
167
168        let mut ret = OwnedInstance::new(Instance {
169            id: req.id,
170            runtime_info: req.runtime_info.clone(),
171            memories,
172            tables,
173            dropped_elements,
174            dropped_data,
175            #[cfg(feature = "wmemcheck")]
176            wmemcheck_state: {
177                if req.store.engine().config().wmemcheck {
178                    let size = memory_tys
179                        .iter()
180                        .next()
181                        .map(|memory| memory.1.limits.min)
182                        .unwrap_or(0)
183                        * 64
184                        * 1024;
185                    Some(Wmemcheck::new(size.try_into().unwrap()))
186                } else {
187                    None
188                }
189            },
190            store: None,
191            vmctx: OwnedVMContext::new(),
192        });
193
194        // SAFETY: this vmctx was allocated with the same layout above, so it
195        // should be safe to initialize with the same values here.
196        unsafe {
197            ret.get_mut().initialize_vmctx(
198                module,
199                req.runtime_info.offsets(),
200                req.store,
201                req.imports,
202            );
203        }
204        ret
205    }
206
207    /// Converts a raw `VMContext` pointer into a raw `Instance` pointer.
208    ///
209    /// # Safety
210    ///
211    /// Calling this function safely requires that `vmctx` is a valid allocation
212    /// of a `VMContext` which is derived from `Instance::new`. To safely
213    /// convert the returned raw pointer into a safe instance pointer callers
214    /// will also want to uphold guarantees such as:
215    ///
216    /// * The instance should not be in use elsewhere. For example you can't
217    ///   call this function twice, turn both raw pointers into safe pointers,
218    ///   and then use both safe pointers.
219    /// * There should be no other active mutable borrow to any other instance
220    ///   within the same store. Note that this is not restricted to just this
221    ///   instance pointer, but to all instances in a store. Instances can
222    ///   safely traverse to other instances "laterally" meaning that a mutable
223    ///   borrow on one is a mutable borrow on all.
224    /// * There should be no active mutable borrow on the store accessible at
225    ///   the same time the instance is turned. Instances are owned by a store
226    ///   and a store can be used to acquire a safe instance borrow at any time.
227    /// * The lifetime of the usage of the instance should not be unnecessarily
228    ///   long, for example it cannot be `'static`.
229    ///
230    /// Other entrypoints exist for converting from a raw `VMContext` to a safe
231    /// pointer such as:
232    ///
233    /// * `Instance::enter_host_from_wasm`
234    /// * `Instance::sibling_vmctx{,_mut}`
235    ///
236    /// These place further restrictions on the API signature to satisfy some of
237    /// the above points.
238    #[inline]
239    pub(crate) unsafe fn from_vmctx(vmctx: NonNull<VMContext>) -> NonNull<Instance> {
240        // SAFETY: The validity of `byte_sub` relies on `vmctx` being a valid
241        // allocation.
242        unsafe {
243            vmctx
244                .byte_sub(mem::size_of::<Instance>())
245                .cast::<Instance>()
246        }
247    }
248
249    /// Encapsulated entrypoint to the host from WebAssembly, converting a raw
250    /// `VMContext` pointer into a `VMStore` plus an `InstanceId`.
251    ///
252    /// This is an entrypoint for core wasm entering back into the host. This is
253    /// used for both host functions and libcalls for example. This will execute
254    /// the closure `f` with safer Internal types than a raw `VMContext`
255    /// pointer.
256    ///
257    /// The closure `f` will have its errors caught, handled, and translated to
258    /// an ABI-safe return value to give back to wasm. This includes both normal
259    /// errors such as traps as well as panics.
260    ///
261    /// # Safety
262    ///
263    /// Callers must ensure that `vmctx` is a valid allocation and is safe to
264    /// dereference at this time. That's generally only true when it's a
265    /// wasm-provided value and this is the first function called after entering
266    /// the host. Otherwise this could unsafely alias the store with a mutable
267    /// pointer, for example.
268    #[inline]
269    pub(crate) unsafe fn enter_host_from_wasm<R>(
270        vmctx: NonNull<VMContext>,
271        f: impl FnOnce(&mut dyn VMStore, InstanceId) -> R,
272    ) -> R::Abi
273    where
274        R: HostResult,
275    {
276        // SAFETY: It's a contract of this function that `vmctx` is a valid
277        // pointer with neither the store nor other instances actively in use
278        // when this is called, so it should be safe to acquire a mutable
279        // pointer to the store and read the instance pointer.
280        let (store, instance) = unsafe {
281            let instance = Instance::from_vmctx(vmctx);
282            let instance = instance.as_ref();
283            let store = &mut *instance.store.unwrap().0.as_ptr();
284            (store, instance.id)
285        };
286
287        // Thread the `store` and `instance` through panic/trap infrastructure
288        // back into `f`.
289        catch_unwind_and_record_trap(store, |store| f(store, instance))
290    }
291
292    /// Converts the provided `*mut VMContext` to an `Instance` pointer and
293    /// returns it with the same lifetime as `self`.
294    ///
295    /// This function can be used when traversing a `VMContext` to reach into
296    /// the context needed for imports, optionally.
297    ///
298    /// # Safety
299    ///
300    /// This function requires that the `vmctx` pointer is indeed valid and
301    /// from the store that `self` belongs to.
302    #[inline]
303    unsafe fn sibling_vmctx<'a>(&'a self, vmctx: NonNull<VMContext>) -> &'a Instance {
304        // SAFETY: it's a contract of this function itself that `vmctx` is a
305        // valid pointer. Additionally with `self` being a
306        let ptr = unsafe { Instance::from_vmctx(vmctx) };
307        // SAFETY: it's a contract of this function itself that `vmctx` is a
308        // valid pointer to dereference. Additionally the lifetime of the return
309        // value is constrained to be the same as `self` to avoid granting a
310        // too-long lifetime.
311        unsafe { ptr.as_ref() }
312    }
313
314    /// Same as [`Self::sibling_vmctx`], but the mutable version.
315    ///
316    /// # Safety
317    ///
318    /// This function requires that the `vmctx` pointer is indeed valid and
319    /// from the store that `self` belongs to.
320    ///
321    /// (Note that it is *NOT* required that `vmctx` be distinct from this
322    /// instance's `vmctx`, or that usage of the resulting instance is limited
323    /// to its defined items! The returned borrow has the same lifetime as
324    /// `self`, which means that this instance cannot be used while the
325    /// resulting instance is in use, and we therefore do not need to worry
326    /// about mutable aliasing between this instance and the resulting
327    /// instance.)
328    #[inline]
329    unsafe fn sibling_vmctx_mut<'a>(
330        self: Pin<&'a mut Self>,
331        vmctx: NonNull<VMContext>,
332    ) -> Pin<&'a mut Instance> {
333        // SAFETY: it's a contract of this function itself that `vmctx` is a
334        // valid pointer such that this pointer arithmetic is valid.
335        let mut ptr = unsafe { Instance::from_vmctx(vmctx) };
336
337        // SAFETY: it's a contract of this function itself that `vmctx` is a
338        // valid pointer to dereference. Additionally the lifetime of the return
339        // value is constrained to be the same as `self` to avoid granting a
340        // too-long lifetime. Finally mutable references to an instance are
341        // always through `Pin`, so it's safe to create a pin-pointer here.
342        unsafe { Pin::new_unchecked(ptr.as_mut()) }
343    }
344
345    pub(crate) fn env_module(&self) -> &Arc<wasmtime_environ::Module> {
346        self.runtime_info.env_module()
347    }
348
349    #[cfg(feature = "gc")]
350    pub(crate) fn runtime_module(&self) -> Option<&crate::Module> {
351        match &self.runtime_info {
352            ModuleRuntimeInfo::Module(m) => Some(m),
353            ModuleRuntimeInfo::Bare(_) => None,
354        }
355    }
356
357    /// Translate a module-level interned type index into an engine-level
358    /// interned type index.
359    #[cfg(feature = "gc")]
360    pub fn engine_type_index(&self, module_index: ModuleInternedTypeIndex) -> VMSharedTypeIndex {
361        self.runtime_info.engine_type_index(module_index)
362    }
363
364    #[inline]
365    fn offsets(&self) -> &VMOffsets<HostPtr> {
366        self.runtime_info.offsets()
367    }
368
369    /// Return the indexed `VMFunctionImport`.
370    fn imported_function(&self, index: FuncIndex) -> &VMFunctionImport {
371        unsafe { self.vmctx_plus_offset(self.offsets().vmctx_vmfunction_import(index)) }
372    }
373
374    /// Return the index `VMTableImport`.
375    fn imported_table(&self, index: TableIndex) -> &VMTableImport {
376        unsafe { self.vmctx_plus_offset(self.offsets().vmctx_vmtable_import(index)) }
377    }
378
379    /// Return the indexed `VMMemoryImport`.
380    fn imported_memory(&self, index: MemoryIndex) -> &VMMemoryImport {
381        unsafe { self.vmctx_plus_offset(self.offsets().vmctx_vmmemory_import(index)) }
382    }
383
384    /// Return the indexed `VMGlobalImport`.
385    fn imported_global(&self, index: GlobalIndex) -> &VMGlobalImport {
386        unsafe { self.vmctx_plus_offset(self.offsets().vmctx_vmglobal_import(index)) }
387    }
388
389    /// Return the indexed `VMTagImport`.
390    fn imported_tag(&self, index: TagIndex) -> &VMTagImport {
391        unsafe { self.vmctx_plus_offset(self.offsets().vmctx_vmtag_import(index)) }
392    }
393
394    /// Return the indexed `VMTagDefinition`.
395    pub fn tag_ptr(&self, index: DefinedTagIndex) -> NonNull<VMTagDefinition> {
396        unsafe { self.vmctx_plus_offset_raw(self.offsets().vmctx_vmtag_definition(index)) }
397    }
398
399    /// Return the indexed `VMTableDefinition`.
400    pub fn table(&self, index: DefinedTableIndex) -> VMTableDefinition {
401        unsafe { self.table_ptr(index).read() }
402    }
403
404    /// Updates the value for a defined table to `VMTableDefinition`.
405    fn set_table(self: Pin<&mut Self>, index: DefinedTableIndex, table: VMTableDefinition) {
406        unsafe {
407            self.table_ptr(index).write(table);
408        }
409    }
410
411    /// Return a pointer to the `index`'th table within this instance, stored
412    /// in vmctx memory.
413    pub fn table_ptr(&self, index: DefinedTableIndex) -> NonNull<VMTableDefinition> {
414        unsafe { self.vmctx_plus_offset_raw(self.offsets().vmctx_vmtable_definition(index)) }
415    }
416
417    /// Get a locally defined or imported memory.
418    pub(crate) fn get_memory(&self, index: MemoryIndex) -> VMMemoryDefinition {
419        if let Some(defined_index) = self.env_module().defined_memory_index(index) {
420            self.memory(defined_index)
421        } else {
422            let import = self.imported_memory(index);
423            unsafe { VMMemoryDefinition::load(import.from.as_ptr()) }
424        }
425    }
426
427    /// Return the indexed `VMMemoryDefinition`, loaded from vmctx memory
428    /// already.
429    #[inline]
430    pub fn memory(&self, index: DefinedMemoryIndex) -> VMMemoryDefinition {
431        unsafe { VMMemoryDefinition::load(self.memory_ptr(index).as_ptr()) }
432    }
433
434    /// Set the indexed memory to `VMMemoryDefinition`.
435    fn set_memory(&self, index: DefinedMemoryIndex, mem: VMMemoryDefinition) {
436        unsafe {
437            self.memory_ptr(index).write(mem);
438        }
439    }
440
441    /// Return the address of the specified memory at `index` within this vmctx.
442    ///
443    /// Note that the returned pointer resides in wasm-code-readable-memory in
444    /// the vmctx.
445    #[inline]
446    pub fn memory_ptr(&self, index: DefinedMemoryIndex) -> NonNull<VMMemoryDefinition> {
447        unsafe {
448            self.vmctx_plus_offset::<VmPtr<_>>(self.offsets().vmctx_vmmemory_pointer(index))
449                .as_non_null()
450        }
451    }
452
453    /// Return the indexed `VMGlobalDefinition`.
454    pub fn global_ptr(&self, index: DefinedGlobalIndex) -> NonNull<VMGlobalDefinition> {
455        unsafe { self.vmctx_plus_offset_raw(self.offsets().vmctx_vmglobal_definition(index)) }
456    }
457
458    /// Get all globals within this instance.
459    ///
460    /// Returns both import and defined globals.
461    ///
462    /// Returns both exported and non-exported globals.
463    ///
464    /// Gives access to the full globals space.
465    pub fn all_globals(
466        &self,
467        store: StoreId,
468    ) -> impl ExactSizeIterator<Item = (GlobalIndex, crate::Global)> + '_ {
469        let module = self.env_module();
470        module
471            .globals
472            .keys()
473            .map(move |idx| (idx, self.get_exported_global(store, idx)))
474    }
475
476    /// Get the globals defined in this instance (not imported).
477    pub fn defined_globals(
478        &self,
479        store: StoreId,
480    ) -> impl ExactSizeIterator<Item = (DefinedGlobalIndex, crate::Global)> + '_ {
481        let module = self.env_module();
482        self.all_globals(store)
483            .skip(module.num_imported_globals)
484            .map(move |(i, global)| (module.defined_global_index(i).unwrap(), global))
485    }
486
487    /// Return a pointer to the interrupts structure
488    #[inline]
489    pub fn vm_store_context(&self) -> NonNull<Option<VmPtr<VMStoreContext>>> {
490        unsafe { self.vmctx_plus_offset_raw(self.offsets().ptr.vmctx_store_context()) }
491    }
492
493    /// Return a pointer to the global epoch counter used by this instance.
494    #[cfg(target_has_atomic = "64")]
495    pub fn epoch_ptr(self: Pin<&mut Self>) -> &mut Option<VmPtr<AtomicU64>> {
496        let offset = self.offsets().ptr.vmctx_epoch_ptr();
497        unsafe { self.vmctx_plus_offset_mut(offset) }
498    }
499
500    /// Return a pointer to the collector-specific heap data.
501    pub fn gc_heap_data(self: Pin<&mut Self>) -> &mut Option<VmPtr<u8>> {
502        let offset = self.offsets().ptr.vmctx_gc_heap_data();
503        unsafe { self.vmctx_plus_offset_mut(offset) }
504    }
505
506    pub(crate) unsafe fn set_store(mut self: Pin<&mut Self>, store: &StoreOpaque) {
507        // FIXME: should be more targeted ideally with the `unsafe` than just
508        // throwing this entire function in a large `unsafe` block.
509        unsafe {
510            *self.as_mut().store_mut() = Some(VMStoreRawPtr(store.traitobj()));
511            self.vm_store_context()
512                .write(Some(store.vm_store_context_ptr().into()));
513            #[cfg(target_has_atomic = "64")]
514            {
515                *self.as_mut().epoch_ptr() =
516                    Some(NonNull::from(store.engine().epoch_counter()).into());
517            }
518
519            if self.env_module().needs_gc_heap {
520                self.as_mut().set_gc_heap(Some(store.unwrap_gc_store()));
521            } else {
522                self.as_mut().set_gc_heap(None);
523            }
524        }
525    }
526
527    unsafe fn set_gc_heap(self: Pin<&mut Self>, gc_store: Option<&GcStore>) {
528        if let Some(gc_store) = gc_store {
529            *self.gc_heap_data() = Some(unsafe { gc_store.gc_heap.vmctx_gc_heap_data().into() });
530        } else {
531            *self.gc_heap_data() = None;
532        }
533    }
534
535    /// Return a reference to the vmctx used by compiled wasm code.
536    #[inline]
537    pub fn vmctx(&self) -> NonNull<VMContext> {
538        InstanceLayout::vmctx(self)
539    }
540
541    /// Lookup a function by index.
542    ///
543    /// # Panics
544    ///
545    /// Panics if `index` is out of bounds for this instance.
546    ///
547    /// # Safety
548    ///
549    /// The `store` parameter must be the store that owns this instance and the
550    /// functions that this instance can reference.
551    pub unsafe fn get_exported_func(
552        self: Pin<&mut Self>,
553        store: StoreId,
554        index: FuncIndex,
555    ) -> crate::Func {
556        let func_ref = self.get_func_ref(index).unwrap();
557
558        // SAFETY: the validity of `func_ref` is guaranteed by the validity of
559        // `self`, and the contract that `store` must own `func_ref` is a
560        // contract of this function itself.
561        unsafe { crate::Func::from_vm_func_ref(store, func_ref) }
562    }
563
564    /// Lookup a table by index.
565    ///
566    /// # Panics
567    ///
568    /// Panics if `index` is out of bounds for this instance.
569    pub fn get_exported_table(&self, store: StoreId, index: TableIndex) -> crate::Table {
570        let (id, def_index) = if let Some(def_index) = self.env_module().defined_table_index(index)
571        {
572            (self.id, def_index)
573        } else {
574            let import = self.imported_table(index);
575            // SAFETY: validity of this `Instance` guarantees validity of the
576            // `vmctx` pointer being read here to find the transitive
577            // `InstanceId` that the import is associated with.
578            let id = unsafe { self.sibling_vmctx(import.vmctx.as_non_null()).id };
579            (id, import.index)
580        };
581        crate::Table::from_raw(StoreInstanceId::new(store, id), def_index)
582    }
583
584    /// Lookup a memory by index.
585    ///
586    /// # Panics
587    ///
588    /// Panics if `index` is out-of-bounds for this instance.
589    pub fn get_exported_memory(&self, store: StoreId, index: MemoryIndex) -> crate::Memory {
590        let (id, def_index) = if let Some(def_index) = self.env_module().defined_memory_index(index)
591        {
592            (self.id, def_index)
593        } else {
594            let import = self.imported_memory(index);
595            // SAFETY: validity of this `Instance` guarantees validity of the
596            // `vmctx` pointer being read here to find the transitive
597            // `InstanceId` that the import is associated with.
598            let id = unsafe { self.sibling_vmctx(import.vmctx.as_non_null()).id };
599            (id, import.index)
600        };
601        crate::Memory::from_raw(StoreInstanceId::new(store, id), def_index)
602    }
603
604    /// Lookup a global by index.
605    ///
606    /// # Panics
607    ///
608    /// Panics if `index` is out-of-bounds for this instance.
609    pub(crate) fn get_exported_global(&self, store: StoreId, index: GlobalIndex) -> crate::Global {
610        // If this global is defined within this instance, then that's easy to
611        // calculate the `Global`.
612        if let Some(def_index) = self.env_module().defined_global_index(index) {
613            let instance = StoreInstanceId::new(store, self.id);
614            return crate::Global::from_core(instance, def_index);
615        }
616
617        // For imported globals it's required to match on the `kind` to
618        // determine which `Global` constructor is going to be invoked.
619        let import = self.imported_global(index);
620        match import.kind {
621            VMGlobalKind::Host(index) => crate::Global::from_host(store, index),
622            VMGlobalKind::Instance(index) => {
623                // SAFETY: validity of this `&Instance` means validity of its
624                // imports meaning we can read the id of the vmctx within.
625                let id = unsafe {
626                    let vmctx = VMContext::from_opaque(import.vmctx.unwrap().as_non_null());
627                    self.sibling_vmctx(vmctx).id
628                };
629                crate::Global::from_core(StoreInstanceId::new(store, id), index)
630            }
631            #[cfg(feature = "component-model")]
632            VMGlobalKind::ComponentFlags(index) => {
633                // SAFETY: validity of this `&Instance` means validity of its
634                // imports meaning we can read the id of the vmctx within.
635                let id = unsafe {
636                    let vmctx = super::component::VMComponentContext::from_opaque(
637                        import.vmctx.unwrap().as_non_null(),
638                    );
639                    super::component::ComponentInstance::vmctx_instance_id(vmctx)
640                };
641                crate::Global::from_component_flags(
642                    crate::component::store::StoreComponentInstanceId::new(store, id),
643                    index,
644                )
645            }
646        }
647    }
648
649    /// Get an exported tag by index.
650    ///
651    /// # Panics
652    ///
653    /// Panics if the index is out-of-range.
654    pub fn get_exported_tag(&self, store: StoreId, index: TagIndex) -> crate::Tag {
655        let (id, def_index) = if let Some(def_index) = self.env_module().defined_tag_index(index) {
656            (self.id, def_index)
657        } else {
658            let import = self.imported_tag(index);
659            // SAFETY: validity of this `Instance` guarantees validity of the
660            // `vmctx` pointer being read here to find the transitive
661            // `InstanceId` that the import is associated with.
662            let id = unsafe { self.sibling_vmctx(import.vmctx.as_non_null()).id };
663            (id, import.index)
664        };
665        crate::Tag::from_raw(StoreInstanceId::new(store, id), def_index)
666    }
667
668    /// Return an iterator over the exports of this instance.
669    ///
670    /// Specifically, it provides access to the key-value pairs, where the keys
671    /// are export names, and the values are export declarations which can be
672    /// resolved `lookup_by_declaration`.
673    pub fn exports(&self) -> wasmparser::collections::index_map::Iter<'_, String, EntityIndex> {
674        self.env_module().exports.iter()
675    }
676
677    /// Grow memory by the specified amount of pages.
678    ///
679    /// Returns `None` if memory can't be grown by the specified amount
680    /// of pages. Returns `Some` with the old size in bytes if growth was
681    /// successful.
682    pub(crate) async fn memory_grow(
683        mut self: Pin<&mut Self>,
684        limiter: Option<&mut StoreResourceLimiter<'_>>,
685        idx: DefinedMemoryIndex,
686        delta: u64,
687    ) -> Result<Option<usize>, Error> {
688        let memory = &mut self.as_mut().memories_mut()[idx].1;
689
690        // SAFETY: this is the safe wrapper around `Memory::grow` because it
691        // automatically updates the `VMMemoryDefinition` in this instance after
692        // a growth operation below.
693        let result = unsafe { memory.grow(delta, limiter).await };
694
695        // Update the state used by a non-shared Wasm memory in case the base
696        // pointer and/or the length changed.
697        if memory.as_shared_memory().is_none() {
698            let vmmemory = memory.vmmemory();
699            self.set_memory(idx, vmmemory);
700        }
701
702        result
703    }
704
705    pub(crate) fn table_element_type(
706        self: Pin<&mut Self>,
707        table_index: TableIndex,
708    ) -> TableElementType {
709        self.get_table(table_index).element_type()
710    }
711
712    /// Performs a grow operation on the `table_index` specified using `grow`.
713    ///
714    /// This will handle updating the VMTableDefinition internally as necessary.
715    pub(crate) async fn defined_table_grow(
716        mut self: Pin<&mut Self>,
717        table_index: DefinedTableIndex,
718        grow: impl AsyncFnOnce(&mut Table) -> Result<Option<usize>>,
719    ) -> Result<Option<usize>> {
720        let table = self.as_mut().get_defined_table(table_index);
721        let result = grow(table).await;
722        let element = table.vmtable();
723        self.set_table(table_index, element);
724        result
725    }
726
727    fn alloc_layout(offsets: &VMOffsets<HostPtr>) -> Layout {
728        let size = mem::size_of::<Self>()
729            .checked_add(usize::try_from(offsets.size_of_vmctx()).unwrap())
730            .unwrap();
731        let align = mem::align_of::<Self>();
732        Layout::from_size_align(size, align).unwrap()
733    }
734
735    fn type_ids_array(&self) -> NonNull<VmPtr<VMSharedTypeIndex>> {
736        unsafe { self.vmctx_plus_offset_raw(self.offsets().ptr.vmctx_type_ids_array()) }
737    }
738
739    /// Construct a new VMFuncRef for the given function
740    /// (imported or defined in this module) and store into the given
741    /// location. Used during lazy initialization.
742    ///
743    /// Note that our current lazy-init scheme actually calls this every
744    /// time the funcref pointer is fetched; this turns out to be better
745    /// than tracking state related to whether it's been initialized
746    /// before, because resetting that state on (re)instantiation is
747    /// very expensive if there are many funcrefs.
748    ///
749    /// # Safety
750    ///
751    /// This functions requires that `into` is a valid pointer.
752    unsafe fn construct_func_ref(
753        self: Pin<&mut Self>,
754        index: FuncIndex,
755        type_index: VMSharedTypeIndex,
756        into: *mut VMFuncRef,
757    ) {
758        let func_ref = if let Some(def_index) = self.env_module().defined_func_index(index) {
759            VMFuncRef {
760                array_call: self
761                    .runtime_info
762                    .array_to_wasm_trampoline(def_index)
763                    .expect("should have array-to-Wasm trampoline for escaping function")
764                    .into(),
765                wasm_call: Some(self.runtime_info.function(def_index).into()),
766                vmctx: VMOpaqueContext::from_vmcontext(self.vmctx()).into(),
767                type_index,
768            }
769        } else {
770            let import = self.imported_function(index);
771            VMFuncRef {
772                array_call: import.array_call,
773                wasm_call: Some(import.wasm_call),
774                vmctx: import.vmctx,
775                type_index,
776            }
777        };
778
779        // SAFETY: the unsafe contract here is forwarded to callers of this
780        // function.
781        unsafe {
782            ptr::write(into, func_ref);
783        }
784    }
785
786    /// Get a `&VMFuncRef` for the given `FuncIndex`.
787    ///
788    /// Returns `None` if the index is the reserved index value.
789    ///
790    /// The returned reference is a stable reference that won't be moved and can
791    /// be passed into JIT code.
792    pub(crate) fn get_func_ref(
793        self: Pin<&mut Self>,
794        index: FuncIndex,
795    ) -> Option<NonNull<VMFuncRef>> {
796        if index == FuncIndex::reserved_value() {
797            return None;
798        }
799
800        // For now, we eagerly initialize an funcref struct in-place
801        // whenever asked for a reference to it. This is mostly
802        // fine, because in practice each funcref is unlikely to be
803        // requested more than a few times: once-ish for funcref
804        // tables used for call_indirect (the usual compilation
805        // strategy places each function in the table at most once),
806        // and once or a few times when fetching exports via API.
807        // Note that for any case driven by table accesses, the lazy
808        // table init behaves like a higher-level cache layer that
809        // protects this initialization from happening multiple
810        // times, via that particular table at least.
811        //
812        // When `ref.func` becomes more commonly used or if we
813        // otherwise see a use-case where this becomes a hotpath,
814        // we can reconsider by using some state to track
815        // "uninitialized" explicitly, for example by zeroing the
816        // funcrefs (perhaps together with other
817        // zeroed-at-instantiate-time state) or using a separate
818        // is-initialized bitmap.
819        //
820        // We arrived at this design because zeroing memory is
821        // expensive, so it's better for instantiation performance
822        // if we don't have to track "is-initialized" state at
823        // all!
824        let func = &self.env_module().functions[index];
825        let sig = func.signature.unwrap_engine_type_index();
826
827        // SAFETY: the offset calculated here should be correct with
828        // `self.offsets`
829        let func_ref = unsafe {
830            self.vmctx_plus_offset_raw::<VMFuncRef>(self.offsets().vmctx_func_ref(func.func_ref))
831        };
832
833        // SAFETY: the `func_ref` ptr should be valid as it's within our
834        // `VMContext` area.
835        unsafe {
836            self.construct_func_ref(index, sig, func_ref.as_ptr());
837        }
838
839        Some(func_ref)
840    }
841
842    /// Get the passive elements segment at the given index.
843    ///
844    /// Returns an empty segment if the index is out of bounds or if the segment
845    /// has been dropped.
846    ///
847    /// The `storage` parameter should always be `None`; it is a bit of a hack
848    /// to work around lifetime issues.
849    pub(crate) fn passive_element_segment<'a>(
850        &self,
851        storage: &'a mut Option<(Arc<wasmtime_environ::Module>, TableSegmentElements)>,
852        elem_index: ElemIndex,
853    ) -> &'a TableSegmentElements {
854        debug_assert!(storage.is_none());
855        *storage = Some((
856            // TODO: this `clone()` shouldn't be necessary but is used for now to
857            // inform `rustc` that the lifetime of the elements here are
858            // disconnected from the lifetime of `self`.
859            self.env_module().clone(),
860            // NB: fall back to an expressions-based list of elements which
861            // doesn't have static type information (as opposed to
862            // `TableSegmentElements::Functions`) since we don't know what type
863            // is needed in the caller's context. Let the type be inferred by
864            // how they use the segment.
865            TableSegmentElements::Expressions(Box::new([])),
866        ));
867        let (module, empty) = storage.as_ref().unwrap();
868
869        match module.passive_elements_map.get(&elem_index) {
870            Some(index) if !self.dropped_elements.contains(elem_index) => {
871                &module.passive_elements[*index]
872            }
873            _ => empty,
874        }
875    }
876
877    /// The `table.init` operation: initializes a portion of a table with a
878    /// passive element.
879    ///
880    /// # Errors
881    ///
882    /// Returns a `Trap` error when the range within the table is out of bounds
883    /// or the range within the passive element is out of bounds.
884    pub(crate) async fn table_init(
885        store: &mut StoreOpaque,
886        limiter: Option<&mut StoreResourceLimiter<'_>>,
887        instance: InstanceId,
888        table_index: TableIndex,
889        elem_index: ElemIndex,
890        dst: u64,
891        src: u64,
892        len: u64,
893    ) -> Result<()> {
894        let mut storage = None;
895        let elements = store
896            .instance(instance)
897            .passive_element_segment(&mut storage, elem_index);
898        let mut const_evaluator = ConstExprEvaluator::default();
899        Self::table_init_segment(
900            store,
901            limiter,
902            instance,
903            &mut const_evaluator,
904            table_index,
905            elements,
906            dst,
907            src,
908            len,
909        )
910        .await
911    }
912
913    pub(crate) async fn table_init_segment(
914        store: &mut StoreOpaque,
915        mut limiter: Option<&mut StoreResourceLimiter<'_>>,
916        elements_instance_id: InstanceId,
917        const_evaluator: &mut ConstExprEvaluator,
918        table_index: TableIndex,
919        elements: &TableSegmentElements,
920        dst: u64,
921        src: u64,
922        len: u64,
923    ) -> Result<()> {
924        // https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-table-init
925
926        let store_id = store.id();
927        let elements_instance = store.instance_mut(elements_instance_id);
928        let table = elements_instance.get_exported_table(store_id, table_index);
929        let table_size = table._size(store);
930
931        // Perform a bounds check on the table being written to. This is done by
932        // ensuring that `dst + len <= table.size()` via checked arithmetic.
933        //
934        // Note that the bounds check for the element segment happens below when
935        // the original segment is sliced via `src` and `len`.
936        table_size
937            .checked_sub(dst)
938            .and_then(|i| i.checked_sub(len))
939            .ok_or(Trap::TableOutOfBounds)?;
940
941        let src = usize::try_from(src).map_err(|_| Trap::TableOutOfBounds)?;
942        let len = usize::try_from(len).map_err(|_| Trap::TableOutOfBounds)?;
943
944        let positions = dst..dst + u64::try_from(len).unwrap();
945        match elements {
946            TableSegmentElements::Functions(funcs) => {
947                let elements = funcs
948                    .get(src..)
949                    .and_then(|s| s.get(..len))
950                    .ok_or(Trap::TableOutOfBounds)?;
951                for (i, func_idx) in positions.zip(elements) {
952                    // SAFETY: the `store_id` passed to `get_exported_func` is
953                    // indeed the store that owns the function.
954                    let func = unsafe {
955                        store
956                            .instance_mut(elements_instance_id)
957                            .get_exported_func(store_id, *func_idx)
958                    };
959                    table.set_(store, i, func.into()).unwrap();
960                }
961            }
962            TableSegmentElements::Expressions(exprs) => {
963                let mut store = OpaqueRootScope::new(store);
964                let exprs = exprs
965                    .get(src..)
966                    .and_then(|s| s.get(..len))
967                    .ok_or(Trap::TableOutOfBounds)?;
968                let mut context = ConstEvalContext::new(elements_instance_id);
969                for (i, expr) in positions.zip(exprs) {
970                    let element = const_evaluator
971                        .eval(&mut store, limiter.as_deref_mut(), &mut context, expr)
972                        .await?;
973                    table.set_(&mut store, i, element.ref_().unwrap()).unwrap();
974                }
975            }
976        }
977
978        Ok(())
979    }
980
981    /// Drop an element.
982    pub(crate) fn elem_drop(self: Pin<&mut Self>, elem_index: ElemIndex) {
983        // https://webassembly.github.io/reference-types/core/exec/instructions.html#exec-elem-drop
984
985        self.dropped_elements_mut().insert(elem_index);
986
987        // Note that we don't check that we actually removed a segment because
988        // dropping a non-passive segment is a no-op (not a trap).
989    }
990
991    /// Get a locally-defined memory.
992    pub fn get_defined_memory_mut(self: Pin<&mut Self>, index: DefinedMemoryIndex) -> &mut Memory {
993        &mut self.memories_mut()[index].1
994    }
995
996    /// Get a locally-defined memory.
997    pub fn get_defined_memory(&self, index: DefinedMemoryIndex) -> &Memory {
998        &self.memories[index].1
999    }
1000
1001    /// Do a `memory.copy`
1002    ///
1003    /// # Errors
1004    ///
1005    /// Returns a `Trap` error when the source or destination ranges are out of
1006    /// bounds.
1007    pub(crate) fn memory_copy(
1008        self: Pin<&mut Self>,
1009        dst_index: MemoryIndex,
1010        dst: u64,
1011        src_index: MemoryIndex,
1012        src: u64,
1013        len: u64,
1014    ) -> Result<(), Trap> {
1015        // https://webassembly.github.io/reference-types/core/exec/instructions.html#exec-memory-copy
1016
1017        let src_mem = self.get_memory(src_index);
1018        let dst_mem = self.get_memory(dst_index);
1019
1020        let src = self.validate_inbounds(src_mem.current_length(), src, len)?;
1021        let dst = self.validate_inbounds(dst_mem.current_length(), dst, len)?;
1022        let len = usize::try_from(len).unwrap();
1023
1024        // Bounds and casts are checked above, by this point we know that
1025        // everything is safe.
1026        unsafe {
1027            let dst = dst_mem.base.as_ptr().add(dst);
1028            let src = src_mem.base.as_ptr().add(src);
1029            // FIXME audit whether this is safe in the presence of shared memory
1030            // (https://github.com/bytecodealliance/wasmtime/issues/4203).
1031            ptr::copy(src, dst, len);
1032        }
1033
1034        Ok(())
1035    }
1036
1037    fn validate_inbounds(&self, max: usize, ptr: u64, len: u64) -> Result<usize, Trap> {
1038        let oob = || Trap::MemoryOutOfBounds;
1039        let end = ptr
1040            .checked_add(len)
1041            .and_then(|i| usize::try_from(i).ok())
1042            .ok_or_else(oob)?;
1043        if end > max {
1044            Err(oob())
1045        } else {
1046            Ok(ptr.try_into().unwrap())
1047        }
1048    }
1049
1050    /// Perform the `memory.fill` operation on a locally defined memory.
1051    ///
1052    /// # Errors
1053    ///
1054    /// Returns a `Trap` error if the memory range is out of bounds.
1055    pub(crate) fn memory_fill(
1056        self: Pin<&mut Self>,
1057        memory_index: DefinedMemoryIndex,
1058        dst: u64,
1059        val: u8,
1060        len: u64,
1061    ) -> Result<(), Trap> {
1062        let memory_index = self.env_module().memory_index(memory_index);
1063        let memory = self.get_memory(memory_index);
1064        let dst = self.validate_inbounds(memory.current_length(), dst, len)?;
1065        let len = usize::try_from(len).unwrap();
1066
1067        // Bounds and casts are checked above, by this point we know that
1068        // everything is safe.
1069        unsafe {
1070            let dst = memory.base.as_ptr().add(dst);
1071            // FIXME audit whether this is safe in the presence of shared memory
1072            // (https://github.com/bytecodealliance/wasmtime/issues/4203).
1073            ptr::write_bytes(dst, val, len);
1074        }
1075
1076        Ok(())
1077    }
1078
1079    /// Get the internal storage range of a particular Wasm data segment.
1080    pub(crate) fn wasm_data_range(&self, index: DataIndex) -> Range<u32> {
1081        match self.env_module().passive_data_map.get(&index) {
1082            Some(range) if !self.dropped_data.contains(index) => range.clone(),
1083            _ => 0..0,
1084        }
1085    }
1086
1087    /// Given an internal storage range of a Wasm data segment (or subset of a
1088    /// Wasm data segment), get the data's raw bytes.
1089    pub(crate) fn wasm_data(&self, range: Range<u32>) -> &[u8] {
1090        let start = usize::try_from(range.start).unwrap();
1091        let end = usize::try_from(range.end).unwrap();
1092        &self.runtime_info.wasm_data()[start..end]
1093    }
1094
1095    /// Performs the `memory.init` operation.
1096    ///
1097    /// # Errors
1098    ///
1099    /// Returns a `Trap` error if the destination range is out of this module's
1100    /// memory's bounds or if the source range is outside the data segment's
1101    /// bounds.
1102    pub(crate) fn memory_init(
1103        self: Pin<&mut Self>,
1104        memory_index: MemoryIndex,
1105        data_index: DataIndex,
1106        dst: u64,
1107        src: u32,
1108        len: u32,
1109    ) -> Result<(), Trap> {
1110        let range = self.wasm_data_range(data_index);
1111        self.memory_init_segment(memory_index, range, dst, src, len)
1112    }
1113
1114    pub(crate) fn memory_init_segment(
1115        self: Pin<&mut Self>,
1116        memory_index: MemoryIndex,
1117        range: Range<u32>,
1118        dst: u64,
1119        src: u32,
1120        len: u32,
1121    ) -> Result<(), Trap> {
1122        // https://webassembly.github.io/bulk-memory-operations/core/exec/instructions.html#exec-memory-init
1123
1124        let memory = self.get_memory(memory_index);
1125        let data = self.wasm_data(range);
1126        let dst = self.validate_inbounds(memory.current_length(), dst, len.into())?;
1127        let src = self.validate_inbounds(data.len(), src.into(), len.into())?;
1128        let len = len as usize;
1129
1130        unsafe {
1131            let src_start = data.as_ptr().add(src);
1132            let dst_start = memory.base.as_ptr().add(dst);
1133            // FIXME audit whether this is safe in the presence of shared memory
1134            // (https://github.com/bytecodealliance/wasmtime/issues/4203).
1135            ptr::copy_nonoverlapping(src_start, dst_start, len);
1136        }
1137
1138        Ok(())
1139    }
1140
1141    /// Drop the given data segment, truncating its length to zero.
1142    pub(crate) fn data_drop(self: Pin<&mut Self>, data_index: DataIndex) {
1143        self.dropped_data_mut().insert(data_index);
1144
1145        // Note that we don't check that we actually removed a segment because
1146        // dropping a non-passive segment is a no-op (not a trap).
1147    }
1148
1149    /// Get a table by index regardless of whether it is locally-defined
1150    /// or an imported, foreign table. Ensure that the given range of
1151    /// elements in the table is lazily initialized.  We define this
1152    /// operation all-in-one for safety, to ensure the lazy-init
1153    /// happens.
1154    ///
1155    /// Takes an `Iterator` for the index-range to lazy-initialize,
1156    /// for flexibility. This can be a range, single item, or empty
1157    /// sequence, for example. The iterator should return indices in
1158    /// increasing order, so that the break-at-out-of-bounds behavior
1159    /// works correctly.
1160    pub(crate) fn get_table_with_lazy_init(
1161        self: Pin<&mut Self>,
1162        table_index: TableIndex,
1163        range: impl Iterator<Item = u64>,
1164    ) -> &mut Table {
1165        let (idx, instance) = self.defined_table_index_and_instance(table_index);
1166        instance.get_defined_table_with_lazy_init(idx, range)
1167    }
1168
1169    /// Gets the raw runtime table data structure owned by this instance
1170    /// given the provided `idx`.
1171    ///
1172    /// The `range` specified is eagerly initialized for funcref tables.
1173    pub fn get_defined_table_with_lazy_init(
1174        mut self: Pin<&mut Self>,
1175        idx: DefinedTableIndex,
1176        range: impl IntoIterator<Item = u64>,
1177    ) -> &mut Table {
1178        let elt_ty = self.tables[idx].1.element_type();
1179
1180        if elt_ty == TableElementType::Func {
1181            for i in range {
1182                match self.tables[idx].1.get_func_maybe_init(i) {
1183                    // Uninitialized table element.
1184                    Ok(None) => {}
1185                    // Initialized table element, move on to the next.
1186                    Ok(Some(_)) => continue,
1187                    // Out-of-bounds; caller will handle by likely
1188                    // throwing a trap. No work to do to lazy-init
1189                    // beyond the end.
1190                    Err(_) => break,
1191                };
1192
1193                // The table element `i` is uninitialized and is now being
1194                // initialized. This must imply that a `precompiled` list of
1195                // function indices is available for this table. The precompiled
1196                // list is extracted and then it is consulted with `i` to
1197                // determine the function that is going to be initialized. Note
1198                // that `i` may be outside the limits of the static
1199                // initialization so it's a fallible `get` instead of an index.
1200                let module = self.env_module();
1201                let precomputed = match &module.table_initialization.initial_values[idx] {
1202                    TableInitialValue::Null { precomputed } => precomputed,
1203                    TableInitialValue::Expr(_) => unreachable!(),
1204                };
1205                // Panicking here helps catch bugs rather than silently truncating by accident.
1206                let func_index = precomputed.get(usize::try_from(i).unwrap()).cloned();
1207                let func_ref =
1208                    func_index.and_then(|func_index| self.as_mut().get_func_ref(func_index));
1209                self.as_mut().tables_mut()[idx]
1210                    .1
1211                    .set_func(i, func_ref)
1212                    .expect("Table type should match and index should be in-bounds");
1213            }
1214        }
1215
1216        self.get_defined_table(idx)
1217    }
1218
1219    /// Get a table by index regardless of whether it is locally-defined or an
1220    /// imported, foreign table.
1221    pub(crate) fn get_table(self: Pin<&mut Self>, table_index: TableIndex) -> &mut Table {
1222        let (idx, instance) = self.defined_table_index_and_instance(table_index);
1223        instance.get_defined_table(idx)
1224    }
1225
1226    /// Get a locally-defined table.
1227    pub(crate) fn get_defined_table(self: Pin<&mut Self>, index: DefinedTableIndex) -> &mut Table {
1228        &mut self.tables_mut()[index].1
1229    }
1230
1231    pub(crate) fn defined_table_index_and_instance<'a>(
1232        self: Pin<&'a mut Self>,
1233        index: TableIndex,
1234    ) -> (DefinedTableIndex, Pin<&'a mut Instance>) {
1235        if let Some(defined_table_index) = self.env_module().defined_table_index(index) {
1236            (defined_table_index, self)
1237        } else {
1238            let import = self.imported_table(index);
1239            let index = import.index;
1240            let vmctx = import.vmctx.as_non_null();
1241            // SAFETY: the validity of `self` means that the reachable instances
1242            // should also all be owned by the same store and fully initialized,
1243            // so it's safe to laterally move from a mutable borrow of this
1244            // instance to a mutable borrow of a sibling instance.
1245            let foreign_instance = unsafe { self.sibling_vmctx_mut(vmctx) };
1246            (index, foreign_instance)
1247        }
1248    }
1249
1250    /// Initialize the VMContext data associated with this Instance.
1251    ///
1252    /// The `VMContext` memory is assumed to be uninitialized; any field
1253    /// that we need in a certain state will be explicitly written by this
1254    /// function.
1255    unsafe fn initialize_vmctx(
1256        mut self: Pin<&mut Self>,
1257        module: &Module,
1258        offsets: &VMOffsets<HostPtr>,
1259        store: &StoreOpaque,
1260        imports: Imports,
1261    ) {
1262        assert!(ptr::eq(module, self.env_module().as_ref()));
1263
1264        // SAFETY: the type of the magic field is indeed `u32` and this function
1265        // is initializing its value.
1266        unsafe {
1267            self.vmctx_plus_offset_raw::<u32>(offsets.ptr.vmctx_magic())
1268                .write(VMCONTEXT_MAGIC);
1269        }
1270
1271        // SAFETY: it's up to the caller to provide a valid store pointer here.
1272        unsafe {
1273            self.as_mut().set_store(store);
1274        }
1275
1276        // Initialize shared types
1277        //
1278        // SAFETY: validity of the vmctx means it should be safe to write to it
1279        // here.
1280        unsafe {
1281            let types = NonNull::from(self.runtime_info.type_ids());
1282            self.type_ids_array().write(types.cast().into());
1283        }
1284
1285        // Initialize the built-in functions
1286        //
1287        // SAFETY: the type of the builtin functions field is indeed a pointer
1288        // and the pointer being filled in here, plus the vmctx is valid to
1289        // write to during initialization.
1290        unsafe {
1291            static BUILTINS: VMBuiltinFunctionsArray = VMBuiltinFunctionsArray::INIT;
1292            let ptr = BUILTINS.expose_provenance();
1293            self.vmctx_plus_offset_raw(offsets.ptr.vmctx_builtin_functions())
1294                .write(VmPtr::from(ptr));
1295        }
1296
1297        // Initialize the imports
1298        //
1299        // SAFETY: the vmctx is safe to initialize during this function and
1300        // validity of each item itself is a contract the caller must uphold.
1301        debug_assert_eq!(imports.functions.len(), module.num_imported_funcs);
1302        unsafe {
1303            ptr::copy_nonoverlapping(
1304                imports.functions.as_ptr(),
1305                self.vmctx_plus_offset_raw(offsets.vmctx_imported_functions_begin())
1306                    .as_ptr(),
1307                imports.functions.len(),
1308            );
1309            debug_assert_eq!(imports.tables.len(), module.num_imported_tables);
1310            ptr::copy_nonoverlapping(
1311                imports.tables.as_ptr(),
1312                self.vmctx_plus_offset_raw(offsets.vmctx_imported_tables_begin())
1313                    .as_ptr(),
1314                imports.tables.len(),
1315            );
1316            debug_assert_eq!(imports.memories.len(), module.num_imported_memories);
1317            ptr::copy_nonoverlapping(
1318                imports.memories.as_ptr(),
1319                self.vmctx_plus_offset_raw(offsets.vmctx_imported_memories_begin())
1320                    .as_ptr(),
1321                imports.memories.len(),
1322            );
1323            debug_assert_eq!(imports.globals.len(), module.num_imported_globals);
1324            ptr::copy_nonoverlapping(
1325                imports.globals.as_ptr(),
1326                self.vmctx_plus_offset_raw(offsets.vmctx_imported_globals_begin())
1327                    .as_ptr(),
1328                imports.globals.len(),
1329            );
1330            debug_assert_eq!(imports.tags.len(), module.num_imported_tags);
1331            ptr::copy_nonoverlapping(
1332                imports.tags.as_ptr(),
1333                self.vmctx_plus_offset_raw(offsets.vmctx_imported_tags_begin())
1334                    .as_ptr(),
1335                imports.tags.len(),
1336            );
1337        }
1338
1339        // N.B.: there is no need to initialize the funcrefs array because we
1340        // eagerly construct each element in it whenever asked for a reference
1341        // to that element. In other words, there is no state needed to track
1342        // the lazy-init, so we don't need to initialize any state now.
1343
1344        // Initialize the defined tables
1345        //
1346        // SAFETY: it's safe to initialize these tables during initialization
1347        // here and the various types of pointers and such here should all be
1348        // valid.
1349        unsafe {
1350            let mut ptr = self.vmctx_plus_offset_raw(offsets.vmctx_tables_begin());
1351            let tables = self.as_mut().tables_mut();
1352            for i in 0..module.num_defined_tables() {
1353                ptr.write(tables[DefinedTableIndex::new(i)].1.vmtable());
1354                ptr = ptr.add(1);
1355            }
1356        }
1357
1358        // Initialize the defined memories. This fills in both the
1359        // `defined_memories` table and the `owned_memories` table at the same
1360        // time. Entries in `defined_memories` hold a pointer to a definition
1361        // (all memories) whereas the `owned_memories` hold the actual
1362        // definitions of memories owned (not shared) in the module.
1363        //
1364        // SAFETY: it's safe to initialize these memories during initialization
1365        // here and the various types of pointers and such here should all be
1366        // valid.
1367        unsafe {
1368            let mut ptr = self.vmctx_plus_offset_raw(offsets.vmctx_memories_begin());
1369            let mut owned_ptr = self.vmctx_plus_offset_raw(offsets.vmctx_owned_memories_begin());
1370            let memories = self.as_mut().memories_mut();
1371            for i in 0..module.num_defined_memories() {
1372                let defined_memory_index = DefinedMemoryIndex::new(i);
1373                let memory_index = module.memory_index(defined_memory_index);
1374                if module.memories[memory_index].shared {
1375                    let def_ptr = memories[defined_memory_index]
1376                        .1
1377                        .as_shared_memory()
1378                        .unwrap()
1379                        .vmmemory_ptr();
1380                    ptr.write(VmPtr::from(def_ptr));
1381                } else {
1382                    owned_ptr.write(memories[defined_memory_index].1.vmmemory());
1383                    ptr.write(VmPtr::from(owned_ptr));
1384                    owned_ptr = owned_ptr.add(1);
1385                }
1386                ptr = ptr.add(1);
1387            }
1388        }
1389
1390        // Zero-initialize the globals so that nothing is uninitialized memory
1391        // after this function returns. The globals are actually initialized
1392        // with their const expression initializers after the instance is fully
1393        // allocated.
1394        //
1395        // SAFETY: it's safe to initialize globals during initialization
1396        // here. Note that while the value being written is not valid for all
1397        // types of globals it's initializing the memory to zero instead of
1398        // being in an undefined state. So it's still unsafe to access globals
1399        // after this, but if it's read then it'd hopefully crash faster than
1400        // leaving this undefined.
1401        unsafe {
1402            for (index, _init) in module.global_initializers.iter() {
1403                self.global_ptr(index).write(VMGlobalDefinition::new());
1404            }
1405        }
1406
1407        // Initialize the defined tags
1408        //
1409        // SAFETY: it's safe to initialize these tags during initialization
1410        // here and the various types of pointers and such here should all be
1411        // valid.
1412        unsafe {
1413            let mut ptr = self.vmctx_plus_offset_raw(offsets.vmctx_tags_begin());
1414            for i in 0..module.num_defined_tags() {
1415                let defined_index = DefinedTagIndex::new(i);
1416                let tag_index = module.tag_index(defined_index);
1417                let tag = module.tags[tag_index];
1418                ptr.write(VMTagDefinition::new(
1419                    tag.signature.unwrap_engine_type_index(),
1420                ));
1421                ptr = ptr.add(1);
1422            }
1423        }
1424    }
1425
1426    /// Attempts to convert from the host `addr` specified to a WebAssembly
1427    /// based address recorded in `WasmFault`.
1428    ///
1429    /// This method will check all linear memories that this instance contains
1430    /// to see if any of them contain `addr`. If one does then `Some` is
1431    /// returned with metadata about the wasm fault. Otherwise `None` is
1432    /// returned and `addr` doesn't belong to this instance.
1433    pub fn wasm_fault(&self, addr: usize) -> Option<WasmFault> {
1434        let mut fault = None;
1435        for (_, (_, memory)) in self.memories.iter() {
1436            let accessible = memory.wasm_accessible();
1437            if accessible.start <= addr && addr < accessible.end {
1438                // All linear memories should be disjoint so assert that no
1439                // prior fault has been found.
1440                assert!(fault.is_none());
1441                fault = Some(WasmFault {
1442                    memory_size: memory.byte_size(),
1443                    wasm_address: u64::try_from(addr - accessible.start).unwrap(),
1444                });
1445            }
1446        }
1447        fault
1448    }
1449
1450    /// Returns the id, within this instance's store, that it's assigned.
1451    pub fn id(&self) -> InstanceId {
1452        self.id
1453    }
1454
1455    /// Get all memories within this instance.
1456    ///
1457    /// Returns both import and defined memories.
1458    ///
1459    /// Returns both exported and non-exported memories.
1460    ///
1461    /// Gives access to the full memories space.
1462    pub fn all_memories(
1463        &self,
1464        store: StoreId,
1465    ) -> impl ExactSizeIterator<Item = (MemoryIndex, crate::Memory)> + '_ {
1466        self.env_module()
1467            .memories
1468            .iter()
1469            .map(move |(i, _)| (i, self.get_exported_memory(store, i)))
1470    }
1471
1472    /// Return the memories defined in this instance (not imported).
1473    pub fn defined_memories<'a>(
1474        &'a self,
1475        store: StoreId,
1476    ) -> impl ExactSizeIterator<Item = crate::Memory> + 'a {
1477        let num_imported = self.env_module().num_imported_memories;
1478        self.all_memories(store)
1479            .skip(num_imported)
1480            .map(|(_i, memory)| memory)
1481    }
1482
1483    /// Lookup an item with the given index.
1484    ///
1485    /// # Panics
1486    ///
1487    /// Panics if `export` is not valid for this instance.
1488    ///
1489    /// # Safety
1490    ///
1491    /// This function requires that `store` is the correct store which owns this
1492    /// instance.
1493    pub unsafe fn get_export_by_index_mut(
1494        self: Pin<&mut Self>,
1495        store: StoreId,
1496        export: EntityIndex,
1497    ) -> Export {
1498        match export {
1499            // SAFETY: the contract of `store` owning the this instance is a
1500            // safety requirement of this function itself.
1501            EntityIndex::Function(i) => {
1502                Export::Function(unsafe { self.get_exported_func(store, i) })
1503            }
1504            EntityIndex::Global(i) => Export::Global(self.get_exported_global(store, i)),
1505            EntityIndex::Table(i) => Export::Table(self.get_exported_table(store, i)),
1506            EntityIndex::Memory(i) => Export::Memory {
1507                memory: self.get_exported_memory(store, i),
1508                shared: self.env_module().memories[i].shared,
1509            },
1510            EntityIndex::Tag(i) => Export::Tag(self.get_exported_tag(store, i)),
1511        }
1512    }
1513
1514    fn store_mut(self: Pin<&mut Self>) -> &mut Option<VMStoreRawPtr> {
1515        // SAFETY: this is a pin-projection to get a mutable reference to an
1516        // internal field and is safe so long as the `&mut Self` temporarily
1517        // created is not overwritten, which it isn't here.
1518        unsafe { &mut self.get_unchecked_mut().store }
1519    }
1520
1521    fn dropped_elements_mut(self: Pin<&mut Self>) -> &mut EntitySet<ElemIndex> {
1522        // SAFETY: see `store_mut` above.
1523        unsafe { &mut self.get_unchecked_mut().dropped_elements }
1524    }
1525
1526    fn dropped_data_mut(self: Pin<&mut Self>) -> &mut EntitySet<DataIndex> {
1527        // SAFETY: see `store_mut` above.
1528        unsafe { &mut self.get_unchecked_mut().dropped_data }
1529    }
1530
1531    fn memories_mut(
1532        self: Pin<&mut Self>,
1533    ) -> &mut PrimaryMap<DefinedMemoryIndex, (MemoryAllocationIndex, Memory)> {
1534        // SAFETY: see `store_mut` above.
1535        unsafe { &mut self.get_unchecked_mut().memories }
1536    }
1537
1538    pub(crate) fn tables_mut(
1539        self: Pin<&mut Self>,
1540    ) -> &mut PrimaryMap<DefinedTableIndex, (TableAllocationIndex, Table)> {
1541        // SAFETY: see `store_mut` above.
1542        unsafe { &mut self.get_unchecked_mut().tables }
1543    }
1544
1545    #[cfg(feature = "wmemcheck")]
1546    pub(super) fn wmemcheck_state_mut(self: Pin<&mut Self>) -> &mut Option<Wmemcheck> {
1547        // SAFETY: see `store_mut` above.
1548        unsafe { &mut self.get_unchecked_mut().wmemcheck_state }
1549    }
1550}
1551
1552// SAFETY: `layout` should describe this accurately and `OwnedVMContext` is the
1553// last field of `ComponentInstance`.
1554unsafe impl InstanceLayout for Instance {
1555    const INIT_ZEROED: bool = false;
1556    type VMContext = VMContext;
1557
1558    fn layout(&self) -> Layout {
1559        Self::alloc_layout(self.runtime_info.offsets())
1560    }
1561
1562    fn owned_vmctx(&self) -> &OwnedVMContext<VMContext> {
1563        &self.vmctx
1564    }
1565
1566    fn owned_vmctx_mut(&mut self) -> &mut OwnedVMContext<VMContext> {
1567        &mut self.vmctx
1568    }
1569}
1570
1571pub type InstanceHandle = OwnedInstance<Instance>;
1572
1573/// A handle holding an `Instance` of a WebAssembly module.
1574///
1575/// This structure is an owning handle of the `instance` contained internally.
1576/// When this value goes out of scope it will deallocate the `Instance` and all
1577/// memory associated with it.
1578///
1579/// Note that this lives within a `StoreOpaque` on a list of instances that a
1580/// store is keeping alive.
1581#[derive(Debug)]
1582#[repr(transparent)] // guarantee this is a zero-cost wrapper
1583pub struct OwnedInstance<T: InstanceLayout> {
1584    /// The raw pointer to the instance that was allocated.
1585    ///
1586    /// Note that this is not equivalent to `Box<Instance>` because the
1587    /// allocation here has a `VMContext` trailing after it. Thus the custom
1588    /// destructor to invoke the `dealloc` function with the appropriate
1589    /// layout.
1590    instance: SendSyncPtr<T>,
1591    _marker: marker::PhantomData<Box<(T, OwnedVMContext<T::VMContext>)>>,
1592}
1593
1594/// Structure that must be placed at the end of a type implementing
1595/// `InstanceLayout`.
1596#[repr(align(16))] // match the alignment of VMContext
1597pub struct OwnedVMContext<T> {
1598    /// A pointer to the `vmctx` field at the end of the `structure`.
1599    ///
1600    /// If you're looking at this a reasonable question would be "why do we need
1601    /// a pointer to ourselves?" because after all the pointer's value is
1602    /// trivially derivable from any `&Instance` pointer. The rationale for this
1603    /// field's existence is subtle, but it's required for correctness. The
1604    /// short version is "this makes miri happy".
1605    ///
1606    /// The long version of why this field exists is that the rules that MIRI
1607    /// uses to ensure pointers are used correctly have various conditions on
1608    /// them depend on how pointers are used. More specifically if `*mut T` is
1609    /// derived from `&mut T`, then that invalidates all prior pointers drived
1610    /// from the `&mut T`. This means that while we liberally want to re-acquire
1611    /// a `*mut VMContext` throughout the implementation of `Instance` the
1612    /// trivial way, a function `fn vmctx(Pin<&mut Instance>) -> *mut VMContext`
1613    /// would effectively invalidate all prior `*mut VMContext` pointers
1614    /// acquired. The purpose of this field is to serve as a sort of
1615    /// source-of-truth for where `*mut VMContext` pointers come from.
1616    ///
1617    /// This field is initialized when the `Instance` is created with the
1618    /// original allocation's pointer. That means that the provenance of this
1619    /// pointer contains the entire allocation (both instance and `VMContext`).
1620    /// This provenance bit is then "carried through" where `fn vmctx` will base
1621    /// all returned pointers on this pointer itself. This provides the means of
1622    /// never invalidating this pointer throughout MIRI and additionally being
1623    /// able to still temporarily have `Pin<&mut Instance>` methods and such.
1624    ///
1625    /// It's important to note, though, that this is not here purely for MIRI.
1626    /// The careful construction of the `fn vmctx` method has ramifications on
1627    /// the LLVM IR generated, for example. A historical CVE on Wasmtime,
1628    /// GHSA-ch89-5g45-qwc7, was caused due to relying on undefined behavior. By
1629    /// deriving VMContext pointers from this pointer it specifically hints to
1630    /// LLVM that trickery is afoot and it properly informs `noalias` and such
1631    /// annotations and analysis. More-or-less this pointer is actually loaded
1632    /// in LLVM IR which helps defeat otherwise present aliasing optimizations,
1633    /// which we want, since writes to this should basically never be optimized
1634    /// out.
1635    ///
1636    /// As a final note it's worth pointing out that the machine code generated
1637    /// for accessing `fn vmctx` is still as one would expect. This member isn't
1638    /// actually ever loaded at runtime (or at least shouldn't be). Perhaps in
1639    /// the future if the memory consumption of this field is a problem we could
1640    /// shrink it slightly, but for now one extra pointer per wasm instance
1641    /// seems not too bad.
1642    vmctx_self_reference: SendSyncPtr<T>,
1643
1644    /// This field ensures that going from `Pin<&mut T>` to `&mut T` is not a
1645    /// safe operation.
1646    _marker: core::marker::PhantomPinned,
1647}
1648
1649impl<T> OwnedVMContext<T> {
1650    /// Creates a new blank vmctx to place at the end of an instance.
1651    pub fn new() -> OwnedVMContext<T> {
1652        OwnedVMContext {
1653            vmctx_self_reference: SendSyncPtr::new(NonNull::dangling()),
1654            _marker: core::marker::PhantomPinned,
1655        }
1656    }
1657}
1658
1659/// Helper trait to plumb both core instances and component instances into
1660/// `OwnedInstance` below.
1661///
1662/// # Safety
1663///
1664/// This trait requires `layout` to correctly describe `Self` and appropriately
1665/// allocate space for `Self::VMContext` afterwards. Additionally the field
1666/// returned by `owned_vmctx()` must be the last field in the structure.
1667pub unsafe trait InstanceLayout {
1668    /// Whether or not to allocate this instance with `alloc_zeroed` or `alloc`.
1669    const INIT_ZEROED: bool;
1670
1671    /// The trailing `VMContext` type at the end of this instance.
1672    type VMContext;
1673
1674    /// The memory layout to use to allocate and deallocate this instance.
1675    fn layout(&self) -> Layout;
1676
1677    fn owned_vmctx(&self) -> &OwnedVMContext<Self::VMContext>;
1678    fn owned_vmctx_mut(&mut self) -> &mut OwnedVMContext<Self::VMContext>;
1679
1680    /// Returns the `vmctx_self_reference` set above.
1681    #[inline]
1682    fn vmctx(&self) -> NonNull<Self::VMContext> {
1683        // The definition of this method is subtle but intentional. The goal
1684        // here is that effectively this should return `&mut self.vmctx`, but
1685        // it's not quite so simple. Some more documentation is available on the
1686        // `vmctx_self_reference` field, but the general idea is that we're
1687        // creating a pointer to return with proper provenance. Provenance is
1688        // still in the works in Rust at the time of this writing but the load
1689        // of the `self.vmctx_self_reference` field is important here as it
1690        // affects how LLVM thinks about aliasing with respect to the returned
1691        // pointer.
1692        //
1693        // The intention of this method is to codegen to machine code as `&mut
1694        // self.vmctx`, however. While it doesn't show up like this in LLVM IR
1695        // (there's an actual load of the field) it does look like that by the
1696        // time the backend runs. (that's magic to me, the backend removing
1697        // loads...)
1698        let owned_vmctx = self.owned_vmctx();
1699        let owned_vmctx_raw = NonNull::from(owned_vmctx);
1700        // SAFETY: it's part of the contract of `InstanceLayout` and the usage
1701        // with `OwnedInstance` that this indeed points to the vmctx.
1702        let addr = unsafe { owned_vmctx_raw.add(1) };
1703        owned_vmctx
1704            .vmctx_self_reference
1705            .as_non_null()
1706            .with_addr(addr.addr())
1707    }
1708
1709    /// Helper function to access various locations offset from our `*mut
1710    /// VMContext` object.
1711    ///
1712    /// Note that this method takes `&self` as an argument but returns
1713    /// `NonNull<T>` which is frequently used to mutate said memory. This is an
1714    /// intentional design decision where the safety of the modification of
1715    /// memory is placed as a burden onto the caller. The implementation of this
1716    /// method explicitly does not require `&mut self` to acquire mutable
1717    /// provenance to update the `VMContext` region. Instead all pointers into
1718    /// the `VMContext` area have provenance/permissions to write.
1719    ///
1720    /// Also note though that care must be taken to ensure that reads/writes of
1721    /// memory must only happen where appropriate, for example a non-atomic
1722    /// write (as most are) should never happen concurrently with another read
1723    /// or write. It's generally on the burden of the caller to adhere to this.
1724    ///
1725    /// Also of note is that most of the time the usage of this method falls
1726    /// into one of:
1727    ///
1728    /// * Something in the VMContext is being read or written. In that case use
1729    ///   `vmctx_plus_offset` or `vmctx_plus_offset_mut` if possible due to
1730    ///   that having a safer lifetime.
1731    ///
1732    /// * A pointer is being created to pass to other VM* data structures. In
1733    ///   that situation the lifetime of all VM data structures are typically
1734    ///   tied to the `Store<T>` which is what provides the guarantees around
1735    ///   concurrency/etc.
1736    ///
1737    /// There's quite a lot of unsafety riding on this method, especially
1738    /// related to the ascription `T` of the byte `offset`. It's hoped that in
1739    /// the future we're able to settle on an in theory safer design.
1740    ///
1741    /// # Safety
1742    ///
1743    /// This method is unsafe because the `offset` must be within bounds of the
1744    /// `VMContext` object trailing this instance. Additionally `T` must be a
1745    /// valid ascription of the value that resides at that location.
1746    unsafe fn vmctx_plus_offset_raw<T: VmSafe>(&self, offset: impl Into<u32>) -> NonNull<T> {
1747        // SAFETY: the safety requirements of `byte_add` are forwarded to this
1748        // method's caller.
1749        unsafe {
1750            self.vmctx()
1751                .byte_add(usize::try_from(offset.into()).unwrap())
1752                .cast()
1753        }
1754    }
1755
1756    /// Helper above `vmctx_plus_offset_raw` which transfers the lifetime of
1757    /// `&self` to the returned reference `&T`.
1758    ///
1759    /// # Safety
1760    ///
1761    /// See the safety documentation of `vmctx_plus_offset_raw`.
1762    unsafe fn vmctx_plus_offset<T: VmSafe>(&self, offset: impl Into<u32>) -> &T {
1763        // SAFETY: this method has the same safety requirements as
1764        // `vmctx_plus_offset_raw`.
1765        unsafe { self.vmctx_plus_offset_raw(offset).as_ref() }
1766    }
1767
1768    /// Helper above `vmctx_plus_offset_raw` which transfers the lifetime of
1769    /// `&mut self` to the returned reference `&mut T`.
1770    ///
1771    /// # Safety
1772    ///
1773    /// See the safety documentation of `vmctx_plus_offset_raw`.
1774    unsafe fn vmctx_plus_offset_mut<T: VmSafe>(
1775        self: Pin<&mut Self>,
1776        offset: impl Into<u32>,
1777    ) -> &mut T {
1778        // SAFETY: this method has the same safety requirements as
1779        // `vmctx_plus_offset_raw`.
1780        unsafe { self.vmctx_plus_offset_raw(offset).as_mut() }
1781    }
1782}
1783
1784impl<T: InstanceLayout> OwnedInstance<T> {
1785    /// Allocates a new `OwnedInstance` and places `instance` inside of it.
1786    ///
1787    /// This will `instance`
1788    pub(super) fn new(mut instance: T) -> OwnedInstance<T> {
1789        let layout = instance.layout();
1790        debug_assert!(layout.size() >= size_of_val(&instance));
1791        debug_assert!(layout.align() >= align_of_val(&instance));
1792
1793        // SAFETY: it's up to us to assert that `layout` has a non-zero size,
1794        // which is asserted here.
1795        let ptr = unsafe {
1796            assert!(layout.size() > 0);
1797            if T::INIT_ZEROED {
1798                alloc::alloc::alloc_zeroed(layout)
1799            } else {
1800                alloc::alloc::alloc(layout)
1801            }
1802        };
1803        if ptr.is_null() {
1804            alloc::alloc::handle_alloc_error(layout);
1805        }
1806        let instance_ptr = NonNull::new(ptr.cast::<T>()).unwrap();
1807
1808        // SAFETY: it's part of the unsafe contract of `InstanceLayout` that the
1809        // `add` here is appropriate for the layout allocated.
1810        let vmctx_self_reference = unsafe { instance_ptr.add(1).cast() };
1811        instance.owned_vmctx_mut().vmctx_self_reference = vmctx_self_reference.into();
1812
1813        // SAFETY: we allocated above and it's an unsafe contract of
1814        // `InstanceLayout` that the layout is suitable for writing the
1815        // instance.
1816        unsafe {
1817            instance_ptr.write(instance);
1818        }
1819
1820        let ret = OwnedInstance {
1821            instance: SendSyncPtr::new(instance_ptr),
1822            _marker: marker::PhantomData,
1823        };
1824
1825        // Double-check various vmctx calculations are correct.
1826        debug_assert_eq!(
1827            vmctx_self_reference.addr(),
1828            // SAFETY: `InstanceLayout` should guarantee it's safe to add 1 to
1829            // the last field to get a pointer to 1-byte-past-the-end of an
1830            // object, which should be valid.
1831            unsafe { NonNull::from(ret.get().owned_vmctx()).add(1).addr() }
1832        );
1833        debug_assert_eq!(vmctx_self_reference.addr(), ret.get().vmctx().addr());
1834
1835        ret
1836    }
1837
1838    /// Gets the raw underlying `&Instance` from this handle.
1839    pub fn get(&self) -> &T {
1840        // SAFETY: this is an owned instance handle that retains exclusive
1841        // ownership of the `Instance` inside. With `&self` given we know
1842        // this pointer is valid valid and the returned lifetime is connected
1843        // to `self` so that should also be valid.
1844        unsafe { self.instance.as_non_null().as_ref() }
1845    }
1846
1847    /// Same as [`Self::get`] except for mutability.
1848    pub fn get_mut(&mut self) -> Pin<&mut T> {
1849        // SAFETY: The lifetime concerns here are the same as `get` above.
1850        // Otherwise `new_unchecked` is used here to uphold the contract that
1851        // instances are always pinned in memory.
1852        unsafe { Pin::new_unchecked(self.instance.as_non_null().as_mut()) }
1853    }
1854}
1855
1856impl<T: InstanceLayout> Drop for OwnedInstance<T> {
1857    fn drop(&mut self) {
1858        unsafe {
1859            let layout = self.get().layout();
1860            ptr::drop_in_place(self.instance.as_ptr());
1861            alloc::alloc::dealloc(self.instance.as_ptr().cast(), layout);
1862        }
1863    }
1864}