Make linkage issues more understandable in Objective-C interop
This commit is contained in:
committed by
SvyatoslavScherbina
parent
a0dc2ecef2
commit
caf6719fc4
@@ -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
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user