Refactor stack leak code
This commit is contained in:
parent
bc64734add
commit
5f47092a65
@ -18,11 +18,7 @@ macro_rules! leak_on {
|
||||
fn $name(&mut self, id: usize) {
|
||||
let read = ReadType::$variant(id);
|
||||
|
||||
for i in 0..self.stack.len() {
|
||||
if self.stack.has_read_at(i, read) {
|
||||
self.leak_at(i);
|
||||
}
|
||||
}
|
||||
self.stack.leak_into(&mut self.code, |v| v.has_read(read))
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -172,16 +168,8 @@ impl StatList {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
fn leak_at(&mut self, index: usize) {
|
||||
if let Some(set) = self.stack.leak_at(index) {
|
||||
self.code.push(set);
|
||||
}
|
||||
}
|
||||
|
||||
fn leak_all(&mut self) {
|
||||
for i in 0..self.stack.len() {
|
||||
self.leak_at(i);
|
||||
}
|
||||
self.stack.leak_into(&mut self.code, |_| true);
|
||||
}
|
||||
|
||||
leak_on!(leak_local_write, Local);
|
||||
|
@ -20,6 +20,10 @@ impl Slot {
|
||||
fn is_temporary(&self, id: usize) -> bool {
|
||||
matches!(self.data, Expression::GetTemporary(ref v) if v.var == id)
|
||||
}
|
||||
|
||||
pub fn has_read(&self, id: ReadType) -> bool {
|
||||
self.read.contains(&id)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@ -97,10 +101,6 @@ impl Stack {
|
||||
range
|
||||
}
|
||||
|
||||
pub fn has_read_at(&self, index: usize, read: ReadType) -> bool {
|
||||
self.var_list[index].read.contains(&read)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@ -115,24 +115,28 @@ impl Stack {
|
||||
|
||||
// Try to leak a slot's value to a `SetTemporary` instruction,
|
||||
// adjusting the capacity and old index accordingly
|
||||
pub fn leak_at(&mut self, index: usize) -> Option<Statement> {
|
||||
let old = &mut self.var_list[index];
|
||||
let var = self.previous + index;
|
||||
pub fn leak_into<P>(&mut self, code: &mut Vec<Statement>, predicate: P)
|
||||
where
|
||||
P: Fn(&Slot) -> bool,
|
||||
{
|
||||
for (i, old) in self.var_list.iter_mut().enumerate() {
|
||||
let var = self.previous + i;
|
||||
|
||||
if old.is_temporary(var) {
|
||||
return None;
|
||||
if old.is_temporary(var) || !predicate(old) {
|
||||
continue;
|
||||
}
|
||||
|
||||
old.read.clear();
|
||||
|
||||
let get = Expression::GetTemporary(GetTemporary { var });
|
||||
let set = Statement::SetTemporary(SetTemporary {
|
||||
var,
|
||||
value: std::mem::replace(&mut old.data, get),
|
||||
});
|
||||
|
||||
self.capacity = self.capacity.max(var + 1);
|
||||
|
||||
code.push(set);
|
||||
}
|
||||
|
||||
old.read.clear();
|
||||
|
||||
let get = Expression::GetTemporary(GetTemporary { var });
|
||||
let set = Statement::SetTemporary(SetTemporary {
|
||||
var,
|
||||
value: std::mem::replace(&mut old.data, get),
|
||||
});
|
||||
|
||||
self.capacity = self.capacity.max(var + 1);
|
||||
|
||||
Some(set)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user