wasm/execution/checked/
interop.rs1use crate::{
2 addrs::FuncAddr,
3 checked::{Stored, StoredRef, StoredValue},
4 interop::RefExtern,
5 value::{ValueTypeMismatchError, F32, F64},
6 NumType, RefType, ValType,
7};
8
9use alloc::{fmt::Debug, vec, vec::Vec};
10
11pub trait StoredInteropValue
13where
14 Self: Copy + Debug + PartialEq + TryFrom<StoredValue, Error = ValueTypeMismatchError>,
15 StoredValue: From<Self>,
16{
17 const TY: ValType;
18}
19
20impl StoredInteropValue for u32 {
21 const TY: ValType = ValType::NumType(NumType::I32);
22}
23
24impl StoredInteropValue for i32 {
25 const TY: ValType = ValType::NumType(NumType::I32);
26}
27
28impl StoredInteropValue for u64 {
29 const TY: ValType = ValType::NumType(NumType::I64);
30}
31
32impl StoredInteropValue for i64 {
33 const TY: ValType = ValType::NumType(NumType::I64);
34}
35
36impl StoredInteropValue for f32 {
37 const TY: ValType = ValType::NumType(NumType::F32);
38}
39
40impl StoredInteropValue for f64 {
41 const TY: ValType = ValType::NumType(NumType::F64);
42}
43
44impl StoredInteropValue for [u8; 16] {
45 const TY: ValType = ValType::VecType;
46}
47
48impl StoredInteropValue for StoredRefFunc {
49 const TY: ValType = ValType::RefType(RefType::FuncRef);
50}
51
52impl StoredInteropValue for RefExtern {
53 const TY: ValType = ValType::RefType(RefType::ExternRef);
54}
55
56impl From<f32> for StoredValue {
57 fn from(value: f32) -> Self {
58 F32(value).into()
59 }
60}
61
62impl TryFrom<StoredValue> for f32 {
63 type Error = ValueTypeMismatchError;
64
65 fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
66 F32::try_from(value).map(|f| f.0)
67 }
68}
69
70impl From<f64> for StoredValue {
71 fn from(value: f64) -> Self {
72 F64(value).into()
73 }
74}
75
76impl TryFrom<StoredValue> for f64 {
77 type Error = ValueTypeMismatchError;
78
79 fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
80 F64::try_from(value).map(|f| f.0)
81 }
82}
83
84#[derive(Debug, Copy, Clone, PartialEq)]
85pub struct StoredRefFunc(pub Option<Stored<FuncAddr>>);
86
87impl From<StoredRefFunc> for StoredValue {
88 fn from(value: StoredRefFunc) -> Self {
89 match value.0 {
90 Some(func_addr) => StoredValue::Ref(StoredRef::Func(func_addr)),
91 None => StoredValue::Ref(StoredRef::Null(RefType::FuncRef)),
92 }
93 }
94}
95impl TryFrom<StoredValue> for StoredRefFunc {
96 type Error = ValueTypeMismatchError;
97
98 fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
99 match StoredRef::try_from(value)? {
100 StoredRef::Func(func_addr) => Ok(Self(Some(func_addr))),
101 StoredRef::Null(RefType::FuncRef) => Ok(Self(None)),
102 _ => Err(ValueTypeMismatchError),
103 }
104 }
105}
106
107impl From<RefExtern> for StoredValue {
108 fn from(value: RefExtern) -> Self {
109 match value.0 {
110 Some(extern_addr) => StoredValue::Ref(StoredRef::Extern(extern_addr)),
111 None => StoredValue::Ref(StoredRef::Null(RefType::ExternRef)),
112 }
113 }
114}
115
116impl TryFrom<StoredValue> for RefExtern {
117 type Error = ValueTypeMismatchError;
118
119 fn try_from(value: StoredValue) -> Result<Self, Self::Error> {
120 match value {
121 StoredValue::Ref(StoredRef::Extern(extern_addr)) => Ok(Self(Some(extern_addr))),
122 StoredValue::Ref(StoredRef::Null(RefType::ExternRef)) => Ok(Self(None)),
123 _ => Err(ValueTypeMismatchError),
124 }
125 }
126}
127
128pub trait StoredInteropValueList: Debug + Copy {
130 const TYS: &'static [ValType];
131
132 fn into_values(self) -> Vec<StoredValue>;
133
134 fn try_from_values(
135 values: impl ExactSizeIterator<Item = StoredValue>,
136 ) -> Result<Self, ValueTypeMismatchError>;
137}
138
139impl StoredInteropValueList for () {
140 const TYS: &'static [ValType] = &[];
141
142 fn into_values(self) -> Vec<StoredValue> {
143 Vec::new()
144 }
145
146 fn try_from_values(
147 values: impl ExactSizeIterator<Item = StoredValue>,
148 ) -> Result<Self, ValueTypeMismatchError> {
149 if values.len() != 0 {
150 return Err(ValueTypeMismatchError);
151 }
152
153 Ok(())
154 }
155}
156
157impl<A> StoredInteropValueList for A
158where
159 A: StoredInteropValue,
160 StoredValue: From<A>,
161{
162 const TYS: &'static [ValType] = &[A::TY];
163
164 fn into_values(self) -> Vec<StoredValue> {
165 vec![self.into()]
166 }
167
168 fn try_from_values(
169 mut values: impl ExactSizeIterator<Item = StoredValue>,
170 ) -> Result<Self, ValueTypeMismatchError> {
171 if values.len() != Self::TYS.len() {
172 return Err(ValueTypeMismatchError);
173 }
174
175 A::try_from(values.next().unwrap())
176 }
177}
178
179impl<A> StoredInteropValueList for (A,)
180where
181 A: StoredInteropValue,
182 StoredValue: From<A>,
183{
184 const TYS: &'static [ValType] = &[A::TY];
185
186 fn into_values(self) -> Vec<StoredValue> {
187 vec![self.0.into()]
188 }
189
190 fn try_from_values(
191 mut values: impl ExactSizeIterator<Item = StoredValue>,
192 ) -> Result<Self, ValueTypeMismatchError> {
193 if values.len() != Self::TYS.len() {
194 return Err(ValueTypeMismatchError);
195 }
196
197 Ok((A::try_from(values.next().unwrap())?,))
198 }
199}
200
201impl<A, B> StoredInteropValueList for (A, B)
202where
203 A: StoredInteropValue,
204 B: StoredInteropValue,
205 StoredValue: From<A> + From<B>,
206{
207 const TYS: &'static [ValType] = &[A::TY, B::TY];
208
209 fn into_values(self) -> Vec<StoredValue> {
210 vec![self.0.into(), self.1.into()]
211 }
212
213 fn try_from_values(
214 mut values: impl ExactSizeIterator<Item = StoredValue>,
215 ) -> Result<Self, ValueTypeMismatchError> {
216 if values.len() != Self::TYS.len() {
217 return Err(ValueTypeMismatchError);
218 }
219
220 Ok((
221 A::try_from(values.next().unwrap())?,
222 B::try_from(values.next().unwrap())?,
223 ))
224 }
225}
226
227impl<A, B, C> StoredInteropValueList for (A, B, C)
228where
229 A: StoredInteropValue,
230 B: StoredInteropValue,
231 C: StoredInteropValue,
232 StoredValue: From<A> + From<B> + From<C>,
233{
234 const TYS: &'static [ValType] = &[A::TY, B::TY, C::TY];
235
236 fn into_values(self) -> Vec<StoredValue> {
237 vec![self.0.into(), self.1.into(), self.2.into()]
238 }
239
240 fn try_from_values(
241 mut values: impl ExactSizeIterator<Item = StoredValue>,
242 ) -> Result<Self, ValueTypeMismatchError> {
243 if values.len() != Self::TYS.len() {
244 return Err(ValueTypeMismatchError);
245 }
246
247 Ok((
248 A::try_from(values.next().unwrap())?,
249 B::try_from(values.next().unwrap())?,
250 C::try_from(values.next().unwrap())?,
251 ))
252 }
253}