diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2024-10-21 13:24:22 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2024-11-05 14:18:15 +0100 |
commit | e90d470733d3d2ca185a0b379ef8773601f60cfb (patch) | |
tree | 353354a1e84a5d14088a4646a101d6230e9b153a | |
parent | cde3c425d16f6d0c8e6f47940ef5152b9021f3f2 (diff) |
rust: cleanup module_init!, use it from #[derive(Object)]
Remove the duplicate code by using the module_init! macro; at the same time,
simplify how module_init! is used, by taking inspiration from the implementation
of #[derive(Object)].
Reviewed-by: Junjie Mao <junjie.mao@hotmail.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | rust/qemu-api-macros/src/lib.rs | 33 | ||||
-rw-r--r-- | rust/qemu-api/src/definitions.rs | 65 |
2 files changed, 32 insertions, 66 deletions
diff --git a/rust/qemu-api-macros/src/lib.rs b/rust/qemu-api-macros/src/lib.rs index 70e3f92046..a4bc5d01ee 100644 --- a/rust/qemu-api-macros/src/lib.rs +++ b/rust/qemu-api-macros/src/lib.rs @@ -3,43 +3,20 @@ // SPDX-License-Identifier: GPL-2.0-or-later use proc_macro::TokenStream; -use quote::{format_ident, quote}; +use quote::quote; use syn::{parse_macro_input, DeriveInput}; #[proc_macro_derive(Object)] pub fn derive_object(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); - let name = input.ident; - let module_static = format_ident!("__{}_LOAD_MODULE", name); let expanded = quote! { - #[allow(non_upper_case_globals)] - #[used] - #[cfg_attr( - not(any(target_vendor = "apple", target_os = "windows")), - link_section = ".init_array" - )] - #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")] - #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")] - pub static #module_static: extern "C" fn() = { - extern "C" fn __register() { - unsafe { - ::qemu_api::bindings::type_register_static(&<#name as ::qemu_api::definitions::ObjectImpl>::TYPE_INFO); - } - } - - extern "C" fn __load() { - unsafe { - ::qemu_api::bindings::register_module_init( - Some(__register), - ::qemu_api::bindings::module_init_type::MODULE_INIT_QOM - ); - } + ::qemu_api::module_init! { + MODULE_INIT_QOM => unsafe { + ::qemu_api::bindings::type_register_static(&<#name as ::qemu_api::definitions::ObjectImpl>::TYPE_INFO); } - - __load - }; + } }; TokenStream::from(expanded) diff --git a/rust/qemu-api/src/definitions.rs b/rust/qemu-api/src/definitions.rs index 3323a665d9..064afe6054 100644 --- a/rust/qemu-api/src/definitions.rs +++ b/rust/qemu-api/src/definitions.rs @@ -29,51 +29,40 @@ pub trait Class { #[macro_export] macro_rules! module_init { - ($func:expr, $type:expr) => { - #[used] - #[cfg_attr( - not(any(target_vendor = "apple", target_os = "windows")), - link_section = ".init_array" - )] - #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")] - #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")] - pub static LOAD_MODULE: extern "C" fn() = { - extern "C" fn __load() { - unsafe { - $crate::bindings::register_module_init(Some($func), $type); - } - } - - __load - }; - }; - (qom: $func:ident => $body:block) => { - // NOTE: To have custom identifiers for the ctor func we need to either supply - // them directly as a macro argument or create them with a proc macro. - #[used] - #[cfg_attr( - not(any(target_vendor = "apple", target_os = "windows")), - link_section = ".init_array" - )] - #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")] - #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")] - pub static LOAD_MODULE: extern "C" fn() = { - extern "C" fn __load() { - unsafe extern "C" fn $func() { + ($type:ident => $body:block) => { + const _: () = { + #[used] + #[cfg_attr( + not(any(target_vendor = "apple", target_os = "windows")), + link_section = ".init_array" + )] + #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")] + #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")] + pub static LOAD_MODULE: extern "C" fn() = { + extern "C" fn init_fn() { $body } - unsafe { - $crate::bindings::register_module_init( - Some($func), - $crate::bindings::module_init_type::MODULE_INIT_QOM, - ); + extern "C" fn ctor_fn() { + unsafe { + $crate::bindings::register_module_init( + Some(init_fn), + $crate::bindings::module_init_type::$type, + ); + } } - } - __load + ctor_fn + }; }; }; + + // shortcut because it's quite common that $body needs unsafe {} + ($type:ident => unsafe $body:block) => { + $crate::module_init! { + $type => { unsafe { $body } } + } + }; } #[macro_export] |