1use crate::{
17 BinaryReaderError, FuncType, GlobalType, HeapType, MemoryType, RefType, SubType, TableType,
18 ValType, WasmFeatures, types::CoreTypeId,
19};
20
21pub trait WasmModuleResources {
30 fn table_at(&self, at: u32) -> Option<TableType>;
34
35 fn memory_at(&self, at: u32) -> Option<MemoryType>;
37
38 fn tag_at(&self, at: u32) -> Option<&FuncType>;
42
43 fn global_at(&self, at: u32) -> Option<GlobalType>;
47
48 fn sub_type_at(&self, type_index: u32) -> Option<&SubType>;
52
53 fn sub_type_at_id(&self, id: CoreTypeId) -> &SubType;
55
56 fn type_id_of_function(&self, func_idx: u32) -> Option<CoreTypeId>;
58
59 fn type_index_of_function(&self, func_index: u32) -> Option<u32>;
61
62 fn element_type_at(&self, at: u32) -> Option<RefType>;
66
67 fn is_subtype(&self, a: ValType, b: ValType) -> bool;
69
70 fn is_shared(&self, ty: RefType) -> bool;
76
77 fn check_value_type(
83 &self,
84 t: &mut ValType,
85 features: &WasmFeatures,
86 offset: usize,
87 ) -> Result<(), BinaryReaderError> {
88 features
89 .check_value_type(*t)
90 .map_err(|s| BinaryReaderError::new(s, offset))?;
91 match t {
92 ValType::Ref(r) => self.check_ref_type(r, offset),
93 ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => Ok(()),
94 }
95 }
96
97 fn check_ref_type(
99 &self,
100 ref_type: &mut RefType,
101 offset: usize,
102 ) -> Result<(), BinaryReaderError> {
103 let is_nullable = ref_type.is_nullable();
104 let mut heap_ty = ref_type.heap_type();
105 self.check_heap_type(&mut heap_ty, offset)?;
106 *ref_type = RefType::new(is_nullable, heap_ty).unwrap();
107 Ok(())
108 }
109
110 fn check_heap_type(
115 &self,
116 heap_type: &mut HeapType,
117 offset: usize,
118 ) -> Result<(), BinaryReaderError>;
119
120 fn top_type(&self, heap_type: &HeapType) -> HeapType;
122
123 fn element_count(&self) -> u32;
125
126 fn data_count(&self) -> Option<u32>;
128
129 fn is_function_referenced(&self, idx: u32) -> bool;
132
133 fn has_function_exact_type(&self, idx: u32) -> bool;
135}
136
137impl<T> WasmModuleResources for &'_ T
138where
139 T: ?Sized + WasmModuleResources,
140{
141 fn table_at(&self, at: u32) -> Option<TableType> {
142 T::table_at(self, at)
143 }
144 fn memory_at(&self, at: u32) -> Option<MemoryType> {
145 T::memory_at(self, at)
146 }
147 fn tag_at(&self, at: u32) -> Option<&FuncType> {
148 T::tag_at(self, at)
149 }
150 fn global_at(&self, at: u32) -> Option<GlobalType> {
151 T::global_at(self, at)
152 }
153 fn sub_type_at(&self, at: u32) -> Option<&SubType> {
154 T::sub_type_at(self, at)
155 }
156 fn sub_type_at_id(&self, at: CoreTypeId) -> &SubType {
157 T::sub_type_at_id(self, at)
158 }
159 fn type_id_of_function(&self, func_idx: u32) -> Option<CoreTypeId> {
160 T::type_id_of_function(self, func_idx)
161 }
162 fn type_index_of_function(&self, func_idx: u32) -> Option<u32> {
163 T::type_index_of_function(self, func_idx)
164 }
165 fn check_heap_type(&self, t: &mut HeapType, offset: usize) -> Result<(), BinaryReaderError> {
166 T::check_heap_type(self, t, offset)
167 }
168 fn top_type(&self, heap_type: &HeapType) -> HeapType {
169 T::top_type(self, heap_type)
170 }
171 fn element_type_at(&self, at: u32) -> Option<RefType> {
172 T::element_type_at(self, at)
173 }
174 fn is_subtype(&self, a: ValType, b: ValType) -> bool {
175 T::is_subtype(self, a, b)
176 }
177 fn is_shared(&self, ty: RefType) -> bool {
178 T::is_shared(self, ty)
179 }
180 fn element_count(&self) -> u32 {
181 T::element_count(self)
182 }
183 fn data_count(&self) -> Option<u32> {
184 T::data_count(self)
185 }
186 fn is_function_referenced(&self, idx: u32) -> bool {
187 T::is_function_referenced(self, idx)
188 }
189 fn has_function_exact_type(&self, idx: u32) -> bool {
190 T::has_function_exact_type(self, idx)
191 }
192}
193
194impl<T> WasmModuleResources for alloc::sync::Arc<T>
195where
196 T: WasmModuleResources,
197{
198 fn table_at(&self, at: u32) -> Option<TableType> {
199 T::table_at(self, at)
200 }
201
202 fn memory_at(&self, at: u32) -> Option<MemoryType> {
203 T::memory_at(self, at)
204 }
205
206 fn tag_at(&self, at: u32) -> Option<&FuncType> {
207 T::tag_at(self, at)
208 }
209
210 fn global_at(&self, at: u32) -> Option<GlobalType> {
211 T::global_at(self, at)
212 }
213
214 fn sub_type_at(&self, type_idx: u32) -> Option<&SubType> {
215 T::sub_type_at(self, type_idx)
216 }
217
218 fn sub_type_at_id(&self, id: CoreTypeId) -> &SubType {
219 T::sub_type_at_id(self, id)
220 }
221
222 fn type_id_of_function(&self, func_idx: u32) -> Option<CoreTypeId> {
223 T::type_id_of_function(self, func_idx)
224 }
225
226 fn type_index_of_function(&self, func_idx: u32) -> Option<u32> {
227 T::type_index_of_function(self, func_idx)
228 }
229
230 fn check_heap_type(&self, t: &mut HeapType, offset: usize) -> Result<(), BinaryReaderError> {
231 T::check_heap_type(self, t, offset)
232 }
233
234 fn top_type(&self, heap_type: &HeapType) -> HeapType {
235 T::top_type(self, heap_type)
236 }
237
238 fn element_type_at(&self, at: u32) -> Option<RefType> {
239 T::element_type_at(self, at)
240 }
241
242 fn is_subtype(&self, a: ValType, b: ValType) -> bool {
243 T::is_subtype(self, a, b)
244 }
245
246 fn is_shared(&self, ty: RefType) -> bool {
247 T::is_shared(self, ty)
248 }
249
250 fn element_count(&self) -> u32 {
251 T::element_count(self)
252 }
253
254 fn data_count(&self) -> Option<u32> {
255 T::data_count(self)
256 }
257
258 fn is_function_referenced(&self, idx: u32) -> bool {
259 T::is_function_referenced(self, idx)
260 }
261
262 fn has_function_exact_type(&self, idx: u32) -> bool {
263 T::has_function_exact_type(self, idx)
264 }
265}