From caf6719fc4e3ac9197a331b64ac5828f62c95a1b Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Fri, 13 Oct 2017 10:36:17 +0300 Subject: [PATCH] Make linkage issues more understandable in Objective-C interop --- .../kotlin/kotlinx/cinterop/ObjectiveCImpl.kt | 16 ++++++++++++++++ .../kotlin/backend/konan/llvm/IrToBitcode.kt | 2 +- runtime/src/main/cpp/ObjCInterop.cpp | 15 ++++++++++++--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/ObjectiveCImpl.kt b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/ObjectiveCImpl.kt index dddd9c4c5ec..420a8860297 100644 --- a/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/ObjectiveCImpl.kt +++ b/Interop/Runtime/src/native/kotlin/kotlinx/cinterop/ObjectiveCImpl.kt @@ -124,6 +124,19 @@ annotation class InteropStubs() @Retention(AnnotationRetention.SOURCE) private annotation class ObjCMethodImp(val selector: String, val encoding: String) +@konan.internal.ExportForCppRuntime("Kotlin_Interop_getObjCClass") +private fun getObjCClassByName(name: NativePtr): NativePtr { + val result = objc_lookUpClass(name) + if (result == nativeNullPtr) { + val className = interpretCPointer(name)!!.toKString() + val message = """Objective-C class '$className' not found. + |Ensure that the containing framework or library was linked.""".trimMargin() + + throw RuntimeException(message) + } + return result +} + @konan.internal.ExportForCompiler private fun allocObjCObject(clazz: NativePtr): T { val rawResult = objc_allocWithZone(clazz) @@ -183,3 +196,6 @@ external fun objc_retain(ptr: NativePtr): NativePtr @SymbolName("Kotlin_objc_release") external fun objc_release(ptr: NativePtr) + +@SymbolName("Kotlin_objc_lookUpClass") +external fun objc_lookUpClass(name: NativePtr): NativePtr diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index c1862bd3dc9..45de3a865e7 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -2081,7 +2081,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: MapsuperclassName); + Class superclass = Kotlin_Interop_getObjCClass(info->superclassName); Class newClass = objc_allocateClassPair(superclass, className, sizeof(struct KotlinClassData)); RuntimeAssert(newClass != nullptr, "Failed to allocate Objective-C class"); @@ -205,6 +206,10 @@ void Kotlin_objc_release(id ptr) { objc_release(ptr); } +Class Kotlin_objc_lookUpClass(const char* name) { + return objc_lookUpClass(name); +} + } // extern "C" #else // KONAN_OBJC_INTEROP @@ -236,6 +241,10 @@ void Kotlin_objc_release(void* ptr) { RuntimeAssert(false, "Objective-C interop is disabled"); } +void* Kotlin_objc_lookUpClass(const char* name) { + RuntimeAssert(false, "Objective-C interop is disabled"); +} + } // extern "C" #endif // KONAN_OBJC_INTEROP