summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wasmparser/src/resources.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/wasmparser/src/resources.rs')
-rw-r--r--third_party/rust/wasmparser/src/resources.rs395
1 files changed, 395 insertions, 0 deletions
diff --git a/third_party/rust/wasmparser/src/resources.rs b/third_party/rust/wasmparser/src/resources.rs
new file mode 100644
index 0000000000..2f0cb5309d
--- /dev/null
+++ b/third_party/rust/wasmparser/src/resources.rs
@@ -0,0 +1,395 @@
+/* Copyright 2019 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use crate::{
+ BinaryReaderError, FuncType, GlobalType, HeapType, MemoryType, RefType, TableType, ValType,
+ WasmFeatures,
+};
+use std::ops::Range;
+
+/// Types that qualify as Wasm function types for validation purposes.
+pub trait WasmFuncType {
+ /// Returns the number of input types.
+ fn len_inputs(&self) -> usize;
+ /// Returns the number of output types.
+ fn len_outputs(&self) -> usize;
+ /// Returns the type at given index if any.
+ ///
+ /// # Note
+ ///
+ /// The returned type may be wrapped by the user crate and thus
+ /// the actually returned type only has to be comparable to a Wasm type.
+ fn input_at(&self, at: u32) -> Option<ValType>;
+ /// Returns the type at given index if any.
+ ///
+ /// # Note
+ ///
+ /// The returned type may be wrapped by the user crate and thus
+ /// the actually returned type only has to be comparable to a Wasm type.
+ fn output_at(&self, at: u32) -> Option<ValType>;
+
+ /// Returns the list of inputs as an iterator.
+ fn inputs(&self) -> WasmFuncTypeInputs<'_, Self>
+ where
+ Self: Sized,
+ {
+ WasmFuncTypeInputs {
+ func_type: self,
+ range: 0..self.len_inputs() as u32,
+ }
+ }
+
+ /// Returns the list of outputs as an iterator.
+ fn outputs(&self) -> WasmFuncTypeOutputs<'_, Self>
+ where
+ Self: Sized,
+ {
+ WasmFuncTypeOutputs {
+ func_type: self,
+ range: 0..self.len_outputs() as u32,
+ }
+ }
+}
+
+impl<T> WasmFuncType for &'_ T
+where
+ T: ?Sized + WasmFuncType,
+{
+ fn len_inputs(&self) -> usize {
+ T::len_inputs(self)
+ }
+ fn len_outputs(&self) -> usize {
+ T::len_outputs(self)
+ }
+ fn input_at(&self, at: u32) -> Option<ValType> {
+ T::input_at(self, at)
+ }
+ fn output_at(&self, at: u32) -> Option<ValType> {
+ T::output_at(self, at)
+ }
+}
+
+/// Iterator over the inputs of a Wasm function type.
+pub struct WasmFuncTypeInputs<'a, T> {
+ /// The iterated-over function type.
+ func_type: &'a T,
+ /// The range we're iterating over.
+ range: Range<u32>,
+}
+
+impl<T> Iterator for WasmFuncTypeInputs<'_, T>
+where
+ T: WasmFuncType,
+{
+ type Item = crate::ValType;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.range
+ .next()
+ .map(|i| self.func_type.input_at(i).unwrap())
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.range.size_hint()
+ }
+}
+
+impl<T> DoubleEndedIterator for WasmFuncTypeInputs<'_, T>
+where
+ T: WasmFuncType,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.range
+ .next_back()
+ .map(|i| self.func_type.input_at(i).unwrap())
+ }
+}
+
+impl<T> ExactSizeIterator for WasmFuncTypeInputs<'_, T>
+where
+ T: WasmFuncType,
+{
+ fn len(&self) -> usize {
+ self.range.len()
+ }
+}
+
+impl<'a, T> Clone for WasmFuncTypeInputs<'a, T> {
+ fn clone(&self) -> WasmFuncTypeInputs<'a, T> {
+ WasmFuncTypeInputs {
+ func_type: self.func_type,
+ range: self.range.clone(),
+ }
+ }
+}
+
+/// Iterator over the outputs of a Wasm function type.
+pub struct WasmFuncTypeOutputs<'a, T> {
+ /// The iterated-over function type.
+ func_type: &'a T,
+ /// The range we're iterating over.
+ range: Range<u32>,
+}
+
+impl<T> Iterator for WasmFuncTypeOutputs<'_, T>
+where
+ T: WasmFuncType,
+{
+ type Item = crate::ValType;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.range
+ .next()
+ .map(|i| self.func_type.output_at(i).unwrap())
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.range.size_hint()
+ }
+}
+
+impl<T> DoubleEndedIterator for WasmFuncTypeOutputs<'_, T>
+where
+ T: WasmFuncType,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.range
+ .next_back()
+ .map(|i| self.func_type.output_at(i).unwrap())
+ }
+}
+
+impl<T> ExactSizeIterator for WasmFuncTypeOutputs<'_, T>
+where
+ T: WasmFuncType,
+{
+ fn len(&self) -> usize {
+ self.range.len()
+ }
+}
+
+impl<'a, T> Clone for WasmFuncTypeOutputs<'a, T> {
+ fn clone(&self) -> WasmFuncTypeOutputs<'a, T> {
+ WasmFuncTypeOutputs {
+ func_type: self.func_type,
+ range: self.range.clone(),
+ }
+ }
+}
+
+/// Types that qualify as Wasm validation database.
+///
+/// # Note
+///
+/// The `wasmparser` crate provides a builtin validation framework but allows
+/// users of this crate to also feed the parsed Wasm into their own data
+/// structure while parsing and also validate at the same time without
+/// the need of an additional parsing or validation step or copying data around.
+pub trait WasmModuleResources {
+ /// The function type used for validation.
+ type FuncType: WasmFuncType;
+
+ /// Returns the table at given index if any.
+ fn table_at(&self, at: u32) -> Option<TableType>;
+ /// Returns the linear memory at given index.
+ fn memory_at(&self, at: u32) -> Option<MemoryType>;
+ /// Returns the tag at given index.
+ fn tag_at(&self, at: u32) -> Option<&Self::FuncType>;
+ /// Returns the global variable at given index.
+ fn global_at(&self, at: u32) -> Option<GlobalType>;
+ /// Returns the `FuncType` associated with the given type index.
+ fn func_type_at(&self, type_idx: u32) -> Option<&Self::FuncType>;
+ /// Returns the type index associated with the given function
+ /// index. type_of_function = func_type_at(type_index_of_function)
+ fn type_index_of_function(&self, func_idx: u32) -> Option<u32>;
+ /// Returns the `FuncType` associated with the given function index.
+ fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType>;
+ /// Returns the element type at the given index.
+ fn element_type_at(&self, at: u32) -> Option<RefType>;
+ /// Under the function references proposal, returns whether t1 <=
+ /// t2. Otherwise, returns whether t1 == t2
+ fn matches(&self, t1: ValType, t2: ValType) -> bool;
+ /// Check a value type. This requires using func_type_at to check references
+ fn check_value_type(
+ &self,
+ t: ValType,
+ features: &WasmFeatures,
+ offset: usize,
+ ) -> Result<(), BinaryReaderError>;
+
+ /// Checks that a `HeapType` is valid, notably its function index if one is
+ /// used.
+ fn check_heap_type(
+ &self,
+ heap_type: HeapType,
+ features: &WasmFeatures,
+ offset: usize,
+ ) -> Result<(), BinaryReaderError> {
+ // Delegate to the generic value type validation which will have the
+ // same validity checks.
+ self.check_value_type(
+ RefType {
+ nullable: true,
+ heap_type,
+ }
+ .into(),
+ features,
+ offset,
+ )
+ }
+
+ /// Returns the number of elements.
+ fn element_count(&self) -> u32;
+ /// Returns the number of bytes in the Wasm data section.
+ fn data_count(&self) -> Option<u32>;
+ /// Returns whether the function index is referenced in the module anywhere
+ /// outside of the start/function sections.
+ fn is_function_referenced(&self, idx: u32) -> bool;
+}
+
+impl<T> WasmModuleResources for &'_ T
+where
+ T: ?Sized + WasmModuleResources,
+{
+ type FuncType = T::FuncType;
+
+ fn table_at(&self, at: u32) -> Option<TableType> {
+ T::table_at(self, at)
+ }
+ fn memory_at(&self, at: u32) -> Option<MemoryType> {
+ T::memory_at(self, at)
+ }
+ fn tag_at(&self, at: u32) -> Option<&Self::FuncType> {
+ T::tag_at(self, at)
+ }
+ fn global_at(&self, at: u32) -> Option<GlobalType> {
+ T::global_at(self, at)
+ }
+ fn func_type_at(&self, at: u32) -> Option<&Self::FuncType> {
+ T::func_type_at(self, at)
+ }
+ fn type_index_of_function(&self, func_idx: u32) -> Option<u32> {
+ T::type_index_of_function(self, func_idx)
+ }
+ fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType> {
+ T::type_of_function(self, func_idx)
+ }
+ fn check_value_type(
+ &self,
+ t: ValType,
+ features: &WasmFeatures,
+ offset: usize,
+ ) -> Result<(), BinaryReaderError> {
+ T::check_value_type(self, t, features, offset)
+ }
+ fn element_type_at(&self, at: u32) -> Option<RefType> {
+ T::element_type_at(self, at)
+ }
+ fn matches(&self, t1: ValType, t2: ValType) -> bool {
+ T::matches(self, t1, t2)
+ }
+
+ fn element_count(&self) -> u32 {
+ T::element_count(self)
+ }
+ fn data_count(&self) -> Option<u32> {
+ T::data_count(self)
+ }
+ fn is_function_referenced(&self, idx: u32) -> bool {
+ T::is_function_referenced(self, idx)
+ }
+}
+
+impl<T> WasmModuleResources for std::sync::Arc<T>
+where
+ T: WasmModuleResources,
+{
+ type FuncType = T::FuncType;
+
+ fn table_at(&self, at: u32) -> Option<TableType> {
+ T::table_at(self, at)
+ }
+
+ fn memory_at(&self, at: u32) -> Option<MemoryType> {
+ T::memory_at(self, at)
+ }
+
+ fn tag_at(&self, at: u32) -> Option<&Self::FuncType> {
+ T::tag_at(self, at)
+ }
+
+ fn global_at(&self, at: u32) -> Option<GlobalType> {
+ T::global_at(self, at)
+ }
+
+ fn func_type_at(&self, type_idx: u32) -> Option<&Self::FuncType> {
+ T::func_type_at(self, type_idx)
+ }
+
+ fn type_index_of_function(&self, func_idx: u32) -> Option<u32> {
+ T::type_index_of_function(self, func_idx)
+ }
+
+ fn type_of_function(&self, func_idx: u32) -> Option<&Self::FuncType> {
+ T::type_of_function(self, func_idx)
+ }
+
+ fn check_value_type(
+ &self,
+ t: ValType,
+ features: &WasmFeatures,
+ offset: usize,
+ ) -> Result<(), BinaryReaderError> {
+ T::check_value_type(self, t, features, offset)
+ }
+
+ fn element_type_at(&self, at: u32) -> Option<RefType> {
+ T::element_type_at(self, at)
+ }
+
+ fn matches(&self, t1: ValType, t2: ValType) -> bool {
+ T::matches(self, t1, t2)
+ }
+
+ fn element_count(&self) -> u32 {
+ T::element_count(self)
+ }
+
+ fn data_count(&self) -> Option<u32> {
+ T::data_count(self)
+ }
+
+ fn is_function_referenced(&self, idx: u32) -> bool {
+ T::is_function_referenced(self, idx)
+ }
+}
+
+impl WasmFuncType for FuncType {
+ fn len_inputs(&self) -> usize {
+ self.params().len()
+ }
+
+ fn len_outputs(&self) -> usize {
+ self.results().len()
+ }
+
+ fn input_at(&self, at: u32) -> Option<ValType> {
+ self.params().get(at as usize).copied()
+ }
+
+ fn output_at(&self, at: u32) -> Option<ValType> {
+ self.results().get(at as usize).copied()
+ }
+}