]>
Commit | Line | Data |
---|---|---|
85aaf69f | 1 | // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT |
223e47cc LB |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
1a4d82fc JJ |
11 | use std::fmt; |
12 | ||
85aaf69f | 13 | #[derive(PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Clone, Copy, Debug)] |
223e47cc LB |
14 | pub enum Abi { |
15 | // NB: This ordering MUST match the AbiDatas array below. | |
16 | // (This is ensured by the test indices_are_correct().) | |
17 | ||
c30ab7b3 | 18 | // Single platform ABIs |
223e47cc LB |
19 | Cdecl, |
20 | Stdcall, | |
21 | Fastcall, | |
9cc50fc6 | 22 | Vectorcall, |
7cac9316 | 23 | Thiscall, |
223e47cc | 24 | Aapcs, |
1a4d82fc | 25 | Win64, |
9e0c209e | 26 | SysV64, |
32a655c1 SL |
27 | PtxKernel, |
28 | Msp430Interrupt, | |
8bb4bdeb | 29 | X86Interrupt, |
223e47cc | 30 | |
c30ab7b3 | 31 | // Multiplatform / generic ABIs |
223e47cc LB |
32 | Rust, |
33 | C, | |
1a4d82fc | 34 | System, |
223e47cc | 35 | RustIntrinsic, |
1a4d82fc | 36 | RustCall, |
e9174d1e | 37 | PlatformIntrinsic, |
32a655c1 | 38 | Unadjusted |
223e47cc LB |
39 | } |
40 | ||
c34b1796 | 41 | #[derive(Copy, Clone)] |
1a4d82fc | 42 | pub struct AbiData { |
223e47cc LB |
43 | abi: Abi, |
44 | ||
c30ab7b3 | 45 | /// Name of this ABI as we like it called. |
223e47cc | 46 | name: &'static str, |
223e47cc | 47 | |
c30ab7b3 SL |
48 | /// A generic ABI is supported on all platforms. |
49 | generic: bool, | |
223e47cc LB |
50 | } |
51 | ||
1a4d82fc | 52 | #[allow(non_upper_case_globals)] |
c34b1796 | 53 | const AbiDatas: &'static [AbiData] = &[ |
223e47cc | 54 | // Platform-specific ABIs |
c30ab7b3 SL |
55 | AbiData {abi: Abi::Cdecl, name: "cdecl", generic: false }, |
56 | AbiData {abi: Abi::Stdcall, name: "stdcall", generic: false }, | |
57 | AbiData {abi: Abi::Fastcall, name: "fastcall", generic: false }, | |
58 | AbiData {abi: Abi::Vectorcall, name: "vectorcall", generic: false}, | |
7cac9316 | 59 | AbiData {abi: Abi::Thiscall, name: "thiscall", generic: false}, |
c30ab7b3 SL |
60 | AbiData {abi: Abi::Aapcs, name: "aapcs", generic: false }, |
61 | AbiData {abi: Abi::Win64, name: "win64", generic: false }, | |
62 | AbiData {abi: Abi::SysV64, name: "sysv64", generic: false }, | |
32a655c1 SL |
63 | AbiData {abi: Abi::PtxKernel, name: "ptx-kernel", generic: false }, |
64 | AbiData {abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false }, | |
8bb4bdeb | 65 | AbiData {abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false }, |
223e47cc LB |
66 | |
67 | // Cross-platform ABIs | |
c30ab7b3 SL |
68 | AbiData {abi: Abi::Rust, name: "Rust", generic: true }, |
69 | AbiData {abi: Abi::C, name: "C", generic: true }, | |
70 | AbiData {abi: Abi::System, name: "system", generic: true }, | |
71 | AbiData {abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true }, | |
72 | AbiData {abi: Abi::RustCall, name: "rust-call", generic: true }, | |
73 | AbiData {abi: Abi::PlatformIntrinsic, name: "platform-intrinsic", generic: true }, | |
32a655c1 | 74 | AbiData {abi: Abi::Unadjusted, name: "unadjusted", generic: true }, |
223e47cc LB |
75 | ]; |
76 | ||
1a4d82fc | 77 | /// Returns the ABI with the given name (if any). |
223e47cc | 78 | pub fn lookup(name: &str) -> Option<Abi> { |
1a4d82fc | 79 | AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi) |
223e47cc LB |
80 | } |
81 | ||
1a4d82fc JJ |
82 | pub fn all_names() -> Vec<&'static str> { |
83 | AbiDatas.iter().map(|d| d.name).collect() | |
223e47cc LB |
84 | } |
85 | ||
970d7e83 | 86 | impl Abi { |
223e47cc | 87 | #[inline] |
85aaf69f SL |
88 | pub fn index(&self) -> usize { |
89 | *self as usize | |
223e47cc LB |
90 | } |
91 | ||
92 | #[inline] | |
970d7e83 | 93 | pub fn data(&self) -> &'static AbiData { |
223e47cc LB |
94 | &AbiDatas[self.index()] |
95 | } | |
96 | ||
970d7e83 | 97 | pub fn name(&self) -> &'static str { |
223e47cc LB |
98 | self.data().name |
99 | } | |
c30ab7b3 SL |
100 | |
101 | pub fn generic(&self) -> bool { | |
102 | self.data().generic | |
103 | } | |
223e47cc LB |
104 | } |
105 | ||
85aaf69f | 106 | impl fmt::Display for Abi { |
1a4d82fc JJ |
107 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
108 | write!(f, "\"{}\"", self.name()) | |
223e47cc LB |
109 | } |
110 | } | |
111 | ||
1a4d82fc | 112 | #[allow(non_snake_case)] |
223e47cc LB |
113 | #[test] |
114 | fn lookup_Rust() { | |
115 | let abi = lookup("Rust"); | |
1a4d82fc | 116 | assert!(abi.is_some() && abi.unwrap().data().name == "Rust"); |
223e47cc LB |
117 | } |
118 | ||
119 | #[test] | |
120 | fn lookup_cdecl() { | |
121 | let abi = lookup("cdecl"); | |
1a4d82fc | 122 | assert!(abi.is_some() && abi.unwrap().data().name == "cdecl"); |
223e47cc LB |
123 | } |
124 | ||
125 | #[test] | |
126 | fn lookup_baz() { | |
127 | let abi = lookup("baz"); | |
128 | assert!(abi.is_none()); | |
129 | } | |
130 | ||
223e47cc LB |
131 | #[test] |
132 | fn indices_are_correct() { | |
1a4d82fc JJ |
133 | for (i, abi_data) in AbiDatas.iter().enumerate() { |
134 | assert_eq!(i, abi_data.abi.index()); | |
223e47cc | 135 | } |
223e47cc | 136 | } |