Add accessors for various stack operations

This commit is contained in:
Rerumu 2022-06-17 21:33:04 -04:00
parent b3c931a38e
commit 0e23793d72
3 changed files with 40 additions and 30 deletions

View File

@ -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);
}

View File

@ -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,

View File

@ -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<ReadType>,
pub data: Expression,
read: HashSet<ReadType>,
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<Slot>,
var_list: Vec<Slot>,
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<Item = Expression> + '_ {
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,