From 0e23793d72e0691893738c0bb375970be46558d0 Mon Sep 17 00:00:00 2001 From: Rerumu Date: Fri, 17 Jun 2022 21:33:04 -0400 Subject: [PATCH] Add accessors for various stack operations --- wasm-ast/src/builder.rs | 14 ++++++------- wasm-ast/src/node.rs | 12 ----------- wasm-ast/src/stack.rs | 44 ++++++++++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/wasm-ast/src/builder.rs b/wasm-ast/src/builder.rs index b37ba19..abdbe7e 100644 --- a/wasm-ast/src/builder.rs +++ b/wasm-ast/src/builder.rs @@ -18,8 +18,8 @@ macro_rules! leak_on { fn $name(&mut self, id: usize) { let read = ReadType::$variant(id); - for i in 0..self.stack.var_list.len() { - if self.stack.var_list[i].read.contains(&read) { + for i in 0..self.stack.len() { + if self.stack.get(i).has_read(read) { self.leak_at(i); } } @@ -179,7 +179,7 @@ impl StatList { } fn leak_all(&mut self) { - for i in 0..self.stack.var_list.len() { + for i in 0..self.stack.len() { self.leak_at(i); } } @@ -464,7 +464,7 @@ impl<'a> Builder<'a> { let arity = self.type_info.rel_arity_of(func); let param_list = self.target.stack.pop_len(arity.num_param).collect(); - let first = self.target.stack.var_list.len(); + let first = self.target.stack.len(); let result = first..first + arity.num_result; self.target.leak_all(); @@ -484,7 +484,7 @@ impl<'a> Builder<'a> { let index = self.target.stack.pop(); let param_list = self.target.stack.pop_len(arity.num_param).collect(); - let first = self.target.stack.var_list.len(); + let first = self.target.stack.len(); let result = first..first + arity.num_result; self.target.leak_all(); @@ -607,9 +607,9 @@ impl<'a> Builder<'a> { self.add_call_indirect(i.try_into().unwrap(), t.into()); } Inst::Drop => { - let last = self.target.stack.var_list.len() - 1; + let last = self.target.stack.len() - 1; - if self.target.stack.var_list[last].data.has_side_effect() { + if self.target.stack.get(last).has_side_effect() { self.target.leak_at(last); } diff --git a/wasm-ast/src/node.rs b/wasm-ast/src/node.rs index cb808ee..b391320 100644 --- a/wasm-ast/src/node.rs +++ b/wasm-ast/src/node.rs @@ -627,18 +627,6 @@ pub enum Expression { CmpOp(CmpOp), } -impl Expression { - #[must_use] - pub fn has_side_effect(&self) -> bool { - matches!(self, Expression::MemorySize(_)) - } - - #[must_use] - pub fn is_temporary(&self, id: usize) -> bool { - matches!(self, Expression::GetTemporary(v) if v.var == id) - } -} - pub struct Align { pub new: usize, pub old: usize, diff --git a/wasm-ast/src/stack.rs b/wasm-ast/src/stack.rs index 680a4ce..815d4c2 100644 --- a/wasm-ast/src/stack.rs +++ b/wasm-ast/src/stack.rs @@ -4,7 +4,7 @@ use crate::node::{ Align, Expression, GetGlobal, GetLocal, GetTemporary, LoadAt, SetTemporary, Statement, }; -#[derive(PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub enum ReadType { Local(usize), Global(usize), @@ -12,24 +12,46 @@ pub enum ReadType { } pub struct Slot { - pub read: HashSet, - pub data: Expression, + read: HashSet, + data: Expression, +} + +impl Slot { + pub fn has_read(&self, read: ReadType) -> bool { + self.read.contains(&read) + } + + pub fn has_side_effect(&self) -> bool { + matches!(self.data, Expression::MemoryGrow(_)) + } + + pub fn is_temporary(&self, id: usize) -> bool { + matches!(self.data, Expression::GetTemporary(ref v) if v.var == id) + } } #[derive(Default)] pub struct Stack { - pub var_list: Vec, + var_list: Vec, pub capacity: usize, pub previous: usize, } impl Stack { + pub fn len(&self) -> usize { + self.var_list.len() + } + + pub fn get(&self, index: usize) -> &Slot { + &self.var_list[index] + } + pub fn split_last(&mut self, len: usize) -> Self { - let desired = self.var_list.len() - len; - let content = self.var_list.split_off(desired); + let desired = self.len() - len; + let var_list = self.var_list.split_off(desired); Self { - var_list: content, + var_list, capacity: self.capacity, previous: self.previous + desired, } @@ -67,13 +89,13 @@ impl Stack { } pub fn pop_len(&'_ mut self, len: usize) -> impl Iterator + '_ { - let desired = self.var_list.len() - len; + let desired = self.len() - len; self.var_list.drain(desired..).map(|v| v.data) } pub fn push_temporary(&mut self, num: usize) { - let len = self.var_list.len() + self.previous; + let len = self.len() + self.previous; for var in len..len + num { let data = Expression::GetTemporary(GetTemporary { var }); @@ -90,7 +112,7 @@ impl Stack { let old = &mut self.var_list[index]; let var = self.previous + index; - if old.data.is_temporary(var) { + if old.is_temporary(var) { return None; } @@ -110,7 +132,7 @@ impl Stack { // Return the alignment necessary for this block to branch out to a // another given stack frame pub fn get_br_alignment(&self, par_start: usize, par_result: usize) -> Align { - let start = self.var_list.len() + self.previous - par_result; + let start = self.len() + self.previous - par_result; Align { new: par_start,