Skip to content

Commit

Permalink
Calculate type signatures at compile time (#2729)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Dec 7, 2023
1 parent 44eadca commit 8e71051
Show file tree
Hide file tree
Showing 296 changed files with 3,709 additions and 3,671 deletions.
53 changes: 25 additions & 28 deletions crates/libs/bindgen/src/rust/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,42 +639,39 @@ impl Writer {
pub fn interface_winrt_trait(&self, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, features: &TokenStream) -> TokenStream {
if def.flags().contains(TypeAttributes::WindowsRuntime) {
let type_signature = if def.kind() == TypeKind::Class {
let type_signature = Literal::byte_string(type_def_signature(def, generics).as_bytes());
quote! { ::windows_core::imp::ConstBuffer::from_slice(#type_signature) }
quote! { ::windows_core::imp::ConstBuffer::for_class::<Self>() }
} else if generics.is_empty() {
quote! { ::windows_core::imp::ConstBuffer::for_interface::<Self>() }
} else {
let signature = Literal::byte_string(
// TODO: workaround for riddle winmd generation (no attribute support)
if let Some(guid) = type_def_guid(def) { format!("{{{:#?}}}", guid) } else { "TODO".to_string() }.as_bytes(),
);

if generics.is_empty() {
quote! { ::windows_core::imp::ConstBuffer::from_slice(#signature) }
} else {
let generics = generics.iter().enumerate().map(|(index, g)| {
let g = self.type_name(g);
let semi = if index != generics.len() - 1 {
Some(quote! {
.push_slice(b";")
})
} else {
None
};

quote! {
.push_other(<#g as ::windows_core::RuntimeType>::SIGNATURE)
#semi
}
});
let generics = generics.iter().enumerate().map(|(index, g)| {
let g = self.type_name(g);
let semi = if index != generics.len() - 1 {
Some(quote! {
.push_slice(b";")
})
} else {
None
};

quote! {
{
::windows_core::imp::ConstBuffer::new()
.push_slice(b"pinterface(")
.push_slice(#signature)
.push_slice(b";")
#(#generics)*
.push_slice(b")")
}
.push_other(<#g as ::windows_core::RuntimeType>::SIGNATURE)
#semi
}
});

quote! {
{
::windows_core::imp::ConstBuffer::new()
.push_slice(b"pinterface(")
.push_slice(#signature)
.push_slice(b";")
#(#generics)*
.push_slice(b")")
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions crates/libs/core/src/imp/com_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ impl IPropertyValue {
}
::windows_core::imp::interface_hierarchy!(IPropertyValue, ::windows_core::IUnknown, ::windows_core::IInspectable);
impl ::windows_core::RuntimeType for IPropertyValue {
const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"{4bd682dd-7554-40e9-9a9b-82654ede7e62}");
const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::for_interface::<Self>();
}
unsafe impl ::windows_core::Interface for IPropertyValue {
type Vtable = IPropertyValue_Vtbl;
Expand Down Expand Up @@ -856,7 +856,7 @@ impl IStringable {
}
::windows_core::imp::interface_hierarchy!(IStringable, ::windows_core::IUnknown, ::windows_core::IInspectable);
impl ::windows_core::RuntimeType for IStringable {
const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(b"{96369f54-8eb6-48f0-abce-c1b211e627c3}");
const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::for_interface::<Self>();
}
unsafe impl ::windows_core::Interface for IStringable {
type Vtable = IStringable_Vtbl;
Expand Down
48 changes: 44 additions & 4 deletions crates/libs/core/src/imp/sha1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ pub struct ConstBuffer {
}

impl ConstBuffer {
pub const fn for_class<T: crate::RuntimeName + crate::ComInterface>() -> Self {
Self::new().push_slice(b"rc(").push_slice(T::NAME.as_bytes()).push(b';').push_guid(&T::IID).push(b')')
}

pub const fn for_interface<T: crate::ComInterface>() -> Self {
Self::new().push_guid(&T::IID)
}

pub const fn from_slice(slice: &[u8]) -> Self {
let s = Self::new();
s.push_slice(slice)
Expand All @@ -37,12 +45,40 @@ impl ConstBuffer {
self.head
}

const fn as_slice(&self) -> &[u8] {
&self.data
pub fn as_slice(&self) -> &[u8] {
&self.data[..self.head]
}

pub const fn push_other(self, other: Self) -> Self {
self.push_amount(other.as_slice(), other.len())
self.push_amount(&other.data, other.len())
}

const fn push(mut self, value: u8) -> Self {
self.data[self.head] = value;
self.head += 1;
self
}

const fn push_hex_u8(self, value: u8) -> Self {
const fn digit(mut value: u8) -> u8 {
value &= 0xF;

if value < 10 {
b'0' + value
} else {
b'a' + (value - 10)
}
}

self.push(digit(value >> 4)).push(digit(value))
}

const fn push_hex_u16(self, value: u16) -> Self {
self.push_hex_u8((value >> 8) as u8).push_hex_u8((value & 0xFF) as u8)
}

const fn push_hex_u32(self, value: u32) -> Self {
self.push_hex_u16((value >> 16) as u16).push_hex_u16((value & 0xFFFF) as u16)
}

const fn push_amount(mut self, slice: &[u8], amount: usize) -> Self {
Expand All @@ -54,6 +90,10 @@ impl ConstBuffer {
self.head += i;
self
}

const fn push_guid(self, guid: &crate::GUID) -> Self {
self.push(b'{').push_hex_u32(guid.data1).push(b'-').push_hex_u16(guid.data2).push(b'-').push_hex_u16(guid.data3).push(b'-').push_hex_u16((guid.data4[0] as u16) << 8 | guid.data4[1] as u16).push(b'-').push_hex_u16((guid.data4[2] as u16) << 8 | guid.data4[3] as u16).push_hex_u16((guid.data4[4] as u16) << 8 | guid.data4[5] as u16).push_hex_u16((guid.data4[6] as u16) << 8 | guid.data4[7] as u16).push(b'}')
}
}

struct Blocks {
Expand Down Expand Up @@ -92,7 +132,7 @@ const fn process_blocks(mut blocks: Blocks, data: &ConstBuffer, mut len: u64, mu
i += 64;
} else {
let num_elems = data.len() - i;
blocks.data = clone_from_slice_64(blocks.data, data.as_slice(), i, num_elems);
blocks.data = clone_from_slice_64(blocks.data, &data.data, i, num_elems);
blocks.len = num_elems as u32;
break;
}
Expand Down
Loading

0 comments on commit 8e71051

Please sign in to comment.