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