@@ -35,6 +35,7 @@ pub struct CSharp {
3535 pub ( crate ) needs_rep_table : bool ,
3636 pub ( crate ) needs_wit_exception : bool ,
3737 pub ( crate ) needs_async_support : bool ,
38+ pub ( crate ) needs_align_stack_ptr : bool ,
3839 pub ( crate ) interface_fragments : HashMap < String , InterfaceTypeAndFragments > ,
3940 pub ( crate ) world_fragments : Vec < InterfaceFragment > ,
4041 pub ( crate ) sizes : SizeAlign ,
@@ -388,7 +389,7 @@ impl WorldGenerator for CSharp {
388389 let world = & resolve. worlds [ id] ;
389390 let world_namespace = self . qualifier ( ) ;
390391 let world_namespace = world_namespace. strip_suffix ( "." ) . unwrap ( ) ;
391- let namespace = format ! ( "{ world_namespace}" ) ;
392+ let namespace = world_namespace;
392393 let name = world. name . to_upper_camel_case ( ) ;
393394
394395 let version = env ! ( "CARGO_PKG_VERSION" ) ;
@@ -623,13 +624,28 @@ impl WorldGenerator for CSharp {
623624 src. push_str ( & ret_area_str) ;
624625 }
625626
627+ if self . needs_align_stack_ptr {
628+ uwrite ! (
629+ src,
630+ "
631+ {access} static class MemoryHelper
632+ {{
633+ {access} static unsafe void* AlignStackPtr(void* stackAddress, uint alignment)
634+ {{
635+ return (void*)(((nint)stackAddress) + ((int)alignment - 1) & -(int)alignment);
636+ }}
637+ }}
638+ "
639+ ) ;
640+ }
641+
626642 if self . needs_rep_table {
627- src. push_str ( " \n " ) ;
643+ src. push ( '\n' ) ;
628644 src. push_str ( include_str ! ( "RepTable.cs" ) ) ;
629645 }
630646
631647 if !& self . world_fragments . is_empty ( ) {
632- src. push_str ( " \n " ) ;
648+ src. push ( '\n' ) ;
633649
634650 if self
635651 . world_fragments
@@ -712,7 +728,7 @@ impl WorldGenerator for CSharp {
712728 src. push_str ( & include_str ! ( "FutureCommonSupport.cs" ) ) ;
713729 }
714730
715- src. push_str ( " \n " ) ;
731+ src. push ( '\n' ) ;
716732
717733 src. push_str ( "}\n " ) ;
718734
@@ -740,11 +756,11 @@ impl WorldGenerator for CSharp {
740756
741757 let ( fragments, fully_qualified_namespace) = match stubs {
742758 Stubs :: World ( fragments) => {
743- let fully_qualified_namespace = format ! ( "{ namespace}" ) ;
759+ let fully_qualified_namespace = namespace. to_string ( ) ;
744760 ( fragments, fully_qualified_namespace)
745761 }
746762 Stubs :: Interface ( fragments) => {
747- let fully_qualified_namespace = format ! ( "{ stub_namespace}" ) ;
763+ let fully_qualified_namespace = stub_namespace. clone ( ) ;
748764 ( fragments, fully_qualified_namespace)
749765 }
750766 } ;
@@ -818,13 +834,9 @@ impl WorldGenerator for CSharp {
818834 // intended to be used non-interactively at link time, the
819835 // linker will have no additional information to resolve such
820836 // ambiguity.
821- let ( resolve, world) =
822- wit_parser:: decoding:: decode_world ( & wit_component:: metadata:: encode (
823- & resolve,
824- id,
825- self . opts . string_encoding ,
826- None ,
827- ) ?) ?;
837+ let ( resolve, world) = wit_parser:: decoding:: decode_world (
838+ & wit_component:: metadata:: encode ( resolve, id, self . opts . string_encoding , None ) ?,
839+ ) ?;
828840 let pkg = resolve. worlds [ world] . package . unwrap ( ) ;
829841
830842 let mut printer = WitPrinter :: default ( ) ;
@@ -878,7 +890,7 @@ impl WorldGenerator for CSharp {
878890 . collect :: < Vec < _ > > ( )
879891 . join ( "\n " ) ;
880892
881- if body. len ( ) > 0 {
893+ if ! body. is_empty ( ) {
882894 let body = format ! (
883895 "{header}
884896
@@ -943,11 +955,12 @@ fn export_types(r#gen: &mut InterfaceGenerator, types: &[(&str, TypeId)]) {
943955// We cant use "StructLayout.Pack" as dotnet will use the minimum of the type and the "Pack" field,
944956// so for byte it would always use 1 regardless of the "Pack".
945957pub fn dotnet_aligned_array ( array_size : usize , required_alignment : usize ) -> ( usize , String ) {
958+ let num_elements = array_size. div_ceil ( required_alignment) ;
946959 match required_alignment {
947- 1 => ( array_size , "byte" . to_owned ( ) ) ,
948- 2 => ( ( array_size + 1 ) / 2 , "ushort" . to_owned ( ) ) ,
949- 4 => ( ( array_size + 3 ) / 4 , "uint" . to_owned ( ) ) ,
950- 8 => ( ( array_size + 7 ) / 8 , "ulong" . to_owned ( ) ) ,
960+ 1 => ( num_elements , "byte" . to_owned ( ) ) ,
961+ 2 => ( num_elements , "ushort" . to_owned ( ) ) ,
962+ 4 => ( num_elements , "uint" . to_owned ( ) ) ,
963+ 8 => ( num_elements , "ulong" . to_owned ( ) ) ,
951964 _ => todo ! ( "unsupported return_area_align {}" , required_alignment) ,
952965 }
953966}
@@ -1033,11 +1046,7 @@ fn interface_name(
10331046 ) ;
10341047
10351048 if let Some ( version) = & name. version {
1036- let v = version
1037- . to_string ( )
1038- . replace ( '.' , "_" )
1039- . replace ( '-' , "_" )
1040- . replace ( '+' , "_" ) ;
1049+ let v = version. to_string ( ) . replace ( [ '.' , '-' , '+' ] , "_" ) ;
10411050 ns = format ! ( "{}v{}." , ns, & v) ;
10421051 }
10431052 ns
0 commit comments