linera_wasmer/externals/
mod.rs

1pub(crate) mod function;
2mod global;
3pub(crate) mod memory;
4mod memory_view;
5mod table;
6
7pub use self::function::{Function, HostFunction};
8pub use self::global::Global;
9pub use self::memory::{Memory, MemoryLocation, SharedMemory};
10pub use self::memory_view::MemoryView;
11pub use self::table::Table;
12
13use crate::exports::{ExportError, Exportable};
14use crate::ExternType;
15use std::fmt;
16
17#[cfg(feature = "js")]
18use crate::js::vm::VMExtern;
19#[cfg(feature = "jsc")]
20use crate::jsc::vm::VMExtern;
21#[cfg(feature = "sys")]
22use wasmer_vm::VMExtern;
23
24use crate::store::{AsStoreMut, AsStoreRef};
25
26/// An `Extern` is the runtime representation of an entity that
27/// can be imported or exported.
28///
29/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#external-values>
30#[derive(Clone, PartialEq, Eq)]
31#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
32pub enum Extern {
33    /// A external [`Function`].
34    Function(Function),
35    /// A external [`Global`].
36    Global(Global),
37    /// A external [`Table`].
38    Table(Table),
39    /// A external [`Memory`].
40    Memory(Memory),
41}
42
43impl Extern {
44    /// Return the underlying type of the inner `Extern`.
45    pub fn ty(&self, store: &impl AsStoreRef) -> ExternType {
46        match self {
47            Self::Function(ft) => ExternType::Function(ft.ty(store)),
48            Self::Memory(ft) => ExternType::Memory(ft.ty(store)),
49            Self::Table(tt) => ExternType::Table(tt.ty(store)),
50            Self::Global(gt) => ExternType::Global(gt.ty(store)),
51        }
52    }
53
54    /// Create an `Extern` from an `wasmer_engine::Export`.
55    pub fn from_vm_extern(store: &mut impl AsStoreMut, vm_extern: VMExtern) -> Self {
56        match vm_extern {
57            VMExtern::Function(f) => Self::Function(Function::from_vm_extern(store, f)),
58            VMExtern::Memory(m) => Self::Memory(Memory::from_vm_extern(store, m)),
59            VMExtern::Global(g) => Self::Global(Global::from_vm_extern(store, g)),
60            VMExtern::Table(t) => Self::Table(Table::from_vm_extern(store, t)),
61        }
62    }
63
64    /// Checks whether this `Extern` can be used with the given context.
65    pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
66        match self {
67            Self::Function(f) => f.is_from_store(store),
68            Self::Global(g) => g.is_from_store(store),
69            Self::Memory(m) => m.is_from_store(store),
70            Self::Table(t) => t.is_from_store(store),
71        }
72    }
73
74    /// To `VMExtern`.
75    pub fn to_vm_extern(&self) -> VMExtern {
76        match self {
77            Self::Function(f) => f.to_vm_extern(),
78            Self::Global(g) => g.to_vm_extern(),
79            Self::Memory(m) => m.to_vm_extern(),
80            Self::Table(t) => t.to_vm_extern(),
81        }
82    }
83}
84
85impl<'a> Exportable<'a> for Extern {
86    fn get_self_from_extern(_extern: &'a Self) -> Result<&'a Self, ExportError> {
87        // Since this is already an extern, we can just return it.
88        Ok(_extern)
89    }
90}
91
92impl fmt::Debug for Extern {
93    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94        write!(
95            f,
96            "{}",
97            match self {
98                Self::Function(_) => "Function(...)",
99                Self::Global(_) => "Global(...)",
100                Self::Memory(_) => "Memory(...)",
101                Self::Table(_) => "Table(...)",
102            }
103        )
104    }
105}
106
107impl From<Function> for Extern {
108    fn from(r: Function) -> Self {
109        Self::Function(r)
110    }
111}
112
113impl From<Global> for Extern {
114    fn from(r: Global) -> Self {
115        Self::Global(r)
116    }
117}
118
119impl From<Memory> for Extern {
120    fn from(r: Memory) -> Self {
121        Self::Memory(r)
122    }
123}
124
125impl From<Table> for Extern {
126    fn from(r: Table) -> Self {
127        Self::Table(r)
128    }
129}