Skip to content

Commit

Permalink
Add the Verify mode (#726)
Browse files Browse the repository at this point in the history
#46

---------

Co-authored-by: Zhou Fang <[email protected]>
Co-authored-by: Julien Cretin <[email protected]>
  • Loading branch information
3 people authored Feb 7, 2025
1 parent 8ff8d8e commit e16faf8
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 131 deletions.
2 changes: 1 addition & 1 deletion crates/interpreter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,4 @@ pub use module::Module;
pub use syntax::{
FuncType, GlobalType, ImportDesc, Limits, Mut, RefType, ResultType, TableType, ValType,
};
pub use valid::validate;
pub use valid::prepare;
4 changes: 2 additions & 2 deletions crates/interpreter/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::parser::{SkipData, SkipElem};
use crate::side_table::*;
use crate::syntax::*;
use crate::toctou::*;
use crate::valid::validate;
use crate::valid::prepare;
use crate::*;

/// Valid module.
Expand Down Expand Up @@ -52,7 +52,7 @@ impl ImportDesc {
impl<'m> Module<'m> {
/// Validates a WASM module in binary format.
pub fn new(binary: &'m [u8]) -> Result<Self, Error> {
let side_table = validate(binary)?;
let side_table = prepare(binary)?;
let mut module = unsafe { Self::new_unchecked(binary) };
// TODO(dev/fast-interp): We should take a buffer as argument to write to.
module.side_table = Box::leak(Box::new(side_table));
Expand Down
47 changes: 35 additions & 12 deletions crates/interpreter/src/side_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,62 @@ use core::ops::Range;
use crate::error::*;
use crate::module::Parser;

#[allow(dead_code)]
pub struct SideTable<'m> {
indices: &'m [u16], // including 0 and the length of metadata_array
metadata: &'m [u16],
pub struct SideTableView<'m> {
pub func_idx: usize,
pub indices: &'m [u16], // including 0 and the length of metadata_array
pub metadata: &'m [u16],
pub branch_table_view: Metadata<'m>,
}

#[allow(dead_code)]
impl<'m> SideTable<'m> {
fn metadata(&self, func_idx: usize) -> Metadata<'m> {
impl<'m> SideTableView<'m> {
pub fn new(parser: &mut crate::valid::Parser<'m>) -> Result<Self, Error> {
Ok(SideTableView {
func_idx: 0,
indices: parse_side_table_field(parser)?,
metadata: parse_side_table_field(parser)?,
branch_table_view: Default::default(),
})
}

pub fn metadata(&self, func_idx: usize) -> Metadata<'m> {
Metadata(
&self.metadata[self.indices[func_idx] as usize .. self.indices[func_idx + 1] as usize],
)
}
}

#[allow(dead_code)]
#[derive(Copy, Clone)]
struct Metadata<'m>(&'m [u16]);
fn parse_u16(data: &[u8]) -> u16 {
bytemuck::pod_read_unaligned::<u16>(bytemuck::cast_slice(&data[0 .. 2]))
}

fn parse_side_table_field<'m>(parser: &mut crate::valid::Parser<'m>) -> Result<&'m [u16], Error> {
let len = parse_u16(parser.save()) as usize;
let parser = parser.split_at(len)?;
let bytes = parser.save().get(0 .. len * 2).unwrap();
Ok(bytemuck::cast_slice::<_, u16>(bytes))
}

#[derive(Default, Copy, Clone)]
pub struct Metadata<'m>(&'m [u16]);

#[allow(dead_code)]
impl<'m> Metadata<'m> {
pub fn type_idx(&self) -> usize {
self.0[0] as usize
}

#[allow(dead_code)]
pub fn parser(&self, module: &'m [u8]) -> Parser<'m> {
unsafe { Parser::new(&module[self.read_u32(1) .. self.read_u32(3)]) }
unsafe { Parser::new(&module[self.parser_range()]) }
}

pub fn branch_table(&self) -> &[BranchTableEntry] {
bytemuck::cast_slice(&self.0[5 ..])
}

pub fn parser_range(&self) -> Range<usize> {
self.read_u32(1) .. self.read_u32(3)
}

fn read_u32(&self, idx: usize) -> usize {
bytemuck::pod_read_unaligned::<u32>(bytemuck::cast_slice(&self.0[idx .. idx + 2])) as usize
}
Expand Down
Loading

0 comments on commit e16faf8

Please sign in to comment.