diff options
| author | Stefan Hajnoczi <stefanha@redhat.com> | 2025-06-04 11:43:30 -0400 |
|---|---|---|
| committer | Stefan Hajnoczi <stefanha@redhat.com> | 2025-06-04 11:43:31 -0400 |
| commit | f8a113701dd2d28f3bedb216e59125ddcb77fd05 (patch) | |
| tree | 55ce05f7943dc3bbb1fbb36f28b22f2608b0f831 /rust/qemu-api-macros/src/lib.rs | |
| parent | 09be8a511a2e278b45729d7b065d30c68dd699d0 (diff) | |
| parent | 214518614c1ce7eb7a002452cd43a7597f90d543 (diff) | |
| download | focaccia-qemu-f8a113701dd2d28f3bedb216e59125ddcb77fd05.tar.gz focaccia-qemu-f8a113701dd2d28f3bedb216e59125ddcb77fd05.zip | |
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* rust: use native Meson support for clippy and rustdoc * rust: add "bits", a custom bitflags implementation * target/i386: Remove FRED dependency on WRMSRNS * target/i386: Add the immediate form MSR access instruction support * TDX fixes # -----BEGIN PGP SIGNATURE----- # # iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmg/XrsUHHBib256aW5p # QHJlZGhhdC5jb20ACgkQv/vSX3jHroOPIwf/VXh98Wd+7BJLkNJVFpczSF7YhJ5J # a5BcWLOdVrzEJoqvfc9lkubgpShgzYDYJH99F/FloHddkPvZ1NRB2JXtDB1O3sSC # NGaI4YM8uA/k21pt1jQtDJkk3Az7GNIBIcvi4HR5GjTOvOKGOXLpYErK52lM4GNG # Aa17/Rb9Ug+QzyuS1M+mDPFdY2X6Hore2jXsp3ZH+U8hs+khecHEPsZUZ/Nlr1Z7 # UoiYks4U29wtVJ/BCjNkgXoMJC6uqL/nOP5dLJBgboOodrtwdwpDMIUcyPLrOnjf # ugJx0zYHIVdqpdft72EvLD92bzB8WoUiPsUA/dG45gGmhzuYWDmOqSdaKg== # =l0gm # -----END PGP SIGNATURE----- # gpg: Signature made Tue 03 Jun 2025 16:44:43 EDT # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * tag 'for-upstream' of https://gitlab.com/bonzini/qemu: rust: qemu-api-macros: add from_bits and into_bits to #[derive(TryInto)] rust: pl011: use the bits macro rust: add "bits", a custom bitflags implementation i386/tdvf: Fix build on 32-bit host i386/tdx: Fix build on 32-bit host meson: use config_base_arch for target libraries target/i386: Add the immediate form MSR access instruction support target/i386: Add a new CPU feature word for CPUID.7.1.ECX target/i386: Remove FRED dependency on WRMSRNS rust: use native Meson support for clippy and rustdoc rust: cell: remove support for running doctests with "cargo test --doc" rust: add qemu-api doctests to "meson test" build, dockerfiles: add support for detecting rustdoc rust: use "objects" for Rust executables as well meson: update to version 1.8.1 rust: bindings: allow ptr_offset_with_cast Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'rust/qemu-api-macros/src/lib.rs')
| -rw-r--r-- | rust/qemu-api-macros/src/lib.rs | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/rust/qemu-api-macros/src/lib.rs b/rust/qemu-api-macros/src/lib.rs index f97449bb30..103470785e 100644 --- a/rust/qemu-api-macros/src/lib.rs +++ b/rust/qemu-api-macros/src/lib.rs @@ -12,6 +12,9 @@ use syn::{ mod utils; use utils::MacroError; +mod bits; +use bits::BitsConstInternal; + fn get_fields<'a>( input: &'a DeriveInput, msg: &str, @@ -190,23 +193,51 @@ fn get_variants(input: &DeriveInput) -> Result<&Punctuated<Variant, Comma>, Macr } #[rustfmt::skip::macros(quote)] +fn derive_tryinto_body( + name: &Ident, + variants: &Punctuated<Variant, Comma>, + repr: &Path, +) -> Result<proc_macro2::TokenStream, MacroError> { + let discriminants: Vec<&Ident> = variants.iter().map(|f| &f.ident).collect(); + + Ok(quote! { + #(const #discriminants: #repr = #name::#discriminants as #repr;)*; + match value { + #(#discriminants => Ok(#name::#discriminants),)* + _ => Err(value), + } + }) +} + +#[rustfmt::skip::macros(quote)] fn derive_tryinto_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream, MacroError> { let repr = get_repr_uN(&input, "#[derive(TryInto)]")?; - let name = &input.ident; - let variants = get_variants(&input)?; - let discriminants: Vec<&Ident> = variants.iter().map(|f| &f.ident).collect(); + let body = derive_tryinto_body(name, get_variants(&input)?, &repr)?; + let errmsg = format!("invalid value for {name}"); Ok(quote! { + impl #name { + #[allow(dead_code)] + pub const fn into_bits(self) -> #repr { + self as #repr + } + + #[allow(dead_code)] + pub const fn from_bits(value: #repr) -> Self { + match ({ + #body + }) { + Ok(x) => x, + Err(_) => panic!(#errmsg) + } + } + } impl core::convert::TryFrom<#repr> for #name { type Error = #repr; fn try_from(value: #repr) -> Result<Self, Self::Error> { - #(const #discriminants: #repr = #name::#discriminants as #repr;)*; - match value { - #(#discriminants => Ok(Self::#discriminants),)* - _ => Err(value), - } + #body } } }) @@ -219,3 +250,12 @@ pub fn derive_tryinto(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } + +#[proc_macro] +pub fn bits_const_internal(ts: TokenStream) -> TokenStream { + let ts = proc_macro2::TokenStream::from(ts); + let mut it = ts.into_iter(); + + let expanded = BitsConstInternal::parse(&mut it).unwrap_or_else(Into::into); + TokenStream::from(expanded) +} |