-
Notifications
You must be signed in to change notification settings - Fork 24
Complete implementation for Verify
#744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 = (); | ||
|
||
|
@@ -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 { | ||
|
@@ -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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a bit surprised by this. In theory, we should have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you explain why you believe so? Before this function, For For There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What does this mean?
|
||
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 | ||
} | ||
} | ||
|
||
|
@@ -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())?, | ||
} | ||
|
@@ -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; | ||
|
@@ -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 | ||
} | ||
}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good to have side table views specific to verification in
valid.rs
becauseexec.rs
will need different views (it won't need the mutable index used only for verification).