1 // run-pass
2 #![allow(dead_code)]
3 // ignore-wasm32-bare no libc to test ffi with
4 
5 #[repr(C)]
6 #[derive(Copy, Clone)]
7 pub struct Quad {
8     a: u64,
9     b: u64,
10     c: u64,
11     d: u64,
12 }
13 
14 #[repr(C)]
15 #[derive(Copy, Clone)]
16 pub struct Floats {
17     a: f64,
18     b: u8,
19     c: f64,
20 }
21 
22 #[repr(C)]
23 #[derive(Copy, Clone)]
24 pub struct CharCharDouble {
25     a: u8,
26     b: u8,
27     c: f64,
28 }
29 
30 #[repr(C)]
31 #[derive(Copy, Clone)]
32 pub struct CharCharFloat {
33     a: u8,
34     b: u8,
35     c: f32,
36 }
37 
38 mod rustrt {
39     use super::{CharCharDouble, CharCharFloat, Floats, Quad};
40 
41     #[link(name = "rust_test_helpers", kind = "static")]
42     extern "C" {
rust_dbg_abi_1(q: Quad) -> Quad43         pub fn rust_dbg_abi_1(q: Quad) -> Quad;
rust_dbg_abi_2(f: Floats) -> Floats44         pub fn rust_dbg_abi_2(f: Floats) -> Floats;
rust_dbg_abi_3(a: CharCharDouble) -> CharCharDouble45         pub fn rust_dbg_abi_3(a: CharCharDouble) -> CharCharDouble;
rust_dbg_abi_4(a: CharCharFloat) -> CharCharFloat46         pub fn rust_dbg_abi_4(a: CharCharFloat) -> CharCharFloat;
47     }
48 }
49 
test1()50 fn test1() {
51     unsafe {
52         let q = Quad {
53             a: 0xaaaa_aaaa_aaaa_aaaa,
54             b: 0xbbbb_bbbb_bbbb_bbbb,
55             c: 0xcccc_cccc_cccc_cccc,
56             d: 0xdddd_dddd_dddd_dddd,
57         };
58         let qq = rustrt::rust_dbg_abi_1(q);
59         println!("a: {:x}", qq.a as usize);
60         println!("b: {:x}", qq.b as usize);
61         println!("c: {:x}", qq.c as usize);
62         println!("d: {:x}", qq.d as usize);
63         assert_eq!(qq.a, q.c + 1);
64         assert_eq!(qq.b, q.d - 1);
65         assert_eq!(qq.c, q.a + 1);
66         assert_eq!(qq.d, q.b - 1);
67     }
68 }
69 
70 #[cfg(target_pointer_width = "64")]
test2()71 fn test2() {
72     unsafe {
73         let f = Floats { a: 1.234567890e-15_f64, b: 0b_1010_1010, c: 1.0987654321e-15_f64 };
74         let ff = rustrt::rust_dbg_abi_2(f);
75         println!("a: {}", ff.a as f64);
76         println!("b: {}", ff.b as usize);
77         println!("c: {}", ff.c as f64);
78         assert_eq!(ff.a, f.c + 1.0f64);
79         assert_eq!(ff.b, 0xff);
80         assert_eq!(ff.c, f.a - 1.0f64);
81     }
82 }
83 
84 #[cfg(target_pointer_width = "32")]
test2()85 fn test2() {}
86 
87 #[cfg(target_pointer_width = "64")]
test3()88 fn test3() {
89     unsafe {
90         let a = CharCharDouble { a: 1, b: 2, c: 3. };
91         let b = rustrt::rust_dbg_abi_3(a);
92         println!("a: {}", b.a);
93         println!("b: {}", b.b);
94         println!("c: {}", b.c);
95         assert_eq!(b.a, a.a + 1);
96         assert_eq!(b.b, a.b - 1);
97         assert_eq!(b.c, a.c + 1.0);
98     }
99 }
100 
101 #[cfg(target_pointer_width = "32")]
test3()102 fn test3() {}
103 
test4()104 fn test4() {
105     unsafe {
106         let a = CharCharFloat { a: 1, b: 2, c: 3. };
107         let b = rustrt::rust_dbg_abi_4(a);
108         println!("a: {}", b.a);
109         println!("b: {}", b.b);
110         println!("c: {}", b.c);
111         assert_eq!(b.a, a.a + 1);
112         assert_eq!(b.b, a.b - 1);
113         assert_eq!(b.c, a.c + 1.0);
114     }
115 }
116 
main()117 pub fn main() {
118     test1();
119     test2();
120     test3();
121     test4();
122 }
123