From: Zhao Liu <zhao1.liu@intel.com>
To: "Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Daniel P . Berrangé" <berrange@redhat.com>
Cc: qemu-devel@nongnu.org, Junjie Mao <junjie.mao@hotmail.com>,
Zhao Liu <zhao1.liu@intel.com>
Subject: [RFC 2/2] rust/qemu-api: Bind PropertyInfo to type
Date: Thu, 17 Oct 2024 22:32:45 +0800 [thread overview]
Message-ID: <20241017143245.1248589-3-zhao1.liu@intel.com> (raw)
In-Reply-To: <20241017143245.1248589-1-zhao1.liu@intel.com>
For traditional property definitions implemented in C, since the C
language cannot bind variable types to specific methods or variables,
user must specify the concrete PropertyInfo and variable type in the
DEFINE_PROP macro and its variants. Then the property macro effectively
associate PropertyInfo with variable type through clever check.
However, in Rust, this process can be more elegant. By introducing the
PropertyType trait, QAPI (in Rust) can associate PropertyInfo with
specific types, allowing Rust to infer the predefined PropertyInfo from
the variable type.
This avoids user errors in passing incorrect PropertyInfo and simplifies
property definitions. And based on this enhancement, the property
definition macro can eliminate the need for the type and prop parameters.
Co-developed-by: Junjie Mao <junjie.mao@hotmail.com>
Signed-off-by: Junjie Mao <junjie.mao@hotmail.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
rust/hw/char/pl011/src/device_class.rs | 4 ---
rust/qemu-api/src/device_class.rs | 48 +++++++++++++++++++++++---
rust/qemu-api/src/tests.rs | 4 ---
3 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/rust/hw/char/pl011/src/device_class.rs b/rust/hw/char/pl011/src/device_class.rs
index b7ab31af02d7..295e970e8564 100644
--- a/rust/hw/char/pl011/src/device_class.rs
+++ b/rust/hw/char/pl011/src/device_class.rs
@@ -21,15 +21,11 @@
c"chardev",
PL011State,
char_backend,
- unsafe { &qdev_prop_chr },
- CharBackend
),
qemu_api::define_property!(
c"migrate-clk",
PL011State,
migrate_clock,
- unsafe { &qdev_prop_bool },
- bool
),
}
diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/device_class.rs
index be363fd63223..0b9d6ca705d3 100644
--- a/rust/qemu-api/src/device_class.rs
+++ b/rust/qemu-api/src/device_class.rs
@@ -4,7 +4,7 @@
use std::sync::OnceLock;
-use crate::bindings::Property;
+use crate::bindings::{CharBackend, Property, PropertyInfo, qdev_prop_chr, qdev_prop_bool};
#[macro_export]
macro_rules! device_class_init {
@@ -24,16 +24,54 @@ macro_rules! device_class_init {
};
}
+pub trait PropertyType {
+ fn get_prop_info() -> *const PropertyInfo;
+}
+
+pub trait PropertyTypeImpl<T: PropertyType> {
+ fn get_prop_info(_: *const T) -> *const PropertyInfo;
+}
+
+impl<T: PropertyType> PropertyTypeImpl<T> for () {
+ fn get_prop_info(_: *const T) -> *const PropertyInfo {
+ T::get_prop_info()
+ }
+}
+
+impl PropertyType for CharBackend {
+ fn get_prop_info() -> *const PropertyInfo {
+ // SAFETY: Access to a defined c-structure, no other operation is performed.
+ unsafe { std::ptr::addr_of!(qdev_prop_chr) }
+ }
+}
+
+impl PropertyType for bool {
+ fn get_prop_info() -> *const PropertyInfo {
+ // SAFETY: Access to a defined c-structure, no other operation is performed.
+ unsafe { std::ptr::addr_of!(qdev_prop_bool) }
+ }
+}
+
+#[macro_export]
+macro_rules! get_prop_info {
+ ($state:ty, $field:ident) => {{
+ use $crate::device_class::PropertyTypeImpl;
+ let base = std::mem::MaybeUninit::<$state>::uninit().as_ptr();
+ <()>::get_prop_info(unsafe { std::ptr::addr_of!((*base).$field) })
+ }};
+}
+
+
#[macro_export]
macro_rules! define_property {
- ($name:expr, $state:ty, $field:ident, $prop:expr, $type:ty, default = $defval:expr$(,)*) => {
+ ($name:expr, $state:ty, $field:ident, default = $defval:expr$(,)*) => {
$crate::bindings::Property {
name: {
#[used]
static _TEMP: &::core::ffi::CStr = $name;
_TEMP.as_ptr()
},
- info: $prop,
+ info: $crate::get_prop_info!($state, $field),
offset: ::core::mem::offset_of!($state, $field)
.try_into()
.expect("Could not fit offset value to type"),
@@ -47,14 +85,14 @@ macro_rules! define_property {
link_type: ::core::ptr::null(),
}
};
- ($name:expr, $state:ty, $field:ident, $prop:expr, $type:ty$(,)*) => {
+ ($name:expr, $state:ty, $field:ident$(,)*) => {
$crate::bindings::Property {
name: {
#[used]
static _TEMP: &::core::ffi::CStr = $name;
_TEMP.as_ptr()
},
- info: $prop,
+ info: $crate::get_prop_info!($state, $field),
offset: ::core::mem::offset_of!($state, $field)
.try_into()
.expect("Could not fit offset value to type"),
diff --git a/rust/qemu-api/src/tests.rs b/rust/qemu-api/src/tests.rs
index df54edbd4e27..d2b7451ef707 100644
--- a/rust/qemu-api/src/tests.rs
+++ b/rust/qemu-api/src/tests.rs
@@ -27,15 +27,11 @@ pub struct DummyState {
c"chardev",
DummyState,
char_backend,
- unsafe { &qdev_prop_chr },
- CharBackend
),
define_property!(
c"migrate-clk",
DummyState,
migrate_clock,
- unsafe { &qdev_prop_bool },
- bool
),
}
--
2.34.1
prev parent reply other threads:[~2024-10-17 14:17 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-17 14:32 [RFC 0/2] rust/qemu-api: Rethink property definition macro Zhao Liu
2024-10-17 14:32 ` [RFC 1/2] rust/qemu-api: Fix fragment-specifiers in define_property macro Zhao Liu
2024-10-17 14:32 ` Zhao Liu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241017143245.1248589-3-zhao1.liu@intel.com \
--to=zhao1.liu@intel.com \
--cc=alex.bennee@linaro.org \
--cc=berrange@redhat.com \
--cc=junjie.mao@hotmail.com \
--cc=manos.pitsidianakis@linaro.org \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).