mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-22 01:21:53 -06:00
rust: qom: add ObjectImpl::CLASS_INIT
As shown in the PL011 device, the orphan rules required a manual implementation of ClassInitImpl for anything not in the qemu_api crate; this gets in the way of moving system emulation-specific code (including DeviceClass, which as a blanket ClassInitImpl<DeviceClass> implementation) into its own crate. Make ClassInitImpl optional, at the cost of having to specify the CLASS_INIT member by hand in every implementation of ObjectImpl. The next commits will get rid of it, replacing all the "impl<T> ClassInitImpl<Class> for T" blocks with a generic class_init<T> method on Class. Right now the definition is always the same, but do not provide a default as that will not be true once ClassInitImpl goes away. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
3212da0033
commit
4551f342fe
4 changed files with 19 additions and 4 deletions
|
@ -160,6 +160,7 @@ impl ObjectImpl for PL011State {
|
||||||
|
|
||||||
const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = Some(Self::init);
|
const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = Some(Self::init);
|
||||||
const INSTANCE_POST_INIT: Option<fn(&Self)> = Some(Self::post_init);
|
const INSTANCE_POST_INIT: Option<fn(&Self)> = Some(Self::post_init);
|
||||||
|
const CLASS_INIT: fn(&mut Self::Class) = <Self as ClassInitImpl<Self::Class>>::class_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceImpl for PL011State {
|
impl DeviceImpl for PL011State {
|
||||||
|
@ -744,6 +745,8 @@ unsafe impl ObjectType for PL011Luminary {
|
||||||
|
|
||||||
impl ObjectImpl for PL011Luminary {
|
impl ObjectImpl for PL011Luminary {
|
||||||
type ParentType = PL011State;
|
type ParentType = PL011State;
|
||||||
|
|
||||||
|
const CLASS_INIT: fn(&mut Self::Class) = <Self as ClassInitImpl<Self::Class>>::class_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceImpl for PL011Luminary {}
|
impl DeviceImpl for PL011Luminary {}
|
||||||
|
|
|
@ -21,7 +21,7 @@ use qemu_api::{
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
qdev::{DeviceImpl, DeviceMethods, DeviceState, Property, ResetType, ResettablePhasesImpl},
|
qdev::{DeviceImpl, DeviceMethods, DeviceState, Property, ResetType, ResettablePhasesImpl},
|
||||||
qom::{ObjectImpl, ObjectType, ParentField},
|
qom::{ClassInitImpl, ObjectImpl, ObjectType, ParentField},
|
||||||
qom_isa,
|
qom_isa,
|
||||||
sysbus::{SysBusDevice, SysBusDeviceImpl},
|
sysbus::{SysBusDevice, SysBusDeviceImpl},
|
||||||
timer::{Timer, CLOCK_VIRTUAL},
|
timer::{Timer, CLOCK_VIRTUAL},
|
||||||
|
@ -836,6 +836,7 @@ impl ObjectImpl for HPETState {
|
||||||
|
|
||||||
const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = Some(Self::init);
|
const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = Some(Self::init);
|
||||||
const INSTANCE_POST_INIT: Option<fn(&Self)> = Some(Self::post_init);
|
const INSTANCE_POST_INIT: Option<fn(&Self)> = Some(Self::post_init);
|
||||||
|
const CLASS_INIT: fn(&mut Self::Class) = <Self as ClassInitImpl<Self::Class>>::class_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make these properties user-configurable!
|
// TODO: Make these properties user-configurable!
|
||||||
|
|
|
@ -180,7 +180,7 @@ unsafe extern "C" fn rust_instance_post_init<T: ObjectImpl>(obj: *mut Object) {
|
||||||
T::INSTANCE_POST_INIT.unwrap()(unsafe { state.as_ref() });
|
T::INSTANCE_POST_INIT.unwrap()(unsafe { state.as_ref() });
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn rust_class_init<T: ObjectType + ClassInitImpl<T::Class>>(
|
unsafe extern "C" fn rust_class_init<T: ObjectType + ObjectImpl>(
|
||||||
klass: *mut ObjectClass,
|
klass: *mut ObjectClass,
|
||||||
_data: *mut c_void,
|
_data: *mut c_void,
|
||||||
) {
|
) {
|
||||||
|
@ -190,7 +190,7 @@ unsafe extern "C" fn rust_class_init<T: ObjectType + ClassInitImpl<T::Class>>(
|
||||||
// SAFETY: klass is a T::Class, since rust_class_init<T>
|
// SAFETY: klass is a T::Class, since rust_class_init<T>
|
||||||
// is called from QOM core as the class_init function
|
// is called from QOM core as the class_init function
|
||||||
// for class T
|
// for class T
|
||||||
T::class_init(unsafe { klass.as_mut() })
|
<T as ObjectImpl>::CLASS_INIT(unsafe { klass.as_mut() })
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn drop_object<T: ObjectImpl>(obj: *mut Object) {
|
unsafe extern "C" fn drop_object<T: ObjectImpl>(obj: *mut Object) {
|
||||||
|
@ -499,7 +499,7 @@ impl<T: ObjectType> ObjectDeref for &mut T {}
|
||||||
impl<T: ObjectType> ObjectCastMut for &mut T {}
|
impl<T: ObjectType> ObjectCastMut for &mut T {}
|
||||||
|
|
||||||
/// Trait a type must implement to be registered with QEMU.
|
/// Trait a type must implement to be registered with QEMU.
|
||||||
pub trait ObjectImpl: ObjectType + ClassInitImpl<Self::Class> + IsA<Object> {
|
pub trait ObjectImpl: ObjectType + IsA<Object> {
|
||||||
/// The parent of the type. This should match the first field of the
|
/// The parent of the type. This should match the first field of the
|
||||||
/// struct that implements `ObjectImpl`, minus the `ParentField<_>` wrapper.
|
/// struct that implements `ObjectImpl`, minus the `ParentField<_>` wrapper.
|
||||||
type ParentType: ObjectType;
|
type ParentType: ObjectType;
|
||||||
|
@ -552,6 +552,14 @@ pub trait ObjectImpl: ObjectType + ClassInitImpl<Self::Class> + IsA<Object> {
|
||||||
|
|
||||||
// methods on ObjectClass
|
// methods on ObjectClass
|
||||||
const UNPARENT: Option<fn(&Self)> = None;
|
const UNPARENT: Option<fn(&Self)> = None;
|
||||||
|
|
||||||
|
/// Store into the argument the virtual method implementations
|
||||||
|
/// for `Self`. On entry, the virtual method pointers are set to
|
||||||
|
/// the default values coming from the parent classes; the function
|
||||||
|
/// can change them to override virtual methods of a parent class.
|
||||||
|
///
|
||||||
|
/// Usually defined as `<Self as ClassInitImpl<Self::Class>::class_init`.
|
||||||
|
const CLASS_INIT: fn(&mut Self::Class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal trait used to automatically fill in a class struct.
|
/// Internal trait used to automatically fill in a class struct.
|
||||||
|
|
|
@ -60,6 +60,7 @@ unsafe impl ObjectType for DummyState {
|
||||||
impl ObjectImpl for DummyState {
|
impl ObjectImpl for DummyState {
|
||||||
type ParentType = DeviceState;
|
type ParentType = DeviceState;
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
|
const CLASS_INIT: fn(&mut DummyClass) = <Self as ClassInitImpl<DummyClass>>::class_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResettablePhasesImpl for DummyState {}
|
impl ResettablePhasesImpl for DummyState {}
|
||||||
|
@ -102,6 +103,8 @@ unsafe impl ObjectType for DummyChildState {
|
||||||
impl ObjectImpl for DummyChildState {
|
impl ObjectImpl for DummyChildState {
|
||||||
type ParentType = DummyState;
|
type ParentType = DummyState;
|
||||||
const ABSTRACT: bool = false;
|
const ABSTRACT: bool = false;
|
||||||
|
const CLASS_INIT: fn(&mut DummyChildClass) =
|
||||||
|
<Self as ClassInitImpl<DummyChildClass>>::class_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResettablePhasesImpl for DummyChildState {}
|
impl ResettablePhasesImpl for DummyChildState {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue