@@ -519,6 +519,8 @@ impl WorldGenerator for CSharp {
519
519
if self . needs_export_return_area {
520
520
let mut ret_area_str = String :: new ( ) ;
521
521
522
+ let ( array_size, element_type) =
523
+ dotnet_aligned_array ( self . return_area_size , self . return_area_align ) ;
522
524
uwrite ! (
523
525
ret_area_str,
524
526
"
@@ -528,23 +530,22 @@ impl WorldGenerator for CSharp {
528
530
[StructLayout(LayoutKind.Sequential, Pack = {1})]
529
531
internal struct ReturnArea
530
532
{{
531
- private byte buffer;
533
+ private {2} buffer;
532
534
533
- internal unsafe int AddressOfReturnArea()
535
+ internal unsafe nint AddressOfReturnArea()
534
536
{{
535
- fixed(byte* ptr = &buffer)
536
- {{
537
- return (int)ptr;
538
- }}
537
+ return (nint)Unsafe.AsPointer(ref buffer);
539
538
}}
540
539
}}
541
540
542
541
[ThreadStatic]
542
+ [FixedAddressValueType]
543
543
internal static ReturnArea returnArea = default;
544
544
}}
545
545
" ,
546
- self . return_area_size ,
546
+ array_size ,
547
547
self . return_area_align,
548
+ element_type
548
549
) ;
549
550
550
551
src. push_str ( & ret_area_str) ;
@@ -984,8 +985,6 @@ impl InterfaceGenerator<'_> {
984
985
) ;
985
986
986
987
let src = bindgen. src ;
987
- let import_return_pointer_area_size = bindgen. import_return_pointer_area_size ;
988
- let import_return_pointer_area_align = bindgen. import_return_pointer_area_align ;
989
988
990
989
let params = func
991
990
. params
@@ -1022,28 +1021,6 @@ impl InterfaceGenerator<'_> {
1022
1021
"#
1023
1022
) ;
1024
1023
1025
- if import_return_pointer_area_size > 0 {
1026
- uwrite ! (
1027
- target,
1028
- r#"
1029
- [InlineArray({import_return_pointer_area_size})]
1030
- [StructLayout(LayoutKind.Sequential, Pack = {import_return_pointer_area_align})]
1031
- internal struct ImportReturnArea
1032
- {{
1033
- private byte buffer;
1034
-
1035
- internal unsafe int AddressOfReturnArea()
1036
- {{
1037
- fixed(byte* ptr = &buffer)
1038
- {{
1039
- return (int)ptr;
1040
- }}
1041
- }}
1042
- }}
1043
- "# ,
1044
- )
1045
- }
1046
-
1047
1024
uwrite ! (
1048
1025
target,
1049
1026
r#"
@@ -1862,6 +1839,7 @@ struct FunctionBindgen<'a, 'b> {
1862
1839
cleanup : Vec < Cleanup > ,
1863
1840
import_return_pointer_area_size : usize ,
1864
1841
import_return_pointer_area_align : usize ,
1842
+ fixed : usize , // Number of `fixed` blocks that need to be closed.
1865
1843
resource_drops : Vec < ( String , String ) > ,
1866
1844
}
1867
1845
@@ -1892,6 +1870,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
1892
1870
cleanup : Vec :: new ( ) ,
1893
1871
import_return_pointer_area_size : 0 ,
1894
1872
import_return_pointer_area_align : 0 ,
1873
+ fixed : 0 ,
1895
1874
resource_drops : Vec :: new ( ) ,
1896
1875
}
1897
1876
}
@@ -2468,7 +2447,6 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2468
2447
2469
2448
let list = & operands[ 0 ] ;
2470
2449
let size = self . gen . gen . sizes . size ( element) ;
2471
- let _align = self . gen . gen . sizes . align ( element) ;
2472
2450
let ty = self . gen . type_name_with_qualifier ( element, true ) ;
2473
2451
let index = self . locals . tmp ( "index" ) ;
2474
2452
@@ -2513,7 +2491,6 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2513
2491
let array = self . locals . tmp ( "array" ) ;
2514
2492
let ty = self . gen . type_name_with_qualifier ( element, true ) ;
2515
2493
let size = self . gen . gen . sizes . size ( element) ;
2516
- let _align = self . gen . gen . sizes . align ( element) ;
2517
2494
let index = self . locals . tmp ( "index" ) ;
2518
2495
2519
2496
let result = match & block_results[ ..] {
@@ -2526,7 +2503,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2526
2503
"
2527
2504
var {array} = new List<{ty}>({length});
2528
2505
for (int {index} = 0; {index} < {length}; ++{index}) {{
2529
- int {base} = {address} + ({index} * {size});
2506
+ nint {base} = {address} + ({index} * {size});
2530
2507
{body}
2531
2508
{array}.Add({result});
2532
2509
}}
@@ -2651,6 +2628,11 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2651
2628
uwriteln ! ( self . src, "return ({results});" )
2652
2629
}
2653
2630
}
2631
+
2632
+ // Close all the fixed blocks.
2633
+ for _ in 0 ..self . fixed {
2634
+ uwriteln ! ( self . src, "}}" ) ;
2635
+ }
2654
2636
}
2655
2637
}
2656
2638
@@ -2780,19 +2762,30 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2780
2762
// their return area to be live until the post-return call.
2781
2763
match self . gen . direction {
2782
2764
Direction :: Import => {
2783
- let ret_area = self . locals . tmp ( "retArea" ) ;
2784
- let name = self . func_name . to_upper_camel_case ( ) ;
2785
2765
self . import_return_pointer_area_size =
2786
2766
self . import_return_pointer_area_size . max ( size) ;
2787
2767
self . import_return_pointer_area_align =
2788
2768
self . import_return_pointer_area_align . max ( align) ;
2769
+ let ( array_size, element_type) = dotnet_aligned_array (
2770
+ self . import_return_pointer_area_size ,
2771
+ self . import_return_pointer_area_align ,
2772
+ ) ;
2773
+ let ret_area = self . locals . tmp ( "retArea" ) ;
2774
+ let ret_area_byte0 = self . locals . tmp ( "retAreaByte0" ) ;
2789
2775
uwrite ! (
2790
2776
self . src,
2791
2777
"
2792
- var {ret_area} = new {name}WasmInterop.ImportReturnArea();
2793
- var {ptr} = {ret_area}.AddressOfReturnArea();
2794
- "
2778
+ var {2} = new {0}[{1}];
2779
+ fixed ({0}* {3} = &{2}[0])
2780
+ {{
2781
+ var {ptr} = (nint){3};
2782
+ " ,
2783
+ element_type,
2784
+ array_size,
2785
+ ret_area,
2786
+ ret_area_byte0
2795
2787
) ;
2788
+ self . fixed = self . fixed + 1 ;
2796
2789
2797
2790
return format ! ( "{ptr}" ) ;
2798
2791
}
@@ -2857,6 +2850,26 @@ impl Bindgen for FunctionBindgen<'_, '_> {
2857
2850
}
2858
2851
}
2859
2852
2853
+ // We cant use "StructLayout.Pack" as dotnet will use the minimum of the type and the "Pack" field,
2854
+ // so for byte it would always use 1 regardless of the "Pack".
2855
+ fn dotnet_aligned_array ( array_size : usize , required_alignment : usize ) -> ( usize , String ) {
2856
+ match required_alignment {
2857
+ 1 => {
2858
+ return ( array_size, "byte" . to_owned ( ) ) ;
2859
+ }
2860
+ 2 => {
2861
+ return ( ( array_size + 1 ) / 2 , "ushort" . to_owned ( ) ) ;
2862
+ }
2863
+ 4 => {
2864
+ return ( ( array_size + 3 ) / 4 , "uint" . to_owned ( ) ) ;
2865
+ }
2866
+ 8 => {
2867
+ return ( ( array_size + 7 ) / 8 , "ulong" . to_owned ( ) ) ;
2868
+ }
2869
+ _ => todo ! ( "unsupported return_area_align {}" , required_alignment) ,
2870
+ }
2871
+ }
2872
+
2860
2873
fn perform_cast ( op : & String , cast : & Bitcast ) -> String {
2861
2874
match cast {
2862
2875
Bitcast :: I32ToF32 => format ! ( "BitConverter.Int32BitsToSingle({op})" ) ,
@@ -2900,7 +2913,7 @@ fn wasm_type(ty: WasmType) -> &'static str {
2900
2913
WasmType :: I64 => "long" ,
2901
2914
WasmType :: F32 => "float" ,
2902
2915
WasmType :: F64 => "double" ,
2903
- WasmType :: Pointer => "int " ,
2916
+ WasmType :: Pointer => "nint " ,
2904
2917
WasmType :: PointerOrI64 => "long" ,
2905
2918
WasmType :: Length => "int" ,
2906
2919
}
0 commit comments