2 * Copyright 2016 Microsoft
3 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
5 #include <mono/metadata/class-internals.h>
6 #include <mono/metadata/tabledefs.h>
9 enum InfrequentDataKind {
10 PROP_MARSHAL_INFO = 1, /* MonoMarshalType */
11 PROP_EXT = 2, /* MonoClassExt */
12 PROP_REF_INFO_HANDLE = 3, /* gchandle */
15 /* Accessors based on class kind*/
18 * mono_class_get_generic_class:
20 * Return the MonoGenericClass of @klass, which MUST be a generic instance.
23 mono_class_get_generic_class (MonoClass *klass)
25 g_assert (mono_class_is_ginst (klass));
26 return ((MonoClassGenericInst*)klass)->generic_class;
30 * mono_class_try_get_generic_class:
32 * Return the MonoGenericClass if @klass is a ginst, NULL otherwise
35 mono_class_try_get_generic_class (MonoClass *klass)
37 if (mono_class_is_ginst (klass))
38 return ((MonoClassGenericInst*)klass)->generic_class;
43 * mono_class_get_flags:
44 * @klass: the MonoClass to act on
46 * Return the TypeAttributes flags of @klass.
47 * See the TYPE_ATTRIBUTE_* definitions on tabledefs.h for the different values.
49 * Returns: The type flags
52 mono_class_get_flags (MonoClass *klass)
54 switch (klass->class_kind) {
57 return ((MonoClassDef*)klass)->flags;
58 case MONO_CLASS_GINST:
59 return mono_class_get_flags (((MonoClassGenericInst*)klass)->generic_class->container_class);
60 case MONO_CLASS_GPARAM:
61 return TYPE_ATTRIBUTE_PUBLIC;
62 case MONO_CLASS_ARRAY:
63 /* all arrays are marked serializable and sealed, bug #42779 */
64 return TYPE_ATTRIBUTE_CLASS | TYPE_ATTRIBUTE_SERIALIZABLE | TYPE_ATTRIBUTE_SEALED | TYPE_ATTRIBUTE_PUBLIC;
65 case MONO_CLASS_POINTER:
66 return TYPE_ATTRIBUTE_CLASS | (mono_class_get_flags (klass->element_class) & TYPE_ATTRIBUTE_VISIBILITY_MASK);
68 g_assert_not_reached ();
72 mono_class_set_flags (MonoClass *klass, guint32 flags)
74 g_assert (klass->class_kind == MONO_CLASS_DEF || klass->class_kind == MONO_CLASS_GTD);
75 ((MonoClassDef*)klass)->flags = flags;
79 * mono_class_get_generic_container:
81 * Return the generic container of KLASS which should be a generic type definition.
84 mono_class_get_generic_container (MonoClass *klass)
86 g_assert (mono_class_is_gtd (klass));
88 return ((MonoClassGtd*)klass)->generic_container;
92 mono_class_try_get_generic_container (MonoClass *klass)
94 if (mono_class_is_gtd (klass))
95 return ((MonoClassGtd*)klass)->generic_container;
101 mono_class_set_generic_container (MonoClass *klass, MonoGenericContainer *container)
103 g_assert (mono_class_is_gtd (klass));
105 ((MonoClassGtd*)klass)->generic_container = container;
109 * mono_class_get_first_method_idx:
111 * Return the table index of the first method for metadata classes.
114 mono_class_get_first_method_idx (MonoClass *klass)
116 g_assert (mono_class_has_static_metadata (klass));
118 return ((MonoClassDef*)klass)->first_method_idx;
122 mono_class_set_first_method_idx (MonoClass *klass, guint32 idx)
124 g_assert (mono_class_has_static_metadata (klass));
126 ((MonoClassDef*)klass)->first_method_idx = idx;
130 mono_class_get_first_field_idx (MonoClass *klass)
132 if (mono_class_is_ginst (klass))
133 return mono_class_get_first_field_idx (mono_class_get_generic_class (klass)->container_class);
135 g_assert (mono_class_has_static_metadata (klass));
137 return ((MonoClassDef*)klass)->first_field_idx;
141 mono_class_set_first_field_idx (MonoClass *klass, guint32 idx)
143 g_assert (mono_class_has_static_metadata (klass));
145 ((MonoClassDef*)klass)->first_field_idx = idx;
149 mono_class_get_method_count (MonoClass *klass)
151 switch (klass->class_kind) {
154 return ((MonoClassDef*)klass)->method_count;
155 case MONO_CLASS_GINST:
156 return mono_class_get_method_count (((MonoClassGenericInst*)klass)->generic_class->container_class);
157 case MONO_CLASS_GPARAM:
159 case MONO_CLASS_ARRAY:
160 return ((MonoClassArray*)klass)->method_count;
161 case MONO_CLASS_POINTER:
164 g_assert_not_reached ();
170 mono_class_set_method_count (MonoClass *klass, guint32 count)
172 switch (klass->class_kind) {
175 ((MonoClassDef*)klass)->method_count = count;
177 case MONO_CLASS_GINST:
179 case MONO_CLASS_GPARAM:
180 case MONO_CLASS_POINTER:
181 g_assert (count == 0);
183 case MONO_CLASS_ARRAY:
184 ((MonoClassArray*)klass)->method_count = count;
187 g_assert_not_reached ();
193 mono_class_get_field_count (MonoClass *klass)
195 switch (klass->class_kind) {
198 return ((MonoClassDef*)klass)->field_count;
199 case MONO_CLASS_GINST:
200 return mono_class_get_field_count (((MonoClassGenericInst*)klass)->generic_class->container_class);
201 case MONO_CLASS_GPARAM:
202 case MONO_CLASS_ARRAY:
203 case MONO_CLASS_POINTER:
206 g_assert_not_reached ();
212 mono_class_set_field_count (MonoClass *klass, guint32 count)
214 switch (klass->class_kind) {
217 ((MonoClassDef*)klass)->field_count = count;
219 case MONO_CLASS_GINST:
221 case MONO_CLASS_GPARAM:
222 case MONO_CLASS_ARRAY:
223 case MONO_CLASS_POINTER:
224 g_assert (count == 0);
227 g_assert_not_reached ();
233 mono_class_get_marshal_info (MonoClass *class)
235 return mono_property_bag_get (&class->infrequent_data, PROP_MARSHAL_INFO);
239 mono_class_set_marshal_info (MonoClass *class, MonoMarshalType *marshal_info)
241 marshal_info->head.tag = PROP_MARSHAL_INFO;
242 mono_property_bag_add (&class->infrequent_data, marshal_info);
246 mono_class_get_ext (MonoClass *class)
248 return mono_property_bag_get (&class->infrequent_data, PROP_EXT);
252 mono_class_set_ext (MonoClass *class, MonoClassExt *ext)
254 ext->head.tag = PROP_EXT;
255 mono_property_bag_add (&class->infrequent_data, ext);
259 MonoPropertyBagItem head;
264 mono_class_get_ref_info_handle (MonoClass *class)
266 Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_REF_INFO_HANDLE);
267 return prop ? prop->value : 0;
271 mono_class_set_ref_info_handle (MonoClass *class, guint32 value)
274 Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_REF_INFO_HANDLE);
280 Uint32Property *prop = mono_class_alloc (class, sizeof (Uint32Property));
281 prop->head.tag = PROP_REF_INFO_HANDLE;
283 prop = mono_property_bag_add (&class->infrequent_data, prop);