mirror of
https://github.com/qemu/qemu.git
synced 2026-02-04 02:24:51 +00:00
rust: move class_init to an extension trait
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 <pbonzini@redhat.com>
This commit is contained in:
@@ -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::ResettablePhasesImpl;
|
||||
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;
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ use migration::{impl_vmstate_c_struct, VMStateDescription};
|
||||
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 @@ unsafe extern "C" fn rust_realize_fn<T: 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>);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ use util::{Error, Result};
|
||||
use crate::{
|
||||
bindings,
|
||||
irq::{IRQState, InterruptSource},
|
||||
qdev::{DeviceImpl, DeviceState},
|
||||
qdev::{DeviceClassExt, DeviceImpl, DeviceState},
|
||||
};
|
||||
|
||||
/// A safe wrapper around [`bindings::SysBusDevice`].
|
||||
@@ -37,10 +37,14 @@ qom_isa!(SysBusDevice: DeviceState, Object);
|
||||
// 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>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ pub use crate::qom::InterfaceType;
|
||||
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;
|
||||
|
||||
@@ -729,10 +729,14 @@ unsafe extern "C" fn rust_unparent_fn<T: ObjectImpl>(dev: *mut bindings::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>);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user