Skip to content

Commit

Permalink
cranelift: Build a runtest case from fuzzer TestCase's (#4590)
Browse files Browse the repository at this point in the history
* cranelift: Build a runtest case from fuzzer TestCase's

* cranelift: Add a default expected output for a fuzzgen case
  • Loading branch information
afonso360 authored Aug 10, 2022
1 parent 597eb6f commit 11f0b00
Showing 1 changed file with 54 additions and 1 deletion.
55 changes: 54 additions & 1 deletion cranelift/fuzzgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,73 @@ use cranelift::codegen::ir::Function;
use cranelift::codegen::Context;
use cranelift::prelude::*;
use cranelift_native::builder_with_options;
use std::fmt;

mod config;
mod function_generator;

pub type TestCaseInput = Vec<DataValue>;

#[derive(Debug)]
pub struct TestCase {
pub func: Function,
/// Generate multiple test inputs for each test case.
/// This allows us to get more coverage per compilation, which may be somewhat expensive.
pub inputs: Vec<TestCaseInput>,
}

impl fmt::Debug for TestCase {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
r#";; Fuzzgen test case
test interpret
test run
set enable_llvm_abi_extensions
target aarch64
target s390x
target x86_64
"#
)?;

writeln!(f, "{}", self.func)?;

writeln!(f, "; Note: the results in the below test cases are simply a placeholder and probably will be wrong\n")?;

for input in self.inputs.iter() {
// TODO: We don't know the expected outputs, maybe we can run the interpreter
// here to figure them out? Should work, however we need to be careful to catch
// panics in case its the interpreter that is failing.
// For now create a placeholder output consisting of the zero value for the type
let returns = &self.func.signature.returns;
let placeholder_output = returns
.iter()
.map(|param| DataValue::read_from_slice(&[0; 16][..], param.value_type))
.map(|val| format!("{}", val))
.collect::<Vec<_>>()
.join(", ");

// If we have no output, we don't need the == condition
let test_condition = match returns.len() {
0 => String::new(),
1 => format!(" == {}", placeholder_output),
_ => format!(" == [{}]", placeholder_output),
};

let args = input
.iter()
.map(|val| format!("{}", val))
.collect::<Vec<_>>()
.join(", ");

writeln!(f, "; run: {}({}){}", self.func.name, args, test_condition)?;
}

Ok(())
}
}

impl<'a> Arbitrary<'a> for TestCase {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
FuzzGen::new(u)
Expand Down

0 comments on commit 11f0b00

Please sign in to comment.