qemu-rust
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 22/26] rust: qom: add casting functionality


From: Zhao Liu
Subject: Re: [PATCH 22/26] rust: qom: add casting functionality
Date: Mon, 16 Dec 2024 20:53:36 +0800

> +/// 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.liu@intel.com>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]