Make linkage issues more understandable in Objective-C interop

This commit is contained in:
Svyatoslav Scherbina
2017-10-13 10:36:17 +03:00
committed by SvyatoslavScherbina
parent a0dc2ecef2
commit caf6719fc4
3 changed files with 29 additions and 4 deletions
@@ -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<ByteVar>(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 <T : ObjCObject> 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
@@ -2081,7 +2081,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
assert(!classDescriptor.isInterface)
return if (classDescriptor.isExternalObjCClass()) {
val lookUpFunction = context.llvm.externalFunction("objc_lookUpClass",
val lookUpFunction = context.llvm.externalFunction("Kotlin_Interop_getObjCClass",
functionType(int8TypePtr, false, int8TypePtr))
call(lookUpFunction,
+12 -3
View File
@@ -27,6 +27,8 @@
extern "C" {
Class Kotlin_Interop_getObjCClass(const char* name);
struct KotlinClassData {
const TypeInfo* typeInfo;
int32_t bodyOffset;
@@ -67,8 +69,7 @@ static void DeallocImp(id self, SEL _cmd) {
}
static void AddDeallocMethod(Class clazz) {
Class nsObjectClass = objc_getClass("NSObject");
RuntimeAssert(nsObjectClass != nullptr, "NSObject class not found");
Class nsObjectClass = Kotlin_Interop_getObjCClass("NSObject");
SEL deallocSelector = sel_registerName("dealloc");
Method nsObjectDeallocMethod = class_getInstanceMethod(nsObjectClass, deallocSelector);
@@ -136,7 +137,7 @@ void* CreateKotlinObjCClass(const KotlinObjCClassInfo* info) {
className = classNameBuffer;
}
Class superclass = objc_getClass(info->superclassName);
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