Skip to content

Commit

Permalink
Add support for calling conventions (#1999)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr committed Sep 2, 2022
1 parent 4cb707a commit 6b5ab01
Show file tree
Hide file tree
Showing 266 changed files with 52,574 additions and 1,710 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Expand Up @@ -140,6 +140,7 @@ jobs:
cargo clippy -p test_arch_feature &&
cargo clippy -p test_bcrypt &&
cargo clippy -p test_bstr &&
cargo clippy -p test_calling_convention &&
cargo clippy -p test_cfg_generic &&
cargo clippy -p test_class_factory &&
cargo clippy -p test_component &&
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Expand Up @@ -123,6 +123,7 @@ jobs:
cargo test --target ${{ matrix.target }} -p test_arch_feature &&
cargo test --target ${{ matrix.target }} -p test_bcrypt &&
cargo test --target ${{ matrix.target }} -p test_bstr &&
cargo test --target ${{ matrix.target }} -p test_calling_convention &&
cargo test --target ${{ matrix.target }} -p test_cfg_generic &&
cargo test --target ${{ matrix.target }} -p test_class_factory &&
cargo test --target ${{ matrix.target }} -p test_component &&
Expand Down
39 changes: 29 additions & 10 deletions crates/libs/bindgen/src/functions.rs
Expand Up @@ -26,10 +26,15 @@ fn gen_sys_function(gen: &Gen, def: MethodDef) -> TokenStream {
quote! { #name: #tokens }
});

let calling_convention = calling_convention(gen, def);

quote! {
#doc
#features
pub fn #name(#(#params),*) #return_type;
#[cfg_attr(windows, link(name = "windows"))]
extern #calling_convention {
#doc
#features
pub fn #name(#(#params),*) #return_type;
}
}
}

Expand Down Expand Up @@ -64,6 +69,7 @@ fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
let cfg = gen.reader.signature_cfg(&signature);
let doc = gen.cfg_doc(&cfg);
let features = gen.cfg_features(&cfg);
let calling_convention = calling_convention(gen, def);

let kind = gen.reader.signature_kind(&signature);
match kind {
Expand All @@ -79,7 +85,7 @@ fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
#[inline]
pub unsafe fn #name<#generics>(#params) -> ::windows::core::Result<T> #where_clause {
#link_attr
extern "system" {
extern #calling_convention {
fn #name(#(#abi_params),*) #abi_return_type;
}
let mut result__ = ::core::option::Option::None;
Expand All @@ -99,7 +105,7 @@ fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
#[inline]
pub unsafe fn #name<#generics>(#params result__: *mut ::core::option::Option<T>) -> ::windows::core::Result<()> #where_clause {
#link_attr
extern "system" {
extern #calling_convention {
fn #name(#(#abi_params),*) #abi_return_type;
}
#name(#args).ok()
Expand All @@ -119,7 +125,7 @@ fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
#[inline]
pub unsafe fn #name<#generics>(#params) -> ::windows::core::Result<#return_type_tokens> #where_clause {
#link_attr
extern "system" {
extern #calling_convention {
fn #name(#(#abi_params),*) #abi_return_type;
}
let mut result__ = ::core::mem::MaybeUninit::zeroed();
Expand All @@ -137,7 +143,7 @@ fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
#[inline]
pub unsafe fn #name<#generics>(#params) -> ::windows::core::Result<()> #where_clause {
#link_attr
extern "system" {
extern #calling_convention {
fn #name(#(#abi_params),*) #abi_return_type;
}
#name(#args).ok()
Expand All @@ -156,7 +162,7 @@ fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
#[inline]
pub unsafe fn #name<#generics>(#params) -> ::windows::core::Result<#return_type> #where_clause {
#link_attr
extern "system" {
extern #calling_convention {
fn #name(#(#abi_params),*) -> #return_type;
}
let result__ = #name(#args);
Expand All @@ -173,7 +179,7 @@ fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
#[inline]
pub unsafe fn #name<#generics>(#params) #abi_return_type #where_clause {
#link_attr
extern "system" {
extern #calling_convention {
fn #name(#(#abi_params),*) #abi_return_type;
}
#name(#args)
Expand All @@ -192,7 +198,7 @@ fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
#[inline]
pub unsafe fn #name<#generics>(#params) #does_not_return #where_clause {
#link_attr
extern "system" {
extern #calling_convention {
fn #name(#(#abi_params),*) #does_not_return;
}
#name(#args)
Expand Down Expand Up @@ -227,3 +233,16 @@ fn handle_last_error(gen: &Gen, def: MethodDef, signature: &Signature) -> bool {
}
false
}

fn calling_convention(gen: &Gen, def: MethodDef) -> &'static str {
let impl_map = gen.reader.method_def_impl_map(def).expect("ImplMap not found");
let flags = gen.reader.impl_map_flags(impl_map);

if flags.conv_platform() {
"system"
} else if flags.conv_cdecl() {
"cdecl"
} else {
unimplemented!()
}
}
5 changes: 1 addition & 4 deletions crates/libs/bindgen/src/lib.rs
Expand Up @@ -80,10 +80,7 @@ pub fn namespace(gen: &Gen, tree: &Tree) -> String {
if !methods.is_empty() {
let methods = methods.values();
functions = vec![quote! {
#[cfg_attr(windows, link(name = "windows"))]
extern "system" {
#(#methods)*
}
#(#methods)*
}];
}
}
Expand Down
15 changes: 15 additions & 0 deletions crates/libs/metadata/src/flags.rs
Expand Up @@ -52,6 +52,21 @@ impl PInvokeAttributes {
pub fn last_error(&self) -> bool {
self.0 & 0x40 != 0
}
pub fn conv_platform(&self) -> bool {
self.0 & 0x100 != 0
}
pub fn conv_cdecl(&self) -> bool {
self.0 & 0x200 != 0
}
pub fn conv_stdcall(&self) -> bool {
self.0 & 0x300 != 0
}
pub fn conv_thiscall(&self) -> bool {
self.0 & 0x400 != 0
}
pub fn conv_fastcall(&self) -> bool {
self.0 & 0x500 != 0
}
}

impl TypeAttributes {
Expand Down
30 changes: 28 additions & 2 deletions crates/libs/metadata/src/reader/mod.rs
Expand Up @@ -595,20 +595,46 @@ impl<'a> Reader<'a> {
if self.type_def_flags(def).explicit_layout() {
self.type_def_fields(def).map(|field| self.type_size(&self.field_type(field, Some(def)))).max().unwrap_or(1)
} else {
self.type_def_fields(def).fold(0, |sum, field| sum + self.type_size(&self.field_type(field, Some(def))))
let mut sum = 0;
for field in self.type_def_fields(def) {
let size = self.type_size(&self.field_type(field, Some(def)));
let align = self.type_align(&self.field_type(field, Some(def)));
sum = (sum + (align - 1)) & !(align - 1);
sum += size;
}
sum
}
}
TypeKind::Enum => self.type_size(&self.type_def_underlying_type(def)),
_ => 4,
}
}
pub fn type_size(&self, ty: &Type) -> usize {
fn type_size(&self, ty: &Type) -> usize {
match ty {
Type::I8 | Type::U8 => 1,
Type::I16 | Type::U16 => 2,
Type::I64 | Type::U64 | Type::F64 => 8,
Type::GUID => 16,
Type::TypeDef((def, _)) => self.type_def_size(*def),
Type::Win32Array((ty, len)) => self.type_size(ty) * len,
_ => 4,
}
}
fn type_def_align(&self, def: TypeDef) -> usize {
match self.type_def_kind(def) {
TypeKind::Struct => self.type_def_fields(def).map(|field| self.type_align(&self.field_type(field, Some(def)))).max().unwrap_or(1),
TypeKind::Enum => self.type_align(&self.type_def_underlying_type(def)),
_ => 4,
}
}
fn type_align(&self, ty: &Type) -> usize {
match ty {
Type::I8 | Type::U8 => 1,
Type::I16 | Type::U16 => 2,
Type::I64 | Type::U64 | Type::F64 => 8,
Type::GUID => 4,
Type::TypeDef((def, _)) => self.type_def_align(*def),
Type::Win32Array((ty, len)) => self.type_align(ty) * len,
_ => 4,
}
}
Expand Down
Expand Up @@ -3,6 +3,9 @@ extern "system" {
#[doc = "*Required features: `\"Win32_AI_MachineLearning_DirectML\"`, `\"Win32_Graphics_Direct3D12\"`*"]
#[cfg(feature = "Win32_Graphics_Direct3D12")]
pub fn DMLCreateDevice(d3d12device: super::super::super::Graphics::Direct3D12::ID3D12Device, flags: DML_CREATE_DEVICE_FLAGS, riid: *const ::windows_sys::core::GUID, ppv: *mut *mut ::core::ffi::c_void) -> ::windows_sys::core::HRESULT;
}
#[cfg_attr(windows, link(name = "windows"))]
extern "system" {
#[doc = "*Required features: `\"Win32_AI_MachineLearning_DirectML\"`, `\"Win32_Graphics_Direct3D12\"`*"]
#[cfg(feature = "Win32_Graphics_Direct3D12")]
pub fn DMLCreateDevice1(d3d12device: super::super::super::Graphics::Direct3D12::ID3D12Device, flags: DML_CREATE_DEVICE_FLAGS, minimumfeaturelevel: DML_FEATURE_LEVEL, riid: *const ::windows_sys::core::GUID, ppv: *mut *mut ::core::ffi::c_void) -> ::windows_sys::core::HRESULT;
Expand Down
Expand Up @@ -2,6 +2,9 @@
extern "system" {
#[doc = "*Required features: `\"Win32_AI_MachineLearning_WinML\"`*"]
pub fn MLCreateOperatorRegistry(registry: *mut IMLOperatorRegistry) -> ::windows_sys::core::HRESULT;
}
#[cfg_attr(windows, link(name = "windows"))]
extern "system" {
#[doc = "*Required features: `\"Win32_AI_MachineLearning_WinML\"`*"]
pub fn WinMLCreateRuntime(runtime: *mut IWinMLRuntime) -> ::windows_sys::core::HRESULT;
}
Expand Down

0 comments on commit 6b5ab01

Please sign in to comment.