mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-17 15:12:07 -06:00
rust: remove offset_of replacement
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
5df3fe062f
commit
b134a09ffa
15 changed files with 16 additions and 239 deletions
|
@ -84,12 +84,6 @@ are missing:
|
||||||
* ``c"" literals`` (stable in 1.77.0). QEMU provides a ``c_str!()`` macro
|
* ``c"" literals`` (stable in 1.77.0). QEMU provides a ``c_str!()`` macro
|
||||||
to define ``CStr`` constants easily
|
to define ``CStr`` constants easily
|
||||||
|
|
||||||
* ``offset_of!`` (stable in 1.77.0). QEMU uses ``offset_of!()`` heavily; it
|
|
||||||
provides a replacement in the ``qemu_api`` crate, but it does not support
|
|
||||||
lifetime parameters and therefore ``&'a Something`` fields in the struct
|
|
||||||
may have to be replaced by ``NonNull<Something>``. *Nested* ``offset_of!``
|
|
||||||
was only stabilized in Rust 1.82.0, but it is not used.
|
|
||||||
|
|
||||||
* inline const expression (stable in 1.79.0), currently worked around with
|
* inline const expression (stable in 1.79.0), currently worked around with
|
||||||
associated constants in the ``FnCall`` trait.
|
associated constants in the ``FnCall`` trait.
|
||||||
|
|
||||||
|
|
1
rust/Cargo.lock
generated
1
rust/Cargo.lock
generated
|
@ -108,7 +108,6 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"qemu_api_macros",
|
"qemu_api_macros",
|
||||||
"version_check",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -17,7 +17,7 @@ rust-version = "1.77.0"
|
||||||
[workspace.lints.rust]
|
[workspace.lints.rust]
|
||||||
unexpected_cfgs = { level = "deny", check-cfg = [
|
unexpected_cfgs = { level = "deny", check-cfg = [
|
||||||
'cfg(MESON)', 'cfg(HAVE_GLIB_WITH_ALIGNED_ALLOC)',
|
'cfg(MESON)', 'cfg(HAVE_GLIB_WITH_ALIGNED_ALLOC)',
|
||||||
'cfg(has_offset_of)'] }
|
] }
|
||||||
|
|
||||||
# Occasionally, we may need to silence warnings and clippy lints that
|
# Occasionally, we may need to silence warnings and clippy lints that
|
||||||
# were only introduced in newer Rust compiler versions. Do not croak
|
# were only introduced in newer Rust compiler versions. Do not croak
|
||||||
|
|
|
@ -74,7 +74,7 @@ impl std::ops::Index<u32> for Fifo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Default, qemu_api_macros::offsets)]
|
#[derive(Debug, Default)]
|
||||||
pub struct PL011Registers {
|
pub struct PL011Registers {
|
||||||
#[doc(alias = "fr")]
|
#[doc(alias = "fr")]
|
||||||
pub flags: registers::Flags,
|
pub flags: registers::Flags,
|
||||||
|
@ -98,7 +98,7 @@ pub struct PL011Registers {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(qemu_api_macros::Object, qemu_api_macros::offsets)]
|
#[derive(qemu_api_macros::Object)]
|
||||||
/// PL011 Device Model in QEMU
|
/// PL011 Device Model in QEMU
|
||||||
pub struct PL011State {
|
pub struct PL011State {
|
||||||
pub parent_obj: ParentField<SysBusDevice>,
|
pub parent_obj: ParentField<SysBusDevice>,
|
||||||
|
|
|
@ -183,7 +183,7 @@ fn timer_handler(timer_cell: &BqlRefCell<HPETTimer>) {
|
||||||
|
|
||||||
/// HPET Timer Abstraction
|
/// HPET Timer Abstraction
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, qemu_api_macros::offsets)]
|
#[derive(Debug)]
|
||||||
pub struct HPETTimer {
|
pub struct HPETTimer {
|
||||||
/// timer N index within the timer block (`HPETState`)
|
/// timer N index within the timer block (`HPETState`)
|
||||||
#[doc(alias = "tn")]
|
#[doc(alias = "tn")]
|
||||||
|
@ -523,7 +523,7 @@ impl HPETTimer {
|
||||||
|
|
||||||
/// HPET Event Timer Block Abstraction
|
/// HPET Event Timer Block Abstraction
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(qemu_api_macros::Object, qemu_api_macros::offsets)]
|
#[derive(qemu_api_macros::Object)]
|
||||||
pub struct HPETState {
|
pub struct HPETState {
|
||||||
parent_obj: ParentField<SysBusDevice>,
|
parent_obj: ParentField<SysBusDevice>,
|
||||||
iomem: MemoryRegion,
|
iomem: MemoryRegion,
|
||||||
|
|
|
@ -6,7 +6,7 @@ use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{
|
use syn::{
|
||||||
parse_macro_input, parse_quote, punctuated::Punctuated, spanned::Spanned, token::Comma, Data,
|
parse_macro_input, parse_quote, punctuated::Punctuated, spanned::Spanned, token::Comma, Data,
|
||||||
DeriveInput, Field, Fields, FieldsUnnamed, Ident, Meta, Path, Token, Type, Variant, Visibility,
|
DeriveInput, Field, Fields, FieldsUnnamed, Ident, Meta, Path, Token, Variant,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
@ -151,33 +151,6 @@ pub fn derive_opaque(input: TokenStream) -> TokenStream {
|
||||||
TokenStream::from(expanded)
|
TokenStream::from(expanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip::macros(quote)]
|
|
||||||
fn derive_offsets_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream, MacroError> {
|
|
||||||
is_c_repr(&input, "#[derive(offsets)]")?;
|
|
||||||
|
|
||||||
let name = &input.ident;
|
|
||||||
let fields = get_fields(&input, "#[derive(offsets)]")?;
|
|
||||||
let field_names: Vec<&Ident> = fields.iter().map(|f| f.ident.as_ref().unwrap()).collect();
|
|
||||||
let field_types: Vec<&Type> = fields.iter().map(|f| &f.ty).collect();
|
|
||||||
let field_vis: Vec<&Visibility> = fields.iter().map(|f| &f.vis).collect();
|
|
||||||
|
|
||||||
Ok(quote! {
|
|
||||||
::qemu_api::with_offsets! {
|
|
||||||
struct #name {
|
|
||||||
#(#field_vis #field_names: #field_types,)*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro_derive(offsets)]
|
|
||||||
pub fn derive_offsets(input: TokenStream) -> TokenStream {
|
|
||||||
let input = parse_macro_input!(input as DeriveInput);
|
|
||||||
let expanded = derive_offsets_or_error(input).unwrap_or_else(Into::into);
|
|
||||||
|
|
||||||
TokenStream::from(expanded)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn get_repr_uN(input: &DeriveInput, msg: &str) -> Result<Path, MacroError> {
|
fn get_repr_uN(input: &DeriveInput, msg: &str) -> Result<Path, MacroError> {
|
||||||
let repr = input.attrs.iter().find(|attr| attr.path().is_ident("repr"));
|
let repr = input.attrs.iter().find(|attr| attr.path().is_ident("repr"));
|
||||||
|
|
|
@ -17,9 +17,6 @@ rust-version.workspace = true
|
||||||
qemu_api_macros = { path = "../qemu-api-macros" }
|
qemu_api_macros = { path = "../qemu-api-macros" }
|
||||||
libc = "0.2.162"
|
libc = "0.2.162"
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
version_check = "~0.9"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["debug_cell"]
|
default = ["debug_cell"]
|
||||||
allocator = []
|
allocator = []
|
||||||
|
|
|
@ -8,8 +8,6 @@ use std::os::unix::fs::symlink as symlink_file;
|
||||||
use std::os::windows::fs::symlink_file;
|
use std::os::windows::fs::symlink_file;
|
||||||
use std::{env, fs::remove_file, io::Result, path::Path};
|
use std::{env, fs::remove_file, io::Result, path::Path};
|
||||||
|
|
||||||
use version_check as rustc;
|
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
// Placing bindings.inc.rs in the source directory is supported
|
// Placing bindings.inc.rs in the source directory is supported
|
||||||
// but not documented or encouraged.
|
// but not documented or encouraged.
|
||||||
|
@ -38,11 +36,6 @@ fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
symlink_file(file, dest_path)?;
|
symlink_file(file, dest_path)?;
|
||||||
|
|
||||||
// Check for available rustc features
|
|
||||||
if rustc::is_min_version("1.77.0").unwrap_or(false) {
|
|
||||||
println!("cargo:rustc-cfg=has_offset_of");
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,6 @@ _qemu_api_cfg = run_command(rustc_args,
|
||||||
libc_dep = dependency('libc-0.2-rs')
|
libc_dep = dependency('libc-0.2-rs')
|
||||||
|
|
||||||
# _qemu_api_cfg += ['--cfg', 'feature="allocator"']
|
# _qemu_api_cfg += ['--cfg', 'feature="allocator"']
|
||||||
if rustc.version().version_compare('>=1.77.0')
|
|
||||||
_qemu_api_cfg += ['--cfg', 'has_offset_of']
|
|
||||||
endif
|
|
||||||
if get_option('debug_mutex')
|
if get_option('debug_mutex')
|
||||||
_qemu_api_cfg += ['--cfg', 'feature="debug_cell"']
|
_qemu_api_cfg += ['--cfg', 'feature="debug_cell"']
|
||||||
endif
|
endif
|
||||||
|
@ -28,7 +25,6 @@ _qemu_api_rs = static_library(
|
||||||
'src/irq.rs',
|
'src/irq.rs',
|
||||||
'src/memory.rs',
|
'src/memory.rs',
|
||||||
'src/module.rs',
|
'src/module.rs',
|
||||||
'src/offset_of.rs',
|
|
||||||
'src/prelude.rs',
|
'src/prelude.rs',
|
||||||
'src/qdev.rs',
|
'src/qdev.rs',
|
||||||
'src/qom.rs',
|
'src/qom.rs',
|
||||||
|
|
|
@ -23,7 +23,6 @@ pub mod errno;
|
||||||
pub mod irq;
|
pub mod irq;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod module;
|
pub mod module;
|
||||||
pub mod offset_of;
|
|
||||||
pub mod qdev;
|
pub mod qdev;
|
||||||
pub mod qom;
|
pub mod qom;
|
||||||
pub mod sysbus;
|
pub mod sysbus;
|
||||||
|
@ -165,6 +164,3 @@ unsafe impl GlobalAlloc for QemuAllocator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_offset_of)]
|
|
||||||
pub use core::mem::offset_of;
|
|
||||||
|
|
|
@ -1,168 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#![doc(hidden)]
|
|
||||||
//! This module provides macros that emulate the functionality of
|
|
||||||
//! `core::mem::offset_of` on older versions of Rust.
|
|
||||||
//!
|
|
||||||
//! Documentation is hidden because it only exposes macros, which
|
|
||||||
//! are exported directly from `qemu_api`.
|
|
||||||
|
|
||||||
/// This macro provides the same functionality as `core::mem::offset_of`,
|
|
||||||
/// except that only one level of field access is supported. The declaration
|
|
||||||
/// of the struct must be wrapped with `with_offsets! { }`.
|
|
||||||
///
|
|
||||||
/// It is needed because `offset_of!` was only stabilized in Rust 1.77.
|
|
||||||
#[cfg(not(has_offset_of))]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! offset_of {
|
|
||||||
($Container:ty, $field:ident) => {
|
|
||||||
<$Container>::OFFSET_TO__.$field
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A wrapper for struct declarations, that allows using `offset_of!` in
|
|
||||||
/// versions of Rust prior to 1.77
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! with_offsets {
|
|
||||||
// This method to generate field offset constants comes from:
|
|
||||||
//
|
|
||||||
// https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=10a22a9b8393abd7b541d8fc844bc0df
|
|
||||||
//
|
|
||||||
// used under MIT license with permission of Yandros aka Daniel Henry-Mantilla
|
|
||||||
(
|
|
||||||
$(#[$struct_meta:meta])*
|
|
||||||
$struct_vis:vis
|
|
||||||
struct $StructName:ident {
|
|
||||||
$(
|
|
||||||
$(#[$field_meta:meta])*
|
|
||||||
$field_vis:vis
|
|
||||||
$field_name:ident : $field_ty:ty
|
|
||||||
),*
|
|
||||||
$(,)?
|
|
||||||
}
|
|
||||||
) => (
|
|
||||||
#[cfg(not(has_offset_of))]
|
|
||||||
const _: () = {
|
|
||||||
struct StructOffsetsHelper<T>(std::marker::PhantomData<T>);
|
|
||||||
const END_OF_PREV_FIELD: usize = 0;
|
|
||||||
|
|
||||||
// populate StructOffsetsHelper<T> with associated consts,
|
|
||||||
// one for each field
|
|
||||||
$crate::with_offsets! {
|
|
||||||
@struct $StructName
|
|
||||||
@names [ $($field_name)* ]
|
|
||||||
@tys [ $($field_ty ,)*]
|
|
||||||
}
|
|
||||||
|
|
||||||
// now turn StructOffsetsHelper<T>'s consts into a single struct,
|
|
||||||
// applying field visibility. This provides better error messages
|
|
||||||
// than if offset_of! used StructOffsetsHelper::<T> directly.
|
|
||||||
pub
|
|
||||||
struct StructOffsets {
|
|
||||||
$(
|
|
||||||
$field_vis
|
|
||||||
$field_name: usize,
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
impl $StructName {
|
|
||||||
pub
|
|
||||||
const OFFSET_TO__: StructOffsets = StructOffsets {
|
|
||||||
$(
|
|
||||||
$field_name: StructOffsetsHelper::<$StructName>::$field_name,
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
);
|
|
||||||
|
|
||||||
(
|
|
||||||
@struct $StructName:ident
|
|
||||||
@names []
|
|
||||||
@tys []
|
|
||||||
) => ();
|
|
||||||
|
|
||||||
(
|
|
||||||
@struct $StructName:ident
|
|
||||||
@names [$field_name:ident $($other_names:tt)*]
|
|
||||||
@tys [$field_ty:ty , $($other_tys:tt)*]
|
|
||||||
) => (
|
|
||||||
#[allow(non_local_definitions)]
|
|
||||||
#[allow(clippy::modulo_one)]
|
|
||||||
impl StructOffsetsHelper<$StructName> {
|
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
const $field_name: usize = {
|
|
||||||
const ALIGN: usize = std::mem::align_of::<$field_ty>();
|
|
||||||
const TRAIL: usize = END_OF_PREV_FIELD % ALIGN;
|
|
||||||
END_OF_PREV_FIELD + (if TRAIL == 0 { 0usize } else { ALIGN - TRAIL })
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const _: () = {
|
|
||||||
const END_OF_PREV_FIELD: usize =
|
|
||||||
StructOffsetsHelper::<$StructName>::$field_name +
|
|
||||||
std::mem::size_of::<$field_ty>()
|
|
||||||
;
|
|
||||||
$crate::with_offsets! {
|
|
||||||
@struct $StructName
|
|
||||||
@names [$($other_names)*]
|
|
||||||
@tys [$($other_tys)*]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::offset_of;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct Foo {
|
|
||||||
a: u16,
|
|
||||||
b: u32,
|
|
||||||
c: u64,
|
|
||||||
d: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct Bar {
|
|
||||||
pub a: u16,
|
|
||||||
pub b: u64,
|
|
||||||
c: Foo,
|
|
||||||
d: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
crate::with_offsets! {
|
|
||||||
#[repr(C)]
|
|
||||||
struct Bar {
|
|
||||||
pub a: u16,
|
|
||||||
pub b: u64,
|
|
||||||
c: Foo,
|
|
||||||
d: u64,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct Baz {
|
|
||||||
b: u32,
|
|
||||||
a: u8,
|
|
||||||
}
|
|
||||||
crate::with_offsets! {
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct Baz {
|
|
||||||
b: u32,
|
|
||||||
a: u8,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_offset_of() {
|
|
||||||
const OFFSET_TO_C: usize = offset_of!(Bar, c);
|
|
||||||
|
|
||||||
assert_eq!(offset_of!(Bar, a), 0);
|
|
||||||
assert_eq!(offset_of!(Bar, b), 8);
|
|
||||||
assert_eq!(OFFSET_TO_C, 16);
|
|
||||||
assert_eq!(offset_of!(Bar, d), 40);
|
|
||||||
|
|
||||||
assert_eq!(offset_of!(Baz, b), 0);
|
|
||||||
assert_eq!(offset_of!(Baz, a), 4);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -190,7 +190,7 @@ macro_rules! define_property {
|
||||||
// use associated function syntax for type checking
|
// use associated function syntax for type checking
|
||||||
name: ::std::ffi::CStr::as_ptr($name),
|
name: ::std::ffi::CStr::as_ptr($name),
|
||||||
info: $prop,
|
info: $prop,
|
||||||
offset: $crate::offset_of!($state, $field) as isize,
|
offset: ::std::mem::offset_of!($state, $field) as isize,
|
||||||
bitnr: $bitnr,
|
bitnr: $bitnr,
|
||||||
set_default: true,
|
set_default: true,
|
||||||
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
|
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
|
||||||
|
@ -202,7 +202,7 @@ macro_rules! define_property {
|
||||||
// use associated function syntax for type checking
|
// use associated function syntax for type checking
|
||||||
name: ::std::ffi::CStr::as_ptr($name),
|
name: ::std::ffi::CStr::as_ptr($name),
|
||||||
info: $prop,
|
info: $prop,
|
||||||
offset: $crate::offset_of!($state, $field) as isize,
|
offset: ::std::mem::offset_of!($state, $field) as isize,
|
||||||
set_default: true,
|
set_default: true,
|
||||||
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
|
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
|
||||||
..$crate::zeroable::Zeroable::ZERO
|
..$crate::zeroable::Zeroable::ZERO
|
||||||
|
@ -213,7 +213,7 @@ macro_rules! define_property {
|
||||||
// use associated function syntax for type checking
|
// use associated function syntax for type checking
|
||||||
name: ::std::ffi::CStr::as_ptr($name),
|
name: ::std::ffi::CStr::as_ptr($name),
|
||||||
info: $prop,
|
info: $prop,
|
||||||
offset: $crate::offset_of!($state, $field) as isize,
|
offset: ::std::mem::offset_of!($state, $field) as isize,
|
||||||
set_default: false,
|
set_default: false,
|
||||||
..$crate::zeroable::Zeroable::ZERO
|
..$crate::zeroable::Zeroable::ZERO
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,8 +205,8 @@ macro_rules! vmstate_of {
|
||||||
name: ::core::concat!(::core::stringify!($field_name), "\0")
|
name: ::core::concat!(::core::stringify!($field_name), "\0")
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
.as_ptr() as *const ::std::os::raw::c_char,
|
.as_ptr() as *const ::std::os::raw::c_char,
|
||||||
offset: $crate::offset_of!($struct_name, $field_name),
|
offset: ::std::mem::offset_of!($struct_name, $field_name),
|
||||||
$(num_offset: $crate::offset_of!($struct_name, $num),)?
|
$(num_offset: ::std::mem::offset_of!($struct_name, $num),)?
|
||||||
$(field_exists: $crate::vmstate_exist_fn!($struct_name, $test_fn),)?
|
$(field_exists: $crate::vmstate_exist_fn!($struct_name, $test_fn),)?
|
||||||
// The calls to `call_func_with_field!` are the magic that
|
// The calls to `call_func_with_field!` are the magic that
|
||||||
// computes most of the VMStateField from the type of the field.
|
// computes most of the VMStateField from the type of the field.
|
||||||
|
@ -483,10 +483,10 @@ macro_rules! vmstate_struct {
|
||||||
name: ::core::concat!(::core::stringify!($field_name), "\0")
|
name: ::core::concat!(::core::stringify!($field_name), "\0")
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
.as_ptr() as *const ::std::os::raw::c_char,
|
.as_ptr() as *const ::std::os::raw::c_char,
|
||||||
$(num_offset: $crate::offset_of!($struct_name, $num),)?
|
$(num_offset: ::std::mem::offset_of!($struct_name, $num),)?
|
||||||
offset: {
|
offset: {
|
||||||
$crate::assert_field_type!($struct_name, $field_name, $type $(, num = $num)?);
|
$crate::assert_field_type!($struct_name, $field_name, $type $(, num = $num)?);
|
||||||
$crate::offset_of!($struct_name, $field_name)
|
::std::mem::offset_of!($struct_name, $field_name)
|
||||||
},
|
},
|
||||||
size: ::core::mem::size_of::<$type>(),
|
size: ::core::mem::size_of::<$type>(),
|
||||||
flags: $crate::bindings::VMStateFlags::VMS_STRUCT,
|
flags: $crate::bindings::VMStateFlags::VMS_STRUCT,
|
||||||
|
@ -518,7 +518,7 @@ macro_rules! vmstate_clock {
|
||||||
$field_name,
|
$field_name,
|
||||||
$crate::qom::Owned<$crate::qdev::Clock> $(, num = $num)?
|
$crate::qom::Owned<$crate::qdev::Clock> $(, num = $num)?
|
||||||
);
|
);
|
||||||
$crate::offset_of!($struct_name, $field_name)
|
::std::mem::offset_of!($struct_name, $field_name)
|
||||||
},
|
},
|
||||||
size: ::core::mem::size_of::<*const $crate::qdev::Clock>(),
|
size: ::core::mem::size_of::<*const $crate::qdev::Clock>(),
|
||||||
flags: $crate::bindings::VMStateFlags(
|
flags: $crate::bindings::VMStateFlags(
|
||||||
|
|
|
@ -26,7 +26,6 @@ pub static VMSTATE: VMStateDescription = VMStateDescription {
|
||||||
..Zeroable::ZERO
|
..Zeroable::ZERO
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(qemu_api_macros::offsets)]
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(qemu_api_macros::Object)]
|
#[derive(qemu_api_macros::Object)]
|
||||||
pub struct DummyState {
|
pub struct DummyState {
|
||||||
|
@ -79,7 +78,6 @@ impl DeviceImpl for DummyState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(qemu_api_macros::offsets)]
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(qemu_api_macros::Object)]
|
#[derive(qemu_api_macros::Object)]
|
||||||
pub struct DummyChildState {
|
pub struct DummyChildState {
|
||||||
|
|
|
@ -33,7 +33,7 @@ const FOO_ARRAY_MAX: usize = 3;
|
||||||
// - VMSTATE_VARRAY_UINT16_UNSAFE
|
// - VMSTATE_VARRAY_UINT16_UNSAFE
|
||||||
// - VMSTATE_VARRAY_MULTIPLY
|
// - VMSTATE_VARRAY_MULTIPLY
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Default, qemu_api_macros::offsets)]
|
#[derive(Default)]
|
||||||
struct FooA {
|
struct FooA {
|
||||||
arr: [u8; FOO_ARRAY_MAX],
|
arr: [u8; FOO_ARRAY_MAX],
|
||||||
num: u16,
|
num: u16,
|
||||||
|
@ -154,7 +154,7 @@ fn test_vmstate_varray_multiply() {
|
||||||
// - VMSTATE_ARRAY
|
// - VMSTATE_ARRAY
|
||||||
// - VMSTATE_STRUCT_VARRAY_UINT8 with BqlCell wrapper & test_fn
|
// - VMSTATE_STRUCT_VARRAY_UINT8 with BqlCell wrapper & test_fn
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Default, qemu_api_macros::offsets)]
|
#[derive(Default)]
|
||||||
struct FooB {
|
struct FooB {
|
||||||
arr_a: [FooA; FOO_ARRAY_MAX],
|
arr_a: [FooA; FOO_ARRAY_MAX],
|
||||||
num_a: u8,
|
num_a: u8,
|
||||||
|
@ -329,7 +329,6 @@ struct FooCWrapper([Opaque<*mut u8>; FOO_ARRAY_MAX]); // Though Opaque<> array i
|
||||||
impl_vmstate_forward!(FooCWrapper);
|
impl_vmstate_forward!(FooCWrapper);
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(qemu_api_macros::offsets)]
|
|
||||||
struct FooC {
|
struct FooC {
|
||||||
ptr: *const i32,
|
ptr: *const i32,
|
||||||
ptr_a: NonNull<FooA>,
|
ptr_a: NonNull<FooA>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue