Skip to content

Commit 244a88d

Browse files
authored
Add standalone code generation support for the Rust Standard Library (#2439)
1 parent 81b7b8c commit 244a88d

File tree

24 files changed

+300
-162
lines changed

24 files changed

+300
-162
lines changed

crates/libs/bindgen/src/constants.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,15 @@ pub fn gen(gen: &Gen, def: Field) -> TokenStream {
3939
} else {
4040
let kind = gen.type_default_name(&ty);
4141
let value = gen.value(&gen.reader.constant_value(constant));
42+
let underlying_type = gen.reader.type_underlying_type(&ty);
4243

43-
let value = if gen.reader.type_underlying_type(&ty) == constant_type {
44+
let value = if underlying_type == constant_type {
4445
value
4546
// TODO: workaround for https://github.com/microsoft/win32metadata/issues/1029
4647
} else if ty == Type::PCWSTR && value.0.starts_with('-') {
4748
quote! { #value as u16 as _ }
49+
} else if gen.std && underlying_type == Type::ISize {
50+
quote! { ::core::ptr::invalid_mut(#value as _) }
4851
} else {
4952
quote! { #value as _ }
5053
};

crates/libs/bindgen/src/functions.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,7 @@ fn gen_sys_function(gen: &Gen, def: MethodDef) -> TokenStream {
1616
let features = gen.cfg_features(&cfg);
1717
let return_type = gen.return_sig(&signature);
1818
let abi = gen.reader.method_def_extern_abi(def);
19-
let impl_map = gen
20-
.reader
21-
.method_def_impl_map(def)
22-
.expect("ImplMap not found");
23-
let scope = gen.reader.impl_map_scope(impl_map);
24-
let link = gen.reader.module_ref_name(scope).to_lowercase();
19+
let link = gen.reader.method_def_module_name(def);
2520

2621
// TODO: skip inline functions for now.
2722
if link == "forceinline" {
@@ -35,14 +30,26 @@ fn gen_sys_function(gen: &Gen, def: MethodDef) -> TokenStream {
3530
});
3631

3732
let mut tokens = features;
38-
tokens.combine(&gen_link(
39-
&link,
40-
abi,
41-
doc.as_str(),
42-
name.as_str(),
43-
params,
44-
return_type.as_str(),
45-
));
33+
34+
if gen.std {
35+
let link = link.trim_end_matches(".dll");
36+
tokens.combine(&quote! {
37+
#[link(name = #link)]
38+
extern #abi {
39+
pub fn #name(#(#params),*) #return_type;
40+
}
41+
});
42+
} else {
43+
tokens.combine(&gen_link(
44+
&link,
45+
abi,
46+
doc.as_str(),
47+
name.as_str(),
48+
params,
49+
return_type.as_str(),
50+
));
51+
}
52+
4653
tokens
4754
}
4855

@@ -96,12 +103,7 @@ fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
96103
}
97104
}
98105
} else {
99-
let impl_map = gen
100-
.reader
101-
.method_def_impl_map(def)
102-
.expect("ImplMap not found");
103-
let scope = gen.reader.impl_map_scope(impl_map);
104-
let link = gen.reader.module_ref_name(scope).to_lowercase();
106+
let link = gen.reader.method_def_module_name(def);
105107

106108
// TODO: skip inline functions for now.
107109
if link == "forceinline" {

crates/libs/bindgen/src/gen.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub struct Gen<'a> {
88
pub doc: bool,
99
pub component: bool,
1010
pub standalone: bool,
11+
pub std: bool,
1112
}
1213

1314
impl<'a> Gen<'a> {
@@ -20,6 +21,7 @@ impl<'a> Gen<'a> {
2021
doc: false,
2122
component: false,
2223
standalone: false,
24+
std: false,
2325
}
2426
}
2527

crates/libs/bindgen/src/handles.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,23 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
1010

1111
pub fn gen_sys_handle(gen: &Gen, def: TypeDef) -> TokenStream {
1212
let ident = to_ident(gen.reader.type_def_name(def));
13-
let signature = gen.type_default_name(&gen.reader.type_def_underlying_type(def));
13+
match gen.reader.type_def_underlying_type(def) {
14+
Type::ISize if gen.std => quote! {
15+
pub type #ident = *mut ::core::ffi::c_void;
16+
},
17+
Type::USize if gen.std => quote! {
18+
#[cfg(target_pointer_width = "32")]
19+
pub type #ident = u32;
20+
#[cfg(target_pointer_width = "64")]
21+
pub type #ident = u64;
22+
},
23+
underlying_type => {
24+
let signature = gen.type_default_name(&underlying_type);
1425

15-
quote! {
16-
pub type #ident = #signature;
26+
quote! {
27+
pub type #ident = #signature;
28+
}
29+
}
1730
}
1831
}
1932

0 commit comments

Comments
 (0)