qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH preview 0/3] reviving minimal QAPI generation from 2021
@ 2025-06-05 10:11 Paolo Bonzini
  2025-06-05 10:11 ` [PATCH 1/3] rust: make TryFrom macro more resilient Paolo Bonzini
                   ` (5 more replies)
  0 siblings, 6 replies; 21+ messages in thread
From: Paolo Bonzini @ 2025-06-05 10:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: marcandre.lureau, qemu-rust, armbru, mkletzan

This is just an extremely minimal extraction from the patches at
https://patchew.org/QEMU/20210907121943.3498701-1-marcandre.lureau@redhat.com/,
limited to generating structs and enums from the QAPI schema.
It does not include them in any crate and does not compile them.

While I'm not going to work on this, I was curious how much work it
was to produce *some* kind of Rust QAPI struct, which could be a first
step towards using serde as an interface to C visitors, like this:

trait QapiType: FreeForeign {
    unsafe fn visit(v: bindings::Visitor, name: *const c_char, obj: *mut <Self as FreeForeign>::Foreign, errp: *mut *mut bindings::Error);
}

fn to_c<T: QAPIType>(obj: &T) -> *mut <T as FreeForeign>::Foreign {
    let mut ptr = libc::calloc(...);
    let mut ser = QapiSerializer::<T>::new(ptr);
    obj.serialize(&mut ser).unwrap();
    ptr.cast()
}

unsafe fn from_c<T: QAPIType>(obj: *const <T as FreeForeign>::Foreign) -> T {
    let mut de = QapiDeserializer::new(T::visit, obj as *const c_void);
    let value = de::Deserialize::deserialize(&mut de).unwrap();
    de.end().unwrap();
    value
}

/* Generated code below: */

impl QapiType for UefiVariable {
    unsafe fn visit(v: bindings::Visitor, name: *const c_char, obj: *mut bindings::UefiVariable, errp: *mut *mut bindings::Error) {
        unsafe extern "C" visit_type_DumpGuestMemoryFormat(v: bindings::Visitor, name: *const c_char, obj: *mut bindings::UefiVariable, errp: *mut *mut bindings::Error) {
        unsafe { visit_type_DumpGuestMemoryFormat(v, name, obj, errp); }
    }
}

impl FreeForeign for UefiVariable {
    type Foreign = bindings::UefiVariable;

    unsafe fn free_foreign(p: *mut bindings::UefiVariable) {
        unsafe extern "C" qapi_free_UefiVariable(p: *mut bindings::UefiVariable);
        unsafe { qapi_free_UefiVariable(p); }
    }
}

impl CloneToForeign for UefiVariable {
    fn clone_to_foreign(&self) -> OwnedPointer<Self> {
        OwnedPointer::new(qapi::to_c(self))
    }
}

impl FromForeign for UefiVariable {
    unsafe fn cloned_from_foreign(obj: *const bindings::UefiVariable) -> Self {
        qapi::from_c(obj)
    }
}

The FFI types could be generated by qapi-gen, as in Marc-André's
proposal, or from bindgen.

I am not sure what approach is better---whether to use serde or to
automatically generate the marshaling and unmarshaling code; and whether
to use bindgen or generate C-compatible FFI types---but it made sense,
from the point of view of extracting "some" code from Marc-André's
proof of concept and enticing other people, :) to start from high-level
types.

Paolo

Marc-André Lureau (2):
  scripts/qapi: add QAPISchemaIfCond.rsgen()
  scripts/qapi: generate high-level Rust bindings

Paolo Bonzini (1):
  rust: make TryFrom macro more resilient

 meson.build                     |   4 +-
 rust/qemu-api-macros/src/lib.rs |   7 +-
 scripts/qapi/backend.py         |   4 +-
 scripts/qapi/common.py          |  16 ++
 scripts/qapi/main.py            |   4 +-
 scripts/qapi/rs.py              | 183 ++++++++++++++++++
 scripts/qapi/rs_types.py        | 320 ++++++++++++++++++++++++++++++++
 scripts/qapi/schema.py          |   4 +
 8 files changed, 535 insertions(+), 7 deletions(-)
 create mode 100644 scripts/qapi/rs.py
 create mode 100644 scripts/qapi/rs_types.py

-- 
2.49.0



^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2025-07-02 19:12 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-05 10:11 [PATCH preview 0/3] reviving minimal QAPI generation from 2021 Paolo Bonzini
2025-06-05 10:11 ` [PATCH 1/3] rust: make TryFrom macro more resilient Paolo Bonzini
2025-06-10 13:26   ` Marc-André Lureau
2025-06-10 15:52   ` Zhao Liu
2025-06-05 10:11 ` [PATCH 2/3] scripts/qapi: add QAPISchemaIfCond.rsgen() Paolo Bonzini
2025-06-10 13:33   ` Marc-André Lureau
2025-06-05 10:11 ` [PATCH 3/3] scripts/qapi: generate high-level Rust bindings Paolo Bonzini
2025-06-11  8:09   ` Zhao Liu
2025-06-10 13:53 ` [PATCH preview 0/3] reviving minimal QAPI generation from 2021 Marc-André Lureau
2025-06-10 16:10   ` Paolo Bonzini
2025-06-11  8:13 ` Zhao Liu
2025-06-11  8:57   ` Paolo Bonzini
2025-06-12 10:24     ` Paolo Bonzini
2025-06-13  5:57       ` Zhao Liu
2025-06-16  8:55         ` Paolo Bonzini
2025-06-18 14:25       ` Markus Armbruster
2025-06-18 17:36         ` Paolo Bonzini
2025-06-23 12:52           ` Markus Armbruster
2025-07-02 19:09             ` Paolo Bonzini
2025-06-17  7:49 ` Markus Armbruster
2025-06-18  8:27   ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).