From df65599b1f95852192c66adb15da073d5ee280f8 Mon Sep 17 00:00:00 2001 From: Putta Khunchalee Date: Thu, 17 Oct 2024 23:51:40 +0700 Subject: [PATCH] Adds cppbind::type_info::align --- cppbind.hpp | 4 +++- macros/src/cpp.rs | 16 ++++++++++++++-- macros/src/meta.rs | 6 ++++++ macros/src/meta/ty.rs | 1 + 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cppbind.hpp b/cppbind.hpp index 5878097..3c110b2 100644 --- a/cppbind.hpp +++ b/cppbind.hpp @@ -5,12 +5,14 @@ #include #define CPPBIND_CLASS(n) \ - template<> const size_t cppbind::type_info::size = sizeof(n) + template<> const size_t cppbind::type_info::size = sizeof(n); \ + template<> const size_t cppbind::type_info::align = alignof(n) namespace cppbind { template struct type_info { static const size_t size; + static const size_t align; }; } diff --git a/macros/src/cpp.rs b/macros/src/cpp.rs index 82239bd..e3840c3 100644 --- a/macros/src/cpp.rs +++ b/macros/src/cpp.rs @@ -1,6 +1,6 @@ use self::class::Class; use crate::META; -use proc_macro2::TokenStream; +use proc_macro2::{Literal, TokenStream}; use quote::{format_ident, quote}; use syn::parse::{Parse, ParseStream}; use syn::Error; @@ -46,6 +46,17 @@ fn render_class(item: Class) -> syn::Result { } }; + // Get alignment. + let align = match meta.align { + Some(v) => v, + None => { + return Err(Error::new_spanned( + class, + format_args!("cppbind::type_info<{name}>::align not found"), + )) + } + }; + // Render constructors. let mut impls = TokenStream::new(); @@ -63,6 +74,7 @@ fn render_class(item: Class) -> syn::Result { } // Compose. + let align = Literal::usize_unsuffixed(align); let mem = if name.chars().next().unwrap().is_uppercase() { format_ident!("{name}Memory") } else { @@ -81,7 +93,7 @@ fn render_class(item: Class) -> syn::Result { } #[allow(non_camel_case_types)] - #[repr(transparent)] + #[repr(C, align(#align))] pub struct #mem([::std::mem::MaybeUninit; #size]); impl #mem { diff --git a/macros/src/meta.rs b/macros/src/meta.rs index e461310..065bc19 100644 --- a/macros/src/meta.rs +++ b/macros/src/meta.rs @@ -158,6 +158,12 @@ impl Metadata { .map(|v| usize::from_ne_bytes(v.try_into().unwrap())) .ok_or_else(|| SymbolError::GetDataFailed(index)) .map(Some)?; + } else if *ty == Segment::Ident("align".into()) { + info.align = section + .get(off..(off + len)) + .map(|v| usize::from_ne_bytes(v.try_into().unwrap())) + .ok_or_else(|| SymbolError::GetDataFailed(index)) + .map(Some)?; } else { return Err(SymbolError::UnknownCppbindSymbol); } diff --git a/macros/src/meta/ty.rs b/macros/src/meta/ty.rs index 114d4f1..71a3f0d 100644 --- a/macros/src/meta/ty.rs +++ b/macros/src/meta/ty.rs @@ -2,4 +2,5 @@ #[derive(Default)] pub struct TypeInfo { pub size: Option, + pub align: Option, }