55use crate::ffi::c_void;
66#[allow(unused_imports)]
77use crate::fmt;
8- use crate::marker::PhantomData;
8+ use crate::marker::{ PhantomData, PhantomInvariantLifetime} ;
99use crate::ops::{Deref, DerefMut};
1010
11- /// Basic implementation of a `va_list`.
1211// The name is WIP, using `VaListImpl` for now.
13- #[cfg(any(
12+ //
13+ // Most targets explicitly specify the layout of `va_list`, this layout is matched here.
14+ crate::cfg_select! {
1415 all(
15- not(target_arch = "aarch64"),
16- not(target_arch = "powerpc"),
17- not(target_arch = "s390x"),
18- not(target_arch = "xtensa"),
19- not(target_arch = "x86_64")
20- ),
21- all(target_arch = "aarch64", target_vendor = "apple"),
22- target_family = "wasm",
23- target_os = "uefi",
24- windows,
25- ))]
26- #[repr(transparent)]
27- #[lang = "va_list"]
28- pub struct VaListImpl<'f> {
29- ptr: *mut c_void,
30-
31- // Invariant over `'f`, so each `VaListImpl<'f>` object is tied to
32- // the region of the function it's defined in
33- _marker: PhantomData<&'f mut &'f c_void>,
34- }
35-
36- #[cfg(any(
37- all(
38- not(target_arch = "aarch64"),
39- not(target_arch = "powerpc"),
40- not(target_arch = "s390x"),
41- not(target_arch = "xtensa"),
42- not(target_arch = "x86_64")
43- ),
44- all(target_arch = "aarch64", target_vendor = "apple"),
45- target_family = "wasm",
46- target_os = "uefi",
47- windows,
48- ))]
49- impl<'f> fmt::Debug for VaListImpl<'f> {
50- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51- write!(f, "va_list* {:p}", self.ptr)
16+ target_arch = "aarch64",
17+ not(target_vendor = "apple"),
18+ not(target_os = "uefi"),
19+ not(windows),
20+ ) => {
21+ /// AArch64 ABI implementation of a `va_list`. See the
22+ /// [AArch64 Procedure Call Standard] for more details.
23+ ///
24+ /// [AArch64 Procedure Call Standard]:
25+ /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
26+ #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
27+ #[derive(Debug)]
28+ #[lang = "va_list"]
29+ pub struct VaListImpl<'f> {
30+ stack: *mut c_void,
31+ gr_top: *mut c_void,
32+ vr_top: *mut c_void,
33+ gr_offs: i32,
34+ vr_offs: i32,
35+ _marker: PhantomInvariantLifetime<'f>,
36+ }
37+ }
38+ all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)) => {
39+ /// PowerPC ABI implementation of a `va_list`.
40+ #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
41+ #[derive(Debug)]
42+ #[lang = "va_list"]
43+ pub struct VaListImpl<'f> {
44+ gpr: u8,
45+ fpr: u8,
46+ reserved: u16,
47+ overflow_arg_area: *mut c_void,
48+ reg_save_area: *mut c_void,
49+ _marker: PhantomInvariantLifetime<'f>,
50+ }
51+ }
52+ target_arch = "s390x" => {
53+ /// s390x ABI implementation of a `va_list`.
54+ #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
55+ #[derive(Debug)]
56+ #[lang = "va_list"]
57+ pub struct VaListImpl<'f> {
58+ gpr: i64,
59+ fpr: i64,
60+ overflow_arg_area: *mut c_void,
61+ reg_save_area: *mut c_void,
62+ _marker: PhantomInvariantLifetime<'f>,
63+ }
64+ }
65+ all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)) => {
66+ /// x86_64 ABI implementation of a `va_list`.
67+ #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
68+ #[derive(Debug)]
69+ #[lang = "va_list"]
70+ pub struct VaListImpl<'f> {
71+ gp_offset: i32,
72+ fp_offset: i32,
73+ overflow_arg_area: *mut c_void,
74+ reg_save_area: *mut c_void,
75+ _marker: PhantomInvariantLifetime<'f>,
76+ }
77+ }
78+ target_arch = "xtensa" => {
79+ /// Xtensa ABI implementation of a `va_list`.
80+ #[repr(C)]
81+ #[derive(Debug)]
82+ #[lang = "va_list"]
83+ pub struct VaListImpl<'f> {
84+ stk: *mut i32,
85+ reg: *mut i32,
86+ ndx: i32,
87+ _marker: PhantomInvariantLifetime<'f>,
88+ }
5289 }
53- }
54-
55- /// AArch64 ABI implementation of a `va_list`. See the
56- /// [AArch64 Procedure Call Standard] for more details.
57- ///
58- /// [AArch64 Procedure Call Standard]:
59- /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
60- #[cfg(all(
61- target_arch = "aarch64",
62- not(target_vendor = "apple"),
63- not(target_os = "uefi"),
64- not(windows),
65- ))]
66- #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
67- #[derive(Debug)]
68- #[lang = "va_list"]
69- pub struct VaListImpl<'f> {
70- stack: *mut c_void,
71- gr_top: *mut c_void,
72- vr_top: *mut c_void,
73- gr_offs: i32,
74- vr_offs: i32,
75- _marker: PhantomData<&'f mut &'f c_void>,
76- }
77-
78- /// PowerPC ABI implementation of a `va_list`.
79- #[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))]
80- #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
81- #[derive(Debug)]
82- #[lang = "va_list"]
83- pub struct VaListImpl<'f> {
84- gpr: u8,
85- fpr: u8,
86- reserved: u16,
87- overflow_arg_area: *mut c_void,
88- reg_save_area: *mut c_void,
89- _marker: PhantomData<&'f mut &'f c_void>,
90- }
91-
92- /// s390x ABI implementation of a `va_list`.
93- #[cfg(target_arch = "s390x")]
94- #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
95- #[derive(Debug)]
96- #[lang = "va_list"]
97- pub struct VaListImpl<'f> {
98- gpr: i64,
99- fpr: i64,
100- overflow_arg_area: *mut c_void,
101- reg_save_area: *mut c_void,
102- _marker: PhantomData<&'f mut &'f c_void>,
103- }
10490
105- /// x86_64 ABI implementation of a `va_list`.
106- #[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))]
107- #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401
108- #[derive(Debug)]
109- #[lang = "va_list"]
110- pub struct VaListImpl<'f> {
111- gp_offset: i32,
112- fp_offset: i32,
113- overflow_arg_area: *mut c_void,
114- reg_save_area: *mut c_void,
115- _marker: PhantomData<&'f mut &'f c_void>,
116- }
91+ // The fallback implementation, used for:
92+ //
93+ // - apple aarch64 (see https://github.com/rust-lang/rust/pull/56599)
94+ // - windows
95+ // - uefi
96+ // - any other target for which we don't specify the `VaListImpl` above
97+ //
98+ // In this implementation the `va_list` type is just an alias for an opaque pointer.
99+ // That pointer is probably just the next variadic argument on the caller's stack.
100+ _ => {
101+ /// Basic implementation of a `va_list`.
102+ #[repr(transparent)]
103+ #[lang = "va_list"]
104+ pub struct VaListImpl<'f> {
105+ ptr: *mut c_void,
106+
107+ // Invariant over `'f`, so each `VaListImpl<'f>` object is tied to
108+ // the region of the function it's defined in
109+ _marker: PhantomInvariantLifetime<'f>,
110+ }
117111
118- /// Xtensa ABI implementation of a `va_list`.
119- #[cfg(target_arch = "xtensa")]
120- #[repr(C)]
121- #[derive(Debug)]
122- #[lang = "va_list"]
123- pub struct VaListImpl<'f> {
124- stk: *mut i32,
125- reg: *mut i32,
126- ndx: i32,
127- _marker: PhantomData<&'f mut &'f c_void>,
112+ impl<'f> fmt::Debug for VaListImpl<'f> {
113+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114+ write!(f, "va_list* {:p}", self.ptr)
115+ }
116+ }
117+ }
128118}
129119
130- /// A wrapper for a `va_list`
131- #[repr(transparent)]
132- #[derive(Debug)]
133- pub struct VaList<'a, 'f: 'a> {
134- #[cfg(any(
135- all(
136- not(target_arch = "aarch64"),
137- not(target_arch = "powerpc"),
138- not(target_arch = "s390x"),
139- not(target_arch = "x86_64")
140- ),
141- target_arch = "xtensa",
142- all(target_arch = "aarch64", target_vendor = "apple"),
143- target_family = "wasm",
144- target_os = "uefi",
145- windows,
146- ))]
147- inner: VaListImpl<'f>,
148-
149- #[cfg(all(
120+ crate::cfg_select! {
121+ all(
150122 any(
151123 target_arch = "aarch64",
152124 target_arch = "powerpc",
@@ -158,52 +130,41 @@ pub struct VaList<'a, 'f: 'a> {
158130 not(target_family = "wasm"),
159131 not(target_os = "uefi"),
160132 not(windows),
161- ))]
162- inner: &'a mut VaListImpl<'f>,
133+ ) => {
134+ /// A wrapper for a `va_list`
135+ #[repr(transparent)]
136+ #[derive(Debug)]
137+ pub struct VaList<'a, 'f: 'a> {
138+ inner: &'a mut VaListImpl<'f>,
139+ _marker: PhantomData<&'a mut VaListImpl<'f>>,
140+ }
163141
164- _marker: PhantomData<&'a mut VaListImpl<'f>>,
165- }
166142
167- #[cfg(any(
168- all(
169- not(target_arch = "aarch64"),
170- not(target_arch = "powerpc"),
171- not(target_arch = "s390x"),
172- not(target_arch = "x86_64")
173- ),
174- target_arch = "xtensa",
175- all(target_arch = "aarch64", target_vendor = "apple"),
176- target_family = "wasm",
177- target_os = "uefi",
178- windows,
179- ))]
180- impl<'f> VaListImpl<'f> {
181- /// Converts a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
182- #[inline]
183- pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
184- VaList { inner: VaListImpl { ..*self }, _marker: PhantomData }
143+ impl<'f> VaListImpl<'f> {
144+ /// Converts a [`VaListImpl`] into a [`VaList`] that is binary-compatible with C's `va_list`.
145+ #[inline]
146+ pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
147+ VaList { inner: self, _marker: PhantomData }
148+ }
149+ }
185150 }
186- }
187151
188- #[cfg(all(
189- any(
190- target_arch = "aarch64",
191- target_arch = "powerpc",
192- target_arch = "s390x",
193- target_arch = "xtensa",
194- target_arch = "x86_64"
195- ),
196- not(target_arch = "xtensa"),
197- any(not(target_arch = "aarch64"), not(target_vendor = "apple")),
198- not(target_family = "wasm"),
199- not(target_os = "uefi"),
200- not(windows),
201- ))]
202- impl<'f> VaListImpl<'f> {
203- /// Converts a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`.
204- #[inline]
205- pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
206- VaList { inner: self, _marker: PhantomData }
152+ _ => {
153+ /// A wrapper for a `va_list`
154+ #[repr(transparent)]
155+ #[derive(Debug)]
156+ pub struct VaList<'a, 'f: 'a> {
157+ inner: VaListImpl<'f>,
158+ _marker: PhantomData<&'a mut VaListImpl<'f>>,
159+ }
160+
161+ impl<'f> VaListImpl<'f> {
162+ /// Converts a [`VaListImpl`] into a [`VaList`] that is binary-compatible with C's `va_list`.
163+ #[inline]
164+ pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> {
165+ VaList { inner: VaListImpl { ..*self }, _marker: PhantomData }
166+ }
167+ }
207168 }
208169}
209170
0 commit comments