cranelift: Build a runtest case from fuzzer TestCase's (#4590)
* cranelift: Build a runtest case from fuzzer TestCase's * cranelift: Add a default expected output for a fuzzgen case
This commit is contained in:
@@ -8,13 +8,13 @@ use cranelift::codegen::ir::Function;
|
|||||||
use cranelift::codegen::Context;
|
use cranelift::codegen::Context;
|
||||||
use cranelift::prelude::*;
|
use cranelift::prelude::*;
|
||||||
use cranelift_native::builder_with_options;
|
use cranelift_native::builder_with_options;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
mod function_generator;
|
mod function_generator;
|
||||||
|
|
||||||
pub type TestCaseInput = Vec<DataValue>;
|
pub type TestCaseInput = Vec<DataValue>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TestCase {
|
pub struct TestCase {
|
||||||
pub func: Function,
|
pub func: Function,
|
||||||
/// Generate multiple test inputs for each test case.
|
/// Generate multiple test inputs for each test case.
|
||||||
@@ -22,6 +22,59 @@ pub struct TestCase {
|
|||||||
pub inputs: Vec<TestCaseInput>,
|
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 {
|
impl<'a> Arbitrary<'a> for TestCase {
|
||||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||||
FuzzGen::new(u)
|
FuzzGen::new(u)
|
||||||
|
|||||||
Reference in New Issue
Block a user