/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 | | Error, FuncType, GlobalType, HeapType, MemoryType, RefType, SubType, TableType, ValType, |
18 | | 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.91M | fn check_value_type( |
83 | 3.91M | &self, |
84 | 3.91M | t: &mut ValType, |
85 | 3.91M | features: &WasmFeatures, |
86 | 3.91M | offset: u64, |
87 | 3.91M | ) -> Result<(), Error> { |
88 | 3.91M | features.check_value_type(*t, offset)?; |
89 | 3.91M | match t { |
90 | 390k | ValType::Ref(r) => self.check_ref_type(r, offset), |
91 | 3.52M | ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => Ok(()), |
92 | | } |
93 | 3.91M | } <wasmparser::validator::core::ValidatorResources as wasmparser::resources::WasmModuleResources>::check_value_type Line | Count | Source | 82 | 3.91M | fn check_value_type( | 83 | 3.91M | &self, | 84 | 3.91M | t: &mut ValType, | 85 | 3.91M | features: &WasmFeatures, | 86 | 3.91M | offset: u64, | 87 | 3.91M | ) -> Result<(), Error> { | 88 | 3.91M | features.check_value_type(*t, offset)?; | 89 | 3.91M | match t { | 90 | 390k | ValType::Ref(r) => self.check_ref_type(r, offset), | 91 | 3.52M | ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => Ok(()), | 92 | | } | 93 | 3.91M | } |
Unexecuted instantiation: <wasmparser::validator::core::OperatorValidatorResources as wasmparser::resources::WasmModuleResources>::check_value_type |
94 | | |
95 | | /// Check and canonicalize a reference type. |
96 | 393k | fn check_ref_type(&self, ref_type: &mut RefType, offset: u64) -> Result<(), Error> { |
97 | 393k | let is_nullable = ref_type.is_nullable(); |
98 | 393k | let mut heap_ty = ref_type.heap_type(); |
99 | 393k | self.check_heap_type(&mut heap_ty, offset)?; |
100 | 393k | *ref_type = RefType::new(is_nullable, heap_ty).unwrap(); |
101 | 393k | Ok(()) |
102 | 393k | } <wasmparser::validator::core::ValidatorResources as wasmparser::resources::WasmModuleResources>::check_ref_type Line | Count | Source | 96 | 393k | fn check_ref_type(&self, ref_type: &mut RefType, offset: u64) -> Result<(), Error> { | 97 | 393k | let is_nullable = ref_type.is_nullable(); | 98 | 393k | let mut heap_ty = ref_type.heap_type(); | 99 | 393k | self.check_heap_type(&mut heap_ty, offset)?; | 100 | 393k | *ref_type = RefType::new(is_nullable, heap_ty).unwrap(); | 101 | 393k | Ok(()) | 102 | 393k | } |
Unexecuted instantiation: <wasmparser::validator::core::OperatorValidatorResources as wasmparser::resources::WasmModuleResources>::check_ref_type |
103 | | |
104 | | /// Checks that a `HeapType` is valid and then additionally place it in its |
105 | | /// canonical form. |
106 | | /// |
107 | | /// Similar to `check_value_type` but for heap types. |
108 | | fn check_heap_type(&self, heap_type: &mut HeapType, offset: u64) -> Result<(), Error>; |
109 | | |
110 | | /// Get the top type for the given heap type. |
111 | | fn top_type(&self, heap_type: &HeapType) -> HeapType; |
112 | | |
113 | | /// Returns the number of elements. |
114 | | fn element_count(&self) -> u32; |
115 | | |
116 | | /// Returns the number of bytes in the Wasm data section. |
117 | | fn data_count(&self) -> Option<u32>; |
118 | | |
119 | | /// Returns whether the function index is referenced in the module anywhere |
120 | | /// outside of the start/function sections. |
121 | | fn is_function_referenced(&self, idx: u32) -> bool; |
122 | | |
123 | | /// Returns whether the function defined with the exact type. |
124 | | fn has_function_exact_type(&self, idx: u32) -> bool; |
125 | | } |
126 | | |
127 | | impl<T> WasmModuleResources for &'_ T |
128 | | where |
129 | | T: ?Sized + WasmModuleResources, |
130 | | { |
131 | 0 | fn table_at(&self, at: u32) -> Option<TableType> { |
132 | 0 | T::table_at(self, at) |
133 | 0 | } |
134 | 0 | fn memory_at(&self, at: u32) -> Option<MemoryType> { |
135 | 0 | T::memory_at(self, at) |
136 | 0 | } |
137 | 0 | fn tag_at(&self, at: u32) -> Option<&FuncType> { |
138 | 0 | T::tag_at(self, at) |
139 | 0 | } |
140 | 0 | fn global_at(&self, at: u32) -> Option<GlobalType> { |
141 | 0 | T::global_at(self, at) |
142 | 0 | } |
143 | 0 | fn sub_type_at(&self, at: u32) -> Option<&SubType> { |
144 | 0 | T::sub_type_at(self, at) |
145 | 0 | } |
146 | 0 | fn sub_type_at_id(&self, at: CoreTypeId) -> &SubType { |
147 | 0 | T::sub_type_at_id(self, at) |
148 | 0 | } |
149 | 0 | fn type_id_of_function(&self, func_idx: u32) -> Option<CoreTypeId> { |
150 | 0 | T::type_id_of_function(self, func_idx) |
151 | 0 | } |
152 | 0 | fn type_index_of_function(&self, func_idx: u32) -> Option<u32> { |
153 | 0 | T::type_index_of_function(self, func_idx) |
154 | 0 | } |
155 | 0 | fn check_heap_type(&self, t: &mut HeapType, offset: u64) -> Result<(), Error> { |
156 | 0 | T::check_heap_type(self, t, offset) |
157 | 0 | } |
158 | 0 | fn top_type(&self, heap_type: &HeapType) -> HeapType { |
159 | 0 | T::top_type(self, heap_type) |
160 | 0 | } |
161 | 0 | fn element_type_at(&self, at: u32) -> Option<RefType> { |
162 | 0 | T::element_type_at(self, at) |
163 | 0 | } |
164 | 0 | fn is_subtype(&self, a: ValType, b: ValType) -> bool { |
165 | 0 | T::is_subtype(self, a, b) |
166 | 0 | } |
167 | 325 | fn is_shared(&self, ty: RefType) -> bool { |
168 | 325 | T::is_shared(self, ty) |
169 | 325 | } <&wasmparser::validator::core::ValidatorResources as wasmparser::resources::WasmModuleResources>::is_shared Line | Count | Source | 167 | 325 | fn is_shared(&self, ty: RefType) -> bool { | 168 | 325 | T::is_shared(self, ty) | 169 | 325 | } |
Unexecuted instantiation: <&wasmparser::validator::core::OperatorValidatorResources as wasmparser::resources::WasmModuleResources>::is_shared |
170 | 0 | fn element_count(&self) -> u32 { |
171 | 0 | T::element_count(self) |
172 | 0 | } |
173 | 0 | fn data_count(&self) -> Option<u32> { |
174 | 0 | T::data_count(self) |
175 | 0 | } |
176 | 0 | fn is_function_referenced(&self, idx: u32) -> bool { |
177 | 0 | T::is_function_referenced(self, idx) |
178 | 0 | } |
179 | 0 | fn has_function_exact_type(&self, idx: u32) -> bool { |
180 | 0 | T::has_function_exact_type(self, idx) |
181 | 0 | } |
182 | | } |
183 | | |
184 | | impl<T> WasmModuleResources for alloc::sync::Arc<T> |
185 | | where |
186 | | T: WasmModuleResources, |
187 | | { |
188 | 0 | fn table_at(&self, at: u32) -> Option<TableType> { |
189 | 0 | T::table_at(self, at) |
190 | 0 | } |
191 | | |
192 | 0 | fn memory_at(&self, at: u32) -> Option<MemoryType> { |
193 | 0 | T::memory_at(self, at) |
194 | 0 | } |
195 | | |
196 | 0 | fn tag_at(&self, at: u32) -> Option<&FuncType> { |
197 | 0 | T::tag_at(self, at) |
198 | 0 | } |
199 | | |
200 | 0 | fn global_at(&self, at: u32) -> Option<GlobalType> { |
201 | 0 | T::global_at(self, at) |
202 | 0 | } |
203 | | |
204 | 0 | fn sub_type_at(&self, type_idx: u32) -> Option<&SubType> { |
205 | 0 | T::sub_type_at(self, type_idx) |
206 | 0 | } |
207 | | |
208 | 0 | fn sub_type_at_id(&self, id: CoreTypeId) -> &SubType { |
209 | 0 | T::sub_type_at_id(self, id) |
210 | 0 | } |
211 | | |
212 | 0 | fn type_id_of_function(&self, func_idx: u32) -> Option<CoreTypeId> { |
213 | 0 | T::type_id_of_function(self, func_idx) |
214 | 0 | } |
215 | | |
216 | 0 | fn type_index_of_function(&self, func_idx: u32) -> Option<u32> { |
217 | 0 | T::type_index_of_function(self, func_idx) |
218 | 0 | } |
219 | | |
220 | 0 | fn check_heap_type(&self, t: &mut HeapType, offset: u64) -> Result<(), Error> { |
221 | 0 | T::check_heap_type(self, t, offset) |
222 | 0 | } |
223 | | |
224 | 0 | fn top_type(&self, heap_type: &HeapType) -> HeapType { |
225 | 0 | T::top_type(self, heap_type) |
226 | 0 | } |
227 | | |
228 | 0 | fn element_type_at(&self, at: u32) -> Option<RefType> { |
229 | 0 | T::element_type_at(self, at) |
230 | 0 | } |
231 | | |
232 | 0 | fn is_subtype(&self, a: ValType, b: ValType) -> bool { |
233 | 0 | T::is_subtype(self, a, b) |
234 | 0 | } |
235 | | |
236 | 0 | fn is_shared(&self, ty: RefType) -> bool { |
237 | 0 | T::is_shared(self, ty) |
238 | 0 | } |
239 | | |
240 | 0 | fn element_count(&self) -> u32 { |
241 | 0 | T::element_count(self) |
242 | 0 | } |
243 | | |
244 | 0 | fn data_count(&self) -> Option<u32> { |
245 | 0 | T::data_count(self) |
246 | 0 | } |
247 | | |
248 | 0 | fn is_function_referenced(&self, idx: u32) -> bool { |
249 | 0 | T::is_function_referenced(self, idx) |
250 | 0 | } |
251 | | |
252 | 0 | fn has_function_exact_type(&self, idx: u32) -> bool { |
253 | 0 | T::has_function_exact_type(self, idx) |
254 | 0 | } |
255 | | } |