CustomAttributeDataReader.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #pragma once
  2. #include <stdint.h>
  3. #include <functional>
  4. #include "il2cpp-object-internals.h"
  5. #include "gc/Allocator.h"
  6. namespace il2cpp
  7. {
  8. namespace metadata
  9. {
  10. // This union is large enough to store any type
  11. // that can be serialized by an attribute argument
  12. // bool, byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort, System.Object, System.Type, or an enum
  13. // Or an szarray/vector of the previous types
  14. union CustomAttributeDataStorage
  15. {
  16. Il2CppObject* obj;
  17. int64_t i;
  18. double d;
  19. };
  20. typedef std::function<bool(const MethodInfo*)> CustomAttributeFilter;
  21. struct CustomAttributeArgument
  22. {
  23. Il2CppClass* klass;
  24. CustomAttributeDataStorage data;
  25. };
  26. struct CustomAttributeFieldArgument
  27. {
  28. CustomAttributeArgument arg;
  29. const FieldInfo* field;
  30. };
  31. struct CustomAttributePropertyArgument
  32. {
  33. CustomAttributeArgument arg;
  34. const PropertyInfo* prop;
  35. };
  36. struct LazyCustomAttributeData
  37. {
  38. const MethodInfo* ctor;
  39. const void* dataStart;
  40. uint32_t dataLength;
  41. };
  42. struct CustomAttributeData
  43. {
  44. const MethodInfo* ctor;
  45. };
  46. class CustomAttributeReaderVisitor
  47. {
  48. public:
  49. // This Visitor methods will be called in the defined order
  50. virtual void MoveNext(const MethodInfo* ctor) {}
  51. virtual void VisitArgumentSizes(uint32_t argumentCount, uint32_t fieldCount, uint32_t propertyCount) {}
  52. virtual void VisitArgument(const CustomAttributeArgument& argument, uint32_t index) {}
  53. virtual void VisitCtor(const MethodInfo* ctor, CustomAttributeArgument args[], uint32_t argumentCount) {}
  54. virtual void VisitField(const CustomAttributeFieldArgument& field, uint32_t index) {}
  55. virtual void VisitProperty(const CustomAttributePropertyArgument& prop, uint32_t index) {}
  56. };
  57. class CustomAttributeDataIterator;
  58. class CustomAttributeCtorIterator
  59. {
  60. private:
  61. CustomAttributeCtorIterator(const char* ctorBuffer, const CustomAttributeFilter& filter) : ctorBuffer(ctorBuffer), filter(filter)
  62. {}
  63. CustomAttributeCtorIterator(const char* ctorBuffer) : ctorBuffer(ctorBuffer), filter(TrueFilter)
  64. {}
  65. const char* ctorBuffer;
  66. const CustomAttributeFilter filter;
  67. friend class CustomAttributeDataReader;
  68. friend class CustomAttributeDataIterator;
  69. static bool TrueFilter(const MethodInfo* ctor)
  70. {
  71. return true;
  72. }
  73. };
  74. class CustomAttributeDataIterator
  75. {
  76. private:
  77. CustomAttributeDataIterator(const char* ctorBuffer, const char* dataBuffer) : dataBuffer(dataBuffer), ctorBuffer(ctorBuffer), filter(CustomAttributeCtorIterator::TrueFilter)
  78. {
  79. }
  80. CustomAttributeDataIterator(const char* ctorBuffer, const char* dataBuffer, const CustomAttributeFilter& filter) : dataBuffer(dataBuffer), ctorBuffer(ctorBuffer), filter(filter)
  81. {}
  82. const char* ctorBuffer;
  83. const char* dataBuffer;
  84. const CustomAttributeFilter filter;
  85. friend class CustomAttributeDataReader;
  86. };
  87. class CustomAttributeDataReader
  88. {
  89. public:
  90. // Creates a CustomAttributeDataReader pointing into the metadata buffer start and end
  91. // This range must be for a single metadata member
  92. CustomAttributeDataReader(const Il2CppImage* image, const void* buffer, const void* bufferEnd);
  93. static CustomAttributeDataReader Empty()
  94. {
  95. return CustomAttributeDataReader();
  96. }
  97. // Returns the number of custom attributes stored for the member
  98. uint32_t GetCount() const
  99. {
  100. return count;
  101. }
  102. uint32_t GetCount(const CustomAttributeFilter& filter) const;
  103. // Iterate through all of the custom attribute constructors
  104. // Call GetCtorIterator to get the iterator and call this method until it returns false
  105. bool IterateAttributeCtors(const MethodInfo** attributeCtor, CustomAttributeCtorIterator* iter) const;
  106. // Iterate through all of the custom attribute data, but only return the attribute type and data range.
  107. // This method does not allocate
  108. // On each call LazyCustomAttributeData will be filled with new custom attribute data
  109. // Call GetDataIterator to get the iterator and call this method until it returns false
  110. // Call the static VisitCustomAttributeData function to get the attribute arguments from the LazyCustomAttributeData
  111. // If this function returns false *exc may be non-null if an exception occurred
  112. bool ReadLazyCustomAttributeData(LazyCustomAttributeData* data, CustomAttributeDataIterator* iter, Il2CppException** exc) const;
  113. // Iterate through all of the custom attribute data and get all of the custom attribute ctor arguments, fields, and parameter info
  114. // On each call the CustomAttributeReaderVisitor will be called with the information for the current custom attribute
  115. // If any of the arguments are managed types (e.g. string, object, arrays) this method will allocate them on the GC heap
  116. // Call GetDataIterator to get the iterator and call this function until it returns false
  117. // If this function returns false *exc may be non-null if an exception occurred
  118. bool VisitCustomAttributeData(CustomAttributeDataIterator* iter, CustomAttributeReaderVisitor* visitor, Il2CppException** exc) const;
  119. // Get the custom attribute ctor arguments, fields, and parameter info for a single custom attribute
  120. // The CustomAttributeReaderVisitor will be called with the information for this custom attribute
  121. // Call ReadLazyCustomAttributeData to get the dataStart & dataLength parameters
  122. // If any of the arguments are managed types (e.g. string, object, arrays) this method will allocate them on the GC heap
  123. // This method returns false on error
  124. // If this function returns false *exc may be non-null if an exception occurred
  125. static bool VisitCustomAttributeData(const Il2CppImage* image, const MethodInfo* ctor, const void* dataStart, uint32_t dataLength, CustomAttributeReaderVisitor* visitor, Il2CppException** exc);
  126. CustomAttributeCtorIterator GetCtorIterator() const;
  127. CustomAttributeCtorIterator GetCtorIterator(const CustomAttributeFilter& filter) const;
  128. CustomAttributeDataIterator GetDataIterator() const;
  129. CustomAttributeDataIterator GetDataIterator(const CustomAttributeFilter& filter) const;
  130. private:
  131. CustomAttributeDataReader() : image(nullptr), bufferStart(nullptr), bufferEnd(nullptr), count(0) {}
  132. CustomAttributeDataReader(const Il2CppImage* image, const char* dataStart, uint32_t dataLength);
  133. const char* GetDataBufferStart() const;
  134. bool IterateAttributeCtorsImpl(const MethodInfo** attributeCtor, const char** ctorBuffer) const;
  135. bool ReadPastCustomAttribute(const MethodInfo* ctor, CustomAttributeDataIterator* iter, Il2CppException** exc) const;
  136. bool ReadAndVisitCustomAttributeData(const MethodInfo* ctor, CustomAttributeDataIterator* iter, CustomAttributeReaderVisitor* visitor, Il2CppException** exc) const;
  137. bool ReadAndVisitCustomAttributeImpl(const MethodInfo* ctor, CustomAttributeDataIterator* iter, CustomAttributeReaderVisitor* visitor, Il2CppException** exc, bool deserializedManagedObjects) const;
  138. const Il2CppImage* image;
  139. const char* bufferStart;
  140. const char* bufferEnd;
  141. uint32_t count;
  142. };
  143. } /* namespace vm */
  144. } /* namespace il2cpp */