[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>
- Re: [PATCH 26/26] rust: callbacks: allow passing optional callbacks as (), (continued)
[PATCH 18/26] rust: qom: add possibility of overriding unparent, Paolo Bonzini, 2024/12/09
[PATCH 25/26] rust: qemu-api: add a module to wrap functions and zero-sized closures, Paolo Bonzini, 2024/12/09
[PATCH 22/26] rust: qom: add casting functionality, Paolo Bonzini, 2024/12/09
- Re: [PATCH 22/26] rust: qom: add casting functionality,
Zhao Liu <=
[PATCH 17/26] rust: qom: put class_init together from multiple ClassInitImpl<>, Paolo Bonzini, 2024/12/09
[PATCH 20/26] rust: re-export C types from qemu-api submodules, Paolo Bonzini, 2024/12/09
Re: [PATCH 00/26] rust: bundle of prerequisites for HPET implementation, Philippe Mathieu-Daudé, 2024/12/09