[ffigen] Test autorelease pools and more copying cases (#385)
diff --git a/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml b/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml index b925491..bc4982e 100644 --- a/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml +++ b/pkgs/ffigen/test/native_objc_test/automated_ref_count_config.yaml
@@ -3,8 +3,9 @@ language: objc output: 'test/native_objc_test/automated_ref_count_bindings.dart' functions: - exclude: - - '.*' + include: + - createAutoreleasePool + - destroyAutoreleasePool headers: entry-points: - 'test/native_objc_test/automated_ref_count_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart index 74c1270..74302f9 100644 --- a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart +++ b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.dart
@@ -86,6 +86,10 @@ expect(counter.value, 2); final obj3 = obj1.makeACopy(); expect(counter.value, 3); + final obj4 = obj1.copyWithZone_(nullptr); + expect(counter.value, 4); + final obj5 = obj1.copy(); + expect(counter.value, 5); } test('copy methods ref count correctly', () { @@ -97,6 +101,37 @@ calloc.free(counter); }); + autoreleaseMethodsInner(Pointer<Int32> counter) { + final obj = ArcTestObject.makeAndAutorelease_(lib, counter); + expect(counter.value, 1); + } + + test('autorelease methods ref count correctly', () { + final counter = calloc<Int32>(); + counter.value = 0; + + final pool1 = lib.createAutoreleasePool(); + autoreleaseMethodsInner(counter); + doGC(); + // The autorelease pool is still holding a reference to the object. + expect(counter.value, 1); + lib.destroyAutoreleasePool(pool1); + expect(counter.value, 0); + + final pool2 = lib.createAutoreleasePool(); + final obj = ArcTestObject.makeAndAutorelease_(lib, counter); + expect(counter.value, 1); + doGC(); + expect(counter.value, 1); + lib.destroyAutoreleasePool(pool2); + // The obj variable still holds a reference to the object. + expect(counter.value, 1); + obj.release(); + expect(counter.value, 0); + + calloc.free(counter); + }); + castFromPointerInnerReleaseAndRetain(int address) { final fromCast = RefCounted.castFromPointer( lib, Pointer<ObjCObject>.fromAddress(address),
diff --git a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m index 78e5a6b..f4a4fc9 100644 --- a/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m +++ b/pkgs/ffigen/test/native_objc_test/automated_ref_count_test.m
@@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. #import <Foundation/NSObject.h> +#import <Foundation/NSAutoreleasePool.h> @interface ArcTestObject : NSObject { int32_t* counter; @@ -11,11 +12,13 @@ + (instancetype)allocTheThing; + (instancetype)newWithCounter:(int32_t*) _counter; - (instancetype)initWithCounter:(int32_t*) _counter; ++ (ArcTestObject*)makeAndAutorelease:(int32_t*) _counter; - (void)setCounter:(int32_t*) _counter; - (void)dealloc; - (ArcTestObject*)unownedReference; - (ArcTestObject*)copyMe; - (ArcTestObject*)makeACopy; +- (id)copyWithZone:(NSZone*) zone; - (ArcTestObject*)returnsRetained NS_RETURNS_RETAINED; @end @@ -44,6 +47,10 @@ return [super init]; } ++ (instancetype)makeAndAutorelease:(int32_t*) _counter { + return [[[ArcTestObject alloc] initWithCounter: _counter] autorelease]; +} + - (void)setCounter:(int32_t*) _counter { counter = _counter; ++*counter; @@ -66,12 +73,24 @@ return [[ArcTestObject alloc] initWithCounter: counter]; } +- (id)copyWithZone:(NSZone*) zone { + return [[ArcTestObject alloc] initWithCounter: counter]; +} + - (ArcTestObject*)returnsRetained NS_RETURNS_RETAINED { return [self retain]; } @end +id createAutoreleasePool() { + return [NSAutoreleasePool new]; +} + +void destroyAutoreleasePool(id pool) { + [pool release]; +} + @implementation RefCounted - (instancetype)init { @@ -97,4 +116,4 @@ return (int64_t) self; } -@end \ No newline at end of file +@end