/src/wasm-tools/crates/wasmparser/src/resources.rs
Line | Count | Source |
1 | | /* Copyright 2019 Mozilla Foundation |
2 | | * |
3 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | * you may not use this file except in compliance with the License. |
5 | | * You may obtain a copy of the License at |
6 | | * |
7 | | * http://www.apache.org/licenses/LICENSE-2.0 |
8 | | * |
9 | | * Unless required by applicable law or agreed to in writing, software |
10 | | * distributed under the License is distributed on an "AS IS" BASIS, |
11 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | * See the License for the specific language governing permissions and |
13 | | * limitations under the License. |
14 | | */ |
15 | | |
16 | | use crate::{ |
17 | | BinaryReaderError, FuncType, GlobalType, HeapType, MemoryType, RefType, SubType, TableType, |
18 | | ValType, WasmFeatures, types::CoreTypeId, |
19 | | }; |
20 | | |
21 | | /// Types that qualify as Wasm validation database. |
22 | | /// |
23 | | /// # Note |
24 | | /// |
25 | | /// The `wasmparser` crate provides a builtin validation framework but allows |
26 | | /// users of this crate to also feed the parsed Wasm into their own data |
27 | | /// structure while parsing and also validate at the same time without |
28 | | /// the need of an additional parsing or validation step or copying data around. |
29 | | pub trait WasmModuleResources { |
30 | | /// Returns the table at given index if any. |
31 | | /// |
32 | | /// The table element type must be canonicalized. |
33 | | fn table_at(&self, at: u32) -> Option<TableType>; |
34 | | |
35 | | /// Returns the linear memory at given index. |
36 | | fn memory_at(&self, at: u32) -> Option<MemoryType>; |
37 | | |
38 | | /// Returns the tag at given index. |
39 | | /// |
40 | | /// The tag's function type must be canonicalized. |
41 | | fn tag_at(&self, at: u32) -> Option<&FuncType>; |
42 | | |
43 | | /// Returns the global variable at given index. |
44 | | /// |
45 | | /// The global's value type must be canonicalized. |
46 | | fn global_at(&self, at: u32) -> Option<GlobalType>; |
47 | | |
48 | | /// Returns the `SubType` associated with the given type index. |
49 | | /// |
50 | | /// The sub type must be canonicalized. |
51 | | fn sub_type_at(&self, type_index: u32) -> Option<&SubType>; |
52 | | |
53 | | /// Returns the `SubType` associated with the given core type id. |
54 | | fn sub_type_at_id(&self, id: CoreTypeId) -> &SubType; |
55 | | |
56 | | /// Returns the type ID associated with the given function index. |
57 | | fn type_id_of_function(&self, func_idx: u32) -> Option<CoreTypeId>; |
58 | | |
59 | | /// Returns the type index associated with the given function index. |
60 | | fn type_index_of_function(&self, func_index: u32) -> Option<u32>; |
61 | | |
62 | | /// Returns the element type at the given index. |
63 | | /// |
64 | | /// The `RefType` must be canonicalized. |
65 | | fn element_type_at(&self, at: u32) -> Option<RefType>; |
66 | | |
67 | | /// Is `a` a subtype of `b`? |
68 | | fn is_subtype(&self, a: ValType, b: ValType) -> bool; |
69 | | |
70 | | /// Is the given reference type `shared`? |
71 | | /// |
72 | | /// While abstract heap types do carry along a `shared` flag, concrete heap |
73 | | /// types do not. This function resolves those concrete heap types to |
74 | | /// determine `shared`-ness. |
75 | | fn is_shared(&self, ty: RefType) -> bool; |
76 | | |
77 | | /// Check and canonicalize a value type. |
78 | | /// |
79 | | /// This will validate that `t` is valid under the `features` provided and |
80 | | /// then additionally validate the structure of `t`. For example any type |
81 | | /// references that `t` makes are validated and canonicalized. |
82 | 3.08M | fn check_value_type( |
83 | 3.08M | &self, |
84 | 3.08M | t: &mut ValType, |
85 | 3.08M | features: &WasmFeatures, |
86 | 3.08M | offset: usize, |
87 | 3.08M | ) -> Result<(), BinaryReaderError> { |
88 | 3.08M | features |
89 | 3.08M | .check_value_type(*t) |
90 | 3.08M | .map_err(|s| BinaryReaderError::new(s, offset))?; Unexecuted instantiation: <wasmparser::validator::core::ValidatorResources as wasmparser::resources::WasmModuleResources>::check_value_type::{closure#0}Unexecuted instantiation: <wasmparser::validator::core::OperatorValidatorResources as wasmparser::resources::WasmModuleResources>::check_value_type::{closure#0} |
91 | 3.08M | match t { |
92 | 196k | ValType::Ref(r) => self.check_ref_type(r, offset), |
93 | 2.88M | ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => Ok(()), |
94 | | } |
95 | 3.08M | } <wasmparser::validator::core::ValidatorResources as wasmparser::resources::WasmModuleResources>::check_value_type Line | Count | Source | 82 | 3.08M | fn check_value_type( | 83 | 3.08M | &self, | 84 | 3.08M | t: &mut ValType, | 85 | 3.08M | features: &WasmFeatures, | 86 | 3.08M | offset: usize, | 87 | 3.08M | ) -> Result<(), BinaryReaderError> { | 88 | 3.08M | features | 89 | 3.08M | .check_value_type(*t) | 90 | 3.08M | .map_err(|s| BinaryReaderError::new(s, offset))?; | 91 | 3.08M | match t { | 92 | 196k | ValType::Ref(r) => self.check_ref_type(r, offset), | 93 | 2.88M | ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => Ok(()), | 94 | | } | 95 | 3.08M | } |
Unexecuted instantiation: <wasmparser::validator::core::OperatorValidatorResources as wasmparser::resources::WasmModuleResources>::check_value_type |
96 | | |
97 | | /// Check and canonicalize a reference type. |
98 | 197k | fn check_ref_type( |
99 | 197k | &self, |
100 | 197k | ref_type: &mut RefType, |
101 | 197k | offset: usize, |
102 | 197k | ) -> Result<(), BinaryReaderError> { |
103 | 197k | let is_nullable = ref_type.is_nullable(); |
104 | 197k | let mut heap_ty = ref_type.heap_type(); |
105 | 197k | self.check_heap_type(&mut heap_ty, offset)?; |
106 | 197k | *ref_type = RefType::new(is_nullable, heap_ty).unwrap(); |
107 | 197k | Ok(()) |
108 | 197k | } <wasmparser::validator::core::ValidatorResources as wasmparser::resources::WasmModuleResources>::check_ref_type Line | Count | Source | 98 | 197k | fn check_ref_type( | 99 | 197k | &self, | 100 | 197k | ref_type: &mut RefType, | 101 | 197k | offset: usize, | 102 | 197k | ) -> Result<(), BinaryReaderError> { | 103 | 197k | let is_nullable = ref_type.is_nullable(); | 104 | 197k | let mut heap_ty = ref_type.heap_type(); | 105 | 197k | self.check_heap_type(&mut heap_ty, offset)?; | 106 | 197k | *ref_type = RefType::new(is_nullable, heap_ty).unwrap(); | 107 | 197k | Ok(()) | 108 | 197k | } |
Unexecuted instantiation: <wasmparser::validator::core::OperatorValidatorResources as wasmparser::resources::WasmModuleResources>::check_ref_type |
109 | | |
110 | | /// Checks that a `HeapType` is valid and then additionally place it in its |
111 | | /// canonical form. |
112 | | /// |
113 | | /// Similar to `check_value_type` but for heap types. |
114 | | fn check_heap_type( |
115 | | &self, |
116 | | heap_type: &mut HeapType, |
117 | | offset: usize, |
118 | | ) -> Result<(), BinaryReaderError>; |
119 | | |
120 | | /// Get the top type for the given heap type. |
121 | | fn top_type(&self, heap_type: &HeapType) -> HeapType; |
122 | | |
123 | | /// Returns the number of elements. |
124 | | fn element_count(&self) -> u32; |
125 | | |
126 | | /// Returns the number of bytes in the Wasm data section. |
127 | | fn data_count(&self) -> Option<u32>; |
128 | | |
129 | | /// Returns whether the function index is referenced in the module anywhere |
130 | | /// outside of the start/function sections. |
131 | | fn is_function_referenced(&self, idx: u32) -> bool; |
132 | | |
133 | | /// Returns whether the function defined with the exact type. |
134 | | fn has_function_exact_type(&self, idx: u32) -> bool; |
135 | | } |
136 | | |
137 | | impl<T> WasmModuleResources for &'_ T |
138 | | where |
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 | 310 | fn is_shared(&self, ty: RefType) -> bool { |
178 | 310 | T::is_shared(self, ty) |
179 | 310 | } <&wasmparser::validator::core::ValidatorResources as wasmparser::resources::WasmModuleResources>::is_shared Line | Count | Source | 177 | 310 | fn is_shared(&self, ty: RefType) -> bool { | 178 | 310 | T::is_shared(self, ty) | 179 | 310 | } |
Unexecuted instantiation: <&wasmparser::validator::core::OperatorValidatorResources as wasmparser::resources::WasmModuleResources>::is_shared |
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 | | |
194 | | impl<T> WasmModuleResources for alloc::sync::Arc<T> |
195 | | where |
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 | | } |