forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathabi.rs
125 lines (108 loc) · 3.68 KB
/
abi.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use std::fmt;
use rustc_macros::HashStable_Generic;
#[cfg(test)]
mod tests;
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)]
#[derive(HashStable_Generic)]
pub enum Abi {
// N.B., this ordering MUST match the AbiDatas array below.
// (This is ensured by the test indices_are_correct().)
// Multiplatform / generic ABIs
//
// These ABIs come first because every time we add a new ABI, we
// have to re-bless all the hashing tests. These are used in many
// places, so giving them stable values reduces test churn. The
// specific values are meaningless.
Rust = 0,
C = 1,
// Single platform ABIs
Cdecl,
Stdcall,
Fastcall,
Vectorcall,
Thiscall,
Aapcs,
Win64,
SysV64,
PtxKernel,
Msp430Interrupt,
X86Interrupt,
AmdGpuKernel,
EfiApi,
AvrInterrupt,
AvrNonBlockingInterrupt,
// Multiplatform / generic ABIs
System,
RustIntrinsic,
RustCall,
PlatformIntrinsic,
Unadjusted,
}
#[derive(Copy, Clone)]
pub struct AbiData {
abi: Abi,
/// Name of this ABI as we like it called.
name: &'static str,
/// A generic ABI is supported on all platforms.
generic: bool,
}
#[allow(non_upper_case_globals)]
const AbiDatas: &[AbiData] = &[
// Cross-platform ABIs
AbiData { abi: Abi::Rust, name: "Rust", generic: true },
AbiData { abi: Abi::C, name: "C", generic: true },
// Platform-specific ABIs
AbiData { abi: Abi::Cdecl, name: "cdecl", generic: false },
AbiData { abi: Abi::Stdcall, name: "stdcall", generic: false },
AbiData { abi: Abi::Fastcall, name: "fastcall", generic: false },
AbiData { abi: Abi::Vectorcall, name: "vectorcall", generic: false },
AbiData { abi: Abi::Thiscall, name: "thiscall", generic: false },
AbiData { abi: Abi::Aapcs, name: "aapcs", generic: false },
AbiData { abi: Abi::Win64, name: "win64", generic: false },
AbiData { abi: Abi::SysV64, name: "sysv64", generic: false },
AbiData { abi: Abi::PtxKernel, name: "ptx-kernel", generic: false },
AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false },
AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false },
AbiData { abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false },
AbiData { abi: Abi::EfiApi, name: "efiapi", generic: false },
AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt", generic: false },
AbiData {
abi: Abi::AvrNonBlockingInterrupt,
name: "avr-non-blocking-interrupt",
generic: false,
},
// Cross-platform ABIs
AbiData { abi: Abi::System, name: "system", generic: true },
AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true },
AbiData { abi: Abi::RustCall, name: "rust-call", generic: true },
AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic", generic: true },
AbiData { abi: Abi::Unadjusted, name: "unadjusted", generic: true },
];
/// Returns the ABI with the given name (if any).
pub fn lookup(name: &str) -> Option<Abi> {
AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
}
pub fn all_names() -> Vec<&'static str> {
AbiDatas.iter().map(|d| d.name).collect()
}
impl Abi {
#[inline]
pub fn index(self) -> usize {
self as usize
}
#[inline]
pub fn data(self) -> &'static AbiData {
&AbiDatas[self.index()]
}
pub fn name(self) -> &'static str {
self.data().name
}
pub fn generic(self) -> bool {
self.data().generic
}
}
impl fmt::Display for Abi {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\"{}\"", self.name())
}
}