/** * \file * Copyright 2016 Microsoft * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include typedef enum { PROP_MARSHAL_INFO = 1, /* MonoMarshalType */ PROP_REF_INFO_HANDLE = 2, /* gchandle */ PROP_EXCEPTION_DATA = 3, /* MonoErrorBoxed* */ PROP_NESTED_CLASSES = 4, /* GList* */ PROP_PROPERTY_INFO = 5, /* MonoClassPropertyInfo* */ PROP_EVENT_INFO = 6, /* MonoClassEventInfo* */ PROP_FIELD_DEF_VALUES = 7, /* MonoFieldDefaultValue* */ PROP_DECLSEC_FLAGS = 8 /* guint32 */ } InfrequentDataKind; /* Accessors based on class kind*/ /* * mono_class_get_generic_class: * * Return the MonoGenericClass of @klass, which MUST be a generic instance. */ MonoGenericClass* mono_class_get_generic_class (MonoClass *klass) { g_assert (mono_class_is_ginst (klass)); return ((MonoClassGenericInst*)klass)->generic_class; } /* * mono_class_try_get_generic_class: * * Return the MonoGenericClass if @klass is a ginst, NULL otherwise */ MonoGenericClass* mono_class_try_get_generic_class (MonoClass *klass) { if (mono_class_is_ginst (klass)) return ((MonoClassGenericInst*)klass)->generic_class; return NULL; } /** * mono_class_get_flags: * \param klass the MonoClass to act on * \returns the \c TypeAttributes flags of \p klass. * See the \c TYPE_ATTRIBUTE_* definitions in \c tabledefs.h for the different values. */ guint32 mono_class_get_flags (MonoClass *klass) { switch (klass->class_kind) { case MONO_CLASS_DEF: case MONO_CLASS_GTD: return ((MonoClassDef*)klass)->flags; case MONO_CLASS_GINST: return mono_class_get_flags (((MonoClassGenericInst*)klass)->generic_class->container_class); case MONO_CLASS_GPARAM: return TYPE_ATTRIBUTE_PUBLIC; case MONO_CLASS_ARRAY: /* all arrays are marked serializable and sealed, bug #42779 */ return TYPE_ATTRIBUTE_CLASS | TYPE_ATTRIBUTE_SERIALIZABLE | TYPE_ATTRIBUTE_SEALED | TYPE_ATTRIBUTE_PUBLIC; case MONO_CLASS_POINTER: return TYPE_ATTRIBUTE_CLASS | (mono_class_get_flags (klass->element_class) & TYPE_ATTRIBUTE_VISIBILITY_MASK); } g_assert_not_reached (); } void mono_class_set_flags (MonoClass *klass, guint32 flags) { g_assert (klass->class_kind == MONO_CLASS_DEF || klass->class_kind == MONO_CLASS_GTD); ((MonoClassDef*)klass)->flags = flags; } /* * mono_class_get_generic_container: * * Return the generic container of KLASS which should be a generic type definition. */ MonoGenericContainer* mono_class_get_generic_container (MonoClass *klass) { g_assert (mono_class_is_gtd (klass)); return ((MonoClassGtd*)klass)->generic_container; } MonoGenericContainer* mono_class_try_get_generic_container (MonoClass *klass) { if (mono_class_is_gtd (klass)) return ((MonoClassGtd*)klass)->generic_container; return NULL; } void mono_class_set_generic_container (MonoClass *klass, MonoGenericContainer *container) { g_assert (mono_class_is_gtd (klass)); ((MonoClassGtd*)klass)->generic_container = container; } /* * mono_class_get_first_method_idx: * * Return the table index of the first method for metadata classes. */ guint32 mono_class_get_first_method_idx (MonoClass *klass) { g_assert (mono_class_has_static_metadata (klass)); return ((MonoClassDef*)klass)->first_method_idx; } void mono_class_set_first_method_idx (MonoClass *klass, guint32 idx) { g_assert (mono_class_has_static_metadata (klass)); ((MonoClassDef*)klass)->first_method_idx = idx; } guint32 mono_class_get_first_field_idx (MonoClass *klass) { if (mono_class_is_ginst (klass)) return mono_class_get_first_field_idx (mono_class_get_generic_class (klass)->container_class); g_assert (mono_class_has_static_metadata (klass)); return ((MonoClassDef*)klass)->first_field_idx; } void mono_class_set_first_field_idx (MonoClass *klass, guint32 idx) { g_assert (mono_class_has_static_metadata (klass)); ((MonoClassDef*)klass)->first_field_idx = idx; } guint32 mono_class_get_method_count (MonoClass *klass) { switch (klass->class_kind) { case MONO_CLASS_DEF: case MONO_CLASS_GTD: return ((MonoClassDef*)klass)->method_count; case MONO_CLASS_GINST: return mono_class_get_method_count (((MonoClassGenericInst*)klass)->generic_class->container_class); case MONO_CLASS_GPARAM: return 0; case MONO_CLASS_ARRAY: return ((MonoClassArray*)klass)->method_count; case MONO_CLASS_POINTER: return 0; default: g_assert_not_reached (); return 0; } } void mono_class_set_method_count (MonoClass *klass, guint32 count) { switch (klass->class_kind) { case MONO_CLASS_DEF: case MONO_CLASS_GTD: ((MonoClassDef*)klass)->method_count = count; break; case MONO_CLASS_GINST: break; case MONO_CLASS_GPARAM: case MONO_CLASS_POINTER: g_assert (count == 0); break; case MONO_CLASS_ARRAY: ((MonoClassArray*)klass)->method_count = count; break; default: g_assert_not_reached (); break; } } guint32 mono_class_get_field_count (MonoClass *klass) { switch (klass->class_kind) { case MONO_CLASS_DEF: case MONO_CLASS_GTD: return ((MonoClassDef*)klass)->field_count; case MONO_CLASS_GINST: return mono_class_get_field_count (((MonoClassGenericInst*)klass)->generic_class->container_class); case MONO_CLASS_GPARAM: case MONO_CLASS_ARRAY: case MONO_CLASS_POINTER: return 0; default: g_assert_not_reached (); return 0; } } void mono_class_set_field_count (MonoClass *klass, guint32 count) { switch (klass->class_kind) { case MONO_CLASS_DEF: case MONO_CLASS_GTD: ((MonoClassDef*)klass)->field_count = count; break; case MONO_CLASS_GINST: break; case MONO_CLASS_GPARAM: case MONO_CLASS_ARRAY: case MONO_CLASS_POINTER: g_assert (count == 0); break; default: g_assert_not_reached (); break; } } MonoMarshalType* mono_class_get_marshal_info (MonoClass *class) { return mono_property_bag_get (&class->infrequent_data, PROP_MARSHAL_INFO); } void mono_class_set_marshal_info (MonoClass *class, MonoMarshalType *marshal_info) { marshal_info->head.tag = PROP_MARSHAL_INFO; mono_property_bag_add (&class->infrequent_data, marshal_info); } typedef struct { MonoPropertyBagItem head; guint32 value; } Uint32Property; guint32 mono_class_get_ref_info_handle (MonoClass *class) { Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_REF_INFO_HANDLE); return prop ? prop->value : 0; } guint32 mono_class_set_ref_info_handle (MonoClass *class, guint32 value) { if (!value) { Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_REF_INFO_HANDLE); if (prop) prop->value = 0; return 0; } Uint32Property *prop = mono_class_alloc (class, sizeof (Uint32Property)); prop->head.tag = PROP_REF_INFO_HANDLE; prop->value = value; prop = mono_property_bag_add (&class->infrequent_data, prop); return prop->value; } typedef struct { MonoPropertyBagItem head; gpointer value; } PointerProperty; static void set_pointer_property (MonoClass *klass, InfrequentDataKind property, gpointer value) { PointerProperty *prop = mono_class_alloc (klass, sizeof (PointerProperty)); prop->head.tag = property; prop->value = value; mono_property_bag_add (&klass->infrequent_data, prop); } static gpointer get_pointer_property (MonoClass *klass, InfrequentDataKind property) { PointerProperty *prop = (PointerProperty*)mono_property_bag_get (&klass->infrequent_data, property); return prop ? prop->value : NULL; } MonoErrorBoxed* mono_class_get_exception_data (MonoClass *klass) { return (MonoErrorBoxed*)get_pointer_property (klass, PROP_EXCEPTION_DATA); } void mono_class_set_exception_data (MonoClass *klass, MonoErrorBoxed *value) { set_pointer_property (klass, PROP_EXCEPTION_DATA, value); } GList* mono_class_get_nested_classes_property (MonoClass *klass) { return (GList*)get_pointer_property (klass, PROP_NESTED_CLASSES); } void mono_class_set_nested_classes_property (MonoClass *klass, GList *value) { set_pointer_property (klass, PROP_NESTED_CLASSES, value); } MonoClassPropertyInfo* mono_class_get_property_info (MonoClass *klass) { return mono_property_bag_get (&klass->infrequent_data, PROP_PROPERTY_INFO); } void mono_class_set_property_info (MonoClass *klass, MonoClassPropertyInfo *info) { info->head.tag = PROP_PROPERTY_INFO; mono_property_bag_add (&klass->infrequent_data, info); } MonoClassEventInfo* mono_class_get_event_info (MonoClass *klass) { return mono_property_bag_get (&klass->infrequent_data, PROP_EVENT_INFO); } void mono_class_set_event_info (MonoClass *klass, MonoClassEventInfo *info) { info->head.tag = PROP_EVENT_INFO; mono_property_bag_add (&klass->infrequent_data, info); } MonoFieldDefaultValue* mono_class_get_field_def_values (MonoClass *klass) { return (MonoFieldDefaultValue*)get_pointer_property (klass, PROP_FIELD_DEF_VALUES); } void mono_class_set_field_def_values (MonoClass *klass, MonoFieldDefaultValue *values) { set_pointer_property (klass, PROP_FIELD_DEF_VALUES, values); } guint32 mono_class_get_declsec_flags (MonoClass *class) { Uint32Property *prop = mono_property_bag_get (&class->infrequent_data, PROP_DECLSEC_FLAGS); return prop ? prop->value : 0; } void mono_class_set_declsec_flags (MonoClass *class, guint32 value) { Uint32Property *prop = mono_class_alloc (class, sizeof (Uint32Property)); prop->head.tag = PROP_DECLSEC_FLAGS; prop->value = value; mono_property_bag_add (&class->infrequent_data, prop); } void mono_class_set_is_com_object (MonoClass *klass) { #ifndef DISABLE_COM mono_loader_lock (); klass->is_com_object = 1; mono_loader_unlock (); #endif } MonoType* mono_class_gtd_get_canonical_inst (MonoClass *klass) { g_assert (mono_class_is_gtd (klass)); return &((MonoClassGtd*)klass)->canonical_inst; }