@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
22
33use serde_json:: Value as JsonValue ;
44
5- use crate :: { AbiFromJsonErr , ArmCall , CanonAbi , ExternAbi , InterruptKind } ;
5+ use crate :: { AbiFromJsonErr , ArmCall , CanonAbi , ExternAbi , InterruptKind , X86Call } ;
66
77#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
88pub struct AbiMap {
@@ -15,14 +15,16 @@ pub struct AbiMap {
1515 /// ABI used for `extern "rust-cold"`
1616 pub rust_cold : CanonAbi ,
1717
18- // optional abstract ABIs
18+ // optional architecture-specific ABIs, should always answer a certain way per-arch
1919 pub efiapi : Option < CanonAbi > ,
20+ pub win64 : Option < CanonAbi > ,
21+ pub sysv64 : Option < CanonAbi > ,
22+
23+ // optional abstract ABIs, these can be very weird
2024 pub stdcall : Option < CanonAbi > ,
2125 pub fastcall : Option < CanonAbi > ,
2226 pub thiscall : Option < CanonAbi > ,
2327 pub vectorcall : Option < CanonAbi > ,
24- pub win64 : Option < CanonAbi > ,
25- pub sysv64 : Option < CanonAbi > ,
2628
2729 // optional concrete ABIs
2830 // arm
@@ -204,6 +206,51 @@ impl AbiMap {
204206 }
205207}
206208
209+ // construction
210+
211+ impl AbiMap {
212+ pub fn base_for_arch ( arch : & str ) -> AbiMap {
213+ match arch {
214+ "aarch64" => AbiMap { efiapi : Some ( CanonAbi :: C ) , ..Default :: default ( ) } ,
215+ "amdgpu" => AbiMap { gpu_kernel : true , ..Default :: default ( ) } ,
216+ "arm" => AbiMap {
217+ aapcs : true ,
218+ efiapi : Some ( CanonAbi :: Arm ( ArmCall :: Aapcs ) ) ,
219+ ..Default :: default ( )
220+ } ,
221+ "avr" => AbiMap { avr_interrupt : true , ..Default :: default ( ) } ,
222+ "msp430" => AbiMap { msp430_interrupt : true , ..Default :: default ( ) } ,
223+ "nvptx64" => AbiMap { ptx_kernel : true , gpu_kernel : true , ..Default :: default ( ) } ,
224+ "riscv32" | "riscv64" => {
225+ AbiMap { efiapi : Some ( CanonAbi :: C ) , riscv_interrupt : true , ..Default :: default ( ) }
226+ }
227+ "x86" => {
228+ AbiMap {
229+ efiapi : Some ( CanonAbi :: C ) ,
230+ x86_interrupt : true ,
231+
232+ //FIXME(jubilee): it seems unlikely we want this?
233+ vectorcall : Some ( CanonAbi :: X86 ( X86Call :: Vectorcall ) ) ,
234+
235+ ..Default :: default ( )
236+ }
237+ }
238+ "x86_64" => AbiMap {
239+ efiapi : Some ( CanonAbi :: X86 ( X86Call :: Win64 ) ) ,
240+ sysv64 : Some ( CanonAbi :: X86 ( X86Call :: SysV64 ) ) ,
241+ win64 : Some ( CanonAbi :: X86 ( X86Call :: Win64 ) ) ,
242+ x86_interrupt : true ,
243+
244+ //FIXME(jubilee): it seems unlikely we want this?
245+ vectorcall : Some ( CanonAbi :: X86 ( X86Call :: Vectorcall ) ) ,
246+
247+ ..Default :: default ( )
248+ } ,
249+ _ => Default :: default ( ) ,
250+ }
251+ }
252+ }
253+
207254// deserialization
208255
209256type JsonObject = serde_json:: Map < String , JsonValue > ;
@@ -241,31 +288,19 @@ fn extract_bool_abi(
241288}
242289
243290impl AbiMap {
244- pub fn from_json_object (
291+ pub fn from_arch_and_json (
292+ arch : & str ,
245293 mut json : JsonObject ,
246- ) -> Result < Self , BTreeMap < String , AbiFromJsonErr > > {
294+ ) -> ( Self , BTreeMap < String , AbiFromJsonErr > ) {
247295 // extract all keys we are interested in
248296 let required_c_abis =
249297 [ "C" , "system" , "system-varargs" ] . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
250298 let rust_cold = extract_abi_str ( & mut json, "rust-cold" ) ;
251- let bool_abis = [
252- // arm...
253- "aapcs" ,
254- "cmse-nonsecure-entry" ,
255- // ...gpu...
256- "gpu-kernel" ,
257- "ptx-kernel" ,
258- // ...interrupt
259- "avr-interrupt" ,
260- "msp430-interrupt" ,
261- "riscv-interrupt" ,
262- "x86-interrupt" ,
263- ]
264- . map ( |abi_str| extract_bool_abi ( & mut json, abi_str) ) ;
265- // x86ish
266- let optional_abis =
267- [ "efiapi" , "stdcall" , "fastcall" , "thiscall" , "vectorcall" , "win64" , "sysv64" ]
268- . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
299+ let bool_abis =
300+ [ "aapcs" , "cmse-nonsecure-entry" ] . map ( |abi_str| extract_bool_abi ( & mut json, abi_str) ) ;
301+ // x86ish optional ABIs
302+ let optional_abis = [ "stdcall" , "fastcall" , "thiscall" , "vectorcall" ]
303+ . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
269304
270305 // accumulate errors
271306 // create an iterator of invalid types and bad parses
@@ -283,28 +318,22 @@ impl AbiMap {
283318 . chain ( errs. cloned ( ) )
284319 . collect :: < BTreeMap < _ , _ > > ( ) ;
285320
286- if error_map. len ( ) > 0 {
287- Err ( error_map)
288- } else {
289- // oh? success? merry giftmas! time to unwrap your presents
290- // these have default ABIs to select
291- let [ c_proper, system, system_varargs] =
292- required_c_abis. map ( |result| result. unwrap ( ) . unwrap_or ( CanonAbi :: C ) ) ;
293- let rust_cold = rust_cold. unwrap ( ) . unwrap_or ( CanonAbi :: RustCold ) ;
294-
295- // these stay options, but shell the Result
296- let [ efiapi, stdcall, fastcall, thiscall, vectorcall, win64, sysv64] =
297- optional_abis. map ( |result| result. unwrap ( ) ) ;
298-
299- // these simplify to booleans
300- let bool_abis = bool_abis. map ( |result| result. unwrap ( ) . unwrap_or ( false ) ) ;
301- // repeat the mantra: arm...
302- let [ aapcs, cmse_nonsecure_entry, bool_abis @ ..] = bool_abis;
303- // ...gpu...
304- let [ gpu_kernel, ptx_kernel, bool_abis @ ..] = bool_abis;
305- // ...interrupt
306- let [ avr_interrupt, msp430_interrupt, riscv_interrupt, x86_interrupt] = bool_abis;
307- Ok ( AbiMap {
321+ // oh? success? merry giftmas! time to unwrap your presents
322+ // start with the architectural defaults
323+ let arch_map = AbiMap :: base_for_arch ( arch) ;
324+ // these have default ABIs to select
325+ let [ c_proper, system, system_varargs] =
326+ required_c_abis. map ( |result| result. unwrap ( ) . unwrap_or ( CanonAbi :: C ) ) ;
327+ let rust_cold = rust_cold. unwrap ( ) . unwrap_or ( CanonAbi :: RustCold ) ;
328+
329+ // these stay options, but shell the Result
330+ let [ stdcall, fastcall, thiscall, vectorcall] = optional_abis. map ( |result| result. unwrap ( ) ) ;
331+
332+ // these simplify to booleans
333+ let bool_abis = bool_abis. map ( |result| result. unwrap ( ) . unwrap_or ( false ) ) ;
334+ let [ aapcs, cmse_nonsecure_entry] = bool_abis;
335+ (
336+ AbiMap {
308337 c_proper,
309338 system,
310339 system_varargs,
@@ -314,26 +343,16 @@ impl AbiMap {
314343 aapcs,
315344 cmse_nonsecure_entry,
316345
317- // ...gpu...
318- gpu_kernel,
319- ptx_kernel,
320-
321- // ...interrupt
322- avr_interrupt,
323- msp430_interrupt,
324- riscv_interrupt,
325- x86_interrupt,
326-
327346 // x86-ish
328- efiapi,
329347 stdcall,
330348 fastcall,
331349 thiscall,
332350 vectorcall,
333- win64,
334- sysv64,
335- } )
336- }
351+
352+ ..arch_map
353+ } ,
354+ error_map,
355+ )
337356 }
338357
339358 // serialization
0 commit comments