1use crate::{
2 decode::{Decode, DecodeError, Decoder},
3 extern_ref::{ExternRef, UnguardedExternRef},
4 func_ref::{FuncRef, UnguardedFuncRef},
5 store::StoreId,
6};
7
8#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
10pub enum Ref {
11 FuncRef(FuncRef),
12 ExternRef(ExternRef),
13}
14
15impl Ref {
16 pub fn null(type_: RefType) -> Self {
18 match type_ {
19 RefType::FuncRef => FuncRef::null().into(),
20 RefType::ExternRef => ExternRef::null().into(),
21 }
22 }
23
24 pub fn type_(self) -> RefType {
26 match self {
27 Ref::FuncRef(_) => RefType::FuncRef,
28 Ref::ExternRef(_) => RefType::ExternRef,
29 }
30 }
31
32 pub fn is_func_ref(self) -> bool {
34 self.to_func_ref().is_some()
35 }
36
37 pub fn is_extern_ref(self) -> bool {
39 self.to_extern_ref().is_some()
40 }
41
42 pub fn to_func_ref(self) -> Option<FuncRef> {
44 match self {
45 Ref::FuncRef(val) => Some(val),
46 _ => None,
47 }
48 }
49
50 pub fn to_extern_ref(self) -> Option<ExternRef> {
52 match self {
53 Ref::ExternRef(val) => Some(val),
54 _ => None,
55 }
56 }
57
58 pub(crate) unsafe fn from_unguarded(val: UnguardedRef, store_id: StoreId) -> Self {
64 match val {
65 UnguardedRef::FuncRef(val) => FuncRef::from_unguarded(val, store_id).into(),
66 UnguardedRef::ExternRef(val) => ExternRef::from_unguarded(val, store_id).into(),
67 }
68 }
69
70 pub(crate) fn to_unguarded(self, store_id: StoreId) -> UnguardedRef {
76 match self {
77 Ref::FuncRef(val) => val.to_unguarded(store_id).into(),
78 Ref::ExternRef(val) => val.to_unguarded(store_id).into(),
79 }
80 }
81}
82
83impl From<FuncRef> for Ref {
84 fn from(val: FuncRef) -> Self {
85 Ref::FuncRef(val)
86 }
87}
88
89impl From<ExternRef> for Ref {
90 fn from(val: ExternRef) -> Self {
91 Ref::ExternRef(val)
92 }
93}
94
95#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
97pub(crate) enum UnguardedRef {
98 FuncRef(UnguardedFuncRef),
99 ExternRef(UnguardedExternRef),
100}
101
102impl From<UnguardedFuncRef> for UnguardedRef {
103 fn from(val: UnguardedFuncRef) -> Self {
104 UnguardedRef::FuncRef(val)
105 }
106}
107
108impl From<UnguardedExternRef> for UnguardedRef {
109 fn from(val: UnguardedExternRef) -> Self {
110 UnguardedRef::ExternRef(val)
111 }
112}
113
114#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
116pub enum RefType {
117 FuncRef,
118 ExternRef,
119}
120
121impl Decode for RefType {
122 fn decode(decoder: &mut Decoder<'_>) -> Result<Self, DecodeError> {
123 match decoder.read_byte()? {
124 0x6F => Ok(Self::ExternRef),
125 0x70 => Ok(Self::FuncRef),
126 _ => Err(DecodeError::new("malformed reference type")),
127 }
128 }
129}