[Native][IR] Move verbose RTTI for local classes and anonymous objects
^KT-45304
This commit is contained in:
@@ -56,6 +56,8 @@ enum Konan_TypeFlags {
|
||||
TF_SUSPEND_FUNCTION = 1 << 5,
|
||||
TF_HAS_FINALIZER = 1 << 6,
|
||||
TF_HAS_FREEZE_HOOK = 1 << 7,
|
||||
TF_REFLECTION_SHOW_PKG_NAME = 1 << 8, // If package name is available in reflection, e.g. in `KClass.qualifiedName`.
|
||||
TF_REFLECTION_SHOW_REL_NAME = 1 << 9 // If relative name is available in reflection, e.g. in `KClass.simpleName`.
|
||||
};
|
||||
|
||||
// Flags per object instance.
|
||||
@@ -115,13 +117,12 @@ struct TypeInfo {
|
||||
int32_t interfaceTableSize_;
|
||||
InterfaceTableRecord const* interfaceTable_;
|
||||
|
||||
// String for the fully qualified dot-separated name of the package containing class,
|
||||
// or `null` if the class is local or anonymous.
|
||||
// String for the fully qualified dot-separated name of the package containing class.
|
||||
ObjHeader* packageName_;
|
||||
|
||||
// String for the qualified class name relative to the containing package
|
||||
// (e.g. TopLevel.Nested1.Nested2), or simple class name if it is local,
|
||||
// or `null` if the class is anonymous.
|
||||
// (e.g. TopLevel.Nested1.Nested2) or the effective class name computed for
|
||||
// local class or anonymous object (e.g. listOf$1).
|
||||
ObjHeader* relativeName_;
|
||||
|
||||
// Various flags.
|
||||
|
||||
@@ -55,12 +55,22 @@ KBoolean Kotlin_TypeInfo_isInstance(KConstRef obj, KNativePtr typeInfo) {
|
||||
return IsInstance(obj, reinterpret_cast<const TypeInfo*>(typeInfo));
|
||||
}
|
||||
|
||||
OBJ_GETTER(Kotlin_TypeInfo_getPackageName, KNativePtr typeInfo) {
|
||||
RETURN_OBJ(reinterpret_cast<const TypeInfo*>(typeInfo)->packageName_);
|
||||
OBJ_GETTER(Kotlin_TypeInfo_getPackageName, KNativePtr typeInfo, KBoolean checkFlags) {
|
||||
const TypeInfo* type_info = reinterpret_cast<const TypeInfo*>(typeInfo);
|
||||
if (!checkFlags || type_info->flags_ & TF_REFLECTION_SHOW_PKG_NAME) {
|
||||
RETURN_OBJ(type_info->packageName_);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OBJ_GETTER(Kotlin_TypeInfo_getRelativeName, KNativePtr typeInfo) {
|
||||
RETURN_OBJ(reinterpret_cast<const TypeInfo*>(typeInfo)->relativeName_);
|
||||
OBJ_GETTER(Kotlin_TypeInfo_getRelativeName, KNativePtr typeInfo, KBoolean checkFlags) {
|
||||
const TypeInfo* type_info = reinterpret_cast<const TypeInfo*>(typeInfo);
|
||||
if (!checkFlags || type_info->flags_ & TF_REFLECTION_SHOW_REL_NAME) {
|
||||
RETURN_OBJ(type_info->relativeName_);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct AssociatedObjectTableRecord {
|
||||
|
||||
@@ -9,25 +9,15 @@ import kotlin.reflect.KClass
|
||||
|
||||
@ExportForCompiler
|
||||
internal class KClassImpl<T : Any>(private val typeInfo: NativePtr) : KClass<T> {
|
||||
// TODO: consider replacing '$' by another delimeter that can't be used in class name specified with backticks (``)
|
||||
override val simpleName: String?
|
||||
get() {
|
||||
val relativeName = getRelativeName(typeInfo)
|
||||
?: return null
|
||||
|
||||
return relativeName.substringAfterLast(".")
|
||||
}
|
||||
get() = getRelativeName(typeInfo, true)?.substringAfterLast('.')?.substringAfterLast('$')
|
||||
|
||||
override val qualifiedName: String?
|
||||
get() {
|
||||
val packageName = getPackageName(typeInfo)
|
||||
?: return null
|
||||
|
||||
val relativeName = getRelativeName(typeInfo)!!
|
||||
return if (packageName.isEmpty()) {
|
||||
relativeName
|
||||
} else {
|
||||
"$packageName.$relativeName"
|
||||
}
|
||||
val packageName = getPackageName(typeInfo, true) ?: return null
|
||||
val relativeName = getRelativeName(typeInfo, true) ?: return null
|
||||
return if (packageName.isEmpty()) relativeName else "$packageName.$relativeName"
|
||||
}
|
||||
|
||||
override fun isInstance(value: Any?): Boolean = value != null && isInstance(value, this.typeInfo)
|
||||
@@ -38,7 +28,13 @@ internal class KClassImpl<T : Any>(private val typeInfo: NativePtr) : KClass<T>
|
||||
override fun hashCode(): Int = typeInfo.hashCode()
|
||||
|
||||
override fun toString(): String {
|
||||
return "class " + (qualifiedName ?: simpleName ?: "<anonymous>")
|
||||
val relativeName = getRelativeName(typeInfo, false)
|
||||
val visibleName = if (relativeName != null) {
|
||||
val packageName = getPackageName(typeInfo, false)!!
|
||||
if (packageName.isEmpty()) relativeName else "$packageName.$relativeName"
|
||||
} else "<anonymous>"
|
||||
|
||||
return "class $visibleName"
|
||||
}
|
||||
|
||||
internal fun findAssociatedObjectImpl(key: KClassImpl<*>): Any? =
|
||||
@@ -80,10 +76,10 @@ internal external fun getObjectTypeInfo(obj: Any): NativePtr
|
||||
internal external inline fun <reified T : Any> getClassTypeInfo(): NativePtr
|
||||
|
||||
@GCUnsafeCall("Kotlin_TypeInfo_getPackageName")
|
||||
private external fun getPackageName(typeInfo: NativePtr): String?
|
||||
private external fun getPackageName(typeInfo: NativePtr, checkFlags: Boolean): String?
|
||||
|
||||
@GCUnsafeCall("Kotlin_TypeInfo_getRelativeName")
|
||||
private external fun getRelativeName(typeInfo: NativePtr): String?
|
||||
private external fun getRelativeName(typeInfo: NativePtr, checkFlags: Boolean): String?
|
||||
|
||||
@GCUnsafeCall("Kotlin_TypeInfo_isInstance")
|
||||
private external fun isInstance(obj: Any, typeInfo: NativePtr): Boolean
|
||||
|
||||
Reference in New Issue
Block a user