fix anymap traverse all
This commit is contained in:
parent
5d2e7b5bc2
commit
4e1d844b7d
@ -1,11 +1,10 @@
|
|||||||
use alloc::rc::Rc;
|
|
||||||
use core::cell::RefCell;
|
|
||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
|
||||||
use crate::executors::{Executor, ExitKind};
|
use crate::executors::{Executor, ExitKind};
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::metamap::NamedAnyMap;
|
use crate::metamap::NamedAnyMap;
|
||||||
|
use crate::observers::Observer;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
type HarnessFunction<I> = fn(&dyn Executor<I>, &[u8]) -> ExitKind;
|
||||||
@ -15,7 +14,7 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
harness: HarnessFunction<I>,
|
harness: HarnessFunction<I>,
|
||||||
observers: NamedAnyMap,
|
observers: NamedAnyMap<dyn Observer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut CURRENT_INMEMORY_EXECUTOR_PTR: *const c_void = ptr::null();
|
static mut CURRENT_INMEMORY_EXECUTOR_PTR: *const c_void = ptr::null();
|
||||||
@ -35,6 +34,14 @@ where
|
|||||||
}
|
}
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn observers(&self) -> &NamedAnyMap<dyn Observer> {
|
||||||
|
&self.observers
|
||||||
|
}
|
||||||
|
|
||||||
|
fn observers_mut(&mut self) -> &mut NamedAnyMap<dyn Observer> {
|
||||||
|
&mut self.observers
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> InMemoryExecutor<I>
|
impl<I> InMemoryExecutor<I>
|
||||||
@ -48,6 +55,7 @@ where
|
|||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
harness: harness_fn,
|
harness: harness_fn,
|
||||||
|
observers: NamedAnyMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
pub mod inmemory;
|
pub mod inmemory;
|
||||||
|
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::observers::Observer;
|
|
||||||
use crate::metamap::NamedAnyMap;
|
use crate::metamap::NamedAnyMap;
|
||||||
|
use crate::observers::Observer;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
pub enum ExitKind {
|
pub enum ExitKind {
|
||||||
@ -22,29 +22,33 @@ where
|
|||||||
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError>;
|
fn run_target(&mut self, input: &I) -> Result<ExitKind, AflError>;
|
||||||
|
|
||||||
/// Get the linked observers
|
/// Get the linked observers
|
||||||
fn observers(&self) -> &NamedAnyMap;
|
fn observers(&self) -> &NamedAnyMap<dyn Observer>;
|
||||||
|
|
||||||
/// Get the linked observers
|
/// Get the linked observers
|
||||||
fn observers_mut(&mut self) -> &mut NamedAnyMap;
|
fn observers_mut(&mut self) -> &mut NamedAnyMap<dyn Observer>;
|
||||||
|
|
||||||
/// Add a linked observer
|
/// Add a linked observer
|
||||||
fn add_observer(&mut self, observer: Box<dyn Observer>, name: &'static str) {
|
fn add_observer(&mut self, observer: Box<dyn Observer>) {
|
||||||
self.observers_mut().push(observer);
|
self.observers_mut().insert(observer, observer.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset the state of all the observes linked to this executor
|
/// Reset the state of all the observes linked to this executor
|
||||||
fn reset_observers(&mut self) -> Result<(), AflError> {
|
fn reset_observers(&mut self) -> Result<(), AflError> {
|
||||||
for observer in self.observers_mut() {
|
for typeid in self.observers().all_typeids() {
|
||||||
|
for observer in self.observers_mut().all_by_typeid_mut(typeid).unwrap() {
|
||||||
observer.reset()?;
|
observer.reset()?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the post exec hook for all the observes linked to this executor
|
/// Run the post exec hook for all the observes linked to this executor
|
||||||
fn post_exec_observers(&mut self) -> Result<(), AflError> {
|
fn post_exec_observers(&mut self) -> Result<(), AflError> {
|
||||||
self.observers_mut()
|
for typeid in self.observers().all_typeids() {
|
||||||
.iter()
|
for observer in self.observers_mut().all_by_typeid_mut(typeid).unwrap() {
|
||||||
.map(|x| x.post_exec())
|
observer.post_exec()?;
|
||||||
.fold(Ok(()), |acc, x| if x.is_err() { x } else { acc })
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ use num::Integer;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::corpus::{Testcase, TestcaseMetadata};
|
use crate::corpus::{Testcase, TestcaseMetadata};
|
||||||
|
use crate::executors::Executor;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::observers::MapObserver;
|
use crate::observers::MapObserver;
|
||||||
use crate::serde_anymap::SerdeAny;
|
use crate::serde_anymap::SerdeAny;
|
||||||
@ -17,7 +18,7 @@ where
|
|||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
/// is_interesting should return the "Interestingness" from 0 to 255 (percent times 2.55)
|
/// is_interesting should return the "Interestingness" from 0 to 255 (percent times 2.55)
|
||||||
fn is_interesting(&mut self, input: &I) -> Result<u32, AflError>;
|
fn is_interesting(&mut self, input: &I, executor: &dyn Executor<I>) -> Result<u32, AflError>;
|
||||||
|
|
||||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||||
fn append_metadata(&mut self, _testcase: &mut Testcase<I>) -> Result<(), AflError> {
|
fn append_metadata(&mut self, _testcase: &mut Testcase<I>) -> Result<(), AflError> {
|
||||||
@ -28,6 +29,8 @@ where
|
|||||||
fn discard_metadata(&mut self, _input: &I) -> Result<(), AflError> {
|
fn discard_metadata(&mut self, _input: &I) -> Result<(), AflError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Reducer function is used to aggregate values for the novelty search
|
/// A Reducer function is used to aggregate values for the novelty search
|
||||||
@ -78,16 +81,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a usable history map of the given size
|
|
||||||
pub fn create_history_map<T>(map_size: usize) -> Rc<RefCell<Vec<T>>>
|
|
||||||
where
|
|
||||||
T: Default + Clone,
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Rc::new(RefCell::new(vec![T::default(); map_size]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The most common AFL-like feedback type
|
/// The most common AFL-like feedback type
|
||||||
pub struct MapFeedback<T, R, O>
|
pub struct MapFeedback<T, R, O>
|
||||||
where
|
where
|
||||||
@ -96,11 +89,11 @@ where
|
|||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
{
|
{
|
||||||
/// Contains information about untouched entries
|
/// Contains information about untouched entries
|
||||||
history_map: Rc<RefCell<Vec<T>>>,
|
history_map: Vec<T>,
|
||||||
/// The observer this feedback struct observes
|
/// Name identifier of this instance
|
||||||
map_observer: Rc<RefCell<O>>,
|
name: &'static str,
|
||||||
/// Phantom Data of Reducer
|
/// Phantom Data of Reducer
|
||||||
phantom: PhantomData<R>,
|
phantom: PhantomData<(R, O)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, R, O, I> Feedback<I> for MapFeedback<T, R, O>
|
impl<T, R, O, I> Feedback<I> for MapFeedback<T, R, O>
|
||||||
@ -110,9 +103,8 @@ where
|
|||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
fn is_interesting(&mut self, _input: &I) -> Result<u32, AflError> {
|
fn is_interesting(&mut self, _input: &I, executor: &dyn Executor<I>) -> Result<u32, AflError> {
|
||||||
let mut interesting = 0;
|
let mut interesting = 0;
|
||||||
|
|
||||||
// TODO optimize
|
// TODO optimize
|
||||||
let size = self.map_observer.borrow().map().len();
|
let size = self.map_observer.borrow().map().len();
|
||||||
let mut history_map = self.history_map.borrow_mut();
|
let mut history_map = self.history_map.borrow_mut();
|
||||||
@ -129,6 +121,10 @@ where
|
|||||||
|
|
||||||
Ok(interesting)
|
Ok(interesting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
self.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, R, O> MapFeedback<T, R, O>
|
impl<T, R, O> MapFeedback<T, R, O>
|
||||||
@ -137,11 +133,11 @@ where
|
|||||||
R: Reducer<T>,
|
R: Reducer<T>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
{
|
{
|
||||||
/// Create new MapFeedback using a map observer
|
/// Create new MapFeedback
|
||||||
pub fn new(map_observer: Rc<RefCell<O>>, map_size: usize) -> Self {
|
pub fn new(name: &'static str, map_size: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
map_observer: map_observer,
|
history_map: vec![T::default(); map_size],
|
||||||
history_map: create_history_map::<T>(map_size),
|
name: name,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,13 +151,10 @@ where
|
|||||||
{
|
{
|
||||||
/// Create new MapFeedback using a map observer, and a map.
|
/// Create new MapFeedback using a map observer, and a map.
|
||||||
/// The map can be shared.
|
/// The map can be shared.
|
||||||
pub fn with_history_map(
|
pub fn with_history_map(name: &'static str, history_map: Vec<T>) -> Self {
|
||||||
map_observer: Rc<RefCell<O>>,
|
|
||||||
history_map: Rc<RefCell<Vec<T>>>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
map_observer: map_observer,
|
|
||||||
history_map: history_map,
|
history_map: history_map,
|
||||||
|
name: name,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,11 +199,11 @@ where
|
|||||||
O: MapObserver<T>,
|
O: MapObserver<T>,
|
||||||
{
|
{
|
||||||
/// Contains information about untouched entries
|
/// Contains information about untouched entries
|
||||||
history_map: Rc<RefCell<Vec<T>>>,
|
history_map: Vec<T>,
|
||||||
/// The observer this feedback struct observes
|
/// Name identifier of this instance
|
||||||
map_observer: Rc<RefCell<O>>,
|
name: &'static str,
|
||||||
/// Phantom Data of Reducer
|
/// Phantom Data of Reducer
|
||||||
phantom: PhantomData<R>,
|
phantom: PhantomData<(R, O)>,
|
||||||
/// Track novel entries indexes
|
/// Track novel entries indexes
|
||||||
novelties: Vec<usize>,
|
novelties: Vec<usize>,
|
||||||
}
|
}
|
||||||
@ -254,6 +247,10 @@ where
|
|||||||
self.novelties.clear();
|
self.novelties.clear();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
self.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, R, O> MapTrackerFeedback<T, R, O>
|
impl<T, R, O> MapTrackerFeedback<T, R, O>
|
||||||
|
@ -2,7 +2,7 @@ use alloc::boxed::Box;
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::any::{Any, TypeId};
|
use core::any::{Any, TypeId};
|
||||||
use core::slice::{Iter, IterMut};
|
use core::slice::{Iter, IterMut};
|
||||||
use hashbrown::hash_map::{Values, ValuesMut};
|
use hashbrown::hash_map::{Keys, Values, ValuesMut};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
pub struct MetaMap {
|
pub struct MetaMap {
|
||||||
@ -241,11 +241,22 @@ impl MetaInstanceMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NamedAnyMap {
|
pub trait AsAny {
|
||||||
map: HashMap<TypeId, HashMap<&'static str, Box<dyn Any>>>,
|
fn as_any(&self) -> &dyn Any;
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NamedAnyMap {
|
pub struct NamedAnyMap<B>
|
||||||
|
where
|
||||||
|
B: ?Sized + Any + AsAny,
|
||||||
|
{
|
||||||
|
map: HashMap<TypeId, HashMap<&'static str, Box<B>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B> NamedAnyMap<B>
|
||||||
|
where
|
||||||
|
B: ?Sized + Any + AsAny,
|
||||||
|
{
|
||||||
pub fn get<T>(&self, name: &'static str) -> Option<&T>
|
pub fn get<T>(&self, name: &'static str) -> Option<&T>
|
||||||
where
|
where
|
||||||
T: Any,
|
T: Any,
|
||||||
@ -254,7 +265,14 @@ impl NamedAnyMap {
|
|||||||
None => None,
|
None => None,
|
||||||
Some(h) => h
|
Some(h) => h
|
||||||
.get(&name)
|
.get(&name)
|
||||||
.map(|x| x.as_ref().downcast_ref::<T>().unwrap()),
|
.map(|x| x.as_any().downcast_ref::<T>().unwrap()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn by_typeid(&self, name: &'static str, typeid: &TypeId) -> Option<&B> {
|
||||||
|
match self.map.get(typeid) {
|
||||||
|
None => None,
|
||||||
|
Some(h) => h.get(&name).map(|x| x.as_ref()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,27 +284,42 @@ impl NamedAnyMap {
|
|||||||
None => None,
|
None => None,
|
||||||
Some(h) => h
|
Some(h) => h
|
||||||
.get_mut(&name)
|
.get_mut(&name)
|
||||||
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
|
.map(|x| x.as_any_mut().downcast_mut::<T>().unwrap()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn by_typeid_mut(&mut self, name: &'static str, typeid: &TypeId) -> Option<&mut B> {
|
||||||
|
match self.map.get_mut(typeid) {
|
||||||
|
None => None,
|
||||||
|
Some(h) => h.get(&name).map(|x| x.as_mut()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all<T>(
|
pub fn get_all<T>(
|
||||||
&self,
|
&self,
|
||||||
) -> Option<core::iter::Map<Values<'_, &'static str, Box<dyn Any>>, fn(&Box<dyn Any>) -> &T>>
|
) -> Option<core::iter::Map<Values<'_, &'static str, Box<B>>, fn(&Box<B>) -> &T>>
|
||||||
where
|
where
|
||||||
T: Any,
|
T: Any,
|
||||||
{
|
{
|
||||||
match self.map.get(&TypeId::of::<T>()) {
|
match self.map.get(&TypeId::of::<T>()) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(h) => Some(h.values().map(|x| x.as_ref().downcast_ref::<T>().unwrap())),
|
Some(h) => Some(h.values().map(|x| x.as_any().downcast_ref::<T>().unwrap())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all_by_typeid(
|
||||||
|
&self,
|
||||||
|
typeid: &TypeId,
|
||||||
|
) -> Option<core::iter::Map<Values<'_, &'static str, Box<B>>, fn(&Box<B>) -> &B>> {
|
||||||
|
match self.map.get(typeid) {
|
||||||
|
None => None,
|
||||||
|
Some(h) => Some(h.values().map(|x| x.as_ref())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_mut<T>(
|
pub fn get_all_mut<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> Option<
|
) -> Option<core::iter::Map<ValuesMut<'_, &'static str, Box<B>>, fn(&mut Box<B>) -> &mut T>>
|
||||||
core::iter::Map<ValuesMut<'_, &'static str, Box<dyn Any>>, fn(&mut Box<dyn Any>) -> &mut T>,
|
|
||||||
>
|
|
||||||
where
|
where
|
||||||
T: Any,
|
T: Any,
|
||||||
{
|
{
|
||||||
@ -294,23 +327,32 @@ impl NamedAnyMap {
|
|||||||
None => None,
|
None => None,
|
||||||
Some(h) => Some(
|
Some(h) => Some(
|
||||||
h.values_mut()
|
h.values_mut()
|
||||||
.map(|x| x.as_mut().downcast_mut::<T>().unwrap()),
|
.map(|x| x.as_any_mut().downcast_mut::<T>().unwrap()),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert<T>(&mut self, t: T, name: &'static str)
|
pub fn all_by_typeid_mut(
|
||||||
where
|
&mut self,
|
||||||
T: Any,
|
typeid: &TypeId,
|
||||||
|
) -> Option<core::iter::Map<ValuesMut<'_, &'static str, Box<B>>, fn(&mut Box<B>) -> &mut B>>
|
||||||
{
|
{
|
||||||
let typeid = TypeId::of::<T>();
|
match self.map.get_mut(typeid) {
|
||||||
|
None => None,
|
||||||
|
Some(h) => Some(h.values_mut().map(|x| x.as_mut())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all_typeids(&self) -> Keys<'_, TypeId, HashMap<&'static str, Box<B>>> {
|
||||||
|
self.map.keys()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, val: Box<B>, name: &'static str) {
|
||||||
|
let typeid = val.type_id();
|
||||||
if !self.map.contains_key(&typeid) {
|
if !self.map.contains_key(&typeid) {
|
||||||
self.map.insert(typeid, HashMap::default());
|
self.map.insert(typeid, HashMap::default());
|
||||||
}
|
}
|
||||||
self.map
|
self.map.get_mut(&typeid).unwrap().insert(name, val);
|
||||||
.get_mut(&typeid)
|
|
||||||
.unwrap()
|
|
||||||
.insert(name, Box::new(t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
extern crate num;
|
extern crate num;
|
||||||
|
|
||||||
use alloc::rc::Rc;
|
|
||||||
use core::cell::RefCell;
|
|
||||||
use core::slice::from_raw_parts_mut;
|
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
|
use core::slice::from_raw_parts_mut;
|
||||||
use num::Integer;
|
use num::Integer;
|
||||||
|
|
||||||
|
use crate::metamap::AsAny;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
/// Observers observe different information about the target.
|
/// Observers observe different information about the target.
|
||||||
/// They can then be used by various sorts of feedback.
|
/// They can then be used by various sorts of feedback.
|
||||||
pub trait Observer: Any {
|
pub trait Observer: Any + AsAny {
|
||||||
fn flush(&mut self) -> Result<(), AflError> {
|
fn flush(&mut self) -> Result<(), AflError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -20,6 +19,8 @@ pub trait Observer: Any {
|
|||||||
fn post_exec(&mut self) -> Result<(), AflError> {
|
fn post_exec(&mut self) -> Result<(), AflError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
|
/// A MapObserver observes the static map, as oftentimes used for afl-like coverage information
|
||||||
@ -52,24 +53,41 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StdMapObserver<'a, T>
|
pub struct StdMapObserver<T>
|
||||||
where
|
where
|
||||||
T: Integer + Copy,
|
T: Integer + Copy + 'static,
|
||||||
{
|
{
|
||||||
map: &'a mut [T],
|
map: &'static mut [T],
|
||||||
initial: T,
|
initial: T,
|
||||||
|
name: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Observer for StdMapObserver<'a, T>
|
impl<T> Observer for StdMapObserver<T>
|
||||||
where
|
where
|
||||||
T: Integer + Copy,
|
T: Integer + Copy,
|
||||||
{
|
{
|
||||||
fn reset(&mut self) -> Result<(), AflError> {
|
fn reset(&mut self) -> Result<(), AflError> {
|
||||||
self.reset_map()
|
self.reset_map()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
self.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> MapObserver<T> for StdMapObserver<'a, T>
|
impl<T> AsAny for StdMapObserver<T>
|
||||||
|
where
|
||||||
|
T: Integer + Copy,
|
||||||
|
{
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
fn as_any_mut(&mut self) -> &mut dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MapObserver<T> for StdMapObserver<T>
|
||||||
where
|
where
|
||||||
T: Integer + Copy,
|
T: Integer + Copy,
|
||||||
{
|
{
|
||||||
@ -94,36 +112,29 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> StdMapObserver<'a, T>
|
impl<T> StdMapObserver<T>
|
||||||
where
|
where
|
||||||
T: Integer + Copy,
|
T: Integer + Copy,
|
||||||
{
|
{
|
||||||
/// Creates a new MapObserver
|
/// Creates a new MapObserver
|
||||||
pub fn new(map: &'a mut [T]) -> Self {
|
pub fn new(name: &'static str, map: &'static mut [T]) -> Self {
|
||||||
let initial = if map.len() > 0 { map[0] } else { T::zero() };
|
let initial = if map.len() > 0 { map[0] } else { T::zero() };
|
||||||
Self {
|
Self {
|
||||||
map: map,
|
map: map,
|
||||||
initial: initial,
|
initial: initial,
|
||||||
|
name: name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new MapObserver from a raw pointer
|
/// Creates a new MapObserver from a raw pointer
|
||||||
pub fn new_from_ptr(map_ptr: *mut T, len: usize) -> Self {
|
pub fn new_from_ptr(name: &'static str, map_ptr: *mut T, len: usize) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let initial = if len > 0 { *map_ptr } else { T::zero() };
|
let initial = if len > 0 { *map_ptr } else { T::zero() };
|
||||||
StdMapObserver {
|
StdMapObserver {
|
||||||
map: from_raw_parts_mut(map_ptr, len),
|
map: from_raw_parts_mut(map_ptr, len),
|
||||||
initial: initial,
|
initial: initial,
|
||||||
|
name: name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Into<Rc<RefCell<Self>>> for StdMapObserver<'a, T>
|
|
||||||
where
|
|
||||||
T: Integer + Copy,
|
|
||||||
{
|
|
||||||
fn into(self) -> Rc<RefCell<Self>> {
|
|
||||||
Rc::new(RefCell::new(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user