SuperSetAOTHomologousImage.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. #include "SuperSetAOTHomologousImage.h"
  2. #include "vm/MetadataLock.h"
  3. #include "vm/GlobalMetadata.h"
  4. #include "vm/Class.h"
  5. #include "vm/Image.h"
  6. #include "vm/Exception.h"
  7. #include "vm/MetadataCache.h"
  8. #include "metadata/GenericMetadata.h"
  9. #include "MetadataPool.h"
  10. namespace hybridclr
  11. {
  12. namespace metadata
  13. {
  14. const Il2CppMethodDefinition* FindMatchMethod(const Il2CppTypeDefinition* aotTypeDef, const SuperSetMethodDefDetail& method2, const char* methodName, const MethodRefSig& methodSignature)
  15. {
  16. const Il2CppGenericContainer* klassGenContainer = aotTypeDef->genericContainerIndex != kGenericContainerIndexInvalid ?
  17. (const Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(aotTypeDef->genericContainerIndex) : nullptr;
  18. for (uint16_t i = 0; i < aotTypeDef->method_count; i++)
  19. {
  20. //const MethodInfo* method1 = klass1->methods[i];
  21. const Il2CppMethodDefinition* aotMethodDef = il2cpp::vm::GlobalMetadata::GetMethodDefinitionFromIndex(aotTypeDef->methodStart + i);
  22. const char* aotMethodName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(aotMethodDef->nameIndex);
  23. if (std::strcmp(aotMethodName, methodName))
  24. {
  25. continue;
  26. }
  27. if (IsMatchMethodSig(aotMethodDef, methodSignature, klassGenContainer))
  28. {
  29. return aotMethodDef;
  30. }
  31. }
  32. return nullptr;
  33. }
  34. const Il2CppFieldDefinition* FindMatchField(const Il2CppTypeDefinition* aotTypeDef, const SuperSetFieldDefDetail& field2, const char* fieldName, const Il2CppType* fieldType)
  35. {
  36. const Il2CppGenericContainer* klassGenContainer = aotTypeDef->genericContainerIndex != kGenericContainerIndexInvalid ?
  37. (const Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(aotTypeDef->genericContainerIndex) : nullptr;
  38. for (uint16_t i = 0; i < aotTypeDef->field_count; i++)
  39. {
  40. //const FieldInfo* field1 = klass1->fields + i;
  41. const Il2CppFieldDefinition* aotField = il2cpp::vm::GlobalMetadata::GetFieldDefinitionFromTypeDefAndFieldIndex(aotTypeDef, i);
  42. const char* aotFieldName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(aotField->nameIndex);
  43. if (std::strcmp(aotFieldName, fieldName))
  44. {
  45. continue;
  46. }
  47. const Il2CppType* aotFieldType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(aotField->typeIndex);
  48. if (IsMatchSigType(aotFieldType, fieldType, klassGenContainer, nullptr))
  49. {
  50. return aotField;
  51. }
  52. }
  53. return nullptr;
  54. }
  55. void SuperSetAOTHomologousImage::InitRuntimeMetadatas()
  56. {
  57. _defaultIl2CppType = &il2cpp_defaults.missing_class->byval_arg;
  58. std::vector< SuperSetTypeIntermediateInfo> typeIntermediateInfos;
  59. InitTypes0(typeIntermediateInfos);
  60. InitNestedClass(typeIntermediateInfos);
  61. InitTypes1(typeIntermediateInfos);
  62. InitMethods(typeIntermediateInfos);
  63. InitFields(typeIntermediateInfos);
  64. }
  65. void SuperSetAOTHomologousImage::InitTypes0(std::vector< SuperSetTypeIntermediateInfo>& typeIntermediateInfos)
  66. {
  67. const Table& typeDefTb = _rawImage->GetTable(TableType::TYPEDEF);
  68. uint32_t typeCount = typeDefTb.rowNum;
  69. typeIntermediateInfos.resize(typeCount);
  70. _typeDefs.resize(typeCount);
  71. _aotTypeIndex2TypeDefs.resize(typeCount);
  72. }
  73. void SuperSetAOTHomologousImage::InitNestedClass(std::vector<SuperSetTypeIntermediateInfo>& typeIntermediateInfos)
  74. {
  75. const Table& nestedClassTb = _rawImage->GetTable(TableType::NESTEDCLASS);
  76. for (uint32_t i = 0; i < nestedClassTb.rowNum; i++)
  77. {
  78. TbNestedClass data = _rawImage->ReadNestedClass(i + 1);
  79. SuperSetTypeIntermediateInfo& nestedType = typeIntermediateInfos[data.nestedClass - 1];
  80. nestedType.homoParentRowIndex = data.enclosingClass;
  81. }
  82. }
  83. void SuperSetAOTHomologousImage::InitType(std::vector<SuperSetTypeIntermediateInfo>& typeIntermediateInfos, SuperSetTypeIntermediateInfo& type)
  84. {
  85. if (type.inited)
  86. {
  87. return;
  88. }
  89. type.inited = true;
  90. uint32_t rowIndex = (uint32_t)(&type - &typeIntermediateInfos[0] + 1);
  91. TbTypeDef data = _rawImage->ReadTypeDef(rowIndex);
  92. type.homoMethodStartIndex = data.methodList;
  93. type.homoFieldStartIndex = data.fieldList;
  94. const char* name = _rawImage->GetStringFromRawIndex(data.typeName);
  95. const char* namespaze = _rawImage->GetStringFromRawIndex(data.typeNamespace);
  96. if (type.homoParentRowIndex)
  97. {
  98. SuperSetTypeIntermediateInfo& parent = typeIntermediateInfos[type.homoParentRowIndex - 1];
  99. InitType(typeIntermediateInfos, parent);
  100. const Il2CppTypeDefinition* parentTypeDef = parent.aotTypeDef;
  101. if (parentTypeDef == nullptr)
  102. {
  103. goto labelInitDefault;
  104. }
  105. void* iter = nullptr;
  106. for (const Il2CppTypeDefinition* nextTypeDef; (nextTypeDef = (const Il2CppTypeDefinition*)il2cpp::vm::GlobalMetadata::GetNestedTypes((Il2CppMetadataTypeHandle)parentTypeDef, &iter));)
  107. {
  108. const char* nestedTypeName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(nextTypeDef->nameIndex);
  109. IL2CPP_ASSERT(nestedTypeName);
  110. if (!std::strcmp(name, nestedTypeName))
  111. {
  112. type.aotTypeDef = nextTypeDef;
  113. //type.aotTypeIndex = nextTypeDef->byvalTypeIndex;
  114. type.aotIl2CppType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(nextTypeDef->byvalTypeIndex);
  115. //type.aotKlass = il2cpp::vm::GlobalMetadata::GetTypeInfoFromHandle((Il2CppMetadataTypeHandle)nextTypeDef);
  116. return;
  117. }
  118. }
  119. }
  120. else
  121. {
  122. const Il2CppTypeDefinition* aotTypeDef = (const Il2CppTypeDefinition*)il2cpp::vm::Image::TypeHandleFromName(_aotAssembly->image, namespaze, name);
  123. if (aotTypeDef)
  124. {
  125. type.aotTypeDef = aotTypeDef;
  126. type.aotIl2CppType = il2cpp::vm::GlobalMetadata::GetIl2CppTypeFromIndex(aotTypeDef->byvalTypeIndex);
  127. //type.aotTypeIndex = type.aotTypeDef->byvalTypeIndex;
  128. return;
  129. }
  130. }
  131. labelInitDefault:
  132. type.aotIl2CppType = _defaultIl2CppType;
  133. //TEMP_FORMAT(msg, "type: %s::%s can't find homologous type in assembly:%s", type.namespaze, type.name, _aotAssembly->aname.name);
  134. //RaiseExecutionEngineException(msg);
  135. }
  136. void SuperSetAOTHomologousImage::InitTypes1(std::vector<SuperSetTypeIntermediateInfo>& typeIntermediateInfos)
  137. {
  138. for (SuperSetTypeIntermediateInfo& td : typeIntermediateInfos)
  139. {
  140. //uint32_t rowIndex = ++index;
  141. //TbTypeDef data = _rawImage->ReadTypeDef(rowIndex);
  142. //td.inited = false;
  143. //td.homoParentRowIndex = 0;
  144. //td.homoRowIndex = rowIndex;
  145. //td.homoMethodStartIndex = data.methodList;
  146. //td.homoFieldStartIndex = data.fieldList;
  147. //td.name = _rawImage->GetStringFromRawIndex(data.typeName);
  148. //td.namespaze = _rawImage->GetStringFromRawIndex(data.typeNamespace);
  149. InitType(typeIntermediateInfos, td);
  150. }
  151. uint32_t index = 0;
  152. for (SuperSetTypeIntermediateInfo& td : typeIntermediateInfos)
  153. {
  154. SuperSetTypeDefDetail& type = _typeDefs[index++];
  155. type.aotIl2CppType = td.aotIl2CppType;
  156. if (td.aotTypeDef)
  157. {
  158. _aotTypeIndex2TypeDefs[il2cpp::vm::GlobalMetadata::GetIndexForTypeDefinition(td.aotTypeDef)] = &type;
  159. }
  160. }
  161. }
  162. void SuperSetAOTHomologousImage::InitMethods(std::vector<SuperSetTypeIntermediateInfo>& typeIntermediateInfos)
  163. {
  164. const Table& methodTb = _rawImage->GetTable(TableType::METHOD);
  165. uint32_t methodCount = methodTb.rowNum;
  166. _methodDefs.resize(methodCount);
  167. //_token2MethodDefs.resize(methodCount * 2);
  168. uint32_t typeCount = (uint32_t)typeIntermediateInfos.size();
  169. for (SuperSetTypeIntermediateInfo& type : typeIntermediateInfos)
  170. {
  171. uint32_t nextTypeIndex = (uint32_t)(&type - &typeIntermediateInfos[0] + 1);
  172. uint32_t nextTypeMethodStartIndex = nextTypeIndex < typeCount ? typeIntermediateInfos[nextTypeIndex].homoMethodStartIndex : methodCount + 1;
  173. for (uint32_t i = type.homoMethodStartIndex; i < nextTypeMethodStartIndex ; i++)
  174. {
  175. SuperSetMethodDefDetail& method = _methodDefs[i - 1];
  176. TbMethod data = _rawImage->ReadMethod(i);
  177. //method.declaringTypeDef = type.aotTypeDef;
  178. //method.name = _rawImage->GetStringFromRawIndex(data.name);
  179. if (type.aotTypeDef == nullptr)
  180. {
  181. continue;
  182. }
  183. MethodRefSig signature = {};
  184. signature.flags = data.flags;
  185. BlobReader methodSigReader = _rawImage->GetBlobReaderByRawIndex(data.signature);
  186. ReadMethodDefSig(methodSigReader, signature);
  187. const char* methodName = _rawImage->GetStringFromRawIndex(data.name);
  188. method.aotMethodDef = FindMatchMethod(type.aotTypeDef, method, methodName, signature);
  189. if (method.aotMethodDef &&
  190. (type.aotTypeDef->genericContainerIndex != kGenericContainerIndexInvalid
  191. || method.aotMethodDef->genericContainerIndex != kGenericContainerIndexInvalid))
  192. {
  193. _token2MethodDefs[method.aotMethodDef->token] = &method;
  194. }
  195. }
  196. }
  197. }
  198. void SuperSetAOTHomologousImage::ReadMethodDefSig(BlobReader& reader, MethodRefSig& method)
  199. {
  200. uint8_t rawSigFlags = reader.ReadByte();
  201. if (rawSigFlags & (uint8_t)MethodSigFlags::GENERIC)
  202. {
  203. //IL2CPP_ASSERT(false);
  204. method.genericParamCount = reader.ReadCompressedUint32();
  205. IL2CPP_ASSERT(method.genericParamCount > 0);
  206. }
  207. uint32_t paramCount = reader.ReadCompressedUint32();
  208. //IL2CPP_ASSERT(paramCount >= methodDef.parameterCount);
  209. method.returnType = ReadType(reader, nullptr, nullptr);
  210. int readParamNum = 0;
  211. for (; reader.NonEmpty(); )
  212. {
  213. const Il2CppType* paramType = ReadType(reader, nullptr, nullptr);
  214. method.params.push_back(paramType);
  215. ++readParamNum;
  216. }
  217. IL2CPP_ASSERT(readParamNum == (int)paramCount);
  218. }
  219. void SuperSetAOTHomologousImage::InitFields(std::vector<SuperSetTypeIntermediateInfo>& typeIntermediateInfos)
  220. {
  221. const Table& fieldTb = _rawImage->GetTable(TableType::FIELD);
  222. uint32_t fieldCount = fieldTb.rowNum;
  223. _fields.resize(fieldTb.rowNum);
  224. uint32_t typeCount = (uint32_t)typeIntermediateInfos.size();
  225. for (SuperSetTypeIntermediateInfo& type : typeIntermediateInfos)
  226. {
  227. uint32_t nextTypeIndex = (uint32_t)(&type - &typeIntermediateInfos[0] + 1);
  228. uint32_t nextTypeFieldStartIndex = nextTypeIndex < typeCount ? typeIntermediateInfos[nextTypeIndex].homoFieldStartIndex : fieldCount + 1;
  229. for (uint32_t i = type.homoFieldStartIndex; i < nextTypeFieldStartIndex; i++)
  230. {
  231. SuperSetFieldDefDetail& field = _fields[i - 1];
  232. //field.homoRowIndex = i;
  233. TbField data = _rawImage->ReadField(i);
  234. //field.name = _rawImage->GetStringFromRawIndex(data.name);
  235. //field.declaringTypeDef = type.aotTypeDef;
  236. field.declaringIl2CppType = type.aotIl2CppType;
  237. if (type.aotTypeDef == nullptr)
  238. {
  239. continue;
  240. }
  241. BlobReader br = _rawImage->GetBlobReaderByRawIndex(data.signature);
  242. FieldRefSig frs;
  243. ReadFieldRefSig(br, nullptr, frs);
  244. if (data.flags)
  245. {
  246. Il2CppType* newType = MetadataPool::ShallowCloneIl2CppType(frs.type);
  247. newType->attrs = data.flags;
  248. frs.type = newType;
  249. }
  250. const char* fieldName = _rawImage->GetStringFromRawIndex(data.name);
  251. field.aotFieldDef = FindMatchField(type.aotTypeDef, field, fieldName, frs.type);
  252. }
  253. }
  254. }
  255. MethodBody* SuperSetAOTHomologousImage::GetMethodBody(uint32_t token)
  256. {
  257. auto it = _token2MethodDefs.find(token);
  258. if (it == _token2MethodDefs.end())
  259. {
  260. return nullptr;
  261. }
  262. SuperSetMethodDefDetail* method = it->second;
  263. uint32_t rowIndex = (uint32_t)(method - &_methodDefs[0] + 1);
  264. TbMethod methodData = _rawImage->ReadMethod(rowIndex);
  265. MethodBody* body = new (HYBRIDCLR_MALLOC_ZERO(sizeof(MethodBody))) MethodBody();
  266. ReadMethodBody(*method->aotMethodDef, methodData, *body);
  267. return body;
  268. }
  269. const Il2CppType* SuperSetAOTHomologousImage::GetIl2CppTypeFromRawTypeDefIndex(uint32_t index)
  270. {
  271. IL2CPP_ASSERT((size_t)index < _typeDefs.size());
  272. return _typeDefs[index].aotIl2CppType;
  273. }
  274. Il2CppGenericContainer* SuperSetAOTHomologousImage::GetGenericContainerByRawIndex(uint32_t index)
  275. {
  276. return (Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(index);
  277. }
  278. Il2CppGenericContainer* SuperSetAOTHomologousImage::GetGenericContainerByTypeDefRawIndex(int32_t typeDefIndex)
  279. {
  280. auto it = _aotTypeIndex2TypeDefs.find(typeDefIndex);
  281. if (it == _aotTypeIndex2TypeDefs.end())
  282. {
  283. return nullptr;
  284. }
  285. const Il2CppType* type = it->second->aotIl2CppType;
  286. if (type == nullptr)
  287. {
  288. return nullptr;
  289. }
  290. const Il2CppTypeDefinition* typeDef = (const Il2CppTypeDefinition*)(type->data.typeHandle);
  291. return (Il2CppGenericContainer*)il2cpp::vm::GlobalMetadata::GetGenericContainerFromIndex(typeDef->genericContainerIndex);
  292. }
  293. const Il2CppMethodDefinition* SuperSetAOTHomologousImage::GetMethodDefinitionFromRawIndex(uint32_t index)
  294. {
  295. IL2CPP_ASSERT((size_t)index < _methodDefs.size());
  296. SuperSetMethodDefDetail& method = _methodDefs[index];
  297. const Il2CppMethodDefinition* methodDef = method.aotMethodDef;
  298. if (!methodDef)
  299. {
  300. TEMP_FORMAT(errMsg, "method not exist. rowIndex:%d", index);
  301. RaiseExecutionEngineException(errMsg);
  302. }
  303. return methodDef;
  304. }
  305. void SuperSetAOTHomologousImage::ReadFieldRefInfoFromFieldDefToken(uint32_t rowIndex, FieldRefInfo& ret)
  306. {
  307. IL2CPP_ASSERT(rowIndex > 0);
  308. SuperSetFieldDefDetail& fd = _fields[rowIndex - 1];
  309. ret.containerType = fd.declaringIl2CppType;
  310. ret.field = fd.aotFieldDef;
  311. }
  312. const Il2CppType* SuperSetAOTHomologousImage::ReadTypeFromResolutionScope(uint32_t scope, uint32_t typeNamespace, uint32_t typeName)
  313. {
  314. TableType tokenType;
  315. uint32_t rawIndex;
  316. DecodeResolutionScopeCodedIndex(scope, tokenType, rawIndex);
  317. switch (tokenType)
  318. {
  319. case TableType::MODULE:
  320. {
  321. const Il2CppType* retType = GetModuleIl2CppType(rawIndex, typeNamespace, typeName, false);
  322. return retType ? retType : _defaultIl2CppType;
  323. }
  324. case TableType::MODULEREF:
  325. {
  326. RaiseNotSupportedException("Image::ReadTypeFromResolutionScope not support ResolutionScore.MODULEREF");
  327. return nullptr;
  328. }
  329. case TableType::ASSEMBLYREF:
  330. {
  331. const Il2CppType* refType = GetIl2CppType(rawIndex, typeNamespace, typeName, false);
  332. return refType ? refType : _defaultIl2CppType;
  333. }
  334. case TableType::TYPEREF:
  335. {
  336. const Il2CppType* enClosingType = ReadTypeFromTypeRef(rawIndex);
  337. IL2CPP_ASSERT(typeNamespace == 0);
  338. const char* name = _rawImage->GetStringFromRawIndex(typeName);
  339. void* iter = nullptr;
  340. Il2CppMetadataTypeHandle enclosingTypeDef = enClosingType->data.typeHandle;
  341. if (!enclosingTypeDef)
  342. {
  343. //TEMP_FORMAT(errMsg, "Image::ReadTypeFromResolutionScope ReadTypeFromResolutionScope.TYPEREF enclosingType:%s", name);
  344. //RaiseExecutionEngineException(errMsg);
  345. return _defaultIl2CppType;
  346. }
  347. for (const Il2CppTypeDefinition* nextTypeDef; (nextTypeDef = (const Il2CppTypeDefinition*)il2cpp::vm::GlobalMetadata::GetNestedTypes(enclosingTypeDef, &iter));)
  348. {
  349. const char* nestedTypeName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(nextTypeDef->nameIndex);
  350. IL2CPP_ASSERT(nestedTypeName);
  351. if (!std::strcmp(name, nestedTypeName))
  352. {
  353. return GetIl2CppTypeFromTypeDefinition(nextTypeDef);
  354. }
  355. }
  356. return _defaultIl2CppType;
  357. }
  358. default:
  359. {
  360. RaiseBadImageException("Image::ReadTypeFromResolutionScope invaild TableType");
  361. return nullptr;
  362. }
  363. }
  364. }
  365. }
  366. }