mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-27 04:13:53 -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
|
@ -23,7 +23,6 @@ pub mod errno;
|
|||
pub mod irq;
|
||||
pub mod memory;
|
||||
pub mod module;
|
||||
pub mod offset_of;
|
||||
pub mod qdev;
|
||||
pub mod qom;
|
||||
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
|
||||
name: ::std::ffi::CStr::as_ptr($name),
|
||||
info: $prop,
|
||||
offset: $crate::offset_of!($state, $field) as isize,
|
||||
offset: ::std::mem::offset_of!($state, $field) as isize,
|
||||
bitnr: $bitnr,
|
||||
set_default: true,
|
||||
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
|
||||
name: ::std::ffi::CStr::as_ptr($name),
|
||||
info: $prop,
|
||||
offset: $crate::offset_of!($state, $field) as isize,
|
||||
offset: ::std::mem::offset_of!($state, $field) as isize,
|
||||
set_default: true,
|
||||
defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval as u64 },
|
||||
..$crate::zeroable::Zeroable::ZERO
|
||||
|
@ -213,7 +213,7 @@ macro_rules! define_property {
|
|||
// use associated function syntax for type checking
|
||||
name: ::std::ffi::CStr::as_ptr($name),
|
||||
info: $prop,
|
||||
offset: $crate::offset_of!($state, $field) as isize,
|
||||
offset: ::std::mem::offset_of!($state, $field) as isize,
|
||||
set_default: false,
|
||||
..$crate::zeroable::Zeroable::ZERO
|
||||
}
|
||||
|
|
|
@ -205,8 +205,8 @@ macro_rules! vmstate_of {
|
|||
name: ::core::concat!(::core::stringify!($field_name), "\0")
|
||||
.as_bytes()
|
||||
.as_ptr() as *const ::std::os::raw::c_char,
|
||||
offset: $crate::offset_of!($struct_name, $field_name),
|
||||
$(num_offset: $crate::offset_of!($struct_name, $num),)?
|
||||
offset: ::std::mem::offset_of!($struct_name, $field_name),
|
||||
$(num_offset: ::std::mem::offset_of!($struct_name, $num),)?
|
||||
$(field_exists: $crate::vmstate_exist_fn!($struct_name, $test_fn),)?
|
||||
// The calls to `call_func_with_field!` are the magic that
|
||||
// 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")
|
||||
.as_bytes()
|
||||
.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: {
|
||||
$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>(),
|
||||
flags: $crate::bindings::VMStateFlags::VMS_STRUCT,
|
||||
|
@ -518,7 +518,7 @@ macro_rules! vmstate_clock {
|
|||
$field_name,
|
||||
$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>(),
|
||||
flags: $crate::bindings::VMStateFlags(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue