[K/N] More meaningful names in objc2kotlin bridges
Now also for throwableAsError, unit accessor and abstract methods.
This commit is contained in:
+19
-21
@@ -315,13 +315,6 @@ internal class ObjCExportCodeGenerator(
|
|||||||
generateUnitContinuationToRetainedCompletionConverter(blockGenerator)
|
generateUnitContinuationToRetainedCompletionConverter(blockGenerator)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun meaningfulBridgeNameOrNull(irFunction: IrFunction?): String? {
|
|
||||||
if (!context.config.configuration.getBoolean(KonanConfigKeys.MEANINGFUL_BRIDGE_NAMES)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return irFunction?.name?.asString()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caution! Arbitrary methods shouldn't be called from Runnable thread state.
|
// Caution! Arbitrary methods shouldn't be called from Runnable thread state.
|
||||||
fun ObjCExportFunctionGenerationContext.genSendMessage(
|
fun ObjCExportFunctionGenerationContext.genSendMessage(
|
||||||
returnType: LlvmParamType,
|
returnType: LlvmParamType,
|
||||||
@@ -954,11 +947,11 @@ private fun ObjCExportFunctionGenerationContextBuilder.setupBridgeDebugInfo() {
|
|||||||
private inline fun ObjCExportCodeGenerator.generateObjCImpBy(
|
private inline fun ObjCExportCodeGenerator.generateObjCImpBy(
|
||||||
methodBridge: MethodBridge,
|
methodBridge: MethodBridge,
|
||||||
debugInfo: Boolean = false,
|
debugInfo: Boolean = false,
|
||||||
suffix: String? = null,
|
suffix: String,
|
||||||
genBody: ObjCExportFunctionGenerationContext.() -> Unit
|
genBody: ObjCExportFunctionGenerationContext.() -> Unit
|
||||||
): LLVMValueRef {
|
): LLVMValueRef {
|
||||||
val functionType = objCFunctionType(context, methodBridge)
|
val functionType = objCFunctionType(context, methodBridge)
|
||||||
val functionName = "objc2kotlin" + (suffix?.let { "_$it" } ?: "")
|
val functionName = "objc2kotlin_$suffix"
|
||||||
val result = functionGenerator(functionType, functionName) {
|
val result = functionGenerator(functionType, functionName) {
|
||||||
if (debugInfo) {
|
if (debugInfo) {
|
||||||
this.setupBridgeDebugInfo()
|
this.setupBridgeDebugInfo()
|
||||||
@@ -973,8 +966,8 @@ private inline fun ObjCExportCodeGenerator.generateObjCImpBy(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.generateAbstractObjCImp(methodBridge: MethodBridge): LLVMValueRef =
|
private fun ObjCExportCodeGenerator.generateAbstractObjCImp(methodBridge: MethodBridge, baseMethod: IrFunction): LLVMValueRef =
|
||||||
generateObjCImpBy(methodBridge) {
|
generateObjCImpBy(methodBridge, suffix = baseMethod.computeSymbolName()) {
|
||||||
callFromBridge(
|
callFromBridge(
|
||||||
context.llvm.Kotlin_ObjCExport_AbstractMethodCalled,
|
context.llvm.Kotlin_ObjCExport_AbstractMethodCalled,
|
||||||
listOf(param(0), param(1))
|
listOf(param(0), param(1))
|
||||||
@@ -988,12 +981,13 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
|
|||||||
methodBridge: MethodBridge,
|
methodBridge: MethodBridge,
|
||||||
isVirtual: Boolean = false
|
isVirtual: Boolean = false
|
||||||
) = if (target == null) {
|
) = if (target == null) {
|
||||||
generateAbstractObjCImp(methodBridge)
|
generateAbstractObjCImp(methodBridge, baseMethod)
|
||||||
} else {
|
} else {
|
||||||
generateObjCImp(
|
generateObjCImp(
|
||||||
methodBridge,
|
methodBridge,
|
||||||
isDirect = !isVirtual,
|
isDirect = !isVirtual,
|
||||||
baseMethod = baseMethod
|
baseMethod = baseMethod,
|
||||||
|
bridgeSuffix = (if (isVirtual) "virtual_" else "") + target.computeSymbolName()
|
||||||
) { args, resultLifetime, exceptionHandler ->
|
) { args, resultLifetime, exceptionHandler ->
|
||||||
if (target is IrConstructor && target.constructedClass.isAbstract()) {
|
if (target is IrConstructor && target.constructedClass.isAbstract()) {
|
||||||
callFromBridge(
|
callFromBridge(
|
||||||
@@ -1014,6 +1008,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
|
|||||||
methodBridge: MethodBridge,
|
methodBridge: MethodBridge,
|
||||||
isDirect: Boolean,
|
isDirect: Boolean,
|
||||||
baseMethod: IrFunction? = null,
|
baseMethod: IrFunction? = null,
|
||||||
|
bridgeSuffix: String,
|
||||||
callKotlin: ObjCExportFunctionGenerationContext.(
|
callKotlin: ObjCExportFunctionGenerationContext.(
|
||||||
args: List<LLVMValueRef>,
|
args: List<LLVMValueRef>,
|
||||||
resultLifetime: Lifetime,
|
resultLifetime: Lifetime,
|
||||||
@@ -1022,7 +1017,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
|
|||||||
): LLVMValueRef = generateObjCImpBy(
|
): LLVMValueRef = generateObjCImpBy(
|
||||||
methodBridge,
|
methodBridge,
|
||||||
debugInfo = isDirect /* see below */,
|
debugInfo = isDirect /* see below */,
|
||||||
suffix = meaningfulBridgeNameOrNull(baseMethod)
|
suffix = bridgeSuffix,
|
||||||
) {
|
) {
|
||||||
// Considering direct calls inlinable above. If such a call is inlined into a bridge with no debug information,
|
// Considering direct calls inlinable above. If such a call is inlined into a bridge with no debug information,
|
||||||
// lldb will not decode the inlined frame even if the callee has debug information.
|
// lldb will not decode the inlined frame even if the callee has debug information.
|
||||||
@@ -1207,7 +1202,7 @@ private fun effectiveThrowsClasses(method: IrFunction, symbols: KonanSymbols): L
|
|||||||
private fun ObjCExportCodeGenerator.generateObjCImpForArrayConstructor(
|
private fun ObjCExportCodeGenerator.generateObjCImpForArrayConstructor(
|
||||||
target: IrConstructor,
|
target: IrConstructor,
|
||||||
methodBridge: MethodBridge
|
methodBridge: MethodBridge
|
||||||
): LLVMValueRef = generateObjCImp(methodBridge, isDirect = true) { args, resultLifetime, exceptionHandler ->
|
): LLVMValueRef = generateObjCImp(methodBridge, bridgeSuffix = target.computeSymbolName(), isDirect = true) { args, resultLifetime, exceptionHandler ->
|
||||||
val arrayInstance = callFromBridge(
|
val arrayInstance = callFromBridge(
|
||||||
context.llvm.allocArrayFunction,
|
context.llvm.allocArrayFunction,
|
||||||
listOf(target.constructedClass.llvmTypeInfoPtr, args.first()),
|
listOf(target.constructedClass.llvmTypeInfoPtr, args.first()),
|
||||||
@@ -1806,6 +1801,7 @@ private fun findImplementation(irClass: IrClass, method: IrSimpleFunction, conte
|
|||||||
|
|
||||||
private inline fun ObjCExportCodeGenerator.generateObjCToKotlinSyntheticGetter(
|
private inline fun ObjCExportCodeGenerator.generateObjCToKotlinSyntheticGetter(
|
||||||
selector: String,
|
selector: String,
|
||||||
|
suffix: String,
|
||||||
block: ObjCExportFunctionGenerationContext.() -> Unit
|
block: ObjCExportFunctionGenerationContext.() -> Unit
|
||||||
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
||||||
|
|
||||||
@@ -1815,13 +1811,14 @@ private inline fun ObjCExportCodeGenerator.generateObjCToKotlinSyntheticGetter(
|
|||||||
)
|
)
|
||||||
|
|
||||||
val functionType = objCFunctionType(context, methodBridge)
|
val functionType = objCFunctionType(context, methodBridge)
|
||||||
val imp = functionGenerator(functionType, "objc2kotlin") {
|
val functionName = "objc2kotlin_$suffix"
|
||||||
|
val imp = functionGenerator(functionType, functionName) {
|
||||||
switchToRunnable = true
|
switchToRunnable = true
|
||||||
}.generate {
|
}.generate {
|
||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMSetLinkage(imp, LLVMLinkage.LLVMPrivateLinkage)
|
LLVMSetLinkage(imp, LLVMLinkage.LLVMInternalLinkage)
|
||||||
|
|
||||||
return objCToKotlinMethodAdapter(selector, methodBridge, imp)
|
return objCToKotlinMethodAdapter(selector, methodBridge, imp)
|
||||||
}
|
}
|
||||||
@@ -1837,7 +1834,7 @@ private fun ObjCExportCodeGenerator.objCToKotlinMethodAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ObjCExportCodeGenerator.createUnitInstanceAdapter(selector: String) =
|
private fun ObjCExportCodeGenerator.createUnitInstanceAdapter(selector: String) =
|
||||||
generateObjCToKotlinSyntheticGetter(selector) {
|
generateObjCToKotlinSyntheticGetter(selector, "UnitInstance") {
|
||||||
// Note: generateObjCToKotlinSyntheticGetter switches to Runnable, which is probably not required here and thus suboptimal.
|
// Note: generateObjCToKotlinSyntheticGetter switches to Runnable, which is probably not required here and thus suboptimal.
|
||||||
initRuntimeIfNeeded() // For instance methods it gets called when allocating.
|
initRuntimeIfNeeded() // For instance methods it gets called when allocating.
|
||||||
|
|
||||||
@@ -1851,7 +1848,7 @@ private fun ObjCExportCodeGenerator.createObjectInstanceAdapter(
|
|||||||
assert(irClass.kind == ClassKind.OBJECT)
|
assert(irClass.kind == ClassKind.OBJECT)
|
||||||
assert(!irClass.isUnit())
|
assert(!irClass.isUnit())
|
||||||
|
|
||||||
return generateObjCToKotlinSyntheticGetter(selector) {
|
return generateObjCToKotlinSyntheticGetter(selector, "${irClass.computeTypeInfoSymbolName()}#$selector") {
|
||||||
initRuntimeIfNeeded() // For instance methods it gets called when allocating.
|
initRuntimeIfNeeded() // For instance methods it gets called when allocating.
|
||||||
val value = getObjectValue(irClass, startLocationInfo = null, exceptionHandler = ExceptionHandler.Caller)
|
val value = getObjectValue(irClass, startLocationInfo = null, exceptionHandler = ExceptionHandler.Caller)
|
||||||
autoreleaseAndRet(kotlinReferenceToRetainedObjC(value))
|
autoreleaseAndRet(kotlinReferenceToRetainedObjC(value))
|
||||||
@@ -1862,7 +1859,8 @@ private fun ObjCExportCodeGenerator.createEnumEntryAdapter(
|
|||||||
irEnumEntry: IrEnumEntry,
|
irEnumEntry: IrEnumEntry,
|
||||||
selector: String
|
selector: String
|
||||||
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
): ObjCExportCodeGenerator.ObjCToKotlinMethodAdapter {
|
||||||
return generateObjCToKotlinSyntheticGetter(selector) {
|
val bridgeName = "${irEnumEntry.parentAsClass.computeTypeInfoSymbolName()}.${irEnumEntry.name.asString()}"
|
||||||
|
return generateObjCToKotlinSyntheticGetter(selector, bridgeName) {
|
||||||
initRuntimeIfNeeded() // For instance methods it gets called when allocating.
|
initRuntimeIfNeeded() // For instance methods it gets called when allocating.
|
||||||
|
|
||||||
val value = getEnumEntry(irEnumEntry, ExceptionHandler.Caller)
|
val value = getEnumEntry(irEnumEntry, ExceptionHandler.Caller)
|
||||||
@@ -1892,7 +1890,7 @@ private fun ObjCExportCodeGenerator.createThrowableAsErrorAdapter(): ObjCExportC
|
|||||||
valueParameters = emptyList()
|
valueParameters = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
val imp = generateObjCImpBy(methodBridge) {
|
val imp = generateObjCImpBy(methodBridge, suffix = "ThrowableAsError") {
|
||||||
val exception = objCReferenceToKotlin(param(0), Lifetime.ARGUMENT)
|
val exception = objCReferenceToKotlin(param(0), Lifetime.ARGUMENT)
|
||||||
ret(callFromBridge(context.llvm.Kotlin_ObjCExport_WrapExceptionToNSError, listOf(exception)))
|
ret(callFromBridge(context.llvm.Kotlin_ObjCExport_WrapExceptionToNSError, listOf(exception)))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user