1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
|
// Copyright 2024, Linaro Limited
// Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
// SPDX-License-Identifier: GPL-2.0-or-later
//! Bindings to access QOM functionality from Rust.
//!
//! The QEMU Object Model (QOM) provides inheritance and dynamic typing for QEMU
//! devices. This module makes QOM's features available in Rust through three
//! main mechanisms:
//!
//! * Automatic creation and registration of `TypeInfo` for classes that are
//! written in Rust, as well as mapping between Rust traits and QOM vtables.
//!
//! * Type-safe casting between parent and child classes, through the [`IsA`]
//! trait and methods such as [`upcast`](ObjectCast::upcast) and
//! [`downcast`](ObjectCast::downcast).
//!
//! * Automatic delegation of parent class methods to child classes. When a
//! trait uses [`IsA`] as a bound, its contents become available to all child
//! classes through blanket implementations. This works both for class methods
//! and for instance methods accessed through references or smart pointers.
//!
//! # Structure of a class
//!
//! A leaf class only needs a struct holding instance state. The struct must
//! implement the [`ObjectType`] and [`IsA`] traits, as well as any `*Impl`
//! traits that exist for its superclasses.
//!
//! If a class has subclasses, it will also provide a struct for instance data,
//! with the same characteristics as for concrete classes, but it also needs
//! additional components to support virtual methods:
//!
//! * a struct for class data, for example `DeviceClass`. This corresponds to
//! the C "class struct" and holds the vtable that is used by instances of the
//! class and its subclasses. It must start with its parent's class struct.
//!
//! * a trait for virtual method implementations, for example `DeviceImpl`.
//! Child classes implement this trait to provide their own behavior for
//! virtual methods. The trait's methods take `&self` to access instance data.
//!
//! * an implementation of [`ClassInitImpl`], for example
//! `ClassInitImpl<DeviceClass>`. This fills the vtable in the class struct;
//! the source for this is the `*Impl` trait; the associated consts and
//! functions if needed are wrapped to map C types into Rust types.
//!
//! * a trait for instance methods, for example `DeviceMethods`. This trait is
//! automatically implemented for any reference or smart pointer to a device
//! instance. It calls into the vtable provides access across all subclasses
//! to methods defined for the class.
//!
//! * optionally, a trait for class methods, for example `DeviceClassMethods`.
//! This provides access to class-wide functionality that doesn't depend on
//! instance data. Like instance methods, these are automatically inherited by
//! child classes.
use std::{
ffi::CStr,
fmt,
mem::ManuallyDrop,
ops::{Deref, DerefMut},
os::raw::c_void,
ptr::NonNull,
};
pub use bindings::{Object, ObjectClass};
use crate::{
bindings::{
self, object_dynamic_cast, object_get_class, object_get_typename, object_ref, object_unref,
TypeInfo,
},
cell::bql_locked,
};
/// Marker trait: `Self` can be statically upcasted to `P` (i.e. `P` is a direct
/// or indirect parent of `Self`).
///
/// # Safety
///
/// The struct `Self` must be `#[repr(C)]` and must begin, directly or
/// indirectly, with a field of type `P`. This ensures that invalid casts,
/// which rely on `IsA<>` for static checking, are rejected at compile time.
pub unsafe trait IsA<P: ObjectType>: ObjectType {}
// SAFETY: it is always safe to cast to your own type
unsafe impl<T: ObjectType> IsA<T> for T {}
/// 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),* ) => {
$(
// 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>() }
}
}
)*
};
}
/// This is the same as [`ManuallyDrop<T>`](std::mem::ManuallyDrop), though
/// it hides the standard methods of `ManuallyDrop`.
///
/// The first field of an `ObjectType` must be of type `ParentField<T>`.
/// (Technically, this is only necessary if there is at least one Rust
/// superclass in the hierarchy). This is to ensure that the parent field is
/// dropped after the subclass; this drop order is enforced by the C
/// `object_deinit` function.
///
/// # Examples
///
/// ```ignore
/// #[repr(C)]
/// #[derive(qemu_api_macros::Object)]
/// pub struct MyDevice {
/// parent: ParentField<DeviceState>,
/// ...
/// }
/// ```
#[derive(Debug)]
#[repr(transparent)]
pub struct ParentField<T: ObjectType>(std::mem::ManuallyDrop<T>);
impl<T: ObjectType> Deref for ParentField<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: ObjectType> DerefMut for ParentField<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: fmt::Display + ObjectType> fmt::Display for ParentField<T> {
#[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.0.fmt(f)
}
}
unsafe extern "C" fn rust_instance_init<T: ObjectImpl>(obj: *mut Object) {
let mut state = NonNull::new(obj).unwrap().cast::<T>();
// SAFETY: obj is an instance of T, since rust_instance_init<T>
// is called from QOM core as the instance_init function
// for class T
unsafe {
T::INSTANCE_INIT.unwrap()(state.as_mut());
}
}
unsafe extern "C" fn rust_instance_post_init<T: ObjectImpl>(obj: *mut Object) {
let state = NonNull::new(obj).unwrap().cast::<T>();
// SAFETY: obj is an instance of T, since rust_instance_post_init<T>
// is called from QOM core as the instance_post_init function
// for class T
T::INSTANCE_POST_INIT.unwrap()(unsafe { state.as_ref() });
}
unsafe extern "C" fn rust_class_init<T: ObjectType + ClassInitImpl<T::Class>>(
klass: *mut ObjectClass,
_data: *mut c_void,
) {
let mut klass = NonNull::new(klass)
.unwrap()
.cast::<<T as ObjectType>::Class>();
// SAFETY: klass is a T::Class, since rust_class_init<T>
// is called from QOM core as the class_init function
// for class T
T::class_init(unsafe { klass.as_mut() })
}
unsafe extern "C" fn drop_object<T: ObjectImpl>(obj: *mut Object) {
// SAFETY: obj is an instance of T, since drop_object<T> is called
// from the QOM core function object_deinit() as the instance_finalize
// function for class T. Note that while object_deinit() will drop the
// superclass field separately after this function returns, `T` must
// implement the unsafe trait ObjectType; the safety rules for the
// trait mandate that the parent field is manually dropped.
unsafe { std::ptr::drop_in_place(obj.cast::<T>()) }
}
/// Trait exposed by all structs corresponding to QOM objects.
///
/// # Safety
///
/// For classes declared in C:
///
/// - `Class` and `TYPE` must match the data in the `TypeInfo`;
///
/// - the first field of the struct must be of the instance type corresponding
/// to the superclass, as declared in the `TypeInfo`
///
/// - likewise, the first field of the `Class` struct must be of the class type
/// corresponding to the superclass
///
/// For classes declared in Rust and implementing [`ObjectImpl`]:
///
/// - the struct must be `#[repr(C)]`;
///
/// - the first field of the struct must be of type
/// [`ParentField<T>`](ParentField), where `T` is the parent type
/// [`ObjectImpl::ParentType`]
///
/// - the first field of the `Class` must be of the class struct corresponding
/// to the superclass, which is `ObjectImpl::ParentType::Class`. `ParentField`
/// is not needed here.
///
/// In both cases, having a separate class type is not necessary if the subclass
/// does not add any field.
pub unsafe trait ObjectType: Sized {
/// The QOM class object corresponding to this struct. This is used
/// to automatically generate a `class_init` method.
type Class;
/// 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.
fn as_object(&self) -> &Object {
unsafe { &*self.as_object_ptr() }
}
/// Return the receiver as a const raw pointer to Object.
/// This is preferrable to `as_object_mut_ptr()` if a C
/// function only needs a `const Object *`.
fn as_object_ptr(&self) -> *const Object {
self.as_ptr().cast()
}
/// Return the receiver as a mutable raw pointer to Object.
///
/// # Safety
///
/// This cast is always safe, but because the result is mutable
/// and the incoming reference is not, this should only be used
/// for calls to C functions, and only if needed.
unsafe fn as_object_mut_ptr(&self) -> *mut Object {
self.as_object_ptr() as *mut _
}
}
/// 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`]
/// trait.
pub trait ObjectDeref: Deref
where
Self::Target: ObjectType,
{
/// Convert to a const Rust pointer, to be used for example for FFI.
/// The target pointer type must be the type of `self` or a superclass
fn as_ptr<U: ObjectType>(&self) -> *const U
where
Self::Target: IsA<U>,
{
let ptr: *const Self::Target = self.deref();
ptr.cast::<U>()
}
/// Convert to a mutable Rust pointer, to be used for example for FFI.
/// The target pointer type must be the type of `self` or a superclass.
/// Used to implement interior mutability for objects.
///
/// # Safety
///
/// This method is safe because only the actual dereference of the pointer
/// has to be unsafe. Bindings to C APIs will use it a lot, but care has
/// to be taken because it overrides the const-ness of `&self`.
fn as_mut_ptr<U: ObjectType>(&self) -> *mut U
where
Self::Target: IsA<U>,
{
#[allow(clippy::as_ptr_cast_mut)]
{
self.as_ptr::<U>() as *mut _
}
}
}
/// Trait that adds extra functionality for `&T` where `T` is a QOM
/// object type. Allows conversion to/from C objects in generic code.
pub trait ObjectCast: ObjectDeref + Copy
where
Self::Target: ObjectType,
{
/// Safely convert from a derived type to one of its parent types.
///
/// This is always safe; the [`IsA`] trait provides static verification
/// trait that `Self` dereferences to `U` or a child of `U`.
fn upcast<'a, U: ObjectType>(self) -> &'a U
where
Self::Target: IsA<U>,
Self: 'a,
{
// SAFETY: soundness is declared via IsA<U>, which is an unsafe trait
unsafe { self.unsafe_cast::<U>() }
}
/// Attempt to convert to a derived type.
///
/// Returns `None` if the object is not actually of type `U`. This is
/// verified at runtime by checking the object's type information.
fn downcast<'a, U: IsA<Self::Target>>(self) -> Option<&'a U>
where
Self: 'a,
{
self.dynamic_cast::<U>()
}
/// Attempt to convert between any two types in the QOM hierarchy.
///
/// Returns `None` if the object is not actually of type `U`. This is
/// verified at runtime by checking the object's type information.
fn dynamic_cast<'a, U: ObjectType>(self) -> Option<&'a U>
where
Self: 'a,
{
unsafe {
// SAFETY: upcasting to Object is always valid, and the
// return type is either NULL or the argument itself
let result: *const U =
object_dynamic_cast(self.as_object_mut_ptr(), U::TYPE_NAME.as_ptr()).cast();
result.as_ref()
}
}
/// Convert to any QOM type without verification.
///
/// # Safety
///
/// What safety? You need to know yourself that the cast is correct; only
/// use when performance is paramount. It is still better than a raw
/// pointer `cast()`, which does not even check that you remain in the
/// realm of QOM `ObjectType`s.
///
/// `unsafe_cast::<Object>()` is always safe.
unsafe fn unsafe_cast<'a, U: ObjectType>(self) -> &'a U
where
Self: 'a,
{
unsafe { &*(self.as_ptr::<Self::Target>().cast::<U>()) }
}
}
impl<T: ObjectType> ObjectDeref for &T {}
impl<T: ObjectType> ObjectCast for &T {}
/// Trait for mutable type casting operations in the QOM hierarchy.
///
/// This trait provides the mutable counterparts to [`ObjectCast`]'s conversion
/// functions. Unlike `ObjectCast`, this trait returns `Result` for fallible
/// conversions to preserve the original smart pointer if the cast fails. This
/// is necessary because mutable references cannot be copied, so a failed cast
/// must return ownership of the original reference. For example:
///
/// ```ignore
/// let mut dev = get_device();
/// // If this fails, we need the original `dev` back to try something else
/// match dev.dynamic_cast_mut::<FooDevice>() {
/// Ok(foodev) => /* use foodev */,
/// Err(dev) => /* still have ownership of dev */
/// }
/// ```
pub trait ObjectCastMut: Sized + ObjectDeref + DerefMut
where
Self::Target: ObjectType,
{
/// Safely convert from a derived type to one of its parent types.
///
/// This is always safe; the [`IsA`] trait provides static verification
/// that `Self` dereferences to `U` or a child of `U`.
fn upcast_mut<'a, U: ObjectType>(self) -> &'a mut U
where
Self::Target: IsA<U>,
Self: 'a,
{
// SAFETY: soundness is declared via IsA<U>, which is an unsafe trait
unsafe { self.unsafe_cast_mut::<U>() }
}
/// Attempt to convert to a derived type.
///
/// Returns `Ok(..)` if the object is of type `U`, or `Err(self)` if the
/// object if the conversion failed. This is verified at runtime by
/// checking the object's type information.
fn downcast_mut<'a, U: IsA<Self::Target>>(self) -> Result<&'a mut U, Self>
where
Self: 'a,
{
self.dynamic_cast_mut::<U>()
}
/// Attempt to convert between any two types in the QOM hierarchy.
///
/// Returns `Ok(..)` if the object is of type `U`, or `Err(self)` if the
/// object if the conversion failed. This is verified at runtime by
/// checking the object's type information.
fn dynamic_cast_mut<'a, U: ObjectType>(self) -> Result<&'a mut U, Self>
where
Self: 'a,
{
unsafe {
// SAFETY: upcasting to Object is always valid, and the
// return type is either NULL or the argument itself
let result: *mut U =
object_dynamic_cast(self.as_object_mut_ptr(), U::TYPE_NAME.as_ptr()).cast();
result.as_mut().ok_or(self)
}
}
/// Convert to any QOM type without verification.
///
/// # Safety
///
/// What safety? You need to know yourself that the cast is correct; only
/// use when performance is paramount. It is still better than a raw
/// pointer `cast()`, which does not even check that you remain in the
/// realm of QOM `ObjectType`s.
///
/// `unsafe_cast::<Object>()` is always safe.
unsafe fn unsafe_cast_mut<'a, U: ObjectType>(self) -> &'a mut U
where
Self: 'a,
{
unsafe { &mut *self.as_mut_ptr::<Self::Target>().cast::<U>() }
}
}
impl<T: ObjectType> ObjectDeref for &mut T {}
impl<T: ObjectType> ObjectCastMut for &mut T {}
/// Trait a type must implement to be registered with QEMU.
pub trait ObjectImpl: ObjectType + ClassInitImpl<Self::Class> {
/// The parent of the type. This should match the first field of the
/// struct that implements `ObjectImpl`, minus the `ParentField<_>` wrapper.
type ParentType: ObjectType;
/// Whether the object can be instantiated
const ABSTRACT: bool = false;
/// Function that is called to initialize an object. The parent class will
/// have already been initialized so the type is only responsible for
/// initializing its own members.
///
/// FIXME: The argument is not really a valid reference. `&mut
/// MaybeUninit<Self>` would be a better description.
const INSTANCE_INIT: Option<unsafe fn(&mut Self)> = None;
/// Function that is called to finish initialization of an object, once
/// `INSTANCE_INIT` functions have been called.
const INSTANCE_POST_INIT: Option<fn(&Self)> = None;
/// Called on descendent classes after all parent class initialization
/// has occurred, but before the class itself is initialized. This
/// is only useful if a class is not a leaf, and can be used to undo
/// the effects of copying the contents of the parent's class struct
/// to the descendants.
const CLASS_BASE_INIT: Option<
unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void),
> = None;
const TYPE_INFO: TypeInfo = TypeInfo {
name: Self::TYPE_NAME.as_ptr(),
parent: Self::ParentType::TYPE_NAME.as_ptr(),
instance_size: core::mem::size_of::<Self>(),
instance_align: core::mem::align_of::<Self>(),
instance_init: match Self::INSTANCE_INIT {
None => None,
Some(_) => Some(rust_instance_init::<Self>),
},
instance_post_init: match Self::INSTANCE_POST_INIT {
None => None,
Some(_) => Some(rust_instance_post_init::<Self>),
},
instance_finalize: Some(drop_object::<Self>),
abstract_: Self::ABSTRACT,
class_size: core::mem::size_of::<Self::Class>(),
class_init: Some(rust_class_init::<Self>),
class_base_init: Self::CLASS_BASE_INIT,
class_data: core::ptr::null_mut(),
interfaces: core::ptr::null_mut(),
};
// methods on ObjectClass
const UNPARENT: Option<fn(&Self)> = None;
}
/// Internal trait used to automatically fill in a class struct.
///
/// Each QOM class that has virtual methods describes them in a
/// _class struct_. Class structs include a parent field corresponding
/// to the vtable of the parent class, all the way up to [`ObjectClass`].
/// Each QOM type has one such class struct; this trait takes care of
/// initializing the `T` part of the class struct, for the type that
/// implements the trait.
///
/// Each struct will implement this trait with `T` equal to each
/// superclass. For example, a device should implement at least
/// `ClassInitImpl<`[`DeviceClass`](crate::qdev::DeviceClass)`>` and
/// `ClassInitImpl<`[`ObjectClass`]`>`. Such implementations are made
/// in one of two ways.
///
/// For most superclasses, `ClassInitImpl` is provided by the `qemu-api`
/// crate itself. The Rust implementation of methods will come from a
/// trait like [`ObjectImpl`] or [`DeviceImpl`](crate::qdev::DeviceImpl),
/// and `ClassInitImpl` is provided by blanket implementations that
/// operate on all implementors of the `*Impl`* trait. For example:
///
/// ```ignore
/// impl<T> ClassInitImpl<DeviceClass> for T
/// where
/// T: ClassInitImpl<ObjectClass> + DeviceImpl,
/// ```
///
/// The bound on `ClassInitImpl<ObjectClass>` is needed so that,
/// after initializing the `DeviceClass` part of the class struct,
/// the parent [`ObjectClass`] is initialized as well.
///
/// The other case is when manual implementation of the trait is needed.
/// This covers the following cases:
///
/// * if a class implements a QOM interface, the Rust code _has_ to define its
/// own class struct `FooClass` and implement `ClassInitImpl<FooClass>`.
/// `ClassInitImpl<FooClass>`'s `class_init` method will then forward to
/// multiple other `class_init`s, for the interfaces as well as the
/// superclass. (Note that there is no Rust example yet for using interfaces).
///
/// * for classes implemented outside the ``qemu-api`` crate, it's not possible
/// to add blanket implementations like the above one, due to orphan rules. In
/// that case, the easiest solution is to implement
/// `ClassInitImpl<YourSuperclass>` for each subclass and not have a
/// `YourSuperclassImpl` trait at all.
///
/// ```ignore
/// impl ClassInitImpl<YourSuperclass> for YourSubclass {
/// fn class_init(klass: &mut YourSuperclass) {
/// klass.some_method = Some(Self::some_method);
/// <Self as ClassInitImpl<SysBusDeviceClass>>::class_init(&mut klass.parent_class);
/// }
/// }
/// ```
///
/// While this method incurs a small amount of code duplication,
/// it is generally limited to the recursive call on the last line.
/// This is because classes defined in Rust do not need the same
/// glue code that is needed when the classes are defined in C code.
/// You may consider using a macro if you have many subclasses.
pub trait ClassInitImpl<T> {
/// Initialize `klass` to point to 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.
///
/// The virtual method implementations usually come from another
/// trait, for example [`DeviceImpl`](crate::qdev::DeviceImpl)
/// when `T` is [`DeviceClass`](crate::qdev::DeviceClass).
///
/// On entry, `klass`'s parent class is initialized, while the other fields
/// are all zero; it is therefore assumed that all fields in `T` can be
/// zeroed, otherwise it would not be possible to provide the class as a
/// `&mut T`. TODO: add a bound of [`Zeroable`](crate::zeroable::Zeroable)
/// to T; this is more easily done once Zeroable does not require a manual
/// implementation (Rust 1.75.0).
fn class_init(klass: &mut T);
}
/// # Safety
///
/// We expect the FFI user of this function to pass a valid pointer that
/// can be downcasted to type `T`. We also expect the device is
/// readable/writeable from one thread at any time.
unsafe extern "C" fn rust_unparent_fn<T: ObjectImpl>(dev: *mut Object) {
let state = NonNull::new(dev).unwrap().cast::<T>();
T::UNPARENT.unwrap()(unsafe { state.as_ref() });
}
impl<T> ClassInitImpl<ObjectClass> for T
where
T: ObjectImpl,
{
fn class_init(oc: &mut ObjectClass) {
if <T as ObjectImpl>::UNPARENT.is_some() {
oc.unparent = Some(rust_unparent_fn::<T>);
}
}
}
unsafe impl ObjectType for Object {
type Class = ObjectClass;
const TYPE_NAME: &'static CStr =
unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_OBJECT) };
}
/// A reference-counted pointer to a QOM object.
///
/// `Owned<T>` wraps `T` with automatic reference counting. It increases the
/// reference count when created via [`Owned::from`] or cloned, and decreases
/// it when dropped. This ensures that the reference count remains elevated
/// as long as any `Owned<T>` references to it exist.
///
/// `Owned<T>` can be used for two reasons:
/// * because the lifetime of the QOM object is unknown and someone else could
/// take a reference (similar to `Arc<T>`, for example): in this case, the
/// object can escape and outlive the Rust struct that contains the `Owned<T>`
/// field;
///
/// * to ensure that the object stays alive until after `Drop::drop` is called
/// on the Rust struct: in this case, the object will always die together with
/// the Rust struct that contains the `Owned<T>` field.
///
/// Child properties are an example of the second case: in C, an object that
/// is created with `object_initialize_child` will die *before*
/// `instance_finalize` is called, whereas Rust expects the struct to have valid
/// contents when `Drop::drop` is called. Therefore Rust structs that have
/// child properties need to keep a reference to the child object. Right now
/// this can be done with `Owned<T>`; in the future one might have a separate
/// `Child<'parent, T>` smart pointer that keeps a reference to a `T`, like
/// `Owned`, but does not allow cloning.
///
/// Note that dropping an `Owned<T>` requires the big QEMU lock to be taken.
#[repr(transparent)]
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Owned<T: ObjectType>(NonNull<T>);
// The following rationale for safety is taken from Linux's kernel::sync::Arc.
// SAFETY: It is safe to send `Owned<T>` to another thread when the underlying
// `T` is `Sync` because it effectively means sharing `&T` (which is safe
// because `T` is `Sync`); additionally, it needs `T` to be `Send` because any
// thread that has an `Owned<T>` may ultimately access `T` using a
// mutable reference when the reference count reaches zero and `T` is dropped.
unsafe impl<T: ObjectType + Send + Sync> Send for Owned<T> {}
// SAFETY: It is safe to send `&Owned<T>` to another thread when the underlying
// `T` is `Sync` because it effectively means sharing `&T` (which is safe
// because `T` is `Sync`); additionally, it needs `T` to be `Send` because any
// thread that has a `&Owned<T>` may clone it and get an `Owned<T>` on that
// thread, so the thread may ultimately access `T` using a mutable reference
// when the reference count reaches zero and `T` is dropped.
unsafe impl<T: ObjectType + Sync + Send> Sync for Owned<T> {}
impl<T: ObjectType> Owned<T> {
/// Convert a raw C pointer into an owned reference to the QOM
/// object it points to. The object's reference count will be
/// decreased when the `Owned` is dropped.
///
/// # Panics
///
/// Panics if `ptr` is NULL.
///
/// # Safety
///
/// The caller must indeed own a reference to the QOM object.
/// The object must not be embedded in another unless the outer
/// object is guaranteed to have a longer lifetime.
///
/// A raw pointer obtained via [`Owned::into_raw()`] can always be passed
/// back to `from_raw()` (assuming the original `Owned` was valid!),
/// since the owned reference remains there between the calls to
/// `into_raw()` and `from_raw()`.
pub unsafe fn from_raw(ptr: *const T) -> Self {
// SAFETY NOTE: while NonNull requires a mutable pointer, only
// Deref is implemented so the pointer passed to from_raw
// remains const
Owned(NonNull::new(ptr as *mut T).unwrap())
}
/// Obtain a raw C pointer from a reference. `src` is consumed
/// and the reference is leaked.
#[allow(clippy::missing_const_for_fn)]
pub fn into_raw(src: Owned<T>) -> *mut T {
let src = ManuallyDrop::new(src);
src.0.as_ptr()
}
/// Increase the reference count of a QOM object and return
/// a new owned reference to it.
///
/// # Safety
///
/// The object must not be embedded in another, unless the outer
/// object is guaranteed to have a longer lifetime.
pub unsafe fn from(obj: &T) -> Self {
unsafe {
object_ref(obj.as_object_mut_ptr().cast::<c_void>());
// SAFETY NOTE: while NonNull requires a mutable pointer, only
// Deref is implemented so the reference passed to from_raw
// remains shared
Owned(NonNull::new_unchecked(obj.as_mut_ptr()))
}
}
}
impl<T: ObjectType> Clone for Owned<T> {
fn clone(&self) -> Self {
// SAFETY: creation method is unsafe; whoever calls it has
// responsibility that the pointer is valid, and remains valid
// throughout the lifetime of the `Owned<T>` and its clones.
unsafe { Owned::from(self.deref()) }
}
}
impl<T: ObjectType> Deref for Owned<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
// SAFETY: creation method is unsafe; whoever calls it has
// responsibility that the pointer is valid, and remains valid
// throughout the lifetime of the `Owned<T>` and its clones.
// With that guarantee, reference counting ensures that
// the object remains alive.
unsafe { &*self.0.as_ptr() }
}
}
impl<T: ObjectType> ObjectDeref for Owned<T> {}
impl<T: ObjectType> Drop for Owned<T> {
fn drop(&mut self) {
assert!(bql_locked());
// SAFETY: creation method is unsafe, and whoever calls it has
// responsibility that the pointer is valid, and remains valid
// throughout the lifetime of the `Owned<T>` and its clones.
unsafe {
object_unref(self.as_object_mut_ptr().cast::<c_void>());
}
}
}
impl<T: IsA<Object>> fmt::Debug for Owned<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.deref().debug_fmt(f)
}
}
/// Trait for methods exposed by the Object class. The methods can be
/// called on all objects that have the trait `IsA<Object>`.
///
/// The trait should only be used through the blanket implementation,
/// which guarantees safety via `IsA`
pub trait ObjectMethods: ObjectDeref
where
Self::Target: IsA<Object>,
{
/// Return the name of the type of `self`
fn typename(&self) -> std::borrow::Cow<'_, str> {
let obj = self.upcast::<Object>();
// SAFETY: safety of this is the requirement for implementing IsA
// The result of the C API has static lifetime
unsafe {
let p = object_get_typename(obj.as_mut_ptr());
CStr::from_ptr(p).to_string_lossy()
}
}
fn get_class(&self) -> &'static <Self::Target as ObjectType>::Class {
let obj = self.upcast::<Object>();
// SAFETY: all objects can call object_get_class; the actual class
// type is guaranteed by the implementation of `ObjectType` and
// `ObjectImpl`.
let klass: &'static <Self::Target as ObjectType>::Class =
unsafe { &*object_get_class(obj.as_mut_ptr()).cast() };
klass
}
/// Convenience function for implementing the Debug trait
fn debug_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple(&self.typename())
.field(&(self as *const Self))
.finish()
}
}
impl<R: ObjectDeref> ObjectMethods for R where R::Target: IsA<Object> {}
|