ObjCExport: don't use autorelease when sending arguments to Swift/Obj-C
This commit is contained in:
committed by
Space
parent
9326978327
commit
085e2448cd
-8
@@ -48,14 +48,6 @@ internal open class ObjCCodeGenerator(val codegen: CodeGenerator) {
|
|||||||
origin = context.stdlibModule.llvmSymbolOrigin
|
origin = context.stdlibModule.llvmSymbolOrigin
|
||||||
))
|
))
|
||||||
|
|
||||||
val objcAutorelease = context.llvm.externalFunction(LlvmFunctionProto(
|
|
||||||
"llvm.objc.autorelease",
|
|
||||||
LlvmRetType(int8TypePtr),
|
|
||||||
listOf(LlvmParamType(int8TypePtr)),
|
|
||||||
listOf(LlvmFunctionAttribute.NoUnwind),
|
|
||||||
origin = context.stdlibModule.llvmSymbolOrigin
|
|
||||||
))
|
|
||||||
|
|
||||||
val objcAutoreleaseReturnValue = context.llvm.externalFunction(LlvmFunctionProto(
|
val objcAutoreleaseReturnValue = context.llvm.externalFunction(LlvmFunctionProto(
|
||||||
"llvm.objc.autoreleaseReturnValue",
|
"llvm.objc.autoreleaseReturnValue",
|
||||||
LlvmRetType(int8TypePtr),
|
LlvmRetType(int8TypePtr),
|
||||||
|
|||||||
+10
-4
@@ -34,10 +34,6 @@ internal fun ObjCExportCodeGeneratorBase.generateBlockToKotlinFunctionConverter(
|
|||||||
LlvmFunctionSignature(invokeMethod, codegen),
|
LlvmFunctionSignature(invokeMethod, codegen),
|
||||||
"invokeFunction${bridge.nameSuffix}"
|
"invokeFunction${bridge.nameSuffix}"
|
||||||
).generate {
|
).generate {
|
||||||
val args = (0 until bridge.numberOfParameters).map { index ->
|
|
||||||
kotlinReferenceToLocalObjC(param(index + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
val thisRef = param(0)
|
val thisRef = param(0)
|
||||||
val associatedObjectHolder = if (useSeparateHolder) {
|
val associatedObjectHolder = if (useSeparateHolder) {
|
||||||
val bodyPtr = bitcast(pointerType(bodyType), thisRef)
|
val bodyPtr = bitcast(pointerType(bodyType), thisRef)
|
||||||
@@ -51,10 +47,20 @@ internal fun ObjCExportCodeGeneratorBase.generateBlockToKotlinFunctionConverter(
|
|||||||
)
|
)
|
||||||
|
|
||||||
val invoke = loadBlockInvoke(blockPtr, bridge)
|
val invoke = loadBlockInvoke(blockPtr, bridge)
|
||||||
|
|
||||||
|
val args = (0 until bridge.numberOfParameters).map { index ->
|
||||||
|
kotlinReferenceToRetainedObjC(param(index + 1))
|
||||||
|
}
|
||||||
|
|
||||||
switchThreadStateIfExperimentalMM(ThreadState.Native)
|
switchThreadStateIfExperimentalMM(ThreadState.Native)
|
||||||
// Using terminatingExceptionHandler, so any exception thrown by `invoke` will lead to the termination,
|
// Using terminatingExceptionHandler, so any exception thrown by `invoke` will lead to the termination,
|
||||||
// and switching the thread state back to `Runnable` on exceptional path is not required.
|
// and switching the thread state back to `Runnable` on exceptional path is not required.
|
||||||
val result = call(invoke, listOf(blockPtr) + args, exceptionHandler = terminatingExceptionHandler)
|
val result = call(invoke, listOf(blockPtr) + args, exceptionHandler = terminatingExceptionHandler)
|
||||||
|
|
||||||
|
args.forEach {
|
||||||
|
objcReleaseFromNativeThreadState(it)
|
||||||
|
}
|
||||||
|
|
||||||
switchThreadStateIfExperimentalMM(ThreadState.Runnable)
|
switchThreadStateIfExperimentalMM(ThreadState.Runnable)
|
||||||
|
|
||||||
val kotlinResult = if (bridge.returnsVoid) {
|
val kotlinResult = if (bridge.returnsVoid) {
|
||||||
|
|||||||
+33
-23
@@ -87,9 +87,13 @@ internal class ObjCExportFunctionGenerationContext(
|
|||||||
|
|
||||||
fun objcReleaseFromRunnableThreadState(objCReference: LLVMValueRef) {
|
fun objcReleaseFromRunnableThreadState(objCReference: LLVMValueRef) {
|
||||||
switchThreadStateIfExperimentalMM(ThreadState.Native)
|
switchThreadStateIfExperimentalMM(ThreadState.Native)
|
||||||
|
objcReleaseFromNativeThreadState(objCReference)
|
||||||
|
switchThreadStateIfExperimentalMM(ThreadState.Runnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun objcReleaseFromNativeThreadState(objCReference: LLVMValueRef) {
|
||||||
// It is nounwind, so no exception handler is required.
|
// It is nounwind, so no exception handler is required.
|
||||||
call(objCExportCodegen.objcRelease, listOf(objCReference), exceptionHandler = ExceptionHandler.None)
|
call(objCExportCodegen.objcRelease, listOf(objCReference), exceptionHandler = ExceptionHandler.None)
|
||||||
switchThreadStateIfExperimentalMM(ThreadState.Runnable)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processReturns() {
|
override fun processReturns() {
|
||||||
@@ -300,29 +304,11 @@ internal class ObjCExportCodeGenerator(
|
|||||||
resultLifetime
|
resultLifetime
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun ObjCExportFunctionGenerationContext.kotlinFunctionToObjCBlockPointer(
|
|
||||||
typeBridge: BlockPointerBridge,
|
|
||||||
value: LLVMValueRef
|
|
||||||
) = callFromBridge(objcAutorelease, listOf(kotlinFunctionToRetainedObjCBlockPointer(typeBridge, value)))
|
|
||||||
|
|
||||||
internal fun ObjCExportFunctionGenerationContext.kotlinFunctionToRetainedObjCBlockPointer(
|
internal fun ObjCExportFunctionGenerationContext.kotlinFunctionToRetainedObjCBlockPointer(
|
||||||
typeBridge: BlockPointerBridge,
|
typeBridge: BlockPointerBridge,
|
||||||
value: LLVMValueRef
|
value: LLVMValueRef
|
||||||
) = callFromBridge(kotlinFunctionToRetainedBlockConverter(typeBridge), listOf(value))
|
) = callFromBridge(kotlinFunctionToRetainedBlockConverter(typeBridge), listOf(value))
|
||||||
|
|
||||||
fun ObjCExportFunctionGenerationContext.kotlinToLocalObjC(
|
|
||||||
value: LLVMValueRef,
|
|
||||||
typeBridge: TypeBridge
|
|
||||||
): LLVMValueRef = if (LLVMTypeOf(value) == voidType) {
|
|
||||||
typeBridge.makeNothing()
|
|
||||||
} else {
|
|
||||||
when (typeBridge) {
|
|
||||||
is ReferenceBridge -> kotlinReferenceToLocalObjC(value)
|
|
||||||
is BlockPointerBridge -> kotlinFunctionToObjCBlockPointer(typeBridge, value) // TODO: use stack-allocated block here.
|
|
||||||
is ValueTypeBridge -> kotlinToObjC(value, typeBridge.objCValueType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ObjCExportFunctionGenerationContext.objCToKotlin(
|
fun ObjCExportFunctionGenerationContext.objCToKotlin(
|
||||||
value: LLVMValueRef,
|
value: LLVMValueRef,
|
||||||
typeBridge: TypeBridge,
|
typeBridge: TypeBridge,
|
||||||
@@ -1184,6 +1170,8 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
parameterDescriptor to param(index)
|
parameterDescriptor to param(index)
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
|
val objCReferenceArgsToRelease = mutableListOf<LLVMValueRef>()
|
||||||
|
|
||||||
val objCArgs = methodBridge.parametersAssociated(irFunction).map { (bridge, parameter) ->
|
val objCArgs = methodBridge.parametersAssociated(irFunction).map { (bridge, parameter) ->
|
||||||
when (bridge) {
|
when (bridge) {
|
||||||
is MethodBridgeValueParameter.Mapped -> {
|
is MethodBridgeValueParameter.Mapped -> {
|
||||||
@@ -1194,10 +1182,26 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
expectedType = parameterToBase[parameter]!!.type,
|
expectedType = parameterToBase[parameter]!!.type,
|
||||||
resultLifetime = Lifetime.ARGUMENT
|
resultLifetime = Lifetime.ARGUMENT
|
||||||
)
|
)
|
||||||
kotlinToLocalObjC(kotlinValue, bridge.bridge)
|
if (LLVMTypeOf(kotlinValue) == voidType) {
|
||||||
|
bridge.bridge.makeNothing()
|
||||||
|
} else {
|
||||||
|
when (bridge.bridge) {
|
||||||
|
is ReferenceBridge -> kotlinReferenceToRetainedObjC(kotlinValue).also { objCReferenceArgsToRelease += it }
|
||||||
|
is BlockPointerBridge -> kotlinFunctionToRetainedObjCBlockPointer(bridge.bridge, kotlinValue) // TODO: use stack-allocated block here.
|
||||||
|
.also { objCReferenceArgsToRelease += it }
|
||||||
|
is ValueTypeBridge -> kotlinToObjC(kotlinValue, bridge.bridge.objCValueType)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodBridgeReceiver.Instance -> kotlinReferenceToLocalObjC(parameters[parameter]!!)
|
MethodBridgeReceiver.Instance -> {
|
||||||
|
// `kotlinReferenceToLocalObjC` can add the result to autoreleasepool in some cases. But not here.
|
||||||
|
// Because this `parameter` is the receiver of a bridge in an Obj-C/Swift class extending
|
||||||
|
// Kotlin class or interface.
|
||||||
|
// So `kotlinReferenceToLocalObjC` here just unwraps the Obj-C reference
|
||||||
|
// without using autoreleasepool or any other reference counting operations.
|
||||||
|
kotlinReferenceToLocalObjC(parameters[parameter]!!)
|
||||||
|
}
|
||||||
MethodBridgeSelector -> {
|
MethodBridgeSelector -> {
|
||||||
val selector = baseMethod.selector
|
val selector = baseMethod.selector
|
||||||
// Selector is referenced thus should be defined to avoid false positive non-public API rejection:
|
// Selector is referenced thus should be defined to avoid false positive non-public API rejection:
|
||||||
@@ -1224,13 +1228,14 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
Lifetime.ARGUMENT
|
Lifetime.ARGUMENT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: use stack-allocated block here instead.
|
||||||
val converter = if (bridge.useUnitCompletion) {
|
val converter = if (bridge.useUnitCompletion) {
|
||||||
unitContinuationToRetainedCompletionConverter
|
unitContinuationToRetainedCompletionConverter
|
||||||
} else {
|
} else {
|
||||||
continuationToRetainedCompletionConverter
|
continuationToRetainedCompletionConverter
|
||||||
}
|
}
|
||||||
val retainedCompletion = callFromBridge(converter, listOf(intercepted))
|
callFromBridge(converter, listOf(intercepted))
|
||||||
callFromBridge(objcAutorelease, listOf(retainedCompletion)) // TODO: use stack-allocated block here instead.
|
.also { objCReferenceArgsToRelease += it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1239,6 +1244,11 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
// Using terminatingExceptionHandler, so any exception thrown by the method will lead to the termination,
|
// Using terminatingExceptionHandler, so any exception thrown by the method will lead to the termination,
|
||||||
// and switching the thread state back to `Runnable` on exceptional path is not required.
|
// and switching the thread state back to `Runnable` on exceptional path is not required.
|
||||||
val targetResult = call(objcMsgSend, objCArgs, exceptionHandler = terminatingExceptionHandler)
|
val targetResult = call(objcMsgSend, objCArgs, exceptionHandler = terminatingExceptionHandler)
|
||||||
|
|
||||||
|
objCReferenceArgsToRelease.forEach {
|
||||||
|
objcReleaseFromNativeThreadState(it)
|
||||||
|
}
|
||||||
|
|
||||||
switchThreadStateIfExperimentalMM(ThreadState.Runnable)
|
switchThreadStateIfExperimentalMM(ThreadState.Runnable)
|
||||||
|
|
||||||
assert(baseMethod.symbol !is IrConstructorSymbol)
|
assert(baseMethod.symbol !is IrConstructorSymbol)
|
||||||
|
|||||||
@@ -1020,11 +1020,18 @@ __attribute__((swift_name("NoAutoreleaseSendHelper")))
|
|||||||
@protocol KtNoAutoreleaseSendHelper
|
@protocol KtNoAutoreleaseSendHelper
|
||||||
@required
|
@required
|
||||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||||
|
- (void (^)(KtKotlinObject *))blockReceivingKotlinObject __attribute__((swift_name("blockReceivingKotlinObject()")));
|
||||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)sendCompletionWithCompletionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("sendCompletion(completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((swift_name("NoAutoreleaseReceiveHelper")))
|
__attribute__((swift_name("NoAutoreleaseReceiveHelper")))
|
||||||
@@ -1043,11 +1050,18 @@ __attribute__((swift_name("NoAutoreleaseKotlinSendHelper")))
|
|||||||
@interface KtNoAutoreleaseKotlinSendHelper : KtBase <KtNoAutoreleaseSendHelper>
|
@interface KtNoAutoreleaseKotlinSendHelper : KtBase <KtNoAutoreleaseSendHelper>
|
||||||
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
||||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||||
|
- (void (^)(KtKotlinObject *))blockReceivingKotlinObject __attribute__((swift_name("blockReceivingKotlinObject()")));
|
||||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)sendCompletionWithCompletionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("sendCompletion(completionHandler:)")));
|
||||||
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
@@ -1091,11 +1105,13 @@ __attribute__((swift_name("NoAutoreleaseKt")))
|
|||||||
@interface KtNoAutoreleaseKt : KtBase
|
@interface KtNoAutoreleaseKt : KtBase
|
||||||
+ (void)gc __attribute__((swift_name("gc()")));
|
+ (void)gc __attribute__((swift_name("gc()")));
|
||||||
+ (void)callSendKotlinObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendKotlinObject(helper:tracker:)")));
|
+ (void)callSendKotlinObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendKotlinObject(helper:tracker:)")));
|
||||||
|
+ (void)sendKotlinObjectToBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("sendKotlinObjectToBlock(helper:tracker:)")));
|
||||||
+ (void)callSendSwiftObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker swiftObject:(id)swiftObject __attribute__((swift_name("callSendSwiftObject(helper:tracker:swiftObject:)")));
|
+ (void)callSendSwiftObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker swiftObject:(id)swiftObject __attribute__((swift_name("callSendSwiftObject(helper:tracker:swiftObject:)")));
|
||||||
+ (void)callSendListHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendList(helper:tracker:)")));
|
+ (void)callSendListHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendList(helper:tracker:)")));
|
||||||
+ (void)callSendStringHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendString(helper:tracker:)")));
|
+ (void)callSendStringHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendString(helper:tracker:)")));
|
||||||
+ (void)callSendNumberHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendNumber(helper:tracker:)")));
|
+ (void)callSendNumberHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendNumber(helper:tracker:)")));
|
||||||
+ (void)callSendBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendBlock(helper:tracker:)")));
|
+ (void)callSendBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendBlock(helper:tracker:)")));
|
||||||
|
+ (void)callSendCompletionHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendCompletion(helper:tracker:)")));
|
||||||
+ (void)callReceiveKotlinObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveKotlinObject(helper:tracker:)")));
|
+ (void)callReceiveKotlinObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveKotlinObject(helper:tracker:)")));
|
||||||
+ (void)callReceiveSwiftObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveSwiftObject(helper:tracker:)")));
|
+ (void)callReceiveSwiftObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveSwiftObject(helper:tracker:)")));
|
||||||
+ (void)callReceiveListHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveList(helper:tracker:)")));
|
+ (void)callReceiveListHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveList(helper:tracker:)")));
|
||||||
|
|||||||
@@ -962,11 +962,18 @@ __attribute__((swift_name("NoAutoreleaseSendHelper")))
|
|||||||
@protocol KtNoAutoreleaseSendHelper
|
@protocol KtNoAutoreleaseSendHelper
|
||||||
@required
|
@required
|
||||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||||
|
- (void (^)(KtKotlinObject *))blockReceivingKotlinObject __attribute__((swift_name("blockReceivingKotlinObject()")));
|
||||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)sendCompletionWithCompletionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("sendCompletion(completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((swift_name("NoAutoreleaseReceiveHelper")))
|
__attribute__((swift_name("NoAutoreleaseReceiveHelper")))
|
||||||
@@ -985,11 +992,18 @@ __attribute__((swift_name("NoAutoreleaseKotlinSendHelper")))
|
|||||||
@interface KtNoAutoreleaseKotlinSendHelper : KtBase <KtNoAutoreleaseSendHelper>
|
@interface KtNoAutoreleaseKotlinSendHelper : KtBase <KtNoAutoreleaseSendHelper>
|
||||||
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
||||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||||
|
- (void (^)(KtKotlinObject *))blockReceivingKotlinObject __attribute__((swift_name("blockReceivingKotlinObject()")));
|
||||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)sendCompletionWithCompletionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("sendCompletion(completionHandler:)")));
|
||||||
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
@@ -1033,11 +1047,13 @@ __attribute__((swift_name("NoAutoreleaseKt")))
|
|||||||
@interface KtNoAutoreleaseKt : KtBase
|
@interface KtNoAutoreleaseKt : KtBase
|
||||||
+ (void)gc __attribute__((swift_name("gc()")));
|
+ (void)gc __attribute__((swift_name("gc()")));
|
||||||
+ (void)callSendKotlinObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendKotlinObject(helper:tracker:)")));
|
+ (void)callSendKotlinObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendKotlinObject(helper:tracker:)")));
|
||||||
|
+ (void)sendKotlinObjectToBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("sendKotlinObjectToBlock(helper:tracker:)")));
|
||||||
+ (void)callSendSwiftObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker swiftObject:(id)swiftObject __attribute__((swift_name("callSendSwiftObject(helper:tracker:swiftObject:)")));
|
+ (void)callSendSwiftObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker swiftObject:(id)swiftObject __attribute__((swift_name("callSendSwiftObject(helper:tracker:swiftObject:)")));
|
||||||
+ (void)callSendListHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendList(helper:tracker:)")));
|
+ (void)callSendListHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendList(helper:tracker:)")));
|
||||||
+ (void)callSendStringHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendString(helper:tracker:)")));
|
+ (void)callSendStringHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendString(helper:tracker:)")));
|
||||||
+ (void)callSendNumberHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendNumber(helper:tracker:)")));
|
+ (void)callSendNumberHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendNumber(helper:tracker:)")));
|
||||||
+ (void)callSendBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendBlock(helper:tracker:)")));
|
+ (void)callSendBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendBlock(helper:tracker:)")));
|
||||||
|
+ (void)callSendCompletionHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendCompletion(helper:tracker:)")));
|
||||||
+ (void)callReceiveKotlinObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveKotlinObject(helper:tracker:)")));
|
+ (void)callReceiveKotlinObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveKotlinObject(helper:tracker:)")));
|
||||||
+ (void)callReceiveSwiftObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveSwiftObject(helper:tracker:)")));
|
+ (void)callReceiveSwiftObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveSwiftObject(helper:tracker:)")));
|
||||||
+ (void)callReceiveListHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveList(helper:tracker:)")));
|
+ (void)callReceiveListHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveList(helper:tracker:)")));
|
||||||
|
|||||||
@@ -962,11 +962,18 @@ __attribute__((swift_name("NoAutoreleaseSendHelper")))
|
|||||||
@protocol KtNoAutoreleaseSendHelper
|
@protocol KtNoAutoreleaseSendHelper
|
||||||
@required
|
@required
|
||||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||||
|
- (void (^)(KtKotlinObject *))blockReceivingKotlinObject __attribute__((swift_name("blockReceivingKotlinObject()")));
|
||||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)sendCompletionWithCompletionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("sendCompletion(completionHandler:)")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
__attribute__((swift_name("NoAutoreleaseReceiveHelper")))
|
__attribute__((swift_name("NoAutoreleaseReceiveHelper")))
|
||||||
@@ -985,11 +992,18 @@ __attribute__((swift_name("NoAutoreleaseKotlinSendHelper")))
|
|||||||
@interface KtNoAutoreleaseKotlinSendHelper : KtBase <KtNoAutoreleaseSendHelper>
|
@interface KtNoAutoreleaseKotlinSendHelper : KtBase <KtNoAutoreleaseSendHelper>
|
||||||
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
- (instancetype)initWithKotlinLivenessTracker:(KtKotlinLivenessTracker *)kotlinLivenessTracker __attribute__((swift_name("init(kotlinLivenessTracker:)"))) __attribute__((objc_designated_initializer));
|
||||||
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
- (void)sendKotlinObjectKotlinObject:(KtKotlinObject *)kotlinObject __attribute__((swift_name("sendKotlinObject(kotlinObject:)")));
|
||||||
|
- (void (^)(KtKotlinObject *))blockReceivingKotlinObject __attribute__((swift_name("blockReceivingKotlinObject()")));
|
||||||
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
- (void)sendSwiftObjectSwiftObject:(id)swiftObject __attribute__((swift_name("sendSwiftObject(swiftObject:)")));
|
||||||
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
- (void)sendListList:(NSArray<id> *)list __attribute__((swift_name("sendList(list:)")));
|
||||||
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
- (void)sendStringString:(NSString *)string __attribute__((swift_name("sendString(string:)")));
|
||||||
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
- (void)sendNumberNumber:(id)number __attribute__((swift_name("sendNumber(number:)")));
|
||||||
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
- (void)sendBlockBlock:(KtKotlinObject *(^)(void))block __attribute__((swift_name("sendBlock(block:)")));
|
||||||
|
|
||||||
|
/**
|
||||||
|
@note This method converts instances of CancellationException to errors.
|
||||||
|
Other uncaught Kotlin exceptions are fatal.
|
||||||
|
*/
|
||||||
|
- (void)sendCompletionWithCompletionHandler:(void (^)(id _Nullable_result, NSError * _Nullable))completionHandler __attribute__((swift_name("sendCompletion(completionHandler:)")));
|
||||||
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
@property (readonly) KtKotlinLivenessTracker *kotlinLivenessTracker __attribute__((swift_name("kotlinLivenessTracker")));
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
@@ -1033,11 +1047,13 @@ __attribute__((swift_name("NoAutoreleaseKt")))
|
|||||||
@interface KtNoAutoreleaseKt : KtBase
|
@interface KtNoAutoreleaseKt : KtBase
|
||||||
+ (void)gc __attribute__((swift_name("gc()")));
|
+ (void)gc __attribute__((swift_name("gc()")));
|
||||||
+ (void)callSendKotlinObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendKotlinObject(helper:tracker:)")));
|
+ (void)callSendKotlinObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendKotlinObject(helper:tracker:)")));
|
||||||
|
+ (void)sendKotlinObjectToBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("sendKotlinObjectToBlock(helper:tracker:)")));
|
||||||
+ (void)callSendSwiftObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker swiftObject:(id)swiftObject __attribute__((swift_name("callSendSwiftObject(helper:tracker:swiftObject:)")));
|
+ (void)callSendSwiftObjectHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker swiftObject:(id)swiftObject __attribute__((swift_name("callSendSwiftObject(helper:tracker:swiftObject:)")));
|
||||||
+ (void)callSendListHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendList(helper:tracker:)")));
|
+ (void)callSendListHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendList(helper:tracker:)")));
|
||||||
+ (void)callSendStringHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendString(helper:tracker:)")));
|
+ (void)callSendStringHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendString(helper:tracker:)")));
|
||||||
+ (void)callSendNumberHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendNumber(helper:tracker:)")));
|
+ (void)callSendNumberHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendNumber(helper:tracker:)")));
|
||||||
+ (void)callSendBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendBlock(helper:tracker:)")));
|
+ (void)callSendBlockHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendBlock(helper:tracker:)")));
|
||||||
|
+ (void)callSendCompletionHelper:(id<KtNoAutoreleaseSendHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callSendCompletion(helper:tracker:)")));
|
||||||
+ (void)callReceiveKotlinObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveKotlinObject(helper:tracker:)")));
|
+ (void)callReceiveKotlinObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveKotlinObject(helper:tracker:)")));
|
||||||
+ (void)callReceiveSwiftObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveSwiftObject(helper:tracker:)")));
|
+ (void)callReceiveSwiftObjectHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveSwiftObject(helper:tracker:)")));
|
||||||
+ (void)callReceiveListHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveList(helper:tracker:)")));
|
+ (void)callReceiveListHelper:(id<KtNoAutoreleaseReceiveHelper>)helper tracker:(KtKotlinLivenessTracker *)tracker __attribute__((swift_name("callReceiveList(helper:tracker:)")));
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package noAutorelease
|
package noAutorelease
|
||||||
|
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
import kotlin.coroutines.intrinsics.*
|
||||||
import kotlin.native.internal.NativePtr
|
import kotlin.native.internal.NativePtr
|
||||||
import kotlin.native.ref.WeakReference
|
import kotlin.native.ref.WeakReference
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
@@ -23,11 +25,13 @@ class KotlinObject
|
|||||||
|
|
||||||
interface NoAutoreleaseSendHelper {
|
interface NoAutoreleaseSendHelper {
|
||||||
fun sendKotlinObject(kotlinObject: KotlinObject)
|
fun sendKotlinObject(kotlinObject: KotlinObject)
|
||||||
|
fun blockReceivingKotlinObject(): (KotlinObject) -> Unit
|
||||||
fun sendSwiftObject(swiftObject: Any)
|
fun sendSwiftObject(swiftObject: Any)
|
||||||
fun sendList(list: List<*>)
|
fun sendList(list: List<*>)
|
||||||
fun sendString(string: String)
|
fun sendString(string: String)
|
||||||
fun sendNumber(number: Any)
|
fun sendNumber(number: Any)
|
||||||
fun sendBlock(block: () -> KotlinObject)
|
fun sendBlock(block: () -> KotlinObject)
|
||||||
|
suspend fun sendCompletion(): Any?
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NoAutoreleaseReceiveHelper {
|
interface NoAutoreleaseReceiveHelper {
|
||||||
@@ -41,11 +45,16 @@ interface NoAutoreleaseReceiveHelper {
|
|||||||
|
|
||||||
class NoAutoreleaseKotlinSendHelper(val kotlinLivenessTracker: KotlinLivenessTracker) : NoAutoreleaseSendHelper {
|
class NoAutoreleaseKotlinSendHelper(val kotlinLivenessTracker: KotlinLivenessTracker) : NoAutoreleaseSendHelper {
|
||||||
override fun sendKotlinObject(kotlinObject: KotlinObject) = kotlinLivenessTracker.add(kotlinObject)
|
override fun sendKotlinObject(kotlinObject: KotlinObject) = kotlinLivenessTracker.add(kotlinObject)
|
||||||
|
override fun blockReceivingKotlinObject(): (KotlinObject) -> Unit = { kotlinLivenessTracker.add(it) }
|
||||||
override fun sendSwiftObject(swiftObject: Any) = kotlinLivenessTracker.add(swiftObject)
|
override fun sendSwiftObject(swiftObject: Any) = kotlinLivenessTracker.add(swiftObject)
|
||||||
override fun sendList(list: List<*>) = kotlinLivenessTracker.add(list)
|
override fun sendList(list: List<*>) = kotlinLivenessTracker.add(list)
|
||||||
override fun sendString(string: String) = kotlinLivenessTracker.add(string)
|
override fun sendString(string: String) = kotlinLivenessTracker.add(string)
|
||||||
override fun sendNumber(number: Any) = kotlinLivenessTracker.add(number)
|
override fun sendNumber(number: Any) = kotlinLivenessTracker.add(number)
|
||||||
override fun sendBlock(block: () -> KotlinObject) = kotlinLivenessTracker.add(block)
|
override fun sendBlock(block: () -> KotlinObject) = kotlinLivenessTracker.add(block)
|
||||||
|
override suspend fun sendCompletion() = suspendCoroutineUninterceptedOrReturn<Any?> { continuation ->
|
||||||
|
kotlinLivenessTracker.add(continuation)
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NoAutoreleaseKotlinReceiveHelper(val kotlinLivenessTracker: KotlinLivenessTracker) : NoAutoreleaseReceiveHelper {
|
class NoAutoreleaseKotlinReceiveHelper(val kotlinLivenessTracker: KotlinLivenessTracker) : NoAutoreleaseReceiveHelper {
|
||||||
@@ -82,6 +91,14 @@ fun callSendKotlinObject(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenes
|
|||||||
tracker.add(kotlinObject)
|
tracker.add(kotlinObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun sendKotlinObjectToBlock(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker) {
|
||||||
|
val kotlinObject = KotlinObject()
|
||||||
|
|
||||||
|
helper.blockReceivingKotlinObject()(kotlinObject)
|
||||||
|
helper.blockReceivingKotlinObject()(kotlinObject)
|
||||||
|
tracker.add(kotlinObject)
|
||||||
|
}
|
||||||
|
|
||||||
fun callSendSwiftObject(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker, swiftObject: Any) {
|
fun callSendSwiftObject(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker, swiftObject: Any) {
|
||||||
helper.sendSwiftObject(swiftObject)
|
helper.sendSwiftObject(swiftObject)
|
||||||
helper.sendSwiftObject(swiftObject)
|
helper.sendSwiftObject(swiftObject)
|
||||||
@@ -120,6 +137,22 @@ fun callSendBlock(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracke
|
|||||||
tracker.add(block)
|
tracker.add(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class EmptyContinuation : Continuation<Any?> {
|
||||||
|
override val context: CoroutineContext = EmptyCoroutineContext
|
||||||
|
override fun resumeWith(result: Result<Any?>) { result.getOrThrow() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun callSendCompletion(helper: NoAutoreleaseSendHelper, tracker: KotlinLivenessTracker) {
|
||||||
|
val completion = EmptyContinuation()
|
||||||
|
|
||||||
|
suspend {
|
||||||
|
helper.sendCompletion()
|
||||||
|
helper.sendCompletion()
|
||||||
|
}.startCoroutine(completion)
|
||||||
|
|
||||||
|
tracker.add(completion)
|
||||||
|
}
|
||||||
|
|
||||||
fun callReceiveKotlinObject(helper: NoAutoreleaseReceiveHelper, tracker: KotlinLivenessTracker) = repeat(2) {
|
fun callReceiveKotlinObject(helper: NoAutoreleaseReceiveHelper, tracker: KotlinLivenessTracker) = repeat(2) {
|
||||||
tracker.add(helper.receiveKotlinObject())
|
tracker.add(helper.receiveKotlinObject())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ private class NoAutoreleaseSwiftHelper : NoAutoreleaseSendHelper, NoAutoreleaseR
|
|||||||
swiftLivenessTracker.add(kotlinObject)
|
swiftLivenessTracker.add(kotlinObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func blockReceivingKotlinObject() -> (KotlinObject) -> Void {
|
||||||
|
return {
|
||||||
|
self.swiftLivenessTracker.add($0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func sendSwiftObject(swiftObject: Any) {
|
func sendSwiftObject(swiftObject: Any) {
|
||||||
swiftLivenessTracker.add(swiftObject as AnyObject)
|
swiftLivenessTracker.add(swiftObject as AnyObject)
|
||||||
}
|
}
|
||||||
@@ -57,6 +63,10 @@ private class NoAutoreleaseSwiftHelper : NoAutoreleaseSendHelper, NoAutoreleaseR
|
|||||||
func sendBlock(block: @escaping () -> KotlinObject) {
|
func sendBlock(block: @escaping () -> KotlinObject) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendCompletion(completionHandler: @escaping (Any?, Error?) -> Void) {
|
||||||
|
completionHandler(nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
let kotlinObject = KotlinObject()
|
let kotlinObject = KotlinObject()
|
||||||
let swiftObject = SwiftObject2()
|
let swiftObject = SwiftObject2()
|
||||||
let list = createList()
|
let list = createList()
|
||||||
@@ -220,6 +230,12 @@ private func testSendKotlinObjectToKotlin() throws {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func testSendKotlinObjectToKotlinBlock() throws {
|
||||||
|
try testSendToKotlin({ KotlinObject() }) {
|
||||||
|
$0.blockReceivingKotlinObject()($1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func testSendSwiftObjectToKotlin() throws {
|
private func testSendSwiftObjectToKotlin() throws {
|
||||||
try testSendToKotlin({ SwiftObject1() }) {
|
try testSendToKotlin({ SwiftObject1() }) {
|
||||||
$0.sendSwiftObject(swiftObject: $1)
|
$0.sendSwiftObject(swiftObject: $1)
|
||||||
@@ -250,6 +266,12 @@ private func testSendBlockToKotlin() throws {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func testSendCompletionToKotlin() throws {
|
||||||
|
try testSendToKotlin({ createCompletion() }, flags: TestFlags(trackSwiftLifetime: false)) {
|
||||||
|
$0.sendCompletion(completionHandler: $1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func testReceiveKotlinObjectFromKotlin() throws {
|
private func testReceiveKotlinObjectFromKotlin() throws {
|
||||||
try testReceiveFromKotlin {
|
try testReceiveFromKotlin {
|
||||||
$0.receiveKotlinObject()
|
$0.receiveKotlinObject()
|
||||||
@@ -328,6 +350,15 @@ private func testSendKotlinObjectToSwift() throws {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func testSendKotlinObjectToSwiftBlock() throws {
|
||||||
|
// Getting Swift block in Kotlin still adds it to the autoreleasepool.
|
||||||
|
// The block is not our target, so just use `checkAutorelease: false` flag
|
||||||
|
// to disable the relevant check for now.
|
||||||
|
try testCallToSwift(flags: TestFlags(checkAutorelease: false)) {
|
||||||
|
NoAutoreleaseKt.sendKotlinObjectToBlock(helper: $0, tracker: $1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func testSendSwiftObjectToSwift() throws {
|
private func testSendSwiftObjectToSwift() throws {
|
||||||
try testCallToSwift {
|
try testCallToSwift {
|
||||||
NoAutoreleaseKt.callSendSwiftObject(helper: $0, tracker: $1, swiftObject: SwiftObject4())
|
NoAutoreleaseKt.callSendSwiftObject(helper: $0, tracker: $1, swiftObject: SwiftObject4())
|
||||||
@@ -361,6 +392,12 @@ private func testSendBlockToSwift() throws {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func testSendCompletionToSwift() throws {
|
||||||
|
try testCallToSwift(flags: TestFlags(trackSwiftLifetime: false)) {
|
||||||
|
NoAutoreleaseKt.callSendCompletion(helper: $0, tracker: $1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func testReceiveKotlinObjectFromSwift() throws {
|
private func testReceiveKotlinObjectFromSwift() throws {
|
||||||
try testCallToSwift(flags: TestFlags(runGCTwice: true)) {
|
try testCallToSwift(flags: TestFlags(runGCTwice: true)) {
|
||||||
NoAutoreleaseKt.callReceiveKotlinObject(helper: $0, tracker: $1)
|
NoAutoreleaseKt.callReceiveKotlinObject(helper: $0, tracker: $1)
|
||||||
@@ -421,6 +458,10 @@ private func createBlock(swiftLivenessTracker: SwiftLivenessTracker) -> () -> Ko
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func createCompletion() -> (Any?, Error?) -> Void {
|
||||||
|
return { _, _ in }
|
||||||
|
}
|
||||||
|
|
||||||
private func createString() -> String {
|
private func createString() -> String {
|
||||||
return NSObject().description // Make it dynamic.
|
return NSObject().description // Make it dynamic.
|
||||||
}
|
}
|
||||||
@@ -434,11 +475,13 @@ class NoAutoreleaseTests : SimpleTestProvider {
|
|||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
test("testSendKotlinObjectToKotlin", testSendKotlinObjectToKotlin)
|
test("testSendKotlinObjectToKotlin", testSendKotlinObjectToKotlin)
|
||||||
|
test("testSendKotlinObjectToKotlinBlock", testSendKotlinObjectToKotlinBlock)
|
||||||
test("testSendSwiftObjectToKotlin", testSendSwiftObjectToKotlin)
|
test("testSendSwiftObjectToKotlin", testSendSwiftObjectToKotlin)
|
||||||
test("testSendListToKotlin", testSendListToKotlin)
|
test("testSendListToKotlin", testSendListToKotlin)
|
||||||
test("testSendStringToKotlin", testSendStringToKotlin)
|
test("testSendStringToKotlin", testSendStringToKotlin)
|
||||||
test("testSendNumberToKotlin", testSendNumberToKotlin)
|
test("testSendNumberToKotlin", testSendNumberToKotlin)
|
||||||
test("testSendBlockToKotlin", testSendBlockToKotlin)
|
test("testSendBlockToKotlin", testSendBlockToKotlin)
|
||||||
|
test("testSendCompletionToKotlin", testSendCompletionToKotlin)
|
||||||
|
|
||||||
test("testReceiveKotlinObjectFromKotlin", testReceiveKotlinObjectFromKotlin)
|
test("testReceiveKotlinObjectFromKotlin", testReceiveKotlinObjectFromKotlin)
|
||||||
test("testReceiveSwiftObjectFromKotlin", testReceiveSwiftObjectFromKotlin)
|
test("testReceiveSwiftObjectFromKotlin", testReceiveSwiftObjectFromKotlin)
|
||||||
@@ -454,18 +497,16 @@ class NoAutoreleaseTests : SimpleTestProvider {
|
|||||||
test("testGetKotlinSingleton", testGetKotlinSingleton)
|
test("testGetKotlinSingleton", testGetKotlinSingleton)
|
||||||
test("testGetKotlinEnumEntry", testGetKotlinEnumEntry)
|
test("testGetKotlinEnumEntry", testGetKotlinEnumEntry)
|
||||||
|
|
||||||
#if false
|
|
||||||
test("testSendKotlinObjectToSwift", testSendKotlinObjectToSwift)
|
test("testSendKotlinObjectToSwift", testSendKotlinObjectToSwift)
|
||||||
#endif
|
test("testSendKotlinObjectToSwiftBlock", testSendKotlinObjectToSwiftBlock)
|
||||||
|
|
||||||
test("testSendSwiftObjectToSwift", testSendSwiftObjectToSwift)
|
test("testSendSwiftObjectToSwift", testSendSwiftObjectToSwift)
|
||||||
|
|
||||||
#if false
|
|
||||||
test("testSendListToSwift", testSendListToSwift)
|
test("testSendListToSwift", testSendListToSwift)
|
||||||
test("testSendStringToSwift", testSendStringToSwift)
|
test("testSendStringToSwift", testSendStringToSwift)
|
||||||
test("testSendNumberToSwift", testSendNumberToSwift)
|
test("testSendNumberToSwift", testSendNumberToSwift)
|
||||||
test("testSendBlockToSwift", testSendBlockToSwift)
|
test("testSendBlockToSwift", testSendBlockToSwift)
|
||||||
|
test("testSendCompletionToSwift", testSendCompletionToSwift)
|
||||||
|
|
||||||
|
#if false
|
||||||
test("testReceiveKotlinObjectFromSwift", testReceiveKotlinObjectFromSwift)
|
test("testReceiveKotlinObjectFromSwift", testReceiveKotlinObjectFromSwift)
|
||||||
test("testReceiveSwiftObjectFromSwift", testReceiveSwiftObjectFromSwift)
|
test("testReceiveSwiftObjectFromSwift", testReceiveSwiftObjectFromSwift)
|
||||||
test("testReceiveListFromSwift", testReceiveListFromSwift)
|
test("testReceiveListFromSwift", testReceiveListFromSwift)
|
||||||
|
|||||||
Reference in New Issue
Block a user