1use crate::{
2 decode::{Decode, DecodeError, Decoder},
3 func::{Func, FuncType, UnguardedFunc},
4 global::{Global, GlobalType, UnguardedGlobal},
5 mem::{Mem, MemType, UnguardedMem},
6 store::{Store, StoreId},
7 table::{Table, TableType, UnguardedTable},
8};
9
10#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
12pub enum ExternVal {
13 Func(Func),
14 Table(Table),
15 Memory(Mem),
16 Global(Global),
17}
18
19impl ExternVal {
20 pub fn type_(self, store: &Store) -> ExternType {
22 match self {
23 Self::Func(func) => ExternType::Func(func.type_(store).clone()),
24 Self::Table(table) => ExternType::Table(table.type_(store)),
25 Self::Memory(mem) => ExternType::Mem(mem.type_(store)),
26 Self::Global(global) => ExternType::Global(global.type_(store)),
27 }
28 }
29
30 pub fn is_func(self) -> bool {
32 self.to_func().is_some()
33 }
34
35 pub fn is_table(self) -> bool {
37 self.to_table().is_some()
38 }
39
40 pub fn is_mem(self) -> bool {
42 self.to_mem().is_some()
43 }
44
45 pub fn is_global(self) -> bool {
47 self.to_global().is_some()
48 }
49
50 pub fn to_func(self) -> Option<Func> {
52 match self {
53 Self::Func(func) => Some(func),
54 _ => None,
55 }
56 }
57
58 pub fn to_table(self) -> Option<Table> {
60 match self {
61 Self::Table(table) => Some(table),
62 _ => None,
63 }
64 }
65
66 pub fn to_mem(self) -> Option<Mem> {
68 match self {
69 Self::Memory(mem) => Some(mem),
70 _ => None,
71 }
72 }
73
74 pub fn to_global(self) -> Option<Global> {
76 match self {
77 Self::Global(global) => Some(global),
78 _ => None,
79 }
80 }
81
82 pub(crate) unsafe fn from_unguarded(val: UnguardedExternVal, store_id: StoreId) -> Self {
89 match val {
90 UnguardedExternVal::Func(func) => Func::from_unguarded(func, store_id).into(),
91 UnguardedExternVal::Table(table) => Table::from_unguarded(table, store_id).into(),
92 UnguardedExternVal::Mem(mem) => Mem::from_unguarded(mem, store_id).into(),
93 UnguardedExternVal::Global(global) => Global::from_unguarded(global, store_id).into(),
94 }
95 }
96
97 pub(crate) fn to_unguarded(self, store_id: StoreId) -> UnguardedExternVal {
104 match self {
105 Self::Func(func) => func.to_unguarded(store_id).into(),
106 Self::Table(table) => table.to_unguarded(store_id).into(),
107 Self::Memory(mem) => mem.to_unguarded(store_id).into(),
108 Self::Global(global) => global.to_unguarded(store_id).into(),
109 }
110 }
111}
112
113impl From<Func> for ExternVal {
114 fn from(func: Func) -> Self {
115 Self::Func(func)
116 }
117}
118
119impl From<Table> for ExternVal {
120 fn from(table: Table) -> Self {
121 Self::Table(table)
122 }
123}
124
125impl From<Mem> for ExternVal {
126 fn from(memory: Mem) -> Self {
127 Self::Memory(memory)
128 }
129}
130
131impl From<Global> for ExternVal {
132 fn from(global: Global) -> Self {
133 Self::Global(global)
134 }
135}
136
137#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
138pub(crate) enum UnguardedExternVal {
139 Func(UnguardedFunc),
140 Table(UnguardedTable),
141 Mem(UnguardedMem),
142 Global(UnguardedGlobal),
143}
144
145impl From<UnguardedFunc> for UnguardedExternVal {
146 fn from(func: UnguardedFunc) -> Self {
147 Self::Func(func)
148 }
149}
150
151impl From<UnguardedTable> for UnguardedExternVal {
152 fn from(table: UnguardedTable) -> Self {
153 Self::Table(table)
154 }
155}
156
157impl From<UnguardedMem> for UnguardedExternVal {
158 fn from(mem: UnguardedMem) -> Self {
159 Self::Mem(mem)
160 }
161}
162
163impl From<UnguardedGlobal> for UnguardedExternVal {
164 fn from(global: UnguardedGlobal) -> Self {
165 Self::Global(global)
166 }
167}
168
169#[derive(Clone, Copy, Debug)]
174pub(crate) enum ExternValDesc {
175 Func(u32),
176 Table(u32),
177 Memory(u32),
178 Global(u32),
179}
180
181impl Decode for ExternValDesc {
182 fn decode(decoder: &mut Decoder<'_>) -> Result<Self, DecodeError> {
183 match decoder.read_byte()? {
184 0x00 => Ok(Self::Func(decoder.decode()?)),
185 0x01 => Ok(Self::Table(decoder.decode()?)),
186 0x02 => Ok(Self::Memory(decoder.decode()?)),
187 0x03 => Ok(Self::Global(decoder.decode()?)),
188 _ => Err(DecodeError::new("malformed external value descriptor")),
189 }
190 }
191}
192
193#[derive(Clone, Debug, Eq, Hash, PartialEq)]
195pub enum ExternType {
196 Func(FuncType),
197 Table(TableType),
198 Mem(MemType),
199 Global(GlobalType),
200}
201
202impl ExternType {
203 pub fn is_func(self) -> bool {
205 self.to_func().is_some()
206 }
207
208 pub fn is_table(self) -> bool {
210 self.to_table().is_some()
211 }
212
213 pub fn is_mem(self) -> bool {
215 self.to_mem().is_some()
216 }
217
218 pub fn is_global(self) -> bool {
220 self.to_global().is_some()
221 }
222
223 pub fn to_func(self) -> Option<FuncType> {
225 match self {
226 Self::Func(func_type) => Some(func_type),
227 _ => None,
228 }
229 }
230
231 pub fn to_table(self) -> Option<TableType> {
233 match self {
234 Self::Table(table_type) => Some(table_type),
235 _ => None,
236 }
237 }
238
239 pub fn to_mem(self) -> Option<MemType> {
241 match self {
242 Self::Mem(mem_type) => Some(mem_type),
243 _ => None,
244 }
245 }
246
247 pub fn to_global(self) -> Option<GlobalType> {
249 match self {
250 Self::Global(global_type) => Some(global_type),
251 _ => None,
252 }
253 }
254}
255
256impl From<FuncType> for ExternType {
257 fn from(type_: FuncType) -> Self {
258 Self::Func(type_)
259 }
260}
261
262impl From<TableType> for ExternType {
263 fn from(type_: TableType) -> Self {
264 Self::Table(type_)
265 }
266}
267
268impl From<MemType> for ExternType {
269 fn from(type_: MemType) -> Self {
270 Self::Mem(type_)
271 }
272}
273
274impl From<GlobalType> for ExternType {
275 fn from(type_: GlobalType) -> Self {
276 Self::Global(type_)
277 }
278}
279
280#[derive(Clone, Copy, Debug)]
285pub(crate) enum ExternTypeDesc {
286 Func(u32),
287 Table(TableType),
288 Memory(MemType),
289 Global(GlobalType),
290}
291
292impl Decode for ExternTypeDesc {
293 fn decode(decoder: &mut Decoder<'_>) -> Result<Self, DecodeError> {
294 match decoder.read_byte()? {
295 0x00 => Ok(ExternTypeDesc::Func(decoder.decode()?)),
296 0x01 => Ok(ExternTypeDesc::Table(decoder.decode()?)),
297 0x02 => Ok(ExternTypeDesc::Memory(decoder.decode()?)),
298 0x03 => Ok(ExternTypeDesc::Global(decoder.decode()?)),
299 _ => Err(DecodeError::new("malformed external type descriptor"))?,
300 }
301 }
302}