Skip to content

Commit c89333b

Browse files
zhouwfangia0
andauthored
Make metadata(), parse_u16() and view() generic (#775)
#46 --------- Co-authored-by: Zhou Fang <[email protected]> Co-authored-by: Julien Cretin <[email protected]>
1 parent 36f42c2 commit c89333b

File tree

4 files changed

+24
-28
lines changed

4 files changed

+24
-28
lines changed

crates/interpreter/src/exec.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,8 @@ impl<'m> Thread<'m> {
10451045
return self.exit_frame();
10461046
}
10471047
frame.labels_cnt = i;
1048-
let BranchTableEntryView { val_cnt, pop_cnt, .. } = frame.side_table[offset].view();
1048+
let Ok(BranchTableEntryView { val_cnt, pop_cnt, .. }) =
1049+
frame.side_table[offset].view::<Use>();
10491050
let val_pos = self.values().len() - val_cnt as usize;
10501051
self.values().drain(val_pos - pop_cnt as usize .. val_pos);
10511052
self.take_jump(offset);
@@ -1413,7 +1414,7 @@ impl<'m> Frame<'m> {
14131414

14141415
fn take_jump(&mut self, parser_pos: &'m [u8], offset: usize) -> Parser<'m> {
14151416
self.side_table = offset_front(self.side_table, offset as isize);
1416-
let entry = self.side_table[0].view();
1417+
let entry = self.side_table[0].view::<Use>().into_ok();
14171418
self.side_table = offset_front(self.side_table, entry.delta_stp as isize);
14181419
unsafe { Parser::new(offset_front(parser_pos, entry.delta_ip as isize)) }
14191420
}

crates/interpreter/src/module.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl<'m> Module<'m> {
112112
}
113113

114114
pub(crate) fn func_type(&self, x: FuncIdx) -> FuncType<'m> {
115-
self.types[self.side_table.metadata(x as usize).type_idx()]
115+
self.types[self.side_table.metadata::<Use>(x as usize).into_ok().type_idx()]
116116
}
117117

118118
pub(crate) fn table_type(&self, x: TableIdx) -> TableType {
@@ -173,7 +173,7 @@ impl<'m> Module<'m> {
173173
}
174174

175175
pub(crate) fn func(&self, x: FuncIdx) -> (Parser<'m>, &'m [BranchTableEntry]) {
176-
let metadata = self.side_table.metadata(x as usize);
176+
let metadata = self.side_table.metadata::<Use>(x as usize).into_ok();
177177
(unsafe { Parser::new(&self.binary[metadata.parser_range()]) }, metadata.branch_table())
178178
}
179179

crates/interpreter/src/side_table.rs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use alloc::vec::Vec;
1616
use core::ops::Range;
1717

1818
use crate::error::*;
19-
use crate::module::Parser;
19+
use crate::toctou::*;
2020

2121
pub const SECTION_NAME: &str = "wasefire-sidetable";
2222

@@ -27,13 +27,12 @@ pub struct SideTableView<'m> {
2727
}
2828

2929
impl<'m> SideTableView<'m> {
30-
// TODO(dev/fast-interp): Make it generic since it will be used in both `Check` and `Use` modes.
31-
// (Returns `MResult<Metadata<'m>, M>` instead.)
32-
pub fn metadata(&self, func_idx: usize) -> Metadata<'m> {
33-
Metadata(
34-
&self.metadata[parse_u16(self.indices, func_idx * 2) as usize
35-
.. parse_u16(self.indices, (func_idx + 1) * 2) as usize],
36-
)
30+
pub fn metadata<M: Mode>(&self, func_idx: usize) -> MResult<Metadata<'m>, M> {
31+
let start_idx = M::open(|| func_idx.checked_mul(2))?;
32+
let end_idx = M::open(|| start_idx.checked_add(2))?;
33+
let start = parse_u16::<M>(self.indices, start_idx)? as usize;
34+
let end = parse_u16::<M>(self.indices, end_idx)? as usize;
35+
Ok(Metadata(M::open(|| self.metadata.get(start .. end))?))
3736
}
3837
}
3938

@@ -42,12 +41,7 @@ pub struct Metadata<'m>(&'m [u8]);
4241

4342
impl<'m> Metadata<'m> {
4443
pub fn type_idx(&self) -> usize {
45-
parse_u16(self.0, 0) as usize
46-
}
47-
48-
#[allow(dead_code)]
49-
pub fn parser(&self, module: &'m [u8]) -> Parser<'m> {
50-
unsafe { Parser::new(&module[self.parser_range()]) }
44+
parse_u16::<Use>(self.0, 0).into_ok() as usize
5145
}
5246

5347
pub fn branch_table(&self) -> &'m [BranchTableEntry] {
@@ -137,14 +131,14 @@ impl BranchTableEntry {
137131
]))
138132
}
139133

140-
pub fn view(self) -> BranchTableEntryView {
141-
let pop_val_counts = parse_u16(&self.0, 4);
142-
BranchTableEntryView {
143-
delta_ip: (parse_u16(&self.0, 0) as i16) as i32,
144-
delta_stp: (parse_u16(&self.0, 2) as i16) as i32,
134+
pub fn view<M: Mode>(self) -> MResult<BranchTableEntryView, M> {
135+
let pop_val_counts = parse_u16::<M>(&self.0, 4)?;
136+
Ok(BranchTableEntryView {
137+
delta_ip: (parse_u16::<M>(&self.0, 0)? as i16) as i32,
138+
delta_stp: (parse_u16::<M>(&self.0, 2)? as i16) as i32,
145139
val_cnt: (pop_val_counts & 0xf) as u32,
146140
pop_cnt: (pop_val_counts >> 4) as u32,
147-
}
141+
})
148142
}
149143

150144
pub fn is_invalid(self) -> bool {
@@ -156,8 +150,9 @@ impl BranchTableEntry {
156150
}
157151
}
158152

159-
fn parse_u16(data: &[u8], offset: usize) -> u16 {
160-
u16::from_le_bytes(data[offset ..][.. 2].try_into().unwrap())
153+
fn parse_u16<M: Mode>(data: &[u8], offset: usize) -> MResult<u16, M> {
154+
let bytes = M::open(|| try { data.get(offset .. offset.checked_add(2)?)? })?;
155+
Ok(u16::from_le_bytes(bytes.try_into().unwrap()))
161156
}
162157

163158
fn parse_u32(data: &[u8], offset: usize) -> u32 {

crates/interpreter/src/valid.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impl ValidMode for Verify {
164164
fn next_branch_table<'a, 'm>(
165165
side_table: &'a mut Self::SideTable<'m>, type_idx: usize, parser_range: Range<usize>,
166166
) -> Result<Self::BranchTable<'a, 'm>, Error> {
167-
let metadata = side_table.view.metadata(side_table.func_idx);
167+
let metadata = side_table.view.metadata::<Check>(side_table.func_idx)?;
168168
side_table.func_idx += 1;
169169
check(metadata.type_idx() == type_idx)?;
170170
check(metadata.parser_range() == parser_range)?;
@@ -190,7 +190,7 @@ impl<'m> BranchTableApi<'m> for MetadataView<'m> {
190190
}
191191

192192
fn patch_branch(&self, mut source: SideTableBranch<'m>) -> Result<SideTableBranch<'m>, Error> {
193-
let entry = self.metadata.branch_table()[source.branch_table].view();
193+
let entry = self.metadata.branch_table()[source.branch_table].view::<Check>()?;
194194
// TODO(dev/fast-interp): We want a safe version of offset_front.
195195
source.parser = offset_front(source.parser, entry.delta_ip as isize);
196196
source.branch_table =

0 commit comments

Comments
 (0)