radix_wasmi/
external.rs

1use super::{Func, Global, Memory, Table};
2use crate::{AsContext, FuncType, GlobalType, MemoryType, TableType};
3
4/// An external item to a WebAssembly module.
5///
6/// This is returned from [`Instance::exports`](crate::Instance::exports).
7#[derive(Debug, Copy, Clone)]
8pub enum Extern {
9    /// A WebAssembly global which acts like a [`Cell<T>`] of sorts, supporting `get` and `set` operations.
10    ///
11    /// [`Cell<T>`]: https://doc.rust-lang.org/core/cell/struct.Cell.html
12    Global(Global),
13    /// A WebAssembly table which is an array of funtion references.
14    Table(Table),
15    /// A WebAssembly linear memory.
16    Memory(Memory),
17    /// A WebAssembly function which can be called.
18    Func(Func),
19}
20
21impl From<Global> for Extern {
22    fn from(global: Global) -> Self {
23        Self::Global(global)
24    }
25}
26
27impl From<Table> for Extern {
28    fn from(table: Table) -> Self {
29        Self::Table(table)
30    }
31}
32
33impl From<Memory> for Extern {
34    fn from(memory: Memory) -> Self {
35        Self::Memory(memory)
36    }
37}
38
39impl From<Func> for Extern {
40    fn from(func: Func) -> Self {
41        Self::Func(func)
42    }
43}
44
45impl Extern {
46    /// Returns the underlying global variable if `self` is a global variable.
47    ///
48    /// Returns `None` otherwise.
49    pub fn into_global(self) -> Option<Global> {
50        if let Self::Global(global) = self {
51            return Some(global);
52        }
53        None
54    }
55
56    /// Returns the underlying table if `self` is a table.
57    ///
58    /// Returns `None` otherwise.
59    pub fn into_table(self) -> Option<Table> {
60        if let Self::Table(table) = self {
61            return Some(table);
62        }
63        None
64    }
65
66    /// Returns the underlying linear memory if `self` is a linear memory.
67    ///
68    /// Returns `None` otherwise.
69    pub fn into_memory(self) -> Option<Memory> {
70        if let Self::Memory(memory) = self {
71            return Some(memory);
72        }
73        None
74    }
75
76    /// Returns the underlying function if `self` is a function.
77    ///
78    /// Returns `None` otherwise.
79    pub fn into_func(self) -> Option<Func> {
80        if let Self::Func(func) = self {
81            return Some(func);
82        }
83        None
84    }
85
86    /// Returns the type associated with this [`Extern`].
87    ///
88    /// # Panics
89    ///
90    /// If this item does not belong to the `store` provided.
91    pub fn ty(&self, ctx: impl AsContext) -> ExternType {
92        match self {
93            Extern::Global(global) => global.ty(ctx).into(),
94            Extern::Table(table) => table.ty(ctx).into(),
95            Extern::Memory(memory) => memory.ty(ctx).into(),
96            Extern::Func(func) => func.ty(ctx).into(),
97        }
98    }
99}
100
101/// The type of an [`Extern`] item.
102///
103/// A list of all possible types which can be externally referenced from a WebAssembly module.
104#[derive(Debug, Clone)]
105pub enum ExternType {
106    /// The type of an [`Extern::Global`].
107    Global(GlobalType),
108    /// The type of an [`Extern::Table`].
109    Table(TableType),
110    /// The type of an [`Extern::Memory`].
111    Memory(MemoryType),
112    /// The type of an [`Extern::Func`].
113    Func(FuncType),
114}
115
116impl From<GlobalType> for ExternType {
117    fn from(global: GlobalType) -> Self {
118        Self::Global(global)
119    }
120}
121
122impl From<TableType> for ExternType {
123    fn from(table: TableType) -> Self {
124        Self::Table(table)
125    }
126}
127
128impl From<MemoryType> for ExternType {
129    fn from(memory: MemoryType) -> Self {
130        Self::Memory(memory)
131    }
132}
133
134impl From<FuncType> for ExternType {
135    fn from(func: FuncType) -> Self {
136        Self::Func(func)
137    }
138}
139
140impl ExternType {
141    /// Returns the underlying [`GlobalType`] or `None` if it is of a different type.
142    pub fn global(&self) -> Option<&GlobalType> {
143        match self {
144            Self::Global(ty) => Some(ty),
145            _ => None,
146        }
147    }
148
149    /// Returns the underlying [`TableType`] or `None` if it is of a different type.
150    pub fn table(&self) -> Option<&TableType> {
151        match self {
152            Self::Table(ty) => Some(ty),
153            _ => None,
154        }
155    }
156
157    /// Returns the underlying [`MemoryType`] or `None` if it is of a different type.
158    pub fn memory(&self) -> Option<&MemoryType> {
159        match self {
160            Self::Memory(ty) => Some(ty),
161            _ => None,
162        }
163    }
164
165    /// Returns the underlying [`FuncType`] or `None` if it is of a different type.
166    pub fn func(&self) -> Option<&FuncType> {
167        match self {
168            Self::Func(ty) => Some(ty),
169            _ => None,
170        }
171    }
172}