Merge branch 'main' of github.com:AFLplusplus/libAFLrs into main
This commit is contained in:
commit
d7661ce9f8
@ -10,6 +10,7 @@ edition = "2018"
|
||||
criterion = "0.3" # Benchmarking
|
||||
ahash = "0.6.1" # another hash
|
||||
fxhash = "0.2.1" # yet another hash
|
||||
xxhash-rust = { version = "0.8.0", features = ["const_xxh3", "xxh3"] } # xxh3 hashing for rust
|
||||
|
||||
[[bench]]
|
||||
name = "rand_speeds"
|
||||
@ -29,7 +30,7 @@ std = []
|
||||
hashbrown = { version = "0.9", features = ["serde"] } # A faster hashmap, nostd compatible
|
||||
libc = "0.2" # For (*nix) libc
|
||||
num = "*"
|
||||
xxhash-rust = { version = "0.8.0-beta.5", features = ["const_xxh3", "xxh3"] } # xxh3 hashing for rust
|
||||
xxhash-rust = { version = "0.8.0", features = ["xxh3"] } # xxh3 hashing for rust
|
||||
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
|
||||
erased-serde = "0.3.12"
|
||||
postcard = "0.5.1" # no_std compatible serde serialization fromat
|
||||
|
@ -1,8 +1,8 @@
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use core::any::Any;
|
||||
use core::cell::RefCell;
|
||||
use core::marker::PhantomData;
|
||||
use core::any::Any;
|
||||
use num::Integer;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -10,12 +10,12 @@ pub mod executors;
|
||||
pub mod feedbacks;
|
||||
pub mod generators;
|
||||
pub mod inputs;
|
||||
pub mod metamap;
|
||||
pub mod mutators;
|
||||
pub mod observers;
|
||||
pub mod serde_anymap;
|
||||
pub mod stages;
|
||||
pub mod utils;
|
||||
pub mod serde_anymap;
|
||||
pub mod metamap;
|
||||
|
||||
use alloc::string::String;
|
||||
use core::fmt;
|
||||
|
@ -1,22 +1,37 @@
|
||||
use hashbrown::HashMap;
|
||||
use hashbrown::hash_map::{ValuesMut, Values};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use core::any::{Any, TypeId};
|
||||
use core::slice::{Iter, IterMut};
|
||||
use core::any::{TypeId, Any};
|
||||
use hashbrown::hash_map::{Values, ValuesMut};
|
||||
use hashbrown::HashMap;
|
||||
|
||||
pub struct MetaMap {
|
||||
map: HashMap<TypeId, Box<dyn Any>>
|
||||
map: HashMap<TypeId, Box<dyn Any>>,
|
||||
}
|
||||
|
||||
impl MetaMap {
|
||||
pub fn get<T>(&self) -> Option<&T> where T: Any {
|
||||
self.map.get(&TypeId::of::<T>()).map(|x| x.as_ref().downcast_ref::<T>().unwrap())
|
||||
pub fn get<T>(&self) -> Option<&T>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.map
|
||||
.get(&TypeId::of::<T>())
|
||||
.map(|x| x.as_ref().downcast_ref::<T>().unwrap())
|
||||
}
|
||||
|
||||
pub fn get_mut<T>(&mut self) -> Option<&mut T> where T: Any {
|
||||
self.map.get_mut(&TypeId::of::<T>()).map(|x| x.as_mut().downcast_mut::<T>().unwrap())
|
||||
pub fn get_mut<T>(&mut self) -> Option<&mut T>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.map
|
||||
.get_mut(&TypeId::of::<T>())
|
||||
.map(|x| x.as_mut().downcast_mut::<T>().unwrap())
|
||||
}
|
||||
|
||||
pub fn insert<T>(&mut self, t: T) where T: Any {
|
||||
pub fn insert<T>(&mut self, t: T)
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.map.insert(TypeId::of::<T>(), Box::new(t));
|
||||
}
|
||||
|
||||
@ -24,39 +39,54 @@ impl MetaMap {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
pub fn contains<T>(&self) -> bool where T: Any {
|
||||
pub fn contains<T>(&self) -> bool
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.map.contains_key(&TypeId::of::<T>())
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self { map: HashMap::default() }
|
||||
Self {
|
||||
map: HashMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MultiMetaMap {
|
||||
map: HashMap<TypeId, Vec<Box<dyn Any>>>
|
||||
map: HashMap<TypeId, Vec<Box<dyn Any>>>,
|
||||
}
|
||||
|
||||
impl MultiMetaMap {
|
||||
pub fn get<T>(&self) -> Option<core::iter::Map<Iter<'_, Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>> where T: Any {
|
||||
pub fn get<T>(&self) -> Option<core::iter::Map<Iter<'_, Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
match self.map.get(&TypeId::of::<T>()) {
|
||||
None => None,
|
||||
Some(v) => {
|
||||
Some(v.iter().map(|x| x.as_ref().downcast_ref::<T>().unwrap()))
|
||||
}
|
||||
Some(v) => Some(v.iter().map(|x| x.as_ref().downcast_ref::<T>().unwrap())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mut<T>(&mut self) -> Option<core::iter::Map<IterMut<'_, Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>> where T: Any {
|
||||
pub fn get_mut<T>(
|
||||
&mut self,
|
||||
) -> Option<core::iter::Map<IterMut<'_, Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
match self.map.get_mut(&TypeId::of::<T>()) {
|
||||
None => None,
|
||||
Some(v) => {
|
||||
Some(v.iter_mut().map(|x| x.as_mut().downcast_mut::<T>().unwrap()))
|
||||
}
|
||||
Some(v) => Some(
|
||||
v.iter_mut()
|
||||
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert<T>(&mut self, t: T) where T: Any {
|
||||
pub fn insert<T>(&mut self, t: T)
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
let typeid = TypeId::of::<T>();
|
||||
if !self.map.contains_key(&typeid) {
|
||||
self.map.insert(typeid, vec![Box::new(t)]);
|
||||
@ -69,99 +99,144 @@ impl MultiMetaMap {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
pub fn contains<T>(&self) -> bool where T: Any {
|
||||
pub fn contains<T>(&self) -> bool
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.map.contains_key(&TypeId::of::<T>())
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self { map: HashMap::default() }
|
||||
Self {
|
||||
map: HashMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct MetaInstanceMap {
|
||||
map: HashMap<TypeId, HashMap<*const (), Box<dyn Any>>>
|
||||
map: HashMap<TypeId, HashMap<*const (), Box<dyn Any>>>,
|
||||
}
|
||||
|
||||
impl MetaInstanceMap {
|
||||
pub fn get<T, U>(&self, instance: &U) -> Option<&T> where T: Any {
|
||||
pub fn get<T, U>(&self, instance: &U) -> Option<&T>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.get_ptr::<T>(instance as *const _ as *const ())
|
||||
}
|
||||
|
||||
pub fn get_ptr<T>(&self, instance: *const ()) -> Option<&T> where T: Any {
|
||||
pub fn get_ptr<T>(&self, instance: *const ()) -> Option<&T>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
match self.map.get(&TypeId::of::<T>()) {
|
||||
None => None,
|
||||
Some(h) => {
|
||||
h.get(&instance).map(|x| x.as_ref().downcast_ref::<T>().unwrap())
|
||||
}
|
||||
Some(h) => h
|
||||
.get(&instance)
|
||||
.map(|x| x.as_ref().downcast_ref::<T>().unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mut<T, U>(&mut self, instance: &U) -> Option<&mut T> where T: Any {
|
||||
pub fn get_mut<T, U>(&mut self, instance: &U) -> Option<&mut T>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.get_mut_ptr::<T>(instance as *const _ as *const ())
|
||||
}
|
||||
|
||||
pub fn get_mut_ptr<T>(&mut self, instance: *const ()) -> Option<&mut T> where T: Any {
|
||||
pub fn get_mut_ptr<T>(&mut self, instance: *const ()) -> Option<&mut T>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
match self.map.get_mut(&TypeId::of::<T>()) {
|
||||
None => None,
|
||||
Some(h) => {
|
||||
h.get_mut(&instance).map(|x| x.as_mut().downcast_mut::<T>().unwrap())
|
||||
}
|
||||
Some(h) => h
|
||||
.get_mut(&instance)
|
||||
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_all<T>(&self) -> Option<core::iter::Map<Values<'_, *const (), Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>> where T: Any {
|
||||
pub fn get_all<T>(
|
||||
&self,
|
||||
) -> Option<core::iter::Map<Values<'_, *const (), Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
match self.map.get(&TypeId::of::<T>()) {
|
||||
None => None,
|
||||
Some(h) => {
|
||||
Some(h.values().map(|x| x.as_ref().downcast_ref::<T>().unwrap()))
|
||||
}
|
||||
Some(h) => Some(h.values().map(|x| x.as_ref().downcast_ref::<T>().unwrap())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_all_mut<T>(&mut self) -> Option<core::iter::Map<ValuesMut<'_, *const (), Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>> where T: Any {
|
||||
pub fn get_all_mut<T>(
|
||||
&mut self,
|
||||
) -> Option<
|
||||
core::iter::Map<ValuesMut<'_, *const (), Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>,
|
||||
>
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
match self.map.get_mut(&TypeId::of::<T>()) {
|
||||
None => None,
|
||||
Some(h) => {
|
||||
Some(h.values_mut().map(|x| x.as_mut().downcast_mut::<T>().unwrap()))
|
||||
}
|
||||
Some(h) => Some(
|
||||
h.values_mut()
|
||||
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert<T, U>(&mut self, t: T, instance: &U) where T: Any {
|
||||
pub fn insert<T, U>(&mut self, t: T, instance: &U)
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.insert_ptr(t, instance as *const _ as *const ())
|
||||
}
|
||||
|
||||
pub fn insert_ptr<T>(&mut self, t: T, instance: *const ()) where T: Any {
|
||||
pub fn insert_ptr<T>(&mut self, t: T, instance: *const ())
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
let typeid = TypeId::of::<T>();
|
||||
if !self.map.contains_key(&typeid) {
|
||||
self.map.insert(typeid, HashMap::default());
|
||||
}
|
||||
self.map.get_mut(&typeid).unwrap().insert(instance, Box::new(t));
|
||||
self.map
|
||||
.get_mut(&typeid)
|
||||
.unwrap()
|
||||
.insert(instance, Box::new(t));
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
pub fn contains_type<T>(&self) -> bool where T: Any {
|
||||
pub fn contains_type<T>(&self) -> bool
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.map.contains_key(&TypeId::of::<T>())
|
||||
}
|
||||
|
||||
pub fn contains<T, U>(&self, instance: &U) -> bool where T: Any {
|
||||
pub fn contains<T, U>(&self, instance: &U) -> bool
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
self.contains_ptr::<T>(instance as *const _ as *const ())
|
||||
}
|
||||
|
||||
pub fn contains_ptr<T>(&self, instance: *const ()) -> bool where T: Any {
|
||||
pub fn contains_ptr<T>(&self, instance: *const ()) -> bool
|
||||
where
|
||||
T: Any,
|
||||
{
|
||||
match self.map.get(&TypeId::of::<T>()) {
|
||||
None => false,
|
||||
Some(h) => {
|
||||
h.contains_key(&instance)
|
||||
}
|
||||
Some(h) => h.contains_key(&instance),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self { map: HashMap::default() }
|
||||
Self {
|
||||
map: HashMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +1,17 @@
|
||||
use hashbrown::HashMap;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use core::any::{Any, TypeId};
|
||||
use core::default::Default;
|
||||
use core::any::{TypeId, Any};
|
||||
use core::fmt;
|
||||
|
||||
pub fn pack_type_id(id: u64) -> TypeId {
|
||||
unsafe {
|
||||
*(&id as *const u64 as *const TypeId)
|
||||
}
|
||||
unsafe { *(&id as *const u64 as *const TypeId) }
|
||||
}
|
||||
|
||||
pub fn unpack_type_id(id: TypeId) -> u64 {
|
||||
unsafe {
|
||||
*(&id as *const _ as *const u64)
|
||||
}
|
||||
unsafe { *(&id as *const _ as *const u64) }
|
||||
}
|
||||
|
||||
pub trait SerdeAny: Any + erased_serde::Serialize {
|
||||
@ -22,7 +19,8 @@ pub trait SerdeAny : Any + erased_serde::Serialize {
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||
}
|
||||
|
||||
type DeserializeCallback = fn(&mut dyn erased_serde::Deserializer) -> Result<Box<dyn SerdeAny>, erased_serde::Error>;
|
||||
type DeserializeCallback =
|
||||
fn(&mut dyn erased_serde::Deserializer) -> Result<Box<dyn SerdeAny>, erased_serde::Error>;
|
||||
|
||||
struct Wrap<'a, T: ?Sized>(pub &'a T);
|
||||
impl<'a, T> Serialize for Wrap<'a, T>
|
||||
@ -39,7 +37,8 @@ where
|
||||
|
||||
impl<'a> serde::Serialize for dyn SerdeAny + 'a {
|
||||
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
|
||||
where S: serde::Serializer
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
use serde::ser::SerializeSeq;
|
||||
|
||||
@ -80,7 +79,14 @@ impl<'de> serde::de::Visitor<'de> for BoxAnyVisitor {
|
||||
V: serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let id: u64 = visitor.next_element()?.unwrap();
|
||||
let cb = unsafe { *REGISTRY.deserializers.as_ref().unwrap().get(&id).expect("Cannot deserialize an unregistered SerdeAny") };
|
||||
let cb = unsafe {
|
||||
*REGISTRY
|
||||
.deserializers
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get(&id)
|
||||
.expect("Cannot deserialize an unregistered SerdeAny")
|
||||
};
|
||||
let seed = DeserializeCallbackSeed { cb: cb };
|
||||
let obj: Box<dyn SerdeAny> = visitor.next_element_seed(seed)?.unwrap();
|
||||
Ok(obj)
|
||||
@ -98,17 +104,22 @@ impl<'de> Deserialize<'de> for Box<dyn SerdeAny> {
|
||||
|
||||
pub struct Registry {
|
||||
deserializers: Option<HashMap<u64, DeserializeCallback>>,
|
||||
finalized: bool
|
||||
finalized: bool,
|
||||
}
|
||||
|
||||
impl Registry {
|
||||
pub fn register<T>(&mut self) where T: SerdeAny + Serialize + serde::de::DeserializeOwned {
|
||||
pub fn register<T>(&mut self)
|
||||
where
|
||||
T: SerdeAny + Serialize + serde::de::DeserializeOwned,
|
||||
{
|
||||
if self.finalized {
|
||||
panic!("Global Registry of SerdeAny types is already finalized!");
|
||||
}
|
||||
|
||||
let deserializers = self.deserializers.get_or_insert_with(|| HashMap::default());
|
||||
deserializers.insert(unpack_type_id(TypeId::of::<T>()), |de| Ok(Box::new(erased_serde::deserialize::<T>(de)?)));
|
||||
deserializers.insert(unpack_type_id(TypeId::of::<T>()), |de| {
|
||||
Ok(Box::new(erased_serde::deserialize::<T>(de)?))
|
||||
});
|
||||
}
|
||||
|
||||
pub fn finalize(&mut self) {
|
||||
@ -116,11 +127,17 @@ impl Registry {
|
||||
}
|
||||
}
|
||||
|
||||
static mut REGISTRY: Registry = Registry { deserializers: None, finalized: false };
|
||||
static mut REGISTRY: Registry = Registry {
|
||||
deserializers: None,
|
||||
finalized: false,
|
||||
};
|
||||
|
||||
pub struct RegistryBuilder {}
|
||||
impl RegistryBuilder {
|
||||
pub fn register<T>() where T: SerdeAny + Serialize + serde::de::DeserializeOwned {
|
||||
pub fn register<T>()
|
||||
where
|
||||
T: SerdeAny + Serialize + serde::de::DeserializeOwned,
|
||||
{
|
||||
unsafe {
|
||||
REGISTRY.register::<T>();
|
||||
}
|
||||
@ -135,31 +152,50 @@ impl RegistryBuilder {
|
||||
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct SerdeAnyMap {
|
||||
map: HashMap<u64, Box<dyn SerdeAny>>
|
||||
map: HashMap<u64, Box<dyn SerdeAny>>,
|
||||
}
|
||||
|
||||
impl SerdeAnyMap {
|
||||
pub fn get<T>(&self) -> Option<&T> where T: SerdeAny {
|
||||
self.map.get(&unpack_type_id(TypeId::of::<T>())).map(|x| x.as_ref().as_any().downcast_ref::<T>().unwrap())
|
||||
pub fn get<T>(&self) -> Option<&T>
|
||||
where
|
||||
T: SerdeAny,
|
||||
{
|
||||
self.map
|
||||
.get(&unpack_type_id(TypeId::of::<T>()))
|
||||
.map(|x| x.as_ref().as_any().downcast_ref::<T>().unwrap())
|
||||
}
|
||||
|
||||
pub fn get_mut<T>(&mut self) -> Option<&mut T> where T: SerdeAny {
|
||||
self.map.get_mut(&unpack_type_id(TypeId::of::<T>())).map(|x| x.as_mut().as_any_mut().downcast_mut::<T>().unwrap())
|
||||
pub fn get_mut<T>(&mut self) -> Option<&mut T>
|
||||
where
|
||||
T: SerdeAny,
|
||||
{
|
||||
self.map
|
||||
.get_mut(&unpack_type_id(TypeId::of::<T>()))
|
||||
.map(|x| x.as_mut().as_any_mut().downcast_mut::<T>().unwrap())
|
||||
}
|
||||
|
||||
pub fn insert<T>(&mut self, t: T) where T: SerdeAny {
|
||||
self.map.insert(unpack_type_id(TypeId::of::<T>()), Box::new(t));
|
||||
pub fn insert<T>(&mut self, t: T)
|
||||
where
|
||||
T: SerdeAny,
|
||||
{
|
||||
self.map
|
||||
.insert(unpack_type_id(TypeId::of::<T>()), Box::new(t));
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
pub fn contains<T>(&self) -> bool where T: SerdeAny {
|
||||
pub fn contains<T>(&self) -> bool
|
||||
where
|
||||
T: SerdeAny,
|
||||
{
|
||||
self.map.contains_key(&unpack_type_id(TypeId::of::<T>()))
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
SerdeAnyMap { map: HashMap::default() }
|
||||
SerdeAnyMap {
|
||||
map: HashMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use alloc::rc::Rc;
|
||||
use core::cell::RefCell;
|
||||
use core::debug_assert;
|
||||
use core::fmt::Debug;
|
||||
use xxhash_rust::const_xxh3::xxh3_64_with_seed;
|
||||
use xxhash_rust::xxh3::xxh3_64_with_seed;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
@ -339,5 +339,4 @@ mod tests {
|
||||
assert_eq!(next_pow2(1000), 1024);
|
||||
assert_eq!(next_pow2(0xFFFFFFFF as u64), (0xFFFFFFFF as u64) + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user