diff --git a/src/guest_memory.rs b/src/guest_memory.rs
index 6bbd02f..72e7b5d 100644
@@ -41,6 +41,7 @@
//! via pointers, references, or slices returned by methods of `GuestMemory`,`GuestMemoryRegion`,
//! `VolatileSlice`, `VolatileRef`, or `VolatileArrayRef`.
+use std::any::Any;
use std::convert::From;
use std::fmt::{self, Display};
use std::fs::File;
@@ -400,33 +401,52 @@ pub trait GuestAddressSpace {
/// to access memory through this address space. The object provides
/// a consistent snapshot of the memory map.
fn memory(&self) -> Self::T;
+
+ /// Cast `self` to a dynamic trait object of `std::any::Any`.
+ fn as_any(&self) -> &dyn Any
+ where Self: Sized + 'static
+ {
+ self
+ }
}
-impl<M: GuestMemory> GuestAddressSpace for &M {
+impl<M: GuestMemory + 'static> GuestAddressSpace for &M {
type M = M;
type T = Self;
fn memory(&self) -> Self {
self
}
+
+ fn as_any(&self) -> &dyn Any {
+ *self
+ }
}
-impl<M: GuestMemory> GuestAddressSpace for Rc<M> {
+impl<M: GuestMemory + 'static> GuestAddressSpace for Rc<M> {
type M = M;
type T = Self;
fn memory(&self) -> Self {
self.clone()
}
+
+ fn as_any(&self) -> &dyn Any {
+ self
+ }
}
-impl<M: GuestMemory> GuestAddressSpace for Arc<M> {
+impl<M: GuestMemory + 'static> GuestAddressSpace for Arc<M> {
type M = M;
type T = Self;
fn memory(&self) -> Self {
self.clone()
}
+
+ fn as_any(&self) -> &dyn Any {
+ self
+ }
}
/// Lifetime generic associated iterators. The actual iterator type is defined through associated
@@ -1256,4 +1276,14 @@ mod tests {
let r = mem.find_region(addr).unwrap();
assert_eq!(r.is_hugetlbfs(), None);
}
+
+ #[cfg(feature = "backend-mmap")]
+ #[test]
+ fn test_as_any() {
+ let addr = GuestAddress(0x1000);
+ let mem = &GuestMemoryMmap::from_ranges(&[(addr, 0x1000)]).unwrap();
+
+ assert!(mem.as_any().downcast_ref::<GuestMemoryMmap>().is_some());
+ assert!(mem.as_any().downcast_ref::<String>().is_none());
+ }
}