[runtime] Move MonoClass::marshal_info and MonoClass::ext to use a property bag.
[mono.git] / mono / metadata / class-accessors.c
1 /*
2  * Copyright 2016 Microsoft
3  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
4  */
5 #include <mono/metadata/class-internals.h>
6 #include <mono/metadata/tabledefs.h>
7
8
9 enum InfrequentDataKind {
10         PROP_MARSHAL_INFO = 1, /* MonoMarshalType */
11         PROP_EXT = 2, /* MonoClassExt */
12 };
13
14 /* Accessors based on class kind*/
15
16 /*
17 * mono_class_get_generic_class:
18 *
19 *   Return the MonoGenericClass of @klass, which MUST be a generic instance.
20 */
21 MonoGenericClass*
22 mono_class_get_generic_class (MonoClass *klass)
23 {
24         g_assert (mono_class_is_ginst (klass));
25         return ((MonoClassGenericInst*)klass)->generic_class;
26 }
27
28 /*
29 * mono_class_try_get_generic_class:
30 *
31 *   Return the MonoGenericClass if @klass is a ginst, NULL otherwise
32 */
33 MonoGenericClass*
34 mono_class_try_get_generic_class (MonoClass *klass)
35 {
36         if (mono_class_is_ginst (klass))
37                 return ((MonoClassGenericInst*)klass)->generic_class;
38         return NULL;
39 }
40
41 /**
42  * mono_class_get_flags:
43  * @klass: the MonoClass to act on
44  *
45  * Return the TypeAttributes flags of @klass.
46  * See the TYPE_ATTRIBUTE_* definitions on tabledefs.h for the different values.
47  *
48  * Returns: The type flags
49  */
50 guint32
51 mono_class_get_flags (MonoClass *klass)
52 {
53         switch (klass->class_kind) {
54         case MONO_CLASS_DEF:
55         case MONO_CLASS_GTD:
56                 return ((MonoClassDef*)klass)->flags;
57         case MONO_CLASS_GINST:
58                 return mono_class_get_flags (((MonoClassGenericInst*)klass)->generic_class->container_class);
59         case MONO_CLASS_GPARAM:
60                 return TYPE_ATTRIBUTE_PUBLIC;
61         case MONO_CLASS_ARRAY:
62                 /* all arrays are marked serializable and sealed, bug #42779 */
63                 return TYPE_ATTRIBUTE_CLASS | TYPE_ATTRIBUTE_SERIALIZABLE | TYPE_ATTRIBUTE_SEALED | TYPE_ATTRIBUTE_PUBLIC;
64         case MONO_CLASS_POINTER:
65                 return TYPE_ATTRIBUTE_CLASS | (mono_class_get_flags (klass->element_class) & TYPE_ATTRIBUTE_VISIBILITY_MASK);
66         }
67         g_assert_not_reached ();
68 }
69
70 void
71 mono_class_set_flags (MonoClass *klass, guint32 flags)
72 {
73         g_assert (klass->class_kind == MONO_CLASS_DEF || klass->class_kind == MONO_CLASS_GTD);
74         ((MonoClassDef*)klass)->flags = flags;
75 }
76
77 /*
78  * mono_class_get_generic_container:
79  *
80  *   Return the generic container of KLASS which should be a generic type definition.
81  */
82 MonoGenericContainer*
83 mono_class_get_generic_container (MonoClass *klass)
84 {
85         g_assert (mono_class_is_gtd (klass));
86
87         return ((MonoClassGtd*)klass)->generic_container;
88 }
89
90 MonoGenericContainer*
91 mono_class_try_get_generic_container (MonoClass *klass)
92 {
93         if (mono_class_is_gtd (klass))
94                 return ((MonoClassGtd*)klass)->generic_container;
95         return NULL;
96 }
97
98
99 void
100 mono_class_set_generic_container (MonoClass *klass, MonoGenericContainer *container)
101 {
102         g_assert (mono_class_is_gtd (klass));
103
104         ((MonoClassGtd*)klass)->generic_container = container;
105 }
106
107 /*
108  * mono_class_get_first_method_idx:
109  *
110  *   Return the table index of the first method for metadata classes.
111  */
112 guint32
113 mono_class_get_first_method_idx (MonoClass *klass)
114 {
115         g_assert (mono_class_has_static_metadata (klass));
116
117         return ((MonoClassDef*)klass)->first_method_idx;
118 }
119
120 void
121 mono_class_set_first_method_idx (MonoClass *klass, guint32 idx)
122 {
123         g_assert (mono_class_has_static_metadata (klass));
124
125         ((MonoClassDef*)klass)->first_method_idx = idx;
126 }
127
128 guint32
129 mono_class_get_first_field_idx (MonoClass *klass)
130 {
131         if (mono_class_is_ginst (klass))
132                 return mono_class_get_first_field_idx (mono_class_get_generic_class (klass)->container_class);
133
134         g_assert (mono_class_has_static_metadata (klass));
135
136         return ((MonoClassDef*)klass)->first_field_idx;
137 }
138
139 void
140 mono_class_set_first_field_idx (MonoClass *klass, guint32 idx)
141 {
142         g_assert (mono_class_has_static_metadata (klass));
143
144         ((MonoClassDef*)klass)->first_field_idx = idx;
145 }
146
147 guint32
148 mono_class_get_method_count (MonoClass *klass)
149 {
150         switch (klass->class_kind) {
151         case MONO_CLASS_DEF:
152         case MONO_CLASS_GTD:
153                 return ((MonoClassDef*)klass)->method_count;
154         case MONO_CLASS_GINST:
155                 return mono_class_get_method_count (((MonoClassGenericInst*)klass)->generic_class->container_class);
156         case MONO_CLASS_GPARAM:
157                 return 0;
158         case MONO_CLASS_ARRAY:
159                 return ((MonoClassArray*)klass)->method_count;
160         case MONO_CLASS_POINTER:
161                 return 0;
162         default:
163                 g_assert_not_reached ();
164                 return 0;
165         }
166 }
167
168 void
169 mono_class_set_method_count (MonoClass *klass, guint32 count)
170 {
171         switch (klass->class_kind) {
172         case MONO_CLASS_DEF:
173         case MONO_CLASS_GTD:
174                 ((MonoClassDef*)klass)->method_count = count;
175                 break;
176         case MONO_CLASS_GINST:
177                 break;
178         case MONO_CLASS_GPARAM:
179         case MONO_CLASS_POINTER:
180                 g_assert (count == 0);
181                 break;
182         case MONO_CLASS_ARRAY:
183                 ((MonoClassArray*)klass)->method_count = count;
184                 break;
185         default:
186                 g_assert_not_reached ();
187                 break;
188         }
189 }
190
191 guint32
192 mono_class_get_field_count (MonoClass *klass)
193 {
194         switch (klass->class_kind) {
195         case MONO_CLASS_DEF:
196         case MONO_CLASS_GTD:
197                 return ((MonoClassDef*)klass)->field_count;
198         case MONO_CLASS_GINST:
199                 return mono_class_get_field_count (((MonoClassGenericInst*)klass)->generic_class->container_class);
200         case MONO_CLASS_GPARAM:
201         case MONO_CLASS_ARRAY:
202         case MONO_CLASS_POINTER:
203                 return 0;
204         default:
205                 g_assert_not_reached ();
206                 return 0;
207         }
208 }
209
210 void
211 mono_class_set_field_count (MonoClass *klass, guint32 count)
212 {
213         switch (klass->class_kind) {
214         case MONO_CLASS_DEF:
215         case MONO_CLASS_GTD:
216                 ((MonoClassDef*)klass)->field_count = count;
217                 break;
218         case MONO_CLASS_GINST:
219                 break;
220         case MONO_CLASS_GPARAM:
221         case MONO_CLASS_ARRAY:
222         case MONO_CLASS_POINTER:
223                 g_assert (count == 0);
224                 break;
225         default:
226                 g_assert_not_reached ();
227                 break;
228         }
229 }
230
231 MonoMarshalType*
232 mono_class_get_marshal_info (MonoClass *class)
233 {
234         return mono_property_bag_get (&class->infrequent_data, PROP_MARSHAL_INFO);
235 }
236
237 void
238 mono_class_set_marshal_info (MonoClass *class, MonoMarshalType *marshal_info)
239 {
240         marshal_info->head.tag = PROP_MARSHAL_INFO;
241         mono_property_bag_add (&class->infrequent_data, marshal_info);
242 }
243
244 MonoClassExt*
245 mono_class_get_ext (MonoClass *class)
246 {
247         return mono_property_bag_get (&class->infrequent_data, PROP_EXT);
248 }
249
250 void
251 mono_class_set_ext (MonoClass *class, MonoClassExt *ext)
252 {
253         ext->head.tag = PROP_EXT;
254         mono_property_bag_add (&class->infrequent_data, ext);
255 }