near_vm_vm/export/
vmmemory.rs

1use crate::instance::WeakOrStrongInstanceRef;
2use crate::memory::{LinearMemory, MemoryStyle};
3use near_vm_types::MemoryType;
4use std::sync::Arc;
5
6/// A memory export value.
7#[derive(Debug, Clone)]
8pub struct VMMemory {
9    /// Pointer to the containing `Memory`.
10    from: Arc<LinearMemory>,
11
12    /// A “reference” to the instance through the
13    /// `InstanceRef`. `None` if it is a host memory.
14    pub instance_ref: Option<WeakOrStrongInstanceRef>,
15}
16
17/// # Safety
18/// This is correct because there is no non-threadsafe logic directly in this type;
19/// correct use of the raw memory from multiple threads via `definition` requires `unsafe`
20/// and is the responsibility of the user of this type.
21unsafe impl Send for VMMemory {}
22
23/// # Safety
24/// This is correct because the values directly in `definition` should be considered immutable
25/// and the type is both `Send` and `Clone` (thus marking it `Sync` adds no new behavior, it
26/// only makes this type easier to use)
27unsafe impl Sync for VMMemory {}
28
29impl VMMemory {
30    /// Create a new `VMMemory`
31    pub fn new(from: Arc<LinearMemory>, instance_ref: Option<WeakOrStrongInstanceRef>) -> Self {
32        Self { from, instance_ref }
33    }
34
35    /// Retrieve the memory this export is having
36    pub fn from(&self) -> &Arc<LinearMemory> {
37        &self.from
38    }
39
40    /// Get the type for this exported memory
41    pub fn ty(&self) -> MemoryType {
42        self.from.ty()
43    }
44
45    /// Get the style for this exported memory
46    pub fn style(&self) -> &MemoryStyle {
47        self.from.style()
48    }
49
50    /// Returns whether or not the two `VMMemory`s refer to the same Memory.
51    pub fn same(&self, other: &Self) -> bool {
52        Arc::ptr_eq(&self.from, &other.from)
53    }
54
55    /// Converts the stored instance ref into a strong `InstanceRef` if it is weak.
56    /// Returns None if it cannot be upgraded.
57    pub fn upgrade_instance_ref(&mut self) -> Option<()> {
58        if let Some(ref mut ir) = self.instance_ref {
59            *ir = ir.upgrade()?;
60        }
61        Some(())
62    }
63}