wasmer/entities/external/
mod.rs

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