mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-28 21:03:54 -06:00
rust: qom: allow initializing interface vtables
Unlike regular classes, interface vtables can only be obtained via object_class_dynamic_cast. Provide a wrapper that allows accessing the vtable and pass it to a ClassInitImpl implementation, for example ClassInitImpl<ResettableClass>. Reviewed-by: Zhao Liu <zhao1.liu@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
201ef001dd
commit
688c674158
2 changed files with 44 additions and 2 deletions
|
@ -66,8 +66,8 @@ pub use bindings::{Object, ObjectClass};
|
|||
|
||||
use crate::{
|
||||
bindings::{
|
||||
self, object_dynamic_cast, object_get_class, object_get_typename, object_new, object_ref,
|
||||
object_unref, TypeInfo,
|
||||
self, object_class_dynamic_cast, object_dynamic_cast, object_get_class,
|
||||
object_get_typename, object_new, object_ref, object_unref, TypeInfo,
|
||||
},
|
||||
cell::bql_locked,
|
||||
};
|
||||
|
@ -263,6 +263,47 @@ pub unsafe trait ObjectType: Sized {
|
|||
}
|
||||
}
|
||||
|
||||
/// Trait exposed by all structs corresponding to QOM interfaces.
|
||||
/// Unlike `ObjectType`, it is implemented on the class type (which provides
|
||||
/// the vtable for the interfaces).
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `TYPE` must match the contents of the `TypeInfo` as found in the C code;
|
||||
/// right now, interfaces can only be declared in C.
|
||||
pub unsafe trait InterfaceType: Sized {
|
||||
/// The name of the type, which can be passed to
|
||||
/// `object_class_dynamic_cast()` to obtain the pointer to the vtable
|
||||
/// for this interface.
|
||||
const TYPE_NAME: &'static CStr;
|
||||
|
||||
/// Initialize the vtable for the interface; the generic argument `T` is the
|
||||
/// type being initialized, while the generic argument `U` is the type that
|
||||
/// lists the interface in its `TypeInfo`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panic if the incoming argument if `T` does not implement the interface.
|
||||
fn interface_init<
|
||||
T: ObjectType + ClassInitImpl<Self> + ClassInitImpl<U::Class>,
|
||||
U: ObjectType,
|
||||
>(
|
||||
klass: &mut U::Class,
|
||||
) {
|
||||
unsafe {
|
||||
// SAFETY: upcasting to ObjectClass is always valid, and the
|
||||
// return type is either NULL or the argument itself
|
||||
let result: *mut Self = object_class_dynamic_cast(
|
||||
(klass as *mut U::Class).cast(),
|
||||
Self::TYPE_NAME.as_ptr(),
|
||||
)
|
||||
.cast();
|
||||
|
||||
<T as ClassInitImpl<Self>>::class_init(result.as_mut().unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This trait provides safe casting operations for QOM objects to raw pointers,
|
||||
/// to be used for example for FFI. The trait can be applied to any kind of
|
||||
/// reference or smart pointers, and enforces correctness through the [`IsA`]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue