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.

Reflection.cpp 29KB

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