Skip to content
This repository was archived by the owner on Jun 16, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a43d4ba
initial traits and impls for new validation interface
Robbepop Jan 12, 2020
4087b69
Merge branch 'master' of github.com:bytecodealliance/wasmparser into …
Robbepop Jan 12, 2020
113bcab
implement new validation interface into existing validation procedures
Robbepop Jan 12, 2020
d81476c
add len_* methods to WasmModuleResources trait
Robbepop Jan 12, 2020
19e7084
add docs
Robbepop Jan 12, 2020
447e548
extend WasmType trait (adds compat method)
Robbepop Jan 12, 2020
d3cf6de
remove globals method from WasmModuleResources trait
Robbepop Jan 12, 2020
71000b8
remove memories method from WasmModuleResources trait
Robbepop Jan 12, 2020
fa4cf1d
add table_at_checked to WasmModuleResources trait
Robbepop Jan 12, 2020
f068385
remove tables method from WasmModuleResources trait
Robbepop Jan 12, 2020
703456f
add len_func_type_id and remove func_type_indices methods in WasmModu…
Robbepop Jan 12, 2020
b4e613f
add docs
Robbepop Jan 12, 2020
81bdced
remove types method from WasmModuleResources trait
Robbepop Jan 12, 2020
03a6ca8
apply rustfmt
Robbepop Jan 12, 2020
2648be9
remove DefaultWasmModuleResources (was a bad idea to begin with)
Robbepop Jan 12, 2020
a0566fb
remove dynamic allocations for wasm_func_type_{inputs, outputs}
Robbepop Jan 15, 2020
c6bd9b7
apply rustfmt
Robbepop Jan 15, 2020
43f65e8
make use of wasm_func_type_inputs where possible instead of raw looping
Robbepop Jan 15, 2020
f4cf920
apply rustfmt
Robbepop Jan 15, 2020
c438c26
remove WasmModuleResources::table_at and rename table_at_checked
Robbepop Jan 16, 2020
6b90993
make WasmModuleResources::global_at return Option<_>
Robbepop Jan 16, 2020
05e242c
remove WasmModuleResources::len_globals
Robbepop Jan 16, 2020
31f3b65
remove WasmModuleResources::len_tables
Robbepop Jan 16, 2020
00bcfc7
make WasmModuleResources::memory_at return an Option
Robbepop Jan 16, 2020
94e208c
remove WasmModuleResources::len_memories
Robbepop Jan 16, 2020
0aac6b8
make WasmModuleResources::func_type_id_at return an Option
Robbepop Jan 16, 2020
dcae0a9
remove WasmModuleResources::len_func_type_id
Robbepop Jan 16, 2020
1f89507
make WasmModuleResources::type_at return Option
Robbepop Jan 16, 2020
4937b8a
remove WasmModuleResources::len_types
Robbepop Jan 16, 2020
6ab86d4
apply rustfmt
Robbepop Jan 16, 2020
eadd74d
Add docs to WasmModuleResources
Robbepop Jan 16, 2020
30d9372
export new validation traits
Robbepop Jan 16, 2020
a10ab50
fix type in docs
Jan 16, 2020
0bb3c6b
fix typo in docs
Jan 16, 2020
7f8b395
move new traits, iterators and functions for validation into their ow…
Robbepop Jan 17, 2020
00430dd
Merge branch 'generalize-validation' of github.com:Robbepop/wasmparse…
Robbepop Jan 17, 2020
4b227e6
apply rustfmt
Robbepop Jan 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,16 @@ pub use crate::validator::ValidatingOperatorParser;
pub use crate::validator::ValidatingParser;
pub use crate::validator::ValidatingParserConfig;

pub use crate::module_resources::WasmFuncType;
pub use crate::module_resources::WasmGlobalType;
pub use crate::module_resources::WasmMemoryType;
pub use crate::module_resources::WasmModuleResources;
pub use crate::module_resources::WasmTableType;
pub use crate::module_resources::WasmType;

pub(crate) use crate::module_resources::{wasm_func_type_inputs, wasm_func_type_outputs};

pub use crate::operators_validator::OperatorValidatorConfig;
pub use crate::operators_validator::WasmModuleResources;

pub use crate::readers::CodeSectionReader;
pub use crate::readers::CustomSectionContent;
Expand Down Expand Up @@ -113,6 +121,7 @@ pub use crate::readers::TypeSectionReader;

mod binary_reader;
mod limits;
mod module_resources;
mod operators_validator;
mod parser;
mod primitives;
Expand Down
370 changes: 370 additions & 0 deletions src/module_resources.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,370 @@
/* 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.
*/

/// Types that qualify as Wasm types for validation purposes.
///
/// Must be comparable with `wasmparser` given Wasm types and
/// must be comparable to themselves.
pub trait WasmType: PartialEq<crate::Type> + PartialEq + Eq {
/// Converts the custom type into a `wasmparser` known type.
///
/// # Note
///
/// This interface is required as bridge until transitioning is complete.
fn to_parser_type(&self) -> crate::Type;
}

/// Types that qualify as Wasm function types for validation purposes.
pub trait WasmFuncType {
/// A type that is comparable with Wasm types.
type Type: WasmType;

/// 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<&Self::Type>;
/// 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<&Self::Type>;
}

/// Iterator over the inputs of a Wasm function type.
pub(crate) struct WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
/// The iterated-over function type.
func_type: &'a F,
/// The current starting index.
start: u32,
/// The current ending index.
end: u32,
}

impl<'a, F, T> WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn new(func_type: &'a F) -> Self {
Self {
func_type,
start: 0,
end: func_type.len_inputs() as u32,
}
}
}

impl<'a, F, T> Iterator for WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
type Item = &'a T;

fn next(&mut self) -> Option<Self::Item> {
if self.start == self.end {
return None;
}
let ty = self
.func_type
.input_at(self.start)
// Expected since `self.start != self.end`.
.expect("we expect to receive an input type at this point");
self.start += 1;
Some(ty)
}

fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}

impl<'a, F, T> DoubleEndedIterator for WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.start == self.end {
return None;
}
let ty = self
.func_type
.input_at(self.end)
// Expected since `self.start != self.end`.
.expect("we expect to receive an input type at this point");
self.end -= 1;
Some(ty)
}
}

impl<'a, F, T> ExactSizeIterator for WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn len(&self) -> usize {
(self.end as usize) - (self.start as usize)
}
}

/// Iterator over the outputs of a Wasm function type.
pub(crate) struct WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
/// The iterated-over function type.
func_type: &'a F,
/// The current starting index.
start: u32,
/// The current ending index.
end: u32,
}

impl<'a, F, T> WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn new(func_type: &'a F) -> Self {
Self {
func_type,
start: 0,
end: func_type.len_outputs() as u32,
}
}
}

impl<'a, F, T> Iterator for WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
type Item = &'a T;

fn next(&mut self) -> Option<Self::Item> {
if self.start == self.end {
return None;
}
let ty = self
.func_type
.output_at(self.start)
// Expected since `self.start != self.end`.
.expect("we expect to receive an input type at this point");
self.start += 1;
Some(ty)
}

fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}

impl<'a, F, T> DoubleEndedIterator for WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.start == self.end {
return None;
}
let ty = self
.func_type
.output_at(self.end)
// Expected since `self.start != self.end`.
.expect("we expect to receive an input type at this point");
self.end -= 1;
Some(ty)
}
}

impl<'a, F, T> ExactSizeIterator for WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
fn len(&self) -> usize {
(self.end as usize) - (self.start as usize)
}
}

/// Returns an iterator over the input types of a Wasm function type.
pub(crate) fn wasm_func_type_inputs<'a, F, T>(func_type: &'a F) -> WasmFuncTypeInputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
WasmFuncTypeInputs::new(func_type)
}

/// Returns an iterator over the output types of a Wasm function type.
pub(crate) fn wasm_func_type_outputs<'a, F, T>(func_type: &'a F) -> WasmFuncTypeOutputs<'a, F, T>
where
F: WasmFuncType<Type = T>,
T: WasmType + 'a,
{
WasmFuncTypeOutputs::new(func_type)
}

/// Types that qualify as Wasm table types for validation purposes.
pub trait WasmTableType {
/// A type that is comparable with Wasm types.
type Type: WasmType;

/// Returns the element type of the table.
fn element_type(&self) -> &Self::Type;
/// Returns the initial limit of the table.
fn initial_limit(&self) -> u32;
/// Returns the maximum limit of the table if any.
fn maximum_limit(&self) -> Option<u32>;
}

/// Types that qualify as Wasm memory types for validation purposes.
pub trait WasmMemoryType {
/// Returns `true` if the linear memory is shared.
fn is_shared(&self) -> bool;
/// Returns the initial limit of the linear memory.
fn initial_limit(&self) -> u32;
/// Returns the maximum limit of the linear memory if any.
fn maximum_limit(&self) -> Option<u32>;
}

/// Types that qualify as Wasm global types for validation purposes.
pub trait WasmGlobalType {
/// A type that is comparable with Wasm types.
type Type: WasmType;

/// Returns `true` if the global variable is mutable.
fn is_mutable(&self) -> bool;
/// Returns the content type of the global variable.
fn content_type(&self) -> &Self::Type;
}

/// Types that qualify as Wasm valiation 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;
/// The table type used for validation.
type TableType: WasmTableType;
/// The memory type used for validation.
type MemoryType: WasmMemoryType;
/// The global type used for validation.
type GlobalType: WasmGlobalType;

/// Returns the type at given index.
fn type_at(&self, at: u32) -> Option<&Self::FuncType>;
/// Returns the table at given index if any.
fn table_at(&self, at: u32) -> Option<&Self::TableType>;
/// Returns the linear memory at given index.
fn memory_at(&self, at: u32) -> Option<&Self::MemoryType>;
/// Returns the global variable at given index.
fn global_at(&self, at: u32) -> Option<&Self::GlobalType>;
/// Returns the function signature ID at given index.
fn func_type_id_at(&self, at: u32) -> Option<u32>;

/// Returns the number of elements.
fn element_count(&self) -> u32;
/// Returns the number of bytes in the Wasm data section.
fn data_count(&self) -> u32;
}

impl WasmType for crate::Type {
fn to_parser_type(&self) -> crate::Type {
*self
}
}

impl WasmFuncType for crate::FuncType {
type Type = crate::Type;

fn len_inputs(&self) -> usize {
self.params.len()
}

fn len_outputs(&self) -> usize {
self.returns.len()
}

fn input_at(&self, at: u32) -> Option<&Self::Type> {
self.params.get(at as usize)
}

fn output_at(&self, at: u32) -> Option<&Self::Type> {
self.returns.get(at as usize)
}
}

impl WasmGlobalType for crate::GlobalType {
type Type = crate::Type;

fn is_mutable(&self) -> bool {
self.mutable
}

fn content_type(&self) -> &Self::Type {
&self.content_type
}
}

impl WasmTableType for crate::TableType {
type Type = crate::Type;

fn element_type(&self) -> &Self::Type {
&self.element_type
}

fn initial_limit(&self) -> u32 {
self.limits.initial
}

fn maximum_limit(&self) -> Option<u32> {
self.limits.maximum
}
}

impl WasmMemoryType for crate::MemoryType {
fn is_shared(&self) -> bool {
self.shared
}

fn initial_limit(&self) -> u32 {
self.limits.initial
}
fn maximum_limit(&self) -> Option<u32> {
self.limits.maximum
}
}
Loading