No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MetadataCache.cpp 51KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  1. #include "il2cpp-config.h"
  2. #include "MetadataCache.h"
  3. #include "GlobalMetadata.h"
  4. #include <map>
  5. #include <limits>
  6. #include "il2cpp-tabledefs.h"
  7. #include "il2cpp-runtime-stats.h"
  8. #include "gc/GarbageCollector.h"
  9. #include "metadata/ArrayMetadata.h"
  10. #include "metadata/GenericMetadata.h"
  11. #include "metadata/GenericMethod.h"
  12. #include "os/Atomic.h"
  13. #include "os/Mutex.h"
  14. #include "utils/CallOnce.h"
  15. #include "utils/Collections.h"
  16. #include "utils/Il2CppHashSet.h"
  17. #include "utils/Memory.h"
  18. #include "utils/PathUtils.h"
  19. #include "vm/Assembly.h"
  20. #include "vm/Class.h"
  21. #include "vm/ClassInlines.h"
  22. #include "vm/GenericClass.h"
  23. #include "vm/MetadataAlloc.h"
  24. #include "vm/MetadataLoader.h"
  25. #include "vm/MetadataLock.h"
  26. #include "vm/Method.h"
  27. #include "vm/Object.h"
  28. #include "vm/Runtime.h"
  29. #include "vm/String.h"
  30. #include "vm/Type.h"
  31. #include "vm-utils/MethodDefinitionKey.h"
  32. #include "vm-utils/NativeSymbol.h"
  33. #include "Baselib.h"
  34. #include "Cpp/ReentrantLock.h"
  35. typedef Il2CppReaderWriterLockedHashMap<Il2CppClass*, Il2CppClass*> PointerTypeMap;
  36. typedef Il2CppHashSet<const Il2CppGenericMethod*, il2cpp::metadata::Il2CppGenericMethodHash, il2cpp::metadata::Il2CppGenericMethodCompare> Il2CppGenericMethodSet;
  37. typedef Il2CppGenericMethodSet::const_iterator Il2CppGenericMethodSetIter;
  38. static Il2CppGenericMethodSet s_GenericMethodSet;
  39. struct Il2CppMetadataCache
  40. {
  41. il2cpp::os::FastReaderReaderWriterLock m_CacheLock;
  42. PointerTypeMap m_PointerTypes;
  43. };
  44. static Il2CppMetadataCache s_MetadataCache;
  45. static int32_t s_ImagesCount = 0;
  46. static Il2CppImage* s_ImagesTable = NULL;
  47. static int32_t s_AssembliesCount = 0;
  48. static Il2CppAssembly* s_AssembliesTable = NULL;
  49. typedef Il2CppReaderWriterLockedHashSet<const Il2CppGenericInst*, il2cpp::metadata::Il2CppGenericInstHash, il2cpp::metadata::Il2CppGenericInstCompare> Il2CppGenericInstSet;
  50. static Il2CppGenericInstSet s_GenericInstSet;
  51. typedef il2cpp::vm::Il2CppMethodTableMap::const_iterator Il2CppMethodTableMapIter;
  52. static il2cpp::vm::Il2CppMethodTableMap s_MethodTableMap;
  53. typedef il2cpp::vm::Il2CppUnresolvedSignatureMap::const_iterator Il2CppUnresolvedSignatureMapIter;
  54. static il2cpp::vm::Il2CppUnresolvedSignatureMap *s_pUnresolvedSignatureMap;
  55. typedef Il2CppHashMap<FieldInfo*, int32_t, il2cpp::utils::PointerHash<FieldInfo> > Il2CppThreadLocalStaticOffsetHashMap;
  56. typedef Il2CppThreadLocalStaticOffsetHashMap::iterator Il2CppThreadLocalStaticOffsetHashMapIter;
  57. static Il2CppThreadLocalStaticOffsetHashMap s_ThreadLocalStaticOffsetMap;
  58. static const Il2CppCodeRegistration * s_Il2CppCodeRegistration;
  59. static const Il2CppMetadataRegistration* s_MetadataCache_Il2CppMetadataRegistration;
  60. static const Il2CppCodeGenOptions* s_Il2CppCodeGenOptions;
  61. static il2cpp::vm::WindowsRuntimeTypeNameToClassMap s_WindowsRuntimeTypeNameToClassMap;
  62. static il2cpp::vm::ClassToWindowsRuntimeTypeNameMap s_ClassToWindowsRuntimeTypeNameMap;
  63. struct InteropDataToTypeConverter
  64. {
  65. inline const Il2CppType* operator()(const Il2CppInteropData& interopData) const
  66. {
  67. return interopData.type;
  68. }
  69. };
  70. typedef il2cpp::utils::collections::ArrayValueMap<const Il2CppType*, Il2CppInteropData, InteropDataToTypeConverter, il2cpp::metadata::Il2CppTypeLess, il2cpp::metadata::Il2CppTypeEqualityComparer> InteropDataMap;
  71. static InteropDataMap s_InteropData;
  72. struct WindowsRuntimeFactoryTableEntryToTypeConverter
  73. {
  74. inline const Il2CppType* operator()(const Il2CppWindowsRuntimeFactoryTableEntry& entry) const
  75. {
  76. return entry.type;
  77. }
  78. };
  79. typedef il2cpp::utils::collections::ArrayValueMap<const Il2CppType*, Il2CppWindowsRuntimeFactoryTableEntry, WindowsRuntimeFactoryTableEntryToTypeConverter, il2cpp::metadata::Il2CppTypeLess, il2cpp::metadata::Il2CppTypeEqualityComparer> WindowsRuntimeFactoryTable;
  80. static WindowsRuntimeFactoryTable s_WindowsRuntimeFactories;
  81. template<typename K, typename V>
  82. struct PairToKeyConverter
  83. {
  84. inline const K& operator()(const std::pair<K, V>& pair) const
  85. {
  86. return pair.first;
  87. }
  88. };
  89. typedef il2cpp::utils::collections::ArrayValueMap<const Il2CppGuid*, std::pair<const Il2CppGuid*, Il2CppClass*>, PairToKeyConverter<const Il2CppGuid*, Il2CppClass*> > GuidToClassMap;
  90. static GuidToClassMap s_GuidToNonImportClassMap;
  91. void il2cpp::vm::MetadataCache::Register(const Il2CppCodeRegistration* const codeRegistration, const Il2CppMetadataRegistration* const metadataRegistration, const Il2CppCodeGenOptions* const codeGenOptions)
  92. {
  93. il2cpp::vm::GlobalMetadata::Register(codeRegistration, metadataRegistration, codeGenOptions);
  94. s_Il2CppCodeRegistration = codeRegistration;
  95. s_MetadataCache_Il2CppMetadataRegistration = metadataRegistration;
  96. s_Il2CppCodeGenOptions = codeGenOptions;
  97. }
  98. Il2CppClass* il2cpp::vm::MetadataCache::GetTypeInfoFromTypeIndex(const Il2CppImage *image, TypeIndex index)
  99. {
  100. return il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeIndex(index);
  101. }
  102. const MethodInfo* il2cpp::vm::MetadataCache::GetMethodInfoFromMethodDefinitionIndex(const Il2CppImage *image, MethodIndex index)
  103. {
  104. return il2cpp::vm::GlobalMetadata::GetMethodInfoFromMethodDefinitionIndex(index);
  105. }
  106. const MethodInfo* il2cpp::vm::MetadataCache::GetAssemblyEntryPoint(const Il2CppImage* image)
  107. {
  108. return il2cpp::vm::GlobalMetadata::GetAssemblyEntryPoint(image);
  109. }
  110. Il2CppMetadataTypeHandle il2cpp::vm::MetadataCache::GetAssemblyTypeHandle(const Il2CppImage* image, AssemblyTypeIndex index)
  111. {
  112. return il2cpp::vm::GlobalMetadata::GetAssemblyTypeHandle(image, index);
  113. }
  114. Il2CppMetadataTypeHandle il2cpp::vm::MetadataCache::GetAssemblyExportedTypeHandle(const Il2CppImage* image, AssemblyExportedTypeIndex index)
  115. {
  116. return il2cpp::vm::GlobalMetadata::GetAssemblyExportedTypeHandle(image, index);
  117. }
  118. const MethodInfo* il2cpp::vm::MetadataCache::GetMethodInfoFromMethodHandle(Il2CppMetadataMethodDefinitionHandle handle)
  119. {
  120. return il2cpp::vm::GlobalMetadata::GetMethodInfoFromMethodHandle(handle);
  121. }
  122. bool il2cpp::vm::MetadataCache::Initialize()
  123. {
  124. if (!il2cpp::vm::GlobalMetadata::Initialize(&s_ImagesCount, &s_AssembliesCount))
  125. {
  126. return false;
  127. }
  128. il2cpp::metadata::GenericMetadata::RegisterGenericClasses(s_MetadataCache_Il2CppMetadataRegistration->genericClasses, s_MetadataCache_Il2CppMetadataRegistration->genericClassesCount);
  129. il2cpp::metadata::GenericMetadata::SetMaximumRuntimeGenericDepth(s_Il2CppCodeGenOptions->maximumRuntimeGenericDepth);
  130. il2cpp::metadata::GenericMetadata::SetGenericVirtualIterations(s_Il2CppCodeGenOptions->recursiveGenericIterations);
  131. s_GenericInstSet.Resize(s_MetadataCache_Il2CppMetadataRegistration->genericInstsCount);
  132. for (int32_t i = 0; i < s_MetadataCache_Il2CppMetadataRegistration->genericInstsCount; i++)
  133. {
  134. bool inserted = s_GenericInstSet.Add(s_MetadataCache_Il2CppMetadataRegistration->genericInsts[i]);
  135. IL2CPP_ASSERT(inserted);
  136. }
  137. s_InteropData.assign_external(s_Il2CppCodeRegistration->interopData, s_Il2CppCodeRegistration->interopDataCount);
  138. s_WindowsRuntimeFactories.assign_external(s_Il2CppCodeRegistration->windowsRuntimeFactoryTable, s_Il2CppCodeRegistration->windowsRuntimeFactoryCount);
  139. // Pre-allocate these arrays so we don't need to lock when reading later.
  140. // These arrays hold the runtime metadata representation for metadata explicitly
  141. // referenced during conversion. There is a corresponding table of same size
  142. // in the converted metadata, giving a description of runtime metadata to construct.
  143. s_ImagesTable = (Il2CppImage*)IL2CPP_CALLOC(s_ImagesCount, sizeof(Il2CppImage));
  144. s_AssembliesTable = (Il2CppAssembly*)IL2CPP_CALLOC(s_AssembliesCount, sizeof(Il2CppAssembly));
  145. // setup all the Il2CppImages. There are not many and it avoid locks later on
  146. for (int32_t imageIndex = 0; imageIndex < s_ImagesCount; imageIndex++)
  147. {
  148. Il2CppImage* image = s_ImagesTable + imageIndex;
  149. AssemblyIndex imageAssemblyIndex;
  150. il2cpp::vm::GlobalMetadata::BuildIl2CppImage(image, imageIndex, &imageAssemblyIndex);
  151. image->assembly = const_cast<Il2CppAssembly*>(GetAssemblyFromIndex(imageAssemblyIndex));
  152. std::string nameNoExt = il2cpp::utils::PathUtils::PathNoExtension(image->name);
  153. image->nameNoExt = (char*)IL2CPP_CALLOC(nameNoExt.size() + 1, sizeof(char));
  154. strcpy(const_cast<char*>(image->nameNoExt), nameNoExt.c_str());
  155. for (uint32_t codeGenModuleIndex = 0; codeGenModuleIndex < s_Il2CppCodeRegistration->codeGenModulesCount; ++codeGenModuleIndex)
  156. {
  157. if (strcmp(image->name, s_Il2CppCodeRegistration->codeGenModules[codeGenModuleIndex]->moduleName) == 0)
  158. image->codeGenModule = s_Il2CppCodeRegistration->codeGenModules[codeGenModuleIndex];
  159. }
  160. IL2CPP_ASSERT(image->codeGenModule);
  161. image->dynamic = false;
  162. }
  163. // setup all the Il2CppAssemblies.
  164. for (int32_t assemblyIndex = 0; assemblyIndex < s_ImagesCount; assemblyIndex++)
  165. {
  166. Il2CppAssembly* assembly = s_AssembliesTable + assemblyIndex;
  167. ImageIndex assemblyImageIndex;
  168. il2cpp::vm::GlobalMetadata::BuildIl2CppAssembly(assembly, assemblyIndex, &assemblyImageIndex);
  169. assembly->image = il2cpp::vm::MetadataCache::GetImageFromIndex(assemblyImageIndex);
  170. Assembly::Register(assembly);
  171. }
  172. InitializeUnresolvedSignatureTable();
  173. #if IL2CPP_ENABLE_NATIVE_STACKTRACES
  174. std::vector<MethodDefinitionKey> managedMethods;
  175. il2cpp::vm::GlobalMetadata::GetAllManagedMethods(managedMethods);
  176. il2cpp::utils::NativeSymbol::RegisterMethods(managedMethods);
  177. #endif
  178. return true;
  179. }
  180. void il2cpp::vm::MetadataCache::ExecuteEagerStaticClassConstructors()
  181. {
  182. for (int32_t i = 0; i < s_AssembliesCount; i++)
  183. {
  184. const Il2CppImage* image = s_AssembliesTable[i].image;
  185. if (image->codeGenModule->staticConstructorTypeIndices != NULL)
  186. {
  187. TypeDefinitionIndex* indexPointer = image->codeGenModule->staticConstructorTypeIndices;
  188. while (*indexPointer) // 0 terminated
  189. {
  190. Il2CppMetadataTypeHandle handle = GetTypeHandleFromIndex(image, *indexPointer);
  191. Il2CppClass* klass = GlobalMetadata::GetTypeInfoFromHandle(handle);
  192. Runtime::ClassInit(klass);
  193. indexPointer++;
  194. }
  195. }
  196. }
  197. }
  198. typedef void(*Il2CppModuleInitializerMethodPointer)(const MethodInfo*);
  199. void il2cpp::vm::MetadataCache::ExecuteModuleInitializers()
  200. {
  201. for (int32_t i = 0; i < s_AssembliesCount; i++)
  202. {
  203. const Il2CppImage* image = s_AssembliesTable[i].image;
  204. if (image->codeGenModule->moduleInitializer != NULL)
  205. {
  206. Il2CppModuleInitializerMethodPointer moduleInitializer = (Il2CppModuleInitializerMethodPointer)image->codeGenModule->moduleInitializer;
  207. moduleInitializer(NULL);
  208. }
  209. }
  210. }
  211. void ClearGenericMethodTable()
  212. {
  213. s_MethodTableMap.clear();
  214. }
  215. void ClearWindowsRuntimeTypeNamesTables()
  216. {
  217. s_ClassToWindowsRuntimeTypeNameMap.clear();
  218. }
  219. void il2cpp::vm::MetadataCache::InitializeGuidToClassTable()
  220. {
  221. Il2CppInteropData* interopData = s_Il2CppCodeRegistration->interopData;
  222. uint32_t interopDataCount = s_Il2CppCodeRegistration->interopDataCount;
  223. std::vector<std::pair<const Il2CppGuid*, Il2CppClass*> > guidToNonImportClassMap;
  224. guidToNonImportClassMap.reserve(interopDataCount);
  225. for (uint32_t i = 0; i < interopDataCount; i++)
  226. {
  227. // It's important to check for non-import types because type projections will have identical GUIDs (e.g. IEnumerable<T> and IIterable<T>)
  228. if (interopData[i].guid != NULL)
  229. {
  230. Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(interopData[i].type);
  231. if (!klass->is_import_or_windows_runtime)
  232. guidToNonImportClassMap.push_back(std::make_pair(interopData[i].guid, klass));
  233. }
  234. }
  235. s_GuidToNonImportClassMap.assign(guidToNonImportClassMap);
  236. }
  237. // this is called later in the intialization cycle with more systems setup like GC
  238. void il2cpp::vm::MetadataCache::InitializeGCSafe()
  239. {
  240. il2cpp::vm::GlobalMetadata::InitializeStringLiteralTable();
  241. il2cpp::vm::GlobalMetadata::InitializeGenericMethodTable(s_MethodTableMap);
  242. il2cpp::vm::GlobalMetadata::InitializeWindowsRuntimeTypeNamesTables(s_WindowsRuntimeTypeNameToClassMap, s_ClassToWindowsRuntimeTypeNameMap);
  243. InitializeGuidToClassTable();
  244. }
  245. void ClearImageNames()
  246. {
  247. for (int32_t imageIndex = 0; imageIndex < s_ImagesCount; imageIndex++)
  248. {
  249. Il2CppImage* image = s_ImagesTable + imageIndex;
  250. IL2CPP_FREE((void*)image->nameNoExt);
  251. }
  252. }
  253. void il2cpp::vm::MetadataCache::Clear()
  254. {
  255. ClearGenericMethodTable();
  256. ClearWindowsRuntimeTypeNamesTables();
  257. delete s_pUnresolvedSignatureMap;
  258. Assembly::ClearAllAssemblies();
  259. ClearImageNames();
  260. IL2CPP_FREE(s_ImagesTable);
  261. s_ImagesTable = NULL;
  262. s_ImagesCount = 0;
  263. IL2CPP_FREE(s_AssembliesTable);
  264. s_AssembliesTable = NULL;
  265. s_AssembliesCount = 0;
  266. s_GenericMethodSet.clear();
  267. metadata::ArrayMetadata::Clear();
  268. s_GenericInstSet.Clear();
  269. s_Il2CppCodeRegistration = NULL;
  270. s_Il2CppCodeGenOptions = NULL;
  271. il2cpp::metadata::GenericMetadata::Clear();
  272. il2cpp::metadata::GenericMethod::ClearStatics();
  273. il2cpp::vm::GlobalMetadata::Clear();
  274. }
  275. void il2cpp::vm::MetadataCache::InitializeUnresolvedSignatureTable()
  276. {
  277. s_pUnresolvedSignatureMap = new Il2CppUnresolvedSignatureMap();
  278. il2cpp::vm::GlobalMetadata::InitializeUnresolvedSignatureTable(*s_pUnresolvedSignatureMap);
  279. }
  280. Il2CppClass* il2cpp::vm::MetadataCache::GetGenericInstanceType(Il2CppClass* genericTypeDefinition, const Il2CppType** genericArgumentTypes, uint32_t genericArgumentCount)
  281. {
  282. const Il2CppGenericInst* inst = il2cpp::vm::MetadataCache::GetGenericInst(genericArgumentTypes, genericArgumentCount);
  283. Il2CppGenericClass* genericClass = il2cpp::metadata::GenericMetadata::GetGenericClass(genericTypeDefinition, inst);
  284. return il2cpp::vm::GenericClass::GetClass(genericClass);
  285. }
  286. const MethodInfo* il2cpp::vm::MetadataCache::GetGenericInstanceMethod(const MethodInfo* genericMethodDefinition, const Il2CppType** genericArgumentTypes, uint32_t genericArgumentCount)
  287. {
  288. Il2CppGenericContext context = { NULL, GetGenericInst(genericArgumentTypes, genericArgumentCount) };
  289. return il2cpp::vm::GlobalMetadata::GetGenericInstanceMethod(genericMethodDefinition, &context);
  290. }
  291. const Il2CppGenericContext* il2cpp::vm::MetadataCache::GetMethodGenericContext(const MethodInfo* method)
  292. {
  293. if (!method->is_inflated)
  294. {
  295. IL2CPP_NOT_IMPLEMENTED(Image::GetMethodGenericContext);
  296. return NULL;
  297. }
  298. return &method->genericMethod->context;
  299. }
  300. const MethodInfo* il2cpp::vm::MetadataCache::GetGenericMethodDefinition(const MethodInfo* method)
  301. {
  302. if (!method->is_inflated)
  303. {
  304. IL2CPP_NOT_IMPLEMENTED(Image::GetGenericMethodDefinition);
  305. return NULL;
  306. }
  307. return method->genericMethod->methodDefinition;
  308. }
  309. Il2CppClass* il2cpp::vm::MetadataCache::GetPointerType(Il2CppClass* type)
  310. {
  311. Il2CppClass* pointerClass;
  312. if (s_MetadataCache.m_PointerTypes.TryGet(type, &pointerClass))
  313. return pointerClass;
  314. return NULL;
  315. }
  316. Il2CppClass* il2cpp::vm::MetadataCache::GetWindowsRuntimeClass(const char* fullName)
  317. {
  318. WindowsRuntimeTypeNameToClassMap::iterator it = s_WindowsRuntimeTypeNameToClassMap.find(fullName);
  319. if (it != s_WindowsRuntimeTypeNameToClassMap.end())
  320. return it->second;
  321. return NULL;
  322. }
  323. const char* il2cpp::vm::MetadataCache::GetWindowsRuntimeClassName(const Il2CppClass* klass)
  324. {
  325. ClassToWindowsRuntimeTypeNameMap::iterator it = s_ClassToWindowsRuntimeTypeNameMap.find(klass);
  326. if (it != s_ClassToWindowsRuntimeTypeNameMap.end())
  327. return it->second;
  328. return NULL;
  329. }
  330. Il2CppMethodPointer il2cpp::vm::MetadataCache::GetWindowsRuntimeFactoryCreationFunction(const char* fullName)
  331. {
  332. Il2CppClass* klass = GetWindowsRuntimeClass(fullName);
  333. if (klass == NULL)
  334. return NULL;
  335. WindowsRuntimeFactoryTable::iterator factoryEntry = s_WindowsRuntimeFactories.find_first(&klass->byval_arg);
  336. if (factoryEntry == s_WindowsRuntimeFactories.end())
  337. return NULL;
  338. return factoryEntry->createFactoryFunction;
  339. }
  340. Il2CppClass* il2cpp::vm::MetadataCache::GetClassForGuid(const Il2CppGuid* guid)
  341. {
  342. IL2CPP_ASSERT(guid != NULL);
  343. GuidToClassMap::iterator it = s_GuidToNonImportClassMap.find_first(guid);
  344. if (it != s_GuidToNonImportClassMap.end())
  345. return it->second;
  346. return NULL;
  347. }
  348. void il2cpp::vm::MetadataCache::AddPointerTypeLocked(Il2CppClass* type, Il2CppClass* pointerType, const il2cpp::os::FastAutoLock& lock)
  349. {
  350. // This method must be called while holding the g_MetadataLock to ensure that we don't insert the same pointer type twice
  351. // And WalkPointerTypes assumes this
  352. IL2CPP_ASSERT(lock.IsLock(&g_MetadataLock));
  353. s_MetadataCache.m_PointerTypes.Add(type, pointerType);
  354. }
  355. const Il2CppGenericInst* il2cpp::vm::MetadataCache::GetGenericInst(const Il2CppType* const* types, uint32_t typeCount)
  356. {
  357. // temporary inst to lookup a permanent one that may already exist
  358. Il2CppGenericInst inst;
  359. inst.type_argc = typeCount;
  360. inst.type_argv = (const Il2CppType**)types;
  361. const Il2CppGenericInst* foundInst;
  362. if (s_GenericInstSet.TryGet(&inst, &foundInst))
  363. return foundInst;
  364. il2cpp::os::FastAutoLock lock(&g_MetadataLock);
  365. // Check if instance was added while we were blocked on g_MetadataLock
  366. if (s_GenericInstSet.TryGet(&inst, &foundInst))
  367. return foundInst;
  368. Il2CppGenericInst* newInst = NULL;
  369. newInst = (Il2CppGenericInst*)MetadataMalloc(sizeof(Il2CppGenericInst));
  370. newInst->type_argc = typeCount;
  371. newInst->type_argv = (const Il2CppType**)MetadataMalloc(newInst->type_argc * sizeof(Il2CppType*));
  372. int index = 0;
  373. const Il2CppType* const* typesEnd = types + typeCount;
  374. for (const Il2CppType* const* iter = types; iter != typesEnd; ++iter, ++index)
  375. newInst->type_argv[index] = *iter;
  376. // Do this while still holding the g_MetadataLock to prevent the same instance from being added twice
  377. bool added = s_GenericInstSet.Add(newInst);
  378. IL2CPP_ASSERT(added);
  379. ++il2cpp_runtime_stats.generic_instance_count;
  380. return newInst;
  381. }
  382. static baselib::ReentrantLock s_GenericMethodMutex;
  383. const Il2CppGenericMethod* il2cpp::vm::MetadataCache::GetGenericMethod(const MethodInfo* methodDefinition, const Il2CppGenericInst* classInst, const Il2CppGenericInst* methodInst)
  384. {
  385. Il2CppGenericMethod method = { 0 };
  386. method.methodDefinition = methodDefinition;
  387. method.context.class_inst = classInst;
  388. method.context.method_inst = methodInst;
  389. il2cpp::os::FastAutoLock lock(&s_GenericMethodMutex);
  390. Il2CppGenericMethodSet::const_iterator iter = s_GenericMethodSet.find(&method);
  391. if (iter != s_GenericMethodSet.end())
  392. return *iter;
  393. Il2CppGenericMethod* newMethod = MetadataAllocGenericMethod();
  394. newMethod->methodDefinition = methodDefinition;
  395. newMethod->context.class_inst = classInst;
  396. newMethod->context.method_inst = methodInst;
  397. s_GenericMethodSet.insert(newMethod);
  398. return newMethod;
  399. }
  400. static bool IsShareableEnum(const Il2CppType* type)
  401. {
  402. // Base case for recursion - we've found an enum.
  403. if (il2cpp::vm::Type::IsEnum(type))
  404. return true;
  405. if (il2cpp::vm::Type::IsGenericInstance(type))
  406. {
  407. // Recursive case - look "inside" the generic instance type to see if this is a nested enum.
  408. Il2CppClass* definition = il2cpp::vm::GenericClass::GetTypeDefinition(type->data.generic_class);
  409. return IsShareableEnum(il2cpp::vm::Class::GetType(definition));
  410. }
  411. // Base case for recurion - this is not an enum or a generic instance type.
  412. return false;
  413. }
  414. static il2cpp::vm::GenericParameterRestriction IsReferenceTypeGenericConstraint(const Il2CppType* constraint)
  415. {
  416. // This must match GenericSharingAnalsyis.GetGenericParameterConstraintRestriction()
  417. if (constraint->type == IL2CPP_TYPE_VAR || constraint->type == IL2CPP_TYPE_MVAR)
  418. return il2cpp::vm::GenericParameterRestrictionNone;
  419. if (il2cpp::metadata::Il2CppTypeEqualityComparer::AreEqual(constraint, &il2cpp_defaults.enum_class->byval_arg))
  420. return il2cpp::vm::GenericParameterRestrictionValueType;
  421. if (il2cpp::metadata::Il2CppTypeEqualityComparer::AreEqual(constraint, &il2cpp_defaults.value_type_class->byval_arg))
  422. return il2cpp::vm::GenericParameterRestrictionNone; // Not a valid constraint, so consider it unconstrained
  423. else if (il2cpp::vm::Class::IsInterface(il2cpp::vm::Class::FromIl2CppType(constraint)))
  424. return il2cpp::vm::GenericParameterRestrictionNone; // Interfaces constraints can be satisfied by reference or value types
  425. // Any other type constraint e.g. T : SomeType, SomeType must be a reference type
  426. return il2cpp::vm::GenericParameterRestrictionReferenceType;
  427. }
  428. il2cpp::vm::GenericParameterRestriction il2cpp::vm::MetadataCache::IsReferenceTypeGenericParameter(Il2CppMetadataGenericParameterHandle genericParameter)
  429. {
  430. uint16_t flags = il2cpp::vm::GlobalMetadata::GetGenericParameterFlags(genericParameter);
  431. if ((flags & IL2CPP_GENERIC_PARAMETER_ATTRIBUTE_REFERENCE_TYPE_CONSTRAINT) != 0)
  432. return GenericParameterRestrictionReferenceType;
  433. if ((flags & IL2CPP_GENERIC_PARAMETER_ATTRIBUTE_NOT_NULLABLE_VALUE_TYPE_CONSTRAINT) != 0)
  434. return GenericParameterRestrictionValueType; // Must be a value type
  435. uint32_t count = il2cpp::vm::GlobalMetadata::GetGenericConstraintCount(genericParameter);
  436. for (uint32_t constraintIndex = 0; constraintIndex < count; ++constraintIndex)
  437. {
  438. const Il2CppType* constraint = il2cpp::vm::GlobalMetadata::GetGenericParameterConstraintFromIndex(genericParameter, constraintIndex);
  439. GenericParameterRestriction restriction = IsReferenceTypeGenericConstraint(constraint);
  440. if (restriction != GenericParameterRestrictionNone)
  441. return restriction;
  442. }
  443. return GenericParameterRestrictionNone;
  444. }
  445. static const Il2CppGenericInst* GetFullySharedInst(Il2CppMetadataGenericContainerHandle genericContainer, const Il2CppGenericInst* inst)
  446. {
  447. if (inst == NULL || !il2cpp::vm::Runtime::IsFullGenericSharingEnabled())
  448. return NULL;
  449. const Il2CppType** types = (const Il2CppType**)alloca(inst->type_argc * sizeof(Il2CppType*));
  450. for (uint32_t i = 0; i < inst->type_argc; ++i)
  451. {
  452. const Il2CppType* type;
  453. switch (il2cpp::vm::MetadataCache::IsReferenceTypeGenericParameter(il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex(genericContainer, i)))
  454. {
  455. case il2cpp::vm::GenericParameterRestrictionValueType:
  456. type = &il2cpp_defaults.il2cpp_fully_shared_struct_type->byval_arg;
  457. break;
  458. case il2cpp::vm::GenericParameterRestrictionReferenceType:
  459. type = &il2cpp_defaults.object_class->byval_arg;
  460. break;
  461. default:
  462. type = &il2cpp_defaults.il2cpp_fully_shared_type->byval_arg;
  463. break;
  464. }
  465. types[i] = type;
  466. }
  467. const Il2CppGenericInst* sharedInst = il2cpp::vm::MetadataCache::GetGenericInst(types, inst->type_argc);
  468. return sharedInst;
  469. }
  470. // this logic must match the C# logic in GenericSharingAnalysis.GetSharedTypeForGenericParameter
  471. static const Il2CppGenericInst* GetSharedInst(const Il2CppGenericInst* inst)
  472. {
  473. if (inst == NULL)
  474. return NULL;
  475. const Il2CppType** types = (const Il2CppType**)alloca(inst->type_argc * sizeof(Il2CppType*));
  476. for (uint32_t i = 0; i < inst->type_argc; ++i)
  477. {
  478. if (il2cpp::vm::Type::IsReference(inst->type_argv[i]))
  479. types[i] = &il2cpp_defaults.object_class->byval_arg;
  480. else
  481. {
  482. const Il2CppType* type = inst->type_argv[i];
  483. if (s_Il2CppCodeGenOptions->enablePrimitiveValueTypeGenericSharing)
  484. {
  485. if (IsShareableEnum(type))
  486. {
  487. const Il2CppType* underlyingType = il2cpp::vm::Type::GetUnderlyingType(type);
  488. switch (underlyingType->type)
  489. {
  490. case IL2CPP_TYPE_I1:
  491. type = &il2cpp_defaults.sbyte_shared_enum->byval_arg;
  492. break;
  493. case IL2CPP_TYPE_I2:
  494. type = &il2cpp_defaults.int16_shared_enum->byval_arg;
  495. break;
  496. case IL2CPP_TYPE_I4:
  497. type = &il2cpp_defaults.int32_shared_enum->byval_arg;
  498. break;
  499. case IL2CPP_TYPE_I8:
  500. type = &il2cpp_defaults.int64_shared_enum->byval_arg;
  501. break;
  502. case IL2CPP_TYPE_U1:
  503. type = &il2cpp_defaults.byte_shared_enum->byval_arg;
  504. break;
  505. case IL2CPP_TYPE_U2:
  506. case IL2CPP_TYPE_CHAR:
  507. type = &il2cpp_defaults.uint16_shared_enum->byval_arg;
  508. break;
  509. case IL2CPP_TYPE_U4:
  510. type = &il2cpp_defaults.uint32_shared_enum->byval_arg;
  511. break;
  512. case IL2CPP_TYPE_U8:
  513. type = &il2cpp_defaults.uint64_shared_enum->byval_arg;
  514. break;
  515. case IL2CPP_TYPE_I:
  516. case IL2CPP_TYPE_U:
  517. break;
  518. default:
  519. IL2CPP_ASSERT(0 && "Invalid enum underlying type");
  520. break;
  521. }
  522. }
  523. }
  524. if (il2cpp::vm::Type::IsGenericInstance(type))
  525. {
  526. const Il2CppGenericInst* sharedInst = GetSharedInst(type->data.generic_class->context.class_inst);
  527. Il2CppGenericClass* gklass = il2cpp::metadata::GenericMetadata::GetGenericClass(type->data.generic_class->type, sharedInst);
  528. Il2CppClass* klass = il2cpp::vm::GenericClass::GetClass(gklass);
  529. type = &klass->byval_arg;
  530. }
  531. types[i] = type;
  532. }
  533. }
  534. const Il2CppGenericInst* sharedInst = il2cpp::vm::MetadataCache::GetGenericInst(types, inst->type_argc);
  535. return sharedInst;
  536. }
  537. static il2cpp::vm::Il2CppGenericMethodPointers MakeGenericMethodPointers(const Il2CppGenericMethodIndices* methodIndicies, bool isFullyShared)
  538. {
  539. IL2CPP_ASSERT(methodIndicies->methodIndex >= 0 && (methodIndicies->invokerIndex >= 0 || methodIndicies->invokerIndex == kMethodIndexInvalid));
  540. if (static_cast<uint32_t>(methodIndicies->methodIndex) < s_Il2CppCodeRegistration->genericMethodPointersCount && static_cast<uint32_t>(methodIndicies->invokerIndex) < s_Il2CppCodeRegistration->invokerPointersCount)
  541. {
  542. Il2CppMethodPointer virtualMethod;
  543. Il2CppMethodPointer method;
  544. method = s_Il2CppCodeRegistration->genericMethodPointers[methodIndicies->methodIndex];
  545. if (methodIndicies->adjustorThunkIndex != -1)
  546. {
  547. virtualMethod = s_Il2CppCodeRegistration->genericAdjustorThunks[methodIndicies->adjustorThunkIndex];
  548. }
  549. else
  550. {
  551. virtualMethod = method;
  552. }
  553. InvokerMethod invokerMethod;
  554. if (methodIndicies->invokerIndex == kMethodIndexInvalid)
  555. invokerMethod = il2cpp::vm::Runtime::GetMissingMethodInvoker();
  556. else
  557. invokerMethod = s_Il2CppCodeRegistration->invokerPointers[methodIndicies->invokerIndex];
  558. return { method, virtualMethod, invokerMethod, isFullyShared };
  559. }
  560. return { NULL, NULL, NULL, false };
  561. }
  562. il2cpp::vm::Il2CppGenericMethodPointers il2cpp::vm::MetadataCache::GetGenericMethodPointers(const MethodInfo* methodDefinition, const Il2CppGenericContext* context)
  563. {
  564. Il2CppGenericMethod method = { 0 };
  565. method.methodDefinition = const_cast<MethodInfo*>(methodDefinition);
  566. method.context.class_inst = context->class_inst;
  567. method.context.method_inst = context->method_inst;
  568. Il2CppMethodTableMapIter iter = s_MethodTableMap.find(&method);
  569. if (iter != s_MethodTableMap.end())
  570. return MakeGenericMethodPointers(iter->second, false);
  571. // get the shared version if it exists
  572. method.context.class_inst = GetSharedInst(context->class_inst);
  573. method.context.method_inst = GetSharedInst(context->method_inst);
  574. iter = s_MethodTableMap.find(&method);
  575. if (iter != s_MethodTableMap.end())
  576. return MakeGenericMethodPointers(iter->second, false);
  577. // get the fully shared version if it exists
  578. method.context.class_inst = GetFullySharedInst(methodDefinition->klass->genericContainerHandle, context->class_inst);
  579. method.context.method_inst = GetFullySharedInst(methodDefinition->genericContainerHandle, context->method_inst);
  580. iter = s_MethodTableMap.find(&method);
  581. if (iter != s_MethodTableMap.end())
  582. return MakeGenericMethodPointers(iter->second, true);
  583. return { NULL, NULL, NULL };
  584. }
  585. const Il2CppType* il2cpp::vm::MetadataCache::GetIl2CppTypeFromIndex(const Il2CppImage* image, TypeIndex index)
  586. {
  587. return il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(index);
  588. }
  589. const Il2CppType* il2cpp::vm::MetadataCache::GetTypeFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef)
  590. {
  591. return il2cpp::vm::GlobalMetadata::GetTypeFromRgctxDefinition(rgctxDef);
  592. }
  593. const Il2CppGenericMethod* il2cpp::vm::MetadataCache::GetGenericMethodFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef)
  594. {
  595. return il2cpp::vm::GlobalMetadata::GetGenericMethodFromRgctxDefinition(rgctxDef);
  596. }
  597. std::pair<const Il2CppType*, const MethodInfo*> il2cpp::vm::MetadataCache::GetConstrainedCallFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef)
  598. {
  599. return il2cpp::vm::GlobalMetadata::GetConstrainedCallFromRgctxDefinition(rgctxDef);
  600. }
  601. const MethodInfo* il2cpp::vm::MetadataCache::GetMethodInfoFromVTableSlot(const Il2CppClass* klass, int32_t vTableSlot)
  602. {
  603. return il2cpp::vm::GlobalMetadata::GetMethodInfoFromVTableSlot(klass, vTableSlot);
  604. }
  605. static int CompareIl2CppTokenAdjustorThunkPair(const void* pkey, const void* pelem)
  606. {
  607. return (int)(((Il2CppTokenAdjustorThunkPair*)pkey)->token - ((Il2CppTokenAdjustorThunkPair*)pelem)->token);
  608. }
  609. Il2CppMethodPointer il2cpp::vm::MetadataCache::GetAdjustorThunk(const Il2CppImage* image, uint32_t token)
  610. {
  611. if (image->codeGenModule->adjustorThunkCount == 0)
  612. return NULL;
  613. Il2CppTokenAdjustorThunkPair key;
  614. memset(&key, 0, sizeof(Il2CppTokenAdjustorThunkPair));
  615. key.token = token;
  616. const Il2CppTokenAdjustorThunkPair* result = (const Il2CppTokenAdjustorThunkPair*)bsearch(&key, image->codeGenModule->adjustorThunks,
  617. image->codeGenModule->adjustorThunkCount, sizeof(Il2CppTokenAdjustorThunkPair), CompareIl2CppTokenAdjustorThunkPair);
  618. if (result == NULL)
  619. return NULL;
  620. return result->adjustorThunk;
  621. }
  622. Il2CppMethodPointer il2cpp::vm::MetadataCache::GetMethodPointer(const Il2CppImage* image, uint32_t token)
  623. {
  624. uint32_t rid = GetTokenRowId(token);
  625. uint32_t table = GetTokenType(token);
  626. if (rid == 0)
  627. return NULL;
  628. IL2CPP_ASSERT(rid <= image->codeGenModule->methodPointerCount);
  629. return image->codeGenModule->methodPointers[rid - 1];
  630. }
  631. InvokerMethod il2cpp::vm::MetadataCache::GetMethodInvoker(const Il2CppImage* image, uint32_t token)
  632. {
  633. uint32_t rid = GetTokenRowId(token);
  634. uint32_t table = GetTokenType(token);
  635. if (rid == 0)
  636. return Runtime::GetMissingMethodInvoker();
  637. int32_t index = image->codeGenModule->invokerIndices[rid - 1];
  638. if (index == (uint32_t)kMethodIndexInvalid)
  639. return Runtime::GetMissingMethodInvoker();
  640. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) < s_Il2CppCodeRegistration->invokerPointersCount);
  641. return s_Il2CppCodeRegistration->invokerPointers[index];
  642. }
  643. const Il2CppInteropData* il2cpp::vm::MetadataCache::GetInteropDataForType(const Il2CppType* type)
  644. {
  645. IL2CPP_ASSERT(type != NULL);
  646. InteropDataMap::iterator interopData = s_InteropData.find_first(type);
  647. if (interopData == s_InteropData.end())
  648. return NULL;
  649. return interopData;
  650. }
  651. static bool MatchTokens(Il2CppTokenIndexMethodTuple key, Il2CppTokenIndexMethodTuple element)
  652. {
  653. return key.token < element.token;
  654. }
  655. static bool GenericInstancesMatch(const MethodInfo* method, const MethodInfo* matchingMethod)
  656. {
  657. if (method->genericMethod->context.class_inst != NULL && matchingMethod->genericMethod->context.class_inst != NULL)
  658. {
  659. if (!il2cpp::metadata::Il2CppGenericInstCompare::AreEqual(method->genericMethod->context.class_inst, matchingMethod->genericMethod->context.class_inst))
  660. return false;
  661. }
  662. if (method->genericMethod->context.method_inst != NULL && matchingMethod->genericMethod->context.method_inst != NULL)
  663. {
  664. if (!il2cpp::metadata::Il2CppGenericInstCompare::AreEqual(method->genericMethod->context.method_inst, matchingMethod->genericMethod->context.method_inst))
  665. return false;
  666. }
  667. return true;
  668. }
  669. Il2CppMethodPointer il2cpp::vm::MetadataCache::GetReversePInvokeWrapper(const Il2CppImage* image, const MethodInfo* method)
  670. {
  671. if (image->codeGenModule->reversePInvokeWrapperCount == 0)
  672. return NULL;
  673. // For each image (i.e. assembly), the reverse pinvoke wrapper indices are in an array sorted by
  674. // metadata token. Each entry also might have the method metadata pointer, which is used to further
  675. // find methods that have a matching metadata token.
  676. Il2CppTokenIndexMethodTuple key;
  677. memset(&key, 0, sizeof(Il2CppTokenIndexMethodTuple));
  678. key.token = method->token;
  679. // Binary search for a range which matches the metadata token.
  680. auto begin = image->codeGenModule->reversePInvokeWrapperIndices;
  681. auto end = image->codeGenModule->reversePInvokeWrapperIndices + image->codeGenModule->reversePInvokeWrapperCount;
  682. auto matchingRange = std::equal_range(begin, end, key, &MatchTokens);
  683. int32_t index = -1;
  684. auto numberOfMatches = std::distance(matchingRange.first, matchingRange.second);
  685. if (numberOfMatches == 1)
  686. {
  687. if (method->genericMethod == NULL)
  688. {
  689. // We found one non-generic method.
  690. index = matchingRange.first->index;
  691. }
  692. else
  693. {
  694. // We found one generic method - let's make sure the class and method generic instances match. This reverse p/invoke
  695. // wrapper might be for a different inflated generic instance.
  696. const MethodInfo* possibleMatch = il2cpp::metadata::GenericMethod::GetMethod(il2cpp::vm::GlobalMetadata::GetGenericMethodFromTokenMethodTuple(matchingRange.first));
  697. if (possibleMatch->genericMethod != NULL && GenericInstancesMatch(method, possibleMatch))
  698. index = matchingRange.first->index;
  699. }
  700. }
  701. else if (numberOfMatches > 1)
  702. {
  703. // Multiple generic instance methods share the same token, since it is from the generic method definition.
  704. // To find the proper method, look for the one with a matching method metadata pointer.
  705. const Il2CppTokenIndexMethodTuple* currentMatch = matchingRange.first;
  706. const Il2CppTokenIndexMethodTuple* lastMatch = matchingRange.second;
  707. while (currentMatch != lastMatch)
  708. {
  709. // First, check the method metadata, and use it if it has been initialized.
  710. // If not, let's fall back to the generic method.
  711. const MethodInfo* possibleMatch = (const MethodInfo*)*currentMatch->method;
  712. if (!il2cpp::vm::GlobalMetadata::IsRuntimeMetadataInitialized(possibleMatch))
  713. possibleMatch = il2cpp::metadata::GenericMethod::GetMethod(il2cpp::vm::GlobalMetadata::GetGenericMethodFromTokenMethodTuple(currentMatch));
  714. if (possibleMatch == method)
  715. {
  716. index = currentMatch->index;
  717. break;
  718. }
  719. currentMatch++;
  720. }
  721. }
  722. if (index == -1)
  723. return NULL;
  724. IL2CPP_ASSERT(index >= 0 && static_cast<uint32_t>(index) < s_Il2CppCodeRegistration->reversePInvokeWrapperCount);
  725. return s_Il2CppCodeRegistration->reversePInvokeWrappers[index];
  726. }
  727. static const Il2CppType* GetReducedType(const Il2CppType* type)
  728. {
  729. if (type->byref)
  730. return &il2cpp_defaults.object_class->byval_arg;
  731. if (il2cpp::vm::Type::IsEnum(type))
  732. type = il2cpp::vm::Type::GetUnderlyingType(type);
  733. switch (type->type)
  734. {
  735. case IL2CPP_TYPE_BOOLEAN:
  736. return &il2cpp_defaults.byte_class->byval_arg;
  737. case IL2CPP_TYPE_CHAR:
  738. return &il2cpp_defaults.uint16_class->byval_arg;
  739. case IL2CPP_TYPE_BYREF:
  740. case IL2CPP_TYPE_CLASS:
  741. case IL2CPP_TYPE_OBJECT:
  742. case IL2CPP_TYPE_STRING:
  743. case IL2CPP_TYPE_ARRAY:
  744. case IL2CPP_TYPE_SZARRAY:
  745. return &il2cpp_defaults.object_class->byval_arg;
  746. case IL2CPP_TYPE_GENERICINST:
  747. if (il2cpp::vm::Type::IsValueType(type))
  748. {
  749. // We can't inflate a generic instance that contains generic arguments
  750. if (il2cpp::metadata::GenericMetadata::ContainsGenericParameters(type))
  751. return type;
  752. const Il2CppGenericInst* sharedInst = GetSharedInst(type->data.generic_class->context.class_inst);
  753. Il2CppGenericClass* gklass = il2cpp::metadata::GenericMetadata::GetGenericClass(type->data.generic_class->type, sharedInst);
  754. Il2CppClass* klass = il2cpp::vm::GenericClass::GetClass(gklass);
  755. return &klass->byval_arg;
  756. }
  757. return &il2cpp_defaults.object_class->byval_arg;
  758. default:
  759. return type;
  760. }
  761. }
  762. il2cpp::vm::Il2CppUnresolvedCallStubs il2cpp::vm::MetadataCache::GetUnresovledCallStubs(const MethodInfo* method)
  763. {
  764. il2cpp::vm::Il2CppUnresolvedCallStubs stubs;
  765. stubs.stubsFound = false;
  766. il2cpp::metadata::Il2CppSignature signature;
  767. signature.Count = method->parameters_count + 1;
  768. signature.Types = (const Il2CppType**)alloca(signature.Count * sizeof(Il2CppType*));
  769. signature.Types[0] = GetReducedType(method->return_type);
  770. for (int i = 0; i < method->parameters_count; ++i)
  771. signature.Types[i + 1] = GetReducedType(method->parameters[i]);
  772. Il2CppUnresolvedSignatureMapIter it = s_pUnresolvedSignatureMap->find(signature);
  773. if (it != s_pUnresolvedSignatureMap->end())
  774. {
  775. if (il2cpp::vm::Method::IsInstance(method))
  776. {
  777. stubs.methodPointer = s_Il2CppCodeRegistration->unresolvedInstanceCallPointers[it->second];
  778. stubs.virtualMethodPointer = s_Il2CppCodeRegistration->unresolvedVirtualCallPointers[it->second];
  779. stubs.stubsFound = true;
  780. }
  781. else
  782. {
  783. stubs.methodPointer = s_Il2CppCodeRegistration->unresolvedStaticCallPointers[it->second];
  784. stubs.virtualMethodPointer = stubs.methodPointer;
  785. stubs.stubsFound = true;
  786. }
  787. }
  788. else
  789. {
  790. const MethodInfo* entryPointNotFoundMethod = il2cpp::vm::Method::GetEntryPointNotFoundMethodInfo();
  791. stubs.methodPointer = entryPointNotFoundMethod->methodPointer;
  792. stubs.virtualMethodPointer = entryPointNotFoundMethod->methodPointer;
  793. }
  794. return stubs;
  795. }
  796. const Il2CppAssembly* il2cpp::vm::MetadataCache::GetAssemblyFromIndex(AssemblyIndex index)
  797. {
  798. if (index == kGenericContainerIndexInvalid)
  799. return NULL;
  800. IL2CPP_ASSERT(index <= s_AssembliesCount);
  801. return s_AssembliesTable + index;
  802. }
  803. const Il2CppAssembly* il2cpp::vm::MetadataCache::GetAssemblyByName(const char* nameToFind)
  804. {
  805. for (int i = 0; i < s_AssembliesCount; i++)
  806. {
  807. const Il2CppAssembly* assembly = s_AssembliesTable + i;
  808. const char* assemblyName = assembly->aname.name;
  809. if (strcmp(assemblyName, nameToFind) == 0)
  810. return assembly;
  811. }
  812. return NULL;
  813. }
  814. Il2CppImage* il2cpp::vm::MetadataCache::GetImageFromIndex(ImageIndex index)
  815. {
  816. if (index == kGenericContainerIndexInvalid)
  817. return NULL;
  818. IL2CPP_ASSERT(index <= s_ImagesCount);
  819. return s_ImagesTable + index;
  820. }
  821. Il2CppClass* il2cpp::vm::MetadataCache::GetTypeInfoFromType(const Il2CppType* type)
  822. {
  823. if (type == NULL)
  824. return NULL;
  825. return il2cpp::vm::GlobalMetadata::GetTypeInfoFromType(type);
  826. }
  827. Il2CppClass* il2cpp::vm::MetadataCache::GetTypeInfoFromHandle(Il2CppMetadataTypeHandle handle)
  828. {
  829. return il2cpp::vm::GlobalMetadata::GetTypeInfoFromHandle(handle);
  830. }
  831. Il2CppMetadataGenericContainerHandle il2cpp::vm::MetadataCache::GetGenericContainerFromGenericClass(const Il2CppImage* image, const Il2CppGenericClass* genericClass)
  832. {
  833. return il2cpp::vm::GlobalMetadata::GetGenericContainerFromGenericClass(genericClass);
  834. }
  835. Il2CppMetadataGenericContainerHandle il2cpp::vm::MetadataCache::GetGenericContainerFromMethod(Il2CppMetadataMethodDefinitionHandle handle)
  836. {
  837. return il2cpp::vm::GlobalMetadata::GetGenericContainerFromMethod(handle);
  838. }
  839. Il2CppMetadataGenericParameterHandle il2cpp::vm::MetadataCache::GetGenericParameterFromType(const Il2CppType* type)
  840. {
  841. return il2cpp::vm::GlobalMetadata::GetGenericParameterFromType(type);
  842. }
  843. Il2CppClass* il2cpp::vm::MetadataCache::GetContainerDeclaringType(Il2CppMetadataGenericContainerHandle handle)
  844. {
  845. return il2cpp::vm::GlobalMetadata::GetContainerDeclaringType(handle);
  846. }
  847. Il2CppClass* il2cpp::vm::MetadataCache::GetParameterDeclaringType(Il2CppMetadataGenericParameterHandle handle)
  848. {
  849. return il2cpp::vm::GlobalMetadata::GetParameterDeclaringType(handle);
  850. }
  851. const MethodInfo* il2cpp::vm::MetadataCache::GetParameterDeclaringMethod(Il2CppMetadataGenericParameterHandle handle)
  852. {
  853. return il2cpp::vm::GlobalMetadata::GetParameterDeclaringMethod(handle);
  854. }
  855. Il2CppMetadataGenericParameterHandle il2cpp::vm::MetadataCache::GetGenericParameterFromIndex(Il2CppMetadataGenericContainerHandle handle, GenericContainerParameterIndex index)
  856. {
  857. return il2cpp::vm::GlobalMetadata::GetGenericParameterFromIndex(handle, index);
  858. }
  859. const Il2CppType* il2cpp::vm::MetadataCache::GetGenericParameterConstraintFromIndex(Il2CppMetadataGenericParameterHandle handle, GenericParameterConstraintIndex index)
  860. {
  861. return il2cpp::vm::GlobalMetadata::GetGenericParameterConstraintFromIndex(handle, index);
  862. }
  863. Il2CppClass* il2cpp::vm::MetadataCache::GetNestedTypeFromOffset(const Il2CppClass* klass, TypeNestedTypeIndex offset)
  864. {
  865. return il2cpp::vm::GlobalMetadata::GetNestedTypeFromOffset(klass, offset);
  866. }
  867. const Il2CppType* il2cpp::vm::MetadataCache::GetInterfaceFromOffset(const Il2CppClass* klass, TypeInterfaceIndex offset)
  868. {
  869. return il2cpp::vm::GlobalMetadata::GetInterfaceFromOffset(klass, offset);
  870. }
  871. Il2CppInterfaceOffsetInfo il2cpp::vm::MetadataCache::GetInterfaceOffsetInfo(const Il2CppClass* klass, TypeInterfaceOffsetIndex index)
  872. {
  873. return il2cpp::vm::GlobalMetadata::GetInterfaceOffsetInfo(klass, index);
  874. }
  875. static int CompareIl2CppTokenRangePair(const void* pkey, const void* pelem)
  876. {
  877. return (int)(((Il2CppTokenRangePair*)pkey)->token - ((Il2CppTokenRangePair*)pelem)->token);
  878. }
  879. il2cpp::vm::RGCTXCollection il2cpp::vm::MetadataCache::GetRGCTXs(const Il2CppImage* image, uint32_t token)
  880. {
  881. RGCTXCollection collection = { 0, NULL };
  882. if (image->codeGenModule->rgctxRangesCount == 0)
  883. return collection;
  884. Il2CppTokenRangePair key;
  885. memset(&key, 0, sizeof(Il2CppTokenRangePair));
  886. key.token = token;
  887. const Il2CppTokenRangePair* res = (const Il2CppTokenRangePair*)bsearch(&key, image->codeGenModule->rgctxRanges, image->codeGenModule->rgctxRangesCount, sizeof(Il2CppTokenRangePair), CompareIl2CppTokenRangePair);
  888. if (res == NULL)
  889. return collection;
  890. collection.count = res->range.length;
  891. collection.items = image->codeGenModule->rgctxs + res->range.start;
  892. return collection;
  893. }
  894. const uint8_t* il2cpp::vm::MetadataCache::GetFieldDefaultValue(const FieldInfo* field, const Il2CppType** type)
  895. {
  896. return il2cpp::vm::GlobalMetadata::GetFieldDefaultValue(field, type);
  897. }
  898. const uint8_t* il2cpp::vm::MetadataCache::GetParameterDefaultValue(const MethodInfo* method, int32_t parameterPosition, const Il2CppType** type, bool* isExplicitySetNullDefaultValue)
  899. {
  900. return il2cpp::vm::GlobalMetadata::GetParameterDefaultValue(method, parameterPosition, type, isExplicitySetNullDefaultValue);
  901. }
  902. int il2cpp::vm::MetadataCache::GetFieldMarshaledSizeForField(const FieldInfo* field)
  903. {
  904. return il2cpp::vm::GlobalMetadata::GetFieldMarshaledSizeForField(field);
  905. }
  906. int32_t il2cpp::vm::MetadataCache::GetFieldOffsetFromIndexLocked(const Il2CppClass* klass, int32_t fieldIndexInType, FieldInfo* field, const il2cpp::os::FastAutoLock& lock)
  907. {
  908. int32_t offset = il2cpp::vm::GlobalMetadata::GetFieldOffset(klass, fieldIndexInType, field);
  909. if (offset < 0)
  910. {
  911. AddThreadLocalStaticOffsetForFieldLocked(field, offset & ~THREAD_LOCAL_STATIC_MASK, lock);
  912. return THREAD_STATIC_FIELD_OFFSET;
  913. }
  914. return offset;
  915. }
  916. void il2cpp::vm::MetadataCache::AddThreadLocalStaticOffsetForFieldLocked(FieldInfo* field, int32_t offset, const il2cpp::os::FastAutoLock& lock)
  917. {
  918. s_ThreadLocalStaticOffsetMap.add(field, offset);
  919. }
  920. int32_t il2cpp::vm::MetadataCache::GetThreadLocalStaticOffsetForField(FieldInfo* field)
  921. {
  922. IL2CPP_ASSERT(field->offset == THREAD_STATIC_FIELD_OFFSET);
  923. il2cpp::os::FastAutoLock lock(&g_MetadataLock);
  924. Il2CppThreadLocalStaticOffsetHashMapIter iter = s_ThreadLocalStaticOffsetMap.find(field);
  925. IL2CPP_ASSERT(iter != s_ThreadLocalStaticOffsetMap.end());
  926. return iter->second;
  927. }
  928. Il2CppMetadataCustomAttributeHandle il2cpp::vm::MetadataCache::GetCustomAttributeTypeToken(const Il2CppImage* image, uint32_t token)
  929. {
  930. return il2cpp::vm::GlobalMetadata::GetCustomAttributeTypeToken(image, token);
  931. }
  932. il2cpp::metadata::CustomAttributeDataReader il2cpp::vm::MetadataCache::GetCustomAttributeDataReader(const Il2CppImage* image, uint32_t token)
  933. {
  934. return il2cpp::vm::GlobalMetadata::GetCustomAttributeDataReader(image, token);
  935. }
  936. il2cpp::metadata::CustomAttributeDataReader il2cpp::vm::MetadataCache::GetCustomAttributeDataReader(Il2CppMetadataCustomAttributeHandle handle)
  937. {
  938. return il2cpp::vm::GlobalMetadata::GetCustomAttributeDataReader(handle);
  939. }
  940. const Il2CppAssembly* il2cpp::vm::MetadataCache::GetReferencedAssembly(const Il2CppAssembly* assembly, int32_t referencedAssemblyTableIndex)
  941. {
  942. return il2cpp::vm::GlobalMetadata::GetReferencedAssembly(assembly, referencedAssemblyTableIndex, s_AssembliesTable, s_AssembliesCount);
  943. }
  944. void il2cpp::vm::MetadataCache::InitializeAllMethodMetadata()
  945. {
  946. il2cpp::vm::GlobalMetadata::InitializeAllMethodMetadata();
  947. }
  948. void* il2cpp::vm::MetadataCache::InitializeRuntimeMetadata(uintptr_t* metadataPointer)
  949. {
  950. return il2cpp::vm::GlobalMetadata::InitializeRuntimeMetadata(metadataPointer, true);
  951. }
  952. void il2cpp::vm::MetadataCache::WalkPointerTypes(WalkTypesCallback callback, void* context)
  953. {
  954. os::FastAutoLock lock(&g_MetadataLock);
  955. for (PointerTypeMap::iterator it = s_MetadataCache.m_PointerTypes.UnlockedBegin(); it != s_MetadataCache.m_PointerTypes.UnlockedEnd(); it++)
  956. {
  957. callback(it->second, context);
  958. }
  959. }
  960. Il2CppMetadataTypeHandle il2cpp::vm::MetadataCache::GetTypeHandleFromIndex(const Il2CppImage* image, TypeDefinitionIndex typeIndex)
  961. {
  962. return il2cpp::vm::GlobalMetadata::GetTypeHandleFromIndex(typeIndex);
  963. }
  964. Il2CppMetadataTypeHandle il2cpp::vm::MetadataCache::GetTypeHandleFromType(const Il2CppType* type)
  965. {
  966. return il2cpp::vm::GlobalMetadata::GetTypeHandleFromType(type);
  967. }
  968. bool il2cpp::vm::MetadataCache::TypeIsNested(Il2CppMetadataTypeHandle handle)
  969. {
  970. return il2cpp::vm::GlobalMetadata::TypeIsNested(handle);
  971. }
  972. bool il2cpp::vm::MetadataCache::TypeIsValueType(Il2CppMetadataTypeHandle handle)
  973. {
  974. return il2cpp::vm::GlobalMetadata::TypeIsValueType(handle);
  975. }
  976. bool il2cpp::vm::MetadataCache::StructLayoutPackIsDefault(Il2CppMetadataTypeHandle handle)
  977. {
  978. return il2cpp::vm::GlobalMetadata::StructLayoutPackIsDefault(handle);
  979. }
  980. int32_t il2cpp::vm::MetadataCache::StructLayoutPack(Il2CppMetadataTypeHandle handle)
  981. {
  982. return il2cpp::vm::GlobalMetadata::StructLayoutPack(handle);
  983. }
  984. bool il2cpp::vm::MetadataCache::StructLayoutSizeIsDefault(Il2CppMetadataTypeHandle handle)
  985. {
  986. return il2cpp::vm::GlobalMetadata::StructLayoutSizeIsDefault(handle);
  987. }
  988. std::pair<const char*, const char*> il2cpp::vm::MetadataCache::GetTypeNamespaceAndName(Il2CppMetadataTypeHandle handle)
  989. {
  990. return il2cpp::vm::GlobalMetadata::GetTypeNamespaceAndName(handle);
  991. }
  992. Il2CppMetadataTypeHandle il2cpp::vm::MetadataCache::GetNestedTypes(Il2CppClass *klass, void* *iter)
  993. {
  994. return GetNestedTypes(
  995. klass->typeMetadataHandle,
  996. iter
  997. );
  998. }
  999. Il2CppMetadataTypeHandle il2cpp::vm::MetadataCache::GetNestedTypes(Il2CppMetadataTypeHandle handle, void** iter)
  1000. {
  1001. return il2cpp::vm::GlobalMetadata::GetNestedTypes(handle, iter);
  1002. }
  1003. Il2CppMetadataFieldInfo il2cpp::vm::MetadataCache::GetFieldInfo(const Il2CppClass* klass, TypeFieldIndex fieldIndex)
  1004. {
  1005. return il2cpp::vm::GlobalMetadata::GetFieldInfo(klass, fieldIndex);
  1006. }
  1007. Il2CppMetadataMethodInfo il2cpp::vm::MetadataCache::GetMethodInfo(const Il2CppClass* klass, TypeMethodIndex index)
  1008. {
  1009. return il2cpp::vm::GlobalMetadata::GetMethodInfo(klass, index);
  1010. }
  1011. Il2CppMetadataParameterInfo il2cpp::vm::MetadataCache::GetParameterInfo(const Il2CppClass* klass, Il2CppMetadataMethodDefinitionHandle handle, MethodParameterIndex paramIndex)
  1012. {
  1013. return il2cpp::vm::GlobalMetadata::GetParameterInfo(klass, handle, paramIndex);
  1014. }
  1015. Il2CppMetadataPropertyInfo il2cpp::vm::MetadataCache::GetPropertyInfo(const Il2CppClass* klass, TypePropertyIndex index)
  1016. {
  1017. return il2cpp::vm::GlobalMetadata::GetPropertyInfo(klass, index);
  1018. }
  1019. Il2CppMetadataEventInfo il2cpp::vm::MetadataCache::GetEventInfo(const Il2CppClass* klass, TypeEventIndex index)
  1020. {
  1021. return il2cpp::vm::GlobalMetadata::GetEventInfo(klass, index);
  1022. }
  1023. uint32_t il2cpp::vm::MetadataCache::GetGenericContainerCount(Il2CppMetadataGenericContainerHandle handle)
  1024. {
  1025. return il2cpp::vm::GlobalMetadata::GetGenericContainerCount(handle);
  1026. }
  1027. void il2cpp::vm::MetadataCache::MakeGenericArgType(Il2CppMetadataGenericContainerHandle containerHandle, Il2CppMetadataGenericParameterHandle paramHandle, Il2CppType* arg)
  1028. {
  1029. return il2cpp::vm::GlobalMetadata::MakeGenericArgType(containerHandle, paramHandle, arg);
  1030. }
  1031. bool il2cpp::vm::MetadataCache::GetGenericContainerIsMethod(Il2CppMetadataGenericContainerHandle handle)
  1032. {
  1033. return il2cpp::vm::GlobalMetadata::GetGenericContainerIsMethod(handle);
  1034. }
  1035. int16_t il2cpp::vm::MetadataCache::GetGenericConstraintCount(Il2CppMetadataGenericParameterHandle handle)
  1036. {
  1037. return il2cpp::vm::GlobalMetadata::GetGenericConstraintCount(handle);
  1038. }
  1039. const char* il2cpp::vm::MetadataCache::GetGenericParameterName(Il2CppMetadataGenericParameterHandle handle)
  1040. {
  1041. return il2cpp::vm::GlobalMetadata::GetGenericParameterName(handle);
  1042. }
  1043. Il2CppGenericParameterInfo il2cpp::vm::MetadataCache::GetGenericParameterInfo(Il2CppMetadataGenericParameterHandle handle)
  1044. {
  1045. return il2cpp::vm::GlobalMetadata::GetGenericParameterInfo(handle);
  1046. }
  1047. uint16_t il2cpp::vm::MetadataCache::GetGenericParameterFlags(Il2CppMetadataGenericParameterHandle handle)
  1048. {
  1049. return il2cpp::vm::GlobalMetadata::GetGenericParameterFlags(handle);
  1050. }
  1051. const MethodInfo* il2cpp::vm::MetadataCache::GetMethodInfoFromCatchPoint(const Il2CppImage* image, const Il2CppCatchPoint* cp)
  1052. {
  1053. return il2cpp::vm::GlobalMetadata::GetMethodInfoFromCatchPoint(cp);
  1054. }
  1055. const MethodInfo* il2cpp::vm::MetadataCache::GetMethodInfoFromSequencePoint(const Il2CppImage* image, const Il2CppSequencePoint* seqPoint)
  1056. {
  1057. return il2cpp::vm::GlobalMetadata::GetMethodInfoFromSequencePoint(seqPoint);
  1058. }
  1059. Il2CppClass* il2cpp::vm::MetadataCache::GetTypeInfoFromTypeSourcePair(const Il2CppImage* image, const Il2CppTypeSourceFilePair* pair)
  1060. {
  1061. return il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeSourcePair(pair);
  1062. }