12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609 |
- #include "InterpreterImage.h"
- #include <cstring>
- #include <cmath>
- #include <iostream>
- #include <algorithm>
- #include "il2cpp-class-internals.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/MetadataLock.h"
- #include "vm/MetadataCache.h"
- #include "vm/MetadataAlloc.h"
- #include "vm/String.h"
- #include "vm/Reflection.h"
- #include "metadata/FieldLayout.h"
- #include "metadata/Il2CppTypeCompare.h"
- #include "metadata/GenericMetadata.h"
- #if HYBRIDCLR_UNITY_2021_OR_NEW
- #include "metadata/CustomAttributeCreator.h"
- #endif
- #include "os/Atomic.h"
- #include "icalls/mscorlib/System/MonoCustomAttrs.h"
- #include "MetadataModule.h"
- #include "MetadataUtil.h"
- #include "ClassFieldLayoutCalculator.h"
- #include "MetadataPool.h"
- #include "../interpreter/Engine.h"
- #include "../interpreter/InterpreterModule.h"
- namespace hybridclr
- {
- namespace metadata
- {
- static uint32_t s_nextImageIndexByKind[4] = { (1u << kMetadataImageIndexExtraShiftBitsA), 0, 0, 0};
- InterpreterImage* InterpreterImage::s_images[kMaxMetadataImageCount] = {};
- static int32_t GetImageKindByDllLength(uint32_t dllLength)
- {
- uint32_t maxPossibleIndexValue = dllLength * 4;
- for (int32_t i = 3; i >= 0; i--)
- {
- if (maxPossibleIndexValue <= kMetadataIndexMaskArr[i])
- {
- return i;
- }
- }
- return -1;
- }
- void InterpreterImage::Initialize()
- {
-
- }
- uint32_t InterpreterImage::AllocImageIndex(uint32_t dllLength)
- {
- int32_t kind = GetImageKindByDllLength(dllLength);
- if (kind < 0)
- {
- return kInvalidImageIndex;
- }
- for (int32_t finalKind = kind; finalKind >= 0; finalKind--)
- {
- uint32_t newImageIndex = s_nextImageIndexByKind[finalKind];
- // 255 is preserved for invalid image index when kind is 3
- if (newImageIndex >= kMaxMetadataImageIndexWithoutKind - (finalKind == 3))
- {
- continue;
- }
- s_nextImageIndexByKind[finalKind] += (1u << kMetadataImageIndexExtraShiftBitsArr[finalKind]);
- return newImageIndex | ((uint32_t)finalKind << (kMetadataImageIndexBits - kMetadataKindBits));
- }
- return kInvalidImageIndex;
- }
- void InterpreterImage::RegisterImage(InterpreterImage* image)
- {
- il2cpp::os::Atomic::FullMemoryBarrier();
- IL2CPP_ASSERT(image->GetIndex() > 0);
- s_images[image->GetIndex()] = image;
- }
- void InterpreterImage::InitBasic(Il2CppImage* image)
- {
- SetIl2CppImage(image);
- RegisterImage(this);
- }
- void InterpreterImage::BuildIl2CppAssembly(Il2CppAssembly* ass)
- {
- ass->token = EncodeToken(TableType::ASSEMBLY, 1);
- ass->referencedAssemblyStart = EncodeWithIndex(1);
- ass->referencedAssemblyCount = _rawImage->GetTableRowNum(TableType::ASSEMBLYREF);
- TbAssembly data = _rawImage->ReadAssembly(1);
- auto& aname = ass->aname;
- aname.hash_alg = data.hashAlgId;
- aname.major = data.majorVersion;
- aname.minor = data.minorVersion;
- aname.build = data.buildNumber;
- aname.revision = data.revisionNumber;
- aname.flags = data.flags;
- aname.public_key = _rawImage->GetBlobFromRawIndex(data.publicKey);
- aname.name = _rawImage->GetStringFromRawIndex(data.name);
- aname.culture = _rawImage->GetStringFromRawIndex(data.culture);
- }
- void InterpreterImage::BuildIl2CppImage(Il2CppImage* image2)
- {
- image2->typeCount = _rawImage->GetTableRowNum(TableType::TYPEDEF);
- image2->exportedTypeCount = _rawImage->GetTableRowNum(TableType::EXPORTEDTYPE);
- image2->customAttributeCount = _rawImage->GetTableRowNum(TableType::CUSTOMATTRIBUTE);
- #if HYBRIDCLR_UNITY_2019
- image2->typeStart = EncodeWithIndex(0);
- image2->customAttributeStart = EncodeWithIndex(0);
- image2->entryPointIndex = EncodeWithIndexExcept0(_rawImage->GetEntryPointToken());
- image2->exportedTypeStart = EncodeWithIndex(0);
- #else
- Il2CppImageGlobalMetadata* metadataImage = (Il2CppImageGlobalMetadata*)HYBRIDCLR_METADATA_MALLOC(sizeof(Il2CppImageGlobalMetadata));
- metadataImage->typeStart = EncodeWithIndex(0);
- metadataImage->customAttributeStart = EncodeWithIndex(0);
- metadataImage->entryPointIndex = EncodeWithIndexExcept0(_rawImage->GetEntryPointToken());
- metadataImage->exportedTypeStart = EncodeWithIndex(0);
- metadataImage->image = image2;
- image2->metadataHandle = reinterpret_cast<Il2CppMetadataImageHandle>(metadataImage);
- #endif
- image2->nameToClassHashTable = nullptr;
- image2->codeGenModule = nullptr;
- image2->token = EncodeWithIndex(0); // TODO
- image2->dynamic = 0;
- }
- void InterpreterImage::InitRuntimeMetadatas()
- {
- IL2CPP_ASSERT(_rawImage->GetTable(TableType::EXPORTEDTYPE).rowNum == 0);
- InitGenericParamDefs0();
- InitTypeDefs_0();
- InitMethodDefs0();
- InitGenericParamDefs();
- InitNestedClass(); // must before typedefs1, because parent may be nested class
- InitTypeDefs_1();
- InitGenericParamConstraintDefs();
- InitParamDefs();
- InitMethodDefs();
- InitFieldDefs();
- InitFieldLayouts();
- InitFieldRVAs();
- InitBlittables();
- InitMethodImpls0();
- InitProperties();
- InitEvents();
- InitMethodSemantics();
- InitConsts();
- InitCustomAttributes();
- InitTypeDefs_2();
- InitClassLayouts();
- InitInterfaces();
- InitClass();
- InitVTables();
- Il2CppHashMap<const Il2CppType*, uint32_t, Il2CppTypeHashShallow, Il2CppTypeEqualityComparerShallow> temp;
- _type2Indexs.swap(temp);
- delete _paramRawIndex2ActualParamIndex;
- _paramRawIndex2ActualParamIndex = nullptr;
- }
- void InterpreterImage::InitTypeDefs_0()
- {
- const Table& typeDefTb = _rawImage->GetTable(TableType::TYPEDEF);
- _typesDefines.resize(typeDefTb.rowNum);
- _typeDetails.resize(typeDefTb.rowNum);
- for (uint32_t i = 0, n = typeDefTb.rowNum; i < n; i++)
- {
- Il2CppTypeDefinition& cur = _typesDefines[i];
- TypeDefinitionDetail& typeDetail = _typeDetails[i];
- typeDetail.typeSizes = {};
- uint32_t rowIndex = i + 1;
- TbTypeDef data = _rawImage->ReadTypeDef(rowIndex);
- cur = {};
- cur.genericContainerIndex = kGenericContainerIndexInvalid;
- cur.declaringTypeIndex = kTypeDefinitionIndexInvalid;
- cur.elementTypeIndex = kTypeDefinitionIndexInvalid;
- cur.token = EncodeToken(TableType::TYPEDEF, rowIndex);
- bool isValueType = data.extends && IsValueTypeFromToken(DecodeTypeDefOrRefOrSpecCodedIndexTableType(data.extends), DecodeTypeDefOrRefOrSpecCodedIndexRowIndex(data.extends));
- Il2CppType* cppType = MetadataMallocT<Il2CppType>();
- cppType->type = isValueType ? IL2CPP_TYPE_VALUETYPE : IL2CPP_TYPE_CLASS;
- SET_IL2CPPTYPE_VALUE_TYPE(*cppType, isValueType);
- cppType->data.typeHandle = (Il2CppMetadataTypeHandle)&cur;
- cur.byvalTypeIndex = AddIl2CppTypeCache(cppType);
- #if HYBRIDCLR_UNITY_2019
- Il2CppType* byRefType = MetadataMallocT<Il2CppType>();
- *byRefType = *cppType;
- byRefType->byref = 1;
- cur.byrefTypeIndex = AddIl2CppTypeCache(byRefType);
- #endif
- if (IsInterface(cur.flags))
- {
- cur.interfaceOffsetsStart = EncodeWithIndex(0);
- cur.interface_offsets_count = 0;
- cur.vtableStart = EncodeWithIndex(0);
- cur.vtable_count = 0;
- }
- else
- {
- cur.interfaceOffsetsStart = 0;
- cur.interface_offsets_count = 0;
- cur.vtableStart = 0;
- cur.vtable_count = 0;
- }
- }
- }
- void InterpreterImage::InitTypeDefs_1()
- {
- const Table& typeDefTb = _rawImage->GetTable(TableType::TYPEDEF);
- for (uint32_t i = 0, n = typeDefTb.rowNum; i < n; i++)
- {
- Il2CppTypeDefinition& last = _typesDefines[i > 0 ? i - 1 : 0];
- Il2CppTypeDefinition& cur = _typesDefines[i];
- uint32_t rowIndex = i + 1;
- TbTypeDef data = _rawImage->ReadTypeDef(rowIndex); // token from 1
- cur.flags = data.flags;
- cur.nameIndex = EncodeWithIndex(data.typeName);
- cur.namespaceIndex = EncodeWithIndex(data.typeNamespace);
- cur.fieldStart = EncodeWithIndex(data.fieldList - 1);
- cur.methodStart = EncodeWithIndex(data.methodList - 1);
- if (i > 0)
- {
- last.field_count = (uint16_t)(cur.fieldStart - last.fieldStart);
- last.method_count = (uint16_t)(cur.methodStart - last.methodStart);
- }
- if (i == n - 1)
- {
- cur.field_count = (uint16_t)(_rawImage->GetTableRowNum(TableType::FIELD) - DecodeMetadataIndex(cur.fieldStart));
- cur.method_count = (uint16_t)(_rawImage->GetTableRowNum(TableType::METHOD) - DecodeMetadataIndex(cur.methodStart));
- }
- if (data.extends != 0)
- {
- const Il2CppType* parentType = ReadTypeFromToken(GetGenericContainerByTypeDefinition(&cur), nullptr, DecodeTypeDefOrRefOrSpecCodedIndexTableType(data.extends), DecodeTypeDefOrRefOrSpecCodedIndexRowIndex(data.extends));
- if (parentType->type == IL2CPP_TYPE_CLASS || parentType->type == IL2CPP_TYPE_VALUETYPE)
- {
- Il2CppTypeDefinition* parentDef = (Il2CppTypeDefinition*)parentType->data.typeHandle;
- // FIXE ME . check mscorelib
- const char* parentNs = il2cpp::vm::GlobalMetadata::GetStringFromIndex(parentDef->namespaceIndex);
- if (std::strcmp(parentNs, "System") == 0)
- {
- const char* parentName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(parentDef->nameIndex);
- if (std::strcmp(parentName, "Enum") == 0)
- {
- cur.bitfield |= (1 << (il2cpp::vm::kBitIsValueType - 1));
- cur.bitfield |= (1 << (il2cpp::vm::kBitIsEnum - 1));
- }
- else if (std::strcmp(parentName, "ValueType") == 0)
- {
- cur.bitfield |= (1 << (il2cpp::vm::kBitIsValueType - 1));
- }
- }
- }
- cur.parentIndex = AddIl2CppTypeCache(parentType);
- }
- else
- {
- cur.parentIndex = kInvalidIndex;
- }
- cur.elementTypeIndex = kInvalidIndex;
- }
- }
- void InterpreterImage::InitTypeDefs_2()
- {
- const Table& typeDefTb = _rawImage->GetTable(TableType::TYPEDEF);
- for (uint32_t i = 0, n = typeDefTb.rowNum; i < n; i++)
- {
- TbTypeDef data = _rawImage->ReadTypeDef(i + 1); // token from 1
- Il2CppTypeDefinition& last = _typesDefines[i > 0 ? i - 1 : 0];
- Il2CppTypeDefinition& cur = _typesDefines[i];
- uint32_t typeIndex = i; // type index start from 0, diff with field index ...
- // enum element_type ==
- if (IsEnumType(&cur))
- {
- cur.elementTypeIndex = _fieldDetails[DecodeMetadataIndex(cur.fieldStart)].fieldDef.typeIndex;
- }
- auto classLayoutRow = _classLayouts.find(typeIndex);
- uint16_t packingSize = 0;
- if (classLayoutRow != _classLayouts.end())
- {
- auto& layoutData = classLayoutRow->second;
- packingSize = layoutData.packingSize;
- }
- else
- {
- cur.bitfield |= (1 << (il2cpp::vm::kClassSizeIsDefault - 1));
- }
- if (packingSize != 0)
- {
- cur.bitfield |= ((uint32_t)il2cpp::vm::GlobalMetadata::ConvertPackingSizeToEnum((uint8_t)packingSize) << (il2cpp::vm::kPackingSize - 1));
- }
- else
- {
- cur.bitfield |= (1 << (il2cpp::vm::kPackingSizeIsDefault - 1));
- }
- }
- }
- void InterpreterImage::InitParamDefs()
- {
- const Table& tb = _rawImage->GetTable(TableType::PARAM);
- // extra 16 for not name params
- _params.reserve(tb.rowNum + 16);
- _paramRawIndex2ActualParamIndex = new std::vector<TypeIndex>(tb.rowNum);
- //for (uint32_t i = 0; i < tb.rowNum; i++)
- //{
- // uint32_t rowIndex = i + 1;
- // Il2CppParameterDefinition& pd = _params[i].paramDef;
- // TbParam data = _rawImage->ReadParam(rowIndex);
- // pd.nameIndex = EncodeWithIndex(data.name);
- // pd.token = EncodeToken(TableType::PARAM, rowIndex);
- // // pd.typeIndex 在InitMethodDefs中解析signature后填充。
- //}
- }
- void InterpreterImage::InitFieldDefs()
- {
- const Table& fieldTb = _rawImage->GetTable(TableType::FIELD);
- _fieldDetails.resize(fieldTb.rowNum);
- for (size_t i = 0; i < _typesDefines.size(); i++)
- {
- Il2CppTypeDefinition& typeDef = _typesDefines[i];
- uint32_t start = DecodeMetadataIndex(typeDef.fieldStart);
- for (uint32_t k = 0; k < typeDef.field_count; k++)
- {
- FieldDetail& fd = _fieldDetails[start + k];
- fd.typeDefIndex = (uint32_t)i;
- }
- }
- for (uint32_t i = 0, n = fieldTb.rowNum; i < n; i++)
- {
- FieldDetail& fd = _fieldDetails[i];
- Il2CppFieldDefinition& cur = fd.fieldDef;
- fd.offset = 0;
- fd.defaultValueIndex = kDefaultValueIndexNull;
- uint32_t rowIndex = i + 1;
- TbField data = _rawImage->ReadField(rowIndex);
- BlobReader br = _rawImage->GetBlobReaderByRawIndex(data.signature);
- FieldRefSig frs;
- ReadFieldRefSig(br, GetGenericContainerByTypeDefRawIndex(DecodeMetadataIndex(fd.typeDefIndex)), frs);
- if (data.flags != 0)
- {
- Il2CppType typeWithAttrs = *frs.type;
- typeWithAttrs.attrs = data.flags;
- frs.type = MetadataPool::GetPooledIl2CppType(typeWithAttrs);
- }
- //cur = {};
- cur.nameIndex = EncodeWithIndex(data.name);
- cur.token = EncodeToken(TableType::FIELD, rowIndex);
- cur.typeIndex = AddIl2CppTypeCache(frs.type);
- }
- }
- void InterpreterImage::InitFieldLayouts()
- {
- const Table& tb = _rawImage->GetTable(TableType::FIELDLAYOUT);
- for (uint32_t i = 0; i < tb.rowNum; i++)
- {
- TbFieldLayout data = _rawImage->ReadFieldLayout(i + 1);
- _fieldDetails[data.field - 1].offset = sizeof(Il2CppObject) + data.offset;
- }
- }
- void InterpreterImage::InitFieldRVAs()
- {
- const Table& tb = _rawImage->GetTable(TableType::FIELDRVA);
- for (uint32_t i = 0; i < tb.rowNum; i++)
- {
- TbFieldRVA data = _rawImage->ReadFieldRVA(i + 1);
- FieldDetail& fd = _fieldDetails[data.field - 1];
- fd.defaultValueIndex = (uint32_t)_fieldDefaultValues.size();
- Il2CppFieldDefaultValue fdv = {};
- fdv.fieldIndex = data.field - 1;
- fdv.typeIndex = fd.fieldDef.typeIndex;
- uint32_t dataImageOffset = (uint32_t)-1;
- bool ret = _rawImage->TranslateRVAToImageOffset(data.rva, dataImageOffset);
- IL2CPP_ASSERT(ret);
- #if HYBRIDCLR_UNITY_2021_OR_NEW
- fdv.dataIndex = (DefaultValueDataIndex)EncodeWithIndex(EncodeWithBlobSource(dataImageOffset, BlobSource::RAW_IMAGE));
- #else
- fdv.dataIndex = (DefaultValueDataIndex)EncodeWithIndex(dataImageOffset);
- #endif
- _fieldDefaultValues.push_back(fdv);
- }
- }
- void InterpreterImage::InitBlittables()
- {
- const Table& typeDefTb = _rawImage->GetTable(TableType::TYPEDEF);
- std::vector<bool> computFlags(typeDefTb.rowNum, false);
- for (uint32_t i = 0, n = typeDefTb.rowNum; i < n; i++)
- {
- ComputeBlittable(&_typesDefines[i], computFlags);
- }
- }
- void InterpreterImage::ComputeBlittable(Il2CppTypeDefinition* def, std::vector<bool>& computFlags)
- {
- if (DecodeImageIndex(def->byvalTypeIndex) != GetIndex())
- {
- return;
- }
- uint32_t typeIndex = GetTypeRawIndex(def);
- if (computFlags[typeIndex])
- {
- return;
- }
- computFlags[typeIndex] = true;
- const Il2CppType* type = GetIl2CppTypeFromRawIndex(DecodeMetadataIndex(def->byvalTypeIndex));
- const char* typeName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(def->nameIndex);
- bool blittable = false;
- if (type->type == IL2CPP_TYPE_VALUETYPE)
- {
- blittable = true;
- for (int i = 0; i < def->field_count; i++)
- {
- const Il2CppFieldDefinition* field = GetFieldDefinitionFromRawIndex(DecodeMetadataIndex(def->fieldStart + i));
- const Il2CppType* fieldType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(field->typeIndex);
- if (!hybridclr::metadata::IsInstanceField(fieldType))
- {
- continue;
- }
- switch (fieldType->type)
- {
- 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_I:
- case IL2CPP_TYPE_U:
- case IL2CPP_TYPE_I8:
- case IL2CPP_TYPE_U8:
- case IL2CPP_TYPE_R4:
- case IL2CPP_TYPE_R8:
- case IL2CPP_TYPE_PTR:
- case IL2CPP_TYPE_FNPTR:
- {
- break;
- }
- case IL2CPP_TYPE_VALUETYPE:
- {
- Il2CppTypeDefinition* fieldDef = (Il2CppTypeDefinition*)fieldType->data.typeHandle;
- ComputeBlittable(fieldDef, computFlags);
- blittable = fieldDef->bitfield & (1 << (il2cpp::vm::kBitIsBlittable - 1));
- break;
- }
- default:
- {
- blittable = false;
- }
- }
- if (!blittable)
- {
- break;
- }
- }
- }
- if (blittable)
- {
- def->bitfield |= (1 << (il2cpp::vm::kBitIsBlittable - 1));
- }
- }
- #if HYBRIDCLR_UNITY_2021_OR_NEW
- DefaultValueDataIndex InterpreterImage::ConvertConstValue(CustomAttributeDataWriter& writer, uint32_t blobIndex, const Il2CppType* type)
- {
- Il2CppTypeEnum ttype = type->type;
- if (ttype == IL2CPP_TYPE_CLASS)
- {
- return kDefaultValueIndexNull;
- }
- DefaultValueIndex retIndex = EncodeWithIndex(EncodeWithBlobSource((DefaultValueIndex)writer.Size(), BlobSource::CONVERTED_IL2CPP_FORMAT));
- BlobReader reader = _rawImage->GetBlobReaderByRawIndex(blobIndex);
- switch (type->type)
- {
- case IL2CPP_TYPE_BOOLEAN:
- case IL2CPP_TYPE_I1:
- case IL2CPP_TYPE_U1:
- {
- writer.Write(reader, 1);
- break;
- }
- case IL2CPP_TYPE_CHAR:
- case IL2CPP_TYPE_I2:
- case IL2CPP_TYPE_U2:
- {
- writer.Write(reader, 2);
- break;
- }
- case IL2CPP_TYPE_I4:
- {
- writer.WriteCompressedInt32((int32_t)reader.Read32());
- break;
- }
- case IL2CPP_TYPE_U4:
- {
- writer.WriteCompressedUint32(reader.Read32());
- break;
- }
- case IL2CPP_TYPE_R4:
- {
- writer.Write(reader, 4);
- break;
- }
- case IL2CPP_TYPE_I8:
- case IL2CPP_TYPE_U8:
- case IL2CPP_TYPE_R8:
- {
- writer.Write(reader, 8);
- break;
- }
- case IL2CPP_TYPE_STRING:
- {
- std::string str = il2cpp::utils::StringUtils::Utf16ToUtf8((const Il2CppChar*)reader.GetData(), reader.GetLength() / 2);
- writer.WriteCompressedInt32((int32_t)str.length());
- writer.WriteBytes((const uint8_t*)str.c_str(), (int32_t)str.length());
- break;
- }
- default:
- {
- RaiseExecutionEngineException("not supported const type");
- }
- }
-
- return retIndex;
- }
- #endif
- void InterpreterImage::InitConsts()
- {
- const Table& tb = _rawImage->GetTable(TableType::CONSTANT);
- for (uint32_t i = 0; i < tb.rowNum; i++)
- {
- TbConstant data = _rawImage->ReadConstant(i + 1);
- TableType parentType = DecodeHasConstantType(data.parent);
- uint32_t rowIndex = DecodeHashConstantIndex(data.parent);
- Il2CppType tempType = {};
- tempType.type = (Il2CppTypeEnum)data.type;
- const Il2CppType& type = *MetadataPool::GetPooledIl2CppType(tempType);
- TypeIndex dataTypeIndex = AddIl2CppTypeCache(&type);
- #if !HYBRIDCLR_UNITY_2021_OR_NEW
- bool isNullValue = type.type == IL2CPP_TYPE_CLASS;
- #endif
- switch (parentType)
- {
- case TableType::FIELD:
- {
- FieldDetail& fd = _fieldDetails[rowIndex - 1];
- fd.defaultValueIndex = (uint32_t)_fieldDefaultValues.size();
- Il2CppFieldDefaultValue fdv = {};
- fdv.fieldIndex = rowIndex - 1;
- fdv.typeIndex = dataTypeIndex;
- #if HYBRIDCLR_UNITY_2021_OR_NEW
- fdv.dataIndex = ConvertConstValue(_constValues, data.value, &type);
- #else
- uint32_t dataImageOffset = _rawImage->GetImageOffsetOfBlob(type.type, data.value);
- fdv.dataIndex = isNullValue ? kDefaultValueIndexNull : (DefaultValueDataIndex)EncodeWithIndex(dataImageOffset);
- #endif
- _fieldDefaultValues.push_back(fdv);
- break;
- }
- case TableType::PARAM:
- {
- int32_t actualIndex = (*_paramRawIndex2ActualParamIndex)[rowIndex - 1];
- ParamDetail& fd = _params[actualIndex];
- fd.defaultValueIndex = (uint32_t)_paramDefaultValues.size();
- Il2CppParameterDefaultValue pdv = {};
- pdv.typeIndex = dataTypeIndex;
- pdv.parameterIndex = fd.parameterIndex;
- #if HYBRIDCLR_UNITY_2021_OR_NEW
- pdv.dataIndex = ConvertConstValue(_constValues, data.value, &type);
- #else
- uint32_t dataImageOffset = _rawImage->GetImageOffsetOfBlob(type.type, data.value);
- pdv.dataIndex = isNullValue ? kDefaultValueIndexNull : (DefaultValueDataIndex)EncodeWithIndex(dataImageOffset);
- #endif
- _paramDefaultValues.push_back(pdv);
- break;
- }
- case TableType::PROPERTY:
- {
- RaiseNotSupportedException("not support property const");
- break;
- }
- default:
- {
- RaiseExecutionEngineException("not support const TableType");
- break;
- }
- }
- }
- }
- void InterpreterImage::InitCustomAttributes()
- {
- const Table& tb = _rawImage->GetTable(TableType::CUSTOMATTRIBUTE);
- _tokenCustomAttributes.reserve(tb.rowNum);
- uint32_t threadStaticMethodToken = 0;
- Il2CppCustomAttributeTypeRange* curTypeRange = nullptr;
- for (uint32_t rowIndex = 1; rowIndex <= tb.rowNum; rowIndex++)
- {
- TbCustomAttribute data = _rawImage->ReadCustomAttribute(rowIndex);
- TableType parentType = DecodeHasCustomAttributeCodedIndexTableType(data.parent);
- uint32_t parentRowIndex = DecodeHasCustomAttributeCodedIndexRowIndex(data.parent);
- uint32_t token = EncodeToken(parentType, parentRowIndex);
- if (curTypeRange == nullptr || curTypeRange->token != token)
- {
- IL2CPP_ASSERT(_tokenCustomAttributes.find(token) == _tokenCustomAttributes.end());
- int32_t attributeStartIndex = EncodeWithIndex((int32_t)_customAttribues.size());
- int32_t handleIndex = (int32_t)_customAttributeHandles.size();
- _tokenCustomAttributes[token] = { (int32_t)EncodeWithIndex(handleIndex), false, nullptr, nullptr };
- #ifdef HYBRIDCLR_UNITY_2021_OR_NEW
- _customAttributeHandles.push_back({ token, (uint32_t)attributeStartIndex });
- #else
- _customAttributeHandles.push_back({ token, attributeStartIndex, 0 });
- #endif
- curTypeRange = &_customAttributeHandles[handleIndex];
- }
- #if !HYBRIDCLR_UNITY_2021_OR_NEW
- ++curTypeRange->count;
- #endif
- TableType ctorMethodTableType = DecodeCustomAttributeTypeCodedIndexTableType(data.type);
- uint32_t ctorMethodRowIndex = DecodeCustomAttributeTypeCodedIndexRowIndex(data.type);
- uint32_t ctorMethodToken = EncodeToken(ctorMethodTableType, ctorMethodRowIndex);
- //CustomAttribute ca = { ctorMethodToken, data.value };
- //ca.value = data.value;
- //ReadMethodRefInfoFromToken(nullptr, nullptr, , ca.attrCtorMethod);
- _customAttribues.push_back({ ctorMethodToken, data.value });
- if (parentType == TableType::FIELD)
- {
- // try set thread static flags
- if (threadStaticMethodToken == 0)
- {
- if (IsThreadStaticCtorToken(ctorMethodTableType, ctorMethodRowIndex))
- {
- threadStaticMethodToken = ctorMethodToken;
- }
- }
- if (ctorMethodToken == threadStaticMethodToken)
- {
- IL2CPP_ASSERT(threadStaticMethodToken != 0);
- _fieldDetails[parentRowIndex - 1].offset = THREAD_LOCAL_STATIC_MASK;
- }
- }
- }
- IL2CPP_ASSERT(_tokenCustomAttributes.size() == _customAttributeHandles.size());
- #ifdef HYBRIDCLR_UNITY_2021_OR_NEW
- // add extra Il2CppCustomAttributeTypeRange for compute count
- _customAttributeHandles.push_back({ 0, EncodeWithIndex((int32_t)_customAttribues.size()) });
- #endif
- #if !HYBRIDCLR_UNITY_2022_OR_NEW
- _customAttribtesCaches.resize(_tokenCustomAttributes.size());
- #endif
- }
- #ifdef HYBRIDCLR_UNITY_2021_OR_NEW
- void InterpreterImage::InitCustomAttributeData(CustomAttributesInfo& cai, const Il2CppCustomAttributeTypeRange& dataRange)
- {
- il2cpp::os::FastAutoLock metaLock(&il2cpp::vm::g_MetadataLock);
- if (cai.inited)
- {
- return;
- }
- BuildCustomAttributesData(cai, dataRange);
- il2cpp::os::Atomic::FullMemoryBarrier();
- cai.inited = true;
- }
- void InterpreterImage::BuildCustomAttributesData(CustomAttributesInfo& cai, const Il2CppCustomAttributeTypeRange& curTypeRange)
- {
- hybridclr::interpreter::ExecutingInterpImageScope scope(hybridclr::interpreter::InterpreterModule::GetCurrentThreadMachineState(), this->_il2cppImage);
- _il2cppFormatCustomDataBlob.Reset();
- const Il2CppCustomAttributeDataRange& nextTypeRange = *(&curTypeRange + 1);
- uint32_t attrCount = nextTypeRange.startOffset - curTypeRange.startOffset;
- IL2CPP_ASSERT(attrCount > 0 && attrCount < 1024);
- _il2cppFormatCustomDataBlob.WriteAttributeCount(attrCount);
- int32_t attrStartOffset = DecodeMetadataIndex(curTypeRange.startOffset);
- int32_t methodIndexDataOffset = _il2cppFormatCustomDataBlob.Size();
- _il2cppFormatCustomDataBlob.Skip(attrCount * sizeof(int32_t));
- for (uint32_t i = 0; i < attrCount; i++)
- {
- const CustomAttribute& ca = _customAttribues[attrStartOffset + (int32_t)i];
- MethodRefInfo mri = {};
- ReadMethodRefInfoFromToken(nullptr, nullptr, DecodeTokenTableType(ca.ctorMethodToken), DecodeTokenRowIndex(ca.ctorMethodToken), mri);
- const MethodInfo* ctorMethod = GetMethodInfoFromMethodDef(mri.containerType, mri.methodDef);
- MethodIndex ctorIndex = il2cpp::vm::GlobalMetadata::GetMethodIndexFromDefinition(mri.methodDef);
- _il2cppFormatCustomDataBlob.WriteMethodIndex(methodIndexDataOffset, ctorIndex);
- methodIndexDataOffset += sizeof(int32_t);
- if (ca.value != 0)
- {
- BlobReader reader = _rawImage->GetBlobReaderByRawIndex(ca.value);
- ConvertILCustomAttributeData2Il2CppFormat(ctorMethod, reader);
- }
- else
- {
- IL2CPP_ASSERT(mri.methodDef->parameterCount == 0);
- _il2cppFormatCustomDataBlob.WriteCompressedUint32(0);
- _il2cppFormatCustomDataBlob.WriteCompressedUint32(0);
- _il2cppFormatCustomDataBlob.WriteCompressedUint32(0);
- }
- }
- void* resultData = HYBRIDCLR_MALLOC(_il2cppFormatCustomDataBlob.Size());
- std::memcpy(resultData, _il2cppFormatCustomDataBlob.Data(), _il2cppFormatCustomDataBlob.Size());
- cai.dataStartPtr = resultData;
- cai.dataEndPtr = (uint8_t*)resultData + _il2cppFormatCustomDataBlob.Size();
- }
- void InterpreterImage::WriteEncodeTypeEnum(CustomAttributeDataWriter& writer, const Il2CppType* type)
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- if (type->type == IL2CPP_TYPE_ENUM || klass->enumtype)
- {
- writer.WriteByte((byte)IL2CPP_TYPE_ENUM);
- int32_t typeIndex = type->type == IL2CPP_TYPE_CLASS || type->type == IL2CPP_TYPE_VALUETYPE ? ((Il2CppTypeDefinition*)type->data.typeHandle)->byvalTypeIndex : AddIl2CppTypeCache(type);
- writer.WriteCompressedInt32(typeIndex);
- }
- else if (klass == il2cpp_defaults.systemtype_class)
- {
- writer.WriteByte((byte)IL2CPP_TYPE_IL2CPP_TYPE_INDEX);
- }
- else
- {
- writer.WriteByte((uint8_t)type->type);
- }
- }
- void InterpreterImage::ConvertBoxedValue(CustomAttributeDataWriter& writer, BlobReader& reader, bool writeType)
- {
- uint64_t obj = 0;
- Il2CppType kind = {};
- ReadCustomAttributeFieldOrPropType(reader, kind);
- ConvertFixedArg(writer, reader, &kind, true);
- }
- void InterpreterImage::ConvertSystemType(CustomAttributeDataWriter& writer, BlobReader& reader, bool writeType)
- {
- if (writeType)
- {
- writer.WriteByte((byte)IL2CPP_TYPE_IL2CPP_TYPE_INDEX);
- }
- Il2CppString* fullName = ReadSerString(reader);
- if (!fullName)
- {
- writer.WriteCompressedInt32(-1);
- return;
- }
- Il2CppReflectionType* type = GetReflectionTypeFromName(fullName);
- if (!type)
- {
- std::string stdTypeName = il2cpp::utils::StringUtils::Utf16ToUtf8(fullName->chars);
- TEMP_FORMAT(errMsg, "CustomAttribute fixed arg type:System.Type fullName:'%s' not find", stdTypeName.c_str());
- il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetTypeLoadException(errMsg));
- }
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type->type);
- if (!klass->generic_class && (Il2CppTypeDefinition*)klass->typeMetadataHandle)
- {
- writer.WriteCompressedInt32(((Il2CppTypeDefinition*)klass->typeMetadataHandle)->byvalTypeIndex);
- }
- else
- {
- writer.WriteCompressedInt32(AddIl2CppTypeCache(type->type));
- }
- }
- void InterpreterImage::ConvertFixedArg(CustomAttributeDataWriter& writer, BlobReader& reader, const Il2CppType* type, bool writeType)
- {
- switch (type->type)
- {
- case IL2CPP_TYPE_BOOLEAN:
- case IL2CPP_TYPE_I1:
- case IL2CPP_TYPE_U1:
- {
- if (writeType)
- {
- writer.WriteByte((uint8_t)type->type);
- }
- writer.Write(reader, 1);
- break;
- }
- case IL2CPP_TYPE_CHAR:
- case IL2CPP_TYPE_I2:
- case IL2CPP_TYPE_U2:
- {
- if (writeType)
- {
- writer.WriteByte((uint8_t)type->type);
- }
- writer.Write(reader, 2);
- break;
- }
- case IL2CPP_TYPE_I4:
- {
- if (writeType)
- {
- writer.WriteByte((uint8_t)type->type);
- }
- writer.WriteCompressedInt32((int32_t)reader.Read32());
- break;
- }
- case IL2CPP_TYPE_U4:
- {
- if (writeType)
- {
- writer.WriteByte((uint8_t)type->type);
- }
- writer.WriteCompressedUint32(reader.Read32());
- break;
- }
- case IL2CPP_TYPE_R4:
- {
- if (writeType)
- {
- writer.WriteByte((uint8_t)type->type);
- }
- writer.Write(reader, 4);
- break;
- }
- case IL2CPP_TYPE_I8:
- case IL2CPP_TYPE_U8:
- case IL2CPP_TYPE_R8:
- {
- if (writeType)
- {
- writer.WriteByte((uint8_t)type->type);
- }
- writer.Write(reader, 8);
- break;
- }
- case IL2CPP_TYPE_SZARRAY:
- {
- if (writeType)
- {
- writer.WriteByte((uint8_t)type->type);
- }
- int32_t numElem = (int32_t)reader.Read32();
- writer.WriteCompressedInt32(numElem);
- if (numElem != -1)
- {
- //Il2CppType kind = {};
- //ReadCustomAttributeFieldOrPropType(reader, kind);
- const Il2CppType* eleType = type->data.type;
- WriteEncodeTypeEnum(writer, eleType);
- if (eleType->type == IL2CPP_TYPE_OBJECT)
- {
- // kArrayTypeWithDifferentElements
- writer.WriteByte(1);
- for (uint16_t i = 0; i < numElem; i++)
- {
- ConvertBoxedValue(writer, reader, false);
- }
- }
- else
- {
- // all element type is same.
- writer.WriteByte(0);
- for (uint16_t i = 0; i < numElem; i++)
- {
- ConvertFixedArg(writer, reader, eleType, false);
- }
- }
- }
- break;
- }
- case IL2CPP_TYPE_STRING:
- {
- if (writeType)
- {
- writer.WriteByte((uint8_t)type->type);
- }
- byte b = reader.PeekByte();
- if (b == 0xFF)
- {
- reader.SkipByte();
- writer.WriteCompressedInt32(-1);
- }
- else if (b == 0)
- {
- reader.SkipByte();
- writer.WriteCompressedInt32(0);
- }
- else
- {
- const byte* beginDataPtr = reader.GetDataOfReadPosition();
- uint32_t len = reader.ReadCompressedUint32();
- writer.WriteCompressedInt32((int32_t)len);
- writer.WriteBytes(reader.GetDataOfReadPosition(), len);
- reader.SkipBytes(len);
- }
- break;
- }
- case IL2CPP_TYPE_OBJECT:
- {
- ConvertBoxedValue(writer, reader, writeType);
- //*(Il2CppObject**)data = ReadBoxedValue(reader);
- // FIXME memory barrier
- break;
- }
- case IL2CPP_TYPE_CLASS:
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- if (!klass)
- {
- RaiseExecutionEngineException("type not find");
- }
- if (klass == il2cpp_defaults.object_class)
- {
- ConvertBoxedValue(writer, reader, writeType);
- }
- else if (klass == il2cpp_defaults.systemtype_class)
- {
- ConvertSystemType(writer, reader, writeType);
- }
- else
- {
- TEMP_FORMAT(errMsg, "fixed arg type:%s.%s not support", klass->namespaze, klass->name);
- RaiseNotSupportedException(errMsg);
- }
- break;
- }
- case IL2CPP_TYPE_VALUETYPE:
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- if (writeType)
- {
- writer.WriteByte((byte)IL2CPP_TYPE_ENUM);
- IL2CPP_ASSERT(klass->enumtype);
- int32_t typeIndex = klass->generic_class ? AddIl2CppTypeCache(type) : ((Il2CppTypeDefinition*)type->data.typeHandle)->byvalTypeIndex;
- writer.WriteCompressedInt32(typeIndex);
- }
- ConvertFixedArg(writer, reader, &klass->element_class->byval_arg, false);
- break;
- }
- case IL2CPP_TYPE_SYSTEM_TYPE:
- {
- ConvertSystemType(writer, reader, true);
- break;
- }
- case IL2CPP_TYPE_BOXED_OBJECT:
- {
- uint8_t fieldOrPropType = reader.ReadByte();
- IL2CPP_ASSERT(fieldOrPropType == 0x51);
- ConvertBoxedValue(writer, reader, writeType);
- break;
- }
- case IL2CPP_TYPE_ENUM:
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type);
- IL2CPP_ASSERT(klass->enumtype);
- if (writeType)
- {
- int32_t typeIndex = klass->generic_class ? AddIl2CppTypeCache(type) : ((Il2CppTypeDefinition*)type->data.typeHandle)->byvalTypeIndex;
- writer.WriteCompressedInt32(typeIndex);
- }
- ConvertFixedArg(writer, reader, &klass->element_class->byval_arg, false);
- break;
- }
- default:
- {
- RaiseExecutionEngineException("not support fixed argument type");
- }
- }
- }
- void InterpreterImage::GetFieldDeclaringTypeIndexAndFieldIndexByName(const Il2CppTypeDefinition* declaringType, const char* name, int32_t& typeIndex, int32_t& fieldIndex)
- {
- Il2CppClass* klass = il2cpp::vm::GlobalMetadata::GetTypeInfoFromHandle((Il2CppMetadataTypeHandle)declaringType);
- FieldInfo* field = il2cpp::vm::Class::GetFieldFromName(klass, name);
- if (!field)
- {
- RaiseExecutionEngineException("GetFieldDeclaringTypeIndexAndFieldIndexByName can't find field");
- }
- if (field->parent == klass)
- {
- typeIndex = kTypeDefinitionIndexInvalid;
- }
- else
- {
- klass = field->parent;
- if (klass->generic_class)
- {
- RaiseExecutionEngineException("GetFieldDeclaringTypeIndexAndFieldIndexByName doesn't support field of generic CustomAttribute");
- }
- typeIndex = il2cpp::vm::GlobalMetadata::GetIndexForTypeDefinition(klass);
- }
- fieldIndex = (int32_t)(field - klass->fields);
- }
- void InterpreterImage::GetPropertyDeclaringTypeIndexAndPropertyIndexByName(const Il2CppTypeDefinition* declaringType, const char* name, int32_t& typeIndex, int32_t& fieldIndex)
- {
- Il2CppClass* klass = il2cpp::vm::GlobalMetadata::GetTypeInfoFromHandle((Il2CppMetadataTypeHandle)declaringType);
- const PropertyInfo* propertyInfo = il2cpp::vm::Class::GetPropertyFromName(klass, name);
- if (!propertyInfo)
- {
- RaiseExecutionEngineException("GetFieldDeclaringTypeIndexAndFieldIndexByName can't find field");
- }
- if (propertyInfo->parent == klass)
- {
- typeIndex = kTypeDefinitionIndexInvalid;
- }
- else
- {
- klass = propertyInfo->parent;
- if (klass->generic_class)
- {
- RaiseExecutionEngineException("GetPropertyDeclaringTypeIndexAndPropertyIndexByName doesn't support field of generic CustomAttribute");
- }
- typeIndex = il2cpp::vm::GlobalMetadata::GetIndexForTypeDefinition(klass);
- }
- #if UNITY_ENGINE_TUANJIE
- fieldIndex = -1;
- for (int32_t i = 0; i < klass->property_count; i++)
- {
- if (klass->properties[i] == propertyInfo)
- {
- fieldIndex = i;
- break;;
- }
- }
- IL2CPP_ASSERT(fieldIndex != -1);
- #else
- fieldIndex = (int32_t)(propertyInfo - klass->properties);
- #endif
- }
- void InterpreterImage::ConvertILCustomAttributeData2Il2CppFormat(const MethodInfo* ctorMethod, BlobReader& reader)
- {
- uint16_t prolog = reader.Read16();
- IL2CPP_ASSERT(prolog == 0x0001);
- IL2CPP_ASSERT(!ctorMethod->is_generic);
- _tempCtorArgBlob.Reset();
- for (uint16_t i = 0; i < ctorMethod->parameters_count; i++)
- {
- const Il2CppType* paramType = GET_METHOD_PARAMETER_TYPE(ctorMethod->parameters[i]);
- ConvertFixedArg(_tempCtorArgBlob, reader, paramType, true);
- }
- uint16_t numNamed = reader.Read16();
- uint32_t fieldCount = 0;
- uint32_t propertyCount = 0;
- _tempFieldBlob.Reset();
- _tempPropertyBlob.Reset();
- const Il2CppTypeDefinition* declaringType = GetUnderlyingTypeDefinition(&ctorMethod->klass->byval_arg);
- for (uint16_t idx = 0; idx < numNamed; idx++)
- {
- byte fieldOrPropTypeTag = reader.ReadByte();
- IL2CPP_ASSERT(fieldOrPropTypeTag == 0x53 || fieldOrPropTypeTag == 0x54);
- Il2CppType fieldOrPropType = {};
- ReadCustomAttributeFieldOrPropType(reader, fieldOrPropType);
- Il2CppString* fieldOrPropName = ReadSerString(reader);
- std::string stdStrName = il2cpp::utils::StringUtils::Utf16ToUtf8(fieldOrPropName->chars);
- const char* cstrName = stdStrName.c_str();
- int32_t fieldOrPropertyDeclaringTypeIndex = kTypeIndexInvalid;
- int32_t fieldOrPropertyIndex = 0;
- if (fieldOrPropTypeTag == 0x53)
- {
- ++fieldCount;
- ConvertFixedArg(_tempFieldBlob, reader, &fieldOrPropType, true);
- GetFieldDeclaringTypeIndexAndFieldIndexByName(declaringType, cstrName, fieldOrPropertyDeclaringTypeIndex, fieldOrPropertyIndex);
- if (fieldOrPropertyDeclaringTypeIndex == kTypeDefinitionIndexInvalid)
- {
- _tempFieldBlob.WriteCompressedInt32(fieldOrPropertyIndex);
- }
- else
- {
- _tempFieldBlob.WriteCompressedInt32(-fieldOrPropertyIndex - 1);
- _tempFieldBlob.WriteCompressedUint32(fieldOrPropertyDeclaringTypeIndex);
- }
- }
- else
- {
- ++propertyCount;
- ConvertFixedArg(_tempPropertyBlob, reader, &fieldOrPropType, true);
- GetPropertyDeclaringTypeIndexAndPropertyIndexByName(declaringType, cstrName, fieldOrPropertyDeclaringTypeIndex, fieldOrPropertyIndex);
- if (fieldOrPropertyDeclaringTypeIndex == kTypeDefinitionIndexInvalid)
- {
- _tempPropertyBlob.WriteCompressedInt32(fieldOrPropertyIndex);
- }
- else
- {
- _tempPropertyBlob.WriteCompressedInt32(-fieldOrPropertyIndex - 1);
- _tempPropertyBlob.WriteCompressedUint32(fieldOrPropertyDeclaringTypeIndex);
- }
- }
- }
- _il2cppFormatCustomDataBlob.WriteCompressedUint32(ctorMethod->parameters_count);
- _il2cppFormatCustomDataBlob.WriteCompressedUint32(fieldCount);
- _il2cppFormatCustomDataBlob.WriteCompressedUint32(propertyCount);
- _il2cppFormatCustomDataBlob.Write(_tempCtorArgBlob);
- _il2cppFormatCustomDataBlob.Write(_tempFieldBlob);
- _il2cppFormatCustomDataBlob.Write(_tempPropertyBlob);
- }
- #endif
- #if !HYBRIDCLR_UNITY_2021_OR_NEW
- void InterpreterImage::ConstructCustomAttribute(BlobReader& reader, Il2CppObject* obj, const MethodInfo* ctorMethod)
- {
- uint16_t prolog = reader.Read16();
- IL2CPP_ASSERT(prolog == 0x0001);
- if (ctorMethod->parameters_count == 0)
- {
- il2cpp::vm::Runtime::Invoke(ctorMethod, obj, nullptr, nullptr);
- }
- else
- {
- int32_t argSize = sizeof(uint64_t) * ctorMethod->parameters_count;
- uint64_t* argDatas = (uint64_t*)alloca(argSize);
- std::memset(argDatas, 0, argSize);
- void** argPtrs = (void**)alloca(sizeof(void*) * ctorMethod->parameters_count); // same with argDatas
- for (uint8_t i = 0; i < ctorMethod->parameters_count; i++)
- {
- argPtrs[i] = argDatas + i;
- const Il2CppType* paramType = GET_METHOD_PARAMETER_TYPE(ctorMethod->parameters[i]);
- ReadFixedArg(reader, paramType, argDatas + i);
- Il2CppClass* paramKlass = il2cpp::vm::Class::FromIl2CppType(paramType);
- if (!IS_CLASS_VALUE_TYPE(paramKlass))
- {
- argPtrs[i] = (void*)argDatas[i];
- }
- }
- il2cpp::vm::Runtime::Invoke(ctorMethod, obj, argPtrs, nullptr);
- // clear ref. may not need. gc memory barrier
- std::memset(argDatas, 0, argSize);
- }
- uint16_t numNamed = reader.Read16();
- Il2CppClass* klass = obj->klass;
- for (uint16_t idx = 0; idx < numNamed; idx++)
- {
- byte fieldOrPropTypeTag = reader.ReadByte();
- IL2CPP_ASSERT(fieldOrPropTypeTag == 0x53 || fieldOrPropTypeTag == 0x54);
- Il2CppType fieldOrPropType = {};
- ReadCustomAttributeFieldOrPropType(reader, fieldOrPropType);
- Il2CppString* fieldOrPropName = ReadSerString(reader);
- std::string stdStrName = il2cpp::utils::StringUtils::Utf16ToUtf8(fieldOrPropName->chars);
- const char* cstrName = stdStrName.c_str();
- uint64_t value = 0;
- ReadFixedArg(reader, &fieldOrPropType, &value);
- if (fieldOrPropTypeTag == 0x53)
- {
- FieldInfo* field = il2cpp::vm::Class::GetFieldFromName(klass, cstrName);
- if (!field)
- {
- TEMP_FORMAT(errMsg, "CustomAttribute field missing. klass:%s.%s field:%s", klass->namespaze, klass->name, cstrName);
- il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetTypeInitializationException(errMsg, nullptr));
- }
- Il2CppReflectionField* refField = il2cpp::vm::Reflection::GetFieldObject(klass, field);
- IL2CPP_ASSERT(IsTypeEqual(&fieldOrPropType, field->type));
- uint32_t fieldSize = GetTypeValueSize(&fieldOrPropType);
- std::memcpy((byte*)obj + field->offset, &value, fieldSize);
- //fixme MEMORY BARRIER
- IL2CPP_ASSERT(refField);
- }
- else
- {
- const PropertyInfo* prop = il2cpp::vm::Class::GetPropertyFromName(klass, cstrName);
- if (!prop)
- {
- TEMP_FORMAT(errMsg, "CustomAttribute property missing. klass:%s property:%s", klass->name, cstrName);
- il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetTypeInitializationException(errMsg, nullptr));
- }
- IL2CPP_ASSERT(IsTypeEqual(&fieldOrPropType, GET_METHOD_PARAMETER_TYPE(prop->set->parameters[0])));
- Il2CppException* ex = nullptr;
- Il2CppClass* propKlass = il2cpp::vm::Class::FromIl2CppType(&fieldOrPropType);
- IL2CPP_ASSERT(propKlass);
- void* args[] = { (IS_CLASS_VALUE_TYPE(propKlass) ? &value : (void*)value) };
- il2cpp::vm::Runtime::Invoke(prop->set, obj, args, &ex);
- if (ex)
- {
- il2cpp::vm::Exception::Raise(ex);
- }
- }
- }
- }
- CustomAttributesCache* InterpreterImage::GenerateCustomAttributesCacheInternal(CustomAttributeIndex index)
- {
- IL2CPP_ASSERT(index != kCustomAttributeIndexInvalid);
- CustomAttributesCache* cache = _customAttribtesCaches[index];
- if (cache)
- {
- return cache;
- }
- IL2CPP_ASSERT(index < (CustomAttributeIndex)_customAttributeHandles.size());
- Il2CppCustomAttributeTypeRange& typeRange = _customAttributeHandles[index];
- il2cpp::os::FastAutoLock metaLock(&il2cpp::vm::g_MetadataLock);
- cache = _customAttribtesCaches[index];
- if (cache)
- {
- return cache;
- }
- hybridclr::interpreter::ExecutingInterpImageScope scope(hybridclr::interpreter::InterpreterModule::GetCurrentThreadMachineState(), this->_il2cppImage);
- cache = (CustomAttributesCache*)IL2CPP_CALLOC(1, sizeof(CustomAttributesCache));
- int32_t count;
- #ifdef HYBRIDCLR_UNITY_2021_OR_NEW
- count = (int32_t)(_customAttributeHandles[index + 1].startOffset - typeRange.startOffset);
- #else
- count = (int32_t)typeRange.count;
- #endif
- cache->count = count;
- cache->attributes = (Il2CppObject**)il2cpp::gc::GarbageCollector::AllocateFixed(sizeof(Il2CppObject*) * count, 0);
- int32_t start = DecodeMetadataIndex(GET_CUSTOM_ATTRIBUTE_TYPE_RANGE_START(typeRange));
- for (int32_t i = 0; i < count; i++)
- {
- int32_t attrIndex = start + i;
- IL2CPP_ASSERT(attrIndex >= 0 && attrIndex < (int32_t)_customAttribues.size());
- CustomAttribute& ca = _customAttribues[attrIndex];
- MethodRefInfo mri = {};
- ReadMethodRefInfoFromToken(nullptr, nullptr, DecodeTokenTableType(ca.ctorMethodToken), DecodeTokenRowIndex(ca.ctorMethodToken), mri);
- const MethodInfo* ctorMethod = GetMethodInfoFromMethodDef(mri.containerType, mri.methodDef);
- IL2CPP_ASSERT(ctorMethod);
- Il2CppClass* klass = ctorMethod->klass;
- Il2CppObject* attr = il2cpp::vm::Object::New(klass);
- Il2CppArray* paramArr = nullptr;
- if (ca.value != 0)
- {
- BlobReader reader = _rawImage->GetBlobReaderByRawIndex(ca.value);
- ConstructCustomAttribute(reader, attr, ctorMethod);
- }
- else
- {
- IL2CPP_ASSERT(ctorMethod->parameters_count == 0);
- il2cpp::vm::Runtime::Invoke(ctorMethod, attr, nullptr, nullptr);
- }
- cache->attributes[i] = attr;
- HYBRIDCLR_SET_WRITE_BARRIER((void**)cache->attributes + i);
- }
- il2cpp::os::Atomic::FullMemoryBarrier();
- _customAttribtesCaches[index] = cache;
- return cache;
- }
- #elif HYBRIDCLR_UNITY_2021
- CustomAttributesCache* InterpreterImage::GenerateCustomAttributesCacheInternal(CustomAttributeIndex index)
- {
- IL2CPP_ASSERT(index != kCustomAttributeIndexInvalid);
- CustomAttributesCache* cache = _customAttribtesCaches[index];
- if (cache)
- {
- return cache;
- }
- IL2CPP_ASSERT(index < (CustomAttributeIndex)_customAttributeHandles.size());
- Il2CppCustomAttributeTypeRange& typeRange = _customAttributeHandles[index];
- cache = _customAttribtesCaches[index];
- if (cache)
- {
- return cache;
- }
- hybridclr::interpreter::ExecutingInterpImageScope scope(hybridclr::interpreter::InterpreterModule::GetCurrentThreadMachineState(), this->_il2cppImage);
- void* start;
- void* end;
- std::tie(start, end) = CreateCustomAttributeDataTuple(&typeRange);
- IL2CPP_ASSERT(start && end);
- il2cpp::metadata::CustomAttributeDataReader reader(start, end);
- cache = (CustomAttributesCache*)IL2CPP_CALLOC(1, sizeof(CustomAttributesCache));
- cache->count = (int)reader.GetCount();
- cache->attributes = (Il2CppObject**)il2cpp::gc::GarbageCollector::AllocateFixed(sizeof(Il2CppObject*) * cache->count, 0);
- il2cpp::metadata::CustomAttributeDataIterator iter = reader.GetDataIterator();
- for (int i = 0; i < cache->count; i++)
- {
- Il2CppException* exc = NULL;
- il2cpp::metadata::CustomAttributeCreator creator;
- if (reader.VisitCustomAttributeData(_il2cppImage, &iter, &creator, &exc))
- {
- cache->attributes[i] = creator.GetAttribute(&exc);
- HYBRIDCLR_SET_WRITE_BARRIER((void**)&cache->attributes[i]);
- }
- if (exc != NULL)
- {
- il2cpp::gc::GarbageCollector::FreeFixed(cache->attributes);
- HYBRIDCLR_FREE(cache);
- il2cpp::vm::Exception::Raise(exc);
- }
- }
- il2cpp::os::FastAutoLock metaLock(&il2cpp::vm::g_MetadataLock);
- CustomAttributesCache* original = _customAttribtesCaches[index];
- if (original)
- {
- // A non-NULL return value indicates some other thread already generated this cache.
- // We need to cleanup the resources we allocated
- il2cpp::gc::GarbageCollector::FreeFixed(cache->attributes);
- HYBRIDCLR_FREE(cache);
- return original;
- }
- il2cpp::os::Atomic::FullMemoryBarrier();
- _customAttribtesCaches[index] = cache;
- return cache;
- }
- #endif
- void InterpreterImage::InitMethodDefs0()
- {
- const Table& typeDefTb = _rawImage->GetTable(TableType::TYPEDEF);
- const Table& methodTb = _rawImage->GetTable(TableType::METHOD);
- _methodDefines.resize(methodTb.rowNum);
- for (Il2CppMethodDefinition& md : _methodDefines)
- {
- md.genericContainerIndex = kGenericContainerIndexInvalid;
- }
- }
- void InterpreterImage::InitMethodDefs()
- {
- const Table& typeDefTb = _rawImage->GetTable(TableType::TYPEDEF);
- const Table& methodTb = _rawImage->GetTable(TableType::METHOD);
- for (uint32_t i = 0, n = typeDefTb.rowNum; i < n; i++)
- {
- Il2CppTypeDefinition& typeDef = _typesDefines[i];
- uint32_t rawMethodStart = DecodeMetadataIndex(typeDef.methodStart);
- for (int m = 0; m < typeDef.method_count; m++)
- {
- Il2CppMethodDefinition& md = _methodDefines[rawMethodStart + m];
- md.declaringType = EncodeWithIndex(i);
- }
- }
- int32_t paramTableRowNum = _rawImage->GetTable(TableType::PARAM).rowNum;
- for (uint32_t index = 0; index < methodTb.rowNum; index++)
- {
- Il2CppMethodDefinition& md = _methodDefines[index];
- uint32_t rowIndex = index + 1;
- TbMethod methodData = _rawImage->ReadMethod(rowIndex);
- md.nameIndex = EncodeWithIndex(methodData.name);
- md.parameterStart = methodData.paramList - 1;
- //md.genericContainerIndex = kGenericContainerIndexInvalid;
- md.token = EncodeToken(TableType::METHOD, rowIndex);
- md.flags = methodData.flags;
- md.iflags = methodData.implFlags;
- md.slot = kInvalidIl2CppMethodSlot;
- if (index > 0)
- {
- auto& last = _methodDefines[index - 1];
- last.parameterCount = md.parameterStart - last.parameterStart;
- }
- if (index == methodTb.rowNum - 1)
- {
- md.parameterCount = (int)paramTableRowNum - (int32_t)md.parameterStart;
- }
- //MethodBody& body = _methodBodies[index];
- //ReadMethodBody(md, methodData, body);
- }
- for (uint32_t i = 0, n = typeDefTb.rowNum; i < n; i++)
- {
- Il2CppTypeDefinition& typeDef = _typesDefines[i];
- uint32_t rawMethodStart = DecodeMetadataIndex(typeDef.methodStart);
- bool isInterface = IsInterface(typeDef.flags);
- uint16_t slotIdx = 0;
- for (int m = 0; m < typeDef.method_count; m++)
- {
- Il2CppMethodDefinition& md = _methodDefines[rawMethodStart + m];
- const char* methodName = _rawImage->GetStringFromRawIndex(DecodeMetadataIndex(md.nameIndex));
- if (!std::strcmp(methodName, ".cctor"))
- {
- typeDef.bitfield |= (1 << (il2cpp::vm::kBitHasStaticConstructor - 1));
- }
- if (!std::strcmp(methodName, "Finalize"))
- {
- typeDef.bitfield |= (1 << (il2cpp::vm::kBitHasFinalizer - 1));
- }
- if (isInterface && IsInstanceMethod(&md) && IsVirtualMethod(md.flags))
- {
- md.slot = slotIdx++;
- }
- // TODO 可以考虑优化一下,将 signature在前一步存到暂时不用的 returnType里
- TbMethod methodData = _rawImage->ReadMethod(rawMethodStart + m + 1);
- BlobReader methodSigReader = _rawImage->GetBlobReaderByRawIndex(methodData.signature);
- uint32_t namedParamStart = md.parameterStart;
- uint32_t namedParamCount = md.parameterCount;
- uint32_t actualParamStart = (uint32_t)_params.size();
- ReadMethodDefSig(
- methodSigReader,
- GetGenericContainerByTypeDefinition(&typeDef),
- GetGenericContainerByRawIndex(DecodeMetadataIndex(md.genericContainerIndex)),
- md,
- _params);
- uint32_t actualParamCount = (uint32_t)_params.size() - actualParamStart;
- md.parameterStart = actualParamStart;
- md.parameterCount = actualParamCount;
- for (uint32_t paramRowIndex = namedParamStart + 1; paramRowIndex <= namedParamStart + namedParamCount; paramRowIndex++)
- {
- TbParam data = _rawImage->ReadParam(paramRowIndex);
- if (data.sequence > 0)
- {
- int32_t actualParamIndex = actualParamStart + data.sequence - 1;
- ParamDetail& paramDetail = _params[actualParamIndex];
- Il2CppParameterDefinition& pd = paramDetail.paramDef;
- IL2CPP_ASSERT(paramDetail.parameterIndex == data.sequence - 1);
- pd.nameIndex = EncodeWithIndex(data.name);
- pd.token = EncodeToken(TableType::PARAM, paramRowIndex);
- (*_paramRawIndex2ActualParamIndex)[paramRowIndex - 1] = actualParamIndex;
- if (data.flags)
- {
- const Il2CppType* fieldType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(pd.typeIndex);
- Il2CppType* newType = MetadataPool::ShallowCloneIl2CppType(fieldType);
- newType->attrs = data.flags;
- //paramDetail.type = newType;
- pd.typeIndex = AddIl2CppTypeCache(newType);
- }
- }
- else
- {
- // data.sequence == 0 is for returnType.
- // used for parent of CustomeAttributes of ReturnType
- // il2cpp not support ReturnType CustomAttributes. so we just ignore it.
- #if SUPPORT_METHOD_RETURN_TYPE_CUSTOM_ATTRIBUTE
- md.returnParameterToken = EncodeToken(TableType::PARAM, paramRowIndex);
- #endif
- }
- }
- }
- }
- }
- const il2cpp::utils::dynamic_array<MethodImpl> InterpreterImage::GetTypeMethodImplByTypeDefinition(const Il2CppTypeDefinition* typeDef)
- {
- uint32_t index = (uint32_t)(typeDef - &_typesDefines[0]);
- IL2CPP_ASSERT(index < (uint32_t)_typeDetails.size());
- TypeDefinitionDetail& tdd = _typeDetails[index];
- il2cpp::utils::dynamic_array<MethodImpl> methodImpls(tdd.methodImplCount);
- for (uint32_t i = 0; i < tdd.methodImplCount; i++)
- {
- uint32_t index = tdd.methodImplStart + i;
- TbMethodImpl data = _rawImage->ReadMethodImpl(index + 1);
- Il2CppTypeDefinition& typeDef = _typesDefines[data.classIdx - 1];
- Il2CppGenericContainer* gc = GetGenericContainerByTypeDefinition(&typeDef);
- MethodImpl& impl = methodImpls[i];
- ReadMethodRefInfoFromToken(gc, nullptr, DecodeMethodDefOrRefCodedIndexTableType(data.methodBody), DecodeMethodDefOrRefCodedIndexRowIndex(data.methodBody), impl.body);
- ReadMethodRefInfoFromToken(gc, nullptr, DecodeMethodDefOrRefCodedIndexTableType(data.methodDeclaration), DecodeMethodDefOrRefCodedIndexRowIndex(data.methodDeclaration), impl.declaration);
- }
- return methodImpls;
- }
- void InterpreterImage::InitMethodImpls0()
- {
- const Table& miTb = _rawImage->GetTable(TableType::METHODIMPL);
- for (uint32_t i = 0; i < miTb.rowNum; i++)
- {
- TbMethodImpl data = _rawImage->ReadMethodImpl(i + 1);
- uint32_t typeIndex = data.classIdx - 1;
- TypeDefinitionDetail& tdd = _typeDetails[typeIndex];
- Il2CppTypeDefinition& typeDef = _typesDefines[typeIndex];
- Il2CppGenericContainer* gc = GetGenericContainerByTypeDefinition(&typeDef);
- if (tdd.methodImplCount == 0)
- {
- tdd.methodImplStart = i;
- }
- ++tdd.methodImplCount;
- //MethodImpl impl;
- //ReadMethodRefInfoFromToken(gc, nullptr, DecodeMethodDefOrRefCodedIndexTableType(data.methodBody), DecodeMethodDefOrRefCodedIndexRowIndex(data.methodBody), impl.body);
- //ReadMethodRefInfoFromToken(gc, nullptr, DecodeMethodDefOrRefCodedIndexTableType(data.methodDeclaration), DecodeMethodDefOrRefCodedIndexRowIndex(data.methodDeclaration), impl.declaration);
- //tdd.methodImpls.push_back(impl);
- }
- }
- void InterpreterImage::InitProperties()
- {
- const Table& propertyMapTb = _rawImage->GetTable(TableType::PROPERTYMAP);
- const Table& propertyTb = _rawImage->GetTable(TableType::PROPERTY);
- _propeties.reserve(propertyTb.rowNum);
- for (uint32_t rowIndex = 1; rowIndex <= propertyTb.rowNum; rowIndex++)
- {
- TbProperty data = _rawImage->ReadProperty(rowIndex);
- _propeties.push_back({ _rawImage->GetStringFromRawIndex(data.name), data.flags, data.type, 0, 0
- , nullptr
- , { (StringIndex)EncodeWithIndex(data.name), kMethodIndexInvalid, kMethodIndexInvalid, (uint32_t)data.flags, EncodeToken(TableType::PROPERTY, rowIndex)}
- });
- }
- Il2CppTypeDefinition* last = nullptr;
- for (uint32_t rowIndex = 1; rowIndex <= propertyMapTb.rowNum; rowIndex++)
- {
- TbPropertyMap data = _rawImage->ReadPropertyMap(rowIndex);
- Il2CppTypeDefinition* typeDef = &_typesDefines[data.parent - 1];
- typeDef->propertyStart = EncodeWithIndex(data.propertyList); // start from 1
- if (last != nullptr)
- {
- last->property_count = data.propertyList - DecodeMetadataIndex(last->propertyStart);
- }
- last = typeDef;
- }
- if (last)
- {
- last->property_count = propertyTb.rowNum - DecodeMetadataIndex(last->propertyStart) + 1;
- }
- #if HYBRIDCLR_UNITY_2019
- for (const Il2CppTypeDefinition& typeDef : _typesDefines)
- {
- if (typeDef.property_count == 0)
- {
- continue;
- }
- for (int32_t start = DecodeMetadataIndex(typeDef.propertyStart), i = 0; i < typeDef.property_count; i++)
- {
- _propeties[start + i - 1].declaringType = &typeDef;
- }
- }
- #endif
- }
- void InterpreterImage::InitEvents()
- {
- const Table& eventMapTb = _rawImage->GetTable(TableType::EVENTMAP);
- const Table& eventTb = _rawImage->GetTable(TableType::EVENT);
- _events.reserve(eventTb.rowNum);
- for (uint32_t rowIndex = 1; rowIndex <= eventTb.rowNum; rowIndex++)
- {
- TbEvent data = _rawImage->ReadEvent(rowIndex);
- _events.push_back({ _rawImage->GetStringFromRawIndex(data.name), data.eventFlags, data.eventType, 0, 0, 0
- #if HYBRIDCLR_UNITY_2019
- , nullptr
- , { (StringIndex)EncodeWithIndex(data.name), kTypeIndexInvalid, kMethodIndexInvalid, kMethodIndexInvalid, kMethodIndexInvalid, EncodeToken(TableType::EVENT, rowIndex)}
- #endif
- });
- }
- Il2CppTypeDefinition* last = nullptr;
- for (uint32_t rowIndex = 1; rowIndex <= eventMapTb.rowNum; rowIndex++)
- {
- TbEventMap data = _rawImage->ReadEventMap(rowIndex);
- Il2CppTypeDefinition* typeDef = &_typesDefines[data.parent - 1];
- typeDef->eventStart = EncodeWithIndex(data.eventList); // start from 1
- if (last != nullptr)
- {
- last->event_count = data.eventList - DecodeMetadataIndex(last->eventStart);
- }
- last = typeDef;
- }
- if (last)
- {
- last->event_count = eventTb.rowNum - DecodeMetadataIndex(last->eventStart) + 1;
- }
- #if HYBRIDCLR_UNITY_2019
- for (const Il2CppTypeDefinition& typeDef : _typesDefines)
- {
- if (typeDef.event_count == 0)
- {
- continue;
- }
- for (int32_t start = DecodeMetadataIndex(typeDef.eventStart), i = 0; i < typeDef.event_count; i++)
- {
- EventDetail& ed = _events[start + i - 1];
- ed.declaringType = &typeDef;
- ed.il2cppDefinition.typeIndex = typeDef.byvalTypeIndex;
- }
- }
- #endif
- }
- void InterpreterImage::InitMethodSemantics()
- {
- const Table& msTb = _rawImage->GetTable(TableType::METHODSEMANTICS);
- for (uint32_t rowIndex = 1; rowIndex <= msTb.rowNum; rowIndex++)
- {
- TbMethodSemantics data = _rawImage->ReadMethodSemantics(rowIndex);
- uint32_t method = data.method;
- uint16_t semantics = data.semantics;
- TableType tableType = DecodeHasSemanticsCodedIndexTableType(data.association);
- uint32_t propertyOrEventIndex = DecodeHasSemanticsCodedIndexRowIndex(data.association) - 1;
- if (semantics & (uint16_t)MethodSemanticsAttributes::Getter)
- {
- IL2CPP_ASSERT(tableType == TableType::PROPERTY);
- PropertyDetail& pd = _propeties[propertyOrEventIndex];
- pd.getterMethodIndex = method;
- #if HYBRIDCLR_UNITY_2019
- pd.il2cppDefinition.get = method - DecodeMetadataIndex(pd.declaringType->methodStart) - 1;
- #endif
- }
- if (semantics & (uint16_t)MethodSemanticsAttributes::Setter)
- {
- IL2CPP_ASSERT(tableType == TableType::PROPERTY);
- PropertyDetail& pd = _propeties[propertyOrEventIndex];
- pd.setterMethodIndex = method;
- #if HYBRIDCLR_UNITY_2019
- pd.il2cppDefinition.set = method - DecodeMetadataIndex(pd.declaringType->methodStart) - 1;
- #endif
- }
- if (semantics & (uint16_t)MethodSemanticsAttributes::AddOn)
- {
- IL2CPP_ASSERT(tableType == TableType::EVENT);
- EventDetail& ed = _events[propertyOrEventIndex];
- ed.addMethodIndex = method;
- #if HYBRIDCLR_UNITY_2019
- ed.il2cppDefinition.add = method - DecodeMetadataIndex(ed.declaringType->methodStart) - 1;
- #endif
- }
- if (semantics & (uint16_t)MethodSemanticsAttributes::RemoveOn)
- {
- IL2CPP_ASSERT(tableType == TableType::EVENT);
- EventDetail& ed = _events[propertyOrEventIndex];
- ed.removeMethodIndex = method;
- #if HYBRIDCLR_UNITY_2019
- ed.il2cppDefinition.remove = method - DecodeMetadataIndex(ed.declaringType->methodStart) - 1;
- #endif
- }
- if (semantics & (uint16_t)MethodSemanticsAttributes::Fire)
- {
- IL2CPP_ASSERT(tableType == TableType::EVENT);
- EventDetail& ed = _events[propertyOrEventIndex];
- ed.fireMethodIndex = method;
- #if HYBRIDCLR_UNITY_2019
- ed.il2cppDefinition.raise = method - DecodeMetadataIndex(ed.declaringType->methodStart) - 1;
- #endif
- }
- }
- }
- struct EnclosingClassInfo
- {
- uint32_t enclosingTypeIndex; // rowIndex - 1
- std::vector<uint32_t> nestedTypeIndexs;
- };
- void InterpreterImage::InitNestedClass()
- {
- const Table& nestedClassTb = _rawImage->GetTable(TableType::NESTEDCLASS);
- _nestedTypeDefineIndexs.reserve(nestedClassTb.rowNum);
- std::vector<EnclosingClassInfo> enclosingTypes;
- for (uint32_t i = 0; i < nestedClassTb.rowNum; i++)
- {
- TbNestedClass data = _rawImage->ReadNestedClass(i + 1);
- Il2CppTypeDefinition& nestedType = _typesDefines[data.nestedClass - 1];
- Il2CppTypeDefinition& enclosingType = _typesDefines[data.enclosingClass - 1];
- if (enclosingType.nested_type_count == 0)
- {
- // 此行代码不能删,用于标识 enclosingTypes的index
- enclosingType.nestedTypesStart = (uint32_t)enclosingTypes.size();
- enclosingTypes.push_back({ data.enclosingClass - 1 });
- }
- ++enclosingType.nested_type_count;
- enclosingTypes[enclosingType.nestedTypesStart].nestedTypeIndexs.push_back(data.nestedClass - 1);
- //_nestedTypeDefineIndexs.push_back(data.nestedClass - 1);
- nestedType.declaringTypeIndex = enclosingType.byvalTypeIndex;
- }
- for (auto& enclosingType : enclosingTypes)
- {
- Il2CppTypeDefinition& enclosingTypeDef = _typesDefines[enclosingType.enclosingTypeIndex];
- IL2CPP_ASSERT(enclosingType.nestedTypeIndexs.size() == (size_t)enclosingTypeDef.nested_type_count);
- enclosingTypeDef.nestedTypesStart = (NestedTypeIndex)_nestedTypeDefineIndexs.size();
- enclosingTypeDef.nested_type_count = (uint16_t)enclosingType.nestedTypeIndexs.size();
- _nestedTypeDefineIndexs.insert(_nestedTypeDefineIndexs.end(), enclosingType.nestedTypeIndexs.begin(), enclosingType.nestedTypeIndexs.end());
- }
- }
- void InterpreterImage::InitClassLayouts()
- {
- const Table& classLayoutTb = _rawImage->GetTable(TableType::CLASSLAYOUT);
- for (uint32_t i = 0; i < classLayoutTb.rowNum; i++)
- {
- TbClassLayout data = _rawImage->ReadClassLayout(i + 1);
- _classLayouts[data.parent - 1] = data;
- if (data.classSize > 0)
- {
- Il2CppTypeDefinitionSizes& typeSizes = _typeDetails[data.parent - 1].typeSizes;
- typeSizes.instance_size = data.classSize + sizeof(Il2CppObject);
- }
- }
- ClassFieldLayoutCalculator calculator(this);
- for (Il2CppTypeDefinition& type : _typesDefines)
- {
- const Il2CppType* il2cppType = GetIl2CppTypeFromTypeDefinition(&type);
- calculator.CalcClassNotStaticFields(il2cppType);
- }
- for (TypeDefinitionDetail& type : _typeDetails)
- {
- const Il2CppTypeDefinition* typeDef = GetTypeDefinitionByTypeDetail(&type);
- const Il2CppType* il2cppType = GetIl2CppTypeFromTypeDefinition(typeDef);
- calculator.CalcClassStaticFields(il2cppType);
- ClassLayoutInfo* layout = calculator.GetClassLayoutInfo(il2cppType);
- auto& sizes = type.typeSizes;
- sizes.native_size = layout->nativeSize;
- if (typeDef->genericContainerIndex == kGenericContainerIndexInvalid)
- {
- sizes.static_fields_size = layout->staticFieldsSize;
- sizes.thread_static_fields_size = layout->threadStaticFieldsSize;
- }
- else
- {
- sizes.static_fields_size = 0;
- sizes.thread_static_fields_size = 0;
- }
- if (sizes.instance_size == 0)
- {
- sizes.instance_size = layout->instanceSize;
- }
- int32_t fieldStart = DecodeMetadataIndex(typeDef->fieldStart);
- for (int32_t i = 0, end = typeDef->field_count; i < end ; i++)
- {
- FieldDetail& fd = _fieldDetails[fieldStart + i];
- FieldLayout& fieldLayout = layout->fields[i];
- if (fd.offset == 0)
- {
- fd.offset = fieldLayout.offset;
- }
- else if (fd.offset == THREAD_LOCAL_STATIC_MASK)
- {
- fd.offset = fieldLayout.offset;
- }
- else
- {
- IL2CPP_ASSERT(fd.offset == fieldLayout.offset);
- int a = 0;
- }
- }
- }
- }
- uint32_t InterpreterImage::AddIl2CppTypeCache(const Il2CppType* type)
- {
- auto it = _type2Indexs.find(type);
- if (it != _type2Indexs.end())
- {
- return it->second;
- }
- uint32_t encodeIndex = EncodeWithIndex((uint32_t)_types.size());
- _types.push_back(type);
- _type2Indexs.insert({ type, encodeIndex });
- return encodeIndex;
- }
- uint32_t InterpreterImage::AddIl2CppGenericContainers(Il2CppGenericContainer& geneContainer)
- {
- uint32_t index = (uint32_t)_genericContainers.size();
- _genericContainers.push_back(geneContainer);
- return EncodeWithIndex(index);
- }
- void InterpreterImage::InitClass()
- {
- const Table& typeDefTb = _rawImage->GetTable(TableType::TYPEDEF);
- _classList.resize(typeDefTb.rowNum);
- }
- Il2CppClass* InterpreterImage::GetTypeInfoFromTypeDefinitionRawIndex(uint32_t index)
- {
- IL2CPP_ASSERT(index < _classList.size());
- Il2CppClass* klass = _classList[index];
- if (klass)
- {
- return klass;
- }
- il2cpp::os::FastAutoLock lock(&il2cpp::vm::g_MetadataLock);
- klass = _classList[index];
- if (klass)
- {
- return klass;
- }
- klass = il2cpp::vm::GlobalMetadata::FromTypeDefinition(EncodeWithIndex(index));
- IL2CPP_ASSERT(klass->interfaces_count <= klass->interface_offsets_count || _typesDefines[index].interfaceOffsetsStart == 0);
- il2cpp::os::Atomic::FullMemoryBarrier();
- _classList[index] = klass;
- return klass;
- }
- const Il2CppType* InterpreterImage::GetInterfaceFromGlobalOffset(TypeInterfaceIndex globalOffset)
- {
- IL2CPP_ASSERT((uint32_t)globalOffset < (uint32_t)_interfaceDefines.size());
- TypeIndex typeIndex = _interfaceDefines[globalOffset];
- if (typeIndex == kTypeIndexInvalid)
- {
- uint32_t rowIndex = globalOffset + 1;
- TbInterfaceImpl data = _rawImage->ReadInterfaceImpl(rowIndex);
- Il2CppTypeDefinition& typeDef = _typesDefines[data.classIdx - 1];
- const Il2CppType* intType = ReadTypeFromToken(GetGenericContainerByTypeDefinition(&typeDef), nullptr,
- DecodeTypeDefOrRefOrSpecCodedIndexTableType(data.interfaceIdx), DecodeTypeDefOrRefOrSpecCodedIndexRowIndex(data.interfaceIdx));
- _interfaceDefines[globalOffset] = typeIndex = DecodeMetadataIndex(AddIl2CppTypeCache(intType));
- }
- return _types[typeIndex];
- }
- const Il2CppType* InterpreterImage::GetInterfaceFromIndex(const Il2CppClass* klass, TypeInterfaceIndex globalOffset)
- {
- return GetInterfaceFromGlobalOffset(globalOffset);
- }
- const Il2CppType* InterpreterImage::GetInterfaceFromOffset(const Il2CppClass* klass, TypeInterfaceIndex offset)
- {
- const Il2CppTypeDefinition* typeDef = (const Il2CppTypeDefinition*)(klass->typeMetadataHandle);
- IL2CPP_ASSERT(typeDef);
- return GetInterfaceFromOffset(typeDef, offset);
- }
- const Il2CppType* InterpreterImage::GetInterfaceFromOffset(const Il2CppTypeDefinition* typeDef, TypeInterfaceIndex offset)
- {
- uint32_t globalOffset = typeDef->interfacesStart + offset;
- return GetInterfaceFromGlobalOffset(globalOffset);
- }
- Il2CppInterfaceOffsetInfo InterpreterImage::GetInterfaceOffsetInfo(const Il2CppTypeDefinition* typeDefine, TypeInterfaceOffsetIndex index)
- {
- uint32_t globalIndex = DecodeMetadataIndex((uint32_t)(typeDefine->interfaceOffsetsStart + index));
- IL2CPP_ASSERT(globalIndex < (uint32_t)_interfaceOffsets.size());
- InterfaceOffsetInfo& offsetPair = _interfaceOffsets[globalIndex];
- return { offsetPair.type, (int32_t)offsetPair.offset };
- }
- Il2CppClass* InterpreterImage::GetNestedTypeFromOffset(const Il2CppTypeDefinition* typeDefine, TypeNestedTypeIndex offset)
- {
- uint32_t globalIndex = typeDefine->nestedTypesStart + offset;
- IL2CPP_ASSERT(globalIndex < (uint32_t)_nestedTypeDefineIndexs.size());
- uint32_t typeDefIndex = _nestedTypeDefineIndexs[globalIndex];
- IL2CPP_ASSERT(typeDefIndex < (uint32_t)_typesDefines.size());
- return il2cpp::vm::GlobalMetadata::GetTypeInfoFromHandle((Il2CppMetadataTypeHandle)&_typesDefines[typeDefIndex]);
- }
- Il2CppClass* InterpreterImage::GetNestedTypeFromOffset(const Il2CppClass* klass, TypeNestedTypeIndex offset)
- {
- return GetNestedTypeFromOffset((Il2CppTypeDefinition*)klass->typeMetadataHandle, offset);
- }
- Il2CppTypeDefinition* InterpreterImage::GetNestedTypes(Il2CppTypeDefinition* typeDefinition, void** iter)
- {
- if (_nestedTypeDefineIndexs.empty())
- {
- return nullptr;
- }
- const TypeDefinitionIndex* nestedTypeIndices = (const TypeDefinitionIndex*)(&_nestedTypeDefineIndexs[typeDefinition->nestedTypesStart]);
- if (!*iter)
- {
- if (typeDefinition->nested_type_count == 0)
- return NULL;
- *iter = (void*)(nestedTypeIndices);
- return &_typesDefines[nestedTypeIndices[0]];
- }
- TypeDefinitionIndex* nestedTypeAddress = (TypeDefinitionIndex*)*iter;
- nestedTypeAddress++;
- ptrdiff_t index = nestedTypeAddress - nestedTypeIndices;
- if (index < typeDefinition->nested_type_count)
- {
- *iter = nestedTypeAddress;
- return &_typesDefines[*nestedTypeAddress];
- }
- return NULL;
- }
- const Il2CppAssembly* InterpreterImage::GetReferencedAssembly(int32_t referencedAssemblyTableIndex, const Il2CppAssembly assembliesTable[], int assembliesCount)
- {
- auto& table = _rawImage->GetTable(TableType::ASSEMBLYREF);
- IL2CPP_ASSERT((uint32_t)referencedAssemblyTableIndex < table.rowNum);
- TbAssemblyRef assRef = _rawImage->ReadAssemblyRef(referencedAssemblyTableIndex + 1);
- const char* refAssName = _rawImage->GetStringFromRawIndex(assRef.name);
- const Il2CppAssembly* il2cppAssRef = il2cpp::vm::Assembly::GetLoadedAssembly(refAssName);
- if (!il2cppAssRef)
- {
- il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetDllNotFoundException(refAssName));
- }
- return il2cppAssRef;
- }
- void InterpreterImage::ReadFieldRefInfoFromFieldDefToken(uint32_t rowIndex, FieldRefInfo& ret)
- {
- IL2CPP_ASSERT(rowIndex > 0);
- const FieldDetail& fd = GetFieldDetailFromRawIndex(rowIndex - 1);
- ret.containerType = GetIl2CppTypeFromRawTypeDefIndex(DecodeMetadataIndex(fd.typeDefIndex));
- ret.field = &fd.fieldDef;
- }
- void InterpreterImage::GetClassAndMethodGenericContainerFromGenericContainerIndex(GenericContainerIndex idx, const Il2CppGenericContainer*& klassGc, const Il2CppGenericContainer*& methodGc)
- {
- Il2CppGenericContainer* gc = GetGenericContainerByRawIndex(DecodeMetadataIndex(idx));
- IL2CPP_ASSERT(gc);
- if (gc->is_method)
- {
- const Il2CppMethodDefinition* methodDef = GetMethodDefinitionFromRawIndex(DecodeMetadataIndex(gc->ownerIndex));
- klassGc = GetGenericContainerByTypeDefRawIndex(DecodeMetadataIndex(methodDef->declaringType));
- methodGc = GetGenericContainerByRawIndex(DecodeMetadataIndex(methodDef->genericContainerIndex));
- }
- else
- {
- klassGc = gc;
- methodGc = nullptr;
- }
- }
- void InterpreterImage::InitGenericParamConstraintDefs()
- {
- const Table& tb = _rawImage->GetTable(TableType::GENERICPARAMCONSTRAINT);
- _genericConstraints.resize(tb.rowNum, kTypeIndexInvalid);
- for (uint32_t i = 0; i < tb.rowNum; i++)
- {
- uint32_t rowIndex = i + 1;
- TbGenericParamConstraint data = _rawImage->ReadGenericParamConstraint(rowIndex);
- Il2CppGenericParameter& genericParam = _genericParams[data.owner - 1];
- if (genericParam.constraintsCount == 0)
- {
- genericParam.constraintsStart = EncodeWithIndex(i);
- }
- ++genericParam.constraintsCount;
- //_genericConstraints[i] == kTypeIndexInvalid;
- //Il2CppType paramCons = {};
- //const Il2CppGenericContainer* klassGc;
- //const Il2CppGenericContainer* methodGc;
- //GetClassAndMethodGenericContainerFromGenericContainerIndex(genericParam.ownerIndex, klassGc, methodGc);
- //ReadTypeFromToken(klassGc, methodGc, DecodeTypeDefOrRefOrSpecCodedIndexTableType(data.constraint), DecodeTypeDefOrRefOrSpecCodedIndexRowIndex(data.constraint), paramCons);
- //_genericConstraints[i] = DecodeMetadataIndex(AddIl2CppTypeCache(paramCons));
- }
- }
- void InterpreterImage::InitGenericParamDefs0()
- {
- const Table& tb = _rawImage->GetTable(TableType::GENERICPARAM);
- _genericParams.resize(tb.rowNum);
- }
- void InterpreterImage::InitGenericParamDefs()
- {
- const Table& tb = _rawImage->GetTable(TableType::GENERICPARAM);
- for (uint32_t i = 0; i < tb.rowNum; i++)
- {
- uint32_t rowIndex = i + 1;
- TbGenericParam data = _rawImage->ReadGenericParam(rowIndex);
- Il2CppGenericParameter& paramDef = _genericParams[i];
- paramDef.num = data.number;
- paramDef.flags = data.flags;
- paramDef.nameIndex = EncodeWithIndex(data.name);
- // constraintsStart 和 constrantsCount init at InitGenericParamConstrains() latter
- TableType ownerType = DecodeTypeOrMethodDefCodedIndexTableType(data.owner);
- uint32_t ownerIndex = DecodeTypeOrMethodDefCodedIndexRowIndex(data.owner);
- IL2CPP_ASSERT(ownerIndex > 0);
- Il2CppGenericContainer* geneContainer;
- int32_t interIndex = ownerIndex - 1;
- if (ownerType == TableType::TYPEDEF)
- {
- Il2CppTypeDefinition& typeDef = _typesDefines[interIndex];
- if (typeDef.genericContainerIndex == kGenericContainerIndexInvalid)
- {
- Il2CppGenericContainer c = {};
- c.ownerIndex = EncodeWithIndex(interIndex);
- c.is_method = false;
- typeDef.genericContainerIndex = AddIl2CppGenericContainers(c);
- }
- geneContainer = &_genericContainers[DecodeMetadataIndex(typeDef.genericContainerIndex)];
- paramDef.ownerIndex = typeDef.genericContainerIndex;
- }
- else
- {
- Il2CppMethodDefinition& methodDef = _methodDefines[interIndex];
- if (methodDef.genericContainerIndex == kGenericContainerIndexInvalid)
- {
- Il2CppGenericContainer c = {};
- c.ownerIndex = EncodeWithIndex(interIndex);
- c.is_method = true;
- methodDef.genericContainerIndex = AddIl2CppGenericContainers(c);
- }
- geneContainer = &_genericContainers[DecodeMetadataIndex(methodDef.genericContainerIndex)];
- paramDef.ownerIndex = methodDef.genericContainerIndex;
- }
- if (geneContainer->type_argc == 0)
- {
- geneContainer->genericParameterStart = EncodeWithIndex(i);
- }
- ++geneContainer->type_argc;
- }
- }
- void InterpreterImage::InitInterfaces()
- {
- const Table& table = _rawImage->GetTable(TableType::INTERFACEIMPL);
- // interface中只包含直接继承的interface,不包括来自父类的
- // 此interface只在CastClass及Type.GetInterfaces()反射函数中
- // 发挥作用,不在callvir中发挥作用。
- // interfaceOffsets中包含了水平展开的所有interface(包括父类的)
- _interfaceDefines.resize(table.rowNum, kTypeIndexInvalid);
- uint32_t lastClassIdx = 0;
- for (uint32_t i = 0; i < table.rowNum; i++)
- {
- uint32_t rowIndex = i + 1;
- TbInterfaceImpl data = _rawImage->ReadInterfaceImpl(rowIndex);
- Il2CppTypeDefinition& typeDef = _typesDefines[data.classIdx - 1];
- //Il2CppType intType = {};
- //ReadTypeFromToken(GetGenericContainerByTypeDefinition(&typeDef), nullptr,
- // DecodeTypeDefOrRefOrSpecCodedIndexTableType(data.interfaceIdx), DecodeTypeDefOrRefOrSpecCodedIndexRowIndex(data.interfaceIdx), intType);
- //_interfaceDefines[i] = DecodeMetadataIndex(AddIl2CppTypeCache(intType));
- if (typeDef.interfaces_count == 0)
- {
- typeDef.interfacesStart = (InterfacesIndex)i;
- }
- else
- {
- // 必须连续
- IL2CPP_ASSERT(data.classIdx == lastClassIdx);
- }
- ++typeDef.interfaces_count;
- lastClassIdx = data.classIdx;
- }
- }
- void InterpreterImage::ComputeVTable(TypeDefinitionDetail* tdd)
- {
- Il2CppTypeDefinition& typeDef = *GetTypeDefinitionByTypeDetail(tdd);
- if (IsInterface(typeDef.flags) || typeDef.interfaceOffsetsStart != 0)
- {
- return;
- }
- if (typeDef.parentIndex != kInvalidIndex)
- {
- const Il2CppType* parentType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(typeDef.parentIndex);
- const Il2CppTypeDefinition* parentTypeDef = GetUnderlyingTypeDefinition(parentType);
- if (IsInterpreterType(parentTypeDef) && parentTypeDef->interfaceOffsetsStart == 0)
- {
- IL2CPP_ASSERT(DecodeImageIndex(parentTypeDef->byvalTypeIndex) == this->GetIndex());
- int32_t typeDefIndex = GetTypeRawIndexByEncodedIl2CppTypeIndex(parentTypeDef->byvalTypeIndex);
- ComputeVTable(&_typeDetails[typeDefIndex]);
- }
- }
- const Il2CppType* type = GetIl2CppTypeFromRawIndex(DecodeMetadataIndex(typeDef.byvalTypeIndex));
- VTableSetUp* typeTree = VTableSetUp::BuildByType(_cacheTrees, type);
- uint32_t offsetsStart = (uint32_t)_interfaceOffsets.size();
- auto& vms = typeTree->GetVirtualMethodImpls();
- if (vms.empty())
- {
- tdd->vtable = nullptr;
- tdd->vtableCount = 0;
- }
- else
- {
- tdd->vtable = (VirtualMethodImpl*)HYBRIDCLR_METADATA_CALLOC(vms.size(), sizeof(VirtualMethodImpl));
- tdd->vtableCount = (uint32_t)vms.size();
- std::memcpy(tdd->vtable, &vms[0], vms.size() * sizeof(VirtualMethodImpl));
- }
- auto& interfaceOffsetInfos = typeTree->GetInterfaceOffsetInfos();
- for (auto ioi : interfaceOffsetInfos)
- {
- _interfaceOffsets.push_back({ ioi.type, ioi.offset });
- }
- typeDef.vtableStart = EncodeWithIndex(0);
- typeDef.vtable_count = (uint16_t)vms.size();
- typeDef.interfaceOffsetsStart = EncodeWithIndex(offsetsStart);
- typeDef.interface_offsets_count = (uint16_t)interfaceOffsetInfos.size();
- Il2CppClass* klass = _classList[GetTypeRawIndex(&typeDef)];
- IL2CPP_ASSERT(!klass);
- }
- void InterpreterImage::InitVTables()
- {
- const Table& typeDefTb = _rawImage->GetTable(TableType::TYPEDEF);
- for (TypeDefinitionDetail& td : _typeDetails)
- {
- ComputeVTable(&td);
- }
- for (auto& e : _cacheTrees)
- {
- e.second->~VTableSetUp();
- HYBRIDCLR_FREE(e.second);
- }
- Il2CppType2TypeDeclaringTreeMap temp;
- _cacheTrees.swap(temp);
- }
- // index => MethodDefinition -> DeclaringClass -> index - klass->methodStart -> MethodInfo*
- const MethodInfo* InterpreterImage::GetMethodInfoFromMethodDefinitionRawIndex(uint32_t index)
- {
- IL2CPP_ASSERT((size_t)index <= _methodDefines.size());
- const Il2CppMethodDefinition* methodDefinition = GetMethodDefinitionFromRawIndex(index);
- const Il2CppTypeDefinition* typeDefinition = (const Il2CppTypeDefinition*)il2cpp::vm::GlobalMetadata::GetTypeHandleFromIndex(methodDefinition->declaringType);
- int32_t indexInClass = index - DecodeMetadataIndex(typeDefinition->methodStart);
- IL2CPP_ASSERT(indexInClass >= 0 && indexInClass < typeDefinition->method_count);
- Il2CppClass* klass = il2cpp::vm::GlobalMetadata::GetTypeInfoFromHandle((Il2CppMetadataTypeHandle)typeDefinition);
- il2cpp::vm::Class::SetupMethods(klass);
- return klass->methods[indexInClass];
- }
- const MethodInfo* InterpreterImage::GetMethodInfoFromMethodDefinition(const Il2CppMethodDefinition* methodDef)
- {
- uint32_t rawIndex = (uint32_t)(methodDef - &_methodDefines[0]);
- IL2CPP_ASSERT(rawIndex < (uint32_t)_methodDefines.size());
- return GetMethodInfoFromMethodDefinitionRawIndex(rawIndex);
- }
- // typeDef vTableSlot -> type virtual method index -> MethodDefinition*
- const Il2CppMethodDefinition* InterpreterImage::GetMethodDefinitionFromVTableSlot(const Il2CppTypeDefinition* typeDef, int32_t vTableSlot)
- {
- uint32_t typeDefIndex = GetTypeRawIndex(typeDef);
- IL2CPP_ASSERT(typeDefIndex < (uint32_t)_typeDetails.size());
- TypeDefinitionDetail& td = _typeDetails[typeDefIndex];
- IL2CPP_ASSERT(vTableSlot >= 0 && vTableSlot < (int32_t)td.vtableCount);
- VirtualMethodImpl& vmi = td.vtable[vTableSlot];
- return vmi.method;
- }
- const MethodInfo* InterpreterImage::GetMethodInfoFromVTableSlot(const Il2CppClass* klass, int32_t vTableSlot)
- {
- IL2CPP_ASSERT(!klass->generic_class);
- const Il2CppTypeDefinition* typeDef = (Il2CppTypeDefinition*)klass->typeMetadataHandle;
- //const Il2CppMethodDefinition* methodDef = GetMethodDefinitionFromVTableSlot((Il2CppTypeDefinition*)klass->typeMetadataHandle, vTableSlot);
- // FIX ME. why return null?
- //IL2CPP_ASSERT(methodDef);
- uint32_t typeDefIndex = GetTypeRawIndex(typeDef);
- IL2CPP_ASSERT(typeDefIndex < (uint32_t)_typeDetails.size());
- TypeDefinitionDetail& td = _typeDetails[typeDefIndex];
- IL2CPP_ASSERT(vTableSlot >= 0 && vTableSlot < (int32_t)td.vtableCount);
- VirtualMethodImpl& vmi = td.vtable[vTableSlot];
- if (vmi.method)
- {
- if (vmi.method->declaringType == EncodeWithIndex(typeDefIndex))
- {
- return il2cpp::vm::GlobalMetadata::GetMethodInfoFromMethodHandle((Il2CppMetadataMethodDefinitionHandle)vmi.method);
- }
- else
- {
- Il2CppClass* implClass = il2cpp::vm::Class::FromIl2CppType(vmi.type);
- IL2CPP_ASSERT(implClass != klass);
- il2cpp::vm::Class::SetupMethods(implClass);
- for (uint32_t i = 0; i < implClass->method_count; i++)
- {
- const MethodInfo* implMethod = implClass->methods[i];
- if (implMethod->token == vmi.method->token)
- {
- return implMethod;
- }
- }
- RaiseExecutionEngineException("not find vtable method");
- }
- }
- return nullptr;
- }
- Il2CppMethodPointer InterpreterImage::GetAdjustorThunk(uint32_t token)
- {
- uint32_t methodIndex = DecodeTokenRowIndex(token) - 1;
- IL2CPP_ASSERT(methodIndex < (uint32_t)_methodDefines.size());
- const Il2CppMethodDefinition* methodDef = &_methodDefines[methodIndex];
- return IsInstanceMethod(methodDef) ? hybridclr::interpreter::InterpreterModule::GetAdjustThunkMethodPointer(methodDef) : nullptr;
- }
- Il2CppMethodPointer InterpreterImage::GetMethodPointer(uint32_t token)
- {
- uint32_t methodIndex = DecodeTokenRowIndex(token) - 1;
- IL2CPP_ASSERT(methodIndex < (uint32_t)_methodDefines.size());
- const Il2CppMethodDefinition* methodDef = &_methodDefines[methodIndex];
- return hybridclr::interpreter::InterpreterModule::GetMethodPointer(methodDef);
- }
- InvokerMethod InterpreterImage::GetMethodInvoker(uint32_t token)
- {
- uint32_t methodIndex = DecodeTokenRowIndex(token) - 1;
- IL2CPP_ASSERT(methodIndex < (uint32_t)_methodDefines.size());
- const Il2CppMethodDefinition* methodDef = &_methodDefines[methodIndex];
- return hybridclr::interpreter::InterpreterModule::GetMethodInvoker(methodDef);
- }
- Il2CppString* InterpreterImage::ReadSerString(BlobReader& reader)
- {
- byte b = reader.PeekByte();
- if (b == 0xFF)
- {
- reader.SkipByte();
- return nullptr;
- }
- else if (b == 0)
- {
- reader.SkipByte();
- return il2cpp::vm::String::Empty();
- }
- else
- {
- uint32_t len = reader.ReadCompressedUint32();
- #if !HYBRIDCLR_UNITY_2021_OR_NEW
- return il2cpp::vm::String::NewLen((char*)reader.GetAndSkipCurBytes(len), len);
- #else
- char* chars = (char*)reader.GetDataOfReadPosition();
- reader.SkipBytes(len);
- return il2cpp::vm::String::NewLen(chars, len);
- #endif
- }
- }
- #if HYBRIDCLR_UNITY_2021_OR_NEW
- bool InterpreterImage::ReadUTF8SerString(BlobReader& reader, std::string& s)
- {
- byte b = reader.PeekByte();
- if (b == 0xFF)
- {
- reader.SkipByte();
- return false;
- }
- else if (b == 0)
- {
- reader.SkipByte();
- s.clear();
- return true;
- }
- else
- {
- uint32_t len = reader.ReadCompressedUint32();
- char* chars = (char*)reader.GetDataOfReadPosition();
- reader.SkipBytes(len);
- s.assign(chars, len);
- return true;
- }
- }
- #endif
- Il2CppReflectionType* InterpreterImage::ReadSystemType(BlobReader& reader)
- {
- Il2CppString* fullName = ReadSerString(reader);
- if (!fullName)
- {
- return nullptr;
- }
- Il2CppReflectionType* type = GetReflectionTypeFromName(fullName);
- if (!type)
- {
- std::string stdTypeName = il2cpp::utils::StringUtils::Utf16ToUtf8(fullName->chars);
- TEMP_FORMAT(errMsg, "CustomAttribute fixed arg type:System.Type fullName:'%s' not find", stdTypeName.c_str());
- il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetTypeLoadException(errMsg));
- }
- return type;
- }
- Il2CppObject* InterpreterImage::ReadBoxedValue(BlobReader& reader)
- {
- uint64_t obj = 0;
- Il2CppType kind = {};
- ReadCustomAttributeFieldOrPropType(reader, kind);
- ReadFixedArg(reader, &kind, &obj);
- Il2CppClass* valueType = il2cpp::vm::Class::FromIl2CppType(&kind);
- return il2cpp::vm::Object::Box(valueType, &obj);
- }
- void InterpreterImage::ReadFixedArg(BlobReader& reader, const Il2CppType* argType, void* data)
- {
- switch (argType->type)
- {
- case IL2CPP_TYPE_BOOLEAN:
- {
- *(byte*)data = reader.ReadByte();
- break;
- }
- case IL2CPP_TYPE_CHAR:
- {
- *(uint16_t*)data = reader.Read16();
- break;
- }
- case IL2CPP_TYPE_I1:
- case IL2CPP_TYPE_U1:
- {
- *(byte*)data = reader.ReadByte();
- break;
- }
- case IL2CPP_TYPE_I2:
- case IL2CPP_TYPE_U2:
- {
- *(uint16_t*)data = reader.Read16();
- break;
- }
- case IL2CPP_TYPE_I4:
- case IL2CPP_TYPE_U4:
- {
- *(uint32_t*)data = reader.Read32();
- break;
- }
- case IL2CPP_TYPE_I8:
- case IL2CPP_TYPE_U8:
- {
- *(uint64_t*)data = reader.Read64();
- break;
- }
- case IL2CPP_TYPE_R4:
- {
- *(float*)data = reader.ReadFloat();
- break;
- }
- case IL2CPP_TYPE_R8:
- {
- *(double*)data = reader.ReadDouble();
- break;
- }
- case IL2CPP_TYPE_SZARRAY:
- {
- uint32_t numElem = reader.Read32();
- if (numElem != (uint32_t)-1)
- {
- Il2CppClass* arrKlass = il2cpp::vm::Class::FromIl2CppType(argType);
- Il2CppArray* arr = il2cpp::vm::Array::New(il2cpp::vm::Class::GetElementClass(arrKlass), numElem);
- for (uint16_t i = 0; i < numElem; i++)
- {
- ReadFixedArg(reader, argType->data.type, GET_ARRAY_ELEMENT_ADDRESS(arr, i, arr->klass->element_size));
- }
- *(void**)data = arr;
- }
- else
- {
- *(void**)data = nullptr;
- }
- HYBRIDCLR_SET_WRITE_BARRIER((void**)data);
- break;
- }
- case IL2CPP_TYPE_STRING:
- {
- *(Il2CppString**)data = ReadSerString(reader);
- HYBRIDCLR_SET_WRITE_BARRIER((void**)data);
- break;
- }
- case IL2CPP_TYPE_OBJECT:
- {
- *(Il2CppObject**)data = ReadBoxedValue(reader);
- HYBRIDCLR_SET_WRITE_BARRIER((void**)data);
- break;
- }
- case IL2CPP_TYPE_CLASS:
- {
- Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(argType);
- if (!klass)
- {
- RaiseExecutionEngineException("type not find");
- }
- if (klass == il2cpp_defaults.object_class)
- {
- *(Il2CppObject**)data = ReadBoxedValue(reader);
- }
- else if (klass == il2cpp_defaults.systemtype_class)
- {
- *(Il2CppReflectionType**)data = ReadSystemType(reader);
- }
- else
- {
- TEMP_FORMAT(errMsg, "fixed arg type:%s.%s not support", klass->namespaze, klass->name);
- RaiseNotSupportedException(errMsg);
- }
- HYBRIDCLR_SET_WRITE_BARRIER((void**)data);
- break;
- }
- case IL2CPP_TYPE_VALUETYPE:
- {
- Il2CppClass* valueType = il2cpp::vm::Class::FromIl2CppType(argType);
- IL2CPP_ASSERT(valueType->enumtype);
- ReadFixedArg(reader, &valueType->element_class->byval_arg, data);
- break;
- }
- case IL2CPP_TYPE_SYSTEM_TYPE:
- {
- *(Il2CppReflectionType**)data = ReadSystemType(reader);
- HYBRIDCLR_SET_WRITE_BARRIER((void**)data);
- break;
- }
- case IL2CPP_TYPE_BOXED_OBJECT:
- {
- uint8_t fieldOrPropType = reader.ReadByte();
- IL2CPP_ASSERT(fieldOrPropType == 0x51);
- *(Il2CppObject**)data = ReadBoxedValue(reader);
- HYBRIDCLR_SET_WRITE_BARRIER((void**)data);
- break;
- }
- case IL2CPP_TYPE_ENUM:
- {
- Il2CppClass* valueType = il2cpp::vm::Class::FromIl2CppType(argType);
- IL2CPP_ASSERT(valueType->enumtype);
- ReadFixedArg(reader, &valueType->element_class->byval_arg, data);
- break;
- }
- default:
- {
- RaiseExecutionEngineException("not support fixed argument type");
- }
- }
- }
- void InterpreterImage::ReadCustomAttributeFieldOrPropType(BlobReader& reader, Il2CppType& type)
- {
- type.type = (Il2CppTypeEnum)reader.ReadByte();
- switch (type.type)
- {
- 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_STRING:
- {
- break;
- }
- case IL2CPP_TYPE_SZARRAY:
- {
- Il2CppType eleType = {};
- ReadCustomAttributeFieldOrPropType(reader, eleType);
- type.data.type = MetadataPool::GetPooledIl2CppType(eleType);
- break;
- }
- case IL2CPP_TYPE_ENUM:
- {
- Il2CppString* enumTypeName = ReadSerString(reader);
- Il2CppReflectionType* enumType = GetReflectionTypeFromName(enumTypeName);
- if (!enumType)
- {
- std::string stdStrName = il2cpp::utils::StringUtils::Utf16ToUtf8(enumTypeName->chars);
- TEMP_FORMAT(errMsg, "ReadCustomAttributeFieldOrPropType enum:'%s' not exists", stdStrName.c_str());
- RaiseExecutionEngineException(errMsg);
- }
- type = *enumType->type;
- break;
- }
- case IL2CPP_TYPE_SYSTEM_TYPE:
- {
- type = il2cpp_defaults.systemtype_class->byval_arg;
- break;
- }
- case IL2CPP_TYPE_BOXED_OBJECT:
- {
- type = il2cpp_defaults.object_class->byval_arg;
- break;
- }
- default:
- {
- TEMP_FORMAT(errMsg, "ReadCustomAttributeFieldOrPropType. image:%s unknown type:%d", GetIl2CppImage()->name, (int)type.type);
- RaiseBadImageException(errMsg);
- }
- }
- }
- void InterpreterImage::ReadMethodDefSig(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, Il2CppMethodDefinition& methodDef, std::vector<ParamDetail>& paramArr)
- {
- uint8_t rawSigFlags = reader.ReadByte();
- if (rawSigFlags & (uint8_t)MethodSigFlags::GENERIC)
- {
- //IL2CPP_ASSERT(false);
- uint32_t genParamCount = reader.ReadCompressedUint32();
- Il2CppGenericContainer* gc = GetGenericContainerByRawIndex(DecodeMetadataIndex(methodDef.genericContainerIndex));
- IL2CPP_ASSERT(gc->type_argc == genParamCount);
- }
- uint32_t paramCount = reader.ReadCompressedUint32();
- //IL2CPP_ASSERT(paramCount >= methodDef.parameterCount);
- const Il2CppType* returnType = ReadType(reader, klassGenericContainer, methodGenericContainer);
- methodDef.returnType = AddIl2CppTypeCache(returnType);
- int readParamNum = 0;
- for (; reader.NonEmpty(); )
- {
- ParamDetail curParam = {};
- const Il2CppType* type = ReadType(reader, klassGenericContainer, methodGenericContainer);
- curParam.parameterIndex = readParamNum++;
- curParam.paramDef.typeIndex = AddIl2CppTypeCache(type);
- paramArr.push_back(curParam);
- }
- IL2CPP_ASSERT(readParamNum == (int)paramCount);
- }
- const Il2CppType* InterpreterImage::GetModuleIl2CppType(uint32_t moduleRowIndex, uint32_t typeNamespace, uint32_t typeName, bool raiseExceptionIfNotFound)
- {
- IL2CPP_ASSERT(moduleRowIndex == 1);
- uint32_t encodedNamespaceIndex = EncodeWithIndex(typeNamespace);
- uint32_t encodedNameIndex = EncodeWithIndex(typeName);
- for (TypeDefinitionDetail& type : _typeDetails)
- {
- Il2CppTypeDefinition* typeDef = GetTypeDefinitionByTypeDetail(&type);
- if (typeDef->namespaceIndex == encodedNamespaceIndex && typeDef->nameIndex == encodedNameIndex)
- {
- return GetIl2CppTypeFromTypeDefinition(typeDef);
- }
- }
- if (!raiseExceptionIfNotFound)
- {
- return nullptr;
- }
- const char* typeNameStr = _rawImage->GetStringFromRawIndex(typeName);
- const char* typeNamespaceStr = _rawImage->GetStringFromRawIndex(typeNamespace);
- il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetTypeLoadException(
- CStringToStringView(typeNamespaceStr),
- CStringToStringView(typeNameStr),
- CStringToStringView(_il2cppImage->nameNoExt)));
- return nullptr;
- }
- }
- }
|