@@ -22,9 +22,7 @@ pub(crate) struct FunctionBindgen<'a, 'b> {
22
22
block_storage : Vec < BlockStorage > ,
23
23
blocks : Vec < Block > ,
24
24
payloads : Vec < String > ,
25
- pub ( crate ) needs_cleanup_list : bool ,
26
- needs_native_alloc_list : bool ,
27
- cleanup : Vec < Cleanup > ,
25
+ pub ( crate ) needs_cleanup : bool ,
28
26
import_return_pointer_area_size : usize ,
29
27
import_return_pointer_area_align : usize ,
30
28
pub ( crate ) resource_drops : Vec < ( String , String ) > ,
@@ -55,9 +53,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> {
55
53
block_storage : Vec :: new ( ) ,
56
54
blocks : Vec :: new ( ) ,
57
55
payloads : Vec :: new ( ) ,
58
- needs_cleanup_list : false ,
59
- needs_native_alloc_list : false ,
60
- cleanup : Vec :: new ( ) ,
56
+ needs_cleanup : false ,
61
57
import_return_pointer_area_size : 0 ,
62
58
import_return_pointer_area_align : 0 ,
63
59
resource_drops : Vec :: new ( ) ,
@@ -729,16 +725,17 @@ impl Bindgen for FunctionBindgen<'_, '_> {
729
725
// Despite the name GCHandle.Alloc here this does not actually allocate memory on the heap.
730
726
// It pins the array with the garbage collector so that it can be passed to unmanaged code.
731
727
// It is required to free the pin after use which is done in the Cleanup section.
728
+ self . needs_cleanup = true ;
732
729
uwrite ! (
733
730
self . src,
734
731
"
735
732
var {handle} = GCHandle.Alloc({list}, GCHandleType.Pinned);
736
733
var {ptr} = {handle}.AddrOfPinnedObject();
734
+ cleanups.Add(()=> {handle}.Free());
737
735
"
738
736
) ;
739
737
results. push ( format ! ( "{ptr}" ) ) ;
740
738
results. push ( format ! ( "({list}).Length" ) ) ;
741
- self . cleanup . push ( Cleanup { address : handle } ) ;
742
739
}
743
740
Direction :: Export => {
744
741
let address = self . locals . tmp ( "address" ) ;
@@ -756,9 +753,12 @@ impl Bindgen for FunctionBindgen<'_, '_> {
756
753
) ;
757
754
758
755
if realloc. is_none ( ) {
759
- self . cleanup . push ( Cleanup {
760
- address : gc_handle. clone ( ) ,
761
- } ) ;
756
+ self . needs_cleanup = true ;
757
+ uwrite ! (
758
+ self . src,
759
+ "
760
+ cleanups.Add(()=> {gc_handle}.Free());
761
+ " ) ;
762
762
}
763
763
results. push ( format ! ( "((IntPtr)({address})).ToInt32()" ) ) ;
764
764
results. push ( format ! ( "{list}.Length" ) ) ;
@@ -786,22 +786,39 @@ impl Bindgen for FunctionBindgen<'_, '_> {
786
786
Instruction :: StringLower { realloc } => {
787
787
let op = & operands[ 0 ] ;
788
788
let interop_string = self . locals . tmp ( "interopString" ) ;
789
- let result_var = self . locals . tmp ( "result" ) ;
789
+ let utf8_bytes = self . locals . tmp ( "utf8Bytes" ) ;
790
+ let length = self . locals . tmp ( "length" ) ;
791
+ let gc_handle = self . locals . tmp ( "gcHandle" ) ;
790
792
uwriteln ! (
791
793
self . src,
792
794
"
793
- var {result_var} = {op};
794
- IntPtr {interop_string} = InteropString.FromString({result_var}, out int length{result_var});"
795
+ var {utf8_bytes} = Encoding.UTF8.GetBytes({op});
796
+ var {length} = {utf8_bytes}.Length;
797
+ var {gc_handle} = GCHandle.Alloc({utf8_bytes}, GCHandleType.Pinned);
798
+ var {interop_string} = {gc_handle}.AddrOfPinnedObject();
799
+ "
795
800
) ;
796
801
797
802
if realloc. is_none ( ) {
798
803
results. push ( format ! ( "{interop_string}.ToInt32()" ) ) ;
804
+ self . needs_cleanup = true ;
805
+ uwrite ! (
806
+ self . src,
807
+ "
808
+ cleanups.Add(()=> {gc_handle}.Free());
809
+ " ) ;
799
810
} else {
800
811
results. push ( format ! ( "{interop_string}.ToInt32()" ) ) ;
801
812
}
802
- results. push ( format ! ( "length{result_var }" ) ) ;
813
+ results. push ( format ! ( "{length }" ) ) ;
803
814
804
- self . interface_gen . csharp_gen . needs_interop_string = true ;
815
+ if FunctionKind :: Freestanding == * self . kind || self . interface_gen . direction == Direction :: Export {
816
+ self . interface_gen . require_interop_using ( "System.Text" ) ;
817
+ self . interface_gen . require_interop_using ( "System.Runtime.InteropServices" ) ;
818
+ } else {
819
+ self . interface_gen . require_using ( "System.Text" ) ;
820
+ self . interface_gen . require_using ( "System.Runtime.InteropServices" ) ;
821
+ }
805
822
}
806
823
807
824
Instruction :: StringLift { .. } => {
@@ -835,14 +852,14 @@ impl Bindgen for FunctionBindgen<'_, '_> {
835
852
let buffer_size = self . locals . tmp ( "bufferSize" ) ;
836
853
//TODO: wasm64
837
854
let align = self . interface_gen . csharp_gen . sizes . align ( element) . align_wasm32 ( ) ;
838
- self . needs_native_alloc_list = true ;
839
855
856
+ self . needs_cleanup = true ;
840
857
uwrite ! (
841
858
self . src,
842
859
"
843
860
var {buffer_size} = {size} * (nuint){list}.Count;
844
861
var {address} = NativeMemory.AlignedAlloc({buffer_size}, {align});
845
- nativeAllocs .Add((IntPtr) {address});
862
+ cleanups .Add(()=> NativeMemory.AlignedFree( {address}) );
846
863
847
864
for (int {index} = 0; {index} < {list}.Count; ++{index}) {{
848
865
{ty} {block_element} = {list}[{index}];
@@ -988,19 +1005,15 @@ impl Bindgen for FunctionBindgen<'_, '_> {
988
1005
}
989
1006
990
1007
Instruction :: Return { amt : _, func } => {
991
- for Cleanup { address } in & self . cleanup {
992
- uwriteln ! ( self . src, "{address}.Free();" ) ;
993
- }
994
-
995
- if self . needs_native_alloc_list {
996
- self . src . insert_str ( 0 , "var nativeAllocs = new List<IntPtr>();
1008
+ if self . needs_cleanup {
1009
+ self . src . insert_str ( 0 , "var cleanups = new List<Action>();
997
1010
" ) ;
998
1011
999
1012
uwriteln ! ( self . src, "\
1000
- foreach (var nativeAlloc in nativeAllocs )
1001
- {{
1002
- NativeMemory.AlignedFree((void*)nativeAlloc );
1003
- }}" ) ;
1013
+ foreach (var cleanup in cleanups )
1014
+ {{
1015
+ cleanup( );
1016
+ }}" ) ;
1004
1017
}
1005
1018
1006
1019
if !matches ! ( ( self . interface_gen. direction, self . kind) , ( Direction :: Import , FunctionKind :: Constructor ( _) ) ) {
@@ -1204,7 +1217,6 @@ impl Bindgen for FunctionBindgen<'_, '_> {
1204
1217
body : mem:: take ( & mut self . src ) ,
1205
1218
element : self . locals . tmp ( "element" ) ,
1206
1219
base : self . locals . tmp ( "basePtr" ) ,
1207
- cleanup : mem:: take ( & mut self . cleanup ) ,
1208
1220
} ) ;
1209
1221
}
1210
1222
@@ -1213,19 +1225,8 @@ impl Bindgen for FunctionBindgen<'_, '_> {
1213
1225
body,
1214
1226
element,
1215
1227
base,
1216
- cleanup,
1217
1228
} = self . block_storage . pop ( ) . unwrap ( ) ;
1218
1229
1219
- if !self . cleanup . is_empty ( ) {
1220
- //self.needs_cleanup_list = true;
1221
-
1222
- for Cleanup { address } in & self . cleanup {
1223
- uwriteln ! ( self . src, "{address}.Free();" ) ;
1224
- }
1225
- }
1226
-
1227
- self . cleanup = cleanup;
1228
-
1229
1230
self . blocks . push ( Block {
1230
1231
body : mem:: replace ( & mut self . src , body) ,
1231
1232
results : mem:: take ( operands) ,
@@ -1304,15 +1305,10 @@ struct Block {
1304
1305
base : String ,
1305
1306
}
1306
1307
1307
- struct Cleanup {
1308
- address : String ,
1309
- }
1310
-
1311
1308
struct BlockStorage {
1312
1309
body : String ,
1313
1310
element : String ,
1314
1311
base : String ,
1315
- cleanup : Vec < Cleanup > ,
1316
1312
}
1317
1313
1318
1314
#[ derive( Clone ) ]
0 commit comments