Allow for AsIter(Mut)/AsSlice(Mut) to be implemented in safe Rust (#2120)
* Generalize `AsIter` to allow iterating over contents of a `RefCell` Towards `MapObserver`s in safe Rust. * Helpers for `RefCellValueObserver` * MapObserver: Return owned Self::Entry from .get() `Self::Entry` is `Copy`, so there's not much value in returning a reference from `get()`. Futhermore, returning a reference limits the possible implementations of `MapObserver`, because it forces the borrow/reset to outlive the body of the method. * MapObserver: Replace `.get_mut()` with `.set(idx, val)` Like the previous commit, this is intended to expand the possible implementations of `MapObserver` to types with interior mutability, which can't necessarily loan out their content. * Make `RefCellValueObserver` into a safe `MapObserver` * as iter mut * as slice (mut): allow for non-& refs * nostd * CI round 1 * cleanup + AsSlice defs for RefCellValueObserver * clippy fixes * avoid unnecessary imports * whoops, too aggressive * use deref instead of as slice * whoops * fix as slice conditional importing in stable --------- Co-authored-by: Addison Crump <addison.crump@cispa.de>
This commit is contained in:
parent
28c43b332f
commit
b0248461e2
@ -165,7 +165,7 @@ where
|
|||||||
|
|
||||||
// Store coverage, mapping coverage map indices to hit counts (if present) and the
|
// Store coverage, mapping coverage map indices to hit counts (if present) and the
|
||||||
// associated seeds for the map indices with those hit counts.
|
// associated seeds for the map indices with those hit counts.
|
||||||
for (i, e) in obs.as_iter().copied().enumerate() {
|
for (i, e) in obs.as_iter().map(|x| *x).enumerate() {
|
||||||
if e != obs.initial() {
|
if e != obs.initial() {
|
||||||
cov_map
|
cov_map
|
||||||
.entry(i)
|
.entry(i)
|
||||||
|
@ -6,12 +6,14 @@ use core::simd::prelude::SimdOrd;
|
|||||||
use core::{
|
use core::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ops::{BitAnd, BitOr},
|
ops::{BitAnd, BitOr, Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[rustversion::nightly]
|
||||||
|
use libafl_bolts::AsSlice;
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
tuples::{MatchNameRef, Reference, Referenceable},
|
tuples::{MatchNameRef, Reference, Referenceable},
|
||||||
AsIter, AsSlice, AsSliceMut, HasRefCnt, Named,
|
AsIter, HasRefCnt, Named,
|
||||||
};
|
};
|
||||||
use num_traits::PrimInt;
|
use num_traits::PrimInt;
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
@ -235,19 +237,18 @@ pub struct MapIndexesMetadata {
|
|||||||
|
|
||||||
libafl_bolts::impl_serdeany!(MapIndexesMetadata);
|
libafl_bolts::impl_serdeany!(MapIndexesMetadata);
|
||||||
|
|
||||||
impl AsSlice for MapIndexesMetadata {
|
impl Deref for MapIndexesMetadata {
|
||||||
type Entry = usize;
|
type Target = [usize];
|
||||||
/// Convert to a slice
|
/// Convert to a slice
|
||||||
fn as_slice(&self) -> &[usize] {
|
fn deref(&self) -> &[usize] {
|
||||||
self.list.as_slice()
|
&self.list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSliceMut for MapIndexesMetadata {
|
impl DerefMut for MapIndexesMetadata {
|
||||||
type Entry = usize;
|
|
||||||
/// Convert to a slice
|
/// Convert to a slice
|
||||||
fn as_slice_mut(&mut self) -> &mut [usize] {
|
fn deref_mut(&mut self) -> &mut [usize] {
|
||||||
self.list.as_slice_mut()
|
&mut self.list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,21 +283,20 @@ pub struct MapNoveltiesMetadata {
|
|||||||
|
|
||||||
libafl_bolts::impl_serdeany!(MapNoveltiesMetadata);
|
libafl_bolts::impl_serdeany!(MapNoveltiesMetadata);
|
||||||
|
|
||||||
impl AsSlice for MapNoveltiesMetadata {
|
impl Deref for MapNoveltiesMetadata {
|
||||||
type Entry = usize;
|
type Target = [usize];
|
||||||
/// Convert to a slice
|
/// Convert to a slice
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn as_slice(&self) -> &[usize] {
|
fn deref(&self) -> &[usize] {
|
||||||
self.list.as_slice()
|
&self.list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSliceMut for MapNoveltiesMetadata {
|
impl DerefMut for MapNoveltiesMetadata {
|
||||||
type Entry = usize;
|
|
||||||
/// Convert to a slice
|
/// Convert to a slice
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn as_slice_mut(&mut self) -> &mut [usize] {
|
fn deref_mut(&mut self) -> &mut [usize] {
|
||||||
self.list.as_slice_mut()
|
&mut self.list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,13 +469,13 @@ where
|
|||||||
map_state.history_map.resize(len, observer.initial());
|
map_state.history_map.resize(len, observer.initial());
|
||||||
}
|
}
|
||||||
|
|
||||||
let history_map = map_state.history_map.as_slice_mut();
|
let history_map = &mut map_state.history_map;
|
||||||
if C::INDICES {
|
if C::INDICES {
|
||||||
let mut indices = Vec::new();
|
let mut indices = Vec::new();
|
||||||
|
|
||||||
for (i, value) in observer
|
for (i, value) in observer
|
||||||
.as_iter()
|
.as_iter()
|
||||||
.copied()
|
.map(|x| *x)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, value)| *value != initial)
|
.filter(|(_, value)| *value != initial)
|
||||||
{
|
{
|
||||||
@ -490,7 +490,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
for (i, value) in observer
|
for (i, value) in observer
|
||||||
.as_iter()
|
.as_iter()
|
||||||
.copied()
|
.map(|x| *x)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, value)| *value != initial)
|
.filter(|(_, value)| *value != initial)
|
||||||
{
|
{
|
||||||
@ -539,8 +539,7 @@ where
|
|||||||
#[rustversion::nightly]
|
#[rustversion::nightly]
|
||||||
impl<C, O, S> Feedback<S> for MapFeedback<C, DifferentIsNovel, O, MaxReducer, u8>
|
impl<C, O, S> Feedback<S> for MapFeedback<C, DifferentIsNovel, O, MaxReducer, u8>
|
||||||
where
|
where
|
||||||
O: MapObserver<Entry = u8> + AsSlice<Entry = u8>,
|
O: MapObserver<Entry = u8> + for<'a> AsSlice<'a, Entry = u8> + for<'a> AsIter<'a, Item = u8>,
|
||||||
for<'it> O: AsIter<'it, Item = u8>,
|
|
||||||
S: State + HasNamedMetadata,
|
S: State + HasNamedMetadata,
|
||||||
C: CanTrack + AsRef<O> + Observer<S>,
|
C: CanTrack + AsRef<O> + Observer<S>,
|
||||||
{
|
{
|
||||||
@ -756,7 +755,7 @@ where
|
|||||||
novelties.clear();
|
novelties.clear();
|
||||||
for (i, item) in observer
|
for (i, item) in observer
|
||||||
.as_iter()
|
.as_iter()
|
||||||
.copied()
|
.map(|x| *x)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, item)| *item != initial)
|
.filter(|(_, item)| *item != initial)
|
||||||
{
|
{
|
||||||
@ -770,7 +769,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
for (i, item) in observer
|
for (i, item) in observer
|
||||||
.as_iter()
|
.as_iter()
|
||||||
.copied()
|
.map(|x| *x)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, item)| *item != initial)
|
.filter(|(_, item)| *item != initial)
|
||||||
{
|
{
|
||||||
|
@ -4,12 +4,13 @@ use alloc::{borrow::Cow, vec::Vec};
|
|||||||
use core::{
|
use core::{
|
||||||
fmt::{self, Debug},
|
fmt::{self, Debug},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
rands::Rand,
|
rands::Rand,
|
||||||
tuples::{tuple_list, tuple_list_type, Merge, NamedTuple},
|
tuples::{tuple_list, tuple_list_type, Merge, NamedTuple},
|
||||||
AsSlice, AsSliceMut, Named,
|
Named,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -45,18 +46,16 @@ pub struct LogMutationMetadata {
|
|||||||
|
|
||||||
libafl_bolts::impl_serdeany!(LogMutationMetadata);
|
libafl_bolts::impl_serdeany!(LogMutationMetadata);
|
||||||
|
|
||||||
impl AsSlice for LogMutationMetadata {
|
impl Deref for LogMutationMetadata {
|
||||||
type Entry = Cow<'static, str>;
|
type Target = [Cow<'static, str>];
|
||||||
#[must_use]
|
fn deref(&self) -> &[Cow<'static, str>] {
|
||||||
fn as_slice(&self) -> &[Cow<'static, str>] {
|
&self.list
|
||||||
self.list.as_slice()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl AsSliceMut for LogMutationMetadata {
|
impl DerefMut for LogMutationMetadata {
|
||||||
type Entry = Cow<'static, str>;
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn as_slice_mut(&mut self) -> &mut [Cow<'static, str>] {
|
fn deref_mut(&mut self) -> &mut [Cow<'static, str>] {
|
||||||
self.list.as_slice_mut()
|
&mut self.list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ use core::slice::from_raw_parts;
|
|||||||
use core::{
|
use core::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
mem::size_of,
|
mem::size_of,
|
||||||
ops::{Add, AddAssign},
|
ops::{Add, AddAssign, Deref},
|
||||||
slice::Iter,
|
slice::Iter,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -272,9 +272,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSlice for Tokens {
|
impl Deref for Tokens {
|
||||||
type Entry = Vec<u8>;
|
type Target = [Vec<u8>];
|
||||||
fn as_slice(&self) -> &[Vec<u8>] {
|
fn deref(&self) -> &[Vec<u8>] {
|
||||||
self.tokens()
|
self.tokens()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
//! The `CmpObserver` provides access to the logged values of CMP instructions
|
//! The `CmpObserver` provides access to the logged values of CMP instructions
|
||||||
|
|
||||||
use alloc::{borrow::Cow, vec::Vec};
|
use alloc::{borrow::Cow, vec::Vec};
|
||||||
use core::{fmt::Debug, marker::PhantomData};
|
use core::{
|
||||||
|
fmt::Debug,
|
||||||
|
marker::PhantomData,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
|
|
||||||
use c2rust_bitfields::BitfieldStruct;
|
use c2rust_bitfields::BitfieldStruct;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl_bolts::{ownedref::OwnedRefMut, serdeany::SerdeAny, AsSlice, AsSliceMut, Named};
|
use libafl_bolts::{ownedref::OwnedRefMut, serdeany::SerdeAny, Named};
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{executors::ExitKind, inputs::UsesInput, observers::Observer, Error, HasMetadata};
|
use crate::{executors::ExitKind, inputs::UsesInput, observers::Observer, Error, HasMetadata};
|
||||||
@ -83,21 +87,16 @@ pub struct CmpValuesMetadata {
|
|||||||
|
|
||||||
libafl_bolts::impl_serdeany!(CmpValuesMetadata);
|
libafl_bolts::impl_serdeany!(CmpValuesMetadata);
|
||||||
|
|
||||||
impl AsSlice for CmpValuesMetadata {
|
impl Deref for CmpValuesMetadata {
|
||||||
type Entry = CmpValues;
|
type Target = [CmpValues];
|
||||||
/// Convert to a slice
|
fn deref(&self) -> &[CmpValues] {
|
||||||
#[must_use]
|
&self.list
|
||||||
fn as_slice(&self) -> &[CmpValues] {
|
|
||||||
self.list.as_slice()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSliceMut for CmpValuesMetadata {
|
impl DerefMut for CmpValuesMetadata {
|
||||||
type Entry = CmpValues;
|
fn deref_mut(&mut self) -> &mut [CmpValues] {
|
||||||
/// Convert to a slice
|
&mut self.list
|
||||||
#[must_use]
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [CmpValues] {
|
|
||||||
self.list.as_slice_mut()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ use core::{
|
|||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
iter::Flatten,
|
iter::Flatten,
|
||||||
marker::PhantomData,
|
|
||||||
mem::size_of,
|
mem::size_of,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
slice::{self, Iter, IterMut},
|
slice::{self, Iter, IterMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -414,10 +414,10 @@ pub trait MapObserver:
|
|||||||
type Entry: Bounded + PartialEq + Default + Copy + Debug + Hash + 'static;
|
type Entry: Bounded + PartialEq + Default + Copy + Debug + Hash + 'static;
|
||||||
|
|
||||||
/// Get the value at `idx`
|
/// Get the value at `idx`
|
||||||
fn get(&self, idx: usize) -> &Self::Entry;
|
fn get(&self, idx: usize) -> Self::Entry;
|
||||||
|
|
||||||
/// Get the value at `idx` (mutable)
|
/// Set the value at `idx`
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut Self::Entry;
|
fn set(&mut self, idx: usize, val: Self::Entry);
|
||||||
|
|
||||||
/// Get the number of usable entries in the map (all by default)
|
/// Get the number of usable entries in the map (all by default)
|
||||||
fn usable_count(&self) -> usize;
|
fn usable_count(&self) -> usize;
|
||||||
@ -459,64 +459,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Simple iterator calling `MapObserver::get`
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct MapObserverSimpleIterator<'a, O>
|
|
||||||
where
|
|
||||||
O: 'a + MapObserver,
|
|
||||||
{
|
|
||||||
index: usize,
|
|
||||||
observer: *const O,
|
|
||||||
phantom: PhantomData<&'a u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, O> Iterator for MapObserverSimpleIterator<'a, O>
|
|
||||||
where
|
|
||||||
O: 'a + MapObserver,
|
|
||||||
{
|
|
||||||
type Item = &'a O::Entry;
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
unsafe {
|
|
||||||
if self.index >= self.observer.as_ref().unwrap().usable_count() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let i = self.index;
|
|
||||||
self.index += 1;
|
|
||||||
Some(self.observer.as_ref().unwrap().get(i))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A Simple iterator calling `MapObserver::get_mut`
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct MapObserverSimpleIteratorMut<'a, O>
|
|
||||||
where
|
|
||||||
O: 'a + MapObserver,
|
|
||||||
{
|
|
||||||
index: usize,
|
|
||||||
observer: *mut O,
|
|
||||||
phantom: PhantomData<&'a u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, O> Iterator for MapObserverSimpleIteratorMut<'a, O>
|
|
||||||
where
|
|
||||||
O: 'a + MapObserver,
|
|
||||||
{
|
|
||||||
type Item = &'a O::Entry;
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
unsafe {
|
|
||||||
if self.index >= self.observer.as_ref().unwrap().usable_count() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let i = self.index;
|
|
||||||
self.index += 1;
|
|
||||||
Some(self.observer.as_mut().unwrap().get_mut(i))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The Map Observer retrieves the state of a map,
|
/// The Map Observer retrieves the state of a map,
|
||||||
/// that will get updated by the target.
|
/// that will get updated by the target.
|
||||||
/// A well-known example is the AFL-Style coverage map.
|
/// A well-known example is the AFL-Style coverage map.
|
||||||
@ -585,48 +527,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'it, T, const DIFFERENTIAL: bool> AsIter<'it> for StdMapObserver<'a, T, DIFFERENTIAL>
|
|
||||||
where
|
|
||||||
T: Bounded
|
|
||||||
+ PartialEq
|
|
||||||
+ Default
|
|
||||||
+ Copy
|
|
||||||
+ Hash
|
|
||||||
+ 'static
|
|
||||||
+ Serialize
|
|
||||||
+ serde::de::DeserializeOwned
|
|
||||||
+ Debug,
|
|
||||||
{
|
|
||||||
type Item = T;
|
|
||||||
type IntoIter = Iter<'it, T>;
|
|
||||||
|
|
||||||
fn as_iter(&'it self) -> Self::IntoIter {
|
|
||||||
let cnt = self.usable_count();
|
|
||||||
self.as_slice()[..cnt].iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'it, T, const DIFFERENTIAL: bool> AsIterMut<'it> for StdMapObserver<'a, T, DIFFERENTIAL>
|
|
||||||
where
|
|
||||||
T: Bounded
|
|
||||||
+ PartialEq
|
|
||||||
+ Default
|
|
||||||
+ Copy
|
|
||||||
+ Hash
|
|
||||||
+ 'static
|
|
||||||
+ Serialize
|
|
||||||
+ serde::de::DeserializeOwned
|
|
||||||
+ Debug,
|
|
||||||
{
|
|
||||||
type Item = T;
|
|
||||||
type IntoIter = IterMut<'it, T>;
|
|
||||||
|
|
||||||
fn as_iter_mut(&'it mut self) -> Self::IntoIter {
|
|
||||||
let cnt = self.usable_count();
|
|
||||||
self.as_slice_mut()[..cnt].iter_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'it, T, const DIFFERENTIAL: bool> IntoIterator for &'it StdMapObserver<'a, T, DIFFERENTIAL>
|
impl<'a, 'it, T, const DIFFERENTIAL: bool> IntoIterator for &'it StdMapObserver<'a, T, DIFFERENTIAL>
|
||||||
where
|
where
|
||||||
T: Bounded
|
T: Bounded
|
||||||
@ -744,13 +644,12 @@ where
|
|||||||
type Entry = T;
|
type Entry = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, pos: usize) -> &T {
|
fn get(&self, pos: usize) -> T {
|
||||||
&self.as_slice()[pos]
|
self.as_slice()[pos]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn set(&mut self, pos: usize, val: T) {
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut T {
|
self.map.as_slice_mut()[pos] = val;
|
||||||
&mut self.as_slice_mut()[idx]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Count the set bytes in the map
|
/// Count the set bytes in the map
|
||||||
@ -829,27 +728,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, const DIFFERENTIAL: bool> AsSlice for StdMapObserver<'a, T, DIFFERENTIAL>
|
impl<'a, T, const DIFFERENTIAL: bool> Deref for StdMapObserver<'a, T, DIFFERENTIAL>
|
||||||
where
|
where
|
||||||
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
type Entry = T;
|
type Target = [T];
|
||||||
#[must_use]
|
fn deref(&self) -> &[T] {
|
||||||
#[inline]
|
&self.map
|
||||||
fn as_slice(&self) -> &[T] {
|
|
||||||
self.map.as_slice()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, const DIFFERENTIAL: bool> AsSliceMut for StdMapObserver<'a, T, DIFFERENTIAL>
|
impl<'a, T, const DIFFERENTIAL: bool> DerefMut for StdMapObserver<'a, T, DIFFERENTIAL>
|
||||||
where
|
where
|
||||||
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
type Entry = T;
|
fn deref_mut(&mut self) -> &mut [T] {
|
||||||
#[must_use]
|
&mut self.map
|
||||||
#[inline]
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
|
||||||
self.map.as_slice_mut()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1114,48 +1008,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'it, T, const N: usize> AsIter<'it> for ConstMapObserver<'a, T, N>
|
|
||||||
where
|
|
||||||
T: Bounded
|
|
||||||
+ PartialEq
|
|
||||||
+ Default
|
|
||||||
+ Copy
|
|
||||||
+ Hash
|
|
||||||
+ 'static
|
|
||||||
+ Serialize
|
|
||||||
+ serde::de::DeserializeOwned
|
|
||||||
+ Debug,
|
|
||||||
{
|
|
||||||
type Item = T;
|
|
||||||
type IntoIter = Iter<'it, T>;
|
|
||||||
|
|
||||||
fn as_iter(&'it self) -> Self::IntoIter {
|
|
||||||
let cnt = self.usable_count();
|
|
||||||
self.as_slice()[..cnt].iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'it, T, const N: usize> AsIterMut<'it> for ConstMapObserver<'a, T, N>
|
|
||||||
where
|
|
||||||
T: Bounded
|
|
||||||
+ PartialEq
|
|
||||||
+ Default
|
|
||||||
+ Copy
|
|
||||||
+ Hash
|
|
||||||
+ 'static
|
|
||||||
+ Serialize
|
|
||||||
+ serde::de::DeserializeOwned
|
|
||||||
+ Debug,
|
|
||||||
{
|
|
||||||
type Item = T;
|
|
||||||
type IntoIter = IterMut<'it, T>;
|
|
||||||
|
|
||||||
fn as_iter_mut(&'it mut self) -> Self::IntoIter {
|
|
||||||
let cnt = self.usable_count();
|
|
||||||
self.as_slice_mut()[..cnt].iter_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'it, T, const N: usize> IntoIterator for &'it ConstMapObserver<'a, T, N>
|
impl<'a, 'it, T, const N: usize> IntoIterator for &'it ConstMapObserver<'a, T, N>
|
||||||
where
|
where
|
||||||
T: Bounded
|
T: Bounded
|
||||||
@ -1276,13 +1128,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, idx: usize) -> &T {
|
fn get(&self, idx: usize) -> T {
|
||||||
&self.as_slice()[idx]
|
self.as_slice()[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut T {
|
fn set(&mut self, idx: usize, val: T) {
|
||||||
&mut self.as_slice_mut()[idx]
|
self.map.as_slice_mut()[idx] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Count the set bytes in the map
|
/// Count the set bytes in the map
|
||||||
@ -1340,25 +1192,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, const N: usize> AsSlice for ConstMapObserver<'a, T, N>
|
impl<'a, T, const N: usize> Deref for ConstMapObserver<'a, T, N>
|
||||||
where
|
where
|
||||||
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
type Entry = T;
|
type Target = [T];
|
||||||
#[inline]
|
fn deref(&self) -> &[T] {
|
||||||
fn as_slice(&self) -> &[T] {
|
&self.map
|
||||||
self.map.as_slice()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, const N: usize> AsSliceMut for ConstMapObserver<'a, T, N>
|
impl<'a, T, const N: usize> DerefMut for ConstMapObserver<'a, T, N>
|
||||||
where
|
where
|
||||||
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
type Entry = T;
|
fn deref_mut(&mut self) -> &mut [T] {
|
||||||
#[inline]
|
&mut self.map
|
||||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
|
||||||
self.map.as_slice_mut()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1459,52 +1308,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'it, T> AsIter<'it> for VariableMapObserver<'a, T>
|
|
||||||
where
|
|
||||||
T: Bounded
|
|
||||||
+ PartialEq
|
|
||||||
+ Default
|
|
||||||
+ Copy
|
|
||||||
+ Hash
|
|
||||||
+ 'static
|
|
||||||
+ Serialize
|
|
||||||
+ serde::de::DeserializeOwned
|
|
||||||
+ Debug
|
|
||||||
+ PartialEq
|
|
||||||
+ Bounded,
|
|
||||||
{
|
|
||||||
type Item = T;
|
|
||||||
type IntoIter = Iter<'it, T>;
|
|
||||||
|
|
||||||
fn as_iter(&'it self) -> Self::IntoIter {
|
|
||||||
let cnt = self.usable_count();
|
|
||||||
self.as_slice()[..cnt].iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'it, T> AsIterMut<'it> for VariableMapObserver<'a, T>
|
|
||||||
where
|
|
||||||
T: Bounded
|
|
||||||
+ PartialEq
|
|
||||||
+ Default
|
|
||||||
+ Copy
|
|
||||||
+ Hash
|
|
||||||
+ 'static
|
|
||||||
+ Serialize
|
|
||||||
+ serde::de::DeserializeOwned
|
|
||||||
+ Debug
|
|
||||||
+ PartialEq
|
|
||||||
+ Bounded,
|
|
||||||
{
|
|
||||||
type Item = T;
|
|
||||||
type IntoIter = IterMut<'it, T>;
|
|
||||||
|
|
||||||
fn as_iter_mut(&'it mut self) -> Self::IntoIter {
|
|
||||||
let cnt = self.usable_count();
|
|
||||||
self.as_slice_mut()[..cnt].iter_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'it, T> IntoIterator for &'it VariableMapObserver<'a, T>
|
impl<'a, 'it, T> IntoIterator for &'it VariableMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: Bounded
|
T: Bounded
|
||||||
@ -1595,6 +1398,7 @@ where
|
|||||||
self.as_slice().hash(hasher);
|
self.as_slice().hash(hasher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> AsRef<Self> for VariableMapObserver<'a, T>
|
impl<'a, T> AsRef<Self> for VariableMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: Default + Copy + 'static + Serialize + PartialEq + Bounded,
|
T: Default + Copy + 'static + Serialize + PartialEq + Bounded,
|
||||||
@ -1639,12 +1443,12 @@ where
|
|||||||
*self.size.as_ref()
|
*self.size.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self, idx: usize) -> &T {
|
fn get(&self, idx: usize) -> T {
|
||||||
&self.map.as_slice()[idx]
|
self.map.as_slice()[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut T {
|
fn set(&mut self, idx: usize, val: T) {
|
||||||
&mut self.map.as_slice_mut()[idx]
|
self.map.as_slice_mut()[idx] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Count the set bytes in the map
|
/// Count the set bytes in the map
|
||||||
@ -1697,7 +1501,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> AsSlice for VariableMapObserver<'a, T>
|
impl<'a, T> Deref for VariableMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: Bounded
|
T: Bounded
|
||||||
+ PartialEq
|
+ PartialEq
|
||||||
@ -1711,15 +1515,14 @@ where
|
|||||||
+ PartialEq
|
+ PartialEq
|
||||||
+ Bounded,
|
+ Bounded,
|
||||||
{
|
{
|
||||||
type Entry = T;
|
type Target = [T];
|
||||||
#[inline]
|
fn deref(&self) -> &[T] {
|
||||||
fn as_slice(&self) -> &[T] {
|
|
||||||
let cnt = self.usable_count();
|
let cnt = self.usable_count();
|
||||||
&self.map.as_slice()[..cnt]
|
&self.map[..cnt]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> AsSliceMut for VariableMapObserver<'a, T>
|
impl<'a, T> DerefMut for VariableMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: 'static
|
T: 'static
|
||||||
+ Default
|
+ Default
|
||||||
@ -1731,11 +1534,9 @@ where
|
|||||||
+ PartialEq
|
+ PartialEq
|
||||||
+ Bounded,
|
+ Bounded,
|
||||||
{
|
{
|
||||||
type Entry = T;
|
fn deref_mut(&mut self) -> &mut [T] {
|
||||||
#[inline]
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
|
||||||
let cnt = self.usable_count();
|
let cnt = self.usable_count();
|
||||||
&mut self.map.as_slice_mut()[..cnt]
|
&mut self.map[..cnt]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1795,7 +1596,7 @@ where
|
|||||||
|
|
||||||
impl<S, M> Observer<S> for HitcountsMapObserver<M>
|
impl<S, M> Observer<S> for HitcountsMapObserver<M>
|
||||||
where
|
where
|
||||||
M: MapObserver<Entry = u8> + Observer<S> + AsSliceMut<Entry = u8>,
|
M: MapObserver<Entry = u8> + Observer<S> + for<'a> AsSliceMut<'a, Entry = u8>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -1811,7 +1612,7 @@ where
|
|||||||
input: &S::Input,
|
input: &S::Input,
|
||||||
exit_kind: &ExitKind,
|
exit_kind: &ExitKind,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let map = self.as_slice_mut();
|
let mut map = self.as_slice_mut();
|
||||||
let mut len = map.len();
|
let mut len = map.len();
|
||||||
let align_offset = map.as_ptr().align_offset(size_of::<u16>());
|
let align_offset = map.as_ptr().align_offset(size_of::<u16>());
|
||||||
|
|
||||||
@ -1849,6 +1650,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop(map);
|
||||||
|
|
||||||
self.base.post_exec(state, input, exit_kind)
|
self.base.post_exec(state, input, exit_kind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1908,13 +1711,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, idx: usize) -> &u8 {
|
fn get(&self, idx: usize) -> u8 {
|
||||||
self.base.get(idx)
|
self.base.get(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut u8 {
|
fn set(&mut self, idx: usize, val: u8) {
|
||||||
self.base.get_mut(idx)
|
self.base.set(idx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Count the set bytes in the map
|
/// Count the set bytes in the map
|
||||||
@ -1950,24 +1753,26 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> AsSlice for HitcountsMapObserver<M>
|
impl<'a, M> AsSlice<'a> for HitcountsMapObserver<M>
|
||||||
where
|
where
|
||||||
M: MapObserver + AsSlice,
|
M: MapObserver + AsSlice<'a>,
|
||||||
{
|
{
|
||||||
type Entry = <M as AsSlice>::Entry;
|
type Entry = <M as AsSlice<'a>>::Entry;
|
||||||
|
type SliceRef = <M as AsSlice<'a>>::SliceRef;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_slice(&self) -> &[Self::Entry] {
|
fn as_slice(&'a self) -> Self::SliceRef {
|
||||||
self.base.as_slice()
|
self.base.as_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> AsSliceMut for HitcountsMapObserver<M>
|
impl<'a, M> AsSliceMut<'a> for HitcountsMapObserver<M>
|
||||||
where
|
where
|
||||||
M: MapObserver + AsSliceMut,
|
M: MapObserver + AsSliceMut<'a>,
|
||||||
{
|
{
|
||||||
type Entry = <M as AsSliceMut>::Entry;
|
type SliceRefMut = <M as AsSliceMut<'a>>::SliceRefMut;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
|
fn as_slice_mut(&'a mut self) -> Self::SliceRefMut {
|
||||||
self.base.as_slice_mut()
|
self.base.as_slice_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1983,30 +1788,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'it, M> AsIter<'it> for HitcountsMapObserver<M>
|
|
||||||
where
|
|
||||||
M: Named + Serialize + serde::de::DeserializeOwned + AsIter<'it, Item = u8>,
|
|
||||||
{
|
|
||||||
type Item = u8;
|
|
||||||
type IntoIter = <M as AsIter<'it>>::IntoIter;
|
|
||||||
|
|
||||||
fn as_iter(&'it self) -> Self::IntoIter {
|
|
||||||
self.base.as_iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'it, M> AsIterMut<'it> for HitcountsMapObserver<M>
|
|
||||||
where
|
|
||||||
M: Named + Serialize + serde::de::DeserializeOwned + AsIterMut<'it, Item = u8>,
|
|
||||||
{
|
|
||||||
type Item = u8;
|
|
||||||
type IntoIter = <M as AsIterMut<'it>>::IntoIter;
|
|
||||||
|
|
||||||
fn as_iter_mut(&'it mut self) -> Self::IntoIter {
|
|
||||||
self.base.as_iter_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'it, M> IntoIterator for &'it HitcountsMapObserver<M>
|
impl<'it, M> IntoIterator for &'it HitcountsMapObserver<M>
|
||||||
where
|
where
|
||||||
M: Serialize + serde::de::DeserializeOwned,
|
M: Serialize + serde::de::DeserializeOwned,
|
||||||
@ -2060,7 +1841,7 @@ where
|
|||||||
M: DifferentialObserver<OTA, OTB, S>
|
M: DifferentialObserver<OTA, OTB, S>
|
||||||
+ MapObserver<Entry = u8>
|
+ MapObserver<Entry = u8>
|
||||||
+ Serialize
|
+ Serialize
|
||||||
+ AsSliceMut<Entry = u8>,
|
+ for<'a> AsSliceMut<'a, Entry = u8>,
|
||||||
OTA: ObserversTuple<S>,
|
OTA: ObserversTuple<S>,
|
||||||
OTB: ObserversTuple<S>,
|
OTB: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -2113,7 +1894,7 @@ where
|
|||||||
input: &S::Input,
|
input: &S::Input,
|
||||||
exit_kind: &ExitKind,
|
exit_kind: &ExitKind,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
for item in self.as_iter_mut() {
|
for mut item in self.as_iter_mut() {
|
||||||
*item = unsafe { *COUNT_CLASS_LOOKUP.get_unchecked((*item) as usize) };
|
*item = unsafe { *COUNT_CLASS_LOOKUP.get_unchecked((*item) as usize) };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2179,13 +1960,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, idx: usize) -> &u8 {
|
fn get(&self, idx: usize) -> u8 {
|
||||||
self.base.get(idx)
|
self.base.get(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut u8 {
|
fn set(&mut self, idx: usize, val: u8) {
|
||||||
self.base.get_mut(idx)
|
self.base.set(idx, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Count the set bytes in the map
|
/// Count the set bytes in the map
|
||||||
@ -2221,28 +2002,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> AsSlice for HitcountsIterableMapObserver<M>
|
|
||||||
where
|
|
||||||
M: MapObserver + AsSlice,
|
|
||||||
{
|
|
||||||
type Entry = <M as AsSlice>::Entry;
|
|
||||||
#[inline]
|
|
||||||
fn as_slice(&self) -> &[Self::Entry] {
|
|
||||||
self.base.as_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<M> AsSliceMut for HitcountsIterableMapObserver<M>
|
|
||||||
where
|
|
||||||
M: MapObserver + AsSliceMut,
|
|
||||||
{
|
|
||||||
type Entry = <M as AsSliceMut>::Entry;
|
|
||||||
#[inline]
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
|
|
||||||
self.base.as_slice_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<M> HitcountsIterableMapObserver<M>
|
impl<M> HitcountsIterableMapObserver<M>
|
||||||
where
|
where
|
||||||
M: Serialize + serde::de::DeserializeOwned,
|
M: Serialize + serde::de::DeserializeOwned,
|
||||||
@ -2259,6 +2018,7 @@ where
|
|||||||
M: Named + Serialize + serde::de::DeserializeOwned + AsIter<'it, Item = u8>,
|
M: Named + Serialize + serde::de::DeserializeOwned + AsIter<'it, Item = u8>,
|
||||||
{
|
{
|
||||||
type Item = u8;
|
type Item = u8;
|
||||||
|
type Ref = <M as AsIter<'it>>::Ref;
|
||||||
type IntoIter = <M as AsIter<'it>>::IntoIter;
|
type IntoIter = <M as AsIter<'it>>::IntoIter;
|
||||||
|
|
||||||
fn as_iter(&'it self) -> Self::IntoIter {
|
fn as_iter(&'it self) -> Self::IntoIter {
|
||||||
@ -2270,10 +2030,10 @@ impl<'it, M> AsIterMut<'it> for HitcountsIterableMapObserver<M>
|
|||||||
where
|
where
|
||||||
M: Named + Serialize + serde::de::DeserializeOwned + AsIterMut<'it, Item = u8>,
|
M: Named + Serialize + serde::de::DeserializeOwned + AsIterMut<'it, Item = u8>,
|
||||||
{
|
{
|
||||||
type Item = u8;
|
type RefMut = <M as AsIterMut<'it>>::RefMut;
|
||||||
type IntoIter = <M as AsIterMut<'it>>::IntoIter;
|
type IntoIterMut = <M as AsIterMut<'it>>::IntoIterMut;
|
||||||
|
|
||||||
fn as_iter_mut(&'it mut self) -> Self::IntoIter {
|
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut {
|
||||||
self.base.as_iter_mut()
|
self.base.as_iter_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2457,19 +2217,19 @@ where
|
|||||||
type Entry = T;
|
type Entry = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, idx: usize) -> &T {
|
fn get(&self, idx: usize) -> T {
|
||||||
let elem = self.intervals.query(idx..=idx).next().unwrap();
|
let elem = self.intervals.query(idx..=idx).next().unwrap();
|
||||||
let i = *elem.value;
|
let i = *elem.value;
|
||||||
let j = idx - elem.interval.start;
|
let j = idx - elem.interval.start;
|
||||||
&self.maps[i].as_slice()[j]
|
self.maps[i].as_slice()[j]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut T {
|
fn set(&mut self, idx: usize, val: Self::Entry) {
|
||||||
let elem = self.intervals.query(idx..=idx).next().unwrap();
|
let elem = self.intervals.query(idx..=idx).next().unwrap();
|
||||||
let i = *elem.value;
|
let i = *elem.value;
|
||||||
let j = idx - elem.interval.start;
|
let j = idx - elem.interval.start;
|
||||||
&mut self.maps[i].as_slice_mut()[j]
|
self.maps[i].as_slice_mut()[j] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -2513,7 +2273,7 @@ where
|
|||||||
let cnt = self.usable_count();
|
let cnt = self.usable_count();
|
||||||
let mut res = Vec::with_capacity(cnt);
|
let mut res = Vec::with_capacity(cnt);
|
||||||
for i in 0..cnt {
|
for i in 0..cnt {
|
||||||
res.push(*self.get(i));
|
res.push(self.get(i));
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
@ -2524,7 +2284,7 @@ where
|
|||||||
let cnt = self.usable_count();
|
let cnt = self.usable_count();
|
||||||
let mut res = 0;
|
let mut res = 0;
|
||||||
for i in indexes {
|
for i in indexes {
|
||||||
if *i < cnt && *self.get(*i) != initial {
|
if *i < cnt && self.get(*i) != initial {
|
||||||
res += 1;
|
res += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2611,6 +2371,7 @@ where
|
|||||||
'a: 'it,
|
'a: 'it,
|
||||||
{
|
{
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
type Ref = &'it T;
|
||||||
type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'a, T>>>;
|
type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'a, T>>>;
|
||||||
|
|
||||||
fn as_iter(&'it self) -> Self::IntoIter {
|
fn as_iter(&'it self) -> Self::IntoIter {
|
||||||
@ -2623,10 +2384,10 @@ where
|
|||||||
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
'a: 'it,
|
'a: 'it,
|
||||||
{
|
{
|
||||||
type Item = T;
|
type RefMut = &'it mut T;
|
||||||
type IntoIter = Flatten<IterMut<'it, OwnedMutSlice<'a, T>>>;
|
type IntoIterMut = Flatten<IterMut<'it, OwnedMutSlice<'a, T>>>;
|
||||||
|
|
||||||
fn as_iter_mut(&'it mut self) -> Self::IntoIter {
|
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut {
|
||||||
self.maps.iter_mut().flatten()
|
self.maps.iter_mut().flatten()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2727,30 +2488,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'it, T> AsIter<'it> for OwnedMapObserver<T>
|
|
||||||
where
|
|
||||||
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
|
||||||
{
|
|
||||||
type Item = T;
|
|
||||||
type IntoIter = Iter<'it, T>;
|
|
||||||
|
|
||||||
fn as_iter(&'it self) -> Self::IntoIter {
|
|
||||||
self.as_slice().iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'it, T> AsIterMut<'it> for OwnedMapObserver<T>
|
|
||||||
where
|
|
||||||
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
|
||||||
{
|
|
||||||
type Item = T;
|
|
||||||
type IntoIter = IterMut<'it, T>;
|
|
||||||
|
|
||||||
fn as_iter_mut(&'it mut self) -> Self::IntoIter {
|
|
||||||
self.as_slice_mut().iter_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'it, T> IntoIterator for &'it OwnedMapObserver<T>
|
impl<'it, T> IntoIterator for &'it OwnedMapObserver<T>
|
||||||
where
|
where
|
||||||
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
@ -2833,13 +2570,13 @@ where
|
|||||||
type Entry = T;
|
type Entry = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, pos: usize) -> &T {
|
fn get(&self, pos: usize) -> T {
|
||||||
&self.as_slice()[pos]
|
self.as_slice()[pos]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut T {
|
fn set(&mut self, pos: usize, val: Self::Entry) {
|
||||||
&mut self.as_slice_mut()[idx]
|
self.as_slice_mut()[pos] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Count the set bytes in the map
|
/// Count the set bytes in the map
|
||||||
@ -2901,27 +2638,23 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AsSlice for OwnedMapObserver<T>
|
impl<T> Deref for OwnedMapObserver<T>
|
||||||
where
|
where
|
||||||
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
type Entry = T;
|
type Target = [T];
|
||||||
#[must_use]
|
|
||||||
#[inline]
|
fn deref(&self) -> &[T] {
|
||||||
fn as_slice(&self) -> &[T] {
|
&self.map
|
||||||
self.map.as_slice()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AsSliceMut for OwnedMapObserver<T>
|
impl<T> DerefMut for OwnedMapObserver<T>
|
||||||
where
|
where
|
||||||
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
type Entry = T;
|
fn deref_mut(&mut self) -> &mut [T] {
|
||||||
#[must_use]
|
&mut self.map
|
||||||
#[inline]
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
|
||||||
self.map.as_slice_mut()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
//! A simple observer with a single value.
|
//! A simple observer with a single value.
|
||||||
|
|
||||||
use alloc::{borrow::Cow, boxed::Box};
|
use alloc::{borrow::Cow, boxed::Box, vec::Vec};
|
||||||
use core::{
|
use core::{
|
||||||
cell::{Ref, RefCell},
|
cell::{Ref, RefCell, RefMut},
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
hash::Hash,
|
hash::{Hash, Hasher},
|
||||||
ops::Deref,
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
use ahash::RandomState;
|
use ahash::RandomState;
|
||||||
use libafl_bolts::{ownedref::OwnedRef, Named};
|
use libafl_bolts::{ownedref::OwnedRef, AsIter, AsIterMut, AsSlice, AsSliceMut, Named};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::Observer;
|
use super::Observer;
|
||||||
@ -100,21 +100,15 @@ where
|
|||||||
|
|
||||||
/// A simple observer with a single [`RefCell`]'d value.
|
/// A simple observer with a single [`RefCell`]'d value.
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
#[serde(bound = "T: serde::de::DeserializeOwned + serde::Serialize")]
|
||||||
pub struct RefCellValueObserver<'a, T>
|
pub struct RefCellValueObserver<'a, T> {
|
||||||
where
|
|
||||||
T: Debug + Serialize,
|
|
||||||
{
|
|
||||||
/// The name of this observer.
|
/// The name of this observer.
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
/// The value.
|
/// The value.
|
||||||
pub value: OwnedRef<'a, RefCell<T>>,
|
pub value: OwnedRef<'a, RefCell<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> RefCellValueObserver<'a, T>
|
impl<'a, T> RefCellValueObserver<'a, T> {
|
||||||
where
|
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
/// Creates a new [`RefCellValueObserver`] with the given name.
|
/// Creates a new [`RefCellValueObserver`] with the given name.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(name: &'static str, value: OwnedRef<'a, RefCell<T>>) -> Self {
|
pub fn new(name: &'static str, value: OwnedRef<'a, RefCell<T>>) -> Self {
|
||||||
@ -125,6 +119,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference to the underlying value.
|
/// Get a reference to the underlying value.
|
||||||
|
///
|
||||||
|
/// Panics if it can't borrow.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_ref<'b>(&'b self) -> Ref<'a, T>
|
pub fn get_ref<'b>(&'b self) -> Ref<'a, T>
|
||||||
where
|
where
|
||||||
@ -133,6 +129,17 @@ where
|
|||||||
self.value.as_ref().borrow()
|
self.value.as_ref().borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a mutable reference to the underlying value.
|
||||||
|
///
|
||||||
|
/// Panics if it can't borrow.
|
||||||
|
#[must_use]
|
||||||
|
pub fn get_ref_mut<'b>(&'b self) -> RefMut<'a, T>
|
||||||
|
where
|
||||||
|
'b: 'a,
|
||||||
|
{
|
||||||
|
self.value.as_ref().borrow_mut()
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the value.
|
/// Set the value.
|
||||||
pub fn set(&mut self, new_value: T) {
|
pub fn set(&mut self, new_value: T) {
|
||||||
self.value.as_ref().replace(new_value);
|
self.value.as_ref().replace(new_value);
|
||||||
@ -156,27 +163,246 @@ where
|
|||||||
impl<'a, S, T> Observer<S> for RefCellValueObserver<'a, T>
|
impl<'a, S, T> Observer<S> for RefCellValueObserver<'a, T>
|
||||||
where
|
where
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
{
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
|
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Named for RefCellValueObserver<'a, T>
|
impl<'a, T> Named for RefCellValueObserver<'a, T> {
|
||||||
where
|
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
|
||||||
{
|
|
||||||
fn name(&self) -> &Cow<'static, str> {
|
fn name(&self) -> &Cow<'static, str> {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Hash> ObserverWithHashField for RefCellValueObserver<'a, T>
|
impl<'a, T> ObserverWithHashField for RefCellValueObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: Debug + Serialize + serde::de::DeserializeOwned,
|
T: Hash,
|
||||||
{
|
{
|
||||||
fn hash(&self) -> Option<u64> {
|
fn hash(&self) -> Option<u64> {
|
||||||
Some(RandomState::with_seeds(1, 2, 3, 4).hash_one(&*self.value.as_ref().borrow()))
|
Some(RandomState::with_seeds(1, 2, 3, 4).hash_one(&*self.value.as_ref().borrow()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`Iterator`] over [`RefCellValueObserver`] of a [`Deref`] to `[T]`.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RefCellValueObserverIter<'it, T> {
|
||||||
|
v: Ref<'it, [T]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'it, T: 'it, A: Deref<Target = [T]>> AsSlice<'it> for RefCellValueObserver<'_, A> {
|
||||||
|
type Entry = T;
|
||||||
|
type SliceRef = Ref<'it, [T]>;
|
||||||
|
|
||||||
|
fn as_slice(&'it self) -> Self::SliceRef {
|
||||||
|
Ref::map(self.value.as_ref().borrow(), |s| &**s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'it, T: 'it, A: DerefMut<Target = [T]>> AsSliceMut<'it> for RefCellValueObserver<'_, A> {
|
||||||
|
type SliceRefMut = RefMut<'it, [T]>;
|
||||||
|
|
||||||
|
fn as_slice_mut(&'it mut self) -> Self::SliceRefMut {
|
||||||
|
RefMut::map(self.value.as_ref().borrow_mut(), |s| &mut **s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'it, T: 'it, A: Deref<Target = [T]>> AsIter<'it> for RefCellValueObserver<'_, A> {
|
||||||
|
type Item = T;
|
||||||
|
type Ref = Ref<'it, Self::Item>;
|
||||||
|
type IntoIter = RefCellValueObserverIter<'it, T>;
|
||||||
|
|
||||||
|
fn as_iter(&'it self) -> Self::IntoIter {
|
||||||
|
Self::IntoIter {
|
||||||
|
v: Ref::map(self.value.as_ref().borrow(), Deref::deref),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'it, T: 'it> Iterator for RefCellValueObserverIter<'it, T> {
|
||||||
|
type Item = Ref<'it, T>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.v.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let cloned = Ref::clone(&self.v);
|
||||||
|
let (next, remainder) = Ref::map_split(cloned, |v| (&v[0], &v[1..]));
|
||||||
|
self.v = remainder;
|
||||||
|
Some(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`Iterator`] over [`RefCellValueObserver`] of a [`DerefMut`] to `[T]`.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RefCellValueObserverIterMut<'it, T> {
|
||||||
|
v: Option<RefMut<'it, [T]>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'it, T: 'it, A: Debug + DerefMut<Target = [T]> + Serialize> AsIterMut<'it>
|
||||||
|
for RefCellValueObserver<'_, A>
|
||||||
|
{
|
||||||
|
type RefMut = RefMut<'it, T>;
|
||||||
|
type IntoIterMut = RefCellValueObserverIterMut<'it, T>;
|
||||||
|
|
||||||
|
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut {
|
||||||
|
Self::IntoIterMut {
|
||||||
|
v: Some(RefMut::map(
|
||||||
|
self.value.as_ref().borrow_mut(),
|
||||||
|
DerefMut::deref_mut,
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'it, T: 'it> Iterator for RefCellValueObserverIterMut<'it, T> {
|
||||||
|
type Item = RefMut<'it, T>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if let Some(v) = self.v.take() {
|
||||||
|
let next_slice = if v.len() > 1 {
|
||||||
|
let (next, remainder) = RefMut::map_split(v, |v| v.split_at_mut(1));
|
||||||
|
self.v = Some(remainder);
|
||||||
|
next
|
||||||
|
} else {
|
||||||
|
v
|
||||||
|
};
|
||||||
|
Some(RefMut::map(next_slice, |v| &mut v[0]))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Hash, A> Hash for RefCellValueObserver<'a, A>
|
||||||
|
where
|
||||||
|
T: Debug,
|
||||||
|
A: Debug + Deref<Target = [T]> + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
#[inline]
|
||||||
|
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||||
|
(*self.get_ref()).hash(hasher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
impl<T, A> libafl_bolts::HasLen for RefCellValueObserver<'_, A>
|
||||||
|
where
|
||||||
|
T: Debug,
|
||||||
|
A: Debug + Deref<Target = [T]> + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.get_ref().len()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.get_ref().is_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Debug + Serialize + serde::de::DeserializeOwned> AsMut<Self>
|
||||||
|
for RefCellValueObserver<'_, T>
|
||||||
|
{
|
||||||
|
fn as_mut(&mut self) -> &mut Self {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Debug + Serialize + serde::de::DeserializeOwned> AsRef<Self>
|
||||||
|
for RefCellValueObserver<'_, T>
|
||||||
|
{
|
||||||
|
fn as_ref(&self) -> &Self {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, A> crate::observers::MapObserver for RefCellValueObserver<'_, A>
|
||||||
|
where
|
||||||
|
T: Copy + Debug + Default + Eq + Hash + num_traits::bounds::Bounded + 'static,
|
||||||
|
A: Debug
|
||||||
|
+ Default
|
||||||
|
+ Deref<Target = [T]>
|
||||||
|
+ DerefMut<Target = [T]>
|
||||||
|
+ serde::de::DeserializeOwned
|
||||||
|
+ Serialize
|
||||||
|
+ 'static,
|
||||||
|
{
|
||||||
|
type Entry = T;
|
||||||
|
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
fn get(&self, idx: usize) -> Self::Entry {
|
||||||
|
self.get_ref()[idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if the contained value is already borrowed (calls
|
||||||
|
/// [`RefCell::borrow_mut`]).
|
||||||
|
fn set(&mut self, idx: usize, val: Self::Entry) {
|
||||||
|
self.get_ref_mut()[idx] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
fn hash_simple(&self) -> u64 {
|
||||||
|
RandomState::with_seeds(0, 0, 0, 0).hash_one(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
fn usable_count(&self) -> usize {
|
||||||
|
self.get_ref().len()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
fn count_bytes(&self) -> u64 {
|
||||||
|
let default = Self::Entry::default();
|
||||||
|
let mut count = 0;
|
||||||
|
for entry in self.get_ref().iter() {
|
||||||
|
if entry != &default {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if the contained value is already borrowed (calls
|
||||||
|
/// [`RefCell::borrow_mut`]).
|
||||||
|
fn reset_map(&mut self) -> Result<(), Error> {
|
||||||
|
// This is less than optimal for `Vec`, for which we could use
|
||||||
|
// `.clear()`. However, it makes the `impl` more general. Worth it?
|
||||||
|
*self.get_ref_mut() = A::default();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
fn to_vec(&self) -> Vec<Self::Entry> {
|
||||||
|
(*self.get_ref()).to_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if the contained value is already mutably borrowed (calls
|
||||||
|
/// [`RefCell::borrow`]).
|
||||||
|
fn how_many_set(&self, indexes: &[usize]) -> usize {
|
||||||
|
let default = Self::Entry::default();
|
||||||
|
let mut count = 0;
|
||||||
|
let arr = self.get_ref();
|
||||||
|
for idx in indexes {
|
||||||
|
if arr[*idx] != default {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initial(&self) -> Self::Entry {
|
||||||
|
Self::Entry::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
//! Coverage accounting corpus scheduler, more details at <https://www.ndss-symposium.org/wp-content/uploads/2020/02/24422-paper.pdf>
|
//! Coverage accounting corpus scheduler, more details at <https://www.ndss-symposium.org/wp-content/uploads/2020/02/24422-paper.pdf>
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::fmt::Debug;
|
use core::{
|
||||||
|
fmt::Debug,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl_bolts::{rands::Rand, AsSlice, AsSliceMut, HasLen, HasRefCnt};
|
use libafl_bolts::{rands::Rand, HasLen, HasRefCnt};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -35,19 +38,15 @@ pub struct AccountingIndexesMetadata {
|
|||||||
|
|
||||||
libafl_bolts::impl_serdeany!(AccountingIndexesMetadata);
|
libafl_bolts::impl_serdeany!(AccountingIndexesMetadata);
|
||||||
|
|
||||||
impl AsSlice for AccountingIndexesMetadata {
|
impl Deref for AccountingIndexesMetadata {
|
||||||
type Entry = usize;
|
type Target = [usize];
|
||||||
/// Convert to a slice
|
fn deref(&self) -> &[usize] {
|
||||||
fn as_slice(&self) -> &[usize] {
|
&self.list
|
||||||
self.list.as_slice()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl AsSliceMut for AccountingIndexesMetadata {
|
impl DerefMut for AccountingIndexesMetadata {
|
||||||
type Entry = usize;
|
fn deref_mut(&mut self) -> &mut [usize] {
|
||||||
|
&mut self.list
|
||||||
/// Convert to a slice
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [usize] {
|
|
||||||
self.list.as_slice_mut()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use alloc::vec::Vec;
|
|||||||
use core::{any::type_name, cmp::Ordering, marker::PhantomData};
|
use core::{any::type_name, cmp::Ordering, marker::PhantomData};
|
||||||
|
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use libafl_bolts::{rands::Rand, serdeany::SerdeAny, AsSlice, HasRefCnt};
|
use libafl_bolts::{rands::Rand, serdeany::SerdeAny, AsIter, HasRefCnt};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -89,7 +89,7 @@ impl<CS, F, M, O> RemovableScheduler for MinimizerScheduler<CS, F, M, O>
|
|||||||
where
|
where
|
||||||
CS: RemovableScheduler,
|
CS: RemovableScheduler,
|
||||||
F: TestcaseScore<CS::State>,
|
F: TestcaseScore<CS::State>,
|
||||||
M: AsSlice<Entry = usize> + SerdeAny + HasRefCnt,
|
M: for<'a> AsIter<'a, Item = usize> + SerdeAny + HasRefCnt,
|
||||||
CS::State: HasCorpus + HasMetadata + HasRand,
|
CS::State: HasCorpus + HasMetadata + HasRand,
|
||||||
O: CanTrack,
|
O: CanTrack,
|
||||||
{
|
{
|
||||||
@ -130,13 +130,13 @@ where
|
|||||||
let factor = F::compute(state, &mut *old)?;
|
let factor = F::compute(state, &mut *old)?;
|
||||||
if let Some(old_map) = old.metadata_map_mut().get_mut::<M>() {
|
if let Some(old_map) = old.metadata_map_mut().get_mut::<M>() {
|
||||||
let mut e_iter = entries.iter();
|
let mut e_iter = entries.iter();
|
||||||
let mut map_iter = old_map.as_slice().iter(); // ASSERTION: guaranteed to be in order?
|
let mut map_iter = old_map.as_iter(); // ASSERTION: guaranteed to be in order?
|
||||||
|
|
||||||
// manual set intersection
|
// manual set intersection
|
||||||
let mut entry = e_iter.next();
|
let mut entry = e_iter.next();
|
||||||
let mut map_entry = map_iter.next();
|
let mut map_entry = map_iter.next();
|
||||||
while let Some(e) = entry {
|
while let Some(e) = entry {
|
||||||
if let Some(me) = map_entry {
|
if let Some(ref me) = map_entry {
|
||||||
match e.cmp(me) {
|
match e.cmp(me) {
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
entry = e_iter.next();
|
entry = e_iter.next();
|
||||||
@ -197,7 +197,7 @@ impl<CS, F, M, O> Scheduler for MinimizerScheduler<CS, F, M, O>
|
|||||||
where
|
where
|
||||||
CS: Scheduler,
|
CS: Scheduler,
|
||||||
F: TestcaseScore<CS::State>,
|
F: TestcaseScore<CS::State>,
|
||||||
M: AsSlice<Entry = usize> + SerdeAny + HasRefCnt,
|
M: for<'a> AsIter<'a, Item = usize> + SerdeAny + HasRefCnt,
|
||||||
CS::State: HasCorpus + HasMetadata + HasRand,
|
CS::State: HasCorpus + HasMetadata + HasRand,
|
||||||
O: CanTrack,
|
O: CanTrack,
|
||||||
{
|
{
|
||||||
@ -253,7 +253,7 @@ impl<CS, F, M, O> MinimizerScheduler<CS, F, M, O>
|
|||||||
where
|
where
|
||||||
CS: Scheduler,
|
CS: Scheduler,
|
||||||
F: TestcaseScore<CS::State>,
|
F: TestcaseScore<CS::State>,
|
||||||
M: AsSlice<Entry = usize> + SerdeAny + HasRefCnt,
|
M: for<'a> AsIter<'a, Item = usize> + SerdeAny + HasRefCnt,
|
||||||
CS::State: HasCorpus + HasMetadata + HasRand,
|
CS::State: HasCorpus + HasMetadata + HasRand,
|
||||||
O: CanTrack,
|
O: CanTrack,
|
||||||
{
|
{
|
||||||
@ -276,8 +276,8 @@ where
|
|||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
let top_rateds = state.metadata_map().get::<TopRatedsMetadata>().unwrap();
|
let top_rateds = state.metadata_map().get::<TopRatedsMetadata>().unwrap();
|
||||||
for elem in meta.as_slice() {
|
for elem in meta.as_iter() {
|
||||||
if let Some(old_idx) = top_rateds.map.get(elem) {
|
if let Some(old_idx) = top_rateds.map.get(&*elem) {
|
||||||
if *old_idx == idx {
|
if *old_idx == idx {
|
||||||
new_favoreds.push(*elem); // always retain current; we'll drop it later otherwise
|
new_favoreds.push(*elem); // always retain current; we'll drop it later otherwise
|
||||||
continue;
|
continue;
|
||||||
@ -350,7 +350,7 @@ where
|
|||||||
type_name::<M>()
|
type_name::<M>()
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
for elem in meta.as_slice() {
|
for elem in meta.as_iter() {
|
||||||
acc.insert(*elem);
|
acc.insert(*elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +213,7 @@ use core::{
|
|||||||
array::TryFromSliceError,
|
array::TryFromSliceError,
|
||||||
fmt::{self, Display},
|
fmt::{self, Display},
|
||||||
num::{ParseIntError, TryFromIntError},
|
num::{ParseIntError, TryFromIntError},
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
time,
|
time,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -674,68 +675,47 @@ pub trait IntoOwned {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Can be converted to a slice
|
/// Can be converted to a slice
|
||||||
pub trait AsSlice {
|
pub trait AsSlice<'a> {
|
||||||
/// Type of the entries in this slice
|
/// Type of the entries of this slice
|
||||||
type Entry;
|
type Entry: 'a;
|
||||||
|
/// Type of the reference to this slice
|
||||||
|
type SliceRef: Deref<Target = [Self::Entry]>;
|
||||||
|
|
||||||
/// Convert to a slice
|
/// Convert to a slice
|
||||||
fn as_slice(&self) -> &[Self::Entry];
|
fn as_slice(&'a self) -> Self::SliceRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T, R> AsSlice<'a> for R
|
||||||
|
where
|
||||||
|
T: 'a,
|
||||||
|
R: Deref<Target = [T]>,
|
||||||
|
{
|
||||||
|
type Entry = T;
|
||||||
|
type SliceRef = &'a [T];
|
||||||
|
|
||||||
|
fn as_slice(&'a self) -> Self::SliceRef {
|
||||||
|
&*self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Can be converted to a mutable slice
|
/// Can be converted to a mutable slice
|
||||||
pub trait AsSliceMut {
|
pub trait AsSliceMut<'a>: AsSlice<'a> {
|
||||||
/// Type of the entries in this mut slice
|
/// Type of the mutable reference to this slice
|
||||||
type Entry;
|
type SliceRefMut: DerefMut<Target = [Self::Entry]>;
|
||||||
|
|
||||||
/// Convert to a slice
|
/// Convert to a slice
|
||||||
fn as_slice_mut(&mut self) -> &mut [Self::Entry];
|
fn as_slice_mut(&'a mut self) -> Self::SliceRefMut;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
impl<'a, T, R> AsSliceMut<'a> for R
|
||||||
impl<T> AsSlice for Vec<T> {
|
where
|
||||||
type Entry = T;
|
T: 'a,
|
||||||
|
R: DerefMut<Target = [T]>,
|
||||||
|
{
|
||||||
|
type SliceRefMut = &'a mut [T];
|
||||||
|
|
||||||
fn as_slice(&self) -> &[Self::Entry] {
|
fn as_slice_mut(&'a mut self) -> Self::SliceRefMut {
|
||||||
self
|
&mut *self
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
impl<T> AsSliceMut for Vec<T> {
|
|
||||||
type Entry = T;
|
|
||||||
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> AsSlice for &[T] {
|
|
||||||
type Entry = T;
|
|
||||||
|
|
||||||
fn as_slice(&self) -> &[Self::Entry] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> AsSlice for [T] {
|
|
||||||
type Entry = T;
|
|
||||||
|
|
||||||
fn as_slice(&self) -> &[Self::Entry] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> AsSliceMut for &mut [T] {
|
|
||||||
type Entry = T;
|
|
||||||
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> AsSliceMut for [T] {
|
|
||||||
type Entry = T;
|
|
||||||
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,22 +723,51 @@ impl<T> AsSliceMut for [T] {
|
|||||||
pub trait AsIter<'it> {
|
pub trait AsIter<'it> {
|
||||||
/// The item type
|
/// The item type
|
||||||
type Item: 'it;
|
type Item: 'it;
|
||||||
|
/// The ref type
|
||||||
|
type Ref: Deref<Target = Self::Item>;
|
||||||
/// The iterator type
|
/// The iterator type
|
||||||
type IntoIter: Iterator<Item = &'it Self::Item>;
|
type IntoIter: Iterator<Item = Self::Ref>;
|
||||||
|
|
||||||
/// Create an iterator from &self
|
/// Create an iterator from &self
|
||||||
fn as_iter(&'it self) -> Self::IntoIter;
|
fn as_iter(&'it self) -> Self::IntoIter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'it, S, T> AsIter<'it> for S
|
||||||
|
where
|
||||||
|
S: AsSlice<'it, Entry = T, SliceRef = &'it [T]>,
|
||||||
|
T: 'it,
|
||||||
|
{
|
||||||
|
type Item = S::Entry;
|
||||||
|
type Ref = &'it Self::Item;
|
||||||
|
type IntoIter = core::slice::Iter<'it, Self::Item>;
|
||||||
|
|
||||||
|
fn as_iter(&'it self) -> Self::IntoIter {
|
||||||
|
self.as_slice().iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create an `Iterator` from a mutable reference
|
/// Create an `Iterator` from a mutable reference
|
||||||
pub trait AsIterMut<'it> {
|
pub trait AsIterMut<'it>: AsIter<'it> {
|
||||||
/// The item type
|
/// The ref type
|
||||||
type Item: 'it;
|
type RefMut: DerefMut<Target = Self::Item>;
|
||||||
/// The iterator type
|
/// The iterator type
|
||||||
type IntoIter: Iterator<Item = &'it mut Self::Item>;
|
type IntoIterMut: Iterator<Item = Self::RefMut>;
|
||||||
|
|
||||||
/// Create an iterator from &mut self
|
/// Create an iterator from &mut self
|
||||||
fn as_iter_mut(&'it mut self) -> Self::IntoIter;
|
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'it, S, T> AsIterMut<'it> for S
|
||||||
|
where
|
||||||
|
S: AsSliceMut<'it, Entry = T, SliceRef = &'it [T], SliceRefMut = &'it mut [T]>,
|
||||||
|
T: 'it,
|
||||||
|
{
|
||||||
|
type RefMut = &'it mut Self::Item;
|
||||||
|
type IntoIterMut = core::slice::IterMut<'it, Self::Item>;
|
||||||
|
|
||||||
|
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut {
|
||||||
|
self.as_slice_mut().iter_mut()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Has a length field
|
/// Has a length field
|
||||||
|
@ -394,14 +394,14 @@ impl Listener {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
unsafe fn shmem2page_mut<SHM: ShMem>(afl_shmem: &mut SHM) -> *mut LlmpPage {
|
unsafe fn shmem2page_mut<SHM: ShMem>(afl_shmem: &mut SHM) -> *mut LlmpPage {
|
||||||
afl_shmem.as_slice_mut().as_mut_ptr() as *mut LlmpPage
|
afl_shmem.as_mut_ptr() as *mut LlmpPage
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get sharedmem from a page
|
/// Get sharedmem from a page
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
unsafe fn shmem2page<SHM: ShMem>(afl_shmem: &SHM) -> *const LlmpPage {
|
unsafe fn shmem2page<SHM: ShMem>(afl_shmem: &SHM) -> *const LlmpPage {
|
||||||
afl_shmem.as_slice().as_ptr() as *const LlmpPage
|
afl_shmem.as_ptr() as *const LlmpPage
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return, if a msg is contained in the current page
|
/// Return, if a msg is contained in the current page
|
||||||
@ -564,7 +564,7 @@ unsafe fn llmp_next_msg_ptr_checked<SHM: ShMem>(
|
|||||||
alloc_size: usize,
|
alloc_size: usize,
|
||||||
) -> Result<*mut LlmpMsg, Error> {
|
) -> Result<*mut LlmpMsg, Error> {
|
||||||
let page = map.page_mut();
|
let page = map.page_mut();
|
||||||
let map_size = map.shmem.as_slice().len();
|
let map_size = map.shmem.len();
|
||||||
let msg_begin_min = (page as *const u8).add(size_of::<LlmpPage>());
|
let msg_begin_min = (page as *const u8).add(size_of::<LlmpPage>());
|
||||||
// We still need space for this msg (alloc_size).
|
// We still need space for this msg (alloc_size).
|
||||||
let msg_begin_max = (page as *const u8).add(map_size - alloc_size);
|
let msg_begin_max = (page as *const u8).add(map_size - alloc_size);
|
||||||
@ -662,7 +662,7 @@ impl LlmpMsg {
|
|||||||
/// Returns `true`, if the pointer is, indeed, in the page of this shared map.
|
/// Returns `true`, if the pointer is, indeed, in the page of this shared map.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn in_shmem<SHM: ShMem>(&self, map: &mut LlmpSharedMap<SHM>) -> bool {
|
pub fn in_shmem<SHM: ShMem>(&self, map: &mut LlmpSharedMap<SHM>) -> bool {
|
||||||
let map_size = map.shmem.as_slice().len();
|
let map_size = map.shmem.len();
|
||||||
let buf_ptr = self.buf.as_ptr();
|
let buf_ptr = self.buf.as_ptr();
|
||||||
let len = self.buf_len_padded as usize + size_of::<LlmpMsg>();
|
let len = self.buf_len_padded as usize + size_of::<LlmpMsg>();
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -1970,7 +1970,7 @@ where
|
|||||||
let offset = offset as usize;
|
let offset = offset as usize;
|
||||||
|
|
||||||
let page = unsafe { self.page_mut() };
|
let page = unsafe { self.page_mut() };
|
||||||
let page_size = self.shmem.as_slice().len() - size_of::<LlmpPage>();
|
let page_size = self.shmem.len() - size_of::<LlmpPage>();
|
||||||
if offset > page_size {
|
if offset > page_size {
|
||||||
Err(Error::illegal_argument(format!(
|
Err(Error::illegal_argument(format!(
|
||||||
"Msg offset out of bounds (size: {page_size}, requested offset: {offset})"
|
"Msg offset out of bounds (size: {page_size}, requested offset: {offset})"
|
||||||
|
@ -10,7 +10,11 @@ use alloc::{
|
|||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use core::{mem::ManuallyDrop, ptr::addr_of};
|
use core::{
|
||||||
|
mem::ManuallyDrop,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
ptr::addr_of,
|
||||||
|
};
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::{
|
use std::{
|
||||||
@ -40,7 +44,7 @@ use uds::{UnixListenerExt, UnixSocketAddr, UnixStreamExt};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider},
|
shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider},
|
||||||
AsSlice, AsSliceMut, Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The default server name for our abstract shmem server
|
/// The default server name for our abstract shmem server
|
||||||
@ -79,6 +83,26 @@ where
|
|||||||
server_fd: i32,
|
server_fd: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<SH> Deref for ServedShMem<SH>
|
||||||
|
where
|
||||||
|
SH: ShMem,
|
||||||
|
{
|
||||||
|
type Target = [u8];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SH> DerefMut for ServedShMem<SH>
|
||||||
|
where
|
||||||
|
SH: ShMem,
|
||||||
|
{
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<SH> ShMem for ServedShMem<SH>
|
impl<SH> ShMem for ServedShMem<SH>
|
||||||
where
|
where
|
||||||
SH: ShMem,
|
SH: ShMem,
|
||||||
@ -87,29 +111,6 @@ where
|
|||||||
let client_id = self.inner.id();
|
let client_id = self.inner.id();
|
||||||
ShMemId::from_string(&format!("{}:{client_id}", self.server_fd))
|
ShMemId::from_string(&format!("{}:{client_id}", self.server_fd))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
|
||||||
self.inner.len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<SH> AsSlice for ServedShMem<SH>
|
|
||||||
where
|
|
||||||
SH: ShMem,
|
|
||||||
{
|
|
||||||
type Entry = u8;
|
|
||||||
fn as_slice(&self) -> &[u8] {
|
|
||||||
self.inner.as_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<SH> AsSliceMut for ServedShMem<SH>
|
|
||||||
where
|
|
||||||
SH: ShMem,
|
|
||||||
{
|
|
||||||
type Entry = u8;
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [u8] {
|
|
||||||
self.inner.as_slice_mut()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SP> ServedShMemProvider<SP>
|
impl<SP> ServedShMemProvider<SP>
|
||||||
|
@ -6,7 +6,12 @@ use alloc::{
|
|||||||
slice::{Iter, IterMut},
|
slice::{Iter, IterMut},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use core::{clone::Clone, fmt::Debug, slice};
|
use core::{
|
||||||
|
clone::Clone,
|
||||||
|
fmt::Debug,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
slice,
|
||||||
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
@ -455,11 +460,10 @@ impl<'a, T> From<OwnedMutSlice<'a, T>> for OwnedSlice<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Sized> AsSlice for OwnedSlice<'a, T> {
|
impl<'a, T: Sized> Deref for OwnedSlice<'a, T> {
|
||||||
type Entry = T;
|
type Target = [T];
|
||||||
/// Get the [`OwnedSlice`] as slice.
|
|
||||||
#[must_use]
|
fn deref(&self) -> &Self::Target {
|
||||||
fn as_slice(&self) -> &[T] {
|
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
OwnedSliceInner::Ref(r) => r,
|
OwnedSliceInner::Ref(r) => r,
|
||||||
OwnedSliceInner::RefRaw(rr, len, _) => unsafe { slice::from_raw_parts(*rr, *len) },
|
OwnedSliceInner::RefRaw(rr, len, _) => unsafe { slice::from_raw_parts(*rr, *len) },
|
||||||
@ -639,11 +643,10 @@ impl<'a, T: 'a + Sized> OwnedMutSlice<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Sized> AsSlice for OwnedMutSlice<'a, T> {
|
impl<'a, T: Sized> Deref for OwnedMutSlice<'a, T> {
|
||||||
type Entry = T;
|
type Target = [T];
|
||||||
/// Get the value as slice
|
|
||||||
#[must_use]
|
fn deref(&self) -> &Self::Target {
|
||||||
fn as_slice(&self) -> &[T] {
|
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe { slice::from_raw_parts(*rr, *len) },
|
OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe { slice::from_raw_parts(*rr, *len) },
|
||||||
OwnedMutSliceInner::Ref(r) => r,
|
OwnedMutSliceInner::Ref(r) => r,
|
||||||
@ -651,11 +654,9 @@ impl<'a, T: Sized> AsSlice for OwnedMutSlice<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, T: Sized> AsSliceMut for OwnedMutSlice<'a, T> {
|
|
||||||
type Entry = T;
|
impl<'a, T: Sized> DerefMut for OwnedMutSlice<'a, T> {
|
||||||
/// Get the value as mut slice
|
fn deref_mut(&mut self) -> &mut [T] {
|
||||||
#[must_use]
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
|
||||||
match &mut self.inner {
|
match &mut self.inner {
|
||||||
OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe {
|
OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe {
|
||||||
slice::from_raw_parts_mut(*rr, *len)
|
slice::from_raw_parts_mut(*rr, *len)
|
||||||
|
@ -7,7 +7,11 @@ use alloc::{rc::Rc, string::ToString};
|
|||||||
use core::fmt::Display;
|
use core::fmt::Display;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use core::{cell::RefCell, fmt, mem::ManuallyDrop};
|
use core::{cell::RefCell, fmt, mem::ManuallyDrop};
|
||||||
use core::{fmt::Debug, mem};
|
use core::{
|
||||||
|
fmt::Debug,
|
||||||
|
mem,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::env;
|
use std::env;
|
||||||
#[cfg(all(unix, feature = "std", not(target_os = "haiku")))]
|
#[cfg(all(unix, feature = "std", not(target_os = "haiku")))]
|
||||||
@ -31,7 +35,7 @@ pub use win32_shmem::{Win32ShMem, Win32ShMemProvider};
|
|||||||
use crate::os::pipes::Pipe;
|
use crate::os::pipes::Pipe;
|
||||||
#[cfg(all(feature = "std", unix, not(target_os = "haiku")))]
|
#[cfg(all(feature = "std", unix, not(target_os = "haiku")))]
|
||||||
pub use crate::os::unix_shmem_server::{ServedShMemProvider, ShMemService};
|
pub use crate::os::unix_shmem_server::{ServedShMemProvider, ShMemService};
|
||||||
use crate::{AsSlice, AsSliceMut, Error};
|
use crate::Error;
|
||||||
|
|
||||||
/// The standard sharedmem provider
|
/// The standard sharedmem provider
|
||||||
#[cfg(all(windows, feature = "std"))]
|
#[cfg(all(windows, feature = "std"))]
|
||||||
@ -168,9 +172,10 @@ impl ShMemId {
|
|||||||
alloc::str::from_utf8(&self.id[..self.null_pos()]).unwrap()
|
alloc::str::from_utf8(&self.id[..self.null_pos()]).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl AsSlice for ShMemId {
|
|
||||||
type Entry = u8;
|
impl Deref for ShMemId {
|
||||||
fn as_slice(&self) -> &[u8] {
|
type Target = [u8];
|
||||||
|
fn deref(&self) -> &[u8] {
|
||||||
&self.id
|
&self.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,23 +197,15 @@ impl Display for ShMemId {
|
|||||||
/// A [`ShMem`] is an interface to shared maps.
|
/// A [`ShMem`] is an interface to shared maps.
|
||||||
/// They are the backbone of [`crate::llmp`] for inter-process communication.
|
/// They are the backbone of [`crate::llmp`] for inter-process communication.
|
||||||
/// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMemProvider`].
|
/// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMemProvider`].
|
||||||
pub trait ShMem: Sized + Debug + Clone + AsSlice<Entry = u8> + AsSliceMut<Entry = u8> {
|
pub trait ShMem: Sized + Debug + Clone + DerefMut<Target = [u8]> {
|
||||||
/// Get the id of this shared memory mapping
|
/// Get the id of this shared memory mapping
|
||||||
fn id(&self) -> ShMemId;
|
fn id(&self) -> ShMemId;
|
||||||
|
|
||||||
/// Get the size of this mapping
|
|
||||||
fn len(&self) -> usize;
|
|
||||||
|
|
||||||
/// Check if the mapping is empty
|
|
||||||
fn is_empty(&self) -> bool {
|
|
||||||
self.len() == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert to a ptr of a given type, checking the size.
|
/// Convert to a ptr of a given type, checking the size.
|
||||||
/// If the map is too small, returns `None`
|
/// If the map is too small, returns `None`
|
||||||
fn as_ptr_of<T: Sized>(&self) -> Option<*const T> {
|
fn as_ptr_of<T: Sized>(&self) -> Option<*const T> {
|
||||||
if self.len() >= mem::size_of::<T>() {
|
if self.len() >= mem::size_of::<T>() {
|
||||||
Some(self.as_slice().as_ptr() as *const T)
|
Some(self.as_ptr() as *const T)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -218,7 +215,7 @@ pub trait ShMem: Sized + Debug + Clone + AsSlice<Entry = u8> + AsSliceMut<Entry
|
|||||||
/// If the map is too small, returns `None`
|
/// If the map is too small, returns `None`
|
||||||
fn as_mut_ptr_of<T: Sized>(&mut self) -> Option<*mut T> {
|
fn as_mut_ptr_of<T: Sized>(&mut self) -> Option<*mut T> {
|
||||||
if self.len() >= mem::size_of::<T>() {
|
if self.len() >= mem::size_of::<T>() {
|
||||||
Some(self.as_slice_mut().as_mut_ptr() as *mut T)
|
Some(self.as_mut_ptr() as *mut T)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -339,31 +336,27 @@ where
|
|||||||
fn id(&self) -> ShMemId {
|
fn id(&self) -> ShMemId {
|
||||||
self.internal.id()
|
self.internal.id()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
#[cfg(feature = "alloc")]
|
||||||
self.internal.len()
|
impl<T> Deref for RcShMem<T>
|
||||||
|
where
|
||||||
|
T: ShMemProvider + Debug,
|
||||||
|
{
|
||||||
|
type Target = [u8];
|
||||||
|
|
||||||
|
fn deref(&self) -> &[u8] {
|
||||||
|
&self.internal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl<T> AsSlice for RcShMem<T>
|
impl<T> DerefMut for RcShMem<T>
|
||||||
where
|
where
|
||||||
T: ShMemProvider + Debug,
|
T: ShMemProvider + Debug,
|
||||||
{
|
{
|
||||||
type Entry = u8;
|
fn deref_mut(&mut self) -> &mut [u8] {
|
||||||
fn as_slice(&self) -> &[u8] {
|
&mut self.internal
|
||||||
self.internal.as_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
|
||||||
impl<T> AsSliceMut for RcShMem<T>
|
|
||||||
where
|
|
||||||
T: ShMemProvider + Debug,
|
|
||||||
{
|
|
||||||
type Entry = u8;
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [u8] {
|
|
||||||
self.internal.as_slice_mut()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,6 +555,13 @@ where
|
|||||||
/// Is needed on top.
|
/// Is needed on top.
|
||||||
#[cfg(all(unix, feature = "std", not(target_os = "haiku")))]
|
#[cfg(all(unix, feature = "std", not(target_os = "haiku")))]
|
||||||
pub mod unix_shmem {
|
pub mod unix_shmem {
|
||||||
|
/// Mmap [`ShMem`] for Unix
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
pub use default::MmapShMem;
|
||||||
|
/// Mmap [`ShMemProvider`] for Unix
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
pub use default::MmapShMemProvider;
|
||||||
|
|
||||||
#[cfg(doc)]
|
#[cfg(doc)]
|
||||||
use crate::shmem::{ShMem, ShMemProvider};
|
use crate::shmem::{ShMem, ShMemProvider};
|
||||||
|
|
||||||
@ -578,18 +578,13 @@ pub mod unix_shmem {
|
|||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
pub type UnixShMem = default::CommonUnixShMem;
|
pub type UnixShMem = default::CommonUnixShMem;
|
||||||
|
|
||||||
/// Mmap [`ShMem`] for Unix
|
|
||||||
#[cfg(not(target_os = "android"))]
|
|
||||||
pub use default::MmapShMem;
|
|
||||||
/// Mmap [`ShMemProvider`] for Unix
|
|
||||||
#[cfg(not(target_os = "android"))]
|
|
||||||
pub use default::MmapShMemProvider;
|
|
||||||
|
|
||||||
#[cfg(all(unix, feature = "std", not(target_os = "android")))]
|
#[cfg(all(unix, feature = "std", not(target_os = "android")))]
|
||||||
mod default {
|
mod default {
|
||||||
|
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
use core::{ptr, slice};
|
use core::{
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
ptr, slice,
|
||||||
|
};
|
||||||
use std::{io::Write, process};
|
use std::{io::Write, process};
|
||||||
|
|
||||||
use libc::{
|
use libc::{
|
||||||
@ -600,7 +595,7 @@ pub mod unix_shmem {
|
|||||||
use crate::{
|
use crate::{
|
||||||
rands::{Rand, RandomSeed, StdRand},
|
rands::{Rand, RandomSeed, StdRand},
|
||||||
shmem::{ShMem, ShMemId, ShMemProvider},
|
shmem::{ShMem, ShMemId, ShMemProvider},
|
||||||
AsSlice, AsSliceMut, Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is macOS's limit
|
// This is macOS's limit
|
||||||
@ -769,22 +764,18 @@ pub mod unix_shmem {
|
|||||||
fn id(&self) -> ShMemId {
|
fn id(&self) -> ShMemId {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
|
||||||
self.map_size
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSlice for MmapShMem {
|
impl Deref for MmapShMem {
|
||||||
type Entry = u8;
|
type Target = [u8];
|
||||||
fn as_slice(&self) -> &[u8] {
|
|
||||||
|
fn deref(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSliceMut for MmapShMem {
|
impl DerefMut for MmapShMem {
|
||||||
type Entry = u8;
|
fn deref_mut(&mut self) -> &mut [u8] {
|
||||||
fn as_slice_mut(&mut self) -> &mut [u8] {
|
|
||||||
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -881,22 +872,18 @@ pub mod unix_shmem {
|
|||||||
fn id(&self) -> ShMemId {
|
fn id(&self) -> ShMemId {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
|
||||||
self.map_size
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSlice for CommonUnixShMem {
|
impl Deref for CommonUnixShMem {
|
||||||
type Entry = u8;
|
type Target = [u8];
|
||||||
fn as_slice(&self) -> &[u8] {
|
|
||||||
|
fn deref(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSliceMut for CommonUnixShMem {
|
impl DerefMut for CommonUnixShMem {
|
||||||
type Entry = u8;
|
fn deref_mut(&mut self) -> &mut [u8] {
|
||||||
fn as_slice_mut(&mut self) -> &mut [u8] {
|
|
||||||
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -954,7 +941,10 @@ pub mod unix_shmem {
|
|||||||
#[cfg(all(unix, feature = "std"))]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
pub mod ashmem {
|
pub mod ashmem {
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
use core::{ptr, slice};
|
use core::{
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
ptr, slice,
|
||||||
|
};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
|
||||||
use libc::{
|
use libc::{
|
||||||
@ -964,7 +954,7 @@ pub mod unix_shmem {
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
shmem::{ShMem, ShMemId, ShMemProvider},
|
shmem::{ShMem, ShMemId, ShMemProvider},
|
||||||
AsSlice, AsSliceMut, Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An ashmem based impl for linux/android
|
/// An ashmem based impl for linux/android
|
||||||
@ -1091,23 +1081,18 @@ pub mod unix_shmem {
|
|||||||
fn id(&self) -> ShMemId {
|
fn id(&self) -> ShMemId {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
|
||||||
self.map_size
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSlice for AshmemShMem {
|
impl Deref for AshmemShMem {
|
||||||
type Entry = u8;
|
type Target = [u8];
|
||||||
fn as_slice(&self) -> &[u8] {
|
|
||||||
|
fn deref(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSliceMut for AshmemShMem {
|
impl DerefMut for AshmemShMem {
|
||||||
type Entry = u8;
|
fn deref_mut(&mut self) -> &mut [u8] {
|
||||||
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [u8] {
|
|
||||||
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1177,23 +1162,15 @@ pub mod unix_shmem {
|
|||||||
/// Then `win32` implementation for shared memory.
|
/// Then `win32` implementation for shared memory.
|
||||||
#[cfg(all(feature = "std", windows))]
|
#[cfg(all(feature = "std", windows))]
|
||||||
pub mod win32_shmem {
|
pub mod win32_shmem {
|
||||||
|
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use core::{
|
use core::{
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
slice,
|
slice,
|
||||||
};
|
};
|
||||||
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
shmem::{ShMem, ShMemId, ShMemProvider},
|
|
||||||
AsSlice, AsSliceMut, Error,
|
|
||||||
};
|
|
||||||
|
|
||||||
const INVALID_HANDLE_VALUE: isize = -1;
|
|
||||||
|
|
||||||
use windows::{
|
use windows::{
|
||||||
core::PCSTR,
|
core::PCSTR,
|
||||||
Win32::{
|
Win32::{
|
||||||
@ -1205,6 +1182,13 @@ pub mod win32_shmem {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
shmem::{ShMem, ShMemId, ShMemProvider},
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
const INVALID_HANDLE_VALUE: isize = -1;
|
||||||
|
|
||||||
/// The default [`ShMem`] impl for Windows using `shmctl` & `shmget`
|
/// The default [`ShMem`] impl for Windows using `shmctl` & `shmget`
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Win32ShMem {
|
pub struct Win32ShMem {
|
||||||
@ -1291,21 +1275,16 @@ pub mod win32_shmem {
|
|||||||
fn id(&self) -> ShMemId {
|
fn id(&self) -> ShMemId {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
|
||||||
self.map_size
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsSlice for Win32ShMem {
|
impl Deref for Win32ShMem {
|
||||||
type Entry = u8;
|
type Target = [u8];
|
||||||
fn as_slice(&self) -> &[u8] {
|
fn deref(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl AsSliceMut for Win32ShMem {
|
impl DerefMut for Win32ShMem {
|
||||||
type Entry = u8;
|
fn deref_mut(&mut self) -> &mut [u8] {
|
||||||
fn as_slice_mut(&mut self) -> &mut [u8] {
|
|
||||||
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1395,6 +1374,7 @@ impl<T: ShMem> ShMemCursor<T> {
|
|||||||
|
|
||||||
/// Slice from the current location on this map to the end, mutable
|
/// Slice from the current location on this map to the end, mutable
|
||||||
fn empty_slice_mut(&mut self) -> &mut [u8] {
|
fn empty_slice_mut(&mut self) -> &mut [u8] {
|
||||||
|
use crate::AsSliceMut;
|
||||||
&mut (self.inner.as_slice_mut()[self.pos..])
|
&mut (self.inner.as_slice_mut()[self.pos..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1442,6 +1422,7 @@ impl<T: ShMem> std::io::Seek for ShMemCursor<T> {
|
|||||||
let effective_new_pos = match pos {
|
let effective_new_pos = match pos {
|
||||||
std::io::SeekFrom::Start(s) => s,
|
std::io::SeekFrom::Start(s) => s,
|
||||||
std::io::SeekFrom::End(offset) => {
|
std::io::SeekFrom::End(offset) => {
|
||||||
|
use crate::AsSlice;
|
||||||
let map_len = self.inner.as_slice().len();
|
let map_len = self.inner.as_slice().len();
|
||||||
let signed_pos = i64::try_from(map_len).unwrap();
|
let signed_pos = i64::try_from(map_len).unwrap();
|
||||||
let effective = signed_pos.checked_add(offset).unwrap();
|
let effective = signed_pos.checked_add(offset).unwrap();
|
||||||
|
@ -195,9 +195,7 @@ where
|
|||||||
// # Safety
|
// # Safety
|
||||||
// The index is modulo by the length, therefore it is always in bounds
|
// The index is modulo by the length, therefore it is always in bounds
|
||||||
let len = self.hitcounts_map.len();
|
let len = self.hitcounts_map.len();
|
||||||
self.hitcounts_map
|
self.hitcounts_map.get_unchecked_mut(hash % len)
|
||||||
.as_slice_mut()
|
|
||||||
.get_unchecked_mut(hash % len)
|
|
||||||
};
|
};
|
||||||
*val = val.saturating_add(1);
|
*val = val.saturating_add(1);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ use std::{
|
|||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
|
ops::Deref,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ahash::AHasher;
|
use ahash::AHasher;
|
||||||
@ -107,16 +108,16 @@ where
|
|||||||
{
|
{
|
||||||
type Entry = O::ValueType;
|
type Entry = O::ValueType;
|
||||||
|
|
||||||
fn get(&self, idx: usize) -> &Self::Entry {
|
fn get(&self, idx: usize) -> Self::Entry {
|
||||||
let initial = self.inner.initial();
|
let initial = self.inner.initial();
|
||||||
if *self.inner.get(idx) == initial {
|
if self.inner.get(idx) == initial {
|
||||||
self.value_observer.default_value()
|
*self.value_observer.default_value()
|
||||||
} else {
|
} else {
|
||||||
self.value_observer.value()
|
*self.value_observer.value()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mut(&mut self, _idx: usize) -> &mut Self::Entry {
|
fn set(&mut self, _idx: usize, _val: Self::Entry) {
|
||||||
unimplemented!("Impossible to implement for a proxy map.")
|
unimplemented!("Impossible to implement for a proxy map.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +149,7 @@ where
|
|||||||
let value = *self.value_observer.value();
|
let value = *self.value_observer.value();
|
||||||
self.inner
|
self.inner
|
||||||
.as_iter()
|
.as_iter()
|
||||||
.map(|&e| if e == initial { default } else { value })
|
.map(|e| if *e == initial { default } else { value })
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,9 +203,10 @@ impl<'it, I, O, T> MappedEdgeMapIter<'it, I, O, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'it, I, O, T> Iterator for MappedEdgeMapIter<'it, I, O, T>
|
impl<'it, I, O, R, T> Iterator for MappedEdgeMapIter<'it, I, O, T>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = &'it T>,
|
I: Iterator<Item = R>,
|
||||||
|
R: Deref<Target = T>,
|
||||||
T: PartialEq + 'it,
|
T: PartialEq + 'it,
|
||||||
O: ValueObserver,
|
O: ValueObserver,
|
||||||
{
|
{
|
||||||
@ -225,6 +227,7 @@ where
|
|||||||
O: ValueObserver + 'it,
|
O: ValueObserver + 'it,
|
||||||
{
|
{
|
||||||
type Item = O::ValueType;
|
type Item = O::ValueType;
|
||||||
|
type Ref = &'it Self::Item;
|
||||||
type IntoIter = MappedEdgeMapIter<'it, <M as AsIter<'it>>::IntoIter, O, M::Entry>;
|
type IntoIter = MappedEdgeMapIter<'it, <M as AsIter<'it>>::IntoIter, O, M::Entry>;
|
||||||
|
|
||||||
fn as_iter(&'it self) -> Self::IntoIter {
|
fn as_iter(&'it self) -> Self::IntoIter {
|
||||||
|
@ -185,19 +185,19 @@ mod observers {
|
|||||||
type Entry = u8;
|
type Entry = u8;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, idx: usize) -> &u8 {
|
fn get(&self, idx: usize) -> u8 {
|
||||||
let elem = self.intervals.query(idx..=idx).next().unwrap();
|
let elem = self.intervals.query(idx..=idx).next().unwrap();
|
||||||
let i = elem.value;
|
let i = elem.value;
|
||||||
let j = idx - elem.interval.start;
|
let j = idx - elem.interval.start;
|
||||||
unsafe { &(*addr_of!(COUNTERS_MAPS[*i])).as_slice()[j] }
|
unsafe { (*addr_of!(COUNTERS_MAPS[*i])).as_slice()[j] }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut u8 {
|
fn set(&mut self, idx: usize, val: u8) {
|
||||||
let elem = self.intervals.query_mut(idx..=idx).next().unwrap();
|
let elem = self.intervals.query_mut(idx..=idx).next().unwrap();
|
||||||
let i = elem.value;
|
let i = elem.value;
|
||||||
let j = idx - elem.interval.start;
|
let j = idx - elem.interval.start;
|
||||||
unsafe { &mut (*addr_of_mut!(COUNTERS_MAPS[*i])).as_slice_mut()[j] }
|
unsafe { (*addr_of_mut!(COUNTERS_MAPS[*i])).as_slice_mut()[j] = val };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -241,7 +241,7 @@ mod observers {
|
|||||||
let cnt = self.usable_count();
|
let cnt = self.usable_count();
|
||||||
let mut res = Vec::with_capacity(cnt);
|
let mut res = Vec::with_capacity(cnt);
|
||||||
for i in 0..cnt {
|
for i in 0..cnt {
|
||||||
res.push(*self.get(i));
|
res.push(self.get(i));
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
@ -252,7 +252,7 @@ mod observers {
|
|||||||
let cnt = self.usable_count();
|
let cnt = self.usable_count();
|
||||||
let mut res = 0;
|
let mut res = 0;
|
||||||
for i in indexes {
|
for i in indexes {
|
||||||
if *i < cnt && *self.get(*i) != initial {
|
if *i < cnt && self.get(*i) != initial {
|
||||||
res += 1;
|
res += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -322,6 +322,7 @@ mod observers {
|
|||||||
|
|
||||||
impl<'it, const DIFFERENTIAL: bool> AsIter<'it> for CountersMultiMapObserver<DIFFERENTIAL> {
|
impl<'it, const DIFFERENTIAL: bool> AsIter<'it> for CountersMultiMapObserver<DIFFERENTIAL> {
|
||||||
type Item = u8;
|
type Item = u8;
|
||||||
|
type Ref = &'it Self::Item;
|
||||||
type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'static, u8>>>;
|
type IntoIter = Flatten<Iter<'it, OwnedMutSlice<'static, u8>>>;
|
||||||
|
|
||||||
fn as_iter(&'it self) -> Self::IntoIter {
|
fn as_iter(&'it self) -> Self::IntoIter {
|
||||||
@ -330,10 +331,10 @@ mod observers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'it, const DIFFERENTIAL: bool> AsIterMut<'it> for CountersMultiMapObserver<DIFFERENTIAL> {
|
impl<'it, const DIFFERENTIAL: bool> AsIterMut<'it> for CountersMultiMapObserver<DIFFERENTIAL> {
|
||||||
type Item = u8;
|
type RefMut = &'it mut Self::Item;
|
||||||
type IntoIter = Flatten<IterMut<'it, OwnedMutSlice<'static, u8>>>;
|
type IntoIterMut = Flatten<IterMut<'it, OwnedMutSlice<'static, u8>>>;
|
||||||
|
|
||||||
fn as_iter_mut(&'it mut self) -> Self::IntoIter {
|
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut {
|
||||||
unsafe { COUNTERS_MAPS.iter_mut().flatten() }
|
unsafe { COUNTERS_MAPS.iter_mut().flatten() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user