diff --git a/libafl/src/mutators/mod.rs b/libafl/src/mutators/mod.rs index 6cd075d8fa..80ddb2207a 100644 --- a/libafl/src/mutators/mod.rs +++ b/libafl/src/mutators/mod.rs @@ -175,6 +175,9 @@ pub trait MutatorsTuple: HasLen { corpus_idx: Option, ) -> Result<(), Error>; + /// Gets all names of the wrapped [`Mutator`]`s`, reversed. + fn names_reversed(&self) -> Vec<&str>; + /// Gets all names of the wrapped [`Mutator`]`s`. fn names(&self) -> Vec<&str>; } @@ -222,6 +225,11 @@ impl MutatorsTuple for () { Ok(()) } + #[inline] + fn names_reversed(&self) -> Vec<&str> { + Vec::new() + } + #[inline] fn names(&self) -> Vec<&str> { Vec::new() @@ -287,9 +295,15 @@ where } } + fn names_reversed(&self) -> Vec<&str> { + let mut ret = self.1.names_reversed(); + ret.push(self.0.name()); + ret + } + fn names(&self) -> Vec<&str> { - let mut ret = self.1.names(); - ret.insert(0, self.0.name()); + let mut ret = self.names_reversed(); + ret.reverse(); ret } } @@ -299,10 +313,16 @@ where Head: Mutator + 'static, Tail: IntoVec>>, { - fn into_vec(self) -> Vec>> { + fn into_vec_reversed(self) -> Vec>> { let (head, tail) = self.uncons(); - let mut ret = tail.into_vec(); - ret.insert(0, Box::new(head)); + let mut ret = tail.into_vec_reversed(); + ret.push(Box::new(head)); + ret + } + + fn into_vec(self) -> Vec>> { + let mut ret = self.into_vec_reversed(); + ret.reverse(); ret } } @@ -353,6 +373,10 @@ where fn names(&self) -> Vec<&str> { self.0.names() } + + fn names_reversed(&self) -> Vec<&str> { + self.0.names_reversed() + } } impl IntoVec>> for (Tail,) @@ -419,6 +443,10 @@ impl MutatorsTuple for Vec>> { mutator.post_exec(state, stage_idx, new_corpus_idx) } + fn names_reversed(&self) -> Vec<&str> { + self.iter().rev().map(|x| x.name()).collect() + } + fn names(&self) -> Vec<&str> { self.iter().map(|x| x.name()).collect() } diff --git a/libafl/src/stages/mod.rs b/libafl/src/stages/mod.rs index 46ed9c017f..dd402bd485 100644 --- a/libafl/src/stages/mod.rs +++ b/libafl/src/stages/mod.rs @@ -222,10 +222,18 @@ where Z: UsesState, Head::State: HasCurrentStage, { - fn into_vec(self) -> Vec>> { + fn into_vec_reversed( + self, + ) -> Vec>> { let (head, tail) = self.uncons(); - let mut ret = tail.0.into_vec(); - ret.insert(0, Box::new(head)); + let mut ret = tail.0.into_vec_reversed(); + ret.push(Box::new(head)); + ret + } + + fn into_vec(self) -> Vec>> { + let mut ret = self.into_vec_reversed(); + ret.reverse(); ret } } diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index 65ae01c4b8..57de864c72 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -94,6 +94,17 @@ where /// (We need this trait since we cannot implement `Into` for foreign types) #[cfg(feature = "alloc")] pub trait IntoVec { + /// Convert this into a [`Vec`], reversed. + /// (Having this method around makes some implementations more performant) + fn into_vec_reversed(self) -> Vec + where + Self: Sized, + { + let mut ret = self.into_vec(); + ret.reverse(); + ret + } + /// Convert this into a [`Vec`]. fn into_vec(self) -> Vec; }