Skip to content
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

Use instead of restoring side table for Loop #705

Merged
merged 6 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
41 changes: 11 additions & 30 deletions crates/interpreter/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,20 +759,13 @@ impl<'m> Thread<'m> {

fn step(mut self, store: &mut Store<'m>) -> Result<ThreadResult<'m>, Error> {
use Instr::*;
let saved = self.parser.save();
let inst_id = self.frame().inst_id;
let inst = &mut store.insts[inst_id];
match self.parser.parse_instr().into_ok() {
Unreachable => return Err(trap()),
Nop => (),
Block(b) => self.push_label(self.blocktype(inst, &b), LabelKind::Block),
Loop(b) => {
let side_table = self.frame().side_table;
self.push_label(
self.blocktype(inst, &b),
LabelKind::Loop(LoopState { parser_data: saved, side_table }),
)
}
Loop(b) => self.push_label(self.blocktype(inst, &b), LabelKind::Loop),
If(b) => match self.pop_value().unwrap_i32() {
0 => {
self.take_jump(0);
Expand Down Expand Up @@ -988,11 +981,11 @@ impl<'m> Thread<'m> {
self.frames.last_mut().unwrap()
}

fn labels(&mut self) -> &mut Vec<Label<'m>> {
fn labels(&mut self) -> &mut Vec<Label> {
&mut self.frame().labels
}

fn label(&mut self) -> &mut Label<'m> {
fn label(&mut self) -> &mut Label {
self.labels().last_mut().unwrap()
}

Expand Down Expand Up @@ -1042,10 +1035,10 @@ impl<'m> Thread<'m> {
self.values().split_off(len)
}

fn push_label(&mut self, type_: FuncType<'m>, kind: LabelKind<'m>) {
fn push_label(&mut self, type_: FuncType<'m>, kind: LabelKind) {
let arity = match kind {
LabelKind::Block | LabelKind::If => type_.results.len(),
LabelKind::Loop(_) => type_.params.len(),
LabelKind::Loop => type_.params.len(),
};
let label = Label { arity, kind, values_cnt: type_.params.len() };
self.label().values_cnt -= label.values_cnt;
Expand All @@ -1064,11 +1057,7 @@ impl<'m> Thread<'m> {
self.values().drain(values_len - values_cnt .. values_len - arity);
self.label().values_cnt += arity;
match kind {
LabelKind::Loop(state) => unsafe {
self.frame().side_table = state.side_table;
self.parser.restore(state.parser_data)
},
LabelKind::Block | LabelKind::If => self.take_jump(offset),
LabelKind::Block | LabelKind::If | LabelKind::Loop => self.take_jump(offset),
zhouwfang marked this conversation as resolved.
Show resolved Hide resolved
}
ThreadResult::Continue(self)
}
Expand Down Expand Up @@ -1422,7 +1411,7 @@ struct Frame<'m> {
arity: usize,
ret: &'m [u8],
locals: Vec<Val>,
labels: Vec<Label<'m>>,
labels: Vec<Label>,
side_table: &'m [SideTableEntry],
}

Expand All @@ -1448,26 +1437,18 @@ impl<'m> Frame<'m> {
}

#[derive(Debug)]
struct Label<'m> {
struct Label {
arity: usize,
kind: LabelKind<'m>,
kind: LabelKind,
values_cnt: usize,
}

#[derive(Debug)]
struct LoopState<'m> {
parser_data: &'m [u8],
side_table: &'m [SideTableEntry],
}

#[derive(Debug)]
enum LabelKind<'m> {
enum LabelKind {
// TODO: If and Block can be merged and then we just have Option<NonNull<u8>> which is
// optimized.
Block,
// TODO: Could be just NonNull<u8> since we can reuse the end of current parser since it
// never changes.
Loop(LoopState<'m>),
Loop,
If,
}

Expand Down
20 changes: 13 additions & 7 deletions crates/interpreter/src/valid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,9 @@ impl<'a, 'm> Expr<'a, 'm> {
Block(b) => self.push_label(self.blocktype(&b)?, LabelKind::Block)?,
Loop(b) => {
let type_ = self.blocktype(&b)?;
self.push_label(type_, LabelKind::Loop(self.branch_target(type_.params.len())))?
let mut target = self.branch_target(type_.params.len());
target.parser = offset_parser(target, -2);
ia0 marked this conversation as resolved.
Show resolved Hide resolved
self.push_label(type_, LabelKind::Loop(target))?
}
If(b) => {
self.pop_check(ValType::I32)?;
Expand Down Expand Up @@ -859,12 +861,7 @@ impl<'a, 'm> Expr<'a, 'm> {
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 = unsafe {
core::slice::from_raw_parts(
target.parser.as_ptr().offset(-1),
target.parser.len() + 1,
)
};
target.parser = offset_parser(target, -1);
self.side_table.stitch(source, target)?;
}
let results = self.label().type_.results;
Expand Down Expand Up @@ -979,3 +976,12 @@ impl<'a, 'm> Expr<'a, 'm> {
}
}
}

fn offset_parser(branch: SideTableBranch, off: isize) -> &[u8] {
zhouwfang marked this conversation as resolved.
Show resolved Hide resolved
unsafe {
core::slice::from_raw_parts(
branch.parser.as_ptr().offset(off),
(branch.parser.len() as isize - off) as usize,
)
}
}
Loading