1 | use super::*; |
2 | |
3 | #[doc (hidden)] |
4 | pub enum CallingConvention { |
5 | Stdcall(usize), |
6 | Cdecl, |
7 | } |
8 | |
9 | // Returns the libraries and their function and stack sizes used by the gnu and msvc tools to build the umbrella libs. |
10 | #[doc (hidden)] |
11 | pub fn libraries() -> BTreeMap<String, BTreeMap<String, CallingConvention>> { |
12 | let mut libraries: BTreeMap> = BTreeMap::new(); |
13 | |
14 | let reader: &'static Reader = Reader::new(files:expand_input(&["default" ])); |
15 | combine_libraries(reader, &mut libraries); |
16 | libraries |
17 | } |
18 | |
19 | fn combine_libraries( |
20 | reader: &Reader, |
21 | libraries: &mut BTreeMap<String, BTreeMap<String, CallingConvention>>, |
22 | ) { |
23 | for types in reader.values() { |
24 | for ty in types.values() { |
25 | let Some(ty) = cpp_fn(ty) else { |
26 | continue; |
27 | }; |
28 | |
29 | // Windows libs are always produced with lower case module names. |
30 | let library = ty.method.module_name().to_lowercase(); |
31 | let impl_map = ty.method.impl_map().unwrap(); |
32 | let flags = impl_map.flags(); |
33 | let name = impl_map.import_name().to_string(); |
34 | |
35 | if flags.contains(PInvokeAttributes::CallConvPlatformapi) { |
36 | let arches = ty.method.arches(); |
37 | let params = if (arches == 0) || (arches & 1 == 1) { |
38 | ty.method.signature(ty.namespace, &[]).size() |
39 | } else { |
40 | 0 |
41 | }; |
42 | |
43 | libraries |
44 | .entry(library) |
45 | .or_default() |
46 | .insert(name, CallingConvention::Stdcall(params)); |
47 | } else if flags.contains(PInvokeAttributes::CallConvCdecl) { |
48 | libraries |
49 | .entry(library) |
50 | .or_default() |
51 | .insert(name, CallingConvention::Cdecl); |
52 | } else { |
53 | panic!(); |
54 | } |
55 | } |
56 | } |
57 | } |
58 | |
59 | fn cpp_fn(types: &[Type]) -> Option<CppFn> { |
60 | let mut functions: Vec = vec![]; |
61 | |
62 | for ty: &Type in types { |
63 | if let Type::CppFn(ty: &CppFn) = ty { |
64 | functions.push(ty.clone()); |
65 | } |
66 | } |
67 | |
68 | for ty: &CppFn in &functions { |
69 | let arches: i32 = ty.method.arches(); |
70 | if (arches == 0) || (arches & 1 == 1) { |
71 | return Some(ty.clone()); |
72 | } |
73 | } |
74 | |
75 | functions.first().cloned() |
76 | } |
77 | |