Files
ft/Client/HybridCLRData/LocalIl2CppData-OSXEditor/il2cpp/libil2cpp/hybridclr/metadata/SuperSetAOTHomologousImage.cpp
2026-06-29 21:18:33 +08:00

411 lines
13 KiB
C++

#include "SuperSetAOTHomologousImage.h"
#include "vm/MetadataLock.h"
#include "vm/GlobalMetadata.h"
#include "vm/Class.h"
#include "vm/Image.h"
#include "vm/Exception.h"
#include "vm/MetadataCache.h"
#include "metadata/GenericMetadata.h"
namespace hybridclr
{
namespace metadata
{
void SuperSetAOTHomologousImage::InitRuntimeMetadatas()
{
_defaultIl2CppType = il2cpp_defaults.missing_class->byval_arg;
InitTypes0();
InitNestedClass();
InitTypes1();
InitMethods();
InitFields();
}
void SuperSetAOTHomologousImage::InitTypes0()
{
const Table& typeDefTb = _rawImage.GetTable(TableType::TYPEDEF);
uint32_t typeCount = typeDefTb.rowNum;
_typeDefs.resize(typeCount);
_aotTypeIndex2TypeDefs.resize(typeCount);
Il2CppImage* image = _aotAssembly->image;
for (uint32_t index = 0; index < typeCount; index++)
{
SuperSetTypeDefDetail& td = _typeDefs[index];
uint32_t rowIndex = index + 1;
TbTypeDef data = _rawImage.ReadTypeDef(rowIndex);
td.inited = false;
td.homoParentRowIndex = 0;
td.homoRowIndex = rowIndex;
td.homoMethodStartIndex = data.methodList;
td.homoFieldStartIndex = data.fieldList;
td.name = _rawImage.GetStringFromRawIndex(data.typeName);
td.namespaze = _rawImage.GetStringFromRawIndex(data.typeNamespace);
td.aotTypeIndex = kInvalidIndex;
td.aotIl2CppType = nullptr;
td.aotTypeDef = nullptr;
}
}
void SuperSetAOTHomologousImage::InitNestedClass()
{
const Table& nestedClassTb = _rawImage.GetTable(TableType::NESTEDCLASS);
for (uint32_t i = 0; i < nestedClassTb.rowNum; i++)
{
TbNestedClass data = _rawImage.ReadNestedClass(i + 1);
SuperSetTypeDefDetail& nestedType = _typeDefs[data.nestedClass - 1];
nestedType.homoParentRowIndex = data.enclosingClass;
}
}
void SuperSetAOTHomologousImage::InitType(SuperSetTypeDefDetail& type)
{
if (type.inited)
{
return;
}
type.inited = true;
if (type.homoParentRowIndex)
{
SuperSetTypeDefDetail& parent = _typeDefs[type.homoParentRowIndex - 1];
InitType(parent);
const Il2CppTypeDefinition* parentTypeDef = parent.aotTypeDef;
if (parentTypeDef == nullptr)
{
goto labelInitDefault;
}
void* iter = nullptr;
for (const Il2CppTypeDefinition* nextTypeDef; (nextTypeDef = (const Il2CppTypeDefinition*)il2cpp::vm::GlobalMetadata::GetNestedTypes((Il2CppMetadataTypeHandle)parentTypeDef, &iter));)
{
const char* nestedTypeName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(nextTypeDef->nameIndex);
IL2CPP_ASSERT(nestedTypeName);
if (!std::strcmp(type.name, nestedTypeName))
{
type.aotTypeDef = nextTypeDef;
type.aotTypeIndex = nextTypeDef->byvalTypeIndex;
type.aotIl2CppType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(nextTypeDef->byvalTypeIndex);
type.aotKlass = il2cpp::vm::GlobalMetadata::GetTypeInfoFromHandle((Il2CppMetadataTypeHandle)nextTypeDef);
_aotTypeIndex2TypeDefs[il2cpp::vm::GlobalMetadata::GetIndexForTypeDefinition(type.aotKlass)] = &type;
return;
}
}
}
else
{
Il2CppClass* klass = il2cpp::vm::Image::ClassFromName(_aotAssembly->image, type.namespaze, type.name);
if (klass)
{
type.aotTypeDef = (const Il2CppTypeDefinition*)klass->typeMetadataHandle;
type.aotIl2CppType = &klass->byval_arg;
type.aotTypeIndex = type.aotTypeDef->byvalTypeIndex;
type.aotKlass = klass;
_aotTypeIndex2TypeDefs[il2cpp::vm::GlobalMetadata::GetIndexForTypeDefinition(type.aotKlass)] = &type;
return;
}
}
labelInitDefault:
type.aotIl2CppType = &_defaultIl2CppType;
//TEMP_FORMAT(msg, "type: %s::%s can't find homologous type in assembly:%s", type.namespaze, type.name, _aotAssembly->aname.name);
//RaiseExecutionEngineException(msg);
}
void SuperSetAOTHomologousImage::InitTypes1()
{
for (SuperSetTypeDefDetail& td : _typeDefs)
{
InitType(td);
}
}
static const Il2CppMethodDefinition* FindMatchMethod(const Il2CppClass* klass1, const SuperSetMethodDefDetail& method2)
{
il2cpp::vm::Class::SetupMethods(const_cast<Il2CppClass*>(klass1));
const Il2CppGenericContainer* klassGenContainer = klass1->is_generic ? GetGenericContainerFromIl2CppType(&klass1->byval_arg) : nullptr;
for (uint16_t i = 0; i < klass1->method_count; i++)
{
const MethodInfo* method1 = klass1->methods[i];
if (std::strcmp(method1->name, method2.name))
{
continue;
}
if (IsMatchMethodSig(method1, method2.signature, klassGenContainer))
{
return (const Il2CppMethodDefinition*)method1->methodMetadataHandle;
}
}
return nullptr;
}
void SuperSetAOTHomologousImage::InitMethods()
{
const Table& methodTb = _rawImage.GetTable(TableType::METHOD);
uint32_t methodCount = methodTb.rowNum;
_methodDefs.resize(methodCount);
_token2MethodDefs.resize(methodCount * 2);
uint32_t typeCount = (uint32_t)_typeDefs.size();
for (SuperSetTypeDefDetail& type : _typeDefs)
{
uint32_t nextTypeMethodStartIndex = type.homoRowIndex < typeCount ? _typeDefs[type.homoRowIndex].homoMethodStartIndex : methodCount + 1;
for (uint32_t i = type.homoMethodStartIndex; i < nextTypeMethodStartIndex ; i++)
{
SuperSetMethodDefDetail& method = _methodDefs[i - 1];
method.homoRowIndex = i;
TbMethod data = _rawImage.ReadMethod(i);
method.declaringTypeDef = type.aotTypeDef;
method.name = _rawImage.GetStringFromRawIndex(data.name);
if (type.aotTypeDef == nullptr)
{
continue;
}
method.signature.flags = data.flags;
BlobReader methodSigReader = _rawImage.GetBlobReaderByRawIndex(data.signature);
ReadMethodDefSig(methodSigReader, method.signature);
method.aotMethodDef = FindMatchMethod(type.aotKlass, method);
if (method.aotMethodDef)
{
_token2MethodDefs[method.aotMethodDef->token] = &method;
}
}
}
}
void SuperSetAOTHomologousImage::ReadMethodDefSig(BlobReader& reader, MethodRefSig& method)
{
uint8_t rawSigFlags = reader.ReadByte();
if (rawSigFlags & (uint8_t)MethodSigFlags::GENERIC)
{
//IL2CPP_ASSERT(false);
method.genericParamCount = reader.ReadCompressedUint32();
IL2CPP_ASSERT(method.genericParamCount > 0);
}
uint32_t paramCount = reader.ReadCompressedUint32();
//IL2CPP_ASSERT(paramCount >= methodDef.parameterCount);
method.returnType = {};
ReadType(reader, nullptr, nullptr, method.returnType);
int readParamNum = 0;
for (; reader.NonEmpty(); )
{
Il2CppType paramType = {};
ReadType(reader, nullptr, nullptr, paramType);
method.params.push_back(paramType);
++readParamNum;
}
IL2CPP_ASSERT(readParamNum == (int)paramCount);
}
const Il2CppFieldDefinition* FindMatchField(const Il2CppClass* klass1, const SuperSetFieldDefDetail& field2)
{
il2cpp::vm::Class::SetupFields(const_cast<Il2CppClass*>(klass1));
const Il2CppGenericContainer* klassGenContainer = klass1->is_generic ? GetGenericContainerFromIl2CppType(&klass1->byval_arg) : nullptr;
for (uint16_t i = 0; i < klass1->field_count; i++)
{
const FieldInfo* field1 = klass1->fields + i;
if (std::strcmp(field1->name, field2.name))
{
continue;
}
if (IsMatchSigType(field1->type, &field2.type, klassGenContainer, nullptr))
{
return il2cpp::vm::GlobalMetadata::GetFieldDefinitionFromTypeDefAndFieldIndex((const Il2CppTypeDefinition*)klass1->typeMetadataHandle, i);
}
}
return nullptr;
}
void SuperSetAOTHomologousImage::InitFields()
{
const Table& fieldTb = _rawImage.GetTable(TableType::FIELD);
uint32_t fieldCount = fieldTb.rowNum;
_fields.resize(fieldTb.rowNum);
uint32_t typeCount = (uint32_t)_typeDefs.size();
for (SuperSetTypeDefDetail& type : _typeDefs)
{
uint32_t nextTypeFieldStartIndex = type.homoRowIndex < typeCount ? _typeDefs[type.homoRowIndex].homoFieldStartIndex : fieldCount + 1;
for (uint32_t i = type.homoFieldStartIndex; i < nextTypeFieldStartIndex; i++)
{
SuperSetFieldDefDetail& field = _fields[i - 1];
field.homoRowIndex = i;
TbField data = _rawImage.ReadField(i);
field.name = _rawImage.GetStringFromRawIndex(data.name);
field.declaringTypeDef = type.aotTypeDef;
field.declaringIl2CppType = type.aotIl2CppType;
if (type.aotTypeDef == nullptr)
{
continue;
}
BlobReader br = _rawImage.GetBlobReaderByRawIndex(data.signature);
FieldRefSig frs;
ReadFieldRefSig(br, nullptr, frs);
frs.type.attrs = data.flags;
field.type = frs.type;
field.aotFieldDef = FindMatchField(type.aotKlass, field);
}
}
}
MethodBody* SuperSetAOTHomologousImage::GetMethodBody(uint32_t token)
{
auto it = _token2MethodDefs.find(token);
if (it == _token2MethodDefs.end())
{
return nullptr;
}
SuperSetMethodDefDetail* method = it->second;
if (!method->body)
{
uint32_t rowIndex = method->homoRowIndex;
TbMethod methodData = _rawImage.ReadMethod(rowIndex);
MethodBody* body = new (HYBRIDCLR_MALLOC_ZERO(sizeof(MethodBody))) MethodBody();
ReadMethodBody(*method->aotMethodDef, methodData, *body);
method->body = body;
}
return method->body;
}
const Il2CppType* SuperSetAOTHomologousImage::GetIl2CppTypeFromRawTypeDefIndex(uint32_t index)
{
IL2CPP_ASSERT((size_t)index < _typeDefs.size());
return _typeDefs[index].aotIl2CppType;
}
Il2CppGenericContainer* SuperSetAOTHomologousImage::GetGenericContainerByRawIndex(uint32_t index)
{
return (Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(index);
}
Il2CppGenericContainer* SuperSetAOTHomologousImage::GetGenericContainerByTypeDefRawIndex(int32_t typeDefIndex)
{
auto it = _aotTypeIndex2TypeDefs.find(typeDefIndex);
if (it == _aotTypeIndex2TypeDefs.end())
{
return nullptr;
}
const Il2CppTypeDefinition* type = it->second->aotTypeDef;
if (type == nullptr)
{
return nullptr;
}
return (Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(type->genericContainerIndex);
}
const Il2CppMethodDefinition* SuperSetAOTHomologousImage::GetMethodDefinitionFromRawIndex(uint32_t index)
{
IL2CPP_ASSERT((size_t)index < _methodDefs.size());
SuperSetMethodDefDetail& method = _methodDefs[index];
const Il2CppMethodDefinition* methodDef = method.aotMethodDef;
if (!methodDef)
{
TEMP_FORMAT(errMsg, "method:%s rowIndex:%d not exist", method.name, method.homoRowIndex);
RaiseExecutionEngineException("find");
}
return methodDef;
}
void SuperSetAOTHomologousImage::ReadFieldRefInfoFromFieldDefToken(uint32_t rowIndex, FieldRefInfo& ret)
{
IL2CPP_ASSERT(rowIndex > 0);
SuperSetFieldDefDetail& fd = _fields[rowIndex - 1];
ret.containerType = *fd.declaringIl2CppType;
ret.field = fd.aotFieldDef;
}
void SuperSetAOTHomologousImage::ReadTypeFromResolutionScope(uint32_t scope, uint32_t typeNamespace, uint32_t typeName, Il2CppType& type)
{
TableType tokenType;
uint32_t rawIndex;
DecodeResolutionScopeCodedIndex(scope, tokenType, rawIndex);
switch (tokenType)
{
case TableType::MODULE:
{
if (!GetModuleIl2CppType(type, rawIndex, typeNamespace, typeName, false))
{
type = _defaultIl2CppType;
}
break;
}
case TableType::MODULEREF:
{
RaiseNotSupportedException("Image::ReadTypeFromResolutionScope not support ResolutionScore.MODULEREF");
break;
}
case TableType::ASSEMBLYREF:
{
TbAssemblyRef assRef = _rawImage.ReadAssemblyRef(rawIndex);
const Il2CppType* refType = GetIl2CppType(rawIndex, typeNamespace, typeName, false);
if (refType)
{
type.type = refType->type;
type.data = refType->data;
}
else
{
type = _defaultIl2CppType;
}
break;
}
case TableType::TYPEREF:
{
Il2CppType enClosingType = {};
ReadTypeFromTypeRef(rawIndex, enClosingType);
IL2CPP_ASSERT(typeNamespace == 0);
const char* name = _rawImage.GetStringFromRawIndex(typeName);
void* iter = nullptr;
Il2CppMetadataTypeHandle enclosingTypeDef = enClosingType.data.typeHandle;
if (!enclosingTypeDef)
{
//TEMP_FORMAT(errMsg, "Image::ReadTypeFromResolutionScope ReadTypeFromResolutionScope.TYPEREF enclosingType:%s", name);
//RaiseExecutionEngineException(errMsg);
type = _defaultIl2CppType;
break;
}
bool find = false;
for (const Il2CppTypeDefinition* nextTypeDef; (nextTypeDef = (const Il2CppTypeDefinition*)il2cpp::vm::GlobalMetadata::GetNestedTypes(enclosingTypeDef, &iter));)
{
const char* nestedTypeName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(nextTypeDef->nameIndex);
IL2CPP_ASSERT(nestedTypeName);
if (!std::strcmp(name, nestedTypeName))
{
GetIl2CppTypeFromTypeDefinition(nextTypeDef, type);
find = true;
break;
}
}
if (!find)
{
//std::string enclosingTypeName = GetKlassCStringFullName(&enClosingType);
//TEMP_FORMAT(errMsg, "Image::ReadTypeFromResolutionScope ReadTypeFromResolutionScope.TYPEREF fail. type:%s.%s", enclosingTypeName.c_str(), name);
//RaiseExecutionEngineException(errMsg);
type = _defaultIl2CppType;
break;
}
break;
}
default:
{
RaiseBadImageException("Image::ReadTypeFromResolutionScope invaild TableType");
}
}
IL2CPP_ASSERT(type.data.typeHandle);
}
}
}