Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More refactoring for COM support #1014

Merged
merged 9 commits into from
Jul 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
rust: stable
other: x86_64-pc-windows-msvc
- os: windows-latest
rust: 1.53.0
rust: 1.54.0
other: x86_64-pc-windows-msvc
- os: windows-latest
rust: nightly
Expand Down
88 changes: 82 additions & 6 deletions crates/gen/src/parser/method_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,32 @@ impl MethodSignature {
quote! { F: FnMut(#(#params),*) -> ::windows::Result<#return_type> + 'static }
}

pub fn gen_win32_abi(&self, gen: &Gen) -> TokenStream {
let params = self.params.iter().map(|p| {
let name = p.param.gen_name();
let tokens = p.gen_win32_abi_param(gen);
quote! { #name: #tokens }
});

let (udt_return_type, return_type) = if let Some(t) = &self.return_type {
if t.is_udt() {
let mut t = t.clone();
t.pointers += 1;
let tokens = t.gen_win32_abi(gen);
(quote! { result__: #tokens }, quote! {})
} else {
let tokens = t.gen_win32_abi(gen);
(quote! {}, quote! { -> #tokens })
}
} else {
(TokenStream::new(), TokenStream::new())
};

quote! {
(this: ::windows::RawPtr, #(#params,)* #udt_return_type) #return_type
}
}

// All WinRT ABI methods return an HRESULT while any return type is transformed into a trailing
// out parameter. This is unlike Win32 methods that don't require this transformation.
pub fn gen_winrt_abi(&self, gen: &Gen) -> TokenStream {
Expand Down Expand Up @@ -278,11 +304,11 @@ impl MethodSignature {

if param.signature.is_array {
if param.param.is_input() {
quote! { #name: &[<#tokens as ::windows::RuntimeType>::DefaultType], }
quote! { #name: &[<#tokens as ::windows::Abi>::DefaultType], }
} else if param.signature.by_ref {
quote! { #name: &mut ::windows::Array<#tokens>, }
} else {
quote! { #name: &mut [<#tokens as ::windows::RuntimeType>::DefaultType], }
quote! { #name: &mut [<#tokens as ::windows::Abi>::DefaultType], }
}
} else if param.param.is_input() {
if param.is_convertible() {
Expand All @@ -305,7 +331,7 @@ impl MethodSignature {
} else if param.signature.kind.is_nullable() {
quote! { #name: &mut ::std::option::Option<#tokens>, }
} else if let ElementType::GenericParam(_) = param.signature.kind {
quote! { &mut <#tokens as ::windows::RuntimeType>::DefaultType, }
quote! { &mut <#tokens as ::windows::Abi>::DefaultType, }
} else if param.signature.pointers > 0 {
let tokens = param.signature.gen_winrt_abi(gen);
quote! { #name: #tokens, }
Expand All @@ -316,6 +342,41 @@ impl MethodSignature {
.collect()
}

pub fn gen_win32_upcall(&self, inner: TokenStream, gen: &Gen) -> TokenStream {
let invoke_args = self
.params
.iter()
.map(|param| param.gen_win32_invoke_arg(gen));

if self.has_query_interface() {
quote! {
unimplemented!("one")
}
} else if self.has_retval() {
quote! {
unimplemented!("two")
}
} else if self.has_udt_return() {
quote! {
unimplemented!("three")
}
} else if let Some(return_type) = &self.return_type {
if return_type.kind == ElementType::HRESULT {
quote! {
#inner(#(#invoke_args,)*).into()
}
} else {
quote! {
unimplemented!("five")
}
}
} else {
quote! {
unimplemented!("six")
}
}
}

pub fn gen_winrt_upcall(&self, inner: TokenStream, gen: &Gen) -> TokenStream {
let invoke_args = self
.params
Expand Down Expand Up @@ -397,6 +458,21 @@ impl MethodParam {
self.signature.is_const || self.param.is_const()
}

fn gen_win32_invoke_arg(&self, gen: &Gen) -> TokenStream {
let name = self.param.gen_name();
let kind = self.signature.kind.gen_name(gen);

if self.param.is_input() {
if self.signature.kind.is_primitive() {
quote! { #name }
} else {
quote! { &*(&#name as *const <#kind as ::windows::Abi>::Abi as *const <#kind as ::windows::Abi>::DefaultType) }
}
} else {
quote! { ::std::mem::transmute_copy(&#name) }
}
}

fn gen_winrt_invoke_arg(&self, gen: &Gen) -> TokenStream {
let name = self.param.gen_name();
let kind = self.signature.kind.gen_name(gen);
Expand All @@ -410,9 +486,9 @@ impl MethodParam {
if self.signature.kind.is_primitive() {
quote! { #name }
} else if self.is_const() {
quote! { &*(#name as *const <#kind as ::windows::Abi>::Abi as *const <#kind as ::windows::RuntimeType>::DefaultType) }
quote! { &*(#name as *const <#kind as ::windows::Abi>::Abi as *const <#kind as ::windows::Abi>::DefaultType) }
} else {
quote! { &*(&#name as *const <#kind as ::windows::Abi>::Abi as *const <#kind as ::windows::RuntimeType>::DefaultType) }
quote! { &*(&#name as *const <#kind as ::windows::Abi>::Abi as *const <#kind as ::windows::Abi>::DefaultType) }
}
} else {
quote! { ::std::mem::transmute_copy(&#name) }
Expand Down Expand Up @@ -532,7 +608,7 @@ impl MethodParam {
}
} else if self.param.is_input() {
if let ElementType::GenericParam(_) = self.signature.kind {
quote! { &<#tokens as ::windows::RuntimeType>::DefaultType }
quote! { &<#tokens as ::windows::Abi>::DefaultType }
} else if self.signature.kind.is_primitive() {
quote! { #tokens }
} else if self.signature.kind.is_nullable() {
Expand Down
1 change: 1 addition & 0 deletions crates/gen/src/types/bool32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub fn gen_bool32() -> TokenStream {

unsafe impl ::windows::Abi for BOOL {
type Abi = Self;
type DefaultType = Self;
}
impl BOOL {
#[inline]
Expand Down
1 change: 1 addition & 0 deletions crates/gen/src/types/bstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ pub fn gen_bstr() -> TokenStream {
}
unsafe impl ::windows::Abi for BSTR {
type Abi = *mut u16;
type DefaultType = Self;

fn set_abi(&mut self) -> *mut *mut u16 {
debug_assert!(self.0.is_null());
Expand Down
2 changes: 0 additions & 2 deletions crates/gen/src/types/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ impl Class {
#(#factories)*
}
unsafe impl ::windows::RuntimeType for #name {
type DefaultType = ::std::option::Option<Self>;
const SIGNATURE: ::windows::ConstBuffer = ::windows::ConstBuffer::from_slice(#type_signature);
}
unsafe impl ::windows::Interface for #name {
Expand Down Expand Up @@ -226,7 +225,6 @@ impl Class {
const IID: ::windows::Guid = #guid;
}
unsafe impl ::windows::RuntimeType for #name {
type DefaultType = ::std::option::Option<Self>;
const SIGNATURE: ::windows::ConstBuffer = ::windows::ConstBuffer::from_slice(#type_signature);
}
}
Expand Down
28 changes: 1 addition & 27 deletions crates/gen/src/types/com_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,33 +44,7 @@ impl ComInterface {
.chain(std::iter::once(&self.0))
.map(|def| def.methods())
.flatten()
.map(|method| {
let signature = method.signature(&[]);

let params = signature.params.iter().map(|p| {
let name = p.param.gen_name();
let tokens = p.gen_win32_abi_param(gen);
quote! { #name: #tokens }
});

let (udt_return_type, return_type) = if let Some(t) = &signature.return_type {
if t.is_udt() {
let mut t = t.clone();
t.pointers += 1;
let tokens = t.gen_win32_abi(gen);
(quote! { result__: #tokens }, quote! {})
} else {
let tokens = t.gen_win32_abi(gen);
(quote! {}, quote! { -> #tokens })
}
} else {
(TokenStream::new(), TokenStream::new())
};

quote! {
(this: ::windows::RawPtr, #(#params,)* #udt_return_type) #return_type
}
});
.map(|method| method.signature(&[]).gen_win32_abi(gen));

let mut method_names = BTreeMap::<String, u32>::new();

Expand Down
1 change: 0 additions & 1 deletion crates/gen/src/types/delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ impl Delegate {
#invoke
}
unsafe impl<#constraints> ::windows::RuntimeType for #name {
type DefaultType = ::std::option::Option<Self>;
const SIGNATURE: ::windows::ConstBuffer = #type_signature;
}
unsafe impl<#constraints> ::windows::Interface for #name {
Expand Down
2 changes: 1 addition & 1 deletion crates/gen/src/types/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ impl Enum {

quote! {
unsafe impl ::windows::RuntimeType for #name {
type DefaultType = Self;
const SIGNATURE: ::windows::ConstBuffer = ::windows::ConstBuffer::from_slice(#signature);
}
}
Expand All @@ -123,6 +122,7 @@ impl Enum {
}
unsafe impl ::windows::Abi for #name {
type Abi = Self;
type DefaultType = Self;
}
#runtime_type
#bitwise
Expand Down
2 changes: 0 additions & 2 deletions crates/gen/src/types/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ impl Interface {
#async_get
}
unsafe impl<#constraints> ::windows::RuntimeType for #name {
type DefaultType = ::std::option::Option<Self>;
const SIGNATURE: ::windows::ConstBuffer = #type_signature;
}
#future
Expand Down Expand Up @@ -140,7 +139,6 @@ impl Interface {
const IID: ::windows::Guid = #guid;
}
unsafe impl<#constraints> ::windows::RuntimeType for #name {
type DefaultType = ::std::option::Option<Self>;
const SIGNATURE: ::windows::ConstBuffer = #type_signature;
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/gen/src/types/ntstatus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub fn gen_ntstatus() -> TokenStream {

unsafe impl ::windows::Abi for NTSTATUS {
type Abi = Self;
type DefaultType = Self;
}
}
}
1 change: 1 addition & 0 deletions crates/gen/src/types/pstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub fn gen_pstr() -> TokenStream {
}
unsafe impl ::windows::Abi for PSTR {
type Abi = Self;
type DefaultType = Self;

fn drop_param(param: &mut ::windows::Param<'_, Self>) {
if let ::windows::Param::Boxed(value) = param {
Expand Down
1 change: 1 addition & 0 deletions crates/gen/src/types/pwstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub fn gen_pwstr() -> TokenStream {
}
unsafe impl ::windows::Abi for PWSTR {
type Abi = Self;
type DefaultType = Self;

fn drop_param(param: &mut ::windows::Param<'_, Self>) {
if let ::windows::Param::Boxed(value) = param {
Expand Down
3 changes: 2 additions & 1 deletion crates/gen/src/types/struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ impl Struct {

quote! {
unsafe impl ::windows::RuntimeType for #name {
type DefaultType = Self;
const SIGNATURE: ::windows::ConstBuffer = ::windows::ConstBuffer::from_slice(#signature);
}
}
Expand Down Expand Up @@ -148,6 +147,7 @@ impl Struct {
quote! {
unsafe impl ::windows::Abi for #name {
type Abi = Self;
type DefaultType = Self;
}
}
} else {
Expand All @@ -174,6 +174,7 @@ impl Struct {
pub #struct_or_union #abi_name{ #fields }
unsafe impl ::windows::Abi for #name {
type Abi = #abi_name;
type DefaultType = Self;
}
}
};
Expand Down
Loading