#ifndef MRT_MCLASS_H
#define MRT_MCLASS_H
#include <functional>
#include <mutex>
#include <unordered_map>
#include "Base/AtomicSpinLock.h"
#include "Common/TypeDef.h"
#include "MethodInfo.h"
#include "FieldInfo.h"
#include "Flags.h"
#include "PackageInfo.h"
namespace MapleRuntime {
class ExtensionData;
class BaseFile;
constexpr U8 BITS_FOR_REF = 1;
constexpr U8 REF_BIT_MASK = 1;
constexpr ArchUInt SIGN_BIT = (ArchUInt)1 << (sizeof(void*) * 8 - 1);
constexpr U16 INVALID_INHERIT_NUM = (1 << 15) - 1;
extern const size_t TYPEINFO_PTR_SIZE;
union MTableBitmap {
using LargeBitmap = std::pair<U32, U8[]>;
ArchUInt shortBitmap;
LargeBitmap* largeBitmap;
ArchUInt tag;
void ForEachBit(const std::function<void(ExtensionData*)>& visitor, ExtensionData** vExtensionPtr)
{
bool isSmallBitmap = tag & SIGN_BIT;
if (isSmallBitmap) {
ArchUInt bitInfo = shortBitmap & (~SIGN_BIT);
while (LIKELY(bitInfo != 0)) {
if (bitInfo & 0x1) {
visitor(*vExtensionPtr);
}
bitInfo >>= 1;
++vExtensionPtr;
}
} else {
U8* bitmaps = largeBitmap->second;
for (U32 i = 0; i < largeBitmap->first; ++i) {
U8 bitInfo = bitmaps[i];
while (LIKELY(bitInfo != 0)) {
if (bitInfo & 0x1) {
visitor(*vExtensionPtr);
}
bitInfo >>= 1;
++vExtensionPtr;
}
}
}
}
};
class InheritFuncTable {
public:
InheritFuncTable() = delete;
InheritFuncTable(const InheritFuncTable& other)
: superExtensionData(other.superExtensionData),
superTypeInfo(other.superTypeInfo),
cachedTypeInfos(other.cachedTypeInfos)
{}
InheritFuncTable& operator=(const InheritFuncTable& other)
{
if (this == &other) {
return *this;
}
superExtensionData = other.superExtensionData;
superTypeInfo = other.superTypeInfo;
cachedTypeInfos = other.cachedTypeInfos;
return *this;
}
InheritFuncTable(InheritFuncTable&& other)
{
superExtensionData = other.superExtensionData;
superTypeInfo = other.superTypeInfo;
cachedTypeInfos = std::move(other.cachedTypeInfos);
other.superExtensionData = nullptr;
other.superTypeInfo = nullptr;
}
InheritFuncTable& operator=(InheritFuncTable&& other)
{
if (this == &other) {
return *this;
}
superExtensionData = other.superExtensionData;
superTypeInfo = other.superTypeInfo;
cachedTypeInfos = std::move(other.cachedTypeInfos);
other.superExtensionData = nullptr;
other.superTypeInfo = nullptr;
return *this;
}
InheritFuncTable(ExtensionData* ed, TypeInfo* super, size_t sz)
: superExtensionData(ed), superTypeInfo(super), cachedTypeInfos(sz) {}
ExtensionData* GetExtensionData() const { return superExtensionData; }
TypeInfo* GetSuperTi() const { return superTypeInfo; }
void ResetAtomicInfoArray(size_t size) { cachedTypeInfos = AtomicTypeInfoArray(size); }
TypeInfo* GetCachedTypeInfo(size_t index) const { return cachedTypeInfos.Get(index); }
void SetCachedTypeInfo(size_t index, TypeInfo* ti) { cachedTypeInfos.Set(index, ti); }
private:
class AtomicTypeInfoArray {
public:
AtomicTypeInfoArray() = default;
AtomicTypeInfoArray(const AtomicTypeInfoArray& other) : cacheSize(other.cacheSize)
{
if (cacheSize == 0) {
typeInfos = nullptr;
return;
}
typeInfos = new (std::nothrow) std::atomic<TypeInfo*>[cacheSize];
if (UNLIKELY(typeInfos == nullptr)) {
LOG(RTLOG_FATAL, "copy construct func table memory failed, size %zu", cacheSize);
}
for (size_t i = 0; i < cacheSize; ++i) {
TypeInfo* ti = other.typeInfos[i].load(std::memory_order_relaxed);
typeInfos[i].store(ti, std::memory_order_relaxed);
}
}
AtomicTypeInfoArray& operator=(const AtomicTypeInfoArray& other)
{
if (this == &other) {
return *this;
}
cacheSize = other.cacheSize;
if (cacheSize == 0) {
typeInfos = nullptr;
return *this;
}
typeInfos = new (std::nothrow) std::atomic<TypeInfo*>[cacheSize];
if (UNLIKELY(typeInfos == nullptr)) {
LOG(RTLOG_FATAL, "copy assign func table memory failed, size %zu", cacheSize);
}
for (size_t i = 0; i < cacheSize; ++i) {
TypeInfo* ti = other.typeInfos[i].load(std::memory_order_relaxed);
typeInfos[i].store(ti, std::memory_order_relaxed);
}
return *this;
}
AtomicTypeInfoArray(AtomicTypeInfoArray&& other)
{
cacheSize = other.cacheSize;
typeInfos = other.typeInfos;
other.cacheSize = 0;
other.typeInfos = nullptr;
}
AtomicTypeInfoArray& operator=(AtomicTypeInfoArray&& other)
{
if (this == &other) {
return *this;
}
cacheSize = other.cacheSize;
typeInfos = other.typeInfos;
other.cacheSize = 0;
other.typeInfos = nullptr;
return *this;
}
explicit AtomicTypeInfoArray(size_t size) : cacheSize(size)
{
if (size == 0) {
typeInfos = nullptr;
return;
}
typeInfos = new (std::nothrow) std::atomic<TypeInfo*>[size];
if (UNLIKELY(typeInfos == nullptr)) {
LOG(RTLOG_FATAL, "allocation func table memory failed, cache size %zu", size);
}
for (size_t i = 0; i < size; ++i) {
typeInfos[i].store(nullptr, std::memory_order_relaxed);
}
}
~AtomicTypeInfoArray()
{
if (typeInfos != nullptr) {
delete[] typeInfos;
}
}
TypeInfo* Get(size_t index) const
{
return typeInfos[index].load(std::memory_order_acquire);
}
void Set(size_t index, TypeInfo* ti)
{
typeInfos[index].store(ti, std::memory_order_release);
}
private:
size_t cacheSize{ 0 };
std::atomic<TypeInfo*>* typeInfos{ nullptr };
};
ExtensionData* superExtensionData { nullptr };
TypeInfo* superTypeInfo { nullptr };
AtomicTypeInfoArray cachedTypeInfos;
};
struct MTableDesc {
std::unordered_map<U32, InheritFuncTable> mTable;
MTableBitmap mTableBitmap;
std::recursive_mutex mTableMutex;
bool pending = false;
bool needsResolveInner = true;
bool needsResolveOuter = true;
explicit MTableDesc(ArchUInt bitmap_);
MTableDesc() = delete;
bool IsFullyHandled() const { return !NeedResolveInner() && !NeedResolveOuter(); };
inline bool NeedResolveInner() const { return needsResolveInner; }
inline bool NeedResolveOuter() const { return needsResolveOuter; }
};
typedef TypeInfo* (*GenericFunc)(TypeInfo**);
struct ShortGCTib {
ArchUInt bitmap;
void ForEachBitmapWord(MAddress fieldAddr, const RefFieldVisitor& visitor) const
{
ArchUInt gcInfo = bitmap & (~SIGN_BIT);
while (LIKELY(gcInfo != 0)) {
if (gcInfo & REF_BIT_MASK) {
visitor(*reinterpret_cast<RefField<>*>(fieldAddr));
}
gcInfo >>= BITS_FOR_REF;
fieldAddr += sizeof(RefField<>);
}
}
void ForEachBitmapWordInRange(MAddress baseAddr, const RefFieldVisitor& visitor, MAddress rangeStart,
MAddress rangeEnd) const
{
ArchUInt gcInfo = bitmap & (~SIGN_BIT);
U32 startPos = (rangeStart - baseAddr) / sizeof(RefField<>);
gcInfo >>= startPos;
MAddress fieldAddr = rangeStart;
while (LIKELY(gcInfo != 0)) {
if (fieldAddr >= rangeEnd) {
return;
}
if (gcInfo & REF_BIT_MASK) {
visitor(*reinterpret_cast<RefField<>*>(fieldAddr));
}
gcInfo >>= BITS_FOR_REF;
fieldAddr += sizeof(RefField<>);
}
}
};
struct StdGCTib {
static constexpr U32 BITS_PER_BYTE = 8;
static constexpr U32 REFS_PER_BIT_WORD = ((sizeof(U8) * BITS_PER_BYTE) / BITS_FOR_REF);
U32 nBitmapWords;
U8 bitmapWords[];
void VisitRefField(U8& bitmapWord, MAddress& fieldAddr, const RefFieldVisitor& visitor) const
{
U8 wordBits = bitmapWord & REF_BIT_MASK;
if (wordBits != 0) {
visitor(*reinterpret_cast<RefField<>*>(fieldAddr));
}
bitmapWord >>= BITS_FOR_REF;
fieldAddr += sizeof(RefField<>);
}
void VisitAllField(U8 &bitmapWord, MAddress &fieldAddr, const RefFieldVisitor &visitor) const
{
visitor(*reinterpret_cast<RefField<> *>(fieldAddr));
bitmapWord >>= BITS_FOR_REF;
fieldAddr += sizeof(RefField<>);
}
void ForEachBitmapWord(MAddress contentAddr, const RefFieldVisitor& visitor) const
{
const U8* bitmaps = bitmapWords;
MAddress baseAddr = contentAddr;
for (U32 i = 0; i < nBitmapWords; ++i) {
U8 bitmapWord = bitmaps[i];
MAddress fieldAddr = baseAddr;
while (LIKELY(bitmapWord != 0)) {
VisitRefField(bitmapWord, fieldAddr, visitor);
}
baseAddr += (sizeof(RefField<>) * REFS_PER_BIT_WORD);
}
}
void ForEachBitmapWordInRange(MAddress contentAddr, const RefFieldVisitor& visitor, MAddress rangeStart,
MAddress rangeEnd) const
{
const U8* bitmaps = bitmapWords;
size_t mapWordSize = (sizeof(RefField<>) * REFS_PER_BIT_WORD);
U32 startIndex = (rangeStart - contentAddr) / mapWordSize;
MAddress baseAddr = startIndex * mapWordSize + contentAddr;
for (U32 i = startIndex; i < nBitmapWords; ++i) {
U8 bitmapWord = bitmaps[i];
MAddress fieldAddr = baseAddr;
if (i == startIndex && bitmapWord != 0) {
bitmapWord >>= ((rangeStart - baseAddr) / sizeof(RefField<>));
fieldAddr = rangeStart;
}
while (LIKELY(bitmapWord != 0)) {
if (fieldAddr >= rangeEnd) {
return;
}
VisitRefField(bitmapWord, fieldAddr, visitor);
}
baseAddr += (sizeof(RefField<>) * REFS_PER_BIT_WORD);
}
}
};
union GCTib {
ArchUInt tag;
ShortGCTib bitmap;
StdGCTib* gctib;
bool IsGCTibWord() const
{
#ifdef __arm__
return false;
#else
return static_cast<bool>(tag & SIGN_BIT);
#endif
}
void ForEachBitmapWord(MAddress contentAddr, const RefFieldVisitor& visitor) const
{
if (IsGCTibWord()) {
bitmap.ForEachBitmapWord(contentAddr, visitor);
} else {
gctib->ForEachBitmapWord(contentAddr, visitor);
}
}
void ForEachBitmapWordInRange(MAddress contentAddr, const RefFieldVisitor& visitor, MAddress rangeStart,
MAddress rangeEnd) const
{
#ifdef __arm__
rangeStart = ((rangeStart + 3) & (~3));
#else
rangeStart = ((rangeStart + 7) & (~7));
#endif
if (rangeStart >= rangeEnd) {
return;
}
if (IsGCTibWord()) {
bitmap.ForEachBitmapWordInRange(contentAddr, visitor, rangeStart, rangeEnd);
} else {
gctib->ForEachBitmapWordInRange(contentAddr, visitor, rangeStart, rangeEnd);
}
}
};
struct FieldNames {
I64 fieldNameOffset[0];
};
class ReflectInfo {
public:
inline U32 GetModifier() const { return modifier; }
char* GetFieldName(U32 idx) const;
FieldNames* GetFieldNames() { return fieldNamesOffset.GetDataRef(); }
void SetFieldNames(FieldNames* fieldNames);
void SetInstanceMethodInfo(U32 idx, MethodInfo* methodInfo);
void SetStaticMethodInfo(U32 idx, MethodInfo* methodInfo);
inline U32 GetNumOfInstanceFieldInfos() const { return instanceFieldInfoCnt; }
inline U32 GetNumOfStaticFieldInfos() const { return staticFieldInfoCnt; }
inline U32 GetNumOfInstanceMethodInfos() const { return instanceMethodCnt; }
inline U32 GetNumOfStaticMethodInfos() const { return staticMethodCnt; }
InstanceFieldInfo* GetInstanceFieldInfo(U32 index);
StaticFieldInfo* GetStaticFieldInfo(U32 index);
MethodInfo* GetInstanceMethodInfo(U32 index) const;
MethodInfo* GetStaticMethodInfo(U32 index);
void* GetDeclaringGenericTypeInfo() { return genericTypeInfo; }
void SetDeclaringGenericTypeInfo(GenericTypeInfo* ti) { genericTypeInfo = ti; }
void* GetAnnotations(TypeInfo* arrayTi);
U8 GetReflectVersion() const;
private:
Uptr GetBaseAddr() const { return reinterpret_cast<Uptr>(base); }
DataRefOffset64<FieldNames> fieldNamesOffset;
U32 modifier;
U16 instanceFieldInfoCnt;
U16 staticFieldInfoCnt;
U32 instanceMethodCnt;
U32 staticMethodCnt;
Uptr annotationMethod;
void* genericTypeInfo;
Uptr base[0];
};
class EnumCtorInfo {
public:
const char* GetName() { return name.GetDataRef(); }
FuncPtr* GetCtorFn() const { return enumCtorFn; }
TypeInfo* GetTypeInfo() const { return typeInfo; }
void SetName(const char* pName);
void SetTypeInfo(TypeInfo* ti) { typeInfo = ti; }
private:
DataRefOffset64<char> name;
union {
FuncPtr* enumCtorFn;
TypeInfo* typeInfo;
};
};
struct EnumDebugInfo {
DataRefOffset64<EnumCtorInfo> enumCtorInfos;
U32 modifier;
U32 enumCtorInfoCnt;
EnumCtorInfo* GetEnumCtor(U32 idx) const;
void SetEnumCtors(void* ctors);
};
class EnumInfo {
public:
inline U32 GetModifier() const { return enumDebugInfo.modifier; }
inline U32 GetNumOfEnumCtor() const { return enumDebugInfo.enumCtorInfoCnt; }
inline U32 GetNumOfInstanceMethodInfos() const { return instanceMethodCnt; }
inline U32 GetNumOfStaticMethodInfos() const { return staticMethodCnt; }
EnumCtorInfo* GetEnumCtor(U32 idx) const;
TypeInfo* GetCtorTypeInfo(U32 idx) const;
void* GetAnnotations(TypeInfo* arrayTi);
MethodInfo* GetInstanceMethodInfo(U32 index) const;
MethodInfo* GetStaticMethodInfo(U32 index);
void SetInstanceMethodInfo(U32 idx, MethodInfo* methodInfo);
void SetStaticMethodInfo(U32 idx, MethodInfo* methodInfo);
void SetCtorInfoNum(U32 num) { enumDebugInfo.enumCtorInfoCnt = num; }
void SetParsed() { enumDebugInfo.modifier |= MODIFIER_ENUM_PARSED; }
bool IsParsed() const { return (enumDebugInfo.modifier & MODIFIER_ENUM_PARSED) != 0; }
bool IsEnumKind0() const { return (enumDebugInfo.modifier & MODIFIER_ENUM_KIND0) != 0; }
bool IsEnumKind1() const { return (enumDebugInfo.modifier & MODIFIER_ENUM_KIND1) != 0; }
bool IsEnumKind2() const { return (enumDebugInfo.modifier & MODIFIER_ENUM_KIND2) != 0; }
bool IsEnumCtor() const { return (enumDebugInfo.modifier & MODIFIER_ENUM_CTOR) != 0; }
EnumDebugInfo* GetEnumDebugInfo() { return &enumDebugInfo; }
void* GetDeclaringGenericTypeInfo() { return genericTypeInfo; }
void SetDeclaringGenericTypeInfo(GenericTypeInfo* ti) { genericTypeInfo = ti; }
U8 GetReflectVersion() const;
private:
Uptr GetBaseAddr() const { return reinterpret_cast<Uptr>(base); }
EnumDebugInfo enumDebugInfo;
U32 instanceMethodCnt;
U32 staticMethodCnt;
Uptr annotationMethod;
void* genericTypeInfo;
Uptr base[0];
};
class EnumCtorReflectInfo {
public:
void* GetAnnotations(TypeInfo* arrayTi);
bool IsEnumCtor() const { return (modifier & MODIFIER_ENUM_CTOR) != 0; }
U32 GetModifier() const { return modifier; }
Uptr GetAnnotationMethod() const { return annotationMethod; }
private:
Uptr annotationMethod;
U32 modifier;
};
class TypeTemplate {
public:
inline bool IsRawArray() const;
inline bool IsVArray() const;
inline bool IsArrayType() const;
inline bool IsWeakRefType() const;
inline bool IsObjectType() const;
inline bool IsPrimitiveType() const;
inline bool IsInterface() const;
inline bool IsClass() const;
inline bool IsStruct() const;
inline bool IsNothing() const;
inline bool IsTuple() const;
inline bool IsEnum() const;
inline bool IsTempEnum() const;
inline bool IsCString() const;
inline bool IsCPointer() const;
inline bool IsCFunc() const;
inline bool IsFunc() const;
inline bool IsRef() const;
inline bool HasRefField() const;
inline bool HasFinalizer() const;
inline bool HasExtPart() const;
inline const char* GetName() const;
inline I8 GetType() const { return type; }
inline I8 GetFlag() const { return flag; }
inline U16 GetFieldNum() const { return fieldNum; }
inline U16 GetTypeArgNum() const { return typeArgsNum; }
inline U16 GetValidInheritNum() const { return validInheritNum; }
inline ExtensionData** GetvExtensionDataStart() const { return vExtensionDataStart; }
inline U16 GetUUID() const { return uuid.load(); }
inline void SetUUID(U16 id);
inline EnumInfo* GetEnumInfo();
inline EnumDebugInfo* GetEnumDebugInfo();
inline EnumCtorReflectInfo* GetEnumCtorReflectInfo();
inline bool ReflectInfoIsNull() const;
bool ReflectIsEnable() const;
bool IsEnumCtor() const;
CString GetTypeInfoName(U32 argSize, TypeInfo* args[]);
ReflectInfo* GetReflectInfo() const { return reflectInfo; }
TypeInfo* GetFieldType(U16 fieldIdx, U32 argSize, TypeInfo* args[]);
TypeInfo* GetSuperTypeInfo(U32 argSize, TypeInfo* args[]);
FuncRef GetFinalizeMethod() const { return finalizerMethod; }
static void* ExecuteGenericFunc(void* genericFunc, U32 argSize, TypeInfo* args[]);
private:
GenericFunc GetFieldGenericFunc(U16 idx) const { return fieldFns[idx]; }
GenericFunc GetSuperGenericFunc() const { return superFn; }
TypeTemplate() = delete;
~TypeTemplate() = delete;
const char* name;
I8 type;
I8 flag;
U16 fieldNum;
U16 typeArgsNum;
std::atomic<U16> uuid;
const GenericFunc* fieldFns;
const GenericFunc superFn;
FuncRef finalizerMethod;
union {
ReflectInfo* reflectInfo;
EnumInfo* enumInfo;
EnumDebugInfo* enumDebugInfo;
EnumCtorReflectInfo* enumCtorReflectInfo;
};
ExtensionData **vExtensionDataStart;
U16 validInheritNum;
};
#ifdef __arm__
class TypeInfo {
#else
class ATTR_PACKED(4) TypeInfo {
#endif
friend class TypeInfoManager;
public:
inline GCTib GetGCTib() const;
inline MSize GetInstanceSize() const;
inline MSize GetComponentSize() const;
inline bool IsObjectType() const;
inline bool IsRawArray() const;
inline bool IsVArray() const;
inline bool IsWeakRefType() const;
inline bool IsForeignType() const;
inline bool IsExportedType() const;
inline bool IsArrayType() const;
inline bool IsStructType() const;
inline bool IsPrimitiveType() const;
inline bool IsVaildType() const;
inline bool IsInterface() const;
inline bool IsClass() const;
inline bool IsSyncClass() const;
inline bool IsStruct() const;
inline bool IsNothing() const;
inline bool IsUnit() const;
inline bool IsBool() const;
inline bool IsTuple() const;
inline bool IsEnum() const;
inline bool IsTempEnum() const;
inline bool IsCString() const;
inline bool IsCPointer() const;
inline bool IsFunc() const;
inline bool IsFloat16() const;
inline bool IsFloat32() const;
inline bool IsFloat64() const;
inline bool IsCFunc() const;
inline bool IsRef() const;
inline bool IsUnknownSize() const;
inline bool IsGenericTypeInfo() const;
inline bool IsGeneric() const;
inline bool IsReflectUnsupportedType() const;
inline bool HasRefField() const;
inline bool HasFinalizer() const;
inline bool IsInitialUUID() const;
inline I8 GetFlags() const;
inline I8 GetType() const;
inline U16 GetAlign() const;
inline U16 GetFieldNum() const;
inline U32* GetFieldOffsets() const;
inline U16 GetValidInheritNum() const;
inline TypeInfo** GetFieldTypes() const { return fields; }
inline TypeInfo* GetFieldType(U16 idx) const;
inline TypeInfo* GetComponentTypeInfo() const;
inline U16 GetTypeArgNum() const { return typeArgsNum; }
inline U32 GetFieldOffset(U16 idx) const { return fieldOffsets[idx]; }
inline TypeInfo** GetTypeArgs() const { return typeArgs; }
inline TypeTemplate* GetSourceGeneric() const;
inline ExtensionData** GetvExtensionDataStart() const;
inline bool IsFutureClass() const;
inline bool IsMonitorClass() const;
inline bool IsMutexClass() const;
inline bool IsWaitQueueClass() const;
inline bool HasExtPart() const;
inline bool IsBoxClass() const;
U32 GetModifier() const;
bool IsEnumCtor() const;
bool IsOptionLikeRefEnum();
bool IsZeroSizedEnum();
bool IsOptionLikeUnassociatedCtor();
bool IsEnumKind1();
bool ReflectIsEnable() const;
bool ReflectInfoIsNull() const;
inline EnumCtorReflectInfo* GetEnumCtorReflectInfo() const;
ReflectInfo* GetReflectInfo() const;
U8 GetReflectionVersion() const;
inline const char* GetName() const;
FuncRef GetFinalizeMethod() const;
U32 GetNumOfInstanceMethodInfos();
MethodInfo* GetInstanceMethodInfo(U32 index);
U32 GetNumOfStaticMethodInfos();
MethodInfo* GetStaticMethodInfo(U32 index);
U32 GetNumOfInstanceFieldInfos();
InstanceFieldInfo* GetInstanceFieldInfo(U32 index);
U32 GetNumOfStaticFieldInfos();
StaticFieldInfo* GetStaticFieldInfo(U32 index);
U32 GetNumOfEnumCtor();
EnumCtorInfo* GetEnumCtor(U32 idx);
PackageInfo* GetPackageInfo();
void* GetAnnotations(TypeInfo* arrayTi);
inline EnumInfo* GetEnumInfo() const;
void SetName(const char* name) { this->typeInfoName = name; }
void SetType(I8 kindType) { this->type = kindType; }
void SetFlag(I8 f) { this->flag = f; }
void SetFieldNum(U16 num) { this->fieldNum = num; }
void SetTypeArgNum(I8 num) { this->typeArgsNum = num; }
void SetUUID(U32 id) { this->uuid = id; }
void SetMTableDesc(MTableDesc* desc);
void SetGenericArgs(TypeInfo** args) { this->typeArgs = args; }
void SetFieldAddr(TypeInfo** types) { this->fields = types; }
void SetFieldType(U16 idx, TypeInfo* fieldType) { this->fields[idx] = fieldType; }
void SetSuperTypeInfo(TypeInfo* super) { this->superTypeInfo = super; }
void SetOffsets(U32* offsets) { this->fieldOffsets = offsets; }
void SetSourceGeneric(TypeTemplate* tt) { this->sourceGeneric = tt; }
void SetAlign(U8 alignment) { this->align = alignment; }
void SetInstanceSize(U32 size) { this->instanceSize = size; }
void SetGCTib(GCTib gctib);
void SetComponentTypeInfo(TypeInfo* ti) { this->componentTypeInfo = ti; }
void SetValidInheritNum(U16 num) { this->validInheritNum = num | (1 << 15); }
bool IsSubType(TypeInfo* superTypeInfo);
void SetFlagHasRefField();
void SetReflectInfo(ReflectInfo* info) { this->reflectInfo = info; }
void SetvExtensionDataStart(ExtensionData **ptr) { this->vExtensionDataStart = ptr; }
void SetEnumInfo(EnumInfo* ei) { this->enumInfo = ei; }
void SetEnumDebugInfo(EnumDebugInfo* enumDebugInfo);
void SetEnumCtorReflectInfo(EnumCtorReflectInfo* enumCtorInfo) { this->enumCtorReflectInfo = enumCtorInfo; }
MTableDesc* GetMTableDesc() const { return mTableDesc; }
void AddMTable(TypeInfo* ti, ExtensionData* extensionData);
FuncPtr* GetMTable(TypeInfo* itf);
TypeInfo* GetMethodOuterTI(TypeInfo* itf, U64 index);
U32 GetUUID();
inline U32 GetClassSize() const;
inline TypeInfo* GetSuperTypeInfo() const;
struct RAIISpinLock {
RAIISpinLock(AtomicSpinLock& pLock) : lock(pLock) { lock.Lock(); }
~RAIISpinLock() { lock.Unlock(); }
AtomicSpinLock& lock;
};
void TryInitMTable();
void TryInitMTableNoLock();
void GetInterfaces(std::vector<TypeInfo*> &itfs);
bool NeedRefresh();
void TryUpdateExtensionData(TypeInfo* itf, ExtensionData* extensionData);
private:
TypeInfo() = delete;
~TypeInfo() = delete;
void TraverseInnerExtensionDefs(const std::function<void(TypeInfo*)> getInterface = nullptr);
void TraverseOuterExtensionDefs(const std::function<void(TypeInfo*)> getInterface = nullptr);
ExtensionData* FindExtensionData(TypeInfo* itf, bool searchRecursively = false);
ExtensionData* FindExtensionDataRecursively(TypeInfo* itf);
std::pair<FuncPtr*, bool> FindMTable(U32 itfUUID);
inline bool IsMTableDescUnInitialized() {
return (mTableDesc == nullptr) || (validInheritNum >> 15 == 1)
#ifndef __arm__
|| (reinterpret_cast<uintptr_t>(mTableDesc) >> 63 == 1)
#endif
;
}
inline ArchUInt GetResolveBitmapFromMTableDesc()
{
return reinterpret_cast<uintptr_t>(mTableDesc);
}
const char* typeInfoName;
I8 type;
U8 flag;
U16 fieldNum;
union {
MSize instanceSize;
MSize componentSize;
};
GCTib gctib;
U32 uuid;
U8 align;
I8 typeArgsNum;
U16 validInheritNum;
U32* fieldOffsets;
union {
TypeTemplate* sourceGeneric;
FuncRef finalizerMethod;
};
TypeInfo **typeArgs;
TypeInfo **fields;
union {
TypeInfo* superTypeInfo;
TypeInfo* componentTypeInfo;
};
ExtensionData **vExtensionDataStart;
MTableDesc* mTableDesc;
union {
ReflectInfo* reflectInfo;
EnumInfo* enumInfo;
EnumDebugInfo* enumDebugInfo;
EnumCtorReflectInfo* enumCtorReflectInfo;
};
};
class GenericTypeInfo {
public:
const char* GetName() const { return name; }
inline const char* GetSourceGenericName();
U8 GetGenericArgsNum() { return genericArgsNum; }
U32 GetGenericConstraintNum() { return genericConstraintNum; }
TypeInfo* GetGenericConstraint(U32 idx) { return genericConstraints[idx]; }
void* GetGenericArg(U8 idx) { return genericArgs[idx]; }
bool IsGenericCustom() { return type == TypeKind::TYPE_KIND_GENERIC_CUSTOM; }
bool IsGeneric() { return type == TypeKind::TYPE_KIND_GENERIC_TI; }
TypeTemplate* GetSourceGeneric() { return tt; }
private:
const char* name;
I8 type;
U8 genericArgsNum;
U16 __attribute__((unused)) slot;
U32 genericConstraintNum;
union {
TypeInfo** genericArgs;
TypeInfo** genericConstraints;
};
TypeTemplate* tt;
};
}
#endif