> +/// Macro to mark superclasses of QOM classes. This enables type-safe > +/// up- and downcasting. > +/// > +/// # Safety > +/// > +/// This macro is a thin wrapper around the [`IsA`] trait and performs > +/// no checking whatsoever of what is declared. It is the caller's > +/// responsibility to have $struct begin, directly or indirectly, with > +/// a field of type `$parent`. > +#[macro_export] > +macro_rules! qom_isa { > + ($struct:ty : $($parent:ty),* ) => {
This macro is quite good, but it requires specifying all the parents... So I am thinking if it is possible to move ParentType to ObjectType, and then try to traverse the ParentType in the macro, implementing IsA for each ParentType... However, the first difficulty has already stopped me: I cannot define ParentType for Object itself. > + $( > + // SAFETY: it is the caller responsibility to have $parent as the > + // first field > + unsafe impl $crate::qom::IsA<$parent> for $struct {} > + > + impl AsRef<$parent> for $struct { > + fn as_ref(&self) -> &$parent { > + // SAFETY: follows the same rules as for IsA<U>, which is > + // declared above. > + let ptr: *const Self = self; > + unsafe { &*ptr.cast::<$parent>() } > + } > + } > + )* > + }; > +} > > unsafe extern "C" fn rust_instance_init<T: ObjectImpl>(obj: *mut Object) { > // SAFETY: obj is an instance of T, since rust_instance_init<T> > @@ -94,8 +147,224 @@ pub unsafe trait ObjectType: Sized { > /// The name of the type, which can be passed to `object_new()` to > /// generate an instance of this type. > const TYPE_NAME: &'static CStr; > + > + /// Return the receiver as an Object. This is always safe, even > + /// if this type represents an interface. This comment is a bit confusing to me... EMM, why mention the interface? I understand if something implements ObjectType, then it should be an Object, so deref/cast here would be valid. And if it is an interface, it would need to implement the corresponding trait. ... This cast idea is nice! In the future, class might also need to implement similar cast support (e.g., class_init in virtio). Reviewed-by: Zhao Liu <zhao1....@intel.com>