Add accessors for various stack operations
This commit is contained in:
parent
b3c931a38e
commit
0e23793d72
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user