These are the initial set of bindings and support code that are needed to apply Zhao's posted HPET implementation, and for him to apply my review comments. They include:
- QOM cleanups (already posted) - interrupts sources and cells (posted and reviewed) - bit deposit and extract operations (new) - QOM generalization beyond DeviceState (new) - callbacks system (new) This is the code that I aim at integrating in QEMU 10.0, and is also what is needed to develop additional bindings (for e.g. timers) more or less independently. I'll focus here on the changes to QOM because they represent the bulk of the patches. The bit operations and callbacks are just one or two patches each, and better explained by the doc comments in the patch itself. With respect to qdev, some of this was already explained in the "Rust in QEMU roadmap". The patches are split in two series, corresponding to patches 7-14 and 15-24. The first and previously posted part mostly removes code duplication, while keeping the focus very much on four elements of DeviceClass (realize, legacy reset, properties, vmstate). The second instead starts to establish a correspondence between the QOM class hierarchy and the Rust trait system. The hierarchy of classes is visible as an ObjectImpl::ParentType associated type, and also present in the implementation of the ClassInitImpl<ClassType> trait. The ClassInitImpl trait is implemented for each Rust-defined QOM class as before, but now its implementation is split over multiple blanket impls, one for each superclass. This allows code reuse of the class_init wrappers, and is implemented in patches 15-18. After a brief cleanup intermission in patches 19-21, patches 22-23 provide the method invocation infrastructure. Taking inspiration from glib-rs's GObject bindings, an IsA<> trait declares what is a subclass of what, which allows two things: - safe and efficient typecasts, which are compile-time checked so that it is an error if the destination type is not a superclass. - automatically making methods available to all subclasses. This is done through another blanket implementation of a trait, as in glib-rs (see https://gtk-rs.org/gtk4-rs/stable/latest/docs/src/gtk4/auto/widget.rs.html#5377), though the details are a bit different. The differences with glib-rs are not small, but fortunately it is the QEMU version that is simpler. QEMU does not use a complicated macro like glib's (https://gtk-rs.org/gtk-rs-core/git/docs/glib/macro.wrapper.html) to wrap all subclasses of GObject with an opaque Rust type. While macros in general, and procedural macros in particular, may be a useful tool(*), for now I prefer to ensure that the infrastructure is usable and readable even without any macro magic. The two pieces allow defining QOM class hierarchies entirely in Rust; patch 24 for example gives TYPE_PL011 its own class type PL011Class, and stores the device id in PL011Class instead of PL011State. I understand that this is a lot of code, and a lot of added lines in particular. Fortunately about 40% of it is docs, which is definitely a change for QEMU's standards. :) Also all except the last two patches have already been used by Zhao, who did not report any particular problem adopting them. Excepting the docs, the bulk of the new code is in the BqlCell and BqlRefCell implementations, as well as in patch 22. Fortunately these patches are also relatively boring. The more interesting patches to review are patch 15-18 for QOM, and 25 for the callbacks. Patch 25 is also the trickiest to explain from the point of view of using advanced language features; (**) I tried to explain that in the doc comments and commit messages but please ask for more if necessary. This series is available at branch rust-next of https://gitlab.com/bonzini/qemu.git. Thanks, Paolo (*) For example they could automate the declaration of various traits, many of which are "unsafe" as a reminder that they interact with C code. This should be pretty easy, considering that the amount of code required to write QOM types is already smaller in Rust than in C. qdev properties are also a useful target, as exemplified by Manos's previously posted series. (**) In particular, zero-sized types and the Fn trait. Paolo Bonzini (26): bql: check that the BQL is not dropped within marked sections rust: cell: add BQL-enforcing Cell variant rust: cell: add BQL-enforcing RefCell variant rust: define prelude rust: add bindings for interrupt sources rust: add a bit operation module rust: qom: add default definitions for ObjectImpl rust: qom: rename Class trait to ClassInitImpl rust: qom: convert type_info! macro to an associated const rust: qom: move ClassInitImpl to the instance side rust: qdev: move device_class_init! body to generic function, ClassInitImpl implementation to macro rust: qdev: move bridge for realize and reset functions out of pl011 rust: qom: automatically use Drop trait to implement instance_finalize rust: qom: move bridge for TypeInfo functions out of pl011 rust: qom: split ObjectType from ObjectImpl trait rust: qom: change the parent type to an associated type rust: qom: put class_init together from multiple ClassInitImpl<> rust: qom: add possibility of overriding unparent rust: rename qemu-api modules to follow C code a bit more rust: re-export C types from qemu-api submodules rust: tests: allow writing more than one test rust: qom: add casting functionality rust: qom: add initial subset of methods on Object rust: qom: move device_id to PL011 class side rust: qemu-api: add a module to wrap functions and zero-sized closures rust: callbacks: allow passing optional callbacks as () include/qemu/main-loop.h | 15 + stubs/iothread-lock.c | 15 + system/cpus.c | 15 + rust/Cargo.toml | 1 + rust/hw/char/pl011/src/device.rs | 156 ++--- rust/hw/char/pl011/src/device_class.rs | 34 - rust/qemu-api-macros/src/lib.rs | 2 +- rust/qemu-api/Cargo.toml | 3 +- rust/qemu-api/meson.build | 14 +- rust/qemu-api/src/bitops.rs | 119 ++++ rust/qemu-api/src/callbacks.rs | 238 +++++++ rust/qemu-api/src/cell.rs | 822 +++++++++++++++++++++++++ rust/qemu-api/src/definitions.rs | 91 --- rust/qemu-api/src/device_class.rs | 74 --- rust/qemu-api/src/irq.rs | 91 +++ rust/qemu-api/src/lib.rs | 15 +- rust/qemu-api/src/module.rs | 43 ++ rust/qemu-api/src/prelude.rs | 18 + rust/qemu-api/src/qdev.rs | 146 +++++ rust/qemu-api/src/qom.rs | 556 +++++++++++++++++ rust/qemu-api/src/sysbus.rs | 51 ++ rust/qemu-api/src/vmstate.rs | 9 +- rust/qemu-api/tests/tests.rs | 208 +++++-- 23 files changed, 2374 insertions(+), 362 deletions(-) create mode 100644 rust/qemu-api/src/bitops.rs create mode 100644 rust/qemu-api/src/callbacks.rs create mode 100644 rust/qemu-api/src/cell.rs delete mode 100644 rust/qemu-api/src/definitions.rs delete mode 100644 rust/qemu-api/src/device_class.rs create mode 100644 rust/qemu-api/src/irq.rs create mode 100644 rust/qemu-api/src/module.rs create mode 100644 rust/qemu-api/src/prelude.rs create mode 100644 rust/qemu-api/src/qdev.rs create mode 100644 rust/qemu-api/src/qom.rs create mode 100644 rust/qemu-api/src/sysbus.rs -- 2.47.1