Reflection.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. #include "il2cpp-config.h"
  2. #include "il2cpp-class-internals.h"
  3. #include "il2cpp-object-internals.h"
  4. #include "il2cpp-tabledefs.h"
  5. #include "mono-structs.h"
  6. #include "gc/GCHandle.h"
  7. #include "gc/WriteBarrier.h"
  8. #include "metadata//CustomAttributeDataReader.h"
  9. #include "metadata/Il2CppTypeCompare.h"
  10. #include "metadata/Il2CppTypeHash.h"
  11. #include "vm/Array.h"
  12. #include "vm/Class.h"
  13. #include "vm/Event.h"
  14. #include "vm/Exception.h"
  15. #include "vm/Field.h"
  16. #include "vm/Image.h"
  17. #include "vm/MetadataCache.h"
  18. #include "vm/Method.h"
  19. #include "vm/Object.h"
  20. #include "vm/Parameter.h"
  21. #include "vm/Property.h"
  22. #include "vm/Reflection.h"
  23. #include "vm/String.h"
  24. #include "vm/AssemblyName.h"
  25. #include "utils/Il2CppHashMap.h"
  26. #include "utils/StringUtils.h"
  27. #include "utils/HashUtils.h"
  28. #include "gc/AppendOnlyGCHashMap.h"
  29. #include "gc/Allocator.h"
  30. template<typename T>
  31. struct ReflectionMapHash
  32. {
  33. size_t operator()(const T& ea) const
  34. {
  35. return ((size_t)(intptr_t)(ea.first)) >> 3;
  36. }
  37. };
  38. template<typename T>
  39. struct ReflectionMapLess
  40. {
  41. bool operator()(const T& ea, const T& eb) const
  42. {
  43. if (ea.first < eb.first)
  44. return true;
  45. if (ea.second < eb.second)
  46. return true;
  47. return false;
  48. }
  49. };
  50. template<typename Key, typename Value>
  51. struct ReflectionMap : public il2cpp::gc::AppendOnlyGCHashMap<Key, Value, ReflectionMapHash<Key> >
  52. {
  53. };
  54. typedef ReflectionMap<std::pair<const Il2CppAssembly*, Il2CppClass*>, Il2CppReflectionAssembly*> AssemblyMap;
  55. typedef ReflectionMap<std::pair<const FieldInfo*, Il2CppClass*>, Il2CppReflectionField*> FieldMap;
  56. typedef ReflectionMap<std::pair<const PropertyInfo*, Il2CppClass*>, Il2CppReflectionProperty*> PropertyMap;
  57. typedef ReflectionMap<std::pair<const EventInfo*, Il2CppClass*>, Il2CppReflectionEvent*> EventMap;
  58. typedef ReflectionMap<std::pair<const MethodInfo*, Il2CppClass*>, Il2CppReflectionMethod*> MethodMap;
  59. typedef ReflectionMap<std::pair<const Il2CppImage*, Il2CppClass*>, Il2CppReflectionModule*> ModuleMap;
  60. typedef ReflectionMap<std::pair<const MethodInfo*, Il2CppClass*>, Il2CppArray*> ParametersMap;
  61. typedef il2cpp::gc::AppendOnlyGCHashMap<const Il2CppType*, Il2CppReflectionType*, il2cpp::metadata::Il2CppTypeHash, il2cpp::metadata::Il2CppTypeEqualityComparer> TypeMap;
  62. typedef Il2CppHashMap<Il2CppMetadataGenericParameterHandle, const MonoGenericParameterInfo*, il2cpp::utils::PassThroughHash<Il2CppMetadataGenericParameterHandle> > MonoGenericParameterMap;
  63. typedef Il2CppHashMap<const Il2CppAssembly*, const Il2CppMonoAssemblyName*, il2cpp::utils::PointerHash<const Il2CppAssembly> > MonoAssemblyNameMap;
  64. // these needs to be pointers and allocated after GC is initialized since it uses GC Allocator
  65. static AssemblyMap* s_AssemblyMap;
  66. static FieldMap* s_FieldMap;
  67. static PropertyMap* s_PropertyMap;
  68. static EventMap* s_EventMap;
  69. static MethodMap* s_MethodMap;
  70. static ModuleMap* s_ModuleMap;
  71. static ParametersMap* s_ParametersMap;
  72. static TypeMap* s_TypeMap;
  73. static MonoGenericParameterMap* s_MonoGenericParamterMap;
  74. static MonoAssemblyNameMap* s_MonoAssemblyNameMap;
  75. namespace il2cpp
  76. {
  77. namespace vm
  78. {
  79. static Il2CppClass *s_System_Reflection_Assembly;
  80. static Il2CppClass * s_System_Reflection_RuntimeFieldInfoKlass;
  81. static Il2CppClass *s_System_Reflection_Module;
  82. static Il2CppClass * s_System_Reflection_RuntimePropertyInfoKlass;
  83. static Il2CppClass * s_System_Reflection_RuntimeEventInfoKlass;
  84. static FieldInfo *s_DbNullValueField;
  85. static FieldInfo *s_ReflectionMissingField;
  86. static Il2CppClass *s_System_Reflection_ParameterInfo;
  87. static Il2CppClass *s_System_Reflection_ParameterInfo_array;
  88. /*
  89. * We use the same C representation for methods and constructors, but the type
  90. * name in C# is different.
  91. */
  92. static Il2CppClass *s_System_Reflection_MethodInfo;
  93. static Il2CppClass *s_System_Reflection_ConstructorInfo;
  94. Il2CppReflectionAssembly* Reflection::GetAssemblyObject(const Il2CppAssembly *assembly)
  95. {
  96. Il2CppReflectionAssembly *res;
  97. AssemblyMap::key_type::wrapped_type key(assembly, (Il2CppClass*)NULL);
  98. AssemblyMap::data_type value = NULL;
  99. if (s_AssemblyMap->TryGetValue(key, &value))
  100. return value;
  101. res = (Il2CppReflectionAssembly*)Object::New(s_System_Reflection_Assembly);
  102. res->assembly = assembly;
  103. return s_AssemblyMap->GetOrAdd(key, res);
  104. }
  105. Il2CppReflectionAssemblyName* Reflection::GetAssemblyNameObject(const Il2CppAssemblyName *assemblyName)
  106. {
  107. IL2CPP_ASSERT(il2cpp_defaults.assembly_name_class != NULL);
  108. std::string fullAssemblyName = vm::AssemblyName::AssemblyNameToString(*assemblyName);
  109. Il2CppReflectionAssemblyName* reflectionAssemblyName = (Il2CppReflectionAssemblyName*)Object::New(il2cpp_defaults.assembly_name_class);
  110. vm::AssemblyName::ParseName(reflectionAssemblyName, fullAssemblyName);
  111. return reflectionAssemblyName;
  112. }
  113. Il2CppReflectionField* Reflection::GetFieldObject(Il2CppClass *klass, FieldInfo *field)
  114. {
  115. Il2CppReflectionField *res;
  116. FieldMap::key_type::wrapped_type key(field, klass);
  117. FieldMap::data_type value = NULL;
  118. if (s_FieldMap->TryGetValue(key, &value))
  119. return value;
  120. res = (Il2CppReflectionField*)Object::New(s_System_Reflection_RuntimeFieldInfoKlass);
  121. res->klass = klass;
  122. res->field = field;
  123. IL2CPP_OBJECT_SETREF(res, name, String::New(Field::GetName(field)));
  124. res->attrs = field->type->attrs;
  125. IL2CPP_OBJECT_SETREF(res, type, GetTypeObject(field->type));
  126. return s_FieldMap->GetOrAdd(key, res);
  127. }
  128. const MethodInfo* Reflection::GetMethod(const Il2CppReflectionMethod* method)
  129. {
  130. return method->method;
  131. }
  132. Il2CppReflectionMethod* Reflection::GetMethodObject(const MethodInfo *method, Il2CppClass *refclass)
  133. {
  134. Il2CppClass *klass;
  135. Il2CppReflectionMethod *ret;
  136. if (!refclass)
  137. refclass = method->klass;
  138. MethodMap::key_type::wrapped_type key(method, refclass);
  139. MethodMap::data_type value = NULL;
  140. if (s_MethodMap->TryGetValue(key, &value))
  141. return value;
  142. if (*method->name == '.' && (strcmp(method->name, ".ctor") == 0 || strcmp(method->name, ".cctor") == 0))
  143. {
  144. klass = s_System_Reflection_ConstructorInfo;
  145. }
  146. else
  147. {
  148. klass = s_System_Reflection_MethodInfo;
  149. }
  150. ret = (Il2CppReflectionMethod*)Object::New(klass);
  151. ret->method = method;
  152. IL2CPP_OBJECT_SETREF(ret, reftype, GetTypeObject(&refclass->byval_arg));
  153. return s_MethodMap->GetOrAdd(key, ret);
  154. }
  155. Il2CppReflectionModule* Reflection::GetModuleObject(const Il2CppImage *image)
  156. {
  157. Il2CppReflectionModule *res;
  158. //char* basename;
  159. ModuleMap::key_type::wrapped_type key(image, (Il2CppClass*)NULL);
  160. ModuleMap::data_type value = NULL;
  161. if (s_ModuleMap->TryGetValue(key, &value))
  162. return value;
  163. res = (Il2CppReflectionModule*)Object::New(s_System_Reflection_Module);
  164. res->image = image;
  165. IL2CPP_OBJECT_SETREF(res, assembly, Reflection::GetAssemblyObject(image->assembly));
  166. IL2CPP_OBJECT_SETREF(res, fqname, String::New(image->name));
  167. IL2CPP_NOT_IMPLEMENTED_ICALL_NO_ASSERT(Reflection::GetModuleObject, "Missing Module fields need set");
  168. //basename = g_path_get_basename (image->name);
  169. //IL2CPP_OBJECT_SETREF (res, name, String::New (basename));
  170. IL2CPP_OBJECT_SETREF(res, name, String::New(image->name));
  171. IL2CPP_OBJECT_SETREF(res, scopename, String::New(image->nameNoExt));
  172. //g_free (basename);
  173. /*if (image->assembly->image == image) {
  174. res->token = mono_metadata_make_token (MONO_TABLE_MODULE, 1);
  175. } else {
  176. int i;
  177. res->token = 0;
  178. if (image->assembly->image->modules) {
  179. for (i = 0; i < image->assembly->image->module_count; i++) {
  180. if (image->assembly->image->modules [i] == image)
  181. res->token = mono_metadata_make_token (MONO_TABLE_MODULEREF, i + 1);
  182. }
  183. IL2CPP_ASSERT(res->token);
  184. }
  185. }*/
  186. return s_ModuleMap->GetOrAdd(key, res);
  187. }
  188. Il2CppReflectionProperty* Reflection::GetPropertyObject(Il2CppClass *klass, const PropertyInfo *property)
  189. {
  190. Il2CppReflectionProperty *res;
  191. PropertyMap::key_type::wrapped_type key(property, klass);
  192. PropertyMap::data_type value = NULL;
  193. if (s_PropertyMap->TryGetValue(key, &value))
  194. return value;
  195. res = (Il2CppReflectionProperty*)Object::New(s_System_Reflection_RuntimePropertyInfoKlass);
  196. res->klass = klass;
  197. res->property = property;
  198. return s_PropertyMap->GetOrAdd(key, res);
  199. }
  200. Il2CppReflectionEvent* Reflection::GetEventObject(Il2CppClass* klass, const EventInfo* event)
  201. {
  202. Il2CppReflectionEvent* result;
  203. EventMap::key_type::wrapped_type key(event, klass);
  204. EventMap::data_type value = NULL;
  205. if (s_EventMap->TryGetValue(key, &value))
  206. return value;
  207. Il2CppReflectionMonoEvent* monoEvent = reinterpret_cast<Il2CppReflectionMonoEvent*>(Object::New(s_System_Reflection_RuntimeEventInfoKlass));
  208. monoEvent->eventInfo = event;
  209. monoEvent->reflectedType = Reflection::GetTypeObject(&klass->byval_arg);
  210. result = reinterpret_cast<Il2CppReflectionEvent*>(monoEvent);
  211. return s_EventMap->GetOrAdd(key, result);
  212. }
  213. Il2CppReflectionType* Reflection::GetTypeObject(const Il2CppType *type)
  214. {
  215. Il2CppReflectionType* object = NULL;
  216. if (s_TypeMap->TryGetValue(type, &object))
  217. return object;
  218. Il2CppReflectionType* typeObject = (Il2CppReflectionType*)Object::New(il2cpp_defaults.runtimetype_class);
  219. typeObject->type = type;
  220. return s_TypeMap->GetOrAdd(type, typeObject);
  221. }
  222. Il2CppObject* Reflection::GetDBNullObject()
  223. {
  224. Il2CppObject* valueFieldValue;
  225. if (!s_DbNullValueField)
  226. {
  227. s_DbNullValueField = Class::GetFieldFromName(il2cpp_defaults.dbnull_class, "Value");
  228. IL2CPP_ASSERT(s_DbNullValueField);
  229. }
  230. valueFieldValue = Field::GetValueObject(s_DbNullValueField, NULL);
  231. IL2CPP_ASSERT(valueFieldValue);
  232. return valueFieldValue;
  233. }
  234. static Il2CppObject* GetReflectionMissingObject()
  235. {
  236. Il2CppObject* valueFieldValue;
  237. if (!s_ReflectionMissingField)
  238. {
  239. Il2CppClass* klass = Image::ClassFromName(il2cpp_defaults.corlib, "System.Reflection", "Missing");
  240. Class::Init(klass);
  241. s_ReflectionMissingField = Class::GetFieldFromName(klass, "Value");
  242. IL2CPP_ASSERT(s_ReflectionMissingField);
  243. }
  244. valueFieldValue = Field::GetValueObject(s_ReflectionMissingField, NULL);
  245. IL2CPP_ASSERT(valueFieldValue);
  246. return valueFieldValue;
  247. }
  248. static Il2CppObject* GetObjectForMissingDefaultValue(uint32_t parameterAttributes)
  249. {
  250. if (parameterAttributes & PARAM_ATTRIBUTE_OPTIONAL)
  251. return GetReflectionMissingObject();
  252. else
  253. return Reflection::GetDBNullObject();
  254. }
  255. Il2CppArray* Reflection::GetParamObjects(const MethodInfo *method, Il2CppClass *refclass)
  256. {
  257. Il2CppArray *res = NULL;
  258. Il2CppReflectionMethod *member = NULL;
  259. IL2CPP_NOT_IMPLEMENTED_NO_ASSERT(Reflection::GetParamObjects, "Work in progress!");
  260. if (!method->parameters_count)
  261. return Array::NewSpecific(s_System_Reflection_ParameterInfo_array, 0);
  262. // Mono caches based on the address of the method pointer in the MethodInfo
  263. // since they put everything in one cache and the MethodInfo is already used as key for GetMethodObject caching
  264. // However, since we have distinct maps for the different types we can use MethodInfo as the key again
  265. ParametersMap::key_type::wrapped_type key(method, refclass);
  266. ParametersMap::data_type value;
  267. if (s_ParametersMap->TryGetValue(key, &value))
  268. return value;
  269. member = GetMethodObject(method, refclass);
  270. res = Array::NewSpecific(s_System_Reflection_ParameterInfo_array, method->parameters_count);
  271. for (int i = 0; i < method->parameters_count; ++i)
  272. {
  273. Il2CppReflectionParameter* param = (Il2CppReflectionParameter*)Object::New(s_System_Reflection_ParameterInfo);
  274. IL2CPP_OBJECT_SETREF(param, ClassImpl, GetTypeObject(method->parameters[i]));
  275. IL2CPP_OBJECT_SETREF(param, MemberImpl, (Il2CppObject*)member);
  276. const char* parameter_name = Method::GetParamName(method, i);
  277. IL2CPP_OBJECT_SETREF(param, NameImpl, parameter_name ? String::New(parameter_name) : NULL);
  278. param->PositionImpl = i;
  279. param->AttrsImpl = method->parameters[i]->attrs;
  280. Il2CppObject* defaultValue = NULL;
  281. if (param->AttrsImpl & PARAM_ATTRIBUTE_HAS_DEFAULT)
  282. {
  283. bool isExplicitySetNullDefaultValue = false;
  284. defaultValue = Parameter::GetDefaultParameterValueObject(method, i, &isExplicitySetNullDefaultValue);
  285. if (defaultValue == NULL && !isExplicitySetNullDefaultValue)
  286. defaultValue = GetObjectForMissingDefaultValue(param->AttrsImpl);
  287. }
  288. else
  289. {
  290. defaultValue = GetObjectForMissingDefaultValue(param->AttrsImpl);
  291. }
  292. IL2CPP_OBJECT_SETREF(param, DefaultValueImpl, defaultValue);
  293. il2cpp_array_setref(res, i, param);
  294. }
  295. return s_ParametersMap->GetOrAdd(key, res);
  296. }
  297. // TODO: move this somewhere else
  298. bool Reflection::IsType(Il2CppObject *obj)
  299. {
  300. return (obj->klass == il2cpp_defaults.runtimetype_class);
  301. }
  302. static bool IsMethod(Il2CppObject *obj)
  303. {
  304. if (obj->klass->image == il2cpp_defaults.corlib)
  305. return strcmp(obj->klass->name, "RuntimeMethodInfo") == 0 && strcmp(obj->klass->namespaze, "System.Reflection") == 0;
  306. return false;
  307. }
  308. static bool IsCMethod(Il2CppObject *obj)
  309. {
  310. if (obj->klass->image == il2cpp_defaults.corlib)
  311. return strcmp(obj->klass->name, "RuntimeConstructorInfo") == 0 && strcmp(obj->klass->namespaze, "System.Reflection") == 0;
  312. return false;
  313. }
  314. bool Reflection::IsAnyMethod(Il2CppObject *obj)
  315. {
  316. return IsMethod(obj) || IsCMethod(obj);
  317. }
  318. bool Reflection::IsField(Il2CppObject *obj)
  319. {
  320. if (obj->klass->image == il2cpp_defaults.corlib)
  321. return strcmp(obj->klass->name, "RuntimeFieldInfo") == 0 && strcmp(obj->klass->namespaze, "System.Reflection") == 0;
  322. return false;
  323. }
  324. bool Reflection::IsProperty(Il2CppObject *obj)
  325. {
  326. if (obj->klass->image == il2cpp_defaults.corlib)
  327. return strcmp(obj->klass->name, "RuntimePropertyInfo") == 0 && strcmp(obj->klass->namespaze, "System.Reflection") == 0;
  328. return false;
  329. }
  330. bool Reflection::IsEvent(Il2CppObject *obj)
  331. {
  332. if (obj->klass->image == il2cpp_defaults.corlib)
  333. return strcmp(obj->klass->name, "RuntimeEventInfo") == 0 && strcmp(obj->klass->namespaze, "System.Reflection") == 0;
  334. return false;
  335. }
  336. static bool IsParameter(Il2CppObject *obj)
  337. {
  338. if (obj->klass->image == il2cpp_defaults.corlib)
  339. return obj->klass == il2cpp_defaults.parameter_info_class;
  340. return false;
  341. }
  342. static bool IsAssembly(Il2CppObject *obj)
  343. {
  344. if (obj->klass->image == il2cpp_defaults.corlib)
  345. return obj->klass == s_System_Reflection_Assembly->klass;
  346. return false;
  347. }
  348. CustomAttributesCache* Reflection::GetCustomAttributesCacheFor(Il2CppClass *klass)
  349. {
  350. return MetadataCache::GenerateCustomAttributesCache(klass->image, klass->token);
  351. }
  352. CustomAttributesCache* Reflection::GetCustomAttributesCacheFor(const MethodInfo *method)
  353. {
  354. return MetadataCache::GenerateCustomAttributesCache(method->klass->image, method->token);
  355. }
  356. CustomAttributesCache* Reflection::GetCustomAttributesCacheFor(const PropertyInfo *property)
  357. {
  358. return MetadataCache::GenerateCustomAttributesCache(property->parent->image, property->token);
  359. }
  360. CustomAttributesCache* Reflection::GetCustomAttributesCacheFor(FieldInfo *field)
  361. {
  362. return MetadataCache::GenerateCustomAttributesCache(field->parent->image, field->token);
  363. }
  364. CustomAttributesCache* Reflection::GetCustomAttributesCacheFor(const EventInfo *event)
  365. {
  366. return MetadataCache::GenerateCustomAttributesCache(event->parent->image, event->token);
  367. }
  368. CustomAttributesCache* Reflection::GetCustomAttributesCacheFor(Il2CppReflectionParameter *parameter)
  369. {
  370. Il2CppReflectionMethod* method = (Il2CppReflectionMethod*)parameter->MemberImpl;
  371. if (method->method->parameters == NULL)
  372. return NULL;
  373. IL2CPP_NOT_IMPLEMENTED_NO_ASSERT(Reflection::GetCustomAttributesCacheFor, "-1 represents the return value. Need to emit custom attribute information for that.")
  374. if (parameter->PositionImpl == -1)
  375. return NULL;
  376. const MethodInfo* methodWithParameterAttributeInformation = method->method;
  377. if (method->method->is_inflated)
  378. methodWithParameterAttributeInformation = method->method->genericMethod->methodDefinition;
  379. return MetadataCache::GenerateCustomAttributesCache(methodWithParameterAttributeInformation->klass->image, Method::GetParameterToken(method->method, parameter->PositionImpl));
  380. }
  381. std::tuple<void*, void*> Reflection::GetCustomAttributesDataRangeFor(Il2CppClass *klass)
  382. {
  383. return MetadataCache::GetCustomAttributeDataRange(klass->image, klass->token);
  384. }
  385. std::tuple<void*, void*> Reflection::GetCustomAttributesDataRangeFor(const MethodInfo *method)
  386. {
  387. return MetadataCache::GetCustomAttributeDataRange(method->klass->image, method->token);
  388. }
  389. std::tuple<void*, void*> Reflection::GetCustomAttributesDataRangeFor(const PropertyInfo *property)
  390. {
  391. return MetadataCache::GetCustomAttributeDataRange(property->parent->image, property->token);
  392. }
  393. std::tuple<void*, void*> Reflection::GetCustomAttributesDataRangeFor(FieldInfo *field)
  394. {
  395. return MetadataCache::GetCustomAttributeDataRange(field->parent->image, field->token);
  396. }
  397. std::tuple<void*, void*> Reflection::GetCustomAttributesDataRangeFor(const EventInfo *event)
  398. {
  399. return MetadataCache::GetCustomAttributeDataRange(event->parent->image, event->token);
  400. }
  401. std::tuple<void*, void*> Reflection::GetCustomAttributesDataRangeFor(Il2CppReflectionParameter *parameter)
  402. {
  403. Il2CppReflectionMethod* method = (Il2CppReflectionMethod*)parameter->MemberImpl;
  404. if (method->method->parameters == NULL)
  405. return std::make_tuple<void*, void*>(NULL, NULL);
  406. IL2CPP_NOT_IMPLEMENTED_NO_ASSERT(Reflection::GetCustomAttributesDataRangeFor, "-1 represents the return value. Need to emit custom attribute information for that.")
  407. if (parameter->PositionImpl == -1)
  408. return std::make_tuple<void*, void*>(NULL, NULL);
  409. const MethodInfo* methodWithParameterAttributeInformation = method->method;
  410. if (method->method->is_inflated)
  411. methodWithParameterAttributeInformation = method->method->genericMethod->methodDefinition;
  412. return MetadataCache::GetCustomAttributeDataRange(methodWithParameterAttributeInformation->klass->image, Method::GetParameterToken(method->method, parameter->PositionImpl));
  413. }
  414. std::tuple<void*, void*> Reflection::GetCustomAttributesDataRangeFor(const Il2CppAssembly *assembly)
  415. {
  416. return MetadataCache::GetCustomAttributeDataRange(assembly->image, assembly->token);
  417. }
  418. int Reflection::GetMetadataToken(Il2CppObject* obj)
  419. {
  420. if (vm::Reflection::IsField(obj))
  421. {
  422. Il2CppReflectionField* field = (Il2CppReflectionField*)obj;
  423. return vm::Field::GetToken(field->field);
  424. }
  425. else if (vm::Reflection::IsAnyMethod(obj))
  426. {
  427. Il2CppReflectionMethod* method = (Il2CppReflectionMethod*)obj;
  428. return vm::Method::GetToken(method->method);
  429. }
  430. else if (vm::Reflection::IsProperty(obj))
  431. {
  432. Il2CppReflectionProperty* prop = (Il2CppReflectionProperty*)obj;
  433. return vm::Property::GetToken(prop->property);
  434. }
  435. else if (vm::Reflection::IsEvent(obj))
  436. {
  437. Il2CppReflectionMonoEvent* eventInfo = (Il2CppReflectionMonoEvent*)obj;
  438. return vm::Event::GetToken(eventInfo->eventInfo);
  439. }
  440. else if (vm::Reflection::IsType(obj))
  441. {
  442. Il2CppReflectionType* type = (Il2CppReflectionType*)obj;
  443. return vm::Type::GetToken(type->type);
  444. }
  445. else if (IsParameter(obj))
  446. {
  447. Il2CppReflectionParameter* parameter = (Il2CppReflectionParameter*)obj;
  448. if (parameter->PositionImpl == -1)
  449. return 0x8000000; // This is what mono returns as a fixed value.
  450. Il2CppReflectionMethod* method = (Il2CppReflectionMethod*)parameter->MemberImpl;
  451. return vm::Method::GetParameterToken(method->method, parameter->PositionImpl);
  452. }
  453. else
  454. {
  455. NOT_SUPPORTED_IL2CPP(MemberInfo::get_MetadataToken, "This icall is not supported by il2cpp.");
  456. }
  457. return 0;
  458. }
  459. bool Reflection::HasAttribute(Il2CppReflectionParameter *parameter, Il2CppClass* attribute)
  460. {
  461. Il2CppReflectionMethod* method = (Il2CppReflectionMethod*)parameter->MemberImpl;
  462. if (method->method->parameters == NULL)
  463. return false;
  464. IL2CPP_NOT_IMPLEMENTED_NO_ASSERT(Reflection::GetCustomAttributeTypeCacheFor, "-1 represents the return value. Need to emit custom attribute information for that.")
  465. if (parameter->PositionImpl == -1)
  466. return false;
  467. const MethodInfo* methodWithParameterAttributeInformation = method->method;
  468. if (method->method->is_inflated)
  469. methodWithParameterAttributeInformation = method->method->genericMethod->methodDefinition;
  470. return MetadataCache::HasAttribute(methodWithParameterAttributeInformation->klass->image, Method::GetParameterToken(method->method, parameter->PositionImpl), attribute);
  471. }
  472. CustomAttributesCache* Reflection::GetCustomAttributesCacheFor(const Il2CppAssembly *assembly)
  473. {
  474. return MetadataCache::GenerateCustomAttributesCache(assembly->image, assembly->token);
  475. }
  476. CustomAttributesCache* Reflection::GetCustomAttrsInfo(Il2CppObject *obj)
  477. {
  478. if (IsMethod(obj) || IsCMethod(obj))
  479. return GetCustomAttributesCacheFor(((Il2CppReflectionMethod*)obj)->method);
  480. if (IsProperty(obj))
  481. return GetCustomAttributesCacheFor(((Il2CppReflectionProperty*)obj)->property);
  482. if (IsField(obj))
  483. return GetCustomAttributesCacheFor(((Il2CppReflectionField*)obj)->field);
  484. if (IsEvent(obj))
  485. return GetCustomAttributesCacheFor(((Il2CppReflectionMonoEvent*)obj)->eventInfo);
  486. if (IsParameter(obj))
  487. return GetCustomAttributesCacheFor(((Il2CppReflectionParameter*)obj));
  488. if (IsAssembly(obj))
  489. return GetCustomAttributesCacheFor(((Il2CppReflectionAssembly*)obj)->assembly);
  490. Il2CppClass *klass = IsType(obj)
  491. ? Class::FromSystemType((Il2CppReflectionType*)obj)
  492. : obj->klass;
  493. return GetCustomAttributesCacheFor(klass);
  494. }
  495. il2cpp::metadata::CustomAttributeDataReader Reflection::GetCustomAttrsDataReader(Il2CppObject* obj)
  496. {
  497. const Il2CppImage* image;
  498. std::tuple<void*, void*> dataRange;
  499. if (IsMethod(obj) || IsCMethod(obj))
  500. {
  501. const MethodInfo* method = ((Il2CppReflectionMethod*)obj)->method;
  502. image = method->klass->image;
  503. dataRange = GetCustomAttributesDataRangeFor(method);
  504. }
  505. else if (IsProperty(obj))
  506. {
  507. const PropertyInfo* prop = ((Il2CppReflectionProperty*)obj)->property;
  508. image = prop->parent->image;
  509. dataRange = GetCustomAttributesDataRangeFor(prop);
  510. }
  511. else if (IsField(obj))
  512. {
  513. FieldInfo* field = ((Il2CppReflectionField*)obj)->field;
  514. image = field->parent->image;
  515. dataRange = GetCustomAttributesDataRangeFor(field);
  516. }
  517. else if (IsEvent(obj))
  518. {
  519. const EventInfo* eventInfo = ((Il2CppReflectionMonoEvent*)obj)->eventInfo;
  520. image = eventInfo->parent->image;
  521. dataRange = GetCustomAttributesDataRangeFor(eventInfo);
  522. }
  523. else if (IsParameter(obj))
  524. {
  525. Il2CppReflectionParameter* parameter = (Il2CppReflectionParameter*)obj;
  526. Il2CppReflectionMethod* method = (Il2CppReflectionMethod*)parameter->MemberImpl;
  527. image = method->method->klass->image;
  528. dataRange = GetCustomAttributesDataRangeFor(parameter);
  529. }
  530. else if (IsAssembly(obj))
  531. {
  532. const Il2CppAssembly* assembly = ((Il2CppReflectionAssembly*)obj)->assembly;
  533. image = assembly->image;
  534. dataRange = GetCustomAttributesDataRangeFor(assembly);
  535. }
  536. else
  537. {
  538. Il2CppClass *klass = IsType(obj)
  539. ? Class::FromSystemType((Il2CppReflectionType*)obj)
  540. : obj->klass;
  541. image = klass->image;
  542. dataRange = GetCustomAttributesDataRangeFor(klass);
  543. }
  544. void* start;
  545. void* end;
  546. std::tie(start, end) = dataRange;
  547. return metadata::CustomAttributeDataReader(start, end);
  548. }
  549. ReflectionObjInfo Reflection::GetImageOfReflectionObject(Il2CppObject* obj)
  550. {
  551. if (il2cpp::vm::Reflection::IsAnyMethod(obj))
  552. {
  553. const MethodInfo* method = ((Il2CppReflectionMethod*)obj)->method;
  554. return { method->klass->image, method->token };
  555. }
  556. else if (il2cpp::vm::Reflection::IsProperty(obj))
  557. {
  558. const PropertyInfo* prop = ((Il2CppReflectionProperty*)obj)->property;
  559. return { prop->parent->image, prop->token };
  560. }
  561. else if (il2cpp::vm::Reflection::IsField(obj))
  562. {
  563. FieldInfo* field = ((Il2CppReflectionField*)obj)->field;
  564. return { field->parent->image, field->token };
  565. }
  566. else if (il2cpp::vm::Reflection::IsEvent(obj))
  567. {
  568. const EventInfo* eventInfo = ((Il2CppReflectionMonoEvent*)obj)->eventInfo;
  569. return { eventInfo->parent->image, eventInfo->token };
  570. }
  571. else if (IsParameter(obj))
  572. {
  573. Il2CppReflectionParameter* parameter = (Il2CppReflectionParameter*)obj;
  574. Il2CppReflectionMethod* method = (Il2CppReflectionMethod*)parameter->MemberImpl;
  575. return { method->method->klass->image, il2cpp::vm::Method::GetParameterToken(method->method, parameter->PositionImpl) };
  576. }
  577. else if (IsAssembly(obj))
  578. {
  579. const Il2CppAssembly* assembly = ((Il2CppReflectionAssembly*)obj)->assembly;
  580. return { assembly->image, assembly->token };
  581. }
  582. else
  583. {
  584. Il2CppClass* klass = il2cpp::vm::Reflection::IsType(obj)
  585. ? il2cpp::vm::Class::FromSystemType((Il2CppReflectionType*)obj)
  586. : obj->klass;
  587. return { klass->image, klass->token };
  588. }
  589. }
  590. bool Reflection::HasAttribute(Il2CppObject *obj, Il2CppClass* attribute)
  591. {
  592. if (IsMethod(obj) || IsCMethod(obj))
  593. return MetadataCache::HasAttribute((((Il2CppReflectionMethod*)obj)->method)->klass->image, (((Il2CppReflectionMethod*)obj)->method)->token, attribute);
  594. if (IsProperty(obj))
  595. return MetadataCache::HasAttribute((((Il2CppReflectionProperty*)obj)->property)->parent->image, (((Il2CppReflectionProperty*)obj)->property)->token, attribute);
  596. if (IsField(obj))
  597. return MetadataCache::HasAttribute((((Il2CppReflectionField*)obj)->field)->parent->image, (((Il2CppReflectionField*)obj)->field)->token, attribute);
  598. if (IsEvent(obj))
  599. return MetadataCache::HasAttribute((((Il2CppReflectionMonoEvent*)obj)->eventInfo)->parent->image, (((Il2CppReflectionMonoEvent*)obj)->eventInfo)->token, attribute);
  600. if (IsParameter(obj))
  601. return HasAttribute((Il2CppReflectionParameter*)obj, attribute);
  602. if (IsAssembly(obj))
  603. return MetadataCache::HasAttribute((((Il2CppReflectionAssembly*)obj)->assembly)->image, (((Il2CppReflectionAssembly*)obj)->assembly)->token, attribute);
  604. Il2CppClass *klass = IsType(obj)
  605. ? Class::FromSystemType((Il2CppReflectionType*)obj)
  606. : obj->klass;
  607. return MetadataCache::HasAttribute(klass->image, klass->token, attribute);
  608. }
  609. Il2CppObject* Reflection::GetCustomAttribute(Il2CppMetadataCustomAttributeHandle token, Il2CppClass* attribute)
  610. {
  611. CustomAttributesCache* cache = MetadataCache::GenerateCustomAttributesCache(token);
  612. if (cache == NULL)
  613. return NULL;
  614. for (int32_t i = 0; i < cache->count; i++)
  615. {
  616. Il2CppObject* obj = cache->attributes[i];
  617. Il2CppClass* klass = Object::GetClass(obj);
  618. if (Class::HasParent(klass, attribute) || (Class::IsInterface(attribute) && Class::IsAssignableFrom(attribute, klass)))
  619. return obj;
  620. }
  621. return NULL;
  622. }
  623. Il2CppArray* Reflection::ConstructCustomAttributes(Il2CppMetadataCustomAttributeHandle token)
  624. {
  625. CustomAttributesCache* cache = MetadataCache::GenerateCustomAttributesCache(token);
  626. if (cache == NULL)
  627. return il2cpp::vm::Array::New(il2cpp_defaults.attribute_class, 0);
  628. Il2CppArray* result = il2cpp::vm::Array::New(il2cpp_defaults.attribute_class, cache->count);
  629. for (int32_t i = 0; i < cache->count; i++)
  630. il2cpp_array_setref(result, i, cache->attributes[i]);
  631. return result;
  632. }
  633. void Reflection::Initialize()
  634. {
  635. s_AssemblyMap = new AssemblyMap();
  636. s_FieldMap = new FieldMap();
  637. s_PropertyMap = new PropertyMap();
  638. s_EventMap = new EventMap();
  639. s_MethodMap = new MethodMap();
  640. s_ModuleMap = new ModuleMap();
  641. s_ParametersMap = new ParametersMap();
  642. s_TypeMap = new TypeMap();
  643. s_MonoGenericParamterMap = new MonoGenericParameterMap();
  644. s_MonoAssemblyNameMap = new MonoAssemblyNameMap();
  645. s_System_Reflection_Assembly = Class::FromName(il2cpp_defaults.corlib, "System.Reflection", "RuntimeAssembly");
  646. IL2CPP_ASSERT(s_System_Reflection_Assembly != NULL);
  647. #if !IL2CPP_TINY_DEBUGGER
  648. s_System_Reflection_Module = Class::FromName(il2cpp_defaults.corlib, "System.Reflection", "RuntimeModule");
  649. IL2CPP_ASSERT(s_System_Reflection_Module != NULL);
  650. s_System_Reflection_ConstructorInfo = Class::FromName(il2cpp_defaults.corlib, "System.Reflection", "RuntimeConstructorInfo");
  651. IL2CPP_ASSERT(s_System_Reflection_ConstructorInfo != NULL);
  652. s_System_Reflection_MethodInfo = Class::FromName(il2cpp_defaults.corlib, "System.Reflection", "RuntimeMethodInfo");
  653. IL2CPP_ASSERT(s_System_Reflection_MethodInfo != NULL);
  654. s_System_Reflection_ParameterInfo = Class::FromName(il2cpp_defaults.corlib, "System.Reflection", "RuntimeParameterInfo");
  655. IL2CPP_ASSERT(s_System_Reflection_ParameterInfo != NULL);
  656. s_System_Reflection_ParameterInfo_array = Class::GetArrayClass(s_System_Reflection_ParameterInfo, 1);
  657. IL2CPP_ASSERT(s_System_Reflection_ParameterInfo_array != NULL);
  658. s_System_Reflection_RuntimeFieldInfoKlass = Class::FromName(il2cpp_defaults.corlib, "System.Reflection", "RuntimeFieldInfo");
  659. IL2CPP_ASSERT(s_System_Reflection_RuntimeFieldInfoKlass != NULL);
  660. s_System_Reflection_RuntimeEventInfoKlass = Class::FromName(il2cpp_defaults.corlib, "System.Reflection", "RuntimeEventInfo");
  661. IL2CPP_ASSERT(s_System_Reflection_RuntimeEventInfoKlass != NULL);
  662. s_System_Reflection_RuntimePropertyInfoKlass = Class::FromName(il2cpp_defaults.corlib, "System.Reflection", "RuntimePropertyInfo");
  663. IL2CPP_ASSERT(s_System_Reflection_RuntimePropertyInfoKlass != NULL);
  664. #endif
  665. }
  666. bool Reflection::HasAttribute(FieldInfo *field, Il2CppClass *attribute)
  667. {
  668. return MetadataCache::HasAttribute(field->parent->image, field->token, attribute);
  669. }
  670. bool Reflection::HasAttribute(const MethodInfo *method, Il2CppClass *attribute)
  671. {
  672. return MetadataCache::HasAttribute(method->klass->image, method->token, attribute);
  673. }
  674. bool Reflection::HasAttribute(Il2CppClass *klass, Il2CppClass *attribute)
  675. {
  676. return MetadataCache::HasAttribute(klass->image, klass->token, attribute);
  677. }
  678. Il2CppClass* Reflection::TypeGetHandle(Il2CppReflectionType* ref)
  679. {
  680. if (!ref)
  681. return NULL;
  682. return Class::FromSystemType(ref);
  683. }
  684. const MonoGenericParameterInfo* Reflection::GetMonoGenericParameterInfo(Il2CppMetadataGenericParameterHandle param)
  685. {
  686. MonoGenericParameterMap::const_iterator it = s_MonoGenericParamterMap->find(param);
  687. if (it == s_MonoGenericParamterMap->end())
  688. return NULL;
  689. return it->second;
  690. }
  691. void Reflection::SetMonoGenericParameterInfo(Il2CppMetadataGenericParameterHandle param, const MonoGenericParameterInfo *monoParam)
  692. {
  693. s_MonoGenericParamterMap->insert(std::make_pair(param, monoParam));
  694. }
  695. const Il2CppMonoAssemblyName* Reflection::GetMonoAssemblyName(const Il2CppAssembly *assembly)
  696. {
  697. MonoAssemblyNameMap::const_iterator it = s_MonoAssemblyNameMap->find(assembly);
  698. if (it == s_MonoAssemblyNameMap->end())
  699. return NULL;
  700. return it->second;
  701. }
  702. void Reflection::SetMonoAssemblyName(const Il2CppAssembly *assembly, const Il2CppMonoAssemblyName *aname)
  703. {
  704. s_MonoAssemblyNameMap->insert(std::make_pair(assembly, aname));
  705. }
  706. void Reflection::ClearStatics()
  707. {
  708. s_System_Reflection_Assembly = NULL;
  709. s_System_Reflection_RuntimeFieldInfoKlass = NULL;
  710. s_System_Reflection_Module = NULL;
  711. s_System_Reflection_RuntimePropertyInfoKlass = NULL;
  712. s_System_Reflection_RuntimeEventInfoKlass = NULL;
  713. s_DbNullValueField = NULL;
  714. s_ReflectionMissingField = NULL;
  715. s_System_Reflection_ParameterInfo = NULL;
  716. s_System_Reflection_ParameterInfo_array = NULL;
  717. s_System_Reflection_MethodInfo = NULL;
  718. s_System_Reflection_ConstructorInfo = NULL;
  719. }
  720. } /* namespace vm */
  721. } /* namespace il2cpp */