Add a spec test fuzzer for Config (#1509)
* Add a spec test fuzzer for Config This commit adds a new fuzzer which is intended to run on oss-fuzz. This fuzzer creates and arbitrary `Config` which *should* pass spec tests and then asserts that it does so. The goal here is to weed out any accidental bugs in global configuration which could cause non-spec-compliant behavior. * Move implementation to `fuzzing` crate
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
#[cfg(feature = "binaryen")]
|
||||
pub mod api;
|
||||
|
||||
use arbitrary::Arbitrary;
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
|
||||
/// A Wasm test case generator that is powered by Binaryen's `wasm-opt -ttf`.
|
||||
#[derive(Clone)]
|
||||
@@ -60,7 +60,7 @@ impl Arbitrary for WasmOptTtf {
|
||||
#[derive(Arbitrary, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct DifferentialConfig {
|
||||
strategy: DifferentialStrategy,
|
||||
opt_level: DifferentialOptLevel,
|
||||
opt_level: OptLevel,
|
||||
}
|
||||
|
||||
impl DifferentialConfig {
|
||||
@@ -70,11 +70,7 @@ impl DifferentialConfig {
|
||||
DifferentialStrategy::Cranelift => wasmtime::Strategy::Cranelift,
|
||||
DifferentialStrategy::Lightbeam => wasmtime::Strategy::Lightbeam,
|
||||
})?;
|
||||
config.cranelift_opt_level(match self.opt_level {
|
||||
DifferentialOptLevel::None => wasmtime::OptLevel::None,
|
||||
DifferentialOptLevel::Speed => wasmtime::OptLevel::Speed,
|
||||
DifferentialOptLevel::SpeedAndSize => wasmtime::OptLevel::SpeedAndSize,
|
||||
});
|
||||
config.cranelift_opt_level(self.opt_level.to_wasmtime());
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
@@ -86,8 +82,65 @@ enum DifferentialStrategy {
|
||||
}
|
||||
|
||||
#[derive(Arbitrary, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
enum DifferentialOptLevel {
|
||||
enum OptLevel {
|
||||
None,
|
||||
Speed,
|
||||
SpeedAndSize,
|
||||
}
|
||||
|
||||
impl OptLevel {
|
||||
fn to_wasmtime(&self) -> wasmtime::OptLevel {
|
||||
match self {
|
||||
OptLevel::None => wasmtime::OptLevel::None,
|
||||
OptLevel::Speed => wasmtime::OptLevel::Speed,
|
||||
OptLevel::SpeedAndSize => wasmtime::OptLevel::SpeedAndSize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation of generating a `wasmtime::Config` arbitrarily
|
||||
#[derive(Arbitrary, Debug)]
|
||||
pub struct Config {
|
||||
opt_level: OptLevel,
|
||||
debug_verifier: bool,
|
||||
debug_info: bool,
|
||||
canonicalize_nans: bool,
|
||||
spectest: usize,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Converts this to a `wasmtime::Config` object
|
||||
pub fn to_wasmtime(&self) -> wasmtime::Config {
|
||||
let mut cfg = wasmtime::Config::new();
|
||||
cfg.debug_info(self.debug_info)
|
||||
.cranelift_nan_canonicalization(self.canonicalize_nans)
|
||||
.cranelift_debug_verifier(self.debug_verifier)
|
||||
.cranelift_opt_level(self.opt_level.to_wasmtime());
|
||||
return cfg;
|
||||
}
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/spectests.rs"));
|
||||
|
||||
/// A spec test from the upstream wast testsuite, arbitrarily chosen from the
|
||||
/// list of known spec tests.
|
||||
#[derive(Debug)]
|
||||
pub struct SpecTest {
|
||||
/// The filename of the spec test
|
||||
pub file: &'static str,
|
||||
/// The `*.wast` contents of the spec test
|
||||
pub contents: &'static str,
|
||||
}
|
||||
|
||||
impl Arbitrary for SpecTest {
|
||||
fn arbitrary(u: &mut Unstructured) -> arbitrary::Result<Self> {
|
||||
// NB: this does get a uniform value in the provided range.
|
||||
let i = u.int_in_range(0..=FILES.len() - 1)?;
|
||||
let (file, contents) = FILES[i];
|
||||
Ok(SpecTest { file, contents })
|
||||
}
|
||||
|
||||
fn size_hint(_depth: usize) -> (usize, Option<usize>) {
|
||||
(1, Some(std::mem::size_of::<usize>()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user