Prepare for having ObjectClass, DeviceClass and SysbusDeviceClass defined outside the hwcore and qom crates. It then becomes impossible to add a method to them.
Extracted from a patch by Marc-André Lureau. Signed-off-by: Paolo Bonzini <[email protected]> --- rust/hw/core/src/prelude.rs | 3 +++ rust/hw/core/src/qdev.rs | 25 +++++++++++++++---------- rust/hw/core/src/sysbus.rs | 10 +++++++--- rust/qom/src/prelude.rs | 1 + rust/qom/src/qom.rs | 8 ++++++-- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/rust/hw/core/src/prelude.rs b/rust/hw/core/src/prelude.rs index c544c317b39..13f7dfc6809 100644 --- a/rust/hw/core/src/prelude.rs +++ b/rust/hw/core/src/prelude.rs @@ -1,6 +1,8 @@ //! Essential types and traits intended for blanket imports. pub use crate::qdev::Clock; + +pub use crate::qdev::DeviceClassExt; pub use crate::qdev::DeviceState; pub use crate::qdev::DeviceImpl; pub use crate::qdev::DeviceMethods; @@ -8,6 +10,7 @@ pub use crate::qdev::ResetType; pub use crate::sysbus::SysBusDevice; +pub use crate::sysbus::SysBusDeviceClassExt; pub use crate::sysbus::SysBusDeviceImpl; pub use crate::sysbus::SysBusDeviceMethods; diff --git a/rust/hw/core/src/qdev.rs b/rust/hw/core/src/qdev.rs index 87232becbad..f6037fbdcae 100644 --- a/rust/hw/core/src/qdev.rs +++ b/rust/hw/core/src/qdev.rs @@ -15,9 +15,9 @@ use qom::{prelude::*, ObjectClass}; use util::{Error, Result}; -pub use crate::bindings::{ClockEvent, DeviceClass, Property, ResetType}; +pub use crate::bindings::{ClockEvent, ResetType}; use crate::{ - bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, ResettableClass}, + bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, DeviceClass, Property}, irq::InterruptSource, }; @@ -206,6 +206,9 @@ pub trait DeviceImpl: } } +#[repr(transparent)] +pub struct ResettableClass(bindings::ResettableClass); + unsafe impl InterfaceType for ResettableClass { const TYPE_NAME: &'static CStr = unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_RESETTABLE_INTERFACE) }; @@ -214,23 +217,25 @@ unsafe impl InterfaceType for ResettableClass { impl ResettableClass { /// Fill in the virtual methods of `ResettableClass` based on the /// definitions in the `ResettablePhasesImpl` trait. - pub fn class_init<T: ResettablePhasesImpl>(&mut self) { + fn class_init<T: ResettablePhasesImpl>(&mut self) { if <T as ResettablePhasesImpl>::ENTER.is_some() { - self.phases.enter = Some(rust_resettable_enter_fn::<T>); + self.0.phases.enter = Some(rust_resettable_enter_fn::<T>); } if <T as ResettablePhasesImpl>::HOLD.is_some() { - self.phases.hold = Some(rust_resettable_hold_fn::<T>); + self.0.phases.hold = Some(rust_resettable_hold_fn::<T>); } if <T as ResettablePhasesImpl>::EXIT.is_some() { - self.phases.exit = Some(rust_resettable_exit_fn::<T>); + self.0.phases.exit = Some(rust_resettable_exit_fn::<T>); } } } -impl DeviceClass { - /// Fill in the virtual methods of `DeviceClass` based on the definitions in - /// the `DeviceImpl` trait. - pub fn class_init<T: DeviceImpl>(&mut self) { +pub trait DeviceClassExt { + fn class_init<T: DeviceImpl>(&mut self); +} + +impl DeviceClassExt for DeviceClass { + fn class_init<T: DeviceImpl>(&mut self) { if <T as DeviceImpl>::REALIZE.is_some() { self.realize = Some(rust_realize_fn::<T>); } diff --git a/rust/hw/core/src/sysbus.rs b/rust/hw/core/src/sysbus.rs index 071fccff1e6..81fab3f1910 100644 --- a/rust/hw/core/src/sysbus.rs +++ b/rust/hw/core/src/sysbus.rs @@ -15,7 +15,7 @@ use crate::{ bindings, irq::{IRQState, InterruptSource}, - qdev::{DeviceImpl, DeviceState}, + qdev::{DeviceClassExt, DeviceImpl, DeviceState}, }; /// A safe wrapper around [`bindings::SysBusDevice`]. @@ -37,10 +37,14 @@ unsafe impl ObjectType for SysBusDevice { // TODO: add virtual methods pub trait SysBusDeviceImpl: DeviceImpl + IsA<SysBusDevice> {} -impl SysBusDeviceClass { +pub trait SysBusDeviceClassExt { + fn class_init<T: SysBusDeviceImpl>(&mut self); +} + +impl SysBusDeviceClassExt for SysBusDeviceClass { /// Fill in the virtual methods of `SysBusDeviceClass` based on the /// definitions in the `SysBusDeviceImpl` trait. - pub fn class_init<T: SysBusDeviceImpl>(self: &mut SysBusDeviceClass) { + fn class_init<T: SysBusDeviceImpl>(&mut self) { self.parent_class.class_init::<T>(); } } diff --git a/rust/qom/src/prelude.rs b/rust/qom/src/prelude.rs index 6a1ecaef2a7..1d1177f1e0d 100644 --- a/rust/qom/src/prelude.rs +++ b/rust/qom/src/prelude.rs @@ -4,6 +4,7 @@ pub use crate::qom::IsA; pub use crate::qom::Object; pub use crate::qom::ObjectCast; +pub use crate::qom::ObjectClassExt; pub use crate::qom::ObjectClassMethods; pub use crate::qom::ObjectDeref; pub use crate::qom::ObjectImpl; diff --git a/rust/qom/src/qom.rs b/rust/qom/src/qom.rs index 84455cea79b..cc00ddcfc98 100644 --- a/rust/qom/src/qom.rs +++ b/rust/qom/src/qom.rs @@ -729,10 +729,14 @@ pub trait ObjectImpl: ObjectType + IsA<Object> { T::UNPARENT.unwrap()(unsafe { state.as_ref() }); } -impl ObjectClass { +pub trait ObjectClassExt { + fn class_init<T: ObjectImpl>(&mut self); +} + +impl ObjectClassExt for ObjectClass { /// Fill in the virtual methods of `ObjectClass` based on the definitions in /// the `ObjectImpl` trait. - pub fn class_init<T: ObjectImpl>(&mut self) { + fn class_init<T: ObjectImpl>(&mut self) { if <T as ObjectImpl>::UNPARENT.is_some() { self.unparent = Some(rust_unparent_fn::<T>); } -- 2.52.0
