Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/fuzzing/src/generators/gc_ops/mutator.rs
3068 views
1
//! Mutators for the `gc` operations.
2
3
use crate::generators::gc_ops::ops::{GcOp, GcOps};
4
use mutatis::{Candidates, Context, DefaultMutate, Generate, Mutate, Result as MutResult};
5
6
/// A mutator for the gc ops
7
#[derive(Debug)]
8
pub struct GcOpsMutator;
9
10
impl Mutate<GcOps> for GcOpsMutator {
11
fn mutate(&mut self, c: &mut Candidates<'_>, ops: &mut GcOps) -> mutatis::Result<()> {
12
if !c.shrink() {
13
c.mutation(|ctx| {
14
if let Some(idx) = ctx.rng().gen_index(ops.ops.len() + 1) {
15
let op = GcOp::generate(ctx)?;
16
ops.ops.insert(idx, op);
17
}
18
Ok(())
19
})?;
20
}
21
22
if !ops.ops.is_empty() {
23
c.mutation(|ctx| {
24
let idx = ctx
25
.rng()
26
.gen_index(ops.ops.len())
27
.expect("ops is not empty");
28
ops.ops.remove(idx);
29
Ok(())
30
})?;
31
}
32
Ok(())
33
}
34
}
35
36
impl DefaultMutate for GcOps {
37
type DefaultMutate = GcOpsMutator;
38
}
39
40
impl Default for GcOpsMutator {
41
fn default() -> Self {
42
GcOpsMutator
43
}
44
}
45
46
impl<'a> arbitrary::Arbitrary<'a> for GcOps {
47
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
48
let mut session = mutatis::Session::new().seed(u.arbitrary()?);
49
session
50
.generate()
51
.map_err(|_| arbitrary::Error::IncorrectFormat)
52
}
53
}
54
55
impl Generate<GcOps> for GcOpsMutator {
56
fn generate(&mut self, _ctx: &mut Context) -> MutResult<GcOps> {
57
let mut ops = GcOps::default();
58
let mut session = mutatis::Session::new();
59
60
for _ in 0..64 {
61
session.mutate(&mut ops)?;
62
}
63
64
Ok(ops)
65
}
66
}
67
68