Skip to content

Commit

Permalink
Complete implementation for Verify (#744)
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 17, 2025
1 parent b254c7e commit 888c329
Showing 1 changed file with 23 additions and 19 deletions.
42 changes: 23 additions & 19 deletions crates/interpreter/src/valid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,18 @@ impl<'m> BranchTableApi<'m> for &mut Vec<BranchTableEntry> {
}
}

struct MetadataView<'m> {
metadata: Metadata<'m>,
branch_idx: usize,
}

#[derive(Default)]
struct Verify;
impl ValidMode for Verify {
/// Contains at most one _target_ branch. Source branches are eagerly patched to
/// their target branch using the branch table.
type Branches<'m> = Option<SideTableBranch<'m>>;
type BranchTable<'a, 'm> = Metadata<'m>;
type BranchTable<'a, 'm> = MetadataView<'m>;
type SideTable<'m> = SideTableView<'m>;
type Result = ();

Expand All @@ -152,11 +157,11 @@ impl ValidMode for Verify {
fn next_branch_table<'a, 'm>(
side_table: &'a mut Self::SideTable<'m>, type_idx: usize, parser_range: Range<usize>,
) -> Result<Self::BranchTable<'a, 'm>, Error> {
let branch_table = side_table.metadata(side_table.func_idx);
let metadata = side_table.metadata(side_table.func_idx);
side_table.func_idx += 1;
check(branch_table.type_idx() == type_idx)?;
check(branch_table.parser_range() == parser_range)?;
Ok(branch_table)
check(metadata.type_idx() == type_idx)?;
check(metadata.parser_range() == parser_range)?;
Ok(MetadataView { metadata, branch_idx: 0 })
}

fn side_table_result(side_table: Self::SideTable<'_>) -> Self::Result {
Expand All @@ -170,26 +175,29 @@ impl<'m> BranchesApi<'m> for Option<SideTableBranch<'m>> {
}
}

impl<'m> BranchTableApi<'m> for Metadata<'m> {
impl<'m> BranchTableApi<'m> for MetadataView<'m> {
fn stitch_branch(
&mut self, source: SideTableBranch<'m>, target: SideTableBranch<'m>,
) -> CheckResult {
check(source == target)
}

fn patch_branch(&self, mut source: SideTableBranch<'m>) -> Result<SideTableBranch<'m>, Error> {
let entry = self.branch_table()[source.branch_table].view();
source.branch_table = self.branch_idx;
let entry = self.metadata.branch_table()[source.branch_table].view();
offset_front(source.parser, entry.delta_ip as isize);
source.branch_table += entry.delta_stp as usize;
source.result = entry.val_cnt as usize;
source.stack -= entry.pop_cnt as usize;
Ok(source)
}

fn allocate_branch(&mut self) {}
fn allocate_branch(&mut self) {
self.branch_idx += 1;
}

fn next_index(&self) -> usize {
0
self.branch_idx
}
}

Expand Down Expand Up @@ -704,11 +712,7 @@ impl<'a, 'm, M: ValidMode> Expr<'a, 'm, M> {
let result = self.label().type_.results.len();
let mut target = self.branch_target(result);
target.branch_table += 1;
M::BranchTable::stitch_branch(
self.branch_table.as_mut().unwrap(),
source,
target,
)?;
self.branch_table.as_mut().unwrap().stitch_branch(source, target)?;
}
_ => Err(invalid())?,
}
Expand Down Expand Up @@ -975,14 +979,14 @@ impl<'a, 'm, M: ValidMode> Expr<'a, 'm, M> {
let results_len = self.label().type_.results.len();
let mut target = self.branch_target(results_len);
for source in branches {
M::BranchTable::stitch_branch(self.branch_table.as_mut().unwrap(), source, target)?;
self.branch_table.as_mut().unwrap().stitch_branch(source, target)?;
}
let label = self.label();
if let LabelKind::If(source) = label.kind {
check(label.type_.params == label.type_.results)?;
// SAFETY: This function is only called after parsing an End instruction.
target.parser = offset_front(target.parser, -1);
M::BranchTable::stitch_branch(self.branch_table.as_mut().unwrap(), source, target)?;
self.branch_table.as_mut().unwrap().stitch_branch(source, target)?;
}
}
let results = self.label().type_.results;
Expand All @@ -999,15 +1003,15 @@ impl<'a, 'm, M: ValidMode> Expr<'a, 'm, M> {
let n = self.labels.len();
check(l < n)?;
let source = self.branch_source();
let source = M::BranchTable::patch_branch(self.branch_table.as_ref().unwrap(), source)?;
let source = self.branch_table.as_ref().unwrap().patch_branch(source)?;
let label = &mut self.labels[n - l - 1];
Ok(match label.kind {
LabelKind::Block | LabelKind::If(_) => {
M::Branches::push_branch(&mut label.branches, source)?;
label.branches.push_branch(source)?;
label.type_.results
}
LabelKind::Loop(target) => {
M::BranchTable::stitch_branch(self.branch_table.as_mut().unwrap(), source, target)?;
self.branch_table.as_mut().unwrap().stitch_branch(source, target)?;
label.type_.params
}
})
Expand Down

0 comments on commit 888c329

Please sign in to comment.