3 * Copyright 2016 Microsoft
4 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
7 #include <mono/metadata/class-internals.h>
8 #include <mono/metadata/marshal.h>
9 #include <mono/metadata/tabledefs.h>
10 #include <mono/metadata/class-abi-details.h>
11 #ifdef MONO_CLASS_DEF_PRIVATE
12 #include <mono/metadata/abi-details.h>
13 #define REALLY_INCLUDE_CLASS_DEF 1
14 #include <mono/metadata/class-private-definition.h>
15 #undef REALLY_INCLUDE_CLASS_DEF
19 PROP_MARSHAL_INFO
= 1, /* MonoMarshalType */
20 PROP_REF_INFO_HANDLE
= 2, /* gchandle */
21 PROP_EXCEPTION_DATA
= 3, /* MonoErrorBoxed* */
22 PROP_NESTED_CLASSES
= 4, /* GList* */
23 PROP_PROPERTY_INFO
= 5, /* MonoClassPropertyInfo* */
24 PROP_EVENT_INFO
= 6, /* MonoClassEventInfo* */
25 PROP_FIELD_DEF_VALUES
= 7, /* MonoFieldDefaultValue* */
26 PROP_DECLSEC_FLAGS
= 8, /* guint32 */
28 PROP_DIM_CONFLICTS
= 10 /* GSList of MonoMethod* */
31 /* Accessors based on class kind*/
34 * mono_class_get_generic_class:
36 * Return the MonoGenericClass of @klass, which MUST be a generic instance.
39 mono_class_get_generic_class (MonoClass
*klass
)
41 g_assert (mono_class_is_ginst (klass
));
42 return m_classgenericinst_get_generic_class ((MonoClassGenericInst
*)klass
);
46 * mono_class_try_get_generic_class:
48 * Return the MonoGenericClass if @klass is a ginst, NULL otherwise
51 mono_class_try_get_generic_class (MonoClass
*klass
)
53 if (mono_class_is_ginst (klass
))
54 return m_classgenericinst_get_generic_class ((MonoClassGenericInst
*)klass
);
59 * mono_class_get_flags:
60 * \param klass the MonoClass to act on
61 * \returns the \c TypeAttributes flags of \p klass.
62 * See the \c TYPE_ATTRIBUTE_* definitions in \c tabledefs.h for the different values.
65 mono_class_get_flags (MonoClass
*klass
)
67 switch (m_class_get_class_kind (klass
)) {
70 return m_classdef_get_flags ((MonoClassDef
*)klass
);
71 case MONO_CLASS_GINST
:
72 return mono_class_get_flags (m_classgenericinst_get_generic_class ((MonoClassGenericInst
*)klass
)->container_class
);
73 case MONO_CLASS_GPARAM
:
74 return TYPE_ATTRIBUTE_PUBLIC
;
75 case MONO_CLASS_ARRAY
:
76 /* all arrays are marked serializable and sealed, bug #42779 */
77 return TYPE_ATTRIBUTE_CLASS
| TYPE_ATTRIBUTE_SERIALIZABLE
| TYPE_ATTRIBUTE_SEALED
| TYPE_ATTRIBUTE_PUBLIC
;
78 case MONO_CLASS_POINTER
:
79 return TYPE_ATTRIBUTE_CLASS
| (mono_class_get_flags (m_class_get_element_class (klass
)) & TYPE_ATTRIBUTE_VISIBILITY_MASK
);
81 g_assert_not_reached ();
85 mono_class_set_flags (MonoClass
*klass
, guint32 flags
)
87 g_assert (m_class_get_class_kind (klass
) == MONO_CLASS_DEF
|| m_class_get_class_kind (klass
) == MONO_CLASS_GTD
);
88 ((MonoClassDef
*)klass
)->flags
= flags
;
92 * mono_class_get_generic_container:
94 * Return the generic container of KLASS which should be a generic type definition.
97 mono_class_get_generic_container (MonoClass
*klass
)
99 g_assert (mono_class_is_gtd (klass
));
101 return m_classgtd_get_generic_container ((MonoClassGtd
*)klass
);
104 MonoGenericContainer
*
105 mono_class_try_get_generic_container (MonoClass
*klass
)
107 if (mono_class_is_gtd (klass
))
108 return m_classgtd_get_generic_container ((MonoClassGtd
*)klass
);
113 mono_class_set_generic_container (MonoClass
*klass
, MonoGenericContainer
*container
)
115 g_assert (mono_class_is_gtd (klass
));
117 ((MonoClassGtd
*)klass
)->generic_container
= container
;
121 * mono_class_get_first_method_idx:
123 * Return the table index of the first method for metadata classes.
126 mono_class_get_first_method_idx (MonoClass
*klass
)
128 g_assert (mono_class_has_static_metadata (klass
));
130 return m_classdef_get_first_method_idx ((MonoClassDef
*)klass
);
134 mono_class_set_first_method_idx (MonoClass
*klass
, guint32 idx
)
136 g_assert (mono_class_has_static_metadata (klass
));
138 ((MonoClassDef
*)klass
)->first_method_idx
= idx
;
142 mono_class_get_first_field_idx (MonoClass
*klass
)
144 if (mono_class_is_ginst (klass
))
145 return mono_class_get_first_field_idx (mono_class_get_generic_class (klass
)->container_class
);
147 g_assert (klass
->type_token
&& !mono_class_is_ginst (klass
));
149 return m_classdef_get_first_field_idx ((MonoClassDef
*)klass
);
153 mono_class_set_first_field_idx (MonoClass
*klass
, guint32 idx
)
155 g_assert (klass
->type_token
&& !mono_class_is_ginst (klass
));
157 ((MonoClassDef
*)klass
)->first_field_idx
= idx
;
161 mono_class_get_method_count (MonoClass
*klass
)
163 switch (m_class_get_class_kind (klass
)) {
166 return m_classdef_get_method_count ((MonoClassDef
*)klass
);
167 case MONO_CLASS_GINST
:
168 return mono_class_get_method_count (m_classgenericinst_get_generic_class ((MonoClassGenericInst
*)klass
)->container_class
);
169 case MONO_CLASS_GPARAM
:
171 case MONO_CLASS_ARRAY
:
172 return m_classarray_get_method_count ((MonoClassArray
*)klass
);
173 case MONO_CLASS_POINTER
:
176 g_assert_not_reached ();
182 mono_class_set_method_count (MonoClass
*klass
, guint32 count
)
184 switch (m_class_get_class_kind (klass
)) {
187 ((MonoClassDef
*)klass
)->method_count
= count
;
189 case MONO_CLASS_GINST
:
191 case MONO_CLASS_GPARAM
:
192 case MONO_CLASS_POINTER
:
193 g_assert (count
== 0);
195 case MONO_CLASS_ARRAY
:
196 ((MonoClassArray
*)klass
)->method_count
= count
;
199 g_assert_not_reached ();
205 mono_class_get_field_count (MonoClass
*klass
)
207 switch (m_class_get_class_kind (klass
)) {
210 return m_classdef_get_field_count ((MonoClassDef
*)klass
);
211 case MONO_CLASS_GINST
:
212 return mono_class_get_field_count (m_classgenericinst_get_generic_class ((MonoClassGenericInst
*)klass
)->container_class
);
213 case MONO_CLASS_GPARAM
:
214 case MONO_CLASS_ARRAY
:
215 case MONO_CLASS_POINTER
:
218 g_assert_not_reached ();
224 mono_class_set_field_count (MonoClass
*klass
, guint32 count
)
226 switch (m_class_get_class_kind (klass
)) {
229 ((MonoClassDef
*)klass
)->field_count
= count
;
231 case MONO_CLASS_GINST
:
233 case MONO_CLASS_GPARAM
:
234 case MONO_CLASS_ARRAY
:
235 case MONO_CLASS_POINTER
:
236 g_assert (count
== 0);
239 g_assert_not_reached ();
245 mono_class_get_marshal_info (MonoClass
*klass
)
247 return (MonoMarshalType
*)mono_property_bag_get (m_class_get_infrequent_data (klass
), PROP_MARSHAL_INFO
);
251 mono_class_set_marshal_info (MonoClass
*klass
, MonoMarshalType
*marshal_info
)
253 marshal_info
->head
.tag
= PROP_MARSHAL_INFO
;
254 mono_property_bag_add (m_class_get_infrequent_data (klass
), marshal_info
);
258 MonoPropertyBagItem head
;
263 mono_class_get_ref_info_handle (MonoClass
*klass
)
265 Uint32Property
*prop
= (Uint32Property
*)mono_property_bag_get (m_class_get_infrequent_data (klass
), PROP_REF_INFO_HANDLE
);
266 return prop
? prop
->value
: 0;
270 mono_class_set_ref_info_handle (MonoClass
*klass
, guint32 value
)
273 Uint32Property
*prop
= (Uint32Property
*)mono_property_bag_get (m_class_get_infrequent_data (klass
), PROP_REF_INFO_HANDLE
);
279 Uint32Property
*prop
= (Uint32Property
*)mono_class_alloc (klass
, sizeof (Uint32Property
));
280 prop
->head
.tag
= PROP_REF_INFO_HANDLE
;
282 prop
= (Uint32Property
*)mono_property_bag_add (m_class_get_infrequent_data (klass
), prop
);
287 MonoPropertyBagItem head
;
292 set_pointer_property (MonoClass
*klass
, InfrequentDataKind property
, gpointer value
)
294 PointerProperty
*prop
= (PointerProperty
*)mono_class_alloc (klass
, sizeof (PointerProperty
));
295 prop
->head
.tag
= property
;
297 mono_property_bag_add (m_class_get_infrequent_data (klass
), prop
);
301 get_pointer_property (MonoClass
*klass
, InfrequentDataKind property
)
303 PointerProperty
*prop
= (PointerProperty
*)mono_property_bag_get (m_class_get_infrequent_data (klass
), property
);
304 return prop
? prop
->value
: NULL
;
308 mono_class_get_exception_data (MonoClass
*klass
)
310 return (MonoErrorBoxed
*)get_pointer_property (klass
, PROP_EXCEPTION_DATA
);
314 mono_class_set_exception_data (MonoClass
*klass
, MonoErrorBoxed
*value
)
316 set_pointer_property (klass
, PROP_EXCEPTION_DATA
, value
);
320 mono_class_get_nested_classes_property (MonoClass
*klass
)
322 return (GList
*)get_pointer_property (klass
, PROP_NESTED_CLASSES
);
326 mono_class_set_nested_classes_property (MonoClass
*klass
, GList
*value
)
328 set_pointer_property (klass
, PROP_NESTED_CLASSES
, value
);
331 MonoClassPropertyInfo
*
332 mono_class_get_property_info (MonoClass
*klass
)
334 return (MonoClassPropertyInfo
*)mono_property_bag_get (m_class_get_infrequent_data (klass
), PROP_PROPERTY_INFO
);
338 mono_class_set_property_info (MonoClass
*klass
, MonoClassPropertyInfo
*info
)
340 info
->head
.tag
= PROP_PROPERTY_INFO
;
341 mono_property_bag_add (m_class_get_infrequent_data (klass
), info
);
345 mono_class_get_event_info (MonoClass
*klass
)
347 return (MonoClassEventInfo
*)mono_property_bag_get (m_class_get_infrequent_data (klass
), PROP_EVENT_INFO
);
351 mono_class_set_event_info (MonoClass
*klass
, MonoClassEventInfo
*info
)
353 info
->head
.tag
= PROP_EVENT_INFO
;
354 mono_property_bag_add (m_class_get_infrequent_data (klass
), info
);
357 MonoFieldDefaultValue
*
358 mono_class_get_field_def_values (MonoClass
*klass
)
360 return (MonoFieldDefaultValue
*)get_pointer_property (klass
, PROP_FIELD_DEF_VALUES
);
364 mono_class_set_field_def_values (MonoClass
*klass
, MonoFieldDefaultValue
*values
)
366 set_pointer_property (klass
, PROP_FIELD_DEF_VALUES
, values
);
370 mono_class_get_declsec_flags (MonoClass
*klass
)
372 Uint32Property
*prop
= (Uint32Property
*)mono_property_bag_get (m_class_get_infrequent_data (klass
), PROP_DECLSEC_FLAGS
);
373 return prop
? prop
->value
: 0;
377 mono_class_set_declsec_flags (MonoClass
*klass
, guint32 value
)
379 Uint32Property
*prop
= (Uint32Property
*)mono_class_alloc (klass
, sizeof (Uint32Property
));
380 prop
->head
.tag
= PROP_DECLSEC_FLAGS
;
382 mono_property_bag_add (m_class_get_infrequent_data (klass
), prop
);
386 mono_class_set_is_com_object (MonoClass
*klass
)
390 klass
->is_com_object
= 1;
391 mono_loader_unlock ();
396 mono_class_gtd_get_canonical_inst (MonoClass
*klass
)
398 g_assert (mono_class_is_gtd (klass
));
399 return m_classgtd_get_canonical_inst ((MonoClassGtd
*)klass
);
403 MonoPropertyBagItem head
;
410 mono_class_set_weak_bitmap (MonoClass
*klass
, int nbits
, gsize
*bits
)
412 WeakBitmapData
*info
= (WeakBitmapData
*)mono_class_alloc (klass
, sizeof (WeakBitmapData
));
416 info
->head
.tag
= PROP_WEAK_BITMAP
;
417 mono_property_bag_add (m_class_get_infrequent_data (klass
), info
);
421 mono_class_get_weak_bitmap (MonoClass
*klass
, int *nbits
)
423 WeakBitmapData
*prop
= (WeakBitmapData
*)mono_property_bag_get (m_class_get_infrequent_data (klass
), PROP_WEAK_BITMAP
);
426 *nbits
= prop
->nbits
;
431 mono_class_has_dim_conflicts (MonoClass
*klass
)
433 if (klass
->has_dim_conflicts
)
436 if (mono_class_is_ginst (klass
)) {
437 MonoClass
*gklass
= mono_class_get_generic_class (klass
)->container_class
;
439 return gklass
->has_dim_conflicts
;
446 MonoPropertyBagItem head
;
452 mono_class_set_dim_conflicts (MonoClass
*klass
, GSList
*conflicts
)
454 DimConflictData
*info
= (DimConflictData
*)mono_class_alloc (klass
, sizeof (DimConflictData
));
455 info
->data
= conflicts
;
457 g_assert (!mono_class_is_ginst (klass
));
459 info
->head
.tag
= PROP_DIM_CONFLICTS
;
460 mono_property_bag_add (&klass
->infrequent_data
, info
);
464 mono_class_get_dim_conflicts (MonoClass
*klass
)
466 if (mono_class_is_ginst (klass
))
467 return mono_class_get_dim_conflicts (mono_class_get_generic_class (klass
)->container_class
);
469 DimConflictData
*info
= (DimConflictData
*)mono_property_bag_get (&klass
->infrequent_data
, PROP_DIM_CONFLICTS
);
476 * mono_class_set_failure:
477 * \param klass class in which the failure was detected
478 * \param ex_type the kind of exception/error to be thrown (later)
479 * \param ex_data exception data (specific to each type of exception/error)
481 * Keep a detected failure informations in the class for later processing.
482 * Note that only the first failure is kept.
484 * LOCKING: Acquires the loader lock.
487 mono_class_set_failure (MonoClass
*klass
, MonoErrorBoxed
*boxed_error
)
489 g_assert (boxed_error
!= NULL
);
491 if (mono_class_has_failure (klass
))
495 klass
->has_failure
= 1;
496 mono_class_set_exception_data (klass
, boxed_error
);
497 mono_loader_unlock ();
503 * mono_class_set_nonblittable:
504 * \param klass class which will be marked as not blittable.
506 * Mark \c klass as not blittable.
508 * LOCKING: Acquires the loader lock.
511 mono_class_set_nonblittable (MonoClass
*klass
) {
513 klass
->blittable
= FALSE
;
514 mono_loader_unlock ();
517 #ifndef DISABLE_REMOTING
519 mono_class_contextbound_bit_offset (int* byte_offset_out
, guint8
* mask_out
) {
520 mono_marshal_find_bitfield_offset (MonoClass
, contextbound
, byte_offset_out
, mask_out
);
525 * mono_class_publish_gc_descriptor:
526 * \param klass the \c MonoClass whose GC descriptor is to be set
527 * \param gc_descr the GC descriptor for \p klass
529 * Sets the \c gc_descr_inited and \c gc_descr fields of \p klass.
530 * \returns previous value of \c klass->gc_descr_inited
532 * LOCKING: Acquires the loader lock.
535 mono_class_publish_gc_descriptor (MonoClass
*klass
, MonoGCDescriptor gc_descr
)
539 ret
= klass
->gc_descr_inited
;
540 klass
->gc_descr
= gc_descr
;
541 mono_memory_barrier ();
542 klass
->gc_descr_inited
= TRUE
;
543 mono_loader_unlock ();
547 #ifdef MONO_CLASS_DEF_PRIVATE
548 #define MONO_CLASS_GETTER(funcname, rettype, optref, argtype, fieldname) rettype funcname (argtype *klass) { return optref klass-> fieldname ; }
549 #define MONO_CLASS_OFFSET(funcname, argtype, fieldname) intptr_t funcname (void) { return MONO_STRUCT_OFFSET (argtype, fieldname); }
550 #include "class-getters.h"
551 #undef MONO_CLASS_GETTER
552 #undef MONO_CLASS_OFFSET
553 #endif /* MONO_CLASS_DEF_PRIVATE */