fn_ptr/
abi.rs

1use crate::AbiValue;
2
3/// Type-level marker trait for function abi.
4///
5/// Types implementing this trait represent a specific `extern "..."` abi.
6///
7/// See [`Abi`] for the runtime representation.
8pub trait Abi {
9    /// The exact abi string used in `extern "..."`.
10    const STR: &'static str;
11
12    /// The runtime [`Abi`] that represent this marker type.
13    const VALUE: AbiValue;
14
15    /// The runtime [`Abi`] that represent this marker type.
16    const ALLOWS_UNWIND: bool = Self::VALUE.allows_unwind();
17}
18
19/// Helper macro to implement [`Abi`].
20macro_rules! define_abi_marker {
21    ($name:ident, $lit:literal) => {
22        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23        #[doc = "Type-level marker for the `"]
24        #[doc = $lit]
25        #[doc = "` abi."]
26        pub struct $name;
27
28        impl Abi for $name {
29            const STR: &'static str = $lit;
30            const VALUE: AbiValue = AbiValue::from_str_const($lit).unwrap();
31        }
32    };
33}
34
35// Universal
36define_abi_marker!(C, "C");
37define_abi_marker!(CUnwind, "C-unwind");
38define_abi_marker!(System, "system");
39define_abi_marker!(SystemUnwind, "system-unwind");
40
41// Rust
42define_abi_marker!(Rust, "Rust");
43
44// ARM
45define_abi_marker!(Aapcs, "aapcs");
46define_abi_marker!(AapcsUnwind, "aapcs-unwind");
47
48// x86
49define_abi_marker!(Cdecl, "cdecl");
50define_abi_marker!(CdeclUnwind, "cdecl-unwind");
51define_abi_marker!(Stdcall, "stdcall");
52define_abi_marker!(StdcallUnwind, "stdcall-unwind");
53define_abi_marker!(Fastcall, "fastcall");
54define_abi_marker!(FastcallUnwind, "fastcall-unwind");
55define_abi_marker!(Thiscall, "thiscall");
56define_abi_marker!(ThiscallUnwind, "thiscall-unwind");
57define_abi_marker!(Vectorcall, "vectorcall");
58define_abi_marker!(VectorcallUnwind, "vectorcall-unwind");
59
60// x86_64
61define_abi_marker!(SysV64, "sysv64");
62define_abi_marker!(SysV64Unwind, "sysv64-unwind");
63define_abi_marker!(Win64, "win64");
64define_abi_marker!(Win64Unwind, "win64-unwind");
65
66// Other
67define_abi_marker!(EfiApi, "efiapi");
68
69/// Macro to convert an abi string to the corresponding [`Abi`] marker type.
70#[macro_export]
71macro_rules! abi {
72    // Common
73    ("Rust") => {
74        $crate::abi::Rust
75    };
76    ("C") => {
77        $crate::abi::C
78    };
79    ("C-unwind") => {
80        $crate::abi::CUnwind
81    };
82    ("system") => {
83        $crate::abi::System
84    };
85    ("system-unwind") => {
86        $crate::abi::SystemUnwind
87    };
88
89    // ARM
90    ("aapcs") => {
91        $crate::abi::Aapcs
92    };
93    ("aapcs-unwind") => {
94        $crate::abi::AapcsUnwind
95    };
96
97    // x86
98    ("cdecl") => {
99        $crate::abi::Cdecl
100    };
101    ("cdecl-unwind") => {
102        $crate::abi::CdeclUnwind
103    };
104    ("stdcall") => {
105        $crate::abi::Stdcall
106    };
107    ("stdcall-unwind") => {
108        $crate::abi::StdcallUnwind
109    };
110    ("fastcall") => {
111        $crate::abi::Fastcall
112    };
113    ("fastcall-unwind") => {
114        $crate::abi::FastcallUnwind
115    };
116    ("thiscall") => {
117        $crate::abi::Thiscall
118    };
119    ("thiscall-unwind") => {
120        $crate::abi::ThiscallUnwind
121    };
122    ("vectorcall") => {
123        $crate::abi::Vectorcall
124    };
125    ("vectorcall-unwind") => {
126        $crate::abi::VectorcallUnwind
127    };
128
129    // x86_64
130    ("sysv64") => {
131        $crate::abi::SysV64
132    };
133    ("sysv64-unwind") => {
134        $crate::abi::SysV64Unwind
135    };
136    ("win64") => {
137        $crate::abi::Win64
138    };
139    ("win64-unwind") => {
140        $crate::abi::Win64Unwind
141    };
142
143    // Other
144    ("efiapi") => {
145        $crate::abi::EfiApi
146    };
147}