1use crate::{FuncType, GlobalType, MemoryType, TableType, ValType};
17use ::core::ops::Range;
18
19pub trait WasmFuncType {
21 fn len_inputs(&self) -> usize;
23 fn len_outputs(&self) -> usize;
25 fn input_at(&self, at: u32) -> Option<ValType>;
32 fn output_at(&self, at: u32) -> Option<ValType>;
39
40 fn inputs(&self) -> WasmFuncTypeInputs<'_, Self>
42 where
43 Self: Sized,
44 {
45 WasmFuncTypeInputs {
46 func_type: self,
47 range: 0..self.len_inputs() as u32,
48 }
49 }
50
51 fn outputs(&self) -> WasmFuncTypeOutputs<'_, Self>
53 where
54 Self: Sized,
55 {
56 WasmFuncTypeOutputs {
57 func_type: self,
58 range: 0..self.len_outputs() as u32,
59 }
60 }
61}
62
63impl<T> WasmFuncType for &'_ T
64where
65 T: ?Sized + WasmFuncType,
66{
67 fn len_inputs(&self) -> usize {
68 T::len_inputs(self)
69 }
70 fn len_outputs(&self) -> usize {
71 T::len_outputs(self)
72 }
73 fn input_at(&self, at: u32) -> Option<ValType> {
74 T::input_at(self, at)
75 }
76 fn output_at(&self, at: u32) -> Option<ValType> {
77 T::output_at(self, at)
78 }
79}
80
81pub struct WasmFuncTypeInputs<'a, T> {
83 func_type: &'a T,
85 range: Range<u32>,
87}
88
89impl<T> Iterator for WasmFuncTypeInputs<'_, T>
90where
91 T: WasmFuncType,
92{
93 type Item = crate::ValType;
94
95 fn next(&mut self) -> Option<Self::Item> {
96 self.range
97 .next()
98 .map(|i| self.func_type.input_at(i).unwrap())
99 }
100
101 fn size_hint(&self) -> (usize, Option<usize>) {
102 self.range.size_hint()
103 }
104}
105
106impl<T> DoubleEndedIterator for WasmFuncTypeInputs<'_, T>
107where
108 T: WasmFuncType,
109{
110 fn next_back(&mut self) -> Option<Self::Item> {
111 self.range
112 .next_back()
113 .map(|i| self.func_type.input_at(i).unwrap())
114 }
115}
116
117impl<T> ExactSizeIterator for WasmFuncTypeInputs<'_, T>
118where
119 T: WasmFuncType,
120{
121 fn len(&self) -> usize {
122 self.range.len()
123 }
124}
125
126impl<'a, T> Clone for WasmFuncTypeInputs<'a, T> {
127 fn clone(&self) -> WasmFuncTypeInputs<'a, T> {
128 WasmFuncTypeInputs {
129 func_type: self.func_type,
130 range: self.range.clone(),
131 }
132 }
133}
134
135pub struct WasmFuncTypeOutputs<'a, T> {
137 func_type: &'a T,
139 range: Range<u32>,
141}
142
143impl<T> Iterator for WasmFuncTypeOutputs<'_, T>
144where
145 T: WasmFuncType,
146{
147 type Item = crate::ValType;
148
149 fn next(&mut self) -> Option<Self::Item> {
150 self.range
151 .next()
152 .map(|i| self.func_type.output_at(i).unwrap())
153 }
154
155 fn size_hint(&self) -> (usize, Option<usize>) {
156 self.range.size_hint()
157 }
158}
159
160impl<T> DoubleEndedIterator for WasmFuncTypeOutputs<'_, T>
161where
162 T: WasmFuncType,
163{
164 fn next_back(&mut self) -> Option<Self::Item> {
165 self.range
166 .next_back()
167 .map(|i| self.func_type.output_at(i).unwrap())
168 }
169}
170
171impl<T> ExactSizeIterator for WasmFuncTypeOutputs<'_, T>
172where
173 T: WasmFuncType,
174{
175 fn len(&self) -> usize {
176 self.range.len()
177 }
178}
179
180impl<'a, T> Clone for WasmFuncTypeOutputs<'a, T> {
181 fn clone(&self) -> WasmFuncTypeOutputs<'a, T> {
182 WasmFuncTypeOutputs {
183 func_type: self.func_type,
184 range: self.range.clone(),
185 }
186 }
187}
188
189pub trait WasmModuleResources {
198 type FuncType: WasmFuncType;
200
201 fn table_at(&self, at: u32) -> Option<TableType>;
203 fn memory_at(&self, at: u32) -> Option<MemoryType>;
205 fn tag_at(&self, at: u32) -> Option<&Self::FuncType>;
207 fn global_at(&self, at: u32) -> Option<GlobalType>;
209 fn func_type_at(&self, type_idx: u32) -> Option<&Self::FuncType>;
211 fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType>;
213 fn element_type_at(&self, at: u32) -> Option<ValType>;
215
216 fn element_count(&self) -> u32;
218 fn data_count(&self) -> Option<u32>;
220 fn is_function_referenced(&self, idx: u32) -> bool;
223}
224
225impl<T> WasmModuleResources for &'_ T
226where
227 T: ?Sized + WasmModuleResources,
228{
229 type FuncType = T::FuncType;
230
231 fn table_at(&self, at: u32) -> Option<TableType> {
232 T::table_at(self, at)
233 }
234 fn memory_at(&self, at: u32) -> Option<MemoryType> {
235 T::memory_at(self, at)
236 }
237 fn tag_at(&self, at: u32) -> Option<&Self::FuncType> {
238 T::tag_at(self, at)
239 }
240 fn global_at(&self, at: u32) -> Option<GlobalType> {
241 T::global_at(self, at)
242 }
243 fn func_type_at(&self, at: u32) -> Option<&Self::FuncType> {
244 T::func_type_at(self, at)
245 }
246 fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType> {
247 T::type_of_function(self, func_idx)
248 }
249 fn element_type_at(&self, at: u32) -> Option<ValType> {
250 T::element_type_at(self, at)
251 }
252
253 fn element_count(&self) -> u32 {
254 T::element_count(self)
255 }
256 fn data_count(&self) -> Option<u32> {
257 T::data_count(self)
258 }
259 fn is_function_referenced(&self, idx: u32) -> bool {
260 T::is_function_referenced(self, idx)
261 }
262}
263
264impl<T> WasmModuleResources for ::alloc::sync::Arc<T>
265where
266 T: WasmModuleResources,
267{
268 type FuncType = T::FuncType;
269
270 fn table_at(&self, at: u32) -> Option<TableType> {
271 T::table_at(self, at)
272 }
273
274 fn memory_at(&self, at: u32) -> Option<MemoryType> {
275 T::memory_at(self, at)
276 }
277
278 fn tag_at(&self, at: u32) -> Option<&Self::FuncType> {
279 T::tag_at(self, at)
280 }
281
282 fn global_at(&self, at: u32) -> Option<GlobalType> {
283 T::global_at(self, at)
284 }
285
286 fn func_type_at(&self, type_idx: u32) -> Option<&Self::FuncType> {
287 T::func_type_at(self, type_idx)
288 }
289
290 fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType> {
291 T::type_of_function(self, func_idx)
292 }
293
294 fn element_type_at(&self, at: u32) -> Option<ValType> {
295 T::element_type_at(self, at)
296 }
297
298 fn element_count(&self) -> u32 {
299 T::element_count(self)
300 }
301
302 fn data_count(&self) -> Option<u32> {
303 T::data_count(self)
304 }
305
306 fn is_function_referenced(&self, idx: u32) -> bool {
307 T::is_function_referenced(self, idx)
308 }
309}
310
311impl WasmFuncType for FuncType {
312 fn len_inputs(&self) -> usize {
313 self.params().len()
314 }
315
316 fn len_outputs(&self) -> usize {
317 self.results().len()
318 }
319
320 fn input_at(&self, at: u32) -> Option<ValType> {
321 self.params().get(at as usize).copied()
322 }
323
324 fn output_at(&self, at: u32) -> Option<ValType> {
325 self.results().get(at as usize).copied()
326 }
327}