use arbitrary::Unstructured;
use std::fmt::{self, Debug};
pub struct FuzzModule {
module: wasm_smith::Module,
}
impl FuzzModule {
pub fn new(
config: impl Into<wasm_smith::Config>,
u: &mut Unstructured,
) -> arbitrary::Result<Self> {
let config = config.into();
let module = wasm_smith::Module::new(config, u)?;
Ok(Self { module })
}
pub fn ensure_termination(&mut self, default_fuel: u32) {
if let Err(err) = self.module.ensure_termination(default_fuel) {
panic!("unexpected invalid Wasm module: {err}")
}
}
pub fn wasm(&self) -> WasmSource {
WasmSource {
bytes: self.module.to_bytes(),
}
}
}
impl Debug for FuzzModule {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let config = self.module.config();
let wat = self.wasm().to_wat();
f.debug_struct("FuzzModule")
.field("config", config)
.field("wat", &wat)
.finish()
}
}
pub struct WasmSource {
bytes: Vec<u8>,
}
impl WasmSource {
pub fn into_bytes(self) -> Box<[u8]> {
self.bytes.into()
}
pub fn as_bytes(&self) -> &[u8] {
&self.bytes[..]
}
pub fn to_wat(&self) -> WatSource {
let wat = match wasmprinter::print_bytes(&self.bytes[..]) {
Ok(wat) => wat,
Err(err) => panic!("invalid Wasm: {err}"),
};
WatSource { text: wat }
}
}
pub struct WatSource {
text: String,
}
impl fmt::Debug for WatSource {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\n{}", self.text)
}
}