X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fclass.c;h=da8fc30585b67fb1fa23f44a182cb0ae2ea3ce3f;hb=ac1d494270ac25b3fd885ef7d8b52cb27109861d;hp=efdf249c61587ec203aaee14b1526fef6096624d;hpb=e103b436e789f25e32e5f13b16959803c9369596;p=mono.git diff --git a/mono/metadata/class.c b/mono/metadata/class.c index efdf249c615..da8fc30585b 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -1,5 +1,6 @@ -/* - * class.c: Class management for the Mono runtime +/** + * \file + * Class management for the Mono runtime * * Author: * Miguel de Icaza (miguel@ximian.com) @@ -45,6 +46,7 @@ #include #include #include +#include #include #include @@ -54,9 +56,9 @@ gboolean mono_print_vtable = FALSE; gboolean mono_align_small_structs = FALSE; /* Statistics */ -guint32 inflated_classes_size, inflated_methods_size; -guint32 classes_size, class_ext_size, class_ext_count; -guint32 class_def_count, class_gtd_count, class_ginst_count, class_gparam_count, class_array_count, class_pointer_count; +gint32 inflated_classes_size, inflated_methods_size; +gint32 classes_size; +gint32 class_def_count, class_gtd_count, class_ginst_count, class_gparam_count, class_array_count, class_pointer_count; /* Low level lock which protects data structures in this module */ static mono_mutex_t classes_mutex; @@ -69,7 +71,7 @@ static gboolean mono_class_get_cached_class_info (MonoClass *klass, MonoCachedCl static gboolean can_access_type (MonoClass *access_klass, MonoClass *member_klass); static MonoMethod* find_method_in_metadata (MonoClass *klass, const char *name, int param_count, int flags); static int generic_array_methods (MonoClass *klass); -static void setup_generic_array_ifaces (MonoClass *klass, MonoClass *iface, MonoMethod **methods, int pos); +static void setup_generic_array_ifaces (MonoClass *klass, MonoClass *iface, MonoMethod **methods, int pos, GHashTable *cache); static MonoMethod* mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter); static char* mono_assembly_name_from_token (MonoImage *image, guint32 type_token); @@ -164,12 +166,12 @@ disable_gclass_recording (gclass_record_func func, void *user_data) /** * mono_class_from_typeref: - * @image: a MonoImage - * @type_token: a TypeRef token + * \param image a MonoImage + * \param type_token a TypeRef token * - * Creates the MonoClass* structure representing the type defined by - * the typeref token valid inside @image. - * Returns: The MonoClass* representing the typeref token, NULL ifcould + * Creates the \c MonoClass* structure representing the type defined by + * the typeref token valid inside \p image. + * \returns The \c MonoClass* representing the typeref token, or NULL if it could * not be loaded. */ MonoClass * @@ -183,15 +185,15 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token) /** * mono_class_from_typeref_checked: - * @image: a MonoImage - * @type_token: a TypeRef token - * @error: error return code, if any. + * \param image a MonoImage + * \param type_token a TypeRef token + * \param error error return code, if any. * - * Creates the MonoClass* structure representing the type defined by - * the typeref token valid inside @image. + * Creates the \c MonoClass* structure representing the type defined by + * the typeref token valid inside \p image. * - * Returns: The MonoClass* representing the typeref token, NULL if it could - * not be loaded with the @error value filled with the information about the + * \returns The \c MonoClass* representing the typeref token, NULL if it could + * not be loaded with the \p error value filled with the information about the * error. */ MonoClass * @@ -204,7 +206,7 @@ mono_class_from_typeref_checked (MonoImage *image, guint32 type_token, MonoError MonoClass *res = NULL; MonoImage *module; - mono_error_init (error); + error_init (error); if (!mono_verifier_verify_typeref_row (image, (type_token & 0xffffff) - 1, error)) return NULL; @@ -300,7 +302,7 @@ done: if (!res && mono_error_ok (error)) { char *name = mono_class_name_from_token (image, type_token); char *assembly = mono_assembly_name_from_token (image, type_token); - mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x", type_token); + mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x (from typeref, class/assembly %s, %s)", type_token, name, assembly); } return res; } @@ -369,10 +371,10 @@ mono_type_name_check_byref (MonoType *type, GString *str) /** * mono_identifier_escape_type_name_chars: - * @str: a destination string - * @identifier: an IDENTIFIER in internal form + * \param str a destination string + * \param identifier an IDENTIFIER in internal form * - * Returns: str. + * \returns \p str * * The displayed form of the identifier is appended to str. * @@ -568,22 +570,22 @@ mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed, /** * mono_type_get_name_full: - * @type: a type - * @format: the format for the return string. + * \param type a type + * \param format the format for the return string. * * - * Returns: The string representation in a number of formats: + * \returns The string representation in a number of formats: * - * if format is MONO_TYPE_NAME_FORMAT_REFLECTION, the return string is - * returned in the formatrequired by System.Reflection, this is the - * inverse of mono_reflection_parse_type (). + * if \p format is \c MONO_TYPE_NAME_FORMAT_REFLECTION, the return string is + * returned in the format required by \c System.Reflection, this is the + * inverse of mono_reflection_parse_type(). * - * if format is MONO_TYPE_NAME_FORMAT_IL, it returns a syntax that can + * if \p format is \c MONO_TYPE_NAME_FORMAT_IL, it returns a syntax that can * be used by the IL assembler. * - * if format is MONO_TYPE_NAME_FORMAT_FULL_NAME + * if \p format is \c MONO_TYPE_NAME_FORMAT_FULL_NAME * - * if format is MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED + * if \p format is \c MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED */ char* mono_type_get_name_full (MonoType *type, MonoTypeNameFormat format) @@ -599,10 +601,10 @@ mono_type_get_name_full (MonoType *type, MonoTypeNameFormat format) /** * mono_type_get_full_name: - * @class: a class + * \param class a class * - * Returns: The string representation for type as required by System.Reflection. - * The inverse of mono_reflection_parse_type (). + * \returns The string representation for type as required by System.Reflection. + * The inverse of mono_reflection_parse_type(). */ char * mono_type_get_full_name (MonoClass *klass) @@ -612,9 +614,8 @@ mono_type_get_full_name (MonoClass *klass) /** * mono_type_get_name: - * @type: a type - * - * Returns: The string representation for type as it would be represented in IL code. + * \param type a type + * \returns The string representation for type as it would be represented in IL code. */ char* mono_type_get_name (MonoType *type) @@ -622,11 +623,10 @@ mono_type_get_name (MonoType *type) return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_IL); } -/* +/** * mono_type_get_underlying_type: - * @type: a type - * - * Returns: The MonoType for the underlying integer type if @type + * \param type a type + * \returns The \c MonoType for the underlying integer type if \p type * is an enum and byref is false, otherwise the type itself. */ MonoType* @@ -641,9 +641,9 @@ mono_type_get_underlying_type (MonoType *type) /** * mono_class_is_open_constructed_type: - * @type: a type + * \param type a type * - * Returns: TRUE if type represents a generics open constructed type. + * \returns TRUE if type represents a generics open constructed type. * IOW, not all type parameters required for the instantiation have * been provided or it's a generic type definition. * @@ -693,7 +693,7 @@ is_valid_generic_argument (MonoType *type) static MonoType* inflate_generic_type (MonoImage *image, MonoType *type, MonoGenericContext *context, MonoError *error) { - mono_error_init (error); + error_init (error); switch (type->type) { case MONO_TYPE_MVAR: { @@ -849,7 +849,7 @@ MonoType* mono_class_inflate_generic_type_with_mempool (MonoImage *image, MonoType *type, MonoGenericContext *context, MonoError *error) { MonoType *inflated = NULL; - mono_error_init (error); + error_init (error); if (context) inflated = inflate_generic_type (image, type, context, error); @@ -865,22 +865,21 @@ mono_class_inflate_generic_type_with_mempool (MonoImage *image, MonoType *type, } } - mono_stats.inflated_type_count++; + UnlockedIncrement (&mono_stats.inflated_type_count); return inflated; } -/* +/** * mono_class_inflate_generic_type: - * @type: a type - * @context: a generics context + * \param type a type + * \param context a generics context + * \deprecated Please use \c mono_class_inflate_generic_type_checked instead * - * If @type is a generic type and @context is not NULL, instantiate it using the - * generics context @context. + * If \p type is a generic type and \p context is not NULL, instantiate it using the + * generics context \p context. * - * Returns: The instantiated type or a copy of @type. The returned MonoType is allocated + * \returns The instantiated type or a copy of \p type. The returned \c MonoType is allocated * on the heap and is owned by the caller. Returns NULL on error. - * - * @deprecated Please use mono_class_inflate_generic_type_checked instead */ MonoType* mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context) @@ -921,7 +920,7 @@ mono_class_inflate_generic_type_no_copy (MonoImage *image, MonoType *type, MonoG { MonoType *inflated = NULL; - mono_error_init (error); + error_init (error); if (context) { inflated = inflate_generic_type (image, type, context, error); return_val_if_nok (error, NULL); @@ -930,7 +929,7 @@ mono_class_inflate_generic_type_no_copy (MonoImage *image, MonoType *type, MonoG if (!inflated) return type; - mono_stats.inflated_type_count++; + UnlockedIncrement (&mono_stats.inflated_type_count); return inflated; } @@ -961,7 +960,7 @@ inflate_generic_context (MonoGenericContext *context, MonoGenericContext *inflat MonoGenericInst *method_inst = NULL; MonoGenericContext res = { NULL, NULL }; - mono_error_init (error); + error_init (error); if (context->class_inst) { class_inst = mono_metadata_inflate_generic_inst (context->class_inst, inflate_with, error); @@ -981,14 +980,14 @@ fail: return res; } -/* +/** * mono_class_inflate_generic_method: - * @method: a generic method - * @context: a generics context + * \param method a generic method + * \param context a generics context * - * Instantiate the generic method @method using the generics context @context. + * Instantiate the generic method \p method using the generics context \p context. * - * Returns: The new instantiated method + * \returns The new instantiated method */ MonoMethod * mono_class_inflate_generic_method (MonoMethod *method, MonoGenericContext *context) @@ -1005,9 +1004,9 @@ mono_class_inflate_generic_method_checked (MonoMethod *method, MonoGenericContex /** * mono_class_inflate_generic_method_full: * - * Instantiate method @method with the generic context @context. + * Instantiate method \p method with the generic context \p context. * BEWARE: All non-trivial fields are invalid, including klass, signature, and header. - * Use mono_method_signature () and mono_method_get_header () to get the correct values. + * Use mono_method_signature() and mono_method_get_header() to get the correct values. */ MonoMethod* mono_class_inflate_generic_method_full (MonoMethod *method, MonoClass *klass_hint, MonoGenericContext *context) @@ -1023,7 +1022,7 @@ mono_class_inflate_generic_method_full (MonoMethod *method, MonoClass *klass_hin /** * mono_class_inflate_generic_method_full_checked: - * Same as mono_class_inflate_generic_method_full but return failure using @error. + * Same as mono_class_inflate_generic_method_full but return failure using \p error. */ MonoMethod* mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *klass_hint, MonoGenericContext *context, MonoError *error) @@ -1033,7 +1032,7 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k MonoMethodSignature *sig; MonoGenericContext tmp_context; - mono_error_init (error); + error_init (error); /* The `method' has already been instantiated before => we need to peel out the instantiation and create a new context */ while (method->is_inflated) { @@ -1091,9 +1090,9 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k return (MonoMethod*)cached; } - mono_stats.inflated_method_count++; + UnlockedIncrement (&mono_stats.inflated_method_count); - inflated_methods_size += sizeof (MonoMethodInflated); + UnlockedAdd (&inflated_methods_size, sizeof (MonoMethodInflated)); sig = mono_method_signature (method); if (!sig) { @@ -1270,7 +1269,7 @@ mono_method_set_generic_container (MonoMethod *method, MonoGenericContainer* con /** * mono_class_find_enum_basetype: - * @class: The enum class + * \param class The enum class * * Determine the basetype of an enum by iterating through its fields. We do this * in a separate function since it is cheaper than calling mono_class_setup_fields. @@ -1285,7 +1284,7 @@ mono_class_find_enum_basetype (MonoClass *klass, MonoError *error) g_assert (klass->enumtype); - mono_error_init (error); + error_init (error); container = mono_class_try_get_generic_container (klass); if (mono_class_is_ginst (klass)) { @@ -1403,7 +1402,7 @@ mono_class_alloc0 (MonoClass *klass, int size) /** * mono_class_setup_basic_field_info: - * @class: The class to initialize + * \param class The class to initialize * * Initializes the following fields in MonoClass: * * klass->fields (only field->parent and field->name) @@ -1480,21 +1479,21 @@ mono_class_setup_basic_field_info (MonoClass *klass) /** * mono_class_set_failure_causedby_class: - * @klass: the class that is failing - * @caused_by: the class that caused the failure - * @msg: Why @klass is failing. + * \param klass the class that is failing + * \param caused_by the class that caused the failure + * \param msg Why \p klass is failing. * - * If @caused_by has a failure, sets a TypeLoadException failure on - * @klass with message "@msg, due to: {@caused_by message}". + * If \p caused_by has a failure, sets a TypeLoadException failure on + * \p klass with message "\p msg, due to: {\p caused_by message}". * - * Returns: TRUE if a failiure was set, or FALSE if @caused_by doesn't have a failure. + * \returns TRUE if a failiure was set, or FALSE if \p caused_by doesn't have a failure. */ static gboolean mono_class_set_type_load_failure_causedby_class (MonoClass *klass, const MonoClass *caused_by, const gchar* msg) { if (mono_class_has_failure (caused_by)) { MonoError cause_error; - mono_error_init (&cause_error); + error_init (&cause_error); mono_error_set_for_class_failure (&cause_error, caused_by); mono_class_set_type_load_failure (klass, "%s, due to: %s", msg, mono_error_get_message (&cause_error)); mono_error_cleanup (&cause_error); @@ -1507,13 +1506,14 @@ mono_class_set_type_load_failure_causedby_class (MonoClass *klass, const MonoCla /** * mono_class_setup_fields: - * @klass: The class to initialize + * \p klass The class to initialize * * Initializes klass->fields, computes class layout and sizes. * typebuilder_setup_fields () is the corresponding function for dynamic classes. - * Sets the following fields in @klass: + * Sets the following fields in \p klass: * - all the fields initialized by mono_class_init_sizes () * - element_class/cast_class (for enums) + * - sizes:element_size (for arrays) * - field->type/offset for all fields * - fields_inited * @@ -1604,6 +1604,11 @@ mono_class_setup_fields (MonoClass *klass) g_assert (field->type); } + if (!mono_type_get_underlying_type (field->type)) { + mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name); + break; + } + if (mono_field_is_deleted (field)) continue; if (layout == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) { @@ -1628,8 +1633,7 @@ mono_class_setup_fields (MonoClass *klass) char *class_name = mono_type_get_full_name (klass); char *type_name = mono_type_full_name (field->type); - mono_class_set_type_load_failure (klass, ""); - g_warning ("Invalid type %s for instance field %s:%s", type_name, class_name, field->name); + mono_class_set_type_load_failure (klass, "Invalid type %s for instance field %s:%s", type_name, class_name, field->name); g_free (class_name); g_free (type_name); break; @@ -1769,6 +1773,7 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_ MonoClassField *field; gboolean blittable; int instance_size = base_instance_size; + int element_size = -1; int class_size, min_align; int *field_offsets; gboolean *fields_has_references; @@ -1860,7 +1865,7 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_ mono_class_setup_fields (field_class); if (mono_class_has_failure (field_class)) { MonoError field_error; - mono_error_init (&field_error); + error_init (&field_error); mono_error_set_for_class_failure (&field_error, field_class); mono_class_set_type_load_failure (klass, "Could not set up field '%s' due to: %s", field->name, mono_error_get_message (&field_error)); mono_error_cleanup (&field_error); @@ -2098,6 +2103,9 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_ else if (klass->byval_arg.type == MONO_TYPE_PTR) instance_size = sizeof (MonoObject) + sizeof (gpointer); + if (klass->byval_arg.type == MONO_TYPE_SZARRAY || klass->byval_arg.type == MONO_TYPE_ARRAY) + element_size = mono_class_array_element_size (klass->element_class); + /* Publish the data */ mono_loader_lock (); if (klass->instance_size && !klass->image->dynamic) { @@ -2128,6 +2136,9 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_ klass->fields [i].offset = field_offsets [i]; } + if (klass->byval_arg.type == MONO_TYPE_SZARRAY || klass->byval_arg.type == MONO_TYPE_ARRAY) + klass->sizes.element_size = element_size; + mono_memory_barrier (); klass->size_inited = 1; mono_loader_unlock (); @@ -2363,8 +2374,10 @@ mono_class_setup_methods (MonoClass *klass) amethod = create_array_method (klass, "Set", sig); methods [method_num++] = amethod; + GHashTable *cache = g_hash_table_new (NULL, NULL); for (i = 0; i < klass->interface_count; i++) - setup_generic_array_ifaces (klass, klass->interfaces [i], methods, first_generic + i * count_generic); + setup_generic_array_ifaces (klass, klass->interfaces [i], methods, first_generic + i * count_generic, cache); + g_hash_table_destroy (cache); } else if (mono_class_has_static_metadata (klass)) { MonoError error; int first_idx = mono_class_get_first_method_idx (klass); @@ -2698,7 +2711,7 @@ mono_class_setup_events (MonoClass *klass) MonoEvent *event = &events [i]; MonoEvent *gevent = &ginfo->events [i]; - mono_error_init (&error); //since we do conditional calls, we must ensure the default value is ok + error_init (&error); //since we do conditional calls, we must ensure the default value is ok event->parent = klass; event->name = gevent->name; @@ -2828,12 +2841,12 @@ mono_unload_interface_id (MonoClass *klass) /** * mono_get_unique_iid: - * @class: interface + * \param klass interface * - * Assign a unique integer ID to the interface represented by @class. + * Assign a unique integer ID to the interface represented by \p klass. * The ID will positive and as small as possible. * LOCKING: Acquires the classes lock. - * Returns: The new ID. + * \returns The new ID. */ static guint32 mono_get_unique_iid (MonoClass *klass) @@ -2913,6 +2926,10 @@ collect_implemented_interfaces_aux (MonoClass *klass, GPtrArray **res, GHashTabl *ifaces = g_hash_table_new (NULL, NULL); if (g_hash_table_lookup (*ifaces, ic)) continue; + /* A gparam is not an implemented interface for the purposes of + * mono_class_get_implemented_interfaces */ + if (mono_class_is_gparam (ic)) + continue; g_ptr_array_add (*res, ic); g_hash_table_insert (*ifaces, ic, ic); mono_class_init (ic); @@ -2972,8 +2989,8 @@ mono_class_interface_offset (MonoClass *klass, MonoClass *itf) /** * mono_class_interface_offset_with_variance: * - * Return the interface offset of @itf in @klass. Sets @non_exact_match to TRUE if the match required variance check - * If @itf is an interface with generic variant arguments, try to find the compatible one. + * Return the interface offset of \p itf in \p klass. Sets \p non_exact_match to TRUE if the match required variance check + * If \p itf is an interface with generic variant arguments, try to find the compatible one. * * Note that this function is responsible for resolving ambiguities. Right now we use whatever ordering interfaces_packed gives us. * @@ -3198,19 +3215,19 @@ set_interface_and_offset (int num_ifaces, MonoClass **interfaces_full, int *inte /** * mono_compress_bitmap: - * @dest: destination buffer - * @bitmap: bitmap buffer - * @size: size of @bitmap in bytes + * \param dest destination buffer + * \param bitmap bitmap buffer + * \param size size of \p bitmap in bytes * * This is a mono internal function. - * The @bitmap data is compressed into a format that is small but + * The \p bitmap data is compressed into a format that is small but * still searchable in few instructions by the JIT and runtime. * The compressed data is stored in the buffer pointed to by the - * @dest array. Passing a #NULL value for @dest allows to just compute + * \p dest array. Passing a NULL value for \p dest allows to just compute * the size of the buffer. * This compression algorithm assumes the bits set in the bitmap are * few and far between, like in interface bitmaps. - * Returns: The size of the compressed bitmap in bytes. + * \returns The size of the compressed bitmap in bytes. */ int mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size) @@ -3244,16 +3261,16 @@ mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size) /** * mono_class_interface_match: - * @bitmap: a compressed bitmap buffer - * @id: the index to check in the bitmap + * \param bitmap a compressed bitmap buffer + * \param id the index to check in the bitmap * * This is a mono internal function. - * Checks if a bit is set in a compressed interface bitmap. @id must + * Checks if a bit is set in a compressed interface bitmap. \p id must * be already checked for being smaller than the maximum id encoded in the * bitmap. * - * Returns: A non-zero value if bit @id is set in the bitmap @bitmap, - * #FALSE otherwise. + * \returns A non-zero value if bit \p id is set in the bitmap \p bitmap, + * FALSE otherwise. */ int mono_class_interface_match (const uint8_t *bitmap, int id) @@ -3303,7 +3320,9 @@ setup_interface_offsets (MonoClass *klass, int cur_slot, gboolean overwrite) for (i = 0; i < k->interface_count; i++) { ic = k->interfaces [i]; - mono_class_init (ic); + /* A gparam does not have any interface_id set. */ + if (! mono_class_is_gparam (ic)) + mono_class_init (ic); if (max_iid < ic->interface_id) max_iid = ic->interface_id; @@ -3564,7 +3583,7 @@ mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup) return; } - mono_stats.generic_vtable_count ++; + UnlockedIncrement (&mono_stats.generic_vtable_count); in_setup = g_list_prepend (in_setup, klass); if (mono_class_is_ginst (klass)) { @@ -3687,7 +3706,7 @@ is_wcf_hack_disabled (void) static gboolean disabled; static gboolean inited = FALSE; if (!inited) { - disabled = g_getenv ("MONO_DISABLE_WCF_HACK") != NULL; + disabled = g_hasenv ("MONO_DISABLE_WCF_HACK"); inited = TRUE; } return disabled; @@ -4034,6 +4053,32 @@ mono_class_need_stelemref_method (MonoClass *klass) return klass->rank == 1 && MONO_TYPE_IS_REFERENCE (&klass->element_class->byval_arg); } +static int +apply_override (MonoClass *klass, MonoMethod **vtable, MonoMethod *decl, MonoMethod *override) +{ + int dslot; + dslot = mono_method_get_vtable_slot (decl); + if (dslot == -1) { + mono_class_set_type_load_failure (klass, ""); + return FALSE; + } + + dslot += mono_class_interface_offset (klass, decl->klass); + vtable [dslot] = override; + if (!MONO_CLASS_IS_INTERFACE (override->klass)) { + /* + * If override from an interface, then it is an override of a default interface method, + * don't override its slot. + */ + vtable [dslot]->slot = dslot; + } + + if (mono_security_core_clr_enabled ()) + mono_security_core_clr_check_override (klass, vtable [dslot], decl); + + return TRUE; +} + /* * LOCKING: this is supposed to be called with the loader lock held. */ @@ -4191,29 +4236,48 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o } TRACE_INTERFACE_VTABLE (print_vtable_full (klass, vtable, cur_slot, first_non_interface_slot, "AFTER INHERITING PARENT VTABLE", TRUE)); + + /* Process overrides from interface default methods */ + // FIXME: Ordering between interfaces + for (int ifindex = 0; ifindex < klass->interface_offsets_count; ifindex++) { + ic = klass->interfaces_packed [ifindex]; + + mono_class_setup_methods (ic); + if (mono_class_has_failure (ic)) + goto fail; + + MonoMethod **iface_overrides; + int iface_onum; + gboolean ok = mono_class_get_overrides_full (ic->image, ic->type_token, &iface_overrides, &iface_onum, mono_class_get_context (ic)); + if (ok) { + for (int i = 0; i < iface_onum; i++) { + MonoMethod *decl = iface_overrides [i*2]; + MonoMethod *override = iface_overrides [i*2 + 1]; + if (!apply_override (klass, vtable, decl, override)) + goto fail; + + if (!override_map) + override_map = g_hash_table_new (mono_aligned_addr_hash, NULL); + g_hash_table_insert (override_map, decl, override); + } + g_free (iface_overrides); + } + } + /* override interface methods */ for (i = 0; i < onum; i++) { MonoMethod *decl = overrides [i*2]; + MonoMethod *override = overrides [i*2 + 1]; if (MONO_CLASS_IS_INTERFACE (decl->klass)) { - int dslot; - dslot = mono_method_get_vtable_slot (decl); - if (dslot == -1) { - mono_class_set_type_load_failure (klass, ""); + if (!apply_override (klass, vtable, decl, override)) goto fail; - } - dslot += mono_class_interface_offset (klass, decl->klass); - vtable [dslot] = overrides [i*2 + 1]; - vtable [dslot]->slot = dslot; if (!override_map) override_map = g_hash_table_new (mono_aligned_addr_hash, NULL); - - g_hash_table_insert (override_map, overrides [i * 2], overrides [i * 2 + 1]); - - if (mono_security_core_clr_enabled ()) - mono_security_core_clr_check_override (klass, vtable [dslot], decl); + g_hash_table_insert (override_map, decl, override); } } + TRACE_INTERFACE_VTABLE (print_overrides (override_map, "AFTER OVERRIDING INTERFACE METHODS")); TRACE_INTERFACE_VTABLE (print_vtable_full (klass, vtable, cur_slot, first_non_interface_slot, "AFTER OVERRIDING INTERFACE METHODS", FALSE)); @@ -4319,6 +4383,13 @@ mono_class_setup_vtable_general (MonoClass *klass, MonoMethod **overrides, int o TRACE_INTERFACE_VTABLE ((cm != NULL) && printf ("\n")); } } + + if (vtable [im_slot] == NULL) { + if (!(im->flags & METHOD_ATTRIBUTE_ABSTRACT)) { + TRACE_INTERFACE_VTABLE (printf (" Using default iface method %s.\n", mono_method_full_name (im, 1))); + vtable [im_slot] = im; + } + } } else { g_assert (vtable [im_slot] == override_im); } @@ -4624,7 +4695,7 @@ mono_method_get_vtable_slot (MonoMethod *method) /** * mono_method_get_vtable_index: - * @method: a method + * \param method a method * * Returns the index into the runtime vtable to access the method or, * in the case of a virtual generic method, the virtual generic method @@ -4742,7 +4813,7 @@ generic_array_methods (MonoClass *klass) } static void -setup_generic_array_ifaces (MonoClass *klass, MonoClass *iface, MonoMethod **methods, int pos) +setup_generic_array_ifaces (MonoClass *klass, MonoClass *iface, MonoMethod **methods, int pos, GHashTable *cache) { MonoGenericContext tmp_context; int i; @@ -4754,11 +4825,16 @@ setup_generic_array_ifaces (MonoClass *klass, MonoClass *iface, MonoMethod **met for (i = 0; i < generic_array_method_num; i++) { MonoError error; MonoMethod *m = generic_array_method_info [i].array_method; - MonoMethod *inflated; + MonoMethod *inflated, *helper; inflated = mono_class_inflate_generic_method_checked (m, &tmp_context, &error); - g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/ - methods [pos++] = mono_marshal_get_generic_array_helper (klass, iface, generic_array_method_info [i].name, inflated); + mono_error_assert_ok (&error); + helper = g_hash_table_lookup (cache, inflated); + if (!helper) { + helper = mono_marshal_get_generic_array_helper (klass, generic_array_method_info [i].name, inflated); + g_hash_table_insert (cache, inflated, helper); + } + methods [pos ++] = helper; } } @@ -4778,19 +4854,20 @@ concat_two_strings_with_zero (MonoImage *image, const char *s1, const char *s2) /** * mono_class_init: - * @klass: the class to initialize + * \param klass the class to initialize * - * Compute the instance_size, class_size and other infos that cannot be - * computed at mono_class_get() time. Also compute vtable_size if possible. - * Returns TRUE on success or FALSE if there was a problem in loading - * the type (incorrect assemblies, missing assemblies, methods, etc). - * Initializes the following fields in @klass: - * - all the fields initialized by mono_class_init_sizes () + * Compute the \c instance_size, \c class_size and other infos that cannot be + * computed at \c mono_class_get time. Also compute vtable_size if possible. + * Initializes the following fields in \p klass: + * - all the fields initialized by \c mono_class_init_sizes * - has_cctor * - ghcimpl * - inited * * LOCKING: Acquires the loader lock. + * + * \returns TRUE on success or FALSE if there was a problem in loading + * the type (incorrect assemblies, missing assemblies, methods, etc). */ gboolean mono_class_init (MonoClass *klass) @@ -4817,7 +4894,7 @@ mono_class_init (MonoClass *klass) GSList *init_list = (GSList *)mono_native_tls_get_value (init_pending_tls_id); if (g_slist_find (init_list, klass)) { mono_class_set_type_load_failure (klass, "Recursive type definition detected"); - goto leave; + goto leave_no_init_pending; } init_list = g_slist_prepend (init_list, klass); mono_native_tls_set_value (init_pending_tls_id, init_list); @@ -4840,7 +4917,7 @@ mono_class_init (MonoClass *klass) goto leave; } - mono_stats.initialized_class_count++; + UnlockedIncrement (&mono_stats.initialized_class_count); if (mono_class_is_ginst (klass) && !mono_class_get_generic_class (klass)->is_dynamic) { MonoClass *gklass = mono_class_get_generic_class (klass)->container_class; @@ -4878,12 +4955,19 @@ mono_class_init (MonoClass *klass) ghcimpl = cached_info.ghcimpl; has_cctor = cached_info.has_cctor; } else if (klass->rank == 1 && klass->byval_arg.type == MONO_TYPE_SZARRAY) { - /* SZARRAY can have 2 vtable layouts, with and without the stelemref method. + /* SZARRAY can have 3 vtable layouts, with and without the stelemref method and enum element type * The first slot if for array with. */ - static int szarray_vtable_size[2] = { 0 }; + static int szarray_vtable_size[3] = { 0 }; - int slot = MONO_TYPE_IS_REFERENCE (&klass->element_class->byval_arg) ? 0 : 1; + int slot; + + if (MONO_TYPE_IS_REFERENCE (&klass->element_class->byval_arg)) + slot = 0; + else if (klass->element_class->enumtype) + slot = 1; + else + slot = 2; /* SZARRAY case */ if (!szarray_vtable_size [slot]) { @@ -4985,10 +5069,10 @@ mono_class_init (MonoClass *klass) return !mono_class_has_failure (klass); } - mono_stats.initialized_class_count++; + UnlockedIncrement (&mono_stats.initialized_class_count); if (mono_class_is_ginst (klass) && !mono_class_get_generic_class (klass)->is_dynamic) - mono_stats.generic_class_count++; + UnlockedIncrement (&mono_stats.generic_class_count); if (mono_class_is_ginst (klass) || image_is_dynamic (klass->image) || !klass->type_token || (has_cached_info && !cached_info.has_nested_classes)) klass->nested_classes_inited = TRUE; @@ -5016,10 +5100,12 @@ mono_class_init (MonoClass *klass) goto leave; - leave: +leave: + init_list = mono_native_tls_get_value (init_pending_tls_id); init_list = g_slist_remove (init_list, klass); mono_native_tls_set_value (init_pending_tls_id, init_list); +leave_no_init_pending: if (locked) mono_loader_unlock (); @@ -5411,6 +5497,12 @@ mono_class_setup_supertypes (MonoClass *klass) mono_loader_unlock (); } +static gboolean +discard_gclass_due_to_failure (MonoClass *gclass, void *user_data) +{ + return mono_class_get_generic_class (gclass)->container_class == user_data; +} + static gboolean fix_gclass_incomplete_instantiation (MonoClass *gclass, void *user_data) { @@ -5435,14 +5527,14 @@ mono_class_set_failure_and_error (MonoClass *klass, MonoError *error, const char /** * mono_class_create_from_typedef: - * @image: image where the token is valid - * @type_token: typedef token - * @error: used to return any error found while creating the type + * \param image: image where the token is valid + * \param type_token: typedef token + * \param error: used to return any error found while creating the type * * Create the MonoClass* representing the specified type token. - * @type_token must be a TypeDef token. + * \p type_token must be a TypeDef token. * - * FIXME: don't return NULL on failure, just the the caller figure it out. + * FIXME: don't return NULL on failure, just let the caller figure it out. */ static MonoClass * mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError *error) @@ -5459,7 +5551,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError guint32 field_last, method_last; guint32 nesting_tokeen; - mono_error_init (error); + error_init (error); if (mono_metadata_token_table (type_token) != MONO_TABLE_TYPEDEF || tidx > tt->rows) { mono_error_set_bad_image (error, image, "Invalid typedef token %x", type_token); @@ -5481,19 +5573,19 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError if (mono_metadata_has_generic_params (image, type_token)) { klass = mono_image_alloc0 (image, sizeof (MonoClassGtd)); klass->class_kind = MONO_CLASS_GTD; - classes_size += sizeof (MonoClassGtd); + UnlockedAdd (&classes_size, sizeof (MonoClassGtd)); ++class_gtd_count; } else { klass = mono_image_alloc0 (image, sizeof (MonoClassDef)); klass->class_kind = MONO_CLASS_DEF; - classes_size += sizeof (MonoClassDef); + UnlockedAdd (&classes_size, sizeof (MonoClassDef)); ++class_def_count; } klass->name = name; klass->name_space = nspace; - mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD); + MONO_PROFILER_RAISE (class_loading, (klass)); klass->image = image; klass->type_token = type_token; @@ -5510,6 +5602,9 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError generic_container->is_anonymous = FALSE; // Owner class is now known, container is no longer anonymous context = &generic_container->context; mono_class_set_generic_container (klass, generic_container); + MonoType *canonical_inst = &((MonoClassGtd*)klass)->canonical_inst; + canonical_inst->type = MONO_TYPE_GENERICINST; + canonical_inst->data.generic_class = mono_metadata_lookup_generic_class (klass, context->class_inst, FALSE); enable_gclass_recording (); } @@ -5564,7 +5659,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError /*FIXME implement a mono_class_set_failure_from_mono_error */ mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error)); mono_loader_unlock (); - mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED); + MONO_PROFILER_RAISE (class_failed, (klass)); return NULL; } } @@ -5621,7 +5716,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error)); mono_loader_unlock (); - mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED); + MONO_PROFILER_RAISE (class_failed, (klass)); return NULL; } @@ -5671,7 +5766,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError klass->cast_class = klass->element_class = mono_defaults.int32_class; mono_class_set_type_load_failure (klass, "%s", mono_error_get_message (error)); mono_loader_unlock (); - mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED); + MONO_PROFILER_RAISE (class_failed, (klass)); return NULL; } klass->cast_class = klass->element_class = mono_class_from_mono_type (enum_basetype); @@ -5685,7 +5780,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError if (mono_class_is_gtd (klass) && !mono_metadata_load_generic_param_constraints_checked (image, type_token, mono_class_get_generic_container (klass), error)) { mono_class_set_type_load_failure (klass, "Could not load generic parameter constrains due to %s", mono_error_get_message (error)); mono_loader_unlock (); - mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED); + MONO_PROFILER_RAISE (class_failed, (klass)); return NULL; } @@ -5699,14 +5794,17 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError mono_loader_unlock (); - mono_profiler_class_loaded (klass, MONO_PROFILE_OK); + MONO_PROFILER_RAISE (class_loaded, (klass)); return klass; parent_failure: + if (mono_class_is_gtd (klass)) + disable_gclass_recording (discard_gclass_due_to_failure, klass); + mono_class_setup_mono_type (klass); mono_loader_unlock (); - mono_profiler_class_loaded (klass, MONO_PROFILE_FAILED); + MONO_PROFILER_RAISE (class_failed, (klass)); return NULL; } @@ -5843,7 +5941,7 @@ mono_generic_class_get_class (MonoGenericClass *gclass) if (mono_class_is_nullable (klass)) klass->cast_class = klass->element_class = mono_class_get_nullable_param (klass); - mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD); + MONO_PROFILER_RAISE (class_loading, (klass)); mono_generic_class_setup_parent (klass, gklass); @@ -5853,7 +5951,7 @@ mono_generic_class_get_class (MonoGenericClass *gclass) mono_memory_barrier (); gclass->cached_class = klass; - mono_profiler_class_loaded (klass, MONO_PROFILE_OK); + MONO_PROFILER_RAISE (class_loaded, (klass)); ++class_ginst_count; inflated_classes_size += sizeof (MonoClassGenericInst); @@ -5919,8 +6017,8 @@ make_generic_param_class (MonoGenericParam *param, MonoGenericParamInfo *pinfo) klass = (MonoClass *)mono_image_alloc0 (image, sizeof (MonoClassGenericParam)); klass->class_kind = MONO_CLASS_GPARAM; - classes_size += sizeof (MonoClassGenericParam); - ++class_gparam_count; + UnlockedAdd (&classes_size, sizeof (MonoClassGenericParam)); + UnlockedIncrement (&class_gparam_count); if (pinfo) { CHECKED_METADATA_WRITE_PTR_EXEMPT ( klass->name , pinfo->name ); @@ -5939,7 +6037,7 @@ make_generic_param_class (MonoGenericParam *param, MonoGenericParamInfo *pinfo) CHECKED_METADATA_WRITE_PTR_EXEMPT ( klass->name_space , oklass ? oklass->name_space : "" ); } - mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD); + MONO_PROFILER_RAISE (class_loading, (klass)); // Count non-NULL items in pinfo->constraints count = 0; @@ -6155,18 +6253,18 @@ mono_class_from_generic_parameter_internal (MonoGenericParam *param) /* FIXME: Should this go inside 'make_generic_param_klass'? */ if (klass2) - mono_profiler_class_loaded (klass2, MONO_PROFILE_FAILED); // Alert profiler about botched class create + MONO_PROFILER_RAISE (class_failed, (klass2)); else - mono_profiler_class_loaded (klass, MONO_PROFILE_OK); + MONO_PROFILER_RAISE (class_loaded, (klass)); return klass; } /** * mono_class_from_generic_parameter: - * @param: Parameter to find/construct a class for. - * @arg2: Is ignored. - * @arg3: Is ignored. + * \param param Parameter to find/construct a class for. + * \param arg2 Is ignored. + * \param arg3 Is ignored. */ MonoClass * mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *arg2 G_GNUC_UNUSED, gboolean arg3 G_GNUC_UNUSED) @@ -6174,6 +6272,9 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *arg2 G_GN return mono_class_from_generic_parameter_internal (param); } +/** + * mono_ptr_class_get: + */ MonoClass * mono_ptr_class_get (MonoType *type) { @@ -6196,7 +6297,7 @@ mono_ptr_class_get (MonoType *type) result = (MonoClass *)mono_image_alloc0 (image, sizeof (MonoClassPointer)); - classes_size += sizeof (MonoClassPointer); + UnlockedAdd (&classes_size, sizeof (MonoClassPointer)); ++class_pointer_count; result->parent = NULL; /* no parent for PTR types */ @@ -6206,7 +6307,7 @@ mono_ptr_class_get (MonoType *type) result->class_kind = MONO_CLASS_POINTER; g_free (name); - mono_profiler_class_event (result, MONO_PROFILE_START_LOAD); + MONO_PROFILER_RAISE (class_loading, (result)); result->image = el_class->image; result->inited = TRUE; @@ -6226,7 +6327,7 @@ mono_ptr_class_get (MonoType *type) MonoClass *result2; if ((result2 = (MonoClass *)g_hash_table_lookup (image->ptr_cache, el_class))) { mono_image_unlock (image); - mono_profiler_class_loaded (result, MONO_PROFILE_FAILED); + MONO_PROFILER_RAISE (class_failed, (result)); return result2; } } else { @@ -6235,7 +6336,7 @@ mono_ptr_class_get (MonoType *type) g_hash_table_insert (image->ptr_cache, el_class, result); mono_image_unlock (image); - mono_profiler_class_loaded (result, MONO_PROFILE_OK); + MONO_PROFILER_RAISE (class_loaded, (result)); return result; } @@ -6284,25 +6385,24 @@ mono_fnptr_class_get (MonoMethodSignature *sig) return cached; } - mono_profiler_class_event (result, MONO_PROFILE_START_LOAD); + MONO_PROFILER_RAISE (class_loading, (result)); - classes_size += sizeof (MonoClassPointer); + UnlockedAdd (&classes_size, sizeof (MonoClassPointer)); ++class_pointer_count; g_hash_table_insert (ptr_hash, sig, result); mono_loader_unlock (); - mono_profiler_class_loaded (result, MONO_PROFILE_OK); + MONO_PROFILER_RAISE (class_loaded, (result)); return result; } /** * mono_class_from_mono_type: - * @type: describes the type to return - * - * This returns a MonoClass for the specified MonoType, the value is never NULL. + * \param type describes the type to return + * \returns a \c MonoClass for the specified \c MonoType, the value is never NULL. */ MonoClass * mono_class_from_mono_type (MonoType *type) @@ -6372,9 +6472,9 @@ mono_class_from_mono_type (MonoType *type) /** * mono_type_retrieve_from_typespec - * @image: context where the image is created - * @type_spec: typespec token - * @context: the generic context used to evaluate generic instantiations in + * \param image context where the image is created + * \param type_spec typespec token + * \param context the generic context used to evaluate generic instantiations in */ static MonoType * mono_type_retrieve_from_typespec (MonoImage *image, guint32 type_spec, MonoGenericContext *context, gboolean *did_inflate, MonoError *error) @@ -6403,9 +6503,9 @@ mono_type_retrieve_from_typespec (MonoImage *image, guint32 type_spec, MonoGener /** * mono_class_create_from_typespec - * @image: context where the image is created - * @type_spec: typespec token - * @context: the generic context used to evaluate generic instantiations in + * \param image context where the image is created + * \param type_spec typespec token + * \param context the generic context used to evaluate generic instantiations in */ static MonoClass * mono_class_create_from_typespec (MonoImage *image, guint32 type_spec, MonoGenericContext *context, MonoError *error) @@ -6422,12 +6522,11 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec, MonoGeneri /** * mono_bounded_array_class_get: - * @element_class: element class - * @rank: the dimension of the array class - * @bounded: whenever the array has non-zero bounds - * - * Returns: A class object describing the array with element type @element_type and - * dimension @rank. + * \param element_class element class + * \param rank the dimension of the array class + * \param bounded whenever the array has non-zero bounds + * \returns A class object describing the array with element type \p element_type and + * dimension \p rank. */ MonoClass * mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded) @@ -6504,11 +6603,11 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded) klass->parent = parent; klass->instance_size = mono_class_instance_size (klass->parent); - if (eclass->byval_arg.type == MONO_TYPE_TYPEDBYREF || eclass->byval_arg.type == MONO_TYPE_VOID) { + if (eclass->byval_arg.type == MONO_TYPE_TYPEDBYREF) { /*Arrays of those two types are invalid.*/ MonoError prepared_error; - mono_error_init (&prepared_error); - mono_error_set_invalid_program (&prepared_error, "Arrays of void or System.TypedReference types are invalid."); + error_init (&prepared_error); + mono_error_set_invalid_program (&prepared_error, "Arrays of System.TypedReference types are invalid."); mono_class_set_failure (klass, mono_error_box (&prepared_error, klass->image)); mono_error_cleanup (&prepared_error); } else if (eclass->enumtype && !mono_class_enum_basetype (eclass)) { @@ -6520,7 +6619,7 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded) /* element_size -1 is ok as this is not an instantitable type*/ klass->sizes.element_size = -1; } else - klass->sizes.element_size = mono_class_array_element_size (eclass); + klass->sizes.element_size = -1; mono_class_setup_supertypes (klass); @@ -6581,6 +6680,16 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded) klass->this_arg = klass->byval_arg; klass->this_arg.byref = 1; + if (rank > 32) { + MonoError prepared_error; + error_init (&prepared_error); + name = mono_type_get_full_name (klass); + mono_error_set_type_load_class (&prepared_error, klass, "%s has too many dimensions.", name); + mono_class_set_failure (klass, mono_error_box (&prepared_error, klass->image)); + mono_error_cleanup (&prepared_error); + g_free (name); + } + mono_loader_lock (); /* Check cache again */ @@ -6604,9 +6713,9 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded) return cached; } - mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD); + MONO_PROFILER_RAISE (class_loading, (klass)); - classes_size += sizeof (MonoClassArray); + UnlockedAdd (&classes_size, sizeof (MonoClassArray)); ++class_array_count; if (rank == 1 && !bounded) { @@ -6620,18 +6729,17 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded) mono_loader_unlock (); - mono_profiler_class_loaded (klass, MONO_PROFILE_OK); + MONO_PROFILER_RAISE (class_loaded, (klass)); return klass; } /** * mono_array_class_get: - * @element_class: element class - * @rank: the dimension of the array class - * - * Returns: A class object describing the array with element type @element_type and - * dimension @rank. + * \param element_class element class + * \param rank the dimension of the array class + * \returns A class object describing the array with element type \p element_type and + * dimension \p rank. */ MonoClass * mono_array_class_get (MonoClass *eclass, guint32 rank) @@ -6641,11 +6749,11 @@ mono_array_class_get (MonoClass *eclass, guint32 rank) /** * mono_class_instance_size: - * @klass: a class + * \param klass a class * * Use to get the size of a class in bytes. * - * Returns: The size of an object instance + * \returns The size of an object instance */ gint32 mono_class_instance_size (MonoClass *klass) @@ -6658,7 +6766,7 @@ mono_class_instance_size (MonoClass *klass) /** * mono_class_min_align: - * @klass: a class + * \param klass a class * * Use to get the computed minimum alignment requirements for the specified class. * @@ -6675,12 +6783,12 @@ mono_class_min_align (MonoClass *klass) /** * mono_class_value_size: - * @klass: a class + * \param klass a class * * This function is used for value types, and return the * space and the alignment to store that kind of value object. * - * Returns: the size of a value of kind @klass + * \returns the size of a value of kind \p klass */ gint32 mono_class_value_size (MonoClass *klass, guint32 *align) @@ -6702,9 +6810,9 @@ mono_class_value_size (MonoClass *klass, guint32 *align) /** * mono_class_data_size: - * @klass: a class + * \param klass a class * - * Returns: The size of the static class data + * \returns The size of the static class data */ gint32 mono_class_data_size (MonoClass *klass) @@ -6765,10 +6873,10 @@ mono_class_get_field_idx (MonoClass *klass, int idx) /** * mono_class_get_field: - * @class: the class to lookup the field. - * @field_token: the field token + * \param class the class to lookup the field. + * \param field_token the field token * - * Returns: A MonoClassField representing the type and offset of + * \returns A \c MonoClassField representing the type and offset of * the field, or a NULL value if the field does not belong to this * class. */ @@ -6784,12 +6892,12 @@ mono_class_get_field (MonoClass *klass, guint32 field_token) /** * mono_class_get_field_from_name: - * @klass: the class to lookup the field. - * @name: the field name + * \param klass the class to lookup the field. + * \param name the field name * - * Search the class @klass and it's parents for a field with the name @name. + * Search the class \p klass and its parents for a field with the name \p name. * - * Returns: The MonoClassField pointer of the named field or NULL + * \returns The \c MonoClassField pointer of the named field or NULL */ MonoClassField * mono_class_get_field_from_name (MonoClass *klass, const char *name) @@ -6799,16 +6907,16 @@ mono_class_get_field_from_name (MonoClass *klass, const char *name) /** * mono_class_get_field_from_name_full: - * @klass: the class to lookup the field. - * @name: the field name - * @type: the type of the fields. This optional. + * \param klass the class to lookup the field. + * \param name the field name + * \param type the type of the fields. This optional. * - * Search the class @klass and it's parents for a field with the name @name and type @type. + * Search the class \p klass and it's parents for a field with the name \p name and type \p type. * - * If @klass is an inflated generic type, the type comparison is done with the equivalent field + * If \p klass is an inflated generic type, the type comparison is done with the equivalent field * of its generic type definition. * - * Returns: The MonoClassField pointer of the named field or NULL + * \returns The MonoClassField pointer of the named field or NULL */ MonoClassField * mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoType *type) @@ -6841,12 +6949,12 @@ mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoTyp /** * mono_class_get_field_token: - * @field: the field we need the token of + * \param field the field we need the token of * * Get the token of a field. Note that the tokesn is only valid for the image * the field was loaded from. Don't use this function for fields in dynamic types. * - * Returns: The token representing the field in the image it was loaded from. + * \returns The token representing the field in the image it was loaded from. */ guint32 mono_class_get_field_token (MonoClassField *field) @@ -6976,6 +7084,9 @@ mono_class_get_property_default_value (MonoProperty *property, MonoTypeEnum *def return (const char *)mono_metadata_blob_heap (klass->image, constant_cols [MONO_CONSTANT_VALUE]); } +/** + * mono_class_get_event_token: + */ guint32 mono_class_get_event_token (MonoEvent *event) { @@ -6999,12 +7110,12 @@ mono_class_get_event_token (MonoEvent *event) /** * mono_class_get_property_from_name: - * @klass: a class - * @name: name of the property to lookup in the specified class + * \param klass a class + * \param name name of the property to lookup in the specified class * * Use this method to lookup a property in a class - * Returns: the MonoProperty with the given name, or NULL if the property - * does not exist on the @klass. + * \returns the \c MonoProperty with the given name, or NULL if the property + * does not exist on the \p klass. */ MonoProperty* mono_class_get_property_from_name (MonoClass *klass, const char *name) @@ -7023,9 +7134,9 @@ mono_class_get_property_from_name (MonoClass *klass, const char *name) /** * mono_class_get_property_token: - * @prop: MonoProperty to query + * \param prop MonoProperty to query * - * Returns: The ECMA token for the specified property. + * \returns The ECMA token for the specified property. */ guint32 mono_class_get_property_token (MonoProperty *prop) @@ -7049,6 +7160,9 @@ mono_class_get_property_token (MonoProperty *prop) return 0; } +/** + * mono_class_name_from_token: + */ char * mono_class_name_from_token (MonoImage *image, guint32 type_token) { @@ -7166,12 +7280,11 @@ mono_assembly_name_from_token (MonoImage *image, guint32 type_token) /** * mono_class_get_full: - * @image: the image where the class resides - * @type_token: the token for the class - * @context: the generic context used to evaluate generic instantiations in - * @deprecated: Functions that expose MonoGenericContext are going away in mono 4.0 - * - * Returns: The MonoClass that represents @type_token in @image + * \param image the image where the class resides + * \param type_token the token for the class + * \param context the generic context used to evaluate generic instantiations in + * \deprecated Functions that expose \c MonoGenericContext are going away in mono 4.0 + * \returns The \c MonoClass that represents \p type_token in \p image */ MonoClass * mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context) @@ -7193,7 +7306,7 @@ mono_class_get_and_inflate_typespec_checked (MonoImage *image, guint32 type_toke { MonoClass *klass; - mono_error_init (error); + error_init (error); klass = mono_class_get_checked (image, type_token, error); if (klass && context && mono_metadata_token_table (type_token) == MONO_TABLE_TYPESPEC) @@ -7203,18 +7316,18 @@ mono_class_get_and_inflate_typespec_checked (MonoImage *image, guint32 type_toke } /** * mono_class_get_checked: - * @image: the image where the class resides - * @type_token: the token for the class - * @error: error object to return any error + * \param image the image where the class resides + * \param type_token the token for the class + * \param error error object to return any error * - * Returns: The MonoClass that represents @type_token in @image, or NULL on error. + * \returns The MonoClass that represents \p type_token in \p image, or NULL on error. */ MonoClass * mono_class_get_checked (MonoImage *image, guint32 type_token, MonoError *error) { MonoClass *klass = NULL; - mono_error_init (error); + error_init (error); if (image_is_dynamic (image)) { int table = mono_metadata_token_table (type_token); @@ -7246,7 +7359,7 @@ done: if (!klass && mono_error_ok (error)) { char *name = mono_class_name_from_token (image, type_token); char *assembly = mono_assembly_name_from_token (image, type_token); - mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x", type_token); + mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x (class/assembly %s, %s)", type_token, name, assembly); } return klass; @@ -7255,14 +7368,14 @@ done: /** * mono_type_get_checked: - * @image: the image where the type resides - * @type_token: the token for the type - * @context: the generic context used to evaluate generic instantiations in - * @error: Error handling context + * \param image the image where the type resides + * \param type_token the token for the type + * \param context the generic context used to evaluate generic instantiations in + * \param error Error handling context * * This functions exists to fullfill the fact that sometimes it's desirable to have access to the * - * Returns: The MonoType that represents @type_token in @image + * \returns The MonoType that represents \p type_token in \p image */ MonoType * mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error) @@ -7270,7 +7383,7 @@ mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext MonoType *type = NULL; gboolean inflated = FALSE; - mono_error_init (error); + error_init (error); //FIXME: this will not fix the very issue for which mono_type_get_full exists -but how to do it then? if (image_is_dynamic (image)) { @@ -7315,10 +7428,9 @@ mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext /** * mono_class_get: - * @image: image where the class token will be looked up. - * @type_token: a type token from the image - * - * Returns the MonoClass with the given @type_token on the @image + * \param image image where the class token will be looked up. + * \param type_token a type token from the image + * \returns the \c MonoClass with the given \p type_token on the \p image */ MonoClass * mono_class_get (MonoImage *image, guint32 type_token) @@ -7428,6 +7540,9 @@ mono_image_init_name_cache (MonoImage *image) } /*FIXME Only dynamic assemblies should allow this operation.*/ +/** + * mono_image_add_to_name_cache: + */ void mono_image_add_to_name_cache (MonoImage *image, const char *nspace, const char *name, guint32 index) @@ -7470,13 +7585,13 @@ find_nocase (gpointer key, gpointer value, gpointer user_data) /** * mono_class_from_name_case: - * @image: The MonoImage where the type is looked up in - * @name_space: the type namespace - * @name: the type short name. - * @deprecated: use the mono_class_from_name_case_checked variant instead. + * \param image The MonoImage where the type is looked up in + * \param name_space the type namespace + * \param name the type short name. + * \deprecated use the mono_class_from_name_case_checked variant instead. * - * Obtains a MonoClass with a given namespace and a given name which - * is located in the given MonoImage. The namespace and name + * Obtains a \c MonoClass with a given namespace and a given name which + * is located in the given \c MonoImage. The namespace and name * lookups are case insensitive. */ MonoClass * @@ -7490,18 +7605,18 @@ mono_class_from_name_case (MonoImage *image, const char* name_space, const char } /** - * mono_class_from_name_case: - * @image: The MonoImage where the type is looked up in - * @name_space: the type namespace - * @name: the type short name. - * @error: if + * mono_class_from_name_case_checked: + * \param image The MonoImage where the type is looked up in + * \param name_space the type namespace + * \param name the type short name. + * \param error if * * Obtains a MonoClass with a given namespace and a given name which * is located in the given MonoImage. The namespace and name * lookups are case insensitive. * - * Returns: The MonoClass if the given namespace and name were found, or NULL if it - * was not found. The @error object will contain information about the problem + * \returns The MonoClass if the given namespace and name were found, or NULL if it + * was not found. The \p error object will contain information about the problem * in that case. */ MonoClass * @@ -7513,7 +7628,7 @@ mono_class_from_name_case_checked (MonoImage *image, const char *name_space, con const char *nspace; guint32 i, visib; - mono_error_init (error); + error_init (error); if (image_is_dynamic (image)) { guint32 token = 0; @@ -7595,7 +7710,7 @@ search_modules (MonoImage *image, const char *name_space, const char *name, Mono MonoClass *klass; int i; - mono_error_init (error); + error_init (error); /* * The EXPORTEDTYPES table only contains public types, so have to search the @@ -7631,7 +7746,7 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons char *nested; char buf [1024]; - mono_error_init (error); + error_init (error); // Checking visited images avoids stack overflows when cyclic references exist. if (g_hash_table_lookup (visited_images, image)) @@ -7740,9 +7855,9 @@ mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, cons /** * mono_class_from_name_checked: - * @image: The MonoImage where the type is looked up in - * @name_space: the type namespace - * @name: the type short name. + * \param image The MonoImage where the type is looked up in + * \param name_space the type namespace + * \param name the type short name. * * Obtains a MonoClass with a given namespace and a given name which * is located in the given MonoImage. @@ -7767,16 +7882,16 @@ mono_class_from_name_checked (MonoImage *image, const char* name_space, const ch /** * mono_class_from_name: - * @image: The MonoImage where the type is looked up in - * @name_space: the type namespace - * @name: the type short name. + * \param image The \c MonoImage where the type is looked up in + * \param name_space the type namespace + * \param name the type short name. * - * Obtains a MonoClass with a given namespace and a given name which - * is located in the given MonoImage. + * Obtains a \c MonoClass with a given namespace and a given name which + * is located in the given \c MonoImage. * * To reference nested classes, use the "/" character as a separator. - * For example use "Foo/Bar" to reference the class Bar that is nested - * inside Foo, like this: "class Foo { class Bar {} }". + * For example use \c "Foo/Bar" to reference the class \c Bar that is nested + * inside \c Foo, like this: "class Foo { class Bar {} }". */ MonoClass * mono_class_from_name (MonoImage *image, const char* name_space, const char *name) @@ -7792,9 +7907,9 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name /** * mono_class_load_from_name: - * @image: The MonoImage where the type is looked up in - * @name_space: the type namespace - * @name: the type short name. + * \param image The MonoImage where the type is looked up in + * \param name_space the type namespace + * \param name the type short name. * * This function works exactly like mono_class_from_name but it will abort if the class is not found. * This function should be used by the runtime for critical types to which there's no way to recover but crash @@ -7816,9 +7931,9 @@ mono_class_load_from_name (MonoImage *image, const char* name_space, const char /** * mono_class_try_load_from_name: - * @image: The MonoImage where the type is looked up in - * @name_space: the type namespace - * @name: the type short name. + * \param image The MonoImage where the type is looked up in + * \param name_space the type namespace + * \param name the type short name. * * This function tries to load a type, returning the class was found or NULL otherwise. * This function should be used by the runtime when probing for optional types, those that could have being linked out. @@ -7842,21 +7957,21 @@ mono_class_try_load_from_name (MonoImage *image, const char* name_space, const c /** * mono_class_is_subclass_of: - * @klass: class to probe if it is a subclass of another one - * @klassc: the class we suspect is the base class - * @check_interfaces: whether we should perform interface checks + * \param klass class to probe if it is a subclass of another one + * \param klassc the class we suspect is the base class + * \param check_interfaces whether we should perform interface checks * - * This method determines whether @klass is a subclass of @klassc. + * This method determines whether \p klass is a subclass of \p klassc. * - * If the @check_interfaces flag is set, then if @klassc is an interface - * this method return TRUE if the @klass implements the interface or - * if @klass is an interface, if one of its base classes is @klass. + * If the \p check_interfaces flag is set, then if \p klassc is an interface + * this method return TRUE if the \p klass implements the interface or + * if \p klass is an interface, if one of its base classes is \p klass. * - * If @check_interfaces is false then, then if @klass is not an interface - * then it returns TRUE if the @klass is a subclass of @klassc. + * If \p check_interfaces is false, then if \p klass is not an interface, + * it returns TRUE if the \p klass is a subclass of \p klassc. * - * if @klass is an interface and @klassc is System.Object, then this function - * return true. + * if \p klass is an interface and \p klassc is \c System.Object, then this function + * returns TRUE. * */ gboolean @@ -8092,11 +8207,11 @@ mono_gparam_is_assignable_from (MonoClass *target, MonoClass *candidate) /** * mono_class_is_assignable_from: - * @klass: the class to be assigned to - * @oklass: the source class + * \param klass the class to be assigned to + * \param oklass the source class * - * Returns: TRUE if an instance of object oklass can be assigned to an - * instance of object @klass + * \returns TRUE if an instance of class \p oklass can be assigned to an + * instance of class \p klass */ gboolean mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass) @@ -8118,22 +8233,31 @@ mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass) return mono_gparam_is_assignable_from (klass, oklass); } - if (MONO_CLASS_IS_INTERFACE (klass)) { - if ((oklass->byval_arg.type == MONO_TYPE_VAR) || (oklass->byval_arg.type == MONO_TYPE_MVAR)) { - MonoGenericParam *gparam = oklass->byval_arg.data.generic_param; - MonoClass **constraints = mono_generic_container_get_param_info (gparam->owner, gparam->num)->constraints; - int i; + /* This can happen if oklass is a tyvar that has a constraint which is another tyvar which in turn + * has a constraint which is a class type: + * + * class Foo { } + * class G where T1 : T2 where T2 : Foo { } + * + * In this case, Foo is assignable from T1. + */ + if ((oklass->byval_arg.type == MONO_TYPE_VAR) || (oklass->byval_arg.type == MONO_TYPE_MVAR)) { + MonoGenericParam *gparam = oklass->byval_arg.data.generic_param; + MonoClass **constraints = mono_generic_container_get_param_info (gparam->owner, gparam->num)->constraints; + int i; - if (constraints) { - for (i = 0; constraints [i]; ++i) { - if (mono_class_is_assignable_from (klass, constraints [i])) - return TRUE; - } + if (constraints) { + for (i = 0; constraints [i]; ++i) { + if (mono_class_is_assignable_from (klass, constraints [i])) + return TRUE; } - - return FALSE; } + return mono_class_has_parent (oklass, klass); + } + + if (MONO_CLASS_IS_INTERFACE (klass)) { + /* interface_offsets might not be set for dynamic classes */ if (mono_class_get_ref_info_handle (oklass) && !oklass->interface_bitmap) { /* @@ -8390,9 +8514,9 @@ mono_class_is_assignable_from_slow (MonoClass *target, MonoClass *candidate) /** * mono_class_get_cctor: - * @klass: A MonoClass pointer + * \param klass A MonoClass pointer * - * Returns: The static constructor of @klass if it exists, NULL otherwise. + * \returns The static constructor of \p klass if it exists, NULL otherwise. */ MonoMethod* mono_class_get_cctor (MonoClass *klass) @@ -8428,9 +8552,9 @@ mono_class_get_cctor (MonoClass *klass) /** * mono_class_get_finalizer: - * @klass: The MonoClass pointer + * \param klass: The MonoClass pointer * - * Returns: The finalizer method of @klass if it exists, NULL otherwise. + * \returns The finalizer method of \p klass if it exists, NULL otherwise. */ MonoMethod* mono_class_get_finalizer (MonoClass *klass) @@ -8456,8 +8580,8 @@ mono_class_get_finalizer (MonoClass *klass) /** * mono_class_needs_cctor_run: - * @klass: the MonoClass pointer - * @caller: a MonoMethod describing the caller + * \param klass the MonoClass pointer + * \param caller a MonoMethod describing the caller * * Determines whenever the class has a static constructor and whenever it * needs to be called when executing CALLER. @@ -8476,10 +8600,9 @@ mono_class_needs_cctor_run (MonoClass *klass, MonoMethod *caller) /** * mono_class_array_element_size: - * @klass: + * \param klass * - * Returns: The number of bytes an element of type @klass - * uses when stored into an array. + * \returns The number of bytes an element of type \p klass uses when stored into an array. */ gint32 mono_class_array_element_size (MonoClass *klass) @@ -8540,17 +8663,25 @@ handle_enum: /** * mono_array_element_size: - * @ac: pointer to a #MonoArrayClass + * \param ac pointer to a \c MonoArrayClass * - * Returns: The size of single array element. + * \returns The size of single array element. + * + * LOCKING: Acquires the loader lock. */ gint32 mono_array_element_size (MonoClass *ac) { g_assert (ac->rank); + if (G_UNLIKELY (!ac->size_inited)) { + mono_class_setup_fields (ac); + } return ac->sizes.element_size; } +/** + * mono_ldtoken: + */ gpointer mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class, MonoGenericContext *context) @@ -8565,7 +8696,7 @@ gpointer mono_ldtoken_checked (MonoImage *image, guint32 token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error) { - mono_error_init (error); + error_init (error); if (image_is_dynamic (image)) { MonoClass *tmp_handle_class; @@ -8655,7 +8786,7 @@ gpointer mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context, MonoError *error) { MonoClass *handle_class; - mono_error_init (error); + error_init (error); return mono_reflection_lookup_dynamic_token (image, token, TRUE, &handle_class, context, error); } @@ -8691,9 +8822,9 @@ mono_install_get_class_from_name (MonoGetClassFromName func) /** * mono_class_get_image: * - * Use this method to get the `MonoImage*` where this class came from. + * Use this method to get the \c MonoImage* where this class came from. * - * Returns: The image where this class is defined. + * \returns The image where this class is defined. */ MonoImage* mono_class_get_image (MonoClass *klass) @@ -8703,11 +8834,11 @@ mono_class_get_image (MonoClass *klass) /** * mono_class_get_element_class: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * * Use this function to get the element class of an array. * - * Returns: The element class of an array. + * \returns The element class of an array. */ MonoClass* mono_class_get_element_class (MonoClass *klass) @@ -8717,12 +8848,12 @@ mono_class_get_element_class (MonoClass *klass) /** * mono_class_is_valuetype: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Use this method to determine if the provided `MonoClass*` represents a value type, + * Use this method to determine if the provided \c MonoClass* represents a value type, * or a reference type. * - * Returns: TRUE if the MonoClass represents a ValueType, FALSE if it represents a reference type. + * \returns TRUE if the \c MonoClass represents a \c ValueType, FALSE if it represents a reference type. */ gboolean mono_class_is_valuetype (MonoClass *klass) @@ -8732,11 +8863,11 @@ mono_class_is_valuetype (MonoClass *klass) /** * mono_class_is_enum: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Use this function to determine if the provided `MonoClass*` represents an enumeration. + * Use this function to determine if the provided \c MonoClass* represents an enumeration. * - * Returns: TRUE if the MonoClass represents an enumeration. + * \returns TRUE if the \c MonoClass represents an enumeration. */ gboolean mono_class_is_enum (MonoClass *klass) @@ -8746,11 +8877,11 @@ mono_class_is_enum (MonoClass *klass) /** * mono_class_enum_basetype: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * * Use this function to get the underlying type for an enumeration value. * - * Returns: The underlying type representation for an enumeration. + * \returns The underlying type representation for an enumeration. */ MonoType* mono_class_enum_basetype (MonoClass *klass) @@ -8764,9 +8895,9 @@ mono_class_enum_basetype (MonoClass *klass) /** * mono_class_get_parent - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Returns: The parent class for this class. + * \returns The parent class for this class. */ MonoClass* mono_class_get_parent (MonoClass *klass) @@ -8776,13 +8907,13 @@ mono_class_get_parent (MonoClass *klass) /** * mono_class_get_nesting_type: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Use this function to obtain the class that the provided `MonoClass*` is nested on. + * Use this function to obtain the class that the provided \c MonoClass* is nested on. * * If the return is NULL, this indicates that this class is not nested. * - * Returns: The container type where this type is nested or NULL if this type is not a nested type. + * \returns The container type where this type is nested or NULL if this type is not a nested type. */ MonoClass* mono_class_get_nesting_type (MonoClass *klass) @@ -8792,9 +8923,9 @@ mono_class_get_nesting_type (MonoClass *klass) /** * mono_class_get_rank: - * @klass: the MonoClass to act on + * \param klass the MonoClass to act on * - * Returns: The rank for the array (the number of dimensions). + * \returns The rank for the array (the number of dimensions). */ int mono_class_get_rank (MonoClass *klass) @@ -8804,9 +8935,9 @@ mono_class_get_rank (MonoClass *klass) /** * mono_class_get_name - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Returns: The name of the class. + * \returns The name of the class. */ const char* mono_class_get_name (MonoClass *klass) @@ -8816,9 +8947,9 @@ mono_class_get_name (MonoClass *klass) /** * mono_class_get_namespace: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Returns: The namespace of the class. + * \returns The namespace of the class. */ const char* mono_class_get_namespace (MonoClass *klass) @@ -8828,11 +8959,11 @@ mono_class_get_namespace (MonoClass *klass) /** * mono_class_get_type: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * This method returns the internal Type representation for the class. + * This method returns the internal \c MonoType representation for the class. * - * Returns: The MonoType from the class. + * \returns The \c MonoType from the class. */ MonoType* mono_class_get_type (MonoClass *klass) @@ -8842,11 +8973,11 @@ mono_class_get_type (MonoClass *klass) /** * mono_class_get_type_token: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * * This method returns type token for the class. * - * Returns: The type token for the class. + * \returns The type token for the class. */ guint32 mono_class_get_type_token (MonoClass *klass) @@ -8856,7 +8987,7 @@ mono_class_get_type_token (MonoClass *klass) /** * mono_class_get_byref_type: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * * */ @@ -8868,9 +8999,9 @@ mono_class_get_byref_type (MonoClass *klass) /** * mono_class_num_fields: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Returns: The number of static and instance fields in the class. + * \returns The number of static and instance fields in the class. */ int mono_class_num_fields (MonoClass *klass) @@ -8880,9 +9011,9 @@ mono_class_num_fields (MonoClass *klass) /** * mono_class_num_methods: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Returns: The number of methods in the class. + * \returns The number of methods in the class. */ int mono_class_num_methods (MonoClass *klass) @@ -8892,9 +9023,9 @@ mono_class_num_methods (MonoClass *klass) /** * mono_class_num_properties - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Returns: The number of properties in the class. + * \returns The number of properties in the class. */ int mono_class_num_properties (MonoClass *klass) @@ -8906,9 +9037,9 @@ mono_class_num_properties (MonoClass *klass) /** * mono_class_num_events: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Returns: The number of events in the class. + * \returns The number of events in the class. */ int mono_class_num_events (MonoClass *klass) @@ -8920,15 +9051,15 @@ mono_class_num_events (MonoClass *klass) /** * mono_class_get_fields: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * * This routine is an iterator routine for retrieving the fields in a class. * - * You must pass a gpointer that points to zero and is treated as an opaque handle to + * You must pass a \c gpointer that points to zero and is treated as an opaque handle to * iterate over all of the elements. When no more values are * available, the return value is NULL. * - * Returns: a @MonoClassField* on each iteration, or NULL when no more fields are available. + * \returns a \c MonoClassField* on each iteration, or NULL when no more fields are available. */ MonoClassField* mono_class_get_fields (MonoClass* klass, gpointer *iter) @@ -8959,16 +9090,16 @@ mono_class_get_fields (MonoClass* klass, gpointer *iter) } /** - * mono_class_get_methods - * @klass: the MonoClass to act on + * mono_class_get_methods: + * \param klass the \c MonoClass to act on * * This routine is an iterator routine for retrieving the fields in a class. * - * You must pass a gpointer that points to zero and is treated as an opaque handle to + * You must pass a \c gpointer that points to zero and is treated as an opaque handle to * iterate over all of the elements. When no more values are * available, the return value is NULL. * - * Returns: a MonoMethod on each iteration or NULL when no more methods are available. + * \returns a \c MonoMethod on each iteration or NULL when no more methods are available. */ MonoMethod* mono_class_get_methods (MonoClass* klass, gpointer *iter) @@ -9013,10 +9144,25 @@ mono_class_get_methods (MonoClass* klass, gpointer *iter) static MonoMethod* mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter) { - MonoMethod** method; + gboolean static_iter = FALSE; + if (!iter) return NULL; - if (klass->methods || !MONO_CLASS_HAS_STATIC_METADATA (klass)) { + + /* + * If the lowest bit of the iterator is 1, this is an iterator for static metadata, + * and the upper bits contain an index. Otherwise, the iterator is a pointer into + * klass->methods. + */ + if ((gsize)(*iter) & 1) + static_iter = TRUE; + /* Use the static metadata only if klass->methods is not yet initialized */ + if (!static_iter && !(klass->methods || !MONO_CLASS_HAS_STATIC_METADATA (klass))) + static_iter = TRUE; + + if (!static_iter) { + MonoMethod** methodptr; + if (!*iter) { mono_class_setup_methods (klass); /* @@ -9026,20 +9172,22 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter) if (!klass->methods) return NULL; /* start from the first */ - method = &klass->methods [0]; + methodptr = &klass->methods [0]; } else { - method = (MonoMethod **)*iter; - method++; + methodptr = (MonoMethod **)*iter; + methodptr++; } + if (*iter) + g_assert ((guint64)(*iter) > 0x100); int mcount = mono_class_get_method_count (klass); - while (method < &klass->methods [mcount]) { - if (*method && ((*method)->flags & METHOD_ATTRIBUTE_VIRTUAL)) + while (methodptr < &klass->methods [mcount]) { + if (*methodptr && ((*methodptr)->flags & METHOD_ATTRIBUTE_VIRTUAL)) break; - method ++; + methodptr ++; } - if (method < &klass->methods [mcount]) { - *iter = method; - return *method; + if (methodptr < &klass->methods [mcount]) { + *iter = methodptr; + return *methodptr; } else { return NULL; } @@ -9051,7 +9199,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter) if (!*iter) { start_index = 0; } else { - start_index = GPOINTER_TO_UINT (*iter); + start_index = GPOINTER_TO_UINT (*iter) >> 1; } int first_idx = mono_class_get_first_method_idx (klass); @@ -9072,7 +9220,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter) mono_error_cleanup (&error); /* FIXME don't swallow the error */ /* Add 1 here so the if (*iter) check fails */ - *iter = GUINT_TO_POINTER (i + 1); + *iter = GUINT_TO_POINTER (((i + 1) << 1) | 1); return res; } else { return NULL; @@ -9082,7 +9230,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter) /** * mono_class_get_properties: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * * This routine is an iterator routine for retrieving the properties in a class. * @@ -9090,7 +9238,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter) * iterate over all of the elements. When no more values are * available, the return value is NULL. * - * Returns: a @MonoProperty* on each invocation, or NULL when no more are available. + * Returns: a \c MonoProperty* on each invocation, or NULL when no more are available. */ MonoProperty* mono_class_get_properties (MonoClass* klass, gpointer *iter) @@ -9122,15 +9270,15 @@ mono_class_get_properties (MonoClass* klass, gpointer *iter) /** * mono_class_get_events: - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * * This routine is an iterator routine for retrieving the properties in a class. * - * You must pass a gpointer that points to zero and is treated as an opaque handle to + * You must pass a \c gpointer that points to zero and is treated as an opaque handle to * iterate over all of the elements. When no more values are * available, the return value is NULL. * - * Returns: a @MonoEvent* on each invocation, or NULL when no more are available. + * \returns a \c MonoEvent* on each invocation, or NULL when no more are available. */ MonoEvent* mono_class_get_events (MonoClass* klass, gpointer *iter) @@ -9162,15 +9310,15 @@ mono_class_get_events (MonoClass* klass, gpointer *iter) /** * mono_class_get_interfaces - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * * This routine is an iterator routine for retrieving the interfaces implemented by this class. * - * You must pass a gpointer that points to zero and is treated as an opaque handle to + * You must pass a \c gpointer that points to zero and is treated as an opaque handle to * iterate over all of the elements. When no more values are * available, the return value is NULL. * - * Returns: a @Monoclass* on each invocation, or NULL when no more are available. + * \returns a \c MonoClass* on each invocation, or NULL when no more are available. */ MonoClass* mono_class_get_interfaces (MonoClass* klass, gpointer *iter) @@ -9260,16 +9408,16 @@ setup_nested_types (MonoClass *klass) /** * mono_class_get_nested_types - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * * This routine is an iterator routine for retrieving the nested types of a class. - * This works only if @klass is non-generic, or a generic type definition. + * This works only if \p klass is non-generic, or a generic type definition. * - * You must pass a gpointer that points to zero and is treated as an opaque handle to + * You must pass a \c gpointer that points to zero and is treated as an opaque handle to * iterate over all of the elements. When no more values are * available, the return value is NULL. * - * Returns: a @Monoclass* on each invocation, or NULL when no more are available. + * \returns a \c Monoclass* on each invocation, or NULL when no more are available. */ MonoClass* mono_class_get_nested_types (MonoClass* klass, gpointer *iter) @@ -9304,9 +9452,9 @@ mono_class_get_nested_types (MonoClass* klass, gpointer *iter) /** * mono_class_is_delegate - * @klass: the MonoClass to act on + * \param klass the \c MonoClass to act on * - * Returns: TRUE if the MonoClass represents a System.Delegate. + * \returns TRUE if the \c MonoClass represents a \c System.Delegate. */ mono_bool mono_class_is_delegate (MonoClass *klass) @@ -9316,10 +9464,10 @@ mono_class_is_delegate (MonoClass *klass) /** * mono_class_implements_interface - * @klass: The MonoClass to act on - * @interface: The interface to check if @klass implements. + * \param klass The MonoClass to act on + * \param interface The interface to check if \p klass implements. * - * Returns: TRUE if @klass implements @interface. + * \returns TRUE if \p klass implements \p interface. */ mono_bool mono_class_implements_interface (MonoClass* klass, MonoClass* iface) @@ -9329,9 +9477,9 @@ mono_class_implements_interface (MonoClass* klass, MonoClass* iface) /** * mono_field_get_name: - * @field: the MonoClassField to act on + * \param field the \c MonoClassField to act on * - * Returns: The name of the field. + * \returns The name of the field. */ const char* mono_field_get_name (MonoClassField *field) @@ -9341,9 +9489,8 @@ mono_field_get_name (MonoClassField *field) /** * mono_field_get_type: - * @field: the MonoClassField to act on - * - * Returns: MonoType of the field. + * \param field the \c MonoClassField to act on + * \returns \c MonoType of the field. */ MonoType* mono_field_get_type (MonoClassField *field) @@ -9360,15 +9507,15 @@ mono_field_get_type (MonoClassField *field) /** * mono_field_get_type_checked: - * @field: the MonoClassField to act on - * @error: used to return any erro found while retrieving @field type + * \param field the \c MonoClassField to act on + * \param error used to return any error found while retrieving \p field type * - * Returns: MonoType of the field. + * \returns \c MonoType of the field. */ MonoType* mono_field_get_type_checked (MonoClassField *field, MonoError *error) { - mono_error_init (error); + error_init (error); if (!field->type) mono_field_resolve_type (field, error); return field->type; @@ -9376,9 +9523,9 @@ mono_field_get_type_checked (MonoClassField *field, MonoError *error) /** * mono_field_get_parent: - * @field: the MonoClassField to act on + * \param field the \c MonoClassField to act on * - * Returns: MonoClass where the field was defined. + * \returns \c MonoClass where the field was defined. */ MonoClass* mono_field_get_parent (MonoClassField *field) @@ -9388,12 +9535,12 @@ mono_field_get_parent (MonoClassField *field) /** * mono_field_get_flags; - * @field: the MonoClassField to act on + * \param field the \c MonoClassField to act on * * The metadata flags for a field are encoded using the - * FIELD_ATTRIBUTE_* constants. See the tabledefs.h file for details. + * \c FIELD_ATTRIBUTE_* constants. See the \c tabledefs.h file for details. * - * Returns: The flags for the field. + * \returns The flags for the field. */ guint32 mono_field_get_flags (MonoClassField *field) @@ -9405,9 +9552,9 @@ mono_field_get_flags (MonoClassField *field) /** * mono_field_get_offset: - * @field: the MonoClassField to act on + * \param field the \c MonoClassField to act on * - * Returns: The field offset. + * \returns The field offset. */ guint32 mono_field_get_offset (MonoClassField *field) @@ -9447,9 +9594,9 @@ mono_field_get_rva (MonoClassField *field) /** * mono_field_get_data: - * @field: the MonoClassField to act on + * \param field the \c MonoClassField to act on * - * Returns: A pointer to the metadata constant value or to the field + * \returns A pointer to the metadata constant value or to the field * data if it has an RVA flag. */ const char * @@ -9468,9 +9615,8 @@ mono_field_get_data (MonoClassField *field) /** * mono_property_get_name: - * @prop: the MonoProperty to act on - * - * Returns: The name of the property + * \param prop the \c MonoProperty to act on + * \returns The name of the property */ const char* mono_property_get_name (MonoProperty *prop) @@ -9480,9 +9626,8 @@ mono_property_get_name (MonoProperty *prop) /** * mono_property_get_set_method - * @prop: the MonoProperty to act on. - * - * Returns: The setter method of the property (A MonoMethod) + * \param prop the \c MonoProperty to act on. + * \returns The setter method of the property, a \c MonoMethod. */ MonoMethod* mono_property_get_set_method (MonoProperty *prop) @@ -9492,9 +9637,8 @@ mono_property_get_set_method (MonoProperty *prop) /** * mono_property_get_get_method - * @prop: the MonoProperty to act on. - * - * Returns: The setter method of the property (A MonoMethod) + * \param prop the MonoProperty to act on. + * \returns The getter method of the property (A \c MonoMethod) */ MonoMethod* mono_property_get_get_method (MonoProperty *prop) @@ -9504,9 +9648,8 @@ mono_property_get_get_method (MonoProperty *prop) /** * mono_property_get_parent: - * @prop: the MonoProperty to act on. - * - * Returns: The MonoClass where the property was defined. + * \param prop the \c MonoProperty to act on. + * \returns The \c MonoClass where the property was defined. */ MonoClass* mono_property_get_parent (MonoProperty *prop) @@ -9516,12 +9659,12 @@ mono_property_get_parent (MonoProperty *prop) /** * mono_property_get_flags: - * @prop: the MonoProperty to act on. + * \param prop the \c MonoProperty to act on. * * The metadata flags for a property are encoded using the - * PROPERTY_ATTRIBUTE_* constants. See the tabledefs.h file for details. + * \c PROPERTY_ATTRIBUTE_* constants. See the \c tabledefs.h file for details. * - * Returns: The flags for the property. + * \returns The flags for the property. */ guint32 mono_property_get_flags (MonoProperty *prop) @@ -9531,9 +9674,8 @@ mono_property_get_flags (MonoProperty *prop) /** * mono_event_get_name: - * @event: the MonoEvent to act on - * - * Returns: The name of the event. + * \param event the MonoEvent to act on + * \returns The name of the event. */ const char* mono_event_get_name (MonoEvent *event) @@ -9543,9 +9685,8 @@ mono_event_get_name (MonoEvent *event) /** * mono_event_get_add_method: - * @event: The MonoEvent to act on. - * - * Returns: The @add' method for the event (a MonoMethod). + * \param event The \c MonoEvent to act on. + * \returns The \c add method for the event, a \c MonoMethod. */ MonoMethod* mono_event_get_add_method (MonoEvent *event) @@ -9555,9 +9696,8 @@ mono_event_get_add_method (MonoEvent *event) /** * mono_event_get_remove_method: - * @event: The MonoEvent to act on. - * - * Returns: The @remove method for the event (a MonoMethod). + * \param event The \c MonoEvent to act on. + * \returns The \c remove method for the event, a \c MonoMethod. */ MonoMethod* mono_event_get_remove_method (MonoEvent *event) @@ -9567,9 +9707,8 @@ mono_event_get_remove_method (MonoEvent *event) /** * mono_event_get_raise_method: - * @event: The MonoEvent to act on. - * - * Returns: The @raise method for the event (a MonoMethod). + * \param event The \c MonoEvent to act on. + * \returns The \c raise method for the event, a \c MonoMethod. */ MonoMethod* mono_event_get_raise_method (MonoEvent *event) @@ -9579,9 +9718,8 @@ mono_event_get_raise_method (MonoEvent *event) /** * mono_event_get_parent: - * @event: the MonoEvent to act on. - * - * Returns: The MonoClass where the event is defined. + * \param event the MonoEvent to act on. + * \returns The \c MonoClass where the event is defined. */ MonoClass* mono_event_get_parent (MonoEvent *event) @@ -9591,12 +9729,12 @@ mono_event_get_parent (MonoEvent *event) /** * mono_event_get_flags - * @event: the MonoEvent to act on. + * \param event the \c MonoEvent to act on. * * The metadata flags for an event are encoded using the - * EVENT_* constants. See the tabledefs.h file for details. + * \c EVENT_* constants. See the \c tabledefs.h file for details. * - * Returns: The flags for the event. + * \returns The flags for the event. */ guint32 mono_event_get_flags (MonoEvent *event) @@ -9606,11 +9744,11 @@ mono_event_get_flags (MonoEvent *event) /** * mono_class_get_method_from_name: - * @klass: where to look for the method - * @name: name of the method - * @param_count: number of parameters. -1 for any number. + * \param klass where to look for the method + * \param name name of the method + * \param param_count number of parameters. -1 for any number. * - * Obtains a MonoMethod with a given name and number of parameters. + * Obtains a \c MonoMethod with a given name and number of parameters. * It only works if there are no multiple signatures for any given method name. */ MonoMethod * @@ -9664,12 +9802,12 @@ find_method_in_metadata (MonoClass *klass, const char *name, int param_count, in /** * mono_class_get_method_from_name_flags: - * @klass: where to look for the method - * @name_space: name of the method - * @param_count: number of parameters. -1 for any number. - * @flags: flags which must be set in the method + * \param klass where to look for the method + * \param name_space name of the method + * \param param_count number of parameters. -1 for any number. + * \param flags flags which must be set in the method * - * Obtains a MonoMethod with a given name and number of parameters. + * Obtains a \c MonoMethod with a given name and number of parameters. * It only works if there are no multiple signatures for any given method name. */ MonoMethod * @@ -9722,9 +9860,9 @@ mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int p /** * mono_class_set_failure: - * @klass: class in which the failure was detected - * @ex_type: the kind of exception/error to be thrown (later) - * @ex_data: exception data (specific to each type of exception/error) + * \param klass class in which the failure was detected + * \param ex_type the kind of exception/error to be thrown (later) + * \param ex_data exception data (specific to each type of exception/error) * * Keep a detected failure informations in the class for later processing. * Note that only the first failure is kept. @@ -9757,16 +9895,16 @@ mono_class_has_failure (const MonoClass *klass) /** * mono_class_set_type_load_failure: - * @klass: class in which the failure was detected - * @fmt: Printf-style error message string. + * \param klass class in which the failure was detected + * \param fmt \c printf -style error message string. * * Collect detected failure informaion in the class for later processing. - * The error is stored as a MonoErrorBoxed as with mono_error_set_type_load_class () + * The error is stored as a MonoErrorBoxed as with mono_error_set_type_load_class() * Note that only the first failure is kept. * - * Returns FALSE if a failure was already set on the class, or TRUE otherwise. - * * LOCKING: Acquires the loader lock. + * + * \returns FALSE if a failure was already set on the class, or TRUE otherwise. */ gboolean mono_class_set_type_load_failure (MonoClass *klass, const char * fmt, ...) @@ -9777,7 +9915,7 @@ mono_class_set_type_load_failure (MonoClass *klass, const char * fmt, ...) if (mono_class_has_failure (klass)) return FALSE; - mono_error_init (&prepare_error); + error_init (&prepare_error); va_start (args, fmt); mono_error_vset_type_load_class (&prepare_error, klass, fmt, args); @@ -9792,7 +9930,9 @@ mono_class_set_type_load_failure (MonoClass *klass, const char * fmt, ...) * mono_classes_init: * * Initialize the resources used by this module. + * Known racy counters: `class_gparam_count`, `classes_size` and `inflated_methods_size` */ +MONO_NO_SANITIZE_THREAD void mono_classes_init (void) { @@ -9840,9 +9980,9 @@ mono_classes_cleanup (void) /** * mono_class_get_exception_for_failure: - * @klass: class in which the failure was detected + * \param klass class in which the failure was detected * - * Return a constructed MonoException than the caller can then throw + * \returns a constructed MonoException than the caller can then throw * using mono_raise_exception - or NULL if no failure is present (or * doesn't result in an exception). */ @@ -9852,7 +9992,7 @@ mono_class_get_exception_for_failure (MonoClass *klass) if (!mono_class_has_failure (klass)) return NULL; MonoError unboxed_error; - mono_error_init (&unboxed_error); + error_init (&unboxed_error); mono_error_set_for_class_failure (&unboxed_error, klass); return mono_error_convert_to_exception (&unboxed_error); } @@ -9949,7 +10089,7 @@ can_access_internals (MonoAssembly *accessing, MonoAssembly* accessed) /* Be conservative with checks */ if (!friend_->name) continue; - if (strcmp (accessing->aname.name, friend_->name)) + if (g_ascii_strcasecmp (accessing->aname.name, friend_->name)) continue; if (friend_->public_key_token [0]) { if (!accessing->aname.public_key_token [0]) @@ -10129,12 +10269,12 @@ can_access_member (MonoClass *access_klass, MonoClass *member_klass, MonoClass* /** * mono_method_can_access_field: - * @method: Method that will attempt to access the field - * @field: the field to access + * \param method Method that will attempt to access the field + * \param field the field to access * * Used to determine if a method is allowed to access the specified field. * - * Returns: TRUE if the given @method is allowed to access the @field while following + * \returns TRUE if the given \p method is allowed to access the \p field while following * the accessibility rules of the CLI. */ gboolean @@ -10156,12 +10296,12 @@ mono_method_can_access_field (MonoMethod *method, MonoClassField *field) /** * mono_method_can_access_method: - * @method: Method that will attempt to access the other method - * @called: the method that we want to probe for accessibility. + * \param method Method that will attempt to access the other method + * \param called the method that we want to probe for accessibility. * - * Used to determine if the @method is allowed to access the specified @called method. + * Used to determine if the \p method is allowed to access the specified \p called method. * - * Returns: TRUE if the given @method is allowed to invoke the @called while following + * \returns TRUE if the given \p method is allowed to invoke the \p called while following * the accessibility rules of the CLI. */ gboolean @@ -10294,9 +10434,8 @@ mono_class_can_access_class (MonoClass *source_class, MonoClass *target_class) /** * mono_type_is_valid_enum_basetype: - * @type: The MonoType to check - * - * Returns: TRUE if the type can be used as the basetype of an enum + * \param type The MonoType to check + * \returns TRUE if the type can be used as the basetype of an enum */ gboolean mono_type_is_valid_enum_basetype (MonoType * type) { switch (type->type) { @@ -10320,15 +10459,15 @@ gboolean mono_type_is_valid_enum_basetype (MonoType * type) { /** * mono_class_is_valid_enum: - * @klass: An enum class to be validated + * \param klass An enum class to be validated * * This method verify the required properties an enum should have. - * - * Returns: TRUE if the informed enum class is valid * * FIXME: TypeBuilder enums are allowed to implement interfaces, but since they cannot have methods, only empty interfaces are possible * FIXME: enum types are not allowed to have a cctor, but mono_reflection_create_runtime_class sets has_cctor to 1 for all types * FIXME: TypeBuilder enums can have any kind of static fields, but the spec is very explicit about that (P II 14.3) + * + * \returns TRUE if the informed enum class is valid */ gboolean mono_class_is_valid_enum (MonoClass *klass) @@ -10400,7 +10539,7 @@ mono_class_setup_interfaces (MonoClass *klass, MonoError *error) int i, interface_count; MonoClass **interfaces; - mono_error_init (error); + error_init (error); if (klass->interfaces_inited) return; @@ -10408,16 +10547,22 @@ mono_class_setup_interfaces (MonoClass *klass, MonoError *error) if (klass->rank == 1 && klass->byval_arg.type != MONO_TYPE_ARRAY) { MonoType *args [1]; - /* generic IList, ICollection, IEnumerable */ - interface_count = mono_defaults.generic_ireadonlylist_class ? 2 : 1; + /* IList and IReadOnlyList -> 2x if enum*/ + interface_count = klass->element_class->enumtype ? 4 : 2; interfaces = (MonoClass **)mono_image_alloc0 (klass->image, sizeof (MonoClass*) * interface_count); args [0] = &klass->element_class->byval_arg; interfaces [0] = mono_class_bind_generic_parameters ( mono_defaults.generic_ilist_class, 1, args, FALSE); - if (interface_count > 1) - interfaces [1] = mono_class_bind_generic_parameters ( + interfaces [1] = mono_class_bind_generic_parameters ( mono_defaults.generic_ireadonlylist_class, 1, args, FALSE); + if (klass->element_class->enumtype) { + args [0] = mono_class_enum_basetype (klass->element_class); + interfaces [2] = mono_class_bind_generic_parameters ( + mono_defaults.generic_ilist_class, 1, args, FALSE); + interfaces [3] = mono_class_bind_generic_parameters ( + mono_defaults.generic_ireadonlylist_class, 1, args, FALSE); + } } else if (mono_class_is_ginst (klass)) { MonoClass *gklass = mono_class_get_generic_class (klass)->container_class; @@ -10462,7 +10607,7 @@ mono_field_resolve_type (MonoClassField *field, MonoError *error) MonoType *ftype; int field_idx = field - klass->fields; - mono_error_init (error); + error_init (error); if (gtd) { MonoClassField *gfield = >d->fields [field_idx]; @@ -10546,7 +10691,7 @@ mono_field_resolve_flags (MonoClassField *field) /** * mono_class_get_fields_lazy: - * @klass: the MonoClass to act on + * \param klass the MonoClass to act on * * This routine is an iterator routine for retrieving the fields in a class. * Only minimal information about fields are loaded. Accessors must be used @@ -10556,7 +10701,7 @@ mono_field_resolve_flags (MonoClassField *field) * iterate over all of the elements. When no more values are * available, the return value is NULL. * - * Returns: a @MonoClassField* on each iteration, or NULL when no more fields are available. + * \returns a \c MonoClassField* on each iteration, or NULL when no more fields are available. */ MonoClassField* mono_class_get_fields_lazy (MonoClass* klass, gpointer *iter) @@ -10593,21 +10738,21 @@ mono_class_full_name (MonoClass *klass) } /* Declare all shared lazy type lookup functions */ -GENERATE_TRY_GET_CLASS_WITH_CACHE (safehandle, System.Runtime.InteropServices, "SafeHandle") +GENERATE_TRY_GET_CLASS_WITH_CACHE (safehandle, "System.Runtime.InteropServices", "SafeHandle") /** * mono_method_get_base_method: - * @method: a method - * @definition: if true, get the definition - * @error: set on failure + * \param method a method + * \param definition if true, get the definition + * \param error set on failure * * Given a virtual method associated with a subclass, return the corresponding - * method from an ancestor. If @definition is FALSE, returns the method in the - * superclass of the given method. If @definition is TRUE, return the method + * method from an ancestor. If \p definition is FALSE, returns the method in the + * superclass of the given method. If \p definition is TRUE, return the method * in the ancestor class where it was first declared. The type arguments will * be inflated in the ancestor classes. If the method is not associated with a * class, or isn't virtual, returns the method itself. On failure returns NULL - * and sets @error. + * and sets \p error. */ MonoMethod* mono_method_get_base_method (MonoMethod *method, gboolean definition, MonoError *error)