1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201 |
- #include "Image.h"
- #include "vm/ClassInlines.h"
- #include "vm/Image.h"
- #include "vm/GlobalMetadata.h"
- #include "vm/Type.h"
- #include "vm/Field.h"
- #include "vm/Object.h"
- #include "vm/Runtime.h"
- #include "vm/Array.h"
- #include "vm/Reflection.h"
- #include "vm/MetadataLock.h"
- #include "vm/String.h"
- #include "metadata/GenericMetadata.h"
- #include "icalls/mscorlib/System.Reflection/FieldInfo.h"
- #ifdef HYBRIDCLR_UNITY_2021_OR_NEW
- #include "icalls/mscorlib/System/RuntimeTypeHandle.h"
- #else
- #include "icalls/mscorlib/System.Reflection/PropertyInfo.h"
- #endif
- #include "icalls/mscorlib/System/Type.h"
- #include "utils/StringUtils.h"
- #include "MetadataUtil.h"
- #include "BlobReader.h"
- #include "MetadataPool.h"
- namespace hybridclr
- {
- namespace metadata
- {
- static const char* s_netstandardRefs[]
- {
- "mscorlib",
- "System",
- "System.Core",
- "System.Numerics",
- "System.Collections",
- "System.Collections.Concurrent",
- "System.Numerics.Vectors",
- "System.Data",
- "System.Configuration",
- "System.IO.Compression",
- "System.Net",
- "System.Security",
- "System.Xml",
- "System.Xml.Linq",
- "System.Xml.Serialization",
- "System.Runtime.Serialization",
- "System.Json",
- "System.Diagnostics.Tracing",
- "System.Net.Http",
- nullptr,
- };
- bool Image::IsValueTypeFromToken(TableType tableType, uint32_t rowIndex)
- {
- switch (tableType)
- {
- case TableType::TYPEREF:
- {
- TbTypeRef r = _rawImage->ReadTypeRef(rowIndex);
- const char* typeNamespace = _rawImage->GetStringFromRawIndex(r.typeNamespace);
- if (std::strcmp(typeNamespace, "System"))
- {
- return false;
- }
- const char* typeName = _rawImage->GetStringFromRawIndex(r.typeName);
- return std::strcmp(typeName, "ValueType") == 0 || std::strcmp(typeName, "Enum") == 0;
- }
- default:
- {
- return false;
- }
- }
- }
- bool Image::IsThreadStaticCtorToken(TableType tableType, uint32_t rowIndex)
- {
- if (tableType != TableType::MEMBERREF)
- {
- return false;
- }
- TbMemberRef data = _rawImage->ReadMemberRef(rowIndex);
- TableType parentTableType = DecodeMemberRefParentType(data.classIdx);
- if (parentTableType != TableType::TYPEREF)
- {
- return false;
- }
- const Il2CppType* type = ReadTypeFromTypeRef(DecodeMemberRefParentRowIndex(data.classIdx));
- const Il2CppTypeDefinition* typeDef = GetUnderlyingTypeDefinition(type);
- const char* strNamespace = il2cpp::vm::GlobalMetadata::GetStringFromIndex(typeDef->namespaceIndex);
- if (std::strcmp(strNamespace, "System"))
- {
- return false;
- }
- const char* strName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(typeDef->nameIndex);
- return std::strcmp(strName, "ThreadStaticAttribute") == 0;
- }
- void Image::ReadMemberRefParentFromToken(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex, ResolveMemberRefParent& ret)
- {
- ret.parentType = tableType;
- switch (tableType)
- {
- case hybridclr::metadata::TableType::TYPEREF:
- ret.type = ReadTypeFromTypeRef(rowIndex);
- break;
- case hybridclr::metadata::TableType::TYPEDEF:
- ret.type = ReadTypeFromTypeDef(rowIndex);
- break;
- case hybridclr::metadata::TableType::METHOD:
- RaiseNotSupportedException("ReadMemberRefParentFromToken. from METHOD");
- break;
- case hybridclr::metadata::TableType::MODULEREF:
- RaiseNotSupportedException("ReadMemberRefParentFromToken. from MODULEREF");
- break;
- case hybridclr::metadata::TableType::TYPESPEC:
- ret.type = ReadTypeFromTypeSpec(klassGenericContainer, methodGenericContainer, rowIndex);
- break;
- default:
- {
- RaiseExecutionEngineException("ReadMemberRefParentFromToken. invalid table type");
- break;
- }
- }
- }
- #pragma region type
- const Il2CppType* Image::ReadArrayType(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer)
- {
- Il2CppType* arrType = MetadataMallocT<Il2CppType>();;
- arrType->type = IL2CPP_TYPE_ARRAY;
- Il2CppArrayType& type = *MetadataMallocT<Il2CppArrayType>();
- arrType->data.array = &type;
- const Il2CppType* eleType = ReadType(reader, klassGenericContainer, methodGenericContainer);
- type.etype = eleType;
- type.rank = reader.ReadCompressedUint32();
- type.numsizes = reader.ReadCompressedUint32();
- if (type.numsizes > 0)
- {
- type.sizes = (int*)alloca(type.numsizes * sizeof(int));
- for (uint8_t i = 0; i < type.numsizes; i++)
- {
- type.sizes[i] = reader.ReadCompressedUint32();
- }
- }
- else
- {
- type.sizes = nullptr;
- }
- type.numlobounds = reader.ReadCompressedUint32();
- if (type.numlobounds > 0)
- {
- type.lobounds = (int*)alloca(type.numlobounds * sizeof(int));
- for (uint8_t i = 0; i < type.numlobounds; i++)
- {
- type.lobounds[i] = reader.ReadCompressedInt32();
- }
- }
- else
- {
- type.lobounds = nullptr;
- }
- return arrType;
- }
- const Il2CppGenericClass* Image::ReadGenericClass(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer)
- {
- const Il2CppType* genericBase = ReadType(reader, klassGenericContainer, methodGenericContainer);
- IL2CPP_ASSERT(genericBase->type == IL2CPP_TYPE_CLASS || genericBase->type == IL2CPP_TYPE_VALUETYPE);
- uint32_t argc = reader.ReadCompressedUint32();
- IL2CPP_ASSERT(argc > 0 && argc <= 32);
- const Il2CppType* types[32];
- //const Il2CppType** types = (const Il2CppType**)alloca(argc * sizeof(const Il2CppType*));
- for (uint32_t i = 0; i < argc; i++)
- {
- types[i] = ReadType(reader, klassGenericContainer, methodGenericContainer);
- }
- const Il2CppGenericInst* genericInst = il2cpp::vm::MetadataCache::GetGenericInst(types, argc);
- return il2cpp::metadata::GenericMetadata::GetGenericClass(genericBase, genericInst);
- }
- const Il2CppType* Image::ReadType(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer)
- {
- Il2CppType type = {};
- const Il2CppType* underlyingType = nullptr;
- readAgain:
- Il2CppTypeEnum etype = (Il2CppTypeEnum)reader.ReadByte();
- type.type = etype;
- switch (etype)
- {
- case IL2CPP_TYPE_VOID:
- break;
- case IL2CPP_TYPE_BOOLEAN:
- case IL2CPP_TYPE_CHAR:
- case IL2CPP_TYPE_I1:
- case IL2CPP_TYPE_U1:
- case IL2CPP_TYPE_I2:
- case IL2CPP_TYPE_U2:
- case IL2CPP_TYPE_I4:
- case IL2CPP_TYPE_U4:
- case IL2CPP_TYPE_I8:
- case IL2CPP_TYPE_U8:
- case IL2CPP_TYPE_R4:
- case IL2CPP_TYPE_R8:
- case IL2CPP_TYPE_TYPEDBYREF:
- case IL2CPP_TYPE_I:
- case IL2CPP_TYPE_U:
- {
- SET_IL2CPPTYPE_VALUE_TYPE(type, 1);
- break;
- }
- case IL2CPP_TYPE_STRING:
- {
- break;
- }
- case IL2CPP_TYPE_PTR:
- {
- //SET_IL2CPPTYPE_VALUE_TYPE(type, 1);
- type.data.type = ReadType(reader, klassGenericContainer, methodGenericContainer);
- //SET_IL2CPPTYPE_VALUE_TYPE(type, 1);
- break;
- }
- case IL2CPP_TYPE_BYREF:
- {
- //const Il2CppType* underlyingType = ReadType(reader, klassGenericContainer, methodGenericContainer);
- //type = *underlyingType;
- type.byref = 1;
- goto readAgain;
- }
- case IL2CPP_TYPE_VALUETYPE:
- case IL2CPP_TYPE_CLASS:
- {
- uint32_t codedIndex = reader.ReadCompressedUint32(); // 低2位为type, 高位为index
- underlyingType = ReadTypeFromToken(klassGenericContainer, methodGenericContainer, DecodeTypeDefOrRefOrSpecCodedIndexTableType(codedIndex), DecodeTypeDefOrRefOrSpecCodedIndexRowIndex(codedIndex));
- break;
- }
- case IL2CPP_TYPE_ARRAY:
- {
- underlyingType = ReadArrayType(reader, klassGenericContainer, methodGenericContainer);
- break;
- }
- case IL2CPP_TYPE_GENERICINST:
- {
- const Il2CppGenericClass* genericClass = ReadGenericClass(reader, klassGenericContainer, methodGenericContainer);
- type.data.generic_class = const_cast<Il2CppGenericClass*>(genericClass);
- COPY_IL2CPPTYPE_VALUE_TYPE_FLAG(type, *genericClass->type);
- break;
- }
- case IL2CPP_TYPE_FNPTR:
- {
- // il2cpp doesn't support FNPTR. il2cpp treats IL2CPP_TYPE_FNPTR as IL2CPP_TYPE_I.
- // so we handle it as IL2CPP_TYPE_I.
- //
- //MethodRefSig* method = new (HYBRIDCLR_MALLOC(sizeof(MethodRefSig))) MethodRefSig();
- //ReadMethodRefSig(reader, *method);
- //type.data.method = method;
- type.type = IL2CPP_TYPE_I;
- MethodRefSig method = {};
- ReadMethodRefSig(reader, method);
- break;
- }
- case IL2CPP_TYPE_OBJECT:
- {
- break;
- }
- case IL2CPP_TYPE_SZARRAY:
- {
- type.data.type = ReadType(reader, klassGenericContainer, methodGenericContainer);
- break;
- }
- case IL2CPP_TYPE_VAR:
- {
- IL2CPP_ASSERT(!klassGenericContainer || !klassGenericContainer->is_method);
- uint32_t number = reader.ReadCompressedUint32();
- if (klassGenericContainer)
- {
- //IL2CPP_ASSERT(hybridclr::metadata::IsInterpreterIndex(klassGenericContainer->ownerIndex));
- type.data.genericParameterHandle = il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex((Il2CppMetadataGenericContainerHandle)klassGenericContainer, number);
- }
- else
- {
- type.data.__genericParameterIndex = number;
- }
- /*Il2CppGenericParameter* gp = (Il2CppGenericParameter*)type.data.genericParameterHandle;
- IL2CPP_ASSERT(hybridclr::metadata::IsInterpreterIndex(gp->ownerIndex));*/
- break;
- }
- case IL2CPP_TYPE_MVAR:
- {
- IL2CPP_ASSERT(!methodGenericContainer || methodGenericContainer->is_method);
- uint32_t number = reader.ReadCompressedUint32();
- if (methodGenericContainer)
- {
- type.data.genericParameterHandle = il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex((Il2CppMetadataGenericContainerHandle)methodGenericContainer, number);
- }
- else
- {
- // method ref can't resolve at that time
- type.data.__genericParameterIndex = number;
- }
- break;
- }
- case IL2CPP_TYPE_CMOD_REQD:
- {
- ++type.num_mods;
- uint32_t encodeToken = reader.ReadCompressedUint32();
- const Il2CppType* modType = ReadTypeFromToken(nullptr, nullptr, DecodeTypeDefOrRefOrSpecCodedIndexTableType(encodeToken), DecodeTypeDefOrRefOrSpecCodedIndexRowIndex(encodeToken));
- if (modType->type != IL2CPP_TYPE_CLASS && modType->type != IL2CPP_TYPE_VALUETYPE)
- {
- goto readAgain;
- }
- IL2CPP_ASSERT(modType->data.typeHandle);
- const Il2CppTypeDefinition* modTypeDef = (const Il2CppTypeDefinition*)modType->data.typeHandle;
- const char* modTypeName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(modTypeDef->nameIndex);
- const char* modTypeNamespace = il2cpp::vm::GlobalMetadata::GetStringFromIndex(modTypeDef->namespaceIndex);
- if (std::strcmp(modTypeNamespace, "System.Runtime.InteropServices") == 0)
- {
- if (std::strcmp(modTypeName, "InAttribute") == 0)
- {
- type.attrs |= PARAM_ATTRIBUTE_IN;
- }
- else if (std::strcmp(modTypeName, "OutAttribute") == 0)
- {
- type.attrs |= PARAM_ATTRIBUTE_OUT;
- }
- else if (std::strcmp(modTypeName, "OptionalAttribute") == 0)
- {
- type.attrs |= PARAM_ATTRIBUTE_OPTIONAL;
- }
- }
- goto readAgain;
- }
- case IL2CPP_TYPE_CMOD_OPT:
- {
- ++type.num_mods;
- uint32_t encodeToken = reader.ReadCompressedUint32();
- goto readAgain;
- }
- case IL2CPP_TYPE_INTERNAL:
- {
- RaiseNotSupportedException("Image::ReadType IL2CPP_TYPE_INTERNAL");
- break;
- }
- case IL2CPP_TYPE_MODIFIER:
- {
- RaiseNotSupportedException("Image::ReadType IL2CPP_TYPE_MODIFIER");
- break;
- }
- case IL2CPP_TYPE_SENTINEL:
- {
- break;
- }
- case IL2CPP_TYPE_PINNED:
- {
- type.pinned = true;
- goto readAgain;
- }
- default:
- {
- RaiseBadImageException("Image::ReadType invalid type");
- break;
- }
- }
- if (underlyingType)
- {
- type.type = underlyingType->type;
- type.data = underlyingType->data;
- COPY_IL2CPPTYPE_VALUE_TYPE_FLAG(type, *underlyingType);
- }
- if (type.byref)
- {
- SET_IL2CPPTYPE_VALUE_TYPE(type, 0);
- }
- return MetadataPool::GetPooledIl2CppType(type);
- }
- const Il2CppType* Image::ReadTypeFromResolutionScope(uint32_t scope, uint32_t typeNamespace, uint32_t typeName)
- {
- TableType tokenType;
- uint32_t rawIndex;
- DecodeResolutionScopeCodedIndex(scope, tokenType, rawIndex);
- switch (tokenType)
- {
- case TableType::MODULE:
- {
- return GetModuleIl2CppType(rawIndex, typeNamespace, typeName, true);
- }
- case TableType::MODULEREF:
- {
- RaiseNotSupportedException("Image::ReadTypeFromResolutionScope not support ResolutionScore.MODULEREF");
- break;
- }
- case TableType::ASSEMBLYREF:
- {
- TbAssemblyRef assRef = _rawImage->ReadAssemblyRef(rawIndex);
- return GetIl2CppType(rawIndex, typeNamespace, typeName, true);
- }
- case TableType::TYPEREF:
- {
- const Il2CppType* enClosingType = ReadTypeFromTypeRef(rawIndex);
- 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);
- }
- 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))
- {
- return GetIl2CppTypeFromTypeDefinition(nextTypeDef);
- }
- }
- std::string enclosingTypeName = GetKlassCStringFullName(enClosingType);
- TEMP_FORMAT(errMsg, "Image::ReadTypeFromResolutionScope ReadTypeFromResolutionScope.TYPEREF fail. type:%s.%s", enclosingTypeName.c_str(), name);
- RaiseExecutionEngineException(errMsg);
- break;
- }
- default:
- {
- RaiseBadImageException("Image::ReadTypeFromResolutionScope invaild TableType");
- break;
- }
- }
- return nullptr;
- }
- const Il2CppType* Image::ReadTypeFromTypeDef(uint32_t rowIndex)
- {
- return GetIl2CppTypeFromRawTypeDefIndex(rowIndex - 1);
- }
- const Il2CppType* Image::ReadTypeFromTypeRef(uint32_t rowIndex)
- {
- TbTypeRef r = _rawImage->ReadTypeRef(rowIndex);
- return ReadTypeFromResolutionScope(r.resolutionScope, r.typeNamespace, r.typeName);
- }
- const Il2CppType* Image::ReadTypeFromTypeSpec(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, uint32_t rowIndex)
- {
- TbTypeSpec r = _rawImage->ReadTypeSpec(rowIndex);
- BlobReader reader = _rawImage->GetBlobReaderByRawIndex(r.signature);
- return ReadType(reader, klassGenericContainer, methodGenericContainer);
- }
- const Il2CppType* Image::ReadTypeFromMemberRefParent(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex)
- {
- ResolveMemberRefParent mrp = {};
- ReadMemberRefParentFromToken(klassGenericContainer, methodGenericContainer, tableType, rowIndex, mrp);
- IL2CPP_ASSERT(mrp.parentType == TableType::TYPEDEF || mrp.parentType == TableType::TYPEREF || mrp.parentType == TableType::TYPESPEC);
- return mrp.type;
- }
- const Il2CppType* Image::ReadTypeFromToken(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex)
- {
- switch (tableType)
- {
- case TableType::TYPEDEF:
- {
- return ReadTypeFromTypeDef(rowIndex);
- }
- case TableType::TYPEREF:
- {
- return ReadTypeFromTypeRef(rowIndex);
- }
- case TableType::TYPESPEC:
- {
- return ReadTypeFromTypeSpec(klassGenericContainer, methodGenericContainer, rowIndex);
- }
- default:
- {
- RaiseBadImageException("Image::ReadTypeFromToken invalid TableType");
- return nullptr;
- }
- }
- }
- #pragma endregion
- void Image::ReadFieldRefSig(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, FieldRefSig& field)
- {
- field = {};
- uint8_t rawSigType = reader.ReadByte();
- SigType sigType = DecodeSigType(rawSigType);
- IL2CPP_ASSERT(sigType == SigType::FIELD);
- field.type = ReadType(reader, klassGenericContainer, nullptr);
- }
- void Image::ReadMethodRefSig(BlobReader& reader, MethodRefSig& method)
- {
- method = {};
- uint8_t rawSigFlags = reader.ReadByte();
- method.flags = rawSigFlags;
- if (rawSigFlags & (uint8_t)SigType::GENERIC)
- {
- method.genericParamCount = reader.ReadCompressedUint32();
- }
- uint32_t paramCount = reader.ReadCompressedUint32();
- method.returnType = ReadType(reader, nullptr, nullptr);
- bool sentinel = false;
- for (uint32_t readParamNum = 0; readParamNum < paramCount; ++readParamNum)
- {
- const Il2CppType* paramType = ReadType(reader, nullptr, nullptr);
- if (paramType->type == IL2CPP_TYPE_SENTINEL)
- {
- IL2CPP_ASSERT(rawSigFlags & (uint8_t)SigType::VARARG);
- sentinel = true;
- continue;
- }
- method.params.push_back(paramType);
- }
- }
- void Image::ReadMemberRefSig(const Il2CppGenericContainer* klassGenericContainer, TbMemberRef& data, ResolveMemberRefSig& signature)
- {
- BlobReader reader = _rawImage->GetBlobReaderByRawIndex(data.signature);
- uint8_t rawSigFlags = reader.PeekByte();
- SigType sigType = DecodeSigType(rawSigFlags);
- if (sigType == SigType::FIELD)
- {
- signature.memberType = TableType::FIELD_POINTER;
- ReadFieldRefSig(reader, klassGenericContainer, signature.field);
- }
- else
- {
- signature.memberType = TableType::METHOD_POINTER;
- ReadMethodRefSig(reader, signature.method);
- }
- }
- void Image::ReadMethodRefInfoFromToken(const Il2CppGenericContainer* klassGenericContainer,
- const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex, MethodRefInfo& ret)
- {
- IL2CPP_ASSERT(rowIndex > 0);
- switch (tableType)
- {
- case TableType::METHOD:
- {
- const Il2CppMethodDefinition* methodDef = GetMethodDefinitionFromRawIndex(rowIndex - 1);
- const Il2CppTypeDefinition* typeDef = (const Il2CppTypeDefinition*)il2cpp::vm::GlobalMetadata::GetTypeHandleFromIndex(methodDef->declaringType);
- const Il2CppType* type = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDef->byvalTypeIndex);
- ret.containerType = type;
- ret.methodDef = methodDef;
- IL2CPP_ASSERT(type);
- IL2CPP_ASSERT(methodDef);
- break;
- }
- case TableType::MEMBERREF:
- {
- ReadMethodRefInfoFromMemberRef(klassGenericContainer, methodGenericContainer, rowIndex, ret);
- break;
- }
- case TableType::METHODSPEC:
- {
- TbMethodSpec methodSpec = _rawImage->ReadMethodSpec(rowIndex);
- ret.instantiation = ReadMethodSpecInstantiation(methodSpec.instantiation, klassGenericContainer, methodGenericContainer);
- TableType methodTableType = DecodeMethodDefOrRefCodedIndexTableType(methodSpec.method);
- uint32_t methodRowIndex = DecodeMethodDefOrRefCodedIndexRowIndex(methodSpec.method);
- switch (methodTableType)
- {
- case TableType::METHOD:
- {
- ReadMethodRefInfoFromToken(klassGenericContainer, methodGenericContainer, methodTableType, methodRowIndex, ret);
- break;
- }
- case TableType::MEMBERREF:
- {
- ReadMethodRefInfoFromMemberRef(klassGenericContainer, methodGenericContainer, methodRowIndex, ret);
- break;
- }
- default:
- {
- RaiseBadImageException("Image::ReadMethodRefInfoFromToken METHODSPEC invalid TableType");
- break;
- }
- }
- break;
- }
- default:
- {
- RaiseBadImageException("Image::ReadMethodRefInfoFromToken invalid TableType");
- }
- }
- }
- void Image::ReadResolveMemberRefFromMemberRef(const Il2CppGenericContainer* klassGenericContainer,
- const Il2CppGenericContainer* methodGenericContainer, uint32_t rowIndex, ResolveMemberRef& ret)
- {
- TbMemberRef data = _rawImage->ReadMemberRef(rowIndex);
- ret.name = _rawImage->GetStringFromRawIndex(data.name);
- ReadMemberRefParentFromToken(klassGenericContainer, methodGenericContainer, DecodeMemberRefParentType(data.classIdx), DecodeMemberRefParentRowIndex(data.classIdx), ret.parent);
- IL2CPP_ASSERT(ret.parent.parentType == TableType::TYPEDEF || ret.parent.parentType == TableType::TYPEREF || ret.parent.parentType == TableType::TYPESPEC);
- ReadMemberRefSig(nullptr, data, ret.signature);
- }
- void Image::ReadMethodRefInfoFromMemberRef(const Il2CppGenericContainer* klassGenericContainer,
- const Il2CppGenericContainer* methodGenericContainer, uint32_t rowIndex, MethodRefInfo& ret)
- {
- ResolveMemberRef rmr = {};
- ReadResolveMemberRefFromMemberRef(klassGenericContainer, methodGenericContainer, rowIndex, rmr);
- IL2CPP_ASSERT(rmr.parent.parentType == TableType::TYPEDEF || rmr.parent.parentType == TableType::TYPEREF || rmr.parent.parentType == TableType::TYPESPEC);
- IL2CPP_ASSERT(rmr.signature.memberType == TableType::METHOD_POINTER);
- ret.containerType = rmr.parent.type;
- ret.methodDef = ResolveMethodDefinition(rmr.parent.type, rmr.name, rmr.signature.method);
- }
- const Il2CppGenericInst* Image::ReadMethodSpecInstantiation(uint32_t signature, const Il2CppGenericContainer* klassGenericContainer,
- const Il2CppGenericContainer* methodGenericContainer)
- {
- BlobReader reader = _rawImage->GetBlobReaderByRawIndex(signature);
- uint8_t rawSigFlags = reader.ReadByte();
- IL2CPP_ASSERT(rawSigFlags == 0xA);
- uint32_t argCount = reader.ReadCompressedUint32();
- IL2CPP_ASSERT(argCount >= 0 && argCount < 100);
- if (argCount == 0)
- {
- return nullptr;
- }
- IL2CPP_ASSERT(argCount > 0 && argCount <= 32);
- const Il2CppType* types[32];
- //genericInstantiation = (Il2CppGenericInst*)il2cpp::vm::MetadataMalloc(sizeof(Il2CppGenericInst));
- //genericInstantiation->type_argc = argCount;
- //genericInstantiation->type_argv = (const Il2CppType**)il2cpp::vm::MetadataCalloc(argCount, sizeof(Il2CppType*));
- for (uint32_t i = 0; i < argCount; i++)
- {
- const Il2CppType* type = ReadType(reader, klassGenericContainer, methodGenericContainer);
- types[i] = type;
- }
- return il2cpp::vm::MetadataCache::GetGenericInst(types, argCount);
- }
- void Image::ReadFieldRefInfoFromMemberRef(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, uint32_t rowIndex, FieldRefInfo& ret)
- {
- ResolveMemberRef rmr = {};
- ReadResolveMemberRefFromMemberRef(klassGenericContainer, methodGenericContainer, rowIndex, rmr);
- IL2CPP_ASSERT(rmr.parent.parentType == TableType::TYPEDEF || rmr.parent.parentType == TableType::TYPEREF || rmr.parent.parentType == TableType::TYPESPEC);
- IL2CPP_ASSERT(rmr.signature.memberType == TableType::FIELD_POINTER);
- ret.containerType = rmr.parent.type;
- ResolveFieldThrow(rmr.parent.type, rmr.name, rmr.signature.field.type, ret.field);
- }
- void Image::ReadLocalVarSig(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, il2cpp::utils::dynamic_array<const Il2CppType*>& vars)
- {
- uint8_t sig = reader.ReadByte();
- IL2CPP_ASSERT(sig == 0x7);
- uint32_t varCount = reader.ReadCompressedUint32();
- IL2CPP_ASSERT(varCount >= 1 && varCount <= 0xFFFE);
- vars.resize_uninitialized(varCount);
- for (uint32_t i = 0; i < varCount; i++)
- {
- vars[i] = ReadType(reader, klassGenericContainer, methodGenericContainer);
- }
- }
- void Image::ReadStandAloneSig(uint32_t signatureIdx, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, ResolveStandAloneMethodSig& methodSig)
- {
- BlobReader reader = _rawImage->GetBlobReaderByRawIndex(signatureIdx);
- uint8_t sig = reader.ReadByte();
- methodSig.flags = sig;
- uint32_t paramCount = reader.ReadCompressedUint32();
- if (paramCount > 0xFFFE)
- {
- RaiseBadImageException("ReadStandAloneSig exceed max param count");
- }
- methodSig.returnType = ReadType(reader, klassGenericContainer, methodGenericContainer);
- if (paramCount > 0)
- {
- for (uint32_t i = 0; i < paramCount; i++)
- {
- methodSig.params.push_back(ReadType(reader, klassGenericContainer, methodGenericContainer));
- }
- }
- if (reader.NonEmpty())
- {
- RaiseNotSupportedException("ReadStandAloneSig don't support sentinel params");
- }
- }
- Il2CppClass* Image::FindNetStandardExportedType(const char* namespaceStr, const char* nameStr)
- {
- for (const char** ptrAssName = s_netstandardRefs; *ptrAssName; ptrAssName++)
- {
- const Il2CppAssembly* refAss = GetLoadedAssembly(*ptrAssName);
- if (refAss)
- {
- const Il2CppImage* image2 = il2cpp::vm::Assembly::GetImage(refAss);
- Il2CppClass* klass = il2cpp::vm::Class::FromName(image2, namespaceStr, nameStr);
- if (klass)
- {
- return klass;
- }
- }
- }
- return nullptr;
- }
- const Il2CppType* Image::GetIl2CppType(uint32_t assemblyRefIndex, uint32_t typeNamespace, uint32_t typeName, bool raiseExceptionIfNotFound)
- {
- TbAssemblyRef data = _rawImage->ReadAssemblyRef(assemblyRefIndex);
- const char* assName = _rawImage->GetStringFromRawIndex(data.name);
- const char* typeNameStr = _rawImage->GetStringFromRawIndex(typeName);
- const char* typeNamespaceStr = _rawImage->GetStringFromRawIndex(typeNamespace);
- const Il2CppAssembly* refAss = GetLoadedAssembly(assName);
- Il2CppClass* klass = nullptr;
- if (refAss)
- {
- const Il2CppImage* image2 = il2cpp::vm::Assembly::GetImage(refAss);
- klass = il2cpp::vm::Class::FromName(image2, typeNamespaceStr, typeNameStr);
- }
- else if (!refAss && std::strcmp(assName, "netstandard") == 0)
- {
- klass = FindNetStandardExportedType(typeNamespaceStr, typeNameStr);
- }
- if (!klass)
- {
- if (!raiseExceptionIfNotFound)
- {
- return nullptr;
- }
- il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetTypeLoadException(
- CStringToStringView(typeNamespaceStr),
- CStringToStringView(typeNameStr),
- CStringToStringView(assName)));
- }
- return &klass->byval_arg;
- }
- void Image::ReadMethodBody(const Il2CppMethodDefinition& methodDef, const TbMethod& methodData, MethodBody& body)
- {
- uint32_t bodyRVA = methodData.rva;
- if (bodyRVA > 0)
- {
- uint32_t methodImageOffset = 0;
- bool ret = _rawImage->TranslateRVAToImageOffset(bodyRVA, methodImageOffset);
- IL2CPP_ASSERT(ret);
- const byte* bodyStart = _rawImage->GetDataPtrByImageOffset(methodImageOffset);
- byte bodyFlags = *bodyStart;
- byte smallFatFlags = bodyFlags & 0x3;
- if (smallFatFlags == (uint8_t)CorILMethodFormat::Tiny)
- {
- body.flags = (uint32_t)(bodyFlags & 0x3);
- body.ilcodes = bodyStart + 1;
- body.codeSize = (uint8_t)bodyFlags >> 2;
- body.maxStack = 8;
- }
- else
- {
- IL2CPP_ASSERT(smallFatFlags == (uint8_t)CorILMethodFormat::Fat);
- const CorILMethodFatHeader* methodHeader = (const CorILMethodFatHeader*)GetAlignBorder<4>(bodyStart);
- IL2CPP_ASSERT(methodHeader->size == 3);
- body.flags = methodHeader->flags;
- body.ilcodes = bodyStart + methodHeader->size * 4;
- body.codeSize = methodHeader->codeSize;
- body.maxStack = methodHeader->maxStack;
- if (methodHeader->localVarSigToken)
- {
- TbStandAloneSig sigData = _rawImage->ReadStandAloneSig(DecodeTokenRowIndex(methodHeader->localVarSigToken));
- BlobReader reader = _rawImage->GetBlobReaderByRawIndex(sigData.signature);
- ReadLocalVarSig(reader,
- GetGenericContainerByTypeDefRawIndex(DecodeMetadataIndex(methodDef.declaringType)),
- GetGenericContainerByRawIndex(DecodeMetadataIndex(methodDef.genericContainerIndex)),
- body.localVars);
- }
- }
- if (body.flags & (uint8_t)CorILMethodFormat::MoreSects)
- {
- const byte* nextSection = (const byte*)GetAlignBorder<4>(body.ilcodes + body.codeSize);
- while (true)
- {
- byte kind = *nextSection;
- if (!(kind & (byte)CorILSecion::EHTable))
- {
- IL2CPP_ASSERT(false && "not support kind");
- break;
- }
- if (kind & (byte)CorILSecion::FatFormat)
- {
- CorILEHSectionHeaderFat* ehSec = (CorILEHSectionHeaderFat*)nextSection;
- uint32_t dataSize = (uint32_t)ehSec->dataSize0 | ((uint32_t)ehSec->dataSize1 << 8) | ((uint32_t)ehSec->dataSize2 << 16);
- IL2CPP_ASSERT(dataSize % 24 == 4);
- uint32_t ehCount = (dataSize - 4) / 24;
- body.exceptionClauses.reserve(ehCount);
- for (uint32_t i = 0; i < ehCount; i++)
- {
- CorILEHFat& eh = ehSec->clauses[i];
- IL2CPP_ASSERT(eh.flags >= (uint32_t)CorILExceptionClauseType::Exception && eh.flags <= (uint32_t)CorILExceptionClauseType::Fault);
- body.exceptionClauses.push_back({
- (CorILExceptionClauseType)eh.flags,
- eh.tryOffset,
- eh.tryLength,
- eh.handlerOffset,
- eh.handlerLength,
- eh.classTokenOrFilterOffset });
- }
- nextSection += dataSize;
- }
- else
- {
- CorILEHSectionHeaderSmall* ehSec = (CorILEHSectionHeaderSmall*)nextSection;
- IL2CPP_ASSERT(ehSec->dataSize % 12 == 4);
- uint32_t ehCount = (ehSec->dataSize - 4) / 12;
- body.exceptionClauses.reserve(ehCount);
- for (uint32_t i = 0; i < ehCount; i++)
- {
- CorILEHSmall& eh = ehSec->clauses[i];
- IL2CPP_ASSERT(eh.flags >= 0 && eh.flags <= 4);
- body.exceptionClauses.push_back({
- (CorILExceptionClauseType)eh.flags,
- eh.tryOffset,
- eh.tryLength,
- ((uint32_t)eh.handlerOffset1 << 8) + eh.handlerOffset0,
- eh.handlerLength,
- eh.classTokenOrFilterOffset });
- }
- nextSection += ehSec->dataSize;
- }
- if (!(kind & (byte)CorILSecion::MoreSects))
- {
- break;
- }
- }
- }
- }
- else
- {
- body.ilcodes = nullptr;
- body.codeSize = 0;
- }
- }
- const MethodInfo* Image::FindImplMethod(Il2CppClass* klass, const MethodInfo* method)
- {
- if (!IsVirtualMethod(method->flags))
- {
- return method;
- }
- il2cpp::vm::Class::Init(klass);
- const MethodInfo* result;
- if (hybridclr::metadata::IsInterface(method->klass->flags))
- {
- result = il2cpp::vm::ClassInlines::GetInterfaceInvokeDataFromVTable(klass, method->klass, method->slot)->method;
- }
- else
- {
- result = klass->vtable[method->slot].method;
- }
- IL2CPP_ASSERT(!method->genericMethod || method->is_inflated);
- if (method->genericMethod && method->genericMethod->context.method_inst/* && method->genericMethod*/) // means it's genericInstance method 或generic method
- {
- result = GetGenericVirtualMethod(result, method);
- }
- return result;
- }
- Il2CppString* Image::GetIl2CppUserStringFromRawIndex(StringIndex index)
- {
- il2cpp::os::FastAutoLock lock(&il2cpp::vm::g_MetadataLock);
- Il2CppString* clrStr;
- if (_il2cppStringCache.TryGetValue(index, &clrStr))
- {
- return clrStr;
- }
- else
- {
- Il2CppString* clrStr = _rawImage->GetUserStringBlogByIndex((uint32_t)index);
- #if HYBRIDCLR_UNITY_2022_OR_NEW
- _il2cppStringCache.GetOrAdd(index, clrStr);
- #else
- _il2cppStringCache.Add(index, clrStr);
- #endif
- return clrStr;
- }
- }
- Il2CppClass* Image::GetClassFromToken(Token2RuntimeHandleMap& tokenCache, uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext)
- {
- TokenGenericContextType key = { token, genericContext };
- auto it = tokenCache.find(key);
- if (it != tokenCache.end())
- {
- return (Il2CppClass*)it->second;
- }
- const Il2CppType* originType = ReadTypeFromToken(klassGenericContainer, methodGenericContainer, DecodeTokenTableType(token), DecodeTokenRowIndex(token));
- const Il2CppType* resultType = genericContext != nullptr ? il2cpp::metadata::GenericMetadata::InflateIfNeeded(originType, genericContext, true) : originType;
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(resultType);
- if (!klass)
- {
- TEMP_FORMAT(errMsg, "InterpreterImage::GetClassFromToken token:%u class not exists", token);
- il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetTypeLoadException(errMsg));
- }
- tokenCache.insert({ key, (void*)klass });
- return klass;
- }
- const FieldInfo* Image::GetFieldInfoFromFieldRef(const Il2CppType& type, const Il2CppFieldDefinition* fieldDef)
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(&type);
- const char* name = il2cpp::vm::GlobalMetadata::GetStringFromIndex(fieldDef->nameIndex);
- void* iter = nullptr;
- for (const FieldInfo* cur = nullptr; (cur = il2cpp::vm::Class::GetFields(klass, &iter)) != nullptr; )
- {
- if (cur->token == fieldDef->token)
- {
- IL2CPP_ASSERT(std::strcmp(cur->name, name) == 0);
- return cur;
- }
- }
- RaiseMissingFieldException(&type, name);
- return nullptr;
- }
- const MethodInfo* Image::ResolveMethodInfo(const Il2CppType* type, const char* resolveMethodName, const MethodRefSig& resolveSig, const Il2CppGenericInst* genericInstantiation, const Il2CppGenericContext* genericContext)
- {
- if (type->type != IL2CPP_TYPE_ARRAY)
- {
- const Il2CppTypeDefinition* typeDef = GetUnderlyingTypeDefinition(type);
- const Il2CppGenericContainer* klassGenericContainer = GetGenericContainerFromIl2CppType(type);
- const char* typeName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(typeDef->nameIndex);
- for (uint32_t i = 0; i < typeDef->method_count; i++)
- {
- const Il2CppMethodDefinition* methodDef = il2cpp::vm::GlobalMetadata::GetMethodDefinitionFromIndex(typeDef->methodStart + i);
- const char* methodName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(methodDef->nameIndex);
- IL2CPP_ASSERT((genericInstantiation ? genericInstantiation->type_argc : 0) == resolveSig.genericParamCount);
- if (std::strcmp(resolveMethodName, methodName) == 0 && IsMatchMethodSig(methodDef, resolveSig, klassGenericContainer))
- {
- return GetMethodInfo(type, methodDef, genericInstantiation, genericContext);
- }
- }
- }
- else
- {
- IL2CPP_ASSERT(genericInstantiation == nullptr);
- Il2CppClass* arrayKlass = il2cpp::vm::Class::FromIl2CppType(type);
- il2cpp::vm::Class::SetupMethods(arrayKlass);
- //const Il2CppType* genericClassInstArgv[] = { &arrayKlass->element_class->byval_arg };
- const Il2CppType** genericClassInstArgv = genericContext && genericContext->class_inst ? genericContext->class_inst->type_argv : nullptr;
- const Il2CppType** genericMethodInstArgv = genericContext && genericContext->method_inst ? genericContext->method_inst->type_argv : nullptr;
- // FIXME MEMORY LEAK
- for (uint16_t i = 0; i < arrayKlass->method_count; i++)
- {
- const MethodInfo* method = arrayKlass->methods[i];
- if (std::strcmp(resolveMethodName, method->name) == 0 && IsMatchMethodSig(method, resolveSig, genericClassInstArgv, genericMethodInstArgv))
- {
- return method;
- }
- }
- }
- RaiseMethodNotFindException(type, resolveMethodName);
- return nullptr;
- }
- const void* Image::ReadRuntimeHandleFromMemberRef(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext, uint32_t rowIndex)
- {
- ResolveMemberRef rmr = {};
- ReadResolveMemberRefFromMemberRef(klassGenericContainer, methodGenericContainer, rowIndex, rmr);
- if (rmr.signature.memberType == TableType::FIELD_POINTER)
- {
- const Il2CppFieldDefinition* fieldDef = nullptr;
- ResolveFieldThrow(rmr.parent.type, rmr.name, rmr.signature.field.type, fieldDef);
- if (!fieldDef)
- {
- RaiseMissingFieldException(rmr.parent.type, rmr.name);
- }
- const FieldInfo* fieldInfo = GetFieldInfoFromFieldRef(*rmr.parent.type, fieldDef);
- return fieldInfo;
- }
- else if (rmr.signature.memberType == TableType::METHOD_POINTER)
- {
- if (genericContext)
- {
- rmr.parent.type = TryInflateIfNeed(rmr.parent.type, genericContext, true);
- }
- return ResolveMethodInfo(rmr.parent.type, rmr.name, rmr.signature.method, nullptr, genericContext);
- }
- else
- {
- RaiseExecutionEngineException("GetRuntimeHandleFromToken invaild ParentType");
- return nullptr;
- }
- }
- const void* Image::GetRuntimeHandleFromToken(Token2RuntimeHandleMap& tokenCache, uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext)
- {
- TableType ttype = DecodeTokenTableType(token);
- uint32_t rowIndex = DecodeTokenRowIndex(token);
- const void* handle = nullptr;
- switch (ttype)
- {
- case hybridclr::metadata::TableType::TYPEREF:
- case hybridclr::metadata::TableType::TYPEDEF:
- case hybridclr::metadata::TableType::TYPESPEC:
- {
- const Il2CppType* type = ReadTypeFromToken(klassGenericContainer, methodGenericContainer, ttype, rowIndex);
- if (genericContext)
- {
- type = TryInflateIfNeed(type, genericContext, true);
- }
- handle = type;
- break;
- }
- case hybridclr::metadata::TableType::FIELD:
- {
- handle = GetFieldInfoFromToken(tokenCache, token, klassGenericContainer, methodGenericContainer, genericContext);
- break;
- }
- case hybridclr::metadata::TableType::METHOD:
- case hybridclr::metadata::TableType::METHODSPEC:
- {
- handle = GetMethodInfoFromToken(tokenCache, token, klassGenericContainer, methodGenericContainer, genericContext);
- break;
- }
- case hybridclr::metadata::TableType::MEMBERREF:
- {
- handle = ReadRuntimeHandleFromMemberRef(klassGenericContainer, methodGenericContainer, genericContext, rowIndex);
- //_token2RuntimeHandleCache.insert({ key, (void*)handle });
- break;
- }
- default:
- {
- RaiseExecutionEngineException("GetRuntimeHandleFromToken invaild TableType");
- return nullptr;
- }
- }
- return handle;
- }
- const FieldInfo* Image::GetFieldInfoFromToken(Token2RuntimeHandleMap& tokenCache, uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext)
- {
- TokenGenericContextType key = { token, genericContext };
- auto it = tokenCache.find(key);
- if (it != tokenCache.end())
- {
- return (const FieldInfo*)it->second;
- }
- FieldRefInfo fri;
- ReadFieldRefInfoFromToken(klassGenericContainer, methodGenericContainer, DecodeTokenTableType(token), DecodeTokenRowIndex(token), fri);
- if (!fri.field)
- {
- TEMP_FORMAT(errMsg, "token:%d", token);
- RaiseMissingFieldException(fri.containerType, errMsg);
- }
- const Il2CppType* resultType = genericContext != nullptr ? il2cpp::metadata::GenericMetadata::InflateIfNeeded(fri.containerType, genericContext, true) : fri.containerType;
- const FieldInfo* fieldInfo = GetFieldInfoFromFieldRef(*resultType, fri.field);
- il2cpp::vm::Class::Init(fieldInfo->parent);
- tokenCache.insert({ key, (void*)fieldInfo });
- return fieldInfo;
- }
- const MethodInfo* Image::ReadMethodInfoFromToken(const Il2CppGenericContainer* klassGenericContainer,
- const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext, const Il2CppGenericInst* genericInst, TableType tableType, uint32_t rowIndex)
- {
- IL2CPP_ASSERT(rowIndex > 0);
- switch (tableType)
- {
- case TableType::METHOD:
- {
- const Il2CppMethodDefinition* methodDef = GetMethodDefinitionFromRawIndex(rowIndex - 1);
- const Il2CppTypeDefinition* declareType = (Il2CppTypeDefinition*)il2cpp::vm::GlobalMetadata::GetTypeHandleFromIndex(methodDef->declaringType);
- const Il2CppType* type = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(declareType->byvalTypeIndex);
- return GetMethodInfo(type, methodDef, genericInst, genericContext);
- }
- case TableType::MEMBERREF:
- {
- ResolveMemberRef rmr = {};
- ReadResolveMemberRefFromMemberRef(klassGenericContainer, methodGenericContainer, rowIndex, rmr);
- IL2CPP_ASSERT(rmr.parent.parentType == TableType::TYPEDEF || rmr.parent.parentType == TableType::TYPEREF || rmr.parent.parentType == TableType::TYPESPEC);
- IL2CPP_ASSERT(rmr.signature.memberType == TableType::METHOD_POINTER);
- if (genericContext)
- {
- rmr.parent.type = TryInflateIfNeed(rmr.parent.type, genericContext, true);
- }
- return ResolveMethodInfo(rmr.parent.type, rmr.name, rmr.signature.method, genericInst, genericContext);
- }
- case TableType::METHODSPEC:
- {
- TbMethodSpec methodSpec = _rawImage->ReadMethodSpec(rowIndex);
- const Il2CppGenericInst* genericInstantiation = ReadMethodSpecInstantiation(methodSpec.instantiation, klassGenericContainer, methodGenericContainer);
- genericInstantiation = TryInflateGenericInst(genericInstantiation, genericContext);
- TableType methodTableType = DecodeMethodDefOrRefCodedIndexTableType(methodSpec.method);
- uint32_t methodRowIndex = DecodeMethodDefOrRefCodedIndexRowIndex(methodSpec.method);
- switch (methodTableType)
- {
- case TableType::METHOD:
- {
- return ReadMethodInfoFromToken(klassGenericContainer, methodGenericContainer, genericContext, genericInstantiation, methodTableType, methodRowIndex);
- }
- case TableType::MEMBERREF:
- {
- return ReadMethodInfoFromToken(klassGenericContainer, methodGenericContainer, genericContext, genericInstantiation, methodTableType, methodRowIndex);
- }
- default:
- {
- RaiseBadImageException("ReadMethodSpec invaild TableType");
- return nullptr;
- }
- }
- break;
- }
- default:
- {
- RaiseBadImageException("ReadMethodInfoFromToken invaild TableType");
- return nullptr;
- }
- }
- }
- const MethodInfo* Image::GetMethodInfoFromToken(Token2RuntimeHandleMap& tokenCache, uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext)
- {
- auto key = std::tuple<uint32_t, const Il2CppGenericContext*>(token, genericContext);
- auto it = tokenCache.find(key);
- if (it != tokenCache.end())
- {
- return (const MethodInfo*)it->second;
- }
- const MethodInfo* method = ReadMethodInfoFromToken(klassGenericContainer, methodGenericContainer, genericContext,
- nullptr, DecodeTokenTableType(token), DecodeTokenRowIndex(token));
- IL2CPP_ASSERT(method);
- il2cpp::vm::Class::Init(method->klass);
- tokenCache.insert({ key, (void*)method });
- return method;
- }
- const MethodInfo* Image::GetMethodInfo(const Il2CppType* containerType, const Il2CppMethodDefinition* methodDef, const Il2CppGenericInst* instantiation, const Il2CppGenericContext* genericContext)
- {
- const Il2CppType* finalContainerType = TryInflateIfNeed(containerType, genericContext, true);
- const MethodInfo* method = GetMethodInfoFromMethodDef(containerType, methodDef);
- IL2CPP_ASSERT(method);
- // final genericContext = finalContainerType.class_inst + mri.instantiation
- if (instantiation)
- {
- const Il2CppGenericInst* finalClassIns = finalContainerType->type == IL2CPP_TYPE_GENERICINST ? finalContainerType->data.generic_class->context.class_inst : nullptr;
- const Il2CppGenericInst* finalMethodIns = instantiation;
- Il2CppGenericContext finalGenericContext = { finalClassIns, finalMethodIns };
- method = method->is_inflated ? method->genericMethod->methodDefinition : method;
- method = il2cpp::metadata::GenericMetadata::Inflate(method, &finalGenericContext);
- IL2CPP_ASSERT(method);
- }
- return method;
- }
- void Image::GetStandAloneMethodSigFromToken(uint32_t token, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, const Il2CppGenericContext* genericContext, ResolveStandAloneMethodSig& methodSig)
- {
- TbStandAloneSig sas = _rawImage->ReadStandAloneSig(DecodeTokenRowIndex(token));
- ReadStandAloneSig(sas.signature, klassGenericContainer, methodGenericContainer, methodSig);
- if (genericContext)
- {
- methodSig.returnType = TryInflateIfNeed(methodSig.returnType, genericContext, true);
- for (uint32_t i = 0, n = (uint32_t)methodSig.params.size(); i < n; i++)
- {
- methodSig.params[i] = TryInflateIfNeed(methodSig.params[i], genericContext, true);
- }
- }
- }
- void Image::ReadFieldRefInfoFromToken(const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, TableType tableType, uint32_t rowIndex, FieldRefInfo& ret)
- {
- IL2CPP_ASSERT(rowIndex > 0);
- if (tableType == TableType::FIELD)
- {
- ReadFieldRefInfoFromFieldDefToken(rowIndex, ret);
- }
- else
- {
- IL2CPP_ASSERT(tableType == TableType::MEMBERREF);
- ReadFieldRefInfoFromMemberRef(klassGenericContainer, methodGenericContainer, rowIndex, ret);
- }
- }
- }
- }
|