diff options
-rw-r--r-- | rust/qemu-api/src/memory.rs | 5 | ||||
-rw-r--r-- | rust/qemu-api/src/prelude.rs | 1 | ||||
-rw-r--r-- | rust/qemu-api/src/qom.rs | 83 | ||||
-rw-r--r-- | rust/qemu-api/tests/tests.rs | 34 |
4 files changed, 2 insertions, 121 deletions
diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs index eff9f09..fdb1ea1 100644 --- a/rust/qemu-api/src/memory.rs +++ b/rust/qemu-api/src/memory.rs @@ -175,11 +175,6 @@ impl MemoryRegion { ) { unsafe { Self::do_init_io( - // self.0.as_mut_ptr() needed because Rust tries to call - // ObjectDeref::as_mut_ptr() on "&mut Self", instead of coercing - // to "&Self" and then calling MemoryRegion::as_mut_ptr(). - // Revisit if/when ObjectCastMut is not needed anymore; it is - // only used in a couple places for initialization. self.0.as_mut_ptr(), owner.cast::<Object>(), &ops.0, diff --git a/rust/qemu-api/src/prelude.rs b/rust/qemu-api/src/prelude.rs index 634acf3..43bfcd5 100644 --- a/rust/qemu-api/src/prelude.rs +++ b/rust/qemu-api/src/prelude.rs @@ -17,7 +17,6 @@ pub use crate::qom::InterfaceType; pub use crate::qom::IsA; pub use crate::qom::Object; pub use crate::qom::ObjectCast; -pub use crate::qom::ObjectCastMut; pub use crate::qom::ObjectDeref; pub use crate::qom::ObjectClassMethods; pub use crate::qom::ObjectMethods; diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 2defbd2..34d7bc0 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -463,90 +463,7 @@ where impl<T: ObjectType> ObjectDeref for &T {} impl<T: ObjectType> ObjectCast for &T {} -/// Trait for mutable type casting operations in the QOM hierarchy. -/// -/// This trait provides the mutable counterparts to [`ObjectCast`]'s conversion -/// functions. Unlike `ObjectCast`, this trait returns `Result` for fallible -/// conversions to preserve the original smart pointer if the cast fails. This -/// is necessary because mutable references cannot be copied, so a failed cast -/// must return ownership of the original reference. For example: -/// -/// ```ignore -/// let mut dev = get_device(); -/// // If this fails, we need the original `dev` back to try something else -/// match dev.dynamic_cast_mut::<FooDevice>() { -/// Ok(foodev) => /* use foodev */, -/// Err(dev) => /* still have ownership of dev */ -/// } -/// ``` -pub trait ObjectCastMut: Sized + ObjectDeref + DerefMut -where - Self::Target: ObjectType, -{ - /// Safely convert from a derived type to one of its parent types. - /// - /// This is always safe; the [`IsA`] trait provides static verification - /// that `Self` dereferences to `U` or a child of `U`. - fn upcast_mut<'a, U: ObjectType>(self) -> &'a mut U - where - Self::Target: IsA<U>, - Self: 'a, - { - // SAFETY: soundness is declared via IsA<U>, which is an unsafe trait - unsafe { self.unsafe_cast_mut::<U>() } - } - - /// Attempt to convert to a derived type. - /// - /// Returns `Ok(..)` if the object is of type `U`, or `Err(self)` if the - /// object if the conversion failed. This is verified at runtime by - /// checking the object's type information. - fn downcast_mut<'a, U: IsA<Self::Target>>(self) -> Result<&'a mut U, Self> - where - Self: 'a, - { - self.dynamic_cast_mut::<U>() - } - - /// Attempt to convert between any two types in the QOM hierarchy. - /// - /// Returns `Ok(..)` if the object is of type `U`, or `Err(self)` if the - /// object if the conversion failed. This is verified at runtime by - /// checking the object's type information. - fn dynamic_cast_mut<'a, U: ObjectType>(self) -> Result<&'a mut U, Self> - where - Self: 'a, - { - unsafe { - // SAFETY: upcasting to Object is always valid, and the - // return type is either NULL or the argument itself - let result: *mut U = - object_dynamic_cast(self.as_object_mut_ptr(), U::TYPE_NAME.as_ptr()).cast(); - - result.as_mut().ok_or(self) - } - } - - /// Convert to any QOM type without verification. - /// - /// # Safety - /// - /// What safety? You need to know yourself that the cast is correct; only - /// use when performance is paramount. It is still better than a raw - /// pointer `cast()`, which does not even check that you remain in the - /// realm of QOM `ObjectType`s. - /// - /// `unsafe_cast::<Object>()` is always safe. - unsafe fn unsafe_cast_mut<'a, U: ObjectType>(self) -> &'a mut U - where - Self: 'a, - { - unsafe { &mut *self.as_mut_ptr::<Self::Target>().cast::<U>() } - } -} - impl<T: ObjectType> ObjectDeref for &mut T {} -impl<T: ObjectType> ObjectCastMut for &mut T {} /// Trait a type must implement to be registered with QEMU. pub trait ObjectImpl: ObjectType + IsA<Object> { diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs index e398578..269122e 100644 --- a/rust/qemu-api/tests/tests.rs +++ b/rust/qemu-api/tests/tests.rs @@ -2,13 +2,10 @@ // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> // SPDX-License-Identifier: GPL-2.0-or-later -use std::{ - ffi::{c_void, CStr}, - ptr::{addr_of, addr_of_mut}, -}; +use std::{ffi::CStr, ptr::addr_of}; use qemu_api::{ - bindings::{module_call_init, module_init_type, object_new, object_unref, qdev_prop_bool}, + bindings::{module_call_init, module_init_type, qdev_prop_bool}, c_str, cell::{self, BqlCell}, declare_properties, define_property, @@ -182,30 +179,3 @@ fn test_cast() { assert_eq!(addr_of!(*sbd_ref), p_ptr.cast()); } } - -#[test] -#[allow(clippy::shadow_unrelated)] -/// Test casts on mutable references. -fn test_cast_mut() { - init_qom(); - let p: *mut DummyState = unsafe { object_new(DummyState::TYPE_NAME.as_ptr()).cast() }; - - let p_ref: &mut DummyState = unsafe { &mut *p }; - let obj_ref: &mut Object = p_ref.upcast_mut(); - assert_eq!(addr_of_mut!(*obj_ref), p.cast()); - - let sbd_ref: Result<&mut SysBusDevice, &mut Object> = obj_ref.dynamic_cast_mut(); - let obj_ref = sbd_ref.unwrap_err(); - - let dev_ref: Result<&mut DeviceState, &mut Object> = obj_ref.downcast_mut(); - let dev_ref = dev_ref.unwrap(); - assert_eq!(addr_of_mut!(*dev_ref), p.cast()); - - // SAFETY: the cast is wrong, but the value is only used for comparison - unsafe { - let sbd_ref: &mut SysBusDevice = obj_ref.unsafe_cast_mut(); - assert_eq!(addr_of_mut!(*sbd_ref), p.cast()); - - object_unref(p_ref.as_object_mut_ptr().cast::<c_void>()); - } -} |