@@ -24,67 +24,84 @@ typedef struct CollectMetadataContext
24
24
MonoMetadataSnapshot * metadata ;
25
25
} CollectMetadataContext ;
26
26
27
- static void ContextInsertClass (CollectMetadataContext * context , MonoClass * klass )
27
+ static void
28
+ ContextRecurseClassData (CollectMetadataContext * context , MonoClass * klass )
28
29
{
29
30
gpointer orig_key , value ;
31
+ gpointer iter = NULL ;
32
+ MonoClassField * field = NULL ;
33
+ int fieldCount ;
34
+
30
35
/* use g_hash_table_lookup_extended as it returns boolean to indicate if value was found.
31
36
* If we use g_hash_table_lookup it returns the value which we were comparing to NULL. The problem is
32
37
* that 0 is a valid class index and was confusing our logic.
33
38
*/
34
- if (klass -> inited && !g_hash_table_lookup_extended (context -> allTypes , klass , & orig_key , & value ))
35
- g_hash_table_insert (context -> allTypes , klass , GINT_TO_POINTER (context -> currentIndex ++ ));
39
+ if (!g_hash_table_lookup_extended (context -> allTypes , klass , & orig_key , & value )) {
40
+ g_hash_table_insert (context -> allTypes , klass , GINT_TO_POINTER (context -> currentIndex ++ ));
41
+
42
+ fieldCount = mono_class_num_fields (klass );
43
+
44
+ if (fieldCount > 0 ) {
45
+ while ((field = mono_class_get_fields (klass , & iter ))) {
46
+ MonoClass * fieldKlass = mono_class_from_mono_type (field -> type );
47
+
48
+ if (fieldKlass != klass )
49
+ ContextRecurseClassData (context , fieldKlass );
50
+ }
51
+ }
52
+ }
36
53
}
37
54
38
- static void CollectHashMapClass (gpointer key , gpointer value , gpointer user_data )
55
+ static void
56
+ CollectHashMapClass (gpointer key , gpointer value , gpointer user_data )
39
57
{
40
- CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
41
- MonoClass * klass = (MonoClass * )value ;
42
- ContextInsertClass (context , klass );
58
+ CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
59
+ MonoClass * klass = (MonoClass * )value ;
60
+ ContextRecurseClassData (context , klass );
43
61
}
44
62
45
- static void CollectHashMapListClasses (gpointer key , gpointer value , gpointer user_data )
63
+ static void
64
+ CollectHashMapListClasses (gpointer key , gpointer value , gpointer user_data )
46
65
{
47
- CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
48
- GSList * list = (GSList * )value ;
66
+ CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
67
+ GSList * list = (GSList * )value ;
49
68
50
- while (list != NULL )
51
- {
52
- MonoClass * klass = (MonoClass * )list -> data ;
53
- ContextInsertClass (context , klass );
69
+ while (list != NULL ) {
70
+ MonoClass * klass = (MonoClass * )list -> data ;
71
+ ContextRecurseClassData (context , klass );
54
72
55
- list = g_slist_next (list );
73
+ list = g_slist_next (list );
56
74
}
57
75
}
58
76
59
- static void CollectGenericClass (MonoGenericClass * genericClass , gpointer user_data )
77
+ static void
78
+ CollectGenericClass (MonoGenericClass * genericClass , gpointer user_data )
60
79
{
61
- CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
80
+ CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
62
81
63
82
if (genericClass -> cached_class != NULL )
64
- ContextInsertClass (context , genericClass -> cached_class );
83
+ ContextRecurseClassData (context , genericClass -> cached_class );
65
84
}
66
85
67
- static void CollectImageMetaData (MonoImage * image , gpointer value , CollectMetadataContext * context )
86
+ static void
87
+ CollectImageMetaData (MonoImage * image , gpointer value , CollectMetadataContext * context )
68
88
{
69
89
int i ;
70
90
MonoTableInfo * tdef = & image -> tables [MONO_TABLE_TYPEDEF ];
71
91
GSList * list ;
72
92
73
- if (image -> dynamic )
74
- {
93
+ if (image -> dynamic ) {
75
94
GHashTableIter iter ;
76
95
gpointer key ;
77
- MonoDynamicImage * dynamicImage = (MonoDynamicImage * )image ;
78
-
79
- g_hash_table_iter_init (& iter , dynamicImage -> typeref );
96
+ MonoDynamicImage * dynamicImage = (MonoDynamicImage * )image ;
97
+ g_hash_table_iter_init (& iter , dynamicImage -> typeref );
80
98
81
- while (g_hash_table_iter_next (& iter , & key , NULL ))
82
- {
83
- MonoType * monoType = (MonoType * )key ;
84
- MonoClass * klass = mono_type_get_class (monoType );
99
+ while (g_hash_table_iter_next (& iter , & key , NULL )) {
100
+ MonoType * monoType = (MonoType * )key ;
101
+ MonoClass * klass = mono_class_from_mono_type (monoType );
85
102
86
103
if (klass )
87
- ContextInsertClass (context , klass );
104
+ ContextRecurseClassData (context , klass );
88
105
}
89
106
}
90
107
@@ -93,119 +110,121 @@ static void CollectImageMetaData(MonoImage* image, gpointer value, CollectMetada
93
110
*/
94
111
list = image -> reflection_info_unregister_classes ;
95
112
96
- while (list )
97
- {
113
+ while (list ) {
98
114
MonoClass * klass = (MonoClass * )list -> data ;
99
115
100
116
if (klass )
101
- ContextInsertClass (context , klass );
117
+ ContextRecurseClassData (context , klass );
102
118
103
119
list = list -> next ;
104
120
}
105
121
106
- for (i = 1 ; i < tdef -> rows ; ++ i )
107
- {
122
+ for (i = 1 ; i < tdef -> rows ; ++ i ) {
108
123
MonoClass * klass ;
109
124
MonoError error ;
110
125
111
126
guint32 token = (i + 1 ) | MONO_TOKEN_TYPE_DEF ;
112
127
113
- klass = mono_class_get_checked (image , token , & error );
128
+ klass = mono_class_get_checked (image , token , & error );
114
129
115
130
if (klass )
116
- ContextInsertClass (context , klass );
131
+ ContextRecurseClassData (context , klass );
117
132
}
118
133
119
134
if (image -> array_cache )
120
- g_hash_table_foreach (image -> array_cache , CollectHashMapListClasses , context );
135
+ g_hash_table_foreach (image -> array_cache , CollectHashMapListClasses , context );
121
136
122
137
if (image -> szarray_cache )
123
- g_hash_table_foreach (image -> szarray_cache , CollectHashMapClass , context );
138
+ g_hash_table_foreach (image -> szarray_cache , CollectHashMapClass , context );
124
139
125
140
if (image -> ptr_cache )
126
- g_hash_table_foreach (image -> ptr_cache , CollectHashMapClass , context );
141
+ g_hash_table_foreach (image -> ptr_cache , CollectHashMapClass , context );
127
142
}
128
143
129
- static int FindClassIndex (GHashTable * hashTable , MonoClass * klass )
144
+ static int
145
+ FindClassIndex (GHashTable * hashTable , MonoClass * klass )
130
146
{
131
147
gpointer orig_key , value ;
132
148
133
- if (!g_hash_table_lookup_extended (hashTable , klass , & orig_key , & value ))
149
+ if (!g_hash_table_lookup_extended (hashTable , klass , & orig_key , & value ))
134
150
return -1 ;
135
151
136
- return GPOINTER_TO_INT (value );
152
+ return GPOINTER_TO_INT (value );
137
153
}
138
154
139
- static void AddMetadataType (gpointer key , gpointer value , gpointer user_data )
155
+ static void
156
+ AddMetadataType (gpointer key , gpointer value , gpointer user_data )
140
157
{
141
- MonoClass * klass = (MonoClass * )key ;
142
- int index = GPOINTER_TO_INT (value );
143
- CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
144
- MonoMetadataSnapshot * metadata = context -> metadata ;
145
- MonoMetadataType * type = & metadata -> types [index ];
158
+ MonoClass * klass = (MonoClass * )key ;
146
159
147
- if (klass -> rank > 0 )
148
- {
149
- type -> flags = (MonoMetadataTypeFlags )(kArray | (kArrayRankMask & (klass -> rank << 16 )));
150
- type -> baseOrElementTypeIndex = FindClassIndex (context -> allTypes , mono_class_get_element_class (klass ));
151
- }
152
- else
153
- {
160
+ int index = GPOINTER_TO_INT (value );
161
+ CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
162
+ MonoMetadataSnapshot * metadata = context -> metadata ;
163
+ MonoMetadataType * type = & metadata -> types [index ];
164
+
165
+ if (klass -> rank > 0 ) {
166
+ type -> flags = (MonoMetadataTypeFlags ) (kArray | (kArrayRankMask & (klass -> rank << 16 )));
167
+ type -> baseOrElementTypeIndex = FindClassIndex (context -> allTypes , mono_class_get_element_class (klass ));
168
+ } else {
154
169
gpointer iter = NULL ;
155
170
int fieldCount = 0 ;
156
- MonoClassField * field ;
157
- MonoClass * baseClass ;
158
- MonoVTable * vtable ;
159
- void * statics_data ;
171
+ MonoClassField * field ;
172
+ MonoClass * baseClass ;
173
+ MonoVTable * vtable ;
174
+ void * statics_data ;
160
175
161
176
type -> flags = (klass -> valuetype || klass -> byval_arg .type == MONO_TYPE_PTR ) ? kValueType : kNone ;
162
177
type -> fieldCount = 0 ;
178
+ fieldCount = mono_class_num_fields (klass );
179
+ if (fieldCount > 0 ) {
180
+ type -> fields = g_new (MonoMetadataField , fieldCount );
163
181
164
- if ( mono_class_num_fields ( klass ) > 0 )
165
- {
166
- type -> fields = g_new ( MonoMetadataField , mono_class_num_fields ( klass ) );
182
+ while (( field = mono_class_get_fields ( klass , & iter ))) {
183
+ MonoMetadataField * metaField = & type -> fields [ type -> fieldCount ];
184
+ MonoClass * typeKlass = mono_class_from_mono_type ( field -> type );
167
185
168
- while (( field = mono_class_get_fields ( klass , & iter )) )
169
- {
170
- MonoMetadataField * metaField = & type -> fields [ type -> fieldCount ];
171
- metaField -> typeIndex = FindClassIndex (context -> allTypes , mono_class_from_mono_type ( field -> type ) );
186
+ if ( typeKlass -> rank > 0 )
187
+ metaField -> typeIndex = FindClassIndex ( context -> allTypes , mono_class_get_element_class ( typeKlass ));
188
+ else
189
+ metaField -> typeIndex = FindClassIndex (context -> allTypes , typeKlass );
172
190
173
191
// This will happen if fields type is not initialized
174
192
// It's OK to skip it, because it means the field is guaranteed to be null on any object
175
- if (metaField -> typeIndex == -1 )
193
+ if (metaField -> typeIndex == -1 ) {
176
194
continue ;
195
+ }
177
196
178
197
// literals have no actual storage, and are not relevant in this context.
179
198
if ((field -> type -> attrs & FIELD_ATTRIBUTE_LITERAL ) != 0 )
180
199
continue ;
181
200
182
201
metaField -> isStatic = (field -> type -> attrs & FIELD_ATTRIBUTE_STATIC ) != 0 ;
202
+
183
203
metaField -> offset = field -> offset ;
184
204
metaField -> name = field -> name ;
185
205
type -> fieldCount ++ ;
186
206
}
187
207
}
188
208
189
- vtable = mono_class_try_get_vtable (mono_domain_get (), klass );
190
- statics_data = vtable ? mono_vtable_get_static_field_data (vtable ) : NULL ;
209
+ vtable = mono_class_try_get_vtable (mono_domain_get (), klass );
210
+ statics_data = vtable ? mono_vtable_get_static_field_data (vtable ) : NULL ;
191
211
192
- type -> staticsSize = statics_data ? mono_class_data_size (klass ) : 0 ;
212
+ type -> staticsSize = statics_data ? mono_class_data_size (klass ) : 0 ;
193
213
type -> statics = NULL ;
194
214
195
- if (type -> staticsSize > 0 )
196
- {
197
- type -> statics = g_new0 (uint8_t , type -> staticsSize );
198
- memcpy (type -> statics , statics_data , type -> staticsSize );
215
+ if (type -> staticsSize > 0 ) {
216
+ type -> statics = g_new0 (uint8_t , type -> staticsSize );
217
+ memcpy (type -> statics , statics_data , type -> staticsSize );
199
218
}
200
219
201
- baseClass = mono_class_get_parent (klass );
202
- type -> baseOrElementTypeIndex = baseClass ? FindClassIndex (context -> allTypes , baseClass ) : -1 ;
220
+ baseClass = mono_class_get_parent (klass );
221
+ type -> baseOrElementTypeIndex = baseClass ? FindClassIndex (context -> allTypes , baseClass ) : -1 ;
203
222
}
204
223
205
- type -> assemblyName = mono_class_get_image (klass )-> assembly -> aname .name ;
206
- type -> name = mono_type_get_name_full (& klass -> byval_arg , MONO_TYPE_NAME_FORMAT_IL );
224
+ type -> assemblyName = mono_class_get_image (klass )-> assembly -> aname .name ;
225
+ type -> name = mono_type_get_name_full (& klass -> byval_arg , MONO_TYPE_NAME_FORMAT_IL );
207
226
type -> typeInfoAddress = (uint64_t )klass ;
208
- type -> size = (klass -> valuetype ) != 0 ? (mono_class_instance_size (klass ) - sizeof (MonoObject )) : mono_class_instance_size (klass );
227
+ type -> size = (klass -> valuetype ) != 0 ? (mono_class_instance_size (klass ) - sizeof (MonoObject )) : mono_class_instance_size (klass );
209
228
}
210
229
211
230
static void CollectMetadata (MonoMetadataSnapshot * metadata , GHashTable * monoImages )
0 commit comments