123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763 |
- #include "MetadataUtil.h"
- #include "vm/GlobalMetadata.h"
- #include "vm/GlobalMetadataFileInternals.h"
- #include "vm/Type.h"
- #include "vm/GlobalMetadata.h"
- #include "vm/Class.h"
- #include "metadata/Il2CppTypeCompare.h"
- #include "metadata/GenericMetadata.h"
- #include "Image.h"
- #include "MetadataPool.h"
- namespace hybridclr
- {
- namespace metadata
- {
- const uint32_t kMetadataImageIndexExtraShiftBitsArr[4] =
- {
- kMetadataImageIndexExtraShiftBitsA,
- kMetadataImageIndexExtraShiftBitsB,
- kMetadataImageIndexExtraShiftBitsC,
- kMetadataImageIndexExtraShiftBitsD,
- };
- const uint32_t kMetadataIndexMaskArr[4] =
- {
- kMetadataIndexMaskA,
- kMetadataIndexMaskB,
- kMetadataIndexMaskC,
- kMetadataIndexMaskD,
- };
- uint32_t GetNotZeroBitCount(uint64_t x)
- {
- uint32_t count = 0;
- for (int i = 0; i < 64; i++)
- {
- if (x & ((uint64_t)1 << i))
- {
- ++count;
- }
- }
- return count;
- }
- int32_t GetTypeValueSize(const Il2CppType* type)
- {
- if (type->byref)
- {
- return PTR_SIZE;
- }
- switch (type->type)
- {
- case IL2CPP_TYPE_BOOLEAN:
- case IL2CPP_TYPE_I1:
- case IL2CPP_TYPE_U1:
- return 1;
- case IL2CPP_TYPE_CHAR:
- case IL2CPP_TYPE_I2:
- case IL2CPP_TYPE_U2:
- return 2;
- case IL2CPP_TYPE_I4:
- case IL2CPP_TYPE_U4:
- case IL2CPP_TYPE_R4:
- return 4;
- case IL2CPP_TYPE_I8:
- case IL2CPP_TYPE_U8:
- case IL2CPP_TYPE_R8:
- return 8;
- case IL2CPP_TYPE_I:
- case IL2CPP_TYPE_U:
- case IL2CPP_TYPE_FNPTR:
- case IL2CPP_TYPE_PTR:
- case IL2CPP_TYPE_BYREF:
- case IL2CPP_TYPE_STRING:
- case IL2CPP_TYPE_ARRAY:
- case IL2CPP_TYPE_SZARRAY:
- case IL2CPP_TYPE_OBJECT:
- return PTR_SIZE;
- case IL2CPP_TYPE_TYPEDBYREF:
- return sizeof(Il2CppTypedRef);
- case IL2CPP_TYPE_CLASS:
- {
- IL2CPP_ASSERT(!IS_CLASS_VALUE_TYPE(il2cpp::vm::Class::FromIl2CppType(type)));
- return PTR_SIZE;
- }
- case IL2CPP_TYPE_VALUETYPE:
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- IL2CPP_ASSERT(IS_CLASS_VALUE_TYPE(klass));
- return il2cpp::vm::Class::GetValueSize(klass, nullptr);
- }
- case IL2CPP_TYPE_GENERICINST:
- {
- Il2CppGenericClass* genericClass = type->data.generic_class;
- if (genericClass->type->type == IL2CPP_TYPE_CLASS)
- {
- IL2CPP_ASSERT(!IS_CLASS_VALUE_TYPE(il2cpp::vm::Class::FromIl2CppType(type)));
- return PTR_SIZE;
- }
- else
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- IL2CPP_ASSERT(IS_CLASS_VALUE_TYPE(klass));
- return il2cpp::vm::Class::GetValueSize(klass, nullptr);
- }
- }
- default:
- {
- TEMP_FORMAT(errMsg, "GetTypeValueSize unknown type:%d", (int)type->type);
- RaiseExecutionEngineException(errMsg);
- return -1;
- }
- }
- }
- bool IsValueType(const Il2CppType* type)
- {
- switch (type->type)
- {
- case IL2CPP_TYPE_BOOLEAN:
- case IL2CPP_TYPE_I1:
- case IL2CPP_TYPE_U1:
- case IL2CPP_TYPE_CHAR:
- case IL2CPP_TYPE_I2:
- case IL2CPP_TYPE_U2:
- case IL2CPP_TYPE_I4:
- case IL2CPP_TYPE_U4:
- case IL2CPP_TYPE_R4:
- case IL2CPP_TYPE_I8:
- case IL2CPP_TYPE_U8:
- case IL2CPP_TYPE_R8:
- case IL2CPP_TYPE_I:
- case IL2CPP_TYPE_U:
- case IL2CPP_TYPE_TYPEDBYREF:
- case IL2CPP_TYPE_VALUETYPE: return true;
- case IL2CPP_TYPE_GENERICINST: return type->data.generic_class->type->type == IL2CPP_TYPE_VALUETYPE;
- default: return false;
- }
- }
- bool IsTypeSameByTypeIndex(TypeIndex t1, TypeIndex t2)
- {
- const Il2CppType* srcParamType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(t1);
- IL2CPP_ASSERT(srcParamType);
- const Il2CppType* dstParamType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(t2);
- IL2CPP_ASSERT(dstParamType);
- return il2cpp::metadata::Il2CppTypeEqualityComparer::AreEqual(srcParamType, dstParamType);
- }
- bool IsTypeEqual(const Il2CppType* t1, const Il2CppType* t2)
- {
- return il2cpp::metadata::Il2CppTypeEqualityComparer::AreEqual(t1, t2);
- }
- bool IsTypeGenericCompatible(const Il2CppType* typeTo, const Il2CppType* typeFrom)
- {
- if (typeTo->type != typeFrom->type)
- {
- return false;
- }
- switch (typeTo->type)
- {
- case IL2CPP_TYPE_VALUETYPE:
- {
- Il2CppClass* klass1 = il2cpp::vm::Class::FromIl2CppType(typeTo);
- Il2CppClass* klass2 = il2cpp::vm::Class::FromIl2CppType(typeFrom);
- return klass1->instance_size == klass2->instance_size;
- }
- case IL2CPP_TYPE_CLASS:
- {
- Il2CppClass* klass1 = il2cpp::vm::Class::FromIl2CppType(typeTo);
- Il2CppClass* klass2 = il2cpp::vm::Class::FromIl2CppType(typeFrom);
- return il2cpp::vm::Class::IsAssignableFrom(klass1, klass2);
- }
- case IL2CPP_TYPE_GENERICINST:
- {
- Il2CppClass* klass1 = il2cpp::vm::Class::FromIl2CppType(typeTo);
- Il2CppClass* klass2 = il2cpp::vm::Class::FromIl2CppType(typeFrom);
- if (IS_CLASS_VALUE_TYPE(klass1) != IS_CLASS_VALUE_TYPE(klass2))
- {
- return false;
- }
- if (IS_CLASS_VALUE_TYPE(klass1))
- {
- return klass1->instance_size == klass2->instance_size;
- }
- else
- {
- return il2cpp::vm::Class::IsAssignableFrom(klass1, klass2);
- }
- break;
- }
- default: return true;
- }
- return true;
- }
- const Il2CppType* TryInflateIfNeed(const Il2CppType* selfType, const Il2CppGenericContext* genericContext, bool inflateMethodVars)
- {
- // FIXME mEMORY LEAK
- return genericContext ? il2cpp::metadata::GenericMetadata::InflateIfNeeded(selfType, genericContext, inflateMethodVars) : selfType;
- }
- const Il2CppType* TryInflateIfNeed(const Il2CppType* containerType, const Il2CppType* selfType)
- {
- if (IsGenericIns(containerType) /* && IsGenericIns(selfType)*/)
- {
- // TOTO memory leak
- return il2cpp::metadata::GenericMetadata::InflateIfNeeded(selfType, &containerType->data.generic_class->context, true);
- }
- else
- {
- return selfType;
- }
- }
- bool IsSameOverrideType(const Il2CppType* t1, const Il2CppType* t2)
- {
- if (t1->type != t2->type)
- {
- return false;
- }
- if (t1->byref != t2->byref)
- {
- return false;
- }
- switch (t1->type)
- {
- case IL2CPP_TYPE_VALUETYPE:
- case IL2CPP_TYPE_CLASS:
- return t1->data.typeHandle == t2->data.typeHandle;
- case IL2CPP_TYPE_PTR:
- case IL2CPP_TYPE_SZARRAY:
- return IsSameOverrideType(t1->data.type, t2->data.type);
- case IL2CPP_TYPE_ARRAY:
- {
- if (t1->data.array->rank < t2->data.array->rank)
- {
- return false;
- }
- return IsSameOverrideType(t1->data.array->etype, t2->data.array->etype);
- }
- case IL2CPP_TYPE_GENERICINST:
- {
- const Il2CppGenericInst* i1 = t1->data.generic_class->context.class_inst;
- const Il2CppGenericInst* i2 = t2->data.generic_class->context.class_inst;
- // this happens when maximum generic recursion is hit
- if (i1 == NULL || i2 == NULL)
- {
- return i1 == i2;
- }
- if (i1->type_argc != i2->type_argc)
- return false;
- if (!IsSameOverrideType(t1->data.generic_class->type, t2->data.generic_class->type))
- return false;
- /* FIXME: we should probably just compare the instance pointers directly. */
- for (uint32_t i = 0; i < i1->type_argc; ++i)
- {
- if (!IsSameOverrideType(i1->type_argv[i], i2->type_argv[i]))
- {
- return false;
- }
- }
- return true;
- }
- case IL2CPP_TYPE_VAR:
- {
- return t1->data.genericParameterHandle == t2->data.genericParameterHandle;
- }
- case IL2CPP_TYPE_MVAR:
- {
- const Il2CppGenericParameter* gp1 = (const Il2CppGenericParameter*)t1->data.genericParameterHandle;
- const Il2CppGenericParameter* gp2 = (const Il2CppGenericParameter*)t2->data.genericParameterHandle;
- return gp1->num == gp2->num;
- }
- default:
- return true;
- }
- RaiseExecutionEngineException("");
- return false;
- }
- static bool IsGenericMethodSameGenericParamCount(const Il2CppMethodDefinition* method1, const Il2CppMethodDefinition* method2)
- {
- if (method1->genericContainerIndex == kGenericContainerIndexInvalid)
- {
- return method2->genericContainerIndex == kGenericContainerIndexInvalid;
- }
- else
- {
- if (method2->genericContainerIndex == kGenericContainerIndexInvalid)
- {
- return false;
- }
- else
- {
- Il2CppGenericContainer* genericContainer1 = (Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(method1->genericContainerIndex);
- Il2CppGenericContainer* genericContainer2 = (Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(method2->genericContainerIndex);
- return genericContainer1->type_argc == genericContainer2->type_argc;
- }
- }
- }
- bool IsOverrideMethodIgnoreName(const Il2CppType* type1, const Il2CppMethodDefinition* methodDef1, const Il2CppType* type2, const Il2CppMethodDefinition* methodDef2)
- {
- if (methodDef1->parameterCount != methodDef2->parameterCount)
- {
- return false;
- }
- if (!IsGenericMethodSameGenericParamCount(methodDef1, methodDef2))
- {
- return false;
- }
- const Il2CppType* returnType1 = TryInflateIfNeed(type1, il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(methodDef1->returnType));
- const Il2CppType* returnType2 = TryInflateIfNeed(type2, il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(methodDef2->returnType));
- if (!IsSameOverrideType(returnType1, returnType2))
- {
- return false;
- }
- for (uint32_t i = 0; i < methodDef1->parameterCount; i++)
- {
- const Il2CppParameterDefinition* srcParam = (const Il2CppParameterDefinition*)il2cpp::vm::GlobalMetadata::GetParameterDefinitionFromIndex(methodDef1, methodDef1->parameterStart + i);
- IL2CPP_ASSERT(srcParam);
- const Il2CppParameterDefinition* dstParam = (const Il2CppParameterDefinition*)il2cpp::vm::GlobalMetadata::GetParameterDefinitionFromIndex(methodDef2, methodDef2->parameterStart + i);
- IL2CPP_ASSERT(dstParam);
- const Il2CppType* paramType1 = TryInflateIfNeed(type1, il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(srcParam->typeIndex));
- const Il2CppType* paramType2 = TryInflateIfNeed(type2, il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(dstParam->typeIndex));
- if (!IsSameOverrideType(paramType1, paramType2))
- {
- return false;
- }
- }
- return true;
- }
- bool IsOverrideMethod(const Il2CppType* type1, const Il2CppMethodDefinition* methodDef1, const Il2CppType* type2, const Il2CppMethodDefinition* methodDef2)
- {
- const char* name1 = il2cpp::vm::GlobalMetadata::GetStringFromIndex(methodDef1->nameIndex);
- const char* name2 = il2cpp::vm::GlobalMetadata::GetStringFromIndex(methodDef2->nameIndex);
- if (std::strcmp(name1, name2))
- {
- return false;
- }
- return IsOverrideMethodIgnoreName(type1, methodDef1, type2, methodDef2);
- }
- bool IsMatchSigType(const Il2CppType* dstType, const Il2CppType* sigType, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer)
- {
- if (dstType->type != sigType->type)
- {
- return false;
- }
- if (dstType->byref != sigType->byref)
- {
- return false;
- }
- switch (dstType->type)
- {
- case IL2CPP_TYPE_VALUETYPE:
- case IL2CPP_TYPE_CLASS:
- return dstType->data.typeHandle == sigType->data.typeHandle;
- case IL2CPP_TYPE_PTR:
- case IL2CPP_TYPE_SZARRAY:
- return IsMatchSigType(dstType->data.type, sigType->data.type, klassGenericContainer, methodGenericContainer);
- case IL2CPP_TYPE_ARRAY:
- {
- if (dstType->data.array->rank < sigType->data.array->rank)
- {
- return false;
- }
- return IsMatchSigType(dstType->data.array->etype, sigType->data.array->etype, klassGenericContainer, methodGenericContainer);
- }
- case IL2CPP_TYPE_GENERICINST:
- {
- const Il2CppGenericInst* i1 = dstType->data.generic_class->context.class_inst;
- const Il2CppGenericInst* i2 = sigType->data.generic_class->context.class_inst;
- // this happens when maximum generic recursion is hit
- if (i1 == NULL || i2 == NULL)
- {
- return i1 == i2;
- }
- if (i1->type_argc != i2->type_argc)
- return false;
- if (!IsMatchSigType(dstType->data.generic_class->type, sigType->data.generic_class->type, klassGenericContainer, methodGenericContainer))
- return false;
- /* FIXME: we should probably just compare the instance pointers directly. */
- for (uint32_t i = 0; i < i1->type_argc; ++i)
- {
- if (!IsMatchSigType(i1->type_argv[i], i2->type_argv[i], klassGenericContainer, methodGenericContainer))
- {
- return false;
- }
- }
- return true;
- }
- case IL2CPP_TYPE_VAR:
- {
- if ((int32_t)sigType->data.__genericParameterIndex >= klassGenericContainer->type_argc)
- {
- return false;
- }
- Il2CppMetadataGenericParameterHandle sigGph = il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex(
- (Il2CppMetadataGenericContainerHandle)klassGenericContainer, sigType->data.__genericParameterIndex);
- return dstType->data.genericParameterHandle == sigGph;
- }
- case IL2CPP_TYPE_MVAR:
- {
- if ((int32_t)sigType->data.__genericParameterIndex >= methodGenericContainer->type_argc)
- {
- return false;
- }
- Il2CppMetadataGenericParameterHandle sigGph = il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex(
- (Il2CppMetadataGenericContainerHandle)methodGenericContainer, sigType->data.__genericParameterIndex);
- return dstType->data.genericParameterHandle == sigGph;
- }
- default:
- return true;
- }
- RaiseExecutionEngineException("");
- return false;
- }
- bool IsMatchSigType(const Il2CppType* dstType, const Il2CppType* sigType, const Il2CppType** klassInstArgv, const Il2CppType** methodInstArgv)
- {
- if (dstType->byref != sigType->byref)
- {
- return false;
- }
- if (sigType->type == IL2CPP_TYPE_VAR)
- {
- sigType = klassInstArgv[sigType->data.__genericParameterIndex];
- }
- else if (sigType->type == IL2CPP_TYPE_MVAR)
- {
- sigType = methodInstArgv[sigType->data.__genericParameterIndex];
- }
- if (dstType->type != sigType->type)
- {
- return false;
- }
- switch (sigType->type)
- {
- case IL2CPP_TYPE_VALUETYPE:
- case IL2CPP_TYPE_CLASS:
- return dstType->data.typeHandle == sigType->data.typeHandle;
- case IL2CPP_TYPE_PTR:
- case IL2CPP_TYPE_SZARRAY:
- return IsMatchSigType(dstType->data.type, sigType->data.type, klassInstArgv, methodInstArgv);
- case IL2CPP_TYPE_ARRAY:
- {
- if (dstType->data.array->rank < sigType->data.array->rank)
- {
- return false;
- }
- return IsMatchSigType(dstType->data.array->etype, sigType->data.array->etype, klassInstArgv, methodInstArgv);
- }
- case IL2CPP_TYPE_GENERICINST:
- {
- const Il2CppGenericInst* i1 = dstType->data.generic_class->context.class_inst;
- const Il2CppGenericInst* i2 = sigType->data.generic_class->context.class_inst;
- // this happens when maximum generic recursion is hit
- if (i1 == NULL || i2 == NULL)
- {
- return i1 == i2;
- }
- if (i1->type_argc != i2->type_argc)
- return false;
- if (!IsMatchSigType(dstType->data.generic_class->type, sigType->data.generic_class->type, klassInstArgv, methodInstArgv))
- return false;
- /* FIXME: we should probably just compare the instance pointers directly. */
- for (uint32_t i = 0; i < i1->type_argc; ++i)
- {
- if (!IsMatchSigType(i1->type_argv[i], i2->type_argv[i], klassInstArgv, methodInstArgv))
- {
- return false;
- }
- }
- return true;
- }
- case IL2CPP_TYPE_VAR:
- {
- /*Il2CppMetadataGenericParameterHandle sigGph = il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex(
- (Il2CppMetadataGenericContainerHandle)klassGenericContainer, sigType->data.__genericParameterIndex);
- return dstType->data.genericParameterHandle == sigType->data.__genericParameterIndex;*/
- RaiseNotSupportedException("");
- break;
- }
- case IL2CPP_TYPE_MVAR:
- {
- /*Il2CppMetadataGenericParameterHandle sigGph = il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex(
- (Il2CppMetadataGenericContainerHandle)methodGenericContainer, sigType->data.__genericParameterIndex);
- return dstType->data.genericParameterHandle == sigGph;*/
- RaiseNotSupportedException("");
- break;
- }
- default: return true;
- }
- RaiseExecutionEngineException("");
- return false;
- }
- bool IsMatchMethodSig(const Il2CppMethodDefinition* methodDef, const MethodRefSig& resolveSig, const Il2CppGenericContainer* klassGenericContainer)
- {
- if (methodDef->parameterCount != (uint16_t)resolveSig.params.size())
- {
- return false;
- }
- Il2CppGenericContainer* methodGenericContainer = nullptr;
- // if generic param not match. return false
- if (methodDef->genericContainerIndex == kGenericContainerIndexInvalid)
- {
- if (resolveSig.genericParamCount)
- {
- return false;
- }
- }
- else
- {
- methodGenericContainer = (Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(methodDef->genericContainerIndex);
- if (resolveSig.genericParamCount != methodGenericContainer->type_argc)
- {
- return false;
- }
- }
- const Il2CppType* returnType1 = resolveSig.returnType;
- const Il2CppType* returnType2 = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(methodDef->returnType);
- if (!IsMatchSigType(returnType2, returnType1, klassGenericContainer, methodGenericContainer))
- {
- return false;
- }
- for (uint32_t i = 0; i < methodDef->parameterCount; i++)
- {
- const Il2CppType* paramType1 = resolveSig.params[i];
- const Il2CppParameterDefinition* dstParam = (const Il2CppParameterDefinition*)il2cpp::vm::GlobalMetadata::GetParameterDefinitionFromIndex(methodDef, methodDef->parameterStart + i);
- IL2CPP_ASSERT(dstParam);
- const Il2CppType* paramType2 = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(dstParam->typeIndex);
- if (!IsMatchSigType(paramType2, paramType1, klassGenericContainer, methodGenericContainer))
- {
- return false;
- }
- }
- return true;
- }
- bool IsMatchMethodSig(const MethodInfo* methodDef, const MethodRefSig& resolveSig, const Il2CppGenericContainer* klassGenericContainer)
- {
- if (methodDef->parameters_count != (uint16_t)resolveSig.params.size())
- {
- return false;
- }
- const Il2CppGenericContainer* methodGenericContainer = GetGenericContainer(methodDef);
- if (methodGenericContainer)
- {
- if (methodGenericContainer->type_argc != resolveSig.genericParamCount)
- {
- return false;
- }
- }
- else
- {
- if (resolveSig.genericParamCount)
- {
- return false;
- }
- }
- const Il2CppType* returnType1 = resolveSig.returnType;
- const Il2CppType* returnType2 = methodDef->return_type;
- if (!IsMatchSigType(returnType2, returnType1, klassGenericContainer, methodGenericContainer))
- {
- return false;
- }
- for (uint32_t i = 0; i < methodDef->parameters_count; i++)
- {
- const Il2CppType* paramType1 = resolveSig.params[i];
- const Il2CppType* paramType2 = GET_METHOD_PARAMETER_TYPE(methodDef->parameters[i]);
- if (!IsMatchSigType(paramType2, paramType1, klassGenericContainer, methodGenericContainer))
- {
- return false;
- }
- }
- return true;
- }
- bool IsMatchMethodSig(const MethodInfo* methodDef, const MethodRefSig& resolveSig, const Il2CppType** klassInstArgv, const Il2CppType** methodInstArgv)
- {
- if (methodDef->parameters_count != (uint16_t)resolveSig.params.size())
- {
- return false;
- }
- const Il2CppGenericContainer* methodGenericContainer = GetGenericContainer(methodDef);
- if (methodGenericContainer)
- {
- if (methodGenericContainer->type_argc != resolveSig.genericParamCount)
- {
- return false;
- }
- }
- else
- {
- if (resolveSig.genericParamCount)
- {
- return false;
- }
- }
- const Il2CppType* returnType1 = resolveSig.returnType;
- const Il2CppType* returnType2 = methodDef->return_type;
- if (!IsMatchSigType(returnType2, returnType1, klassInstArgv, methodInstArgv))
- {
- return false;
- }
- for (uint32_t i = 0; i < methodDef->parameters_count; i++)
- {
- const Il2CppType* paramType1 = resolveSig.params[i];
- const Il2CppType* paramType2 = GET_METHOD_PARAMETER_TYPE(methodDef->parameters[i]);
- if (!IsMatchSigType(paramType2, paramType1, klassInstArgv, methodInstArgv))
- {
- return false;
- }
- }
- return true;
- }
- const Il2CppMethodDefinition* ResolveMethodDefinition(const Il2CppType* type, const char* resolveMethodName, const MethodRefSig& resolveSig)
- {
- 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);
- if (std::strcmp(resolveMethodName, methodName) == 0 && IsMatchMethodSig(methodDef, resolveSig, klassGenericContainer))
- {
- return methodDef;
- }
- }
- RaiseMethodNotFindException(type, resolveMethodName);
- return nullptr;
- }
- const MethodInfo* GetMethodInfoFromMethodDef(const Il2CppType* type, const Il2CppMethodDefinition* methodDef)
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- il2cpp::vm::Class::SetupMethods(klass);
- void* iter = nullptr;
- for (const MethodInfo* cur = nullptr; (cur = il2cpp::vm::Class::GetMethods(klass, &iter)) != nullptr; )
- {
- if (!cur->is_inflated)
- {
- if ((const Il2CppMethodDefinition*)cur->methodMetadataHandle == methodDef)
- {
- return cur;
- }
- }
- else
- {
- if ((const Il2CppMethodDefinition*)cur->genericMethod->methodDefinition->methodMetadataHandle == methodDef)
- {
- return cur;
- }
- }
- }
- RaiseMethodNotFindException(type, il2cpp::vm::GlobalMetadata::GetStringFromIndex(methodDef->nameIndex));
- return nullptr;
- }
- bool ResolveField(const Il2CppType* type, const char* resolveFieldName, const Il2CppType* resolveFieldType, const Il2CppFieldDefinition*& retFieldDef)
- {
- const Il2CppTypeDefinition* typeDef = GetUnderlyingTypeDefinition(type);
- const Il2CppGenericContainer* klassGenericContainer = GetGenericContainerFromIl2CppType(type);
- for (uint16_t i = 0; i < typeDef->field_count; i++)
- {
- const Il2CppFieldDefinition* fieldDef = il2cpp::vm::GlobalMetadata::GetFieldDefinitionFromTypeDefAndFieldIndex(typeDef, i);
- const char* fieldName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(fieldDef->nameIndex);
- const Il2CppType* fieldType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(fieldDef->typeIndex);
- if (std::strcmp(resolveFieldName, fieldName) == 0 && IsMatchSigType(fieldType, resolveFieldType, klassGenericContainer, nullptr))
- {
- retFieldDef = fieldDef;
- return true;
- }
- }
- retFieldDef = nullptr;
- return false;
- }
- const Il2CppGenericContainer* GetGenericContainerFromIl2CppType(const Il2CppType* type)
- {
- switch (type->type)
- {
- case IL2CPP_TYPE_GENERICINST:
- {
- return (Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromGenericClass(type->data.generic_class);
- }
- case IL2CPP_TYPE_VALUETYPE:
- case IL2CPP_TYPE_CLASS:
- {
- return (Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(((Il2CppTypeDefinition*)type->data.typeHandle)->genericContainerIndex);
- }
- default:
- {
- return nullptr;
- }
- }
- }
- const Il2CppGenericInst* TryInflateGenericInst(const Il2CppGenericInst* inst, const Il2CppGenericContext* genericContext)
- {
- IL2CPP_ASSERT(inst->type_argc > 0);
- const Il2CppType** argv = (const Il2CppType**)alloca(sizeof(Il2CppType*) * inst->type_argc);
- for (uint32_t i = 0; i < inst->type_argc; i++)
- {
- argv[i] = TryInflateIfNeed(inst->type_argv[i], genericContext, true);
- }
- return il2cpp::vm::MetadataCache::GetGenericInst(argv, inst->type_argc);
- }
- const Il2CppType* GetIl2CppTypeFromTypeDefinition(const Il2CppTypeDefinition* typeDef)
- {
- Il2CppType type = {};
- bool isValueType = IsValueType(typeDef);
- type.type = isValueType ? IL2CPP_TYPE_VALUETYPE : IL2CPP_TYPE_CLASS;
- type.data.typeHandle = (Il2CppMetadataTypeHandle)typeDef;
- SET_IL2CPPTYPE_VALUE_TYPE(type, isValueType);
- return MetadataPool::GetPooledIl2CppType(type);
- }
- }
- }
|