wip
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_block.dart b/pkgs/ffigen/lib/src/code_generator/objc_block.dart index ca90f3b..753cd66 100644 --- a/pkgs/ffigen/lib/src/code_generator/objc_block.dart +++ b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
@@ -251,8 +251,8 @@ /// until it is garbage collected by both Dart and ObjC. static $blockType fromFunction(${func.dartType} fn, {bool keepIsolateAlive = true}) => - $blockType($newClosureBlock($closureCallable, $convFn, - keepIsolateAlive), retain: false, release: true); + $blockType($newClosureBlock($closureCallable, $convFn, keepIsolateAlive), + retain: false, release: true); '''); // Listener block constructor is only available for void blocks. @@ -310,15 +310,14 @@ {bool keepIsolateAlive = true}) { final raw = $newClosureBlock($blockingCallable.nativeFunction.cast(), $listenerConvFn, keepIsolateAlive); + final flag = $newDestroyedFlag(); final rawListener = $newClosureBlock( $blockingListenerCallable.nativeFunction.cast(), - $listenerConvFn, keepIsolateAlive); - final flag = $newDestroyedFlag(); + $listenerConvFn, keepIsolateAlive, destroyedFlag: flag); final wrapper = $wrapBlockingFn(raw, rawListener, flag, $objCContext); $releaseFn(raw.cast()); $releaseFn(rawListener.cast()); - return $blockType( - wrapper, retain: false, release: true, destroyedFlag: flag); + return $blockType(wrapper, retain: false, release: true); } '''); }
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.dart b/pkgs/ffigen/test/native_objc_test/block_test.dart index 7490ab2..7c6877c 100644 --- a/pkgs/ffigen/test/native_objc_test/block_test.dart +++ b/pkgs/ffigen/test/native_objc_test/block_test.dart
@@ -196,16 +196,10 @@ }); final isolate = await Isolate.spawn((_) async { - ObjCBlock<Void Function()>? block = VoidBlock.blocking(() { - while (true) { - // Block forever. - } + final block = VoidBlock.blocking(() { + Isolate.exit(); }); - final thread = - BlockTester.callBlockOnNewThread_andListener_(block, resultBlock); - block = null; - thread.start(); - Isolate.current.kill(); + BlockTester.callBlockOnNewThread_andListener_(block, resultBlock); }, null); expect(await resultPort.first, 1234);
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.h b/pkgs/ffigen/test/native_objc_test/block_test.h index 4777671..c16e3fa 100644 --- a/pkgs/ffigen/test/native_objc_test/block_test.h +++ b/pkgs/ffigen/test/native_objc_test/block_test.h
@@ -87,6 +87,6 @@ - (void)invokeAndReleaseListener:(_Nullable id)_; + (void)blockingBlockTest:(IntPtrBlock)blockingBlock resultBlock:(ResultBlock)resultBlock; -+ (NSThread*)callBlockOnNewThread:(VoidBlock)blockingBlock ++ (void)callBlockOnNewThread:(VoidBlock)blockingBlock andListener:(ResultBlock)resultBlock; @end
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.m b/pkgs/ffigen/test/native_objc_test/block_test.m index d0fee4e..d0ba625 100644 --- a/pkgs/ffigen/test/native_objc_test/block_test.m +++ b/pkgs/ffigen/test/native_objc_test/block_test.m
@@ -218,12 +218,12 @@ }] start]; } -+ (NSThread*)callBlockOnNewThread:(VoidBlock)blockingBlock ++ (void)callBlockOnNewThread:(VoidBlock)blockingBlock andListener:(ResultBlock)resultBlock { - return [[NSThread alloc] initWithBlock:^void() { + [[[NSThread alloc] initWithBlock:^void() { blockingBlock(); resultBlock(1234); - }]; + }] start]; } @end
diff --git a/pkgs/objective_c/ffigen_c.yaml b/pkgs/objective_c/ffigen_c.yaml index 779f01e..d65ba69 100644 --- a/pkgs/objective_c/ffigen_c.yaml +++ b/pkgs/objective_c/ffigen_c.yaml
@@ -32,6 +32,7 @@ - 'DOBJC_disposeObjCBlockWithClosure' - 'DOBJC_newFinalizableBool' - 'DOBJC_newFinalizableHandle' + - 'DOBJC_newFinalizableFlag' - 'DOBJC_awaitWaiter' rename: 'DOBJC_(.*)': '$1'
diff --git a/pkgs/objective_c/ffigen_objc.yaml b/pkgs/objective_c/ffigen_objc.yaml index 41d2277..9728249 100644 --- a/pkgs/objective_c/ffigen_objc.yaml +++ b/pkgs/objective_c/ffigen_objc.yaml
@@ -7,7 +7,6 @@ objc-bindings: 'src/objective_c_bindings_generated.m' headers: entry-points: - - 'src/atomic_bool.h' - 'src/foundation.h' - 'src/input_stream_adapter.h' - 'src/protocol.h' @@ -25,7 +24,6 @@ objc-interfaces: # Keep in sync with ffigen's ObjCBuiltInFunctions.builtInInterfaces. include: - - DOBJCAtomicBool - DOBJCDartInputStreamAdapter - DOBJCDartProtocolBuilder - DOBJCDartProtocol @@ -65,7 +63,6 @@ - NSValue - Protocol rename: - 'DOBJCAtomicBool': 'AtomicBool' 'DOBJCDartInputStreamAdapter': 'DartInputStreamAdapter' 'DOBJCDartProtocolBuilder': 'DartProtocolBuilder' 'DOBJCDartProtocol': 'DartProtocol'
diff --git a/pkgs/objective_c/lib/src/block.dart b/pkgs/objective_c/lib/src/block.dart index 3f63c32..929f736 100644 --- a/pkgs/objective_c/lib/src/block.dart +++ b/pkgs/objective_c/lib/src/block.dart
@@ -26,8 +26,7 @@ /// out the block's type is to simply copy it from the ffigen generated API. class ObjCBlock<T extends Function> extends ObjCBlockBase { /// This constructor is only for use by ffigen bindings. - ObjCBlock(super.ptr, - {required super.retain, required super.release, super.destroyedFlag}); + ObjCBlock(super.ptr, {required super.retain, required super.release}); } /// A sentinel class representing the `ns_returns_retained` attribute for
diff --git a/pkgs/objective_c/lib/src/c_bindings_generated.dart b/pkgs/objective_c/lib/src/c_bindings_generated.dart index e6fbd60..7439910 100644 --- a/pkgs/objective_c/lib/src/c_bindings_generated.dart +++ b/pkgs/objective_c/lib/src/c_bindings_generated.dart
@@ -164,13 +164,19 @@ Object owner, ); +@ffi.Native<Dart_FinalizableHandle Function(ffi.Handle, ffi.Pointer<ffi.Void>)>( + symbol: 'DOBJC_newFinalizableFlag') +external Dart_FinalizableHandle newFinalizableFlag( + Object owner, + ffi.Pointer<ffi.Void> flag, +); + @ffi.Native< - Dart_FinalizableHandle Function(ffi.Handle, ffi.Pointer<ObjCObject>, - ffi.Pointer<ffi.Void>)>(symbol: 'DOBJC_newFinalizableHandle') + Dart_FinalizableHandle Function(ffi.Handle, ffi.Pointer<ObjCObject>)>( + symbol: 'DOBJC_newFinalizableHandle') external Dart_FinalizableHandle newFinalizableHandle( Object owner, ffi.Pointer<ObjCObject> object, - ffi.Pointer<ffi.Void> destroyed_flag, ); @ffi.Native<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>)>(
diff --git a/pkgs/objective_c/lib/src/internal.dart b/pkgs/objective_c/lib/src/internal.dart index 848c3cc..70bd142 100644 --- a/pkgs/objective_c/lib/src/internal.dart +++ b/pkgs/objective_c/lib/src/internal.dart
@@ -172,10 +172,9 @@ } c.Dart_FinalizableHandle _newFinalizableHandle( - _FinalizablePointer finalizable, Pointer<Void> destroyedFlag) { + _FinalizablePointer finalizable) { _ensureDartAPI(); - return c.newFinalizableHandle( - finalizable, finalizable.ptr.cast(), destroyedFlag); + return c.newFinalizableHandle(finalizable, finalizable.ptr.cast()); } Pointer<Bool> _newFinalizableBool(Object owner) { @@ -183,6 +182,12 @@ return c.newFinalizableBool(owner); } +c.Dart_FinalizableHandle? _newFinalizableFlag(_FinalizablePointer? flag) { + if (flag == null) return null; + _ensureDartAPI(); + return c.newFinalizableFlag(flag, flag.ptr.cast()); +} + @pragma('vm:deeply-immutable') abstract final class _ObjCReference<T extends NativeType> implements Finalizable { @@ -190,10 +195,10 @@ final c.Dart_FinalizableHandle? _ptrFinalizableHandle; final Pointer<Bool> _isReleased; - _ObjCReference(this._finalizable, Pointer<Void> destroyedFlag, + _ObjCReference(this._finalizable, {required bool retain, required bool release}) : _ptrFinalizableHandle = - release ? _newFinalizableHandle(_finalizable, destroyedFlag) : null, + release ? _newFinalizableHandle(_finalizable) : null, _isReleased = _newFinalizableBool(_finalizable) { assert(_isValid(_finalizable.ptr)); if (retain) { @@ -272,7 +277,7 @@ @pragma('vm:deeply-immutable') final class ObjCObjectRef extends _ObjCReference<c.ObjCObject> { ObjCObjectRef(ObjectPtr ptr, {required super.retain, required super.release}) - : super(_FinalizablePointer(ptr), nullptr); + : super(_FinalizablePointer(ptr)); @override void _retain(ObjectPtr ptr) => c.objectRetain(ptr); @@ -325,11 +330,8 @@ @pragma('vm:deeply-immutable') final class ObjCBlockRef extends _ObjCReference<c.ObjCBlockImpl> { - ObjCBlockRef(BlockPtr ptr, - {required super.retain, - required super.release, - required Pointer<Void> destroyedFlag}) - : super(_FinalizablePointer(ptr), destroyedFlag); + ObjCBlockRef(BlockPtr ptr, {required super.retain, required super.release}) + : super(_FinalizablePointer(ptr)); @override void _retain(BlockPtr ptr) => c.blockRetain(ptr.cast()); @@ -340,14 +342,8 @@ /// Only for use by ffigen bindings. class ObjCBlockBase extends _ObjCRefHolder<c.ObjCBlockImpl, ObjCBlockRef> { - ObjCBlockBase(BlockPtr ptr, - {required bool retain, - required bool release, - Pointer<Void>? destroyedFlag}) - : super(ObjCBlockRef(ptr, - retain: retain, - release: release, - destroyedFlag: destroyedFlag ?? nullptr)); + ObjCBlockBase(BlockPtr ptr, {required bool retain, required bool release}) + : super(ObjCBlockRef(ptr, retain: retain, release: release)); } Pointer<c.ObjCBlockDesc> _newBlockDesc( @@ -388,10 +384,11 @@ const int _blockHasCopyDispose = 1 << 25; /// Only for use by ffigen bindings. -BlockPtr newClosureBlock(VoidPtr invoke, Function fn, bool keepIsolateAlive) => +BlockPtr newClosureBlock(VoidPtr invoke, Function fn, bool keepIsolateAlive, + {Pointer<Void>? destroyedFlag}) => _newBlock( invoke, - _registerBlockClosure(fn, keepIsolateAlive), + _registerBlockClosure(fn, keepIsolateAlive, destroyedFlag ?? nullptr), _closureBlockDesc, _blockClosureDisposer.sendPort.nativePort, _blockHasCopyDispose); @@ -400,10 +397,15 @@ BlockPtr newPointerBlock(VoidPtr invoke, VoidPtr target) => _newBlock(invoke, target, _pointerBlockDesc, 0, 0); -typedef _RegEntry = ({ - Function closure, - RawReceivePort? keepAlivePort, -}); +class _RegEntry { + final Function closure; + final RawReceivePort? keepAlivePort; + final _FinalizablePointer<Void>? destroyedFlag; + final c.Dart_FinalizableHandle? destroyedFlagFinalizableHandle; + + _RegEntry(this.closure, this.keepAlivePort, this.destroyedFlag) + : destroyedFlagFinalizableHandle = _newFinalizableFlag(destroyedFlag); +} final _blockClosureRegistry = <int, _RegEntry>{}; @@ -415,17 +417,26 @@ final id = msg as int; assert(_blockClosureRegistry.containsKey(id)); final entry = _blockClosureRegistry.remove(id)!; + final flag = entry.destroyedFlag; + final flagHandle = entry.destroyedFlagFinalizableHandle; + if (flagHandle != null && flag != null) { + print("ZZZZ: deleteFinalizableHandle: ${flag.ptr}"); + c.deleteFinalizableHandle(flagHandle, flag); + c.flipDestroyedFlag(flag.ptr); + } entry.keepAlivePort?.close(); }, 'ObjCBlockClosureDisposer') ..keepIsolateAlive = false; }(); -VoidPtr _registerBlockClosure(Function closure, bool keepIsolateAlive) { +VoidPtr _registerBlockClosure( + Function closure, bool keepIsolateAlive, Pointer<Void> destroyedFlag) { ++_blockClosureRegistryLastId; assert(!_blockClosureRegistry.containsKey(_blockClosureRegistryLastId)); - _blockClosureRegistry[_blockClosureRegistryLastId] = ( - closure: closure, - keepAlivePort: keepIsolateAlive ? RawReceivePort() : null, + _blockClosureRegistry[_blockClosureRegistryLastId] = _RegEntry( + closure, + keepIsolateAlive ? RawReceivePort() : null, + destroyedFlag == nullptr ? null : _FinalizablePointer<Void>(destroyedFlag), ); return VoidPtr.fromAddress(_blockClosureRegistryLastId); }
diff --git a/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart b/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart index 387171e..5852db3 100644 --- a/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart +++ b/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart
@@ -320,87 +320,6 @@ ffi.Pointer<objc.ObjCBlockImpl> block, ); -/// DOBJCAtomicBool -class AtomicBool extends NSObject { - AtomicBool._(ffi.Pointer<objc.ObjCObject> pointer, - {bool retain = false, bool release = false}) - : super.castFromPointer(pointer, retain: retain, release: release); - - /// Constructs a [AtomicBool] that points to the same underlying object as [other]. - AtomicBool.castFrom(objc.ObjCObjectBase other) - : this._(other.ref.pointer, retain: true, release: true); - - /// Constructs a [AtomicBool] that wraps the given raw object pointer. - AtomicBool.castFromPointer(ffi.Pointer<objc.ObjCObject> other, - {bool retain = false, bool release = false}) - : this._(other, retain: retain, release: release); - - /// Returns whether [obj] is an instance of [AtomicBool]. - static bool isInstance(objc.ObjCObjectBase obj) { - return _objc_msgSend_19nvye5( - obj.ref.pointer, _sel_isKindOfClass_, _class_DOBJCAtomicBool); - } - - /// alloc - static AtomicBool alloc() { - final _ret = _objc_msgSend_151sglz(_class_DOBJCAtomicBool, _sel_alloc); - return AtomicBool.castFromPointer(_ret, retain: false, release: true); - } - - /// allocWithZone: - static AtomicBool allocWithZone_(ffi.Pointer<NSZone> zone) { - final _ret = _objc_msgSend_1cwp428( - _class_DOBJCAtomicBool, _sel_allocWithZone_, zone); - return AtomicBool.castFromPointer(_ret, retain: false, release: true); - } - - /// new - static AtomicBool new$() { - final _ret = _objc_msgSend_151sglz(_class_DOBJCAtomicBool, _sel_new); - return AtomicBool.castFromPointer(_ret, retain: false, release: true); - } - - /// autorelease - AtomicBool autorelease() { - final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_autorelease); - return AtomicBool.castFromPointer(_ret, retain: true, release: true); - } - - /// init - AtomicBool init() { - objc.checkOsVersion('DOBJCAtomicBool.init', - iOS: (false, (2, 0, 0)), macOS: (false, (10, 0, 0))); - final _ret = - _objc_msgSend_151sglz(this.ref.retainAndReturnPointer(), _sel_init); - return AtomicBool.castFromPointer(_ret, retain: false, release: true); - } - - /// retain - AtomicBool retain() { - final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_retain); - return AtomicBool.castFromPointer(_ret, retain: true, release: true); - } - - /// self - AtomicBool self$1() { - final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_self); - return AtomicBool.castFromPointer(_ret, retain: true, release: true); - } - - /// setValue: - set value(bool value) { - _objc_msgSend_1s56lr9(this.ref.pointer, _sel_setValue_, value); - } - - /// value - bool get value { - return _objc_msgSend_91o635(this.ref.pointer, _sel_value); - } - - /// Returns a new instance of AtomicBool constructed with the default `new` method. - factory AtomicBool() => new$(); -} - /// Helper class to adapt a Dart stream into a `NSInputStream`. class DartInputStreamAdapter extends NSInputStream implements NSStreamDelegate { DartInputStreamAdapter._(ffi.Pointer<objc.ObjCObject> pointer, @@ -13525,6 +13444,7 @@ NSDictionary.castFromPointer(arg2, retain: false, release: true)), keepIsolateAlive); + final flag = objc.newDestroyedFlag(); final rawListener = objc.newClosureBlock( _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_blockingListenerCallable .nativeFunction @@ -13538,19 +13458,18 @@ objc.ObjCObjectBase(arg1, retain: false, release: true), NSDictionary.castFromPointer(arg2, retain: false, release: true)), - keepIsolateAlive); - final flag = objc.newDestroyedFlag(); + keepIsolateAlive, + destroyedFlag: flag); final wrapper = _ObjectiveCBindings_wrapBlockingBlock_1b3bb6a( raw, rawListener, flag, objc.objCContext); objc.objectRelease(raw.cast()); objc.objectRelease(rawListener.cast()); return objc.ObjCBlock< - ffi.Void Function( - objc.ObjCBlock< - ffi.Void Function(ffi.Pointer<objc.ObjCObject>?, NSError)>, - ffi.Pointer<objc.ObjCObject>, - NSDictionary)>(wrapper, - retain: false, release: true, destroyedFlag: flag); + ffi.Void Function( + objc.ObjCBlock< + ffi.Void Function(ffi.Pointer<objc.ObjCObject>?, NSError)>, + ffi.Pointer<objc.ObjCObject>, + NSDictionary)>(wrapper, retain: false, release: true); } } @@ -13730,18 +13649,19 @@ _ObjCBlock_ffiVoid_ffiVoid_blockingCallable.nativeFunction.cast(), (ffi.Pointer<ffi.Void> arg0) => fn(arg0), keepIsolateAlive); + final flag = objc.newDestroyedFlag(); final rawListener = objc.newClosureBlock( _ObjCBlock_ffiVoid_ffiVoid_blockingListenerCallable.nativeFunction .cast(), (ffi.Pointer<ffi.Void> arg0) => fn(arg0), - keepIsolateAlive); - final flag = objc.newDestroyedFlag(); + keepIsolateAlive, + destroyedFlag: flag); final wrapper = _ObjectiveCBindings_wrapBlockingBlock_ovsamd( raw, rawListener, flag, objc.objCContext); objc.objectRelease(raw.cast()); objc.objectRelease(rawListener.cast()); return objc.ObjCBlock<ffi.Void Function(ffi.Pointer<ffi.Void>)>(wrapper, - retain: false, release: true, destroyedFlag: flag); + retain: false, release: true); } } @@ -13944,14 +13864,15 @@ (ffi.Pointer<ffi.Void> arg0, ffi.Pointer<objc.ObjCObject> arg1) => fn( arg0, NSCoder.castFromPointer(arg1, retain: false, release: true)), keepIsolateAlive); + final flag = objc.newDestroyedFlag(); final rawListener = objc.newClosureBlock( _ObjCBlock_ffiVoid_ffiVoid_NSCoder_blockingListenerCallable .nativeFunction .cast(), (ffi.Pointer<ffi.Void> arg0, ffi.Pointer<objc.ObjCObject> arg1) => fn( arg0, NSCoder.castFromPointer(arg1, retain: false, release: true)), - keepIsolateAlive); - final flag = objc.newDestroyedFlag(); + keepIsolateAlive, + destroyedFlag: flag); final wrapper = _ObjectiveCBindings_wrapBlockingBlock_18v1jvf( raw, rawListener, flag, objc.objCContext); objc.objectRelease(raw.cast()); @@ -13959,8 +13880,7 @@ return objc.ObjCBlock<ffi.Void Function(ffi.Pointer<ffi.Void>, NSCoder)>( wrapper, retain: false, - release: true, - destroyedFlag: flag); + release: true); } } @@ -14205,6 +14125,7 @@ NSStream.castFromPointer(arg1, retain: false, release: true), NSStreamEvent.fromValue(arg2)), keepIsolateAlive); + final flag = objc.newDestroyedFlag(); final rawListener = objc.newClosureBlock( _ObjCBlock_ffiVoid_ffiVoid_NSStream_NSStreamEvent_blockingListenerCallable .nativeFunction @@ -14215,16 +14136,15 @@ arg0, NSStream.castFromPointer(arg1, retain: false, release: true), NSStreamEvent.fromValue(arg2)), - keepIsolateAlive); - final flag = objc.newDestroyedFlag(); + keepIsolateAlive, + destroyedFlag: flag); final wrapper = _ObjectiveCBindings_wrapBlockingBlock_hoampi( raw, rawListener, flag, objc.objCContext); objc.objectRelease(raw.cast()); objc.objectRelease(rawListener.cast()); return objc.ObjCBlock< - ffi.Void Function( - ffi.Pointer<ffi.Void>, NSStream, ffi.UnsignedLong)>(wrapper, - retain: false, release: true, destroyedFlag: flag); + ffi.Void Function(ffi.Pointer<ffi.Void>, NSStream, + ffi.UnsignedLong)>(wrapper, retain: false, release: true); } } @@ -14461,6 +14381,7 @@ retain: false, release: true), NSError.castFromPointer(arg1, retain: false, release: true)), keepIsolateAlive); + final flag = objc.newDestroyedFlag(); final rawListener = objc.newClosureBlock( _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_blockingListenerCallable .nativeFunction @@ -14473,15 +14394,15 @@ : NSSecureCoding.castFromPointer(arg0, retain: false, release: true), NSError.castFromPointer(arg1, retain: false, release: true)), - keepIsolateAlive); - final flag = objc.newDestroyedFlag(); + keepIsolateAlive, + destroyedFlag: flag); final wrapper = _ObjectiveCBindings_wrapBlockingBlock_pfv6jd( raw, rawListener, flag, objc.objCContext); objc.objectRelease(raw.cast()); objc.objectRelease(rawListener.cast()); return objc.ObjCBlock< ffi.Void Function(ffi.Pointer<objc.ObjCObject>?, NSError)>(wrapper, - retain: false, release: true, destroyedFlag: flag); + retain: false, release: true); } } @@ -15408,7 +15329,6 @@ } } -late final _class_DOBJCAtomicBool = objc.getClass("DOBJCAtomicBool"); late final _class_DOBJCDartInputStreamAdapter = objc.getClass("DOBJCDartInputStreamAdapter"); late final _class_DOBJCDartProtocol = objc.getClass("DOBJCDartProtocol"); @@ -16369,14 +16289,6 @@ ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>)>(); -final _objc_msgSend_1s56lr9 = objc.msgSendPointer - .cast< - ffi.NativeFunction< - ffi.Void Function(ffi.Pointer<objc.ObjCObject>, - ffi.Pointer<objc.ObjCSelector>, ffi.Bool)>>() - .asFunction< - void Function(ffi.Pointer<objc.ObjCObject>, - ffi.Pointer<objc.ObjCSelector>, bool)>(); final _objc_msgSend_1sotr3r = objc.msgSendPointer .cast< ffi.NativeFunction< @@ -18334,7 +18246,6 @@ late final _sel_setSuggestedName_ = objc.registerName("setSuggestedName:"); late final _sel_setTemporaryResourceValue_forKey_ = objc.registerName("setTemporaryResourceValue:forKey:"); -late final _sel_setValue_ = objc.registerName("setValue:"); late final _sel_setWithArray_ = objc.registerName("setWithArray:"); late final _sel_setWithCapacity_ = objc.registerName("setWithCapacity:"); late final _sel_setWithObject_ = objc.registerName("setWithObject:"); @@ -18441,7 +18352,6 @@ objc.registerName("uppercaseStringWithLocale:"); late final _sel_user = objc.registerName("user"); late final _sel_userInfo = objc.registerName("userInfo"); -late final _sel_value = objc.registerName("value"); late final _sel_whitespaceAndNewlineCharacterSet = objc.registerName("whitespaceAndNewlineCharacterSet"); late final _sel_whitespaceCharacterSet =
diff --git a/pkgs/objective_c/src/atomic_bool.h b/pkgs/objective_c/src/atomic_bool.h deleted file mode 100644 index faffa1f..0000000 --- a/pkgs/objective_c/src/atomic_bool.h +++ /dev/null
@@ -1,9 +0,0 @@ -// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#import <Foundation/NSObject.h> - -@interface DOBJCAtomicBool : NSObject -@property(atomic) bool value; -@end
diff --git a/pkgs/objective_c/src/objective_c.c b/pkgs/objective_c/src/objective_c.c index db29980..90ec7b2 100644 --- a/pkgs/objective_c/src/objective_c.c +++ b/pkgs/objective_c/src/objective_c.c
@@ -5,6 +5,7 @@ #include "objective_c.h" #include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include "include/dart_api_dl.h" @@ -29,30 +30,9 @@ DOBJC_runOnMainThread((void (*)(void*))objc_release, peer); } -typedef struct { - ObjCObject* object; - void* destroyed_flag; -} _DOBJCObjectWithDestroyedFlag; - -FFI_EXPORT void DOBJC_finalizeObjectWithDestroyedFlag( - void* isolate_callback_data, _DOBJCObjectWithDestroyedFlag* pair) { - DOBJC_flipDestroyedFlag(pair->destroyed_flag); - DOBJC_runOnMainThread((void (*)(void*))objc_release, pair->object); - free(pair); -} - FFI_EXPORT Dart_FinalizableHandle -DOBJC_newFinalizableHandle( - Dart_Handle owner, ObjCObject* object, void* destroyed_flag) { - if (destroyed_flag == NULL) { - return Dart_NewFinalizableHandle_DL(owner, object, 0, DOBJC_finalizeObject); - } - _DOBJCObjectWithDestroyedFlag* pair = - malloc(sizeof(_DOBJCObjectWithDestroyedFlag)); - pair->object = object; - pair->destroyed_flag = destroyed_flag; - return Dart_NewFinalizableHandle_DL(owner, pair, 0, - (Dart_HandleFinalizer)DOBJC_finalizeObjectWithDestroyedFlag); +DOBJC_newFinalizableHandle(Dart_Handle owner, ObjCObject* object) { + return Dart_NewFinalizableHandle_DL(owner, object, 0, DOBJC_finalizeObject); } FFI_EXPORT void DOBJC_deleteFinalizableHandle(Dart_FinalizableHandle handle, @@ -71,6 +51,17 @@ return pointer; } +static void finalizeFlag(void* isolate_callback_data, void* peer) { + printf("\nZZZZ: finalizeFlag: %p\n", peer); + DOBJC_flipDestroyedFlag(peer); +} + +FFI_EXPORT Dart_FinalizableHandle +DOBJC_newFinalizableFlag(Dart_Handle owner, void* flag) { + printf("\nZZZZ: DOBJC_newFinalizableFlag: %p\n", flag); + return Dart_NewFinalizableHandle_DL(owner, flag, 0, finalizeFlag); +} + FFI_EXPORT intptr_t DOBJC_initializeApi(void* data) { return Dart_InitializeApiDL(data); }
diff --git a/pkgs/objective_c/src/objective_c.h b/pkgs/objective_c/src/objective_c.h index a94d1ee..2dead9f 100644 --- a/pkgs/objective_c/src/objective_c.h +++ b/pkgs/objective_c/src/objective_c.h
@@ -22,7 +22,7 @@ // Returns a new Dart_FinalizableHandle that will clean up the object when the // Dart owner is garbage collected. FFI_EXPORT Dart_FinalizableHandle DOBJC_newFinalizableHandle( - Dart_Handle owner, ObjCObject* object, void* destroyed_flag); + Dart_Handle owner, ObjCObject* object); // Delete a finalizable handle. Doesn't run the finalization callback, so // doesn't clean up the assocated pointer. @@ -50,13 +50,14 @@ FFI_EXPORT void DOBJC_awaitWaiter(void *waiter); // A destroyed flag is a DOBJCAtomicBool used to track whether a Dart object is -// still alive. DOBJC_newDestroyedFlag returns a +1 reference that is held in a -// _DOBJCObjectWithDestroyedFlag, and balanced by DOBJC_flipDestroyedFlag. Other -// code that needs to know whether the object is alive can cast it to a -// DOBJCAtomicBool, hold a strong reference to it (so it outlives the object it -// is tracking), and check its value. +// still alive. DOBJC_newDestroyedFlag returns a +1 reference that is balanced +// by DOBJC_flipDestroyedFlag. Other code that needs to know whether the object +// is alive can cast it to a DOBJCAtomicBool, hold a strong reference to it (so +// it outlives the object it is tracking), and check its value. FFI_EXPORT void *DOBJC_newDestroyedFlag(); FFI_EXPORT void DOBJC_flipDestroyedFlag(void* flag); +FFI_EXPORT Dart_FinalizableHandle DOBJC_newFinalizableFlag( + Dart_Handle owner, void* flag); // Context object containing functions needed by the ffigen bindings. Any // changes to this struct should bump the `version` field filled in by
diff --git a/pkgs/objective_c/src/objective_c.m b/pkgs/objective_c/src/objective_c.m index 5200cc0..e6fe093 100644 --- a/pkgs/objective_c/src/objective_c.m +++ b/pkgs/objective_c/src/objective_c.m
@@ -7,12 +7,9 @@ #import <Foundation/NSThread.h> #import <dispatch/dispatch.h> -#include "atomic_bool.h" #include "ffi.h" #include "os_version.h" -uint64_t getObjectRetainCount(void* object); - FFI_EXPORT void DOBJC_runOnMainThread(void (*fn)(void *), void *arg) { #ifdef NO_MAIN_THREAD_DISPATCH fn(arg); @@ -27,6 +24,10 @@ #endif } +@interface DOBJCAtomicBool : NSObject +@property(atomic) bool value; +@end + @implementation DOBJCAtomicBool -(instancetype)init { _value = false;
diff --git a/pkgs/objective_c/src/objective_c_bindings_generated.m b/pkgs/objective_c/src/objective_c_bindings_generated.m index e308fbd..d6cbfc3 100644 --- a/pkgs/objective_c/src/objective_c_bindings_generated.m +++ b/pkgs/objective_c/src/objective_c_bindings_generated.m
@@ -1,7 +1,6 @@ #include <stdint.h> #import <Foundation/Foundation.h> #import <objc/message.h> -#import "atomic_bool.h" #import "foundation.h" #import "input_stream_adapter.h" #import "protocol.h"