fuzzbug fix

This commit is contained in:
Chris Fallin 2021-12-24 11:42:02 -08:00
parent 1bd6b25d34
commit 80f7fc8a6c
4 changed files with 28 additions and 63 deletions

View file

@ -155,12 +155,7 @@ pub fn produce_func_wasm(f: &FunctionBody, body: &SerializedBody, locations: &Lo
wasm.locals
.extend(locations.new_locals.iter().map(|ty| ty_to_valty(*ty)));
let mut next_delete = 0;
for (index, operator) in body.operators.iter().enumerate() {
if next_delete < locations.delete.len() && locations.delete[next_delete] == index {
next_delete += 1;
continue;
}
for operator in &body.operators {
wasm.translate(operator, locations);
}

View file

@ -9,7 +9,6 @@ use super::{SerializedBody, SerializedOperator};
#[derive(Debug)]
pub struct Locations {
pub locations: FxHashMap<(Value, usize), LocalId>,
pub delete: Vec<usize>,
pub new_locals: Vec<wasmparser::Type>,
}
@ -42,7 +41,6 @@ impl Locations {
pub fn compute(f: &FunctionBody, body: &SerializedBody) -> Locations {
let mut locations = Locations {
locations: FxHashMap::default(),
delete: vec![],
new_locals: vec![],
};
let mut allocator = Allocator {
@ -54,7 +52,7 @@ impl Locations {
ends: vec![],
};
allocator.compute_spans_and_deleted_ops(&body.operators[..]);
allocator.compute_spans(&body.operators[..]);
locations
}
@ -73,6 +71,14 @@ impl<'a> Allocator<'a> {
},
);
log::trace!(
"handle_op: at location {} op {:?} reads {:?} writes {:?}",
location,
op,
reads,
writes
);
for (value, index) in reads {
let span = match self.spans.get_mut(&(value, index)) {
Some(span) => span,
@ -81,64 +87,24 @@ impl<'a> Allocator<'a> {
}
};
span.end = location + 1;
log::trace!(" -> span for {}: {:?}", value, span);
}
for (value, index) in writes {
self.spans
.entry((value, index))
.or_insert(ValueSpan {
value,
multi_value_index: index,
start: location,
end: location + 1,
})
.end = location + 1;
let span = self.spans.entry((value, index)).or_insert(ValueSpan {
value,
multi_value_index: index,
start: location,
end: location + 1,
});
span.end = location + 1;
log::trace!(" -> span for {}: {:?}", value, span);
}
}
fn compute_spans_and_deleted_ops(&mut self, operators: &[SerializedOperator]) {
// Delete runs of Set(A), Set(B), Get(B), Get(A): these are
// stack-neutral sequences.
let mut start = None;
let mut current_run = vec![];
fn compute_spans(&mut self, operators: &[SerializedOperator]) {
// For each operator, get the reads and writes and construct spans.
for (index, operator) in operators.iter().enumerate() {
match operator {
&SerializedOperator::Set(..) if start.is_none() => {
start = Some(index);
current_run.push(operator.clone());
}
&SerializedOperator::Set(..) => {
current_run.push(operator.clone());
}
&SerializedOperator::Get(v, i)
if start.is_some()
&& current_run.last() == Some(&SerializedOperator::Set(v, i)) =>
{
current_run.pop();
if current_run.is_empty() {
for i in start.unwrap()..=index {
self.locations.delete.push(i);
}
start = None;
}
}
_ => {
current_run.clear();
start = None;
}
}
}
// For each non-deleted operator, get the reads and writes and construct spans.
let mut next_delete = 0;
for (index, operator) in operators.iter().enumerate() {
if next_delete < self.locations.delete.len()
&& self.locations.delete[next_delete] == index
{
next_delete += 1;
continue;
}
self.handle_op(index, operator);
}

View file

@ -400,6 +400,7 @@ impl<'a> SerializedBodyContext<'a> {
// Now push the args in reverse order.
for &arg in operands.iter().rev() {
let arg = self.f.resolve_alias(arg);
match &self.f.values[arg.index()] {
&ValueDef::Operator(op, ..) => {
if op_rematerialize(&op) {

View file

@ -25,6 +25,7 @@ impl UseCountAnalysis {
for &value in &f.blocks[block].insts {
if value != Value::undef() {
let value = f.resolve_alias(value);
counts.add(value);
if workqueue_set.insert(value) {
workqueue.push_back(value);
}
@ -34,6 +35,7 @@ impl UseCountAnalysis {
f.blocks[block].terminator.visit_uses(|value| {
if value != Value::undef() {
let value = f.resolve_alias(value);
counts.add(value);
if workqueue_set.insert(value) {
workqueue.push_back(value);
}
@ -42,7 +44,6 @@ impl UseCountAnalysis {
while let Some(value) = workqueue.pop_front() {
workqueue_set.remove(&value);
counts.add(value);
match &f.values[value.index()] {
&ValueDef::Alias(..) | &ValueDef::Arg(..) | &ValueDef::BlockParam(..) => {}
&ValueDef::Operator(_op, ref args) => {
@ -51,7 +52,8 @@ impl UseCountAnalysis {
continue;
}
let arg = f.resolve_alias(arg);
if counts.use_count[arg.index()] == 0 {
counts.add(arg);
if counts.use_count[arg.index()] == 1 {
if workqueue_set.insert(arg) {
workqueue.push_back(arg);
}
@ -63,7 +65,8 @@ impl UseCountAnalysis {
continue;
}
let value = f.resolve_alias(value);
if counts.use_count[value.index()] == 0 {
counts.add(value);
if counts.use_count[value.index()] == 1 {
if workqueue_set.insert(value) {
workqueue.push_back(value);
}