Fix stack size heuristic overshooting
This commit is contained in:
parent
c756b4bc6d
commit
a7f30b8157
@ -165,6 +165,10 @@ impl StatList {
|
|||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_data(&mut self, data: Expression) {
|
||||||
|
self.stack.push(data);
|
||||||
|
}
|
||||||
|
|
||||||
fn pop_required(&mut self) -> Expression {
|
fn pop_required(&mut self) -> Expression {
|
||||||
self.stack.pop().unwrap()
|
self.stack.pop().unwrap()
|
||||||
}
|
}
|
||||||
@ -173,9 +177,16 @@ impl StatList {
|
|||||||
self.stack.split_off(self.stack.len() - len)
|
self.stack.split_off(self.stack.len() - len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_tracked(&mut self, data: Expression) {
|
fn push_temporary(&mut self, num: usize) {
|
||||||
self.stack.push(data);
|
let len = self.stack.len() + self.num_previous;
|
||||||
self.num_stack = self.num_stack.max(self.stack.len());
|
|
||||||
|
for var in len..len + num {
|
||||||
|
let data = Expression::GetTemporary(GetTemporary { var });
|
||||||
|
|
||||||
|
self.push_data(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.num_stack = self.num_stack.max(len + num);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn leak_at(&mut self, index: usize) {
|
fn leak_at(&mut self, index: usize) {
|
||||||
@ -192,6 +203,7 @@ impl StatList {
|
|||||||
value: std::mem::replace(old, get),
|
value: std::mem::replace(old, get),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.num_stack = self.num_stack.max(var + 1);
|
||||||
self.code.push(set);
|
self.code.push(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,18 +231,6 @@ impl StatList {
|
|||||||
self.leak_with(|_| true);
|
self.leak_with(|_| true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_temporary(&mut self, num: usize) {
|
|
||||||
let len = self.stack.len();
|
|
||||||
|
|
||||||
for i in len..len + num {
|
|
||||||
let data = Expression::GetTemporary(GetTemporary {
|
|
||||||
var: self.num_previous + i,
|
|
||||||
});
|
|
||||||
|
|
||||||
self.push_tracked(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn push_load(&mut self, what: LoadType, offset: u32) {
|
fn push_load(&mut self, what: LoadType, offset: u32) {
|
||||||
let data = Expression::LoadAt(LoadAt {
|
let data = Expression::LoadAt(LoadAt {
|
||||||
what,
|
what,
|
||||||
@ -238,7 +238,7 @@ impl StatList {
|
|||||||
pointer: self.pop_required().into(),
|
pointer: self.pop_required().into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.push_tracked(data);
|
self.push_data(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_store(&mut self, what: StoreType, offset: u32) {
|
fn add_store(&mut self, what: StoreType, offset: u32) {
|
||||||
@ -256,7 +256,7 @@ impl StatList {
|
|||||||
fn push_constant<T: Into<Value>>(&mut self, value: T) {
|
fn push_constant<T: Into<Value>>(&mut self, value: T) {
|
||||||
let value = Expression::Value(value.into());
|
let value = Expression::Value(value.into());
|
||||||
|
|
||||||
self.push_tracked(value);
|
self.push_data(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_un_op(&mut self, op: UnOpType) {
|
fn push_un_op(&mut self, op: UnOpType) {
|
||||||
@ -265,7 +265,7 @@ impl StatList {
|
|||||||
rhs: self.pop_required().into(),
|
rhs: self.pop_required().into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.push_tracked(data);
|
self.push_data(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_bin_op(&mut self, op: BinOpType) {
|
fn push_bin_op(&mut self, op: BinOpType) {
|
||||||
@ -275,7 +275,7 @@ impl StatList {
|
|||||||
lhs: self.pop_required().into(),
|
lhs: self.pop_required().into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.push_tracked(data);
|
self.push_data(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_cmp_op(&mut self, op: CmpOpType) {
|
fn push_cmp_op(&mut self, op: CmpOpType) {
|
||||||
@ -285,7 +285,7 @@ impl StatList {
|
|||||||
lhs: self.pop_required().into(),
|
lhs: self.pop_required().into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.push_tracked(data);
|
self.push_data(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eqz is the only unary comparison so it's "emulated"
|
// Eqz is the only unary comparison so it's "emulated"
|
||||||
@ -433,6 +433,7 @@ impl<'a> Builder<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.target.stack = old.pop_len(num_param);
|
self.target.stack = old.pop_len(num_param);
|
||||||
|
self.target.num_stack = old.num_stack;
|
||||||
self.target.num_previous = old.num_previous + old.stack.len();
|
self.target.num_previous = old.num_previous + old.stack.len();
|
||||||
|
|
||||||
old.push_temporary(num_result);
|
old.push_temporary(num_result);
|
||||||
@ -664,14 +665,14 @@ impl<'a> Builder<'a> {
|
|||||||
a: self.target.pop_required().into(),
|
a: self.target.pop_required().into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.target.push_tracked(data);
|
self.target.push_data(data);
|
||||||
}
|
}
|
||||||
Inst::GetLocal(i) => {
|
Inst::GetLocal(i) => {
|
||||||
let data = Expression::GetLocal(GetLocal {
|
let data = Expression::GetLocal(GetLocal {
|
||||||
var: i.try_into().unwrap(),
|
var: i.try_into().unwrap(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.target.push_tracked(data);
|
self.target.push_data(data);
|
||||||
}
|
}
|
||||||
Inst::SetLocal(i) => {
|
Inst::SetLocal(i) => {
|
||||||
let var = i.try_into().unwrap();
|
let var = i.try_into().unwrap();
|
||||||
@ -692,7 +693,7 @@ impl<'a> Builder<'a> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.target.leak_local_write(var);
|
self.target.leak_local_write(var);
|
||||||
self.target.push_tracked(get);
|
self.target.push_data(get);
|
||||||
self.target.code.push(set);
|
self.target.code.push(set);
|
||||||
}
|
}
|
||||||
Inst::GetGlobal(i) => {
|
Inst::GetGlobal(i) => {
|
||||||
@ -700,7 +701,7 @@ impl<'a> Builder<'a> {
|
|||||||
var: i.try_into().unwrap(),
|
var: i.try_into().unwrap(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.target.push_tracked(data);
|
self.target.push_data(data);
|
||||||
}
|
}
|
||||||
Inst::SetGlobal(i) => {
|
Inst::SetGlobal(i) => {
|
||||||
let var = i.try_into().unwrap();
|
let var = i.try_into().unwrap();
|
||||||
@ -739,7 +740,7 @@ impl<'a> Builder<'a> {
|
|||||||
let memory = i.try_into().unwrap();
|
let memory = i.try_into().unwrap();
|
||||||
let data = Expression::MemorySize(MemorySize { memory });
|
let data = Expression::MemorySize(MemorySize { memory });
|
||||||
|
|
||||||
self.target.push_tracked(data);
|
self.target.push_data(data);
|
||||||
}
|
}
|
||||||
Inst::GrowMemory(i) => {
|
Inst::GrowMemory(i) => {
|
||||||
let memory = i.try_into().unwrap();
|
let memory = i.try_into().unwrap();
|
||||||
@ -748,7 +749,7 @@ impl<'a> Builder<'a> {
|
|||||||
value: self.target.pop_required().into(),
|
value: self.target.pop_required().into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
self.target.push_tracked(data);
|
self.target.push_data(data);
|
||||||
self.target.leak_all();
|
self.target.leak_all();
|
||||||
}
|
}
|
||||||
Inst::I32Const(v) => self.target.push_constant(v),
|
Inst::I32Const(v) => self.target.push_constant(v),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user