[K/N] Support of collectReferenceFieldValues function
This commit is contained in:
@@ -16,6 +16,9 @@
|
||||
|
||||
#include "KAssert.h"
|
||||
#include "TypeInfo.h"
|
||||
#include "Memory.h"
|
||||
#include "Types.h"
|
||||
#include "KString.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -39,4 +42,14 @@ InterfaceTableRecord const* LookupInterfaceTableRecord(InterfaceTableRecord cons
|
||||
return interfaceTable + l;
|
||||
}
|
||||
|
||||
RUNTIME_NOTHROW int Kotlin_internal_reflect_getObjectReferenceFieldsCount(ObjHeader* object) {
|
||||
auto *info = object->type_info();
|
||||
if (info->IsArray()) return 0;
|
||||
return info->objOffsetsCount_;
|
||||
}
|
||||
|
||||
RUNTIME_NOTHROW OBJ_GETTER(Kotlin_internal_reflect_getObjectReferenceFieldByIndex, ObjHeader* object, int index) {
|
||||
RETURN_OBJ(*reinterpret_cast<ObjHeader**>(reinterpret_cast<uintptr_t>(object) + object->type_info()->objOffsets_[index]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,3 +19,36 @@ internal fun debugDescription(kClass: KClass<*>, identity: Int): String {
|
||||
val identityStr = unsignedIdentity.toString(16)
|
||||
return "$className@$identityStr"
|
||||
}
|
||||
|
||||
@GCUnsafeCall("Kotlin_internal_reflect_getObjectReferenceFieldsCount")
|
||||
private external fun getObjectReferenceFieldsCount(o: Any): Int
|
||||
@GCUnsafeCall("Kotlin_internal_reflect_getObjectReferenceFieldByIndex")
|
||||
private external fun getObjectReferenceFieldByIndex(o: Any, index: Int): Any?
|
||||
|
||||
/**
|
||||
* Returns [List] of non-null reference fields of the object.
|
||||
*
|
||||
* This function is intended to be used for testing and debugging purposes.
|
||||
* - It heavily relies on internal ABI details. No compatibility guarantees on exact list contents are provided.
|
||||
* - Order and representation of object's fields are subject to change.
|
||||
* - Performance characteristics of the implementation
|
||||
*
|
||||
* Limitations:
|
||||
* - Primitives (unboxed [Int], [Double], [Float], etc.) are not included in the result.
|
||||
* - Non-boxed value classes over primitives are not included in the result.
|
||||
* - Non-boxed value classes over references are included in the result as the underlying reference type.
|
||||
* - Synthetic fields (e.g. special fields for delegation) are included in the result.
|
||||
* - There is no way to find which reference in the result corresponds to which field.
|
||||
*
|
||||
* For `Array<T>` list of all its non-null elements is returned.
|
||||
* For primitive arrays ([IntArray], [DoubleArray], [FloatArray], etc.) empty list is returned.
|
||||
*/
|
||||
@InternalForKotlinNative
|
||||
public fun Any.collectReferenceFieldValues() : List<Any> {
|
||||
return when {
|
||||
this is Array<*> -> this.filterNotNull()
|
||||
else -> (0 until getObjectReferenceFieldsCount(this@collectReferenceFieldValues)).mapNotNull {
|
||||
getObjectReferenceFieldByIndex(this@collectReferenceFieldValues, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user