use cfg_select! to select the right VaListImpl definition
This commit is contained in:
parent
6eef33bb39
commit
89a8abc4be
1 changed files with 136 additions and 175 deletions
|
|
@ -5,148 +5,120 @@
|
|||
use crate::ffi::c_void;
|
||||
#[allow(unused_imports)]
|
||||
use crate::fmt;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::marker::{PhantomData, PhantomInvariantLifetime};
|
||||
use crate::ops::{Deref, DerefMut};
|
||||
|
||||
/// Basic implementation of a `va_list`.
|
||||
// The name is WIP, using `VaListImpl` for now.
|
||||
#[cfg(any(
|
||||
//
|
||||
// Most targets explicitly specify the layout of `va_list`, this layout is matched here.
|
||||
crate::cfg_select! {
|
||||
all(
|
||||
not(target_arch = "aarch64"),
|
||||
not(target_arch = "powerpc"),
|
||||
not(target_arch = "s390x"),
|
||||
not(target_arch = "xtensa"),
|
||||
not(target_arch = "x86_64")
|
||||
),
|
||||
all(target_arch = "aarch64", target_vendor = "apple"),
|
||||
target_family = "wasm",
|
||||
target_os = "uefi",
|
||||
windows,
|
||||
))]
|
||||
#[repr(transparent)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
ptr: *mut c_void,
|
||||
target_arch = "aarch64",
|
||||
not(target_vendor = "apple"),
|
||||
not(target_os = "uefi"),
|
||||
not(windows),
|
||||
) => {
|
||||
/// AArch64 ABI implementation of a `va_list`. See the
|
||||
/// [AArch64 Procedure Call Standard] for more details.
|
||||
///
|
||||
/// [AArch64 Procedure Call Standard]:
|
||||
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
|
||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
stack: *mut c_void,
|
||||
gr_top: *mut c_void,
|
||||
vr_top: *mut c_void,
|
||||
gr_offs: i32,
|
||||
vr_offs: i32,
|
||||
_marker: PhantomInvariantLifetime<'f>,
|
||||
}
|
||||
}
|
||||
all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)) => {
|
||||
/// PowerPC ABI implementation of a `va_list`.
|
||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
gpr: u8,
|
||||
fpr: u8,
|
||||
reserved: u16,
|
||||
overflow_arg_area: *mut c_void,
|
||||
reg_save_area: *mut c_void,
|
||||
_marker: PhantomInvariantLifetime<'f>,
|
||||
}
|
||||
}
|
||||
target_arch = "s390x" => {
|
||||
/// s390x ABI implementation of a `va_list`.
|
||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
gpr: i64,
|
||||
fpr: i64,
|
||||
overflow_arg_area: *mut c_void,
|
||||
reg_save_area: *mut c_void,
|
||||
_marker: PhantomInvariantLifetime<'f>,
|
||||
}
|
||||
}
|
||||
all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)) => {
|
||||
/// x86_64 ABI implementation of a `va_list`.
|
||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
gp_offset: i32,
|
||||
fp_offset: i32,
|
||||
overflow_arg_area: *mut c_void,
|
||||
reg_save_area: *mut c_void,
|
||||
_marker: PhantomInvariantLifetime<'f>,
|
||||
}
|
||||
}
|
||||
target_arch = "xtensa" => {
|
||||
/// Xtensa ABI implementation of a `va_list`.
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
stk: *mut i32,
|
||||
reg: *mut i32,
|
||||
ndx: i32,
|
||||
_marker: PhantomInvariantLifetime<'f>,
|
||||
}
|
||||
}
|
||||
|
||||
// Invariant over `'f`, so each `VaListImpl<'f>` object is tied to
|
||||
// the region of the function it's defined in
|
||||
_marker: PhantomData<&'f mut &'f c_void>,
|
||||
}
|
||||
// The fallback implementation, used for:
|
||||
//
|
||||
// - apple aarch64 (see https://github.com/rust-lang/rust/pull/56599)
|
||||
// - windows
|
||||
// - uefi
|
||||
// - any other target for which we don't specify the `VaListImpl` above
|
||||
//
|
||||
// In this implementation the `va_list` type is just an alias for an opaque pointer.
|
||||
// That pointer is probably just the next variadic argument on the caller's stack.
|
||||
_ => {
|
||||
/// Basic implementation of a `va_list`.
|
||||
#[repr(transparent)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
ptr: *mut c_void,
|
||||
|
||||
#[cfg(any(
|
||||
all(
|
||||
not(target_arch = "aarch64"),
|
||||
not(target_arch = "powerpc"),
|
||||
not(target_arch = "s390x"),
|
||||
not(target_arch = "xtensa"),
|
||||
not(target_arch = "x86_64")
|
||||
),
|
||||
all(target_arch = "aarch64", target_vendor = "apple"),
|
||||
target_family = "wasm",
|
||||
target_os = "uefi",
|
||||
windows,
|
||||
))]
|
||||
impl<'f> fmt::Debug for VaListImpl<'f> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "va_list* {:p}", self.ptr)
|
||||
// Invariant over `'f`, so each `VaListImpl<'f>` object is tied to
|
||||
// the region of the function it's defined in
|
||||
_marker: PhantomInvariantLifetime<'f>,
|
||||
}
|
||||
|
||||
impl<'f> fmt::Debug for VaListImpl<'f> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "va_list* {:p}", self.ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// AArch64 ABI implementation of a `va_list`. See the
|
||||
/// [AArch64 Procedure Call Standard] for more details.
|
||||
///
|
||||
/// [AArch64 Procedure Call Standard]:
|
||||
/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
|
||||
#[cfg(all(
|
||||
target_arch = "aarch64",
|
||||
not(target_vendor = "apple"),
|
||||
not(target_os = "uefi"),
|
||||
not(windows),
|
||||
))]
|
||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
stack: *mut c_void,
|
||||
gr_top: *mut c_void,
|
||||
vr_top: *mut c_void,
|
||||
gr_offs: i32,
|
||||
vr_offs: i32,
|
||||
_marker: PhantomData<&'f mut &'f c_void>,
|
||||
}
|
||||
|
||||
/// PowerPC ABI implementation of a `va_list`.
|
||||
#[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))]
|
||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
gpr: u8,
|
||||
fpr: u8,
|
||||
reserved: u16,
|
||||
overflow_arg_area: *mut c_void,
|
||||
reg_save_area: *mut c_void,
|
||||
_marker: PhantomData<&'f mut &'f c_void>,
|
||||
}
|
||||
|
||||
/// s390x ABI implementation of a `va_list`.
|
||||
#[cfg(target_arch = "s390x")]
|
||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
gpr: i64,
|
||||
fpr: i64,
|
||||
overflow_arg_area: *mut c_void,
|
||||
reg_save_area: *mut c_void,
|
||||
_marker: PhantomData<&'f mut &'f c_void>,
|
||||
}
|
||||
|
||||
/// x86_64 ABI implementation of a `va_list`.
|
||||
#[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))]
|
||||
#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
gp_offset: i32,
|
||||
fp_offset: i32,
|
||||
overflow_arg_area: *mut c_void,
|
||||
reg_save_area: *mut c_void,
|
||||
_marker: PhantomData<&'f mut &'f c_void>,
|
||||
}
|
||||
|
||||
/// Xtensa ABI implementation of a `va_list`.
|
||||
#[cfg(target_arch = "xtensa")]
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[lang = "va_list"]
|
||||
pub struct VaListImpl<'f> {
|
||||
stk: *mut i32,
|
||||
reg: *mut i32,
|
||||
ndx: i32,
|
||||
_marker: PhantomData<&'f mut &'f c_void>,
|
||||
}
|
||||
|
||||
/// A wrapper for a `va_list`
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct VaList<'a, 'f: 'a> {
|
||||
#[cfg(any(
|
||||
all(
|
||||
not(target_arch = "aarch64"),
|
||||
not(target_arch = "powerpc"),
|
||||
not(target_arch = "s390x"),
|
||||
not(target_arch = "x86_64")
|
||||
),
|
||||
target_arch = "xtensa",
|
||||
all(target_arch = "aarch64", target_vendor = "apple"),
|
||||
target_family = "wasm",
|
||||
target_os = "uefi",
|
||||
windows,
|
||||
))]
|
||||
inner: VaListImpl<'f>,
|
||||
|
||||
#[cfg(all(
|
||||
crate::cfg_select! {
|
||||
all(
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "powerpc",
|
||||
|
|
@ -158,52 +130,41 @@ pub struct VaList<'a, 'f: 'a> {
|
|||
not(target_family = "wasm"),
|
||||
not(target_os = "uefi"),
|
||||
not(windows),
|
||||
))]
|
||||
inner: &'a mut VaListImpl<'f>,
|
||||
) => {
|
||||
/// A wrapper for a `va_list`
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct VaList<'a, 'f: 'a> {
|
||||
inner: &'a mut VaListImpl<'f>,
|
||||
_marker: PhantomData<&'a mut VaListImpl<'f>>,
|
||||
}
|
||||
|
||||
_marker: PhantomData<&'a mut VaListImpl<'f>>,
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
all(
|
||||
not(target_arch = "aarch64"),
|
||||
not(target_arch = "powerpc"),
|
||||
not(target_arch = "s390x"),
|
||||
not(target_arch = "x86_64")
|
||||
),
|
||||
target_arch = "xtensa",
|
||||
all(target_arch = "aarch64", target_vendor = "apple"),
|
||||
target_family = "wasm",
|
||||
target_os = "uefi",
|
||||
windows,
|
||||
))]
|
||||
impl<'f> VaListImpl<'f> {
|
||||
/// Converts a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
|
||||
#[inline]
|
||||
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
||||
VaList { inner: VaListImpl { ..*self }, _marker: PhantomData }
|
||||
impl<'f> VaListImpl<'f> {
|
||||
/// Converts a [`VaListImpl`] into a [`VaList`] that is binary-compatible with C's `va_list`.
|
||||
#[inline]
|
||||
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
||||
VaList { inner: self, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "s390x",
|
||||
target_arch = "xtensa",
|
||||
target_arch = "x86_64"
|
||||
),
|
||||
not(target_arch = "xtensa"),
|
||||
any(not(target_arch = "aarch64"), not(target_vendor = "apple")),
|
||||
not(target_family = "wasm"),
|
||||
not(target_os = "uefi"),
|
||||
not(windows),
|
||||
))]
|
||||
impl<'f> VaListImpl<'f> {
|
||||
/// Converts a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
|
||||
#[inline]
|
||||
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
||||
VaList { inner: self, _marker: PhantomData }
|
||||
_ => {
|
||||
/// A wrapper for a `va_list`
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
pub struct VaList<'a, 'f: 'a> {
|
||||
inner: VaListImpl<'f>,
|
||||
_marker: PhantomData<&'a mut VaListImpl<'f>>,
|
||||
}
|
||||
|
||||
impl<'f> VaListImpl<'f> {
|
||||
/// Converts a [`VaListImpl`] into a [`VaList`] that is binary-compatible with C's `va_list`.
|
||||
#[inline]
|
||||
pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
|
||||
VaList { inner: VaListImpl { ..*self }, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue