InterpreterImage.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. #pragma once
  2. #include <unordered_map>
  3. #if HYBRIDCLR_UNITY_2021_OR_NEW
  4. #include "metadata/CustomAttributeDataReader.h"
  5. #include "CustomAttributeDataWriter.h"
  6. #endif
  7. #include "Image.h"
  8. #include "CustomAttributeDataWriter.h"
  9. namespace hybridclr
  10. {
  11. namespace metadata
  12. {
  13. struct InterfaceOffsetInfo
  14. {
  15. const Il2CppType* type;
  16. uint32_t offset;
  17. };
  18. struct TypeDefinitionDetail
  19. {
  20. uint32_t methodImplStart;
  21. uint32_t methodImplCount;
  22. uint32_t vtableCount;
  23. Il2CppTypeDefinitionSizes typeSizes;
  24. VirtualMethodImpl* vtable;
  25. };
  26. struct ParamDetail
  27. {
  28. Il2CppParameterDefinition paramDef;
  29. uint32_t parameterIndex;
  30. uint32_t defaultValueIndex; // -1 for invalid
  31. };
  32. struct FieldDetail
  33. {
  34. Il2CppFieldDefinition fieldDef;
  35. uint32_t typeDefIndex;
  36. uint32_t offset;
  37. uint32_t defaultValueIndex; // -1 for invalid
  38. };
  39. struct PropertyDetail
  40. {
  41. const char* name;
  42. uint16_t flags;
  43. uint32_t signatureBlobIndex;
  44. uint32_t getterMethodIndex; // start from 1;
  45. uint32_t setterMethodIndex;
  46. const Il2CppTypeDefinition* declaringType;
  47. Il2CppPropertyDefinition il2cppDefinition;
  48. };
  49. struct EventDetail
  50. {
  51. const char* name;
  52. uint16_t eventFlags;
  53. uint32_t eventType; // TypeDefOrRef codedIndex
  54. uint32_t addMethodIndex; // start from 1
  55. uint32_t removeMethodIndex; // start from 1
  56. uint32_t fireMethodIndex; // start from 1;
  57. #if HYBRIDCLR_UNITY_2019
  58. const Il2CppTypeDefinition* declaringType;
  59. Il2CppEventDefinition il2cppDefinition;
  60. #endif
  61. };
  62. struct CustomAttribute
  63. {
  64. uint32_t ctorMethodToken;
  65. uint32_t value;
  66. };
  67. struct CustomAttributesInfo
  68. {
  69. int32_t typeRangeIndex;
  70. bool inited;
  71. void* dataStartPtr;
  72. void* dataEndPtr;
  73. };
  74. #if HYBRIDCLR_UNITY_2021_OR_NEW
  75. enum class BlobSource
  76. {
  77. RAW_IMAGE = 0,
  78. CONVERTED_IL2CPP_FORMAT = 1,
  79. };
  80. #endif
  81. class InterpreterImage : public Image
  82. {
  83. public:
  84. static void Initialize();
  85. static uint32_t AllocImageIndex(uint32_t dllLength);
  86. static void RegisterImage(InterpreterImage* image);
  87. static InterpreterImage* GetImage(uint32_t imageIndex)
  88. {
  89. //os::FastAutoLock lock(&s_imageLock);
  90. IL2CPP_ASSERT(imageIndex < kMaxMetadataImageCount);
  91. return s_images[imageIndex];
  92. }
  93. private:
  94. static InterpreterImage* s_images[kMaxMetadataImageCount];
  95. public:
  96. InterpreterImage(uint32_t imageIndex) : _index(imageIndex), _inited(false), _il2cppImage(nullptr)
  97. #if HYBRIDCLR_UNITY_2021_OR_NEW
  98. , _constValues(1024), _il2cppFormatCustomDataBlob(256), _tempCtorArgBlob(256), _tempFieldBlob(256), _tempPropertyBlob(256)
  99. #endif
  100. {
  101. }
  102. LoadImageErrorCode Load(const void* imageData, size_t length)
  103. {
  104. if (_inited)
  105. {
  106. RaiseExecutionEngineException("image can't be inited again");
  107. }
  108. _inited = true;
  109. _rawImage = new RawImage();
  110. LoadImageErrorCode err = _rawImage->Load(imageData, length);
  111. if (err != LoadImageErrorCode::OK)
  112. {
  113. delete _rawImage;
  114. _rawImage = nullptr;
  115. return err;
  116. }
  117. return LoadImageErrorCode::OK;
  118. }
  119. bool IsInitialized() const
  120. {
  121. return _inited;
  122. }
  123. uint32_t GetIndex() const
  124. {
  125. return _index;
  126. }
  127. const Il2CppImage* GetIl2CppImage() const
  128. {
  129. return _il2cppImage;
  130. }
  131. uint32_t EncodeWithIndex(uint32_t rawIndex) const
  132. {
  133. return EncodeImageAndMetadataIndex(_index, rawIndex);
  134. }
  135. uint32_t EncodeWithIndexExcept0(uint32_t rawIndex) const
  136. {
  137. return rawIndex != 0 ? EncodeImageAndMetadataIndex(_index, rawIndex) : 0;
  138. }
  139. MethodBody* GetMethodBody(uint32_t token) override
  140. {
  141. IL2CPP_ASSERT(DecodeTokenTableType(token) == TableType::METHOD);
  142. uint32_t rowIndex = DecodeTokenRowIndex(token);
  143. IL2CPP_ASSERT(rowIndex > 0 && rowIndex <= (uint32_t)_methodDefines.size());
  144. const Il2CppMethodDefinition* methodDef = &_methodDefines[rowIndex - 1];
  145. bool isGenericMethod = methodDef->genericContainerIndex != kGenericContainerIndexInvalid || _typesDefines[DecodeMetadataIndex(methodDef->declaringType)].genericContainerIndex != kGenericContainerIndexInvalid;
  146. TbMethod methodData = _rawImage->ReadMethod(rowIndex);
  147. MethodBody* resultMethodBody = new (HYBRIDCLR_MALLOC_ZERO(sizeof(MethodBody))) MethodBody();
  148. ReadMethodBody(*methodDef, methodData, *resultMethodBody);
  149. return resultMethodBody;
  150. }
  151. // type index start from 0, difference with table index...
  152. Il2CppMetadataTypeHandle GetAssemblyTypeHandleFromRawIndex(AssemblyTypeIndex index) const
  153. {
  154. IL2CPP_ASSERT(DecodeImageIndex(index) == 0);
  155. IL2CPP_ASSERT(index >= 0 && (size_t)index < _typesDefines.size());
  156. return (Il2CppMetadataTypeHandle)&_typesDefines[index];
  157. }
  158. Il2CppMetadataTypeHandle GetAssemblyExportedTypeHandleFromRawIndex(AssemblyTypeIndex index) const
  159. {
  160. IL2CPP_ASSERT(DecodeImageIndex(index) == 0);
  161. IL2CPP_ASSERT(index >= 0 && (size_t)index < _typesDefines.size());
  162. return (Il2CppMetadataTypeHandle)&_exportedTypeDefines[index];
  163. }
  164. const Il2CppTypeDefinitionSizes* GetTypeDefinitionSizesFromRawIndex(TypeDefinitionIndex index)
  165. {
  166. IL2CPP_ASSERT((size_t)index < _typeDetails.size());
  167. return &_typeDetails[index].typeSizes;
  168. }
  169. const char* GetStringFromRawIndex(StringIndex index) const
  170. {
  171. IL2CPP_ASSERT(DecodeImageIndex(index) == 0);
  172. return _rawImage->GetStringFromRawIndex(index);
  173. }
  174. uint32_t GetTypeRawIndex(const Il2CppTypeDefinition* typeDef) const
  175. {
  176. return (uint32_t)(typeDef - &_typesDefines[0]);
  177. }
  178. Il2CppTypeDefinition* GetTypeDefinitionByTypeDetail(const TypeDefinitionDetail* typeDetail)
  179. {
  180. uint32_t index = (uint32_t)(typeDetail - &_typeDetails[0]);
  181. return &_typesDefines[index];
  182. }
  183. uint32_t GetTypeRawIndexByEncodedIl2CppTypeIndex(int32_t il2cppTypeIndex) const
  184. {
  185. return GetTypeRawIndex((const Il2CppTypeDefinition*)_types[DecodeMetadataIndex(il2cppTypeIndex)]->data.typeHandle);
  186. }
  187. const Il2CppTypeDefinition* GetTypeFromRawIndex(uint32_t index) const
  188. {
  189. IL2CPP_ASSERT((size_t)index < _typesDefines.size());
  190. return &_typesDefines[index];
  191. }
  192. const Il2CppType* GetIl2CppTypeFromRawIndex(uint32_t index) const
  193. {
  194. IL2CPP_ASSERT((size_t)index < _types.size());
  195. return _types[index];
  196. }
  197. const Il2CppType* GetIl2CppTypeFromRawTypeDefIndex(uint32_t index) override
  198. {
  199. IL2CPP_ASSERT(index < (uint32_t)_typesDefines.size());
  200. return _types[DecodeMetadataIndex(_typesDefines[index].byvalTypeIndex)];
  201. }
  202. const Il2CppFieldDefinition* GetFieldDefinitionFromRawIndex(uint32_t index)
  203. {
  204. IL2CPP_ASSERT(index < (uint32_t)_fieldDetails.size());
  205. return &(_fieldDetails[index].fieldDef);
  206. }
  207. const FieldDetail& GetFieldDetailFromRawIndex(uint32_t index)
  208. {
  209. IL2CPP_ASSERT(index < (uint32_t)_fieldDetails.size());
  210. return _fieldDetails[index];
  211. }
  212. const Il2CppMethodDefinition* GetMethodDefinitionFromRawIndex(uint32_t index) override
  213. {
  214. IL2CPP_ASSERT((size_t)index < _methodDefines.size());
  215. return &_methodDefines[index];
  216. }
  217. MethodIndex GetMethodIndexFromDefinition(const Il2CppMethodDefinition* methodDefine)
  218. {
  219. return EncodeWithIndex((uint32_t)(methodDefine - &_methodDefines[0]));
  220. }
  221. const Il2CppGenericParameter* GetGenericParameterByGlobalIndex(uint32_t index)
  222. {
  223. IL2CPP_ASSERT(index < (uint32_t)_genericParams.size());
  224. return &_genericParams[index];
  225. }
  226. const Il2CppGenericParameter* GetGenericParameterByRawIndex(const Il2CppGenericContainer* container, uint32_t index)
  227. {
  228. uint32_t globalIndex = DecodeMetadataIndex(container->genericParameterStart) + index;
  229. IL2CPP_ASSERT(globalIndex < (uint32_t)_genericParams.size());
  230. return &_genericParams[globalIndex];
  231. }
  232. Il2CppGenericContainer* GetGenericContainerByRawIndex(uint32_t index) override
  233. {
  234. if (index != kGenericContainerIndexInvalid)
  235. {
  236. IL2CPP_ASSERT(index < (uint32_t)_genericContainers.size());
  237. return &_genericContainers[index];
  238. }
  239. return nullptr;
  240. }
  241. Il2CppGenericContainer* GetGenericContainerByTypeDefinition(const Il2CppTypeDefinition* typeDef)
  242. {
  243. GenericContainerIndex idx = DecodeMetadataIndex(typeDef->genericContainerIndex);
  244. if (idx != kGenericContainerIndexInvalid)
  245. {
  246. IL2CPP_ASSERT(idx < (GenericContainerIndex)_genericContainers.size());
  247. return &_genericContainers[idx];
  248. }
  249. return nullptr;
  250. }
  251. Il2CppGenericContainer* GetGenericContainerByTypeDefRawIndex(int32_t typeDefIndex) override
  252. {
  253. IL2CPP_ASSERT(typeDefIndex < (int32_t)_typeDetails.size());
  254. return GetGenericContainerByTypeDefinition(&_typesDefines[typeDefIndex]);
  255. }
  256. const il2cpp::utils::dynamic_array<MethodImpl> GetTypeMethodImplByTypeDefinition(const Il2CppTypeDefinition* typeDef);
  257. const Il2CppType* GetGenericParameterConstraintFromIndex(GenericParameterConstraintIndex index)
  258. {
  259. IL2CPP_ASSERT((size_t)index < _genericConstraints.size());
  260. TypeIndex typeIndex = _genericConstraints[index];
  261. if (typeIndex == kTypeIndexInvalid)
  262. {
  263. TbGenericParamConstraint data = _rawImage->ReadGenericParamConstraint(index + 1);
  264. Il2CppGenericParameter& genericParam = _genericParams[data.owner - 1];
  265. const Il2CppGenericContainer* klassGc;
  266. const Il2CppGenericContainer* methodGc;
  267. GetClassAndMethodGenericContainerFromGenericContainerIndex(genericParam.ownerIndex, klassGc, methodGc);
  268. const Il2CppType* paramCons = ReadTypeFromToken(klassGc, methodGc, DecodeTypeDefOrRefOrSpecCodedIndexTableType(data.constraint), DecodeTypeDefOrRefOrSpecCodedIndexRowIndex(data.constraint));
  269. _genericConstraints[index] = typeIndex = DecodeMetadataIndex(AddIl2CppTypeCache(paramCons));
  270. }
  271. return _types[typeIndex];
  272. }
  273. Il2CppClass* GetNestedTypeFromOffset(const Il2CppClass* klass, TypeNestedTypeIndex offset);
  274. Il2CppClass* GetNestedTypeFromOffset(const Il2CppTypeDefinition* typeDef, TypeNestedTypeIndex offset);
  275. const MethodInfo* GetMethodInfoFromMethodDefinitionRawIndex(uint32_t index);
  276. const MethodInfo* GetMethodInfoFromMethodDefinition(const Il2CppMethodDefinition* methodDef);
  277. const Il2CppMethodDefinition* GetMethodDefinitionFromVTableSlot(const Il2CppTypeDefinition* typeDefine, int32_t vTableSlot);
  278. const MethodInfo* GetMethodInfoFromVTableSlot(const Il2CppClass* klass, int32_t vTableSlot);
  279. Il2CppTypeDefinition* GetNestedTypes(Il2CppTypeDefinition* handle, void** iter);
  280. void GetClassAndMethodGenericContainerFromGenericContainerIndex(GenericContainerIndex idx, const Il2CppGenericContainer*& klassGc, const Il2CppGenericContainer*& methodGc);
  281. Il2CppMethodPointer GetAdjustorThunk(uint32_t token);
  282. Il2CppMethodPointer GetMethodPointer(uint32_t token);
  283. InvokerMethod GetMethodInvoker(uint32_t token);
  284. const Il2CppParameterDefinition* GetParameterDefinitionFromIndex(uint32_t index)
  285. {
  286. IL2CPP_ASSERT((size_t)index < _params.size());
  287. return &_params[index].paramDef;
  288. }
  289. const Il2CppParameterDefaultValue* GetParameterDefaultValueEntryByRawIndex(uint32_t index)
  290. {
  291. IL2CPP_ASSERT(index < (uint32_t)_params.size());
  292. uint32_t defaultValueIndex = _params[index].defaultValueIndex;
  293. return defaultValueIndex != kDefaultValueIndexNull ? &_paramDefaultValues[defaultValueIndex] : nullptr;
  294. }
  295. uint32_t GetFieldOffset(const Il2CppTypeDefinition* typeDef, int32_t fieldIndexInType)
  296. {
  297. uint32_t fieldActualIndex = DecodeMetadataIndex(typeDef->fieldStart) + fieldIndexInType;
  298. IL2CPP_ASSERT(fieldActualIndex < (uint32_t)_fieldDetails.size());
  299. return _fieldDetails[fieldActualIndex].offset;
  300. }
  301. uint32_t GetFieldOffset(TypeDefinitionIndex typeIndex, int32_t fieldIndexInType)
  302. {
  303. Il2CppTypeDefinition* typeDef = &_typesDefines[typeIndex];
  304. return GetFieldOffset(typeDef, fieldIndexInType);
  305. }
  306. uint32_t GetFieldOffset(const Il2CppClass* klass, int32_t fieldIndexInType)
  307. {
  308. Il2CppTypeDefinition* typeDef = (Il2CppTypeDefinition*)(klass->typeMetadataHandle);
  309. return GetFieldOffset(typeDef, fieldIndexInType);
  310. }
  311. int32_t GetPackingSize(const Il2CppTypeDefinition* typeDef) const
  312. {
  313. int32_t typeIndex = GetTypeRawIndex(typeDef);
  314. auto it = _classLayouts.find(typeIndex);
  315. return it != _classLayouts.end() ? it->second.packingSize : 0;
  316. }
  317. TbClassLayout GetClassLayout(const Il2CppTypeDefinition* typeDef) const
  318. {
  319. int32_t typeIndex = GetTypeRawIndex(typeDef);
  320. auto it = _classLayouts.find(typeIndex);
  321. return it != _classLayouts.end() ? it->second : TbClassLayout{};
  322. }
  323. const Il2CppFieldDefaultValue* GetFieldDefaultValueEntryByRawIndex(uint32_t index)
  324. {
  325. IL2CPP_ASSERT(index < (uint32_t)_fieldDetails.size());
  326. uint32_t fdvIndex = _fieldDetails[index].defaultValueIndex;
  327. IL2CPP_ASSERT(fdvIndex != kDefaultValueIndexNull);
  328. return &_fieldDefaultValues[fdvIndex];
  329. }
  330. #if HYBRIDCLR_UNITY_2021_OR_NEW
  331. static uint32_t EncodeWithBlobSource(uint32_t index, BlobSource source)
  332. {
  333. return (index << 1) | (uint32_t)source;
  334. }
  335. #endif
  336. const uint8_t* GetFieldOrParameterDefalutValueByRawIndex(uint32_t index)
  337. {
  338. #if !HYBRIDCLR_UNITY_2021_OR_NEW
  339. return _rawImage->GetFieldOrParameterDefalutValueByRawIndex(index);
  340. #else
  341. BlobSource source = (BlobSource)(index & 0x1);
  342. uint32_t offset = index >> 1;
  343. if (source == BlobSource::RAW_IMAGE)
  344. {
  345. return _rawImage->GetFieldOrParameterDefalutValueByRawIndex(offset);
  346. }
  347. else
  348. {
  349. return _constValues.DataAt(offset);
  350. }
  351. #endif
  352. }
  353. #if HYBRIDCLR_UNITY_2021_OR_NEW
  354. DefaultValueDataIndex ConvertConstValue(CustomAttributeDataWriter& writer, uint32_t blobIndex, const Il2CppType* type);
  355. #endif
  356. Il2CppPropertyDefinition* GetPropertyDefinitionFromIndex(PropertyIndex index)
  357. {
  358. IL2CPP_ASSERT(index > 0 && index <= (int32_t)_propeties.size());
  359. PropertyDetail& pd = _propeties[(uint32_t)index - 1];
  360. return &pd.il2cppDefinition;
  361. }
  362. Il2CppMetadataPropertyInfo GetPropertyInfo(const Il2CppClass* klass, TypePropertyIndex index)
  363. {
  364. const Il2CppTypeDefinition* typeDef = (Il2CppTypeDefinition*)klass->typeMetadataHandle;
  365. IL2CPP_ASSERT(typeDef->propertyStart);
  366. uint32_t rowIndex = DecodeMetadataIndex(typeDef->propertyStart) + index;
  367. PropertyDetail& pd = _propeties[rowIndex - 1];
  368. uint32_t baseMethodIdx = DecodeMetadataIndex(typeDef->methodStart) + 1;
  369. #if UNITY_ENGINE_TUANJIE
  370. const MethodInfo* getter = pd.getterMethodIndex ? il2cpp::vm::Class::GetOrSetupOneMethod(const_cast<Il2CppClass*>(klass), pd.getterMethodIndex - baseMethodIdx) : nullptr;
  371. const MethodInfo* setter = pd.setterMethodIndex ? il2cpp::vm::Class::GetOrSetupOneMethod(const_cast<Il2CppClass*>(klass), pd.setterMethodIndex - baseMethodIdx) : nullptr;
  372. #else
  373. const MethodInfo* getter = pd.getterMethodIndex ? klass->methods[pd.getterMethodIndex - baseMethodIdx] : nullptr;
  374. const MethodInfo* setter = pd.setterMethodIndex ? klass->methods[pd.setterMethodIndex - baseMethodIdx] : nullptr;
  375. #endif
  376. return { pd.name, getter, setter, pd.flags, EncodeToken(TableType::PROPERTY, rowIndex) };
  377. }
  378. #ifdef HYBRIDCLR_UNITY_2019
  379. const Il2CppEventDefinition* GetEventDefinitionFromIndex(EventIndex index)
  380. {
  381. IL2CPP_ASSERT(index > 0 && index <= (int32_t)_events.size());
  382. EventDetail& pd = _events[index - 1];
  383. return &pd.il2cppDefinition;
  384. }
  385. #endif
  386. Il2CppMetadataEventInfo GetEventInfo(const Il2CppClass* klass, TypeEventIndex index)
  387. {
  388. const Il2CppTypeDefinition* typeDef = (Il2CppTypeDefinition*)klass->typeMetadataHandle;
  389. IL2CPP_ASSERT(typeDef->eventStart);
  390. uint32_t rowIndex = DecodeMetadataIndex(typeDef->eventStart) + index;
  391. EventDetail& pd = _events[rowIndex - 1];
  392. uint32_t baseMethodIdx = DecodeMetadataIndex(typeDef->methodStart) + 1;
  393. #if UNITY_ENGINE_TUANJIE
  394. const MethodInfo* addOn = pd.addMethodIndex ? il2cpp::vm::Class::GetOrSetupOneMethod(const_cast<Il2CppClass*>(klass), pd.addMethodIndex - baseMethodIdx) : nullptr;
  395. const MethodInfo* removeOn = pd.removeMethodIndex ? il2cpp::vm::Class::GetOrSetupOneMethod(const_cast<Il2CppClass*>(klass), pd.removeMethodIndex - baseMethodIdx) : nullptr;
  396. const MethodInfo* raiseOn = pd.fireMethodIndex ? il2cpp::vm::Class::GetOrSetupOneMethod(const_cast<Il2CppClass*>(klass), pd.fireMethodIndex - baseMethodIdx) : nullptr;
  397. #else
  398. const MethodInfo* addOn = pd.addMethodIndex ? klass->methods[pd.addMethodIndex - baseMethodIdx] : nullptr;
  399. const MethodInfo* removeOn = pd.removeMethodIndex ? klass->methods[pd.removeMethodIndex - baseMethodIdx] : nullptr;
  400. const MethodInfo* raiseOn = pd.fireMethodIndex ? klass->methods[pd.fireMethodIndex - baseMethodIdx] : nullptr;
  401. #endif
  402. return { pd.name, &klass->byval_arg, addOn, removeOn, raiseOn, EncodeToken(TableType::EVENT, rowIndex) };
  403. }
  404. const Il2CppAssembly* GetReferencedAssembly(int32_t referencedAssemblyTableIndex, const Il2CppAssembly assembliesTable[], int assembliesCount);
  405. Il2CppMetadataCustomAttributeHandle GetCustomAttributeTypeToken(uint32_t token)
  406. {
  407. auto it = _tokenCustomAttributes.find(token);
  408. return it != _tokenCustomAttributes.end() ? (Il2CppMetadataCustomAttributeHandle)&_customAttributeHandles[DecodeMetadataIndex(it->second.typeRangeIndex)] : nullptr;
  409. }
  410. CustomAttributeIndex GetCustomAttributeIndex(uint32_t token)
  411. {
  412. auto it = _tokenCustomAttributes.find(token);
  413. return it != _tokenCustomAttributes.end() ? it->second.typeRangeIndex : kCustomAttributeIndexInvalid;
  414. }
  415. #if !HYBRIDCLR_UNITY_2021_OR_NEW
  416. std::tuple<void*, void*> GetCustomAttributeDataRange(uint32_t token)
  417. {
  418. const Il2CppCustomAttributeTypeRange* dataRangeCur = (const Il2CppCustomAttributeTypeRange*)GetCustomAttributeTypeToken(token);
  419. CustomAttributeIndex curIndex = DecodeMetadataIndex(GET_CUSTOM_ATTRIBUTE_TYPE_RANGE_START(*dataRangeCur));
  420. CustomAttributeIndex nextIndex = DecodeMetadataIndex(GET_CUSTOM_ATTRIBUTE_TYPE_RANGE_START(*(dataRangeCur + 1)));
  421. CustomAttribute& curCa = _customAttribues[curIndex];
  422. CustomAttribute& nextCa = _customAttribues[nextIndex];
  423. return std::make_tuple<void*, void*>((void*)_rawImage->GetBlobReaderByRawIndex(curCa.value).GetData(), (void*)_rawImage->GetBlobReaderByRawIndex(nextCa.value).GetData());
  424. }
  425. CustomAttributesCache* GenerateCustomAttributesCacheInternal(const Il2CppCustomAttributeTypeRange* typeRange)
  426. {
  427. CustomAttributeIndex index = (CustomAttributeIndex)(typeRange - (const Il2CppCustomAttributeTypeRange*)&_customAttributeHandles[0]);
  428. IL2CPP_ASSERT(index >= 0 && index < (CustomAttributeIndex)_customAttributeHandles.size());
  429. return GenerateCustomAttributesCacheInternal(index);
  430. }
  431. bool HasAttribute(CustomAttributeIndex index, Il2CppClass* attribute)
  432. {
  433. const Il2CppCustomAttributeTypeRange* typeRange = &_customAttributeHandles[DecodeMetadataIndex(index)];
  434. return HasAttribute(typeRange, attribute);
  435. }
  436. bool HasAttribute(const Il2CppCustomAttributeTypeRange* typeRange, Il2CppClass* attribute)
  437. {
  438. CustomAttributesCache* attrCache = GenerateCustomAttributesCacheInternal(typeRange);
  439. return HasAttribute(attrCache, attribute);
  440. }
  441. bool HasAttributeByToken(uint32_t token, Il2CppClass* attribute)
  442. {
  443. CustomAttributeIndex index = GetCustomAttributeIndex(token);
  444. if (index == kCustomAttributeIndexInvalid)
  445. {
  446. return false;
  447. }
  448. CustomAttributesCache* attrCache = GenerateCustomAttributesCacheInternal(DecodeMetadataIndex(index));
  449. return HasAttribute(attrCache, attribute);
  450. }
  451. bool HasAttribute(CustomAttributesCache* attrCache, Il2CppClass* attribute)
  452. {
  453. for (int i = 0; i < attrCache->count; i++)
  454. {
  455. Il2CppObject* attrObj = attrCache->attributes[i];
  456. if (il2cpp::vm::Class::IsAssignableFrom(attribute, attrObj->klass))
  457. {
  458. return true;
  459. }
  460. }
  461. return false;
  462. }
  463. CustomAttributesCache* GenerateCustomAttributesCacheInternal(CustomAttributeIndex index);
  464. #else
  465. void InitCustomAttributeData(CustomAttributesInfo& cai, const Il2CppCustomAttributeTypeRange& dataRange);
  466. il2cpp::metadata::CustomAttributeDataReader CreateCustomAttributeDataReader(Il2CppMetadataCustomAttributeHandle handle)
  467. {
  468. const Il2CppCustomAttributeTypeRange* dataRange = (const Il2CppCustomAttributeTypeRange*)handle;
  469. IL2CPP_ASSERT(_tokenCustomAttributes.find(dataRange->token) != _tokenCustomAttributes.end());
  470. CustomAttributesInfo& cai = _tokenCustomAttributes[dataRange->token];
  471. if (!cai.inited)
  472. {
  473. InitCustomAttributeData(cai, *dataRange);
  474. }
  475. #if HYBRIDCLR_UNITY_2022_OR_NEW
  476. return il2cpp::metadata::CustomAttributeDataReader(_il2cppImage, cai.dataStartPtr, cai.dataEndPtr);
  477. #else
  478. return il2cpp::metadata::CustomAttributeDataReader(cai.dataStartPtr, cai.dataEndPtr);
  479. #endif
  480. }
  481. std::tuple<void*, void*> CreateCustomAttributeDataTuple(const Il2CppCustomAttributeDataRange* dataRange)
  482. {
  483. IL2CPP_ASSERT(_tokenCustomAttributes.find(dataRange->token) != _tokenCustomAttributes.end());
  484. CustomAttributesInfo& cai = _tokenCustomAttributes[dataRange->token];
  485. if (!cai.inited)
  486. {
  487. InitCustomAttributeData(cai, *dataRange);
  488. }
  489. return std::tuple<void*, void*>(cai.dataStartPtr, cai.dataEndPtr);
  490. }
  491. std::tuple<void*, void*> CreateCustomAttributeDataTupleByToken(uint32_t token)
  492. {
  493. const Il2CppCustomAttributeTypeRange* dataRangeCur = (const Il2CppCustomAttributeTypeRange*)GetCustomAttributeTypeToken(token);
  494. return dataRangeCur ? CreateCustomAttributeDataTuple(dataRangeCur) : std::tuple<void*, void*>(nullptr, nullptr);
  495. }
  496. #if !HYBRIDCLR_UNITY_2022_OR_NEW
  497. CustomAttributesCache* GenerateCustomAttributesCacheInternal(const Il2CppCustomAttributeTypeRange* typeRange)
  498. {
  499. CustomAttributeIndex index = (CustomAttributeIndex)(typeRange - (const Il2CppCustomAttributeTypeRange*)&_customAttributeHandles[0]);
  500. IL2CPP_ASSERT(index >= 0 && index < (CustomAttributeIndex)_customAttributeHandles.size());
  501. return GenerateCustomAttributesCacheInternal(index);
  502. }
  503. CustomAttributesCache* GenerateCustomAttributesCacheInternal(CustomAttributeIndex index);
  504. #endif
  505. void BuildCustomAttributesData(CustomAttributesInfo& cai, const Il2CppCustomAttributeTypeRange& typeRange);
  506. void ConvertILCustomAttributeData2Il2CppFormat(const MethodInfo* ctorMethod, BlobReader& reader);
  507. void ConvertFixedArg(CustomAttributeDataWriter& writer, BlobReader& reader, const Il2CppType* type, bool writeType);
  508. void ConvertBoxedValue(CustomAttributeDataWriter& writer, BlobReader& reader, bool writeType);
  509. void ConvertSystemType(CustomAttributeDataWriter& writer, BlobReader& reader, bool writeType);
  510. void WriteEncodeTypeEnum(CustomAttributeDataWriter& writer, const Il2CppType* type);
  511. void GetFieldDeclaringTypeIndexAndFieldIndexByName(const Il2CppTypeDefinition* declaringType, const char* name, int32_t& typeIndex, int32_t& fieldIndex);
  512. void GetPropertyDeclaringTypeIndexAndPropertyIndexByName(const Il2CppTypeDefinition* declaringType, const char* name, int32_t& typeIndex, int32_t& fieldIndex);
  513. #endif
  514. Il2CppClass* GetTypeInfoFromTypeDefinitionRawIndex(uint32_t index);
  515. const Il2CppType* GetInterfaceFromGlobalOffset(TypeInterfaceIndex offset);
  516. const Il2CppType* GetInterfaceFromIndex(const Il2CppClass* klass, TypeInterfaceIndex index);
  517. const Il2CppType* GetInterfaceFromOffset(const Il2CppClass* klass, TypeInterfaceIndex offset);
  518. const Il2CppType* GetInterfaceFromOffset(const Il2CppTypeDefinition* typeDefine, TypeInterfaceIndex offset);
  519. Il2CppInterfaceOffsetInfo GetInterfaceOffsetInfo(const Il2CppTypeDefinition* typeDefine, TypeInterfaceOffsetIndex index);
  520. uint32_t AddIl2CppTypeCache(const Il2CppType* type);
  521. uint32_t AddIl2CppGenericContainers(Il2CppGenericContainer& geneContainer);
  522. const Il2CppType* GetModuleIl2CppType(uint32_t moduleRowIndex, uint32_t typeNamespace, uint32_t typeName, bool raiseExceptionIfNotFound) override;
  523. void ReadFieldRefInfoFromFieldDefToken(uint32_t rowIndex, FieldRefInfo& ret) override;
  524. void ReadMethodDefSig(BlobReader& reader, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer, Il2CppMethodDefinition& methodDef, std::vector<ParamDetail>& paramArr);
  525. void InitBasic(Il2CppImage* image);
  526. void BuildIl2CppImage(Il2CppImage* image);
  527. void BuildIl2CppAssembly(Il2CppAssembly* assembly);
  528. void InitRuntimeMetadatas() override;
  529. protected:
  530. void InitTypeDefs_0();
  531. void InitTypeDefs_1();
  532. void InitTypeDefs_2();
  533. void InitConsts();
  534. void InitClass();
  535. void InitParamDefs();
  536. void InitGenericParamConstraintDefs();
  537. void InitGenericParamDefs0();
  538. void InitGenericParamDefs();
  539. void InitFieldDefs();
  540. void InitFieldLayouts();
  541. void InitFieldRVAs();
  542. void InitBlittables();
  543. void InitMethodDefs0();
  544. void InitMethodDefs();
  545. void InitMethodImpls0();
  546. void InitNestedClass();
  547. void InitClassLayouts();
  548. void InitCustomAttributes();
  549. void InitProperties();
  550. void InitEvents();
  551. void InitMethodSemantics();
  552. void InitInterfaces();
  553. void InitVTables();
  554. void ComputeBlittable(Il2CppTypeDefinition* def, std::vector<bool>& computFlags);
  555. void ComputeVTable(TypeDefinitionDetail* tdd);
  556. void SetIl2CppImage(Il2CppImage* image)
  557. {
  558. _il2cppImage = image;
  559. }
  560. Il2CppString* ReadSerString(BlobReader& reader);
  561. #if HYBRIDCLR_UNITY_2021_OR_NEW
  562. bool ReadUTF8SerString(BlobReader& reader, std::string& s);
  563. #endif
  564. Il2CppReflectionType* ReadSystemType(BlobReader& reader);
  565. Il2CppObject* ReadBoxedValue(BlobReader& reader);
  566. void ReadFixedArg(BlobReader& reader, const Il2CppType* argType, void* data);
  567. void ReadCustomAttributeFieldOrPropType(BlobReader& reader, Il2CppType& type);
  568. #if !HYBRIDCLR_UNITY_2021_OR_NEW
  569. void ConstructCustomAttribute(BlobReader& reader, Il2CppObject* obj, const MethodInfo* ctorMethod);
  570. #endif
  571. bool _inited;
  572. Il2CppImage* _il2cppImage;
  573. const uint32_t _index;
  574. std::vector<TypeDefinitionDetail> _typeDetails;
  575. std::vector<Il2CppTypeDefinition> _typesDefines;
  576. std::vector<Il2CppTypeDefinition> _exportedTypeDefines;
  577. std::vector<const Il2CppType*> _types;
  578. Il2CppHashMap<const Il2CppType*, uint32_t, Il2CppTypeHashShallow, Il2CppTypeEqualityComparerShallow> _type2Indexs;
  579. std::vector<TypeIndex> _interfaceDefines;
  580. std::vector<InterfaceOffsetInfo> _interfaceOffsets;
  581. std::vector<Il2CppMethodDefinition> _methodDefines;
  582. std::vector<ParamDetail> _params;
  583. std::vector<int32_t>* _paramRawIndex2ActualParamIndex; // rawIindex = rowIndex - 1; because local function, param list count maybe less than actual method param count
  584. std::vector<Il2CppParameterDefaultValue> _paramDefaultValues;
  585. std::vector<Il2CppGenericParameter> _genericParams;
  586. std::vector<TypeIndex> _genericConstraints; // raw TypeIndex
  587. std::vector<Il2CppGenericContainer> _genericContainers;
  588. std::vector<FieldDetail> _fieldDetails;
  589. std::vector<Il2CppFieldDefaultValue> _fieldDefaultValues;
  590. std::unordered_map<uint32_t, TbClassLayout> _classLayouts;
  591. std::vector<uint32_t> _nestedTypeDefineIndexs;
  592. // runtime data
  593. std::vector<Il2CppClass*> _classList;
  594. Il2CppType2TypeDeclaringTreeMap _cacheTrees;
  595. #if HYBRIDCLR_UNITY_2021_OR_NEW
  596. CustomAttributeDataWriter _constValues;
  597. #endif
  598. std::unordered_map<uint32_t, CustomAttributesInfo> _tokenCustomAttributes;
  599. std::vector<Il2CppCustomAttributeTypeRange> _customAttributeHandles;
  600. #if !HYBRIDCLR_UNITY_2022_OR_NEW
  601. std::vector<CustomAttributesCache*> _customAttribtesCaches;
  602. #endif
  603. #if HYBRIDCLR_UNITY_2021_OR_NEW
  604. CustomAttributeDataWriter _il2cppFormatCustomDataBlob;
  605. CustomAttributeDataWriter _tempCtorArgBlob;
  606. CustomAttributeDataWriter _tempFieldBlob;
  607. CustomAttributeDataWriter _tempPropertyBlob;
  608. #endif
  609. std::vector<CustomAttribute> _customAttribues;
  610. std::vector<PropertyDetail> _propeties;
  611. std::vector<EventDetail> _events;
  612. };
  613. }
  614. }