* Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
* Copyright 2004-2009 Novell, Inc (http://www.novell.com)
* Copyright 2012 Xamarin Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <config.h>
#ifdef HAVE_ALLOCA_H
}
}
-/*
+/**
* mono_class_from_typeref:
* @image: a MonoImage
* @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
+ * Returns: The MonoClass* representing the typeref token, NULL ifcould
* not be loaded.
*/
MonoClass *
return klass;
}
+/**
+ * mono_class_from_typeref_checked:
+ * @image: a MonoImage
+ * @type_token: a TypeRef token
+ * @error: error return code, if any.
+ *
+ * Creates the MonoClass* structure representing the type defined by
+ * the typeref token valid inside @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
+ * error.
+ */
MonoClass *
mono_class_from_typeref_checked (MonoImage *image, guint32 type_token, MonoError *error)
{
* @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
* mono_type_get_full_name:
* @class: a class
*
- * Returns: the string representation for type as required by System.Reflection.
+ * Returns: The string representation for type as required by System.Reflection.
* The inverse of mono_reflection_parse_type ().
*/
char *
* mono_type_get_name:
* @type: a type
*
- * Returns: the string representation for type as it would be represented in IL code.
+ * Returns: The string representation for type as it would be represented in IL code.
*/
char*
mono_type_get_name (MonoType *type)
* mono_type_get_underlying_type:
* @type: a type
*
- * Returns: the MonoType for the underlying integer type if @type
+ * Returns: The MonoType for the underlying integer type if @type
* is an enum and byref is false, otherwise the type itself.
*/
MonoType*
return type;
}
-/*
+/**
* mono_class_is_open_constructed_type:
* @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.
*
* If @type is a generic type and @context is not NULL, instantiate it using the
* generics context @context.
*
- * Returns: the instantiated type or a copy of @type. The returned MonoType is allocated
+ * Returns: The instantiated type or a copy of @type. The returned 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
MonoError error;
MonoType *result;
result = mono_class_inflate_generic_type_checked (type, context, &error);
-
- if (!mono_error_ok (&error)) {
- mono_error_cleanup (&error);
- return NULL;
- }
+ mono_error_cleanup (&error);
return result;
}
* If @type is a generic type and @context is not NULL, instantiate it using the
* generics context @context.
*
- * Returns: the instantiated type or a copy of @type. The returned MonoType is allocated
+ * Returns: The instantiated type or a copy of @type. The returned MonoType is allocated
* on the heap and is owned by the caller.
*/
MonoType*
return inflated;
}
+/*
+ * mono_class_inflate_generic_class:
+ *
+ * Inflate the class @gklass with @context. Set @error on failure.
+ */
MonoClass*
mono_class_inflate_generic_class_checked (MonoClass *gklass, MonoGenericContext *context, MonoError *error)
{
return res;
}
-/*
- * mono_class_inflate_generic_class:
- *
- * Inflate the class GKLASS with CONTEXT.
- */
-MonoClass*
-mono_class_inflate_generic_class (MonoClass *gklass, MonoGenericContext *context)
-{
- MonoError error;
- MonoClass *res;
-
- res = mono_class_inflate_generic_class_checked (gklass, context, &error);
- g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
-
- return res;
-}
-
-
static MonoGenericContext
inflate_generic_context (MonoGenericContext *context, MonoGenericContext *inflate_with, MonoError *error)
*
* Instantiate the generic method @method using the generics context @context.
*
- * Returns: the new instantiated method
+ * Returns: The new instantiated method
*/
MonoMethod *
mono_class_inflate_generic_method (MonoMethod *method, MonoGenericContext *context)
goto fail;
}
- ftype = mono_metadata_parse_type_full (m, container, cols [MONO_FIELD_FLAGS], sig + 1, &sig);
- if (!ftype) {
- if (mono_loader_get_last_error ()) /*FIXME plug the above to not leak errors*/
- mono_error_set_from_loader_error (error);
- else
- mono_error_set_bad_image (error, klass->image, "Could not parse type for field signature %x", cols [MONO_FIELD_SIGNATURE]);
+ ftype = mono_metadata_parse_type_checked (m, container, cols [MONO_FIELD_FLAGS], FALSE, sig + 1, &sig, error);
+ if (!ftype)
goto fail;
- }
+
if (klass->generic_class) {
//FIXME do we leak here?
ftype = mono_class_inflate_generic_type_checked (ftype, mono_class_get_context (klass), error);
case MONO_TYPE_CLASS:
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_SZARRAY:
- return type->data.klass->exception_type;
+ return mono_class_has_failure (type->data.klass);
case MONO_TYPE_ARRAY:
- return type->data.array->eklass->exception_type;
+ return mono_class_has_failure (type->data.array->eklass);
case MONO_TYPE_GENERICINST:
- return mono_generic_class_get_class (type->data.generic_class)->exception_type;
+ return mono_class_has_failure (mono_generic_class_get_class (type->data.generic_class));
default:
return FALSE;
}
int i, blittable = TRUE;
guint32 real_size = 0;
guint32 packing_size = 0;
+ int instance_size;
gboolean explicit_size;
MonoClassField *field;
MonoGenericContainer *container = NULL;
if (gtd) {
mono_class_setup_fields (gtd);
- if (gtd->exception_type) {
+ if (mono_class_has_failure (gtd)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
return;
}
}
- klass->instance_size = 0;
+ instance_size = 0;
if (!klass->rank)
klass->sizes.class_size = 0;
mono_class_init (klass->parent);
if (!klass->parent->size_inited) {
mono_class_setup_fields (klass->parent);
- if (klass->parent->exception_type) {
+ if (mono_class_has_failure (klass->parent)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
return;
}
}
- klass->instance_size += klass->parent->instance_size;
+ instance_size += klass->parent->instance_size;
klass->min_align = klass->parent->min_align;
/* we use |= since it may have been set already */
klass->has_references |= klass->parent->has_references;
blittable = klass->parent->blittable;
} else {
- klass->instance_size = sizeof (MonoObject);
+ instance_size = sizeof (MonoObject);
klass->min_align = 1;
}
return;
}
klass->packing_size = packing_size;
- real_size += klass->instance_size;
+ real_size += instance_size;
}
if (!top) {
if (explicit_size && real_size) {
- klass->instance_size = MAX (real_size, klass->instance_size);
+ instance_size = MAX (real_size, instance_size);
}
klass->blittable = blittable;
+ if (!klass->instance_size)
+ klass->instance_size = instance_size;
mono_memory_barrier ();
klass->size_inited = 1;
klass->fields_inited = 1;
MonoClass *field_class = mono_class_from_mono_type (field->type);
if (field_class) {
mono_class_setup_fields (field_class);
- if (field_class->exception_type) {
+ if (mono_class_has_failure (field_class)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
break;
}
return;
}
if (explicit_size && real_size) {
- klass->instance_size = MAX (real_size, klass->instance_size);
+ instance_size = MAX (real_size, instance_size);
}
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return;
- mono_class_layout_fields (klass);
+ mono_class_layout_fields (klass, instance_size);
/*valuetypes can't be neither bigger than 1Mb or empty. */
if (klass->valuetype && (klass->instance_size <= 0 || klass->instance_size > (0x100000 + sizeof (MonoObject))))
/*
* mono_class_layout_fields:
* @class: a class
+ * @instance_size: base instance size
*
* Compute the placement of fields inside an object or struct, according to
* the layout rules and set the following fields in @class:
* LOCKING: this is supposed to be called with the loader lock held.
*/
void
-mono_class_layout_fields (MonoClass *klass)
+mono_class_layout_fields (MonoClass *klass, int instance_size)
{
int i;
const int top = klass->field.count;
/*
* Compute field layout and total size (not considering static fields)
*/
-
switch (layout) {
case TYPE_ATTRIBUTE_AUTO_LAYOUT:
case TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT:
if (klass->parent) {
mono_class_setup_fields (klass->parent);
- if (klass->parent->exception_type) {
+ if (mono_class_has_failure (klass->parent)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
return;
}
real_size = field->offset + size;
}
- klass->instance_size = MAX (real_size, klass->instance_size);
+ instance_size = MAX (real_size, instance_size);
- if (klass->instance_size & (klass->min_align - 1)) {
- klass->instance_size += klass->min_align - 1;
- klass->instance_size &= ~(klass->min_align - 1);
+ if (instance_size & (klass->min_align - 1)) {
+ instance_size += klass->min_align - 1;
+ instance_size &= ~(klass->min_align - 1);
}
}
break;
g_free (ref_bitmap);
}
- klass->instance_size = MAX (real_size, klass->instance_size);
- if (klass->instance_size & (klass->min_align - 1)) {
- klass->instance_size += klass->min_align - 1;
- klass->instance_size &= ~(klass->min_align - 1);
+ instance_size = MAX (real_size, instance_size);
+ if (instance_size & (klass->min_align - 1)) {
+ instance_size += klass->min_align - 1;
+ instance_size &= ~(klass->min_align - 1);
}
break;
}
* unaligned accesses otherwise. See #78990 for a testcase.
*/
if (mono_align_small_structs) {
- if (klass->instance_size <= sizeof (MonoObject) + sizeof (gpointer))
- klass->min_align = MAX (klass->min_align, klass->instance_size - sizeof (MonoObject));
+ if (instance_size <= sizeof (MonoObject) + sizeof (gpointer))
+ klass->min_align = MAX (klass->min_align, instance_size - sizeof (MonoObject));
}
}
+ if (klass->instance_size && !klass->image->dynamic) {
+ /* Might be already set using cached info */
+ g_assert (klass->instance_size == instance_size);
+ } else {
+ klass->instance_size = instance_size;
+ }
mono_memory_barrier ();
klass->size_inited = 1;
MonoClass *gklass = klass->generic_class->container_class;
mono_class_init (gklass);
- if (!gklass->exception_type)
+ if (!mono_class_has_failure (gklass))
mono_class_setup_methods (gklass);
- if (gklass->exception_type) {
+ if (mono_class_has_failure (gklass)) {
/* FIXME make exception_data less opaque so it's possible to dup it here */
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load"));
return;
return m;
} else {
mono_class_setup_methods (klass);
- if (klass->exception_type) /*FIXME do proper error handling*/
+ if (mono_class_has_failure (klass)) /*FIXME do proper error handling*/
return NULL;
g_assert (index >= 0 && index < klass->method.count);
return klass->methods [index];
g_assert (method->klass == gklass);
mono_class_setup_methods (gklass);
- g_assert (!gklass->exception_type); /*FIXME do proper error handling*/
+ g_assert (!mono_class_has_failure (gklass)); /*FIXME do proper error handling*/
for (i = 0; i < gklass->method.count; ++i) {
if (gklass->methods [i] == method) {
g_assert (mono_error_ok (&error)); /* FIXME don't swallow this error */
} else {
mono_class_setup_vtable (klass);
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return NULL;
m = klass->vtable [offset];
}
mono_class_init (gklass);
mono_class_setup_properties (gklass);
- if (gklass->exception_type) {
+ if (mono_class_has_failure (gklass)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load"));
return;
}
if (count) {
mono_class_setup_methods (klass);
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return;
}
MonoGenericContext *context = NULL;
mono_class_setup_events (gklass);
- if (gklass->exception_type) {
+ if (mono_class_has_failure (gklass)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load"));
return;
}
if (count) {
mono_class_setup_methods (klass);
- if (klass->exception_type) {
+ if (mono_class_has_failure (klass)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Generic type definition failed to load"));
return;
}
}
}
-/*
+/**
* mono_get_unique_iid:
* @class: interface
*
* Assign a unique integer ID to the interface represented by @class.
* The ID will positive and as small as possible.
* LOCKING: Acquires the classes lock.
- * Returns: the new ID.
+ * Returns: The new ID.
*/
static guint
mono_get_unique_iid (MonoClass *klass)
*res = g_ptr_array_new ();
g_ptr_array_add (*res, ic);
mono_class_init (ic);
- if (ic->exception_type) {
+ if (mono_class_has_failure (ic)) {
mono_error_set_type_load_class (error, ic, "Error Loading class");
return;
}
}
}
-/*
+/**
* 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
all_interfaces = eclass->rank && eclass->element_class->rank? FALSE: TRUE;
if (!generic_icollection_class) {
- generic_icollection_class = mono_class_from_name (mono_defaults.corlib,
+ generic_icollection_class = mono_class_load_from_name (mono_defaults.corlib,
"System.Collections.Generic", "ICollection`1");
- generic_ienumerable_class = mono_class_from_name (mono_defaults.corlib,
+ generic_ienumerable_class = mono_class_load_from_name (mono_defaults.corlib,
"System.Collections.Generic", "IEnumerable`1");
- generic_ienumerator_class = mono_class_from_name (mono_defaults.corlib,
+ generic_ienumerator_class = mono_class_load_from_name (mono_defaults.corlib,
"System.Collections.Generic", "IEnumerator`1");
- generic_ireadonlylist_class = mono_class_from_name (mono_defaults.corlib,
+ generic_ireadonlylist_class = mono_class_load_from_name (mono_defaults.corlib,
"System.Collections.Generic", "IReadOnlyList`1");
- generic_ireadonlycollection_class = mono_class_from_name (mono_defaults.corlib,
+ generic_ireadonlycollection_class = mono_class_load_from_name (mono_defaults.corlib,
"System.Collections.Generic", "IReadOnlyCollection`1");
}
if (klass->methods || !MONO_CLASS_HAS_STATIC_METADATA (klass)) {
mono_class_setup_methods (klass);
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return -1;
for (i = 0; i < klass->method.count; ++i) {
* 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)
* 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,
+ * Returns: A non-zero value if bit @id is set in the bitmap @bitmap,
* #FALSE otherwise.
*/
int
int i;
if (!klass->generic_class) {
mono_class_setup_vtable_full (klass, in_setup);
- return klass->exception_type == 0;
+ return !mono_class_has_failure (klass);
}
mono_class_setup_vtable_full (mono_class_get_generic_type_definition (klass), in_setup);
- if (klass->generic_class->container_class->exception_type) {
+ if (mono_class_has_failure (klass->generic_class->container_class)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Failed to load generic definition vtable"));
return FALSE;
}
static void
mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup)
{
+ MonoError error;
MonoMethod **overrides;
MonoGenericContext *context;
guint32 type_token;
return;
}
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return;
if (g_list_find (in_setup, klass))
* This is true since we don't do layout all over again for them, we simply inflate
* the layout of the parent.
*/
- mono_reflection_get_dynamic_overrides (klass, &overrides, &onum);
+ mono_reflection_get_dynamic_overrides (klass, &overrides, &onum, &error);
+ if (!is_ok (&error)) {
+ mono_loader_unlock ();
+ g_list_remove (in_setup, klass);
+ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf("Could not load list of method overrides due to %s", mono_error_get_message (&error)));
+ mono_error_cleanup (&error);
+ return;
+ }
} else {
/* The following call fails if there are missing methods in the type */
/* FIXME it's probably a good idea to avoid this for generic instances. */
g_free (method_signature);
g_free (type_name);
mono_class_setup_methods (klass);
- if (klass->exception_type) {
+ if (mono_class_has_failure (klass)) {
char *name = mono_type_get_full_name (klass);
mono_trace_warning (MONO_TRACE_TYPE, "CLASS %s failed to resolve methods\n", name);
g_free (name);
mono_class_init (klass->parent);
mono_class_setup_vtable_full (klass->parent, in_setup);
- if (klass->parent->exception_type) {
+ if (mono_class_has_failure (klass->parent)) {
char *name = mono_type_get_full_name (klass->parent);
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Parent %s failed to load", name));
g_free (name);
MonoMethod **tmp;
mono_class_setup_vtable_full (gklass, in_setup);
- if (gklass->exception_type != MONO_EXCEPTION_NONE) {
+ if (mono_class_has_failure (gklass)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
return;
}
mono_class_setup_methods (parent_interface); /*FIXME Just kill this whole chunk of dead code*/
TRACE_INTERFACE_VTABLE (printf (" +++ Inheriting interface %s.%s\n", parent_interface->name_space, parent_interface->name));
- for (j = 0; j < parent_interface->method.count && !klass->exception_type; j++) {
+ for (j = 0; j < parent_interface->method.count && !mono_class_has_failure (klass); j++) {
vtable [interface_offset + j] = parent->vtable [parent_interface_offset + j];
TRACE_INTERFACE_VTABLE (printf (" --- Inheriting: [%03d][(%03d)+(%03d)] => [%03d][(%03d)+(%03d)]\n",
parent_interface_offset + j, parent_interface_offset, j,
while ((cm = mono_class_get_virtual_methods (klass, &iter))) {
virt_methods = g_slist_prepend (virt_methods, cm);
}
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
goto fail;
}
ic_offset = mono_class_interface_offset (klass, ic);
mono_class_setup_methods (ic);
- if (ic->exception_type)
+ if (mono_class_has_failure (ic))
goto fail;
// Check if this interface is explicitly implemented (instead of just inherited)
}
}
TRACE_INTERFACE_VTABLE (printf ("\n"));
- if (klass->exception_type) /*Might be set by check_interface_method_override*/
+ if (mono_class_has_failure (klass)) /*Might be set by check_interface_method_override*/
goto fail;
}
}
break;
}
- if (klass->exception_type) /*Might be set by check_interface_method_override*/
+ if (mono_class_has_failure (klass)) /*Might be set by check_interface_method_override*/
goto fail;
TRACE_INTERFACE_VTABLE ((cm != NULL) && printf ("\n"));
}
break;
}
}
- if (k->exception_type)
+ if (mono_class_has_failure (k))
goto fail;
if (slot >= 0)
{
if (method->slot == -1) {
mono_class_setup_vtable (method->klass);
- if (method->klass->exception_type)
+ if (mono_class_has_failure (method->klass))
return -1;
if (method->slot == -1) {
MonoClass *gklass;
if (generic_array_method_num)
return generic_array_method_num;
mono_class_setup_methods (klass->parent); /*This is setting up System.Array*/
- g_assert (!klass->parent->exception_type); /*So hitting this assert is a huge problem*/
+ g_assert (!mono_class_has_failure (klass->parent)); /*So hitting this assert is a huge problem*/
for (i = 0; i < klass->parent->method.count; i++) {
MonoMethod *m = klass->parent->methods [i];
if (!strncmp (m->name, "InternalArray__", 15)) {
g_assert (klass);
/* Double-checking locking pattern */
- if (klass->inited || klass->exception_type)
- return klass->exception_type == MONO_EXCEPTION_NONE;
+ if (klass->inited || mono_class_has_failure (klass))
+ return !mono_class_has_failure (klass);
/*g_print ("Init class %s\n", mono_type_get_full_name (klass));*/
/* We do everything inside the lock to prevent races */
mono_loader_lock ();
- if (klass->inited || klass->exception_type) {
+ if (klass->inited || mono_class_has_failure (klass)) {
mono_loader_unlock ();
/* Somebody might have gotten in before us */
- return klass->exception_type == MONO_EXCEPTION_NONE;
+ return !mono_class_has_failure (klass);
}
if (klass->init_pending) {
MonoClass *element_class = klass->element_class;
if (!element_class->inited)
mono_class_init (element_class);
- if (element_class->exception_type != MONO_EXCEPTION_NONE) {
+ if (mono_class_has_failure (element_class)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
goto leave;
}
mono_class_init (gklass);
// FIXME: Why is this needed ?
- if (!gklass->exception_type)
+ if (!mono_class_has_failure (gklass))
mono_class_setup_methods (gklass);
- if (gklass->exception_type) {
+ if (mono_class_has_failure (gklass)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Generic Type Defintion failed to init"));
goto leave;
}
else
if (!klass->size_inited){
mono_class_setup_fields (klass);
- if (klass->exception_type || mono_loader_get_last_error ())
+ if (mono_class_has_failure (klass) || mono_loader_get_last_error ())
goto leave;
}
klass->has_cctor = gklass->has_cctor;
mono_class_setup_vtable (gklass);
- if (gklass->exception_type) {
+ if (mono_class_has_failure (gklass)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
goto leave;
}
klass->has_cctor = 1;
} else {
mono_class_setup_methods (klass);
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
goto leave;
for (i = 0; i < klass->method.count; ++i) {
int first_iface_slot;
/* This will compute klass->parent->vtable_size for some classes */
mono_class_init (klass->parent);
- if (klass->parent->exception_type) {
+ if (mono_class_has_failure (klass->parent)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
goto leave;
}
if (!klass->parent->vtable_size) {
/* FIXME: Get rid of this somehow */
mono_class_setup_vtable (klass->parent);
- if (klass->parent->exception_type) {
+ if (mono_class_has_failure (klass->parent)) {
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
goto leave;
}
mono_security_core_clr_check_inheritance (klass);
if (mono_loader_get_last_error ()) {
- if (klass->exception_type == MONO_EXCEPTION_NONE) {
+ if (!mono_class_has_failure (klass)) {
set_failure_from_loader_error (klass, mono_loader_get_last_error ());
}
mono_loader_clear_error ();
mono_loader_unlock ();
- return klass->exception_type == MONO_EXCEPTION_NONE;
+ return !mono_class_has_failure (klass);
}
/*
* ignores overrides.
*/
mono_class_setup_vtable (klass);
- if (klass->exception_type || mono_loader_get_last_error ())
+ if (mono_class_has_failure (klass) || mono_loader_get_last_error ())
cmethod = NULL;
else
cmethod = klass->vtable [finalize_slot];
mono_error_set_type_load_class (error, klass, msg);
}
-static void
-mono_class_set_failure_from_loader_error (MonoClass *klass, MonoError *error, char *msg)
-{
- MonoLoaderError *lerror = mono_loader_get_last_error ();
-
- if (lerror) {
- set_failure_from_loader_error (klass, lerror);
- mono_error_set_from_loader_error (error);
- if (msg)
- g_free (msg);
- } else {
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, msg);
- mono_error_set_type_load_class (error, klass, msg);
- }
-}
-
/**
* mono_class_create_from_typedef:
* @image: image where the token is valid
CHECKED_METADATA_WRITE_PTR ( klass->parent , pinfo->constraints [0] );
pos++;
} else if (pinfo && pinfo->flags & GENERIC_PARAMETER_ATTRIBUTE_VALUE_TYPE_CONSTRAINT) {
- CHECKED_METADATA_WRITE_PTR ( klass->parent , mono_class_from_name (mono_defaults.corlib, "System", "ValueType") );
+ CHECKED_METADATA_WRITE_PTR ( klass->parent , mono_class_load_from_name (mono_defaults.corlib, "System", "ValueType") );
} else {
CHECKED_METADATA_WRITE_PTR ( klass->parent , mono_defaults.object_class );
}
if (count - pos > 0) {
mono_class_setup_vtable (klass->parent);
- if (klass->parent->exception_type)
+ if (mono_class_has_failure (klass->parent))
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup ("Failed to setup parent interfaces"));
else
setup_interface_offsets (klass, klass->parent->vtable_size, TRUE);
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.
+ */
MonoClass *
mono_class_from_mono_type (MonoType *type)
{
g_warning ("mono_class_from_mono_type: implement me 0x%02x\n", type->type);
g_assert_not_reached ();
}
-
+
+ // Yes, this returns NULL, even if it is documented as not doing so, but there
+ // is no way for the code to make it this far, due to the assert above.
return NULL;
}
* @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
+ * Returns: A class object describing the array with element type @element_type and
* dimension @rank.
*/
MonoClass *
/* for the building corlib use System.Array from it */
if (image->assembly && assembly_is_dynamic (image->assembly) && image->assembly_name && strcmp (image->assembly_name, "mscorlib") == 0) {
- parent = mono_class_from_name (image, "System", "Array");
+ parent = mono_class_load_from_name (image, "System", "Array");
corlib_type = TRUE;
} else {
parent = mono_defaults.array_class;
if (eclass->byval_arg.type == MONO_TYPE_TYPEDBYREF || eclass->byval_arg.type == MONO_TYPE_VOID) {
/*Arrays of those two types are invalid.*/
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_failure (klass, MONO_EXCEPTION_INVALID_PROGRAM, NULL);
} else if (eclass->enumtype && !mono_class_enum_basetype (eclass)) {
if (!eclass->ref_info_handle || eclass->wastypebuilder) {
g_warning ("Only incomplete TypeBuilder objects are allowed to be an enum without base_type");
mono_class_init (eclass);
if (!eclass->size_inited)
mono_class_setup_fields (eclass);
- if (eclass->exception_type) /*FIXME we fail the array type, but we have to let other fields be set.*/
+ if (mono_class_has_failure (eclass)) /*FIXME we fail the array type, but we have to let other fields be set.*/
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
klass->has_references = MONO_TYPE_IS_REFERENCE (&eclass->byval_arg) || eclass->has_references? TRUE: FALSE;
* @element_class: element class
* @rank: the dimension of the array class
*
- * Returns: a class object describing the array with element type @element_type and
+ * Returns: A class object describing the array with element type @element_type and
* dimension @rank.
*/
MonoClass *
/**
* mono_class_instance_size:
* @klass: a class
- *
- * Returns: the size of an object instance
+ *
+ * Use to get the size of a class in bytes.
+ *
+ * Returns: The size of an object instance
*/
gint32
mono_class_instance_size (MonoClass *klass)
/**
* mono_class_min_align:
* @klass: a class
- *
+ *
+ * Use to get the computed minimum alignment requirements for the specified class.
+ *
* Returns: minimm alignment requirements
*/
gint32
* mono_class_data_size:
* @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)
mono_class_get_field_idx (MonoClass *klass, int idx)
{
mono_class_setup_fields_locking (klass);
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return NULL;
while (klass) {
*
* Search the class @klass and it's parents for a field with the name @name.
*
- * 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 (MonoClass *klass, const char *name)
* If @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)
int i;
mono_class_setup_fields_locking (klass);
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return NULL;
while (klass) {
* 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)
return 0;
}
+/**
+ * mono_class_get_property_from_name:
+ * @klass: a class
+ * @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.
+ */
MonoProperty*
mono_class_get_property_from_name (MonoClass *klass, const char *name)
{
return NULL;
}
+/**
+ * mono_class_get_property_token:
+ * @prop: MonoProperty to query
+ *
+ * Returns: The ECMA token for the specified property.
+ */
guint32
mono_class_get_property_token (MonoProperty *prop)
{
* @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
+ * Returns: The MonoClass that represents @type_token in @image
*/
MonoClass *
mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context)
* @type_token: the token for the class
* @error: error object to return any error
*
- * Returns: the MonoClass that represents @type_token in @image
+ * Returns: The MonoClass that represents @type_token in @image, or NULL on error.
*/
MonoClass *
mono_class_get_checked (MonoImage *image, guint32 type_token, MonoError *error)
*
* 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 @type_token in @image
*/
MonoType *
mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error)
return type;
}
-
+/**
+ * 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
+ */
MonoClass *
mono_class_get (MonoImage *image, guint32 type_token)
{
* @image: The MonoImage where the type is looked up in
* @name_space: the type namespace
* @name: the type short name.
- * @deprecated: use the _checked variant
+ * @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
{
MonoError error;
MonoClass *res = mono_class_from_name_case_checked (image, name_space, name, &error);
- g_assert (!mono_error_ok (&error));
+ mono_error_cleanup (&error);
+
return res;
}
+/**
+ * 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
+ *
+ * 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
+ * in that case.
+ */
MonoClass *
-mono_class_from_name_case_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error)
+mono_class_from_name_case_checked (MonoImage *image, const char *name_space, const char *name, MonoError *error)
{
MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEDEF];
guint32 cols [MONO_TYPEDEF_SIZE];
}
static MonoClass*
-search_modules (MonoImage *image, const char *name_space, const char *name)
+search_modules (MonoImage *image, const char *name_space, const char *name, MonoError *error)
{
MonoTableInfo *file_table = &image->tables [MONO_TABLE_FILE];
MonoImage *file_image;
MonoClass *klass;
int i;
+ mono_error_init (error);
+
/*
* The EXPORTEDTYPES table only contains public types, so have to search the
* modules as well.
file_image = mono_image_load_file_for_image (image, i + 1);
if (file_image) {
- klass = mono_class_from_name (file_image, name_space, name);
- if (klass)
+ klass = mono_class_from_name_checked (file_image, name_space, name, error);
+ if (klass || !is_ok (error))
return klass;
}
}
}
static MonoClass *
-mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, MonoError *error, GHashTable* visited_images)
+mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, GHashTable* visited_images, MonoError *error)
{
GHashTable *nspace_table;
MonoImage *loaded_image;
if (get_class_from_name && image->tables [MONO_TABLE_EXPORTEDTYPE].rows == 0) {
gboolean res = get_class_from_name (image, name_space, name, &klass);
if (res) {
- if (!klass)
- klass = search_modules (image, name_space, name);
+ if (!klass) {
+ klass = search_modules (image, name_space, name, error);
+ if (!is_ok (error))
+ return NULL;
+ }
if (nested)
return klass ? return_nested_in (klass, nested) : NULL;
else
for (i = 0; i < image->module_count; ++i) {
MonoImage *module = image->modules [i];
- klass = mono_class_from_name (module, name_space, name);
- if (klass)
+ klass = mono_class_from_name_checked (module, name_space, name, error);
+ if (klass || !is_ok (error))
return klass;
}
}
if (!token) {
- klass = search_modules (image, name_space, name);
- if (klass)
+ klass = search_modules (image, name_space, name, error);
+ if (klass || !is_ok (error))
return klass;
}
loaded_image = mono_assembly_load_module (image->assembly, impl >> MONO_IMPLEMENTATION_BITS);
if (!loaded_image)
return NULL;
- klass = mono_class_from_name_checked_aux (loaded_image, name_space, name, error, visited_images);
+ klass = mono_class_from_name_checked_aux (loaded_image, name_space, name, visited_images, error);
if (nested)
return klass ? return_nested_in (klass, nested) : NULL;
return klass;
g_assert (image->references [assembly_idx - 1]);
if (image->references [assembly_idx - 1] == (gpointer)-1)
return NULL;
- klass = mono_class_from_name_checked_aux (image->references [assembly_idx - 1]->image, name_space, name, error, visited_images);
+ klass = mono_class_from_name_checked_aux (image->references [assembly_idx - 1]->image, name_space, name, visited_images, error);
if (nested)
- return return_nested_in (klass, nested);
+ return klass ? return_nested_in (klass, nested) : NULL;
return klass;
} else {
g_assert_not_reached ();
return klass;
}
+/**
+ * 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.
+ *
+ * Obtains a MonoClass with a given namespace and a given name which
+ * is located in the given MonoImage.
+ *
+ * Works like mono_class_from_name, but error handling is tricky. It can return NULL and have no error
+ * set if the class was not found or it will return NULL and set the error if there was a loading error.
+ */
MonoClass *
mono_class_from_name_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error)
{
visited_images = g_hash_table_new (g_direct_hash, g_direct_equal);
- klass = mono_class_from_name_checked_aux (image, name_space, name, error, visited_images);
+ klass = mono_class_from_name_checked_aux (image, name_space, name, visited_images, error);
g_hash_table_destroy (visited_images);
MonoClass *klass;
klass = mono_class_from_name_checked (image, name_space, name, &error);
- if (!mono_error_ok (&error)) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error); /* FIXME Don't swallow the error */
- }
+ mono_error_cleanup (&error); /* FIXME Don't swallow the error */
+
+ return klass;
+}
+
+/**
+ * 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.
+ *
+ * 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
+ * If they are missing. Thing of System.Object or System.String.
+ */
+MonoClass *
+mono_class_load_from_name (MonoImage *image, const char* name_space, const char *name)
+{
+ MonoError error;
+ MonoClass *klass;
+
+ klass = mono_class_from_name_checked (image, name_space, name, &error);
+ if (!klass)
+ g_error ("Runtime critical type %s.%s not found", name_space, name);
+ if (!mono_error_ok (&error))
+ g_error ("Could not load runtime critical type %s.%s due to %s", name_space, name, mono_error_get_message (&error));
+ return klass;
+}
+
+/**
+ * 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.
+ *
+ * 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.
+ *
+ * Big design consideration. This function aborts if there was an error loading the type. This prevents us from missing
+ * a type that we would otherwise assume to be available but was not due some error.
+ *
+ */
+MonoClass*
+mono_class_try_load_from_name (MonoImage *image, const char* name_space, const char *name)
+{
+ MonoError error;
+ MonoClass *klass;
+
+ klass = mono_class_from_name_checked (image, name_space, name, &error);
+ if (!mono_error_ok (&error))
+ g_error ("Could not load runtime critical type %s.%s due to %s", name_space, name, mono_error_get_message (&error));
return klass;
}
+
/**
* mono_class_is_subclass_of:
* @klass: class to probe if it is a subclass of another one
* This method determines whether @klass is a subclass of @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
+ * 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 @check_interfaces is false then, then if @klass is not an interface
- * then it returns true if the @klass is a subclass of @klassc.
+ * then it returns TRUE if the @klass is a subclass of @klassc.
*
* if @klass is an interface and @klassc is System.Object, then this function
* return true.
* @klass: the class to be assigned to
* @oklass: the source class
*
- * Both klass and oklass must be instances of the same generic interface.
- * Return true if @klass can be assigned to a @klass variable
+ * Both @klass and @oklass must be instances of the same generic interface.
+ *
+ * Returns: TRUE if @klass can be assigned to a @klass variable
*/
gboolean
mono_class_is_variant_compatible (MonoClass *klass, MonoClass *oklass, gboolean check_for_reference_conv)
* @klass: the class to be assigned to
* @oklass: the source class
*
- * Return: true if an instance of object oklass can be assigned to an
+ * Returns: TRUE if an instance of object oklass can be assigned to an
* instance of object @klass
*/
gboolean
mono_class_is_assignable_from (MonoClass *klass, MonoClass *oklass)
{
+ MonoError error;
/*FIXME this will cause a lot of irrelevant stuff to be loaded.*/
if (!klass->inited)
mono_class_init (klass);
if (!oklass->inited)
mono_class_init (oklass);
- if (klass->exception_type || oklass->exception_type)
+ if (mono_class_has_failure (klass) || mono_class_has_failure (oklass))
return FALSE;
if (mono_type_is_generic_argument (&klass->byval_arg)) {
}
/* interface_offsets might not be set for dynamic classes */
- if (oklass->ref_info_handle && !oklass->interface_bitmap)
+ if (oklass->ref_info_handle && !oklass->interface_bitmap) {
/*
* oklass might be a generic type parameter but they have
* interface_offsets set.
*/
- return mono_reflection_call_is_assignable_to (oklass, klass);
+ gboolean result = mono_reflection_call_is_assignable_to (oklass, klass, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error);
+ return FALSE;
+ }
+ return result;
+ }
if (!oklass->interface_bitmap)
/* Happens with generic instances of not-yet created dynamic types */
return FALSE;
return TRUE;
if (mono_class_has_variant_generic_params (klass)) {
- MonoError error;
int i;
mono_class_setup_interfaces (oklass, &error);
if (!mono_error_ok (&error)) {
* mono_class_get_cctor:
* @klass: A MonoClass pointer
*
- * Returns: the static constructor of @klass if it exists, NULL otherwise.
+ * Returns: The static constructor of @klass if it exists, NULL otherwise.
*/
MonoMethod*
mono_class_get_cctor (MonoClass *klass)
* mono_class_get_finalizer:
* @klass: The MonoClass pointer
*
- * Returns: the finalizer method of @klass if it exists, NULL otherwise.
+ * Returns: The finalizer method of @klass if it exists, NULL otherwise.
*/
MonoMethod*
mono_class_get_finalizer (MonoClass *klass)
* mono_class_array_element_size:
* @klass:
*
- * Returns: the number of bytes an element of type @klass
+ * Returns: The number of bytes an element of type @klass
* uses when stored into an array.
*/
gint32
* mono_array_element_size:
* @ac: pointer to a #MonoArrayClass
*
- * Returns: the size of single array element.
+ * Returns: The size of single array element.
*/
gint32
mono_array_element_size (MonoClass *ac)
get_class_from_name = func;
}
+/**
+ * mono_class_get_image:
+ *
+ * Use this method to get the `MonoImage*` where this class came from.
+ *
+ * Returns: The image where this class is defined.
+ */
MonoImage*
mono_class_get_image (MonoClass *klass)
{
* mono_class_get_element_class:
* @klass: the MonoClass to act on
*
- * Returns: the element class of an array or an enumeration.
+ * Use this function to get the element class of an array.
+ *
+ * Returns: The element class of an array.
*/
MonoClass*
mono_class_get_element_class (MonoClass *klass)
* mono_class_is_valuetype:
* @klass: the MonoClass to act on
*
- * Returns: true if the MonoClass represents a ValueType.
+ * Use this method to determine if the provided `MonoClass*` represents a value type,
+ * or a reference type.
+ *
+ * Returns: TRUE if the MonoClass represents a ValueType, FALSE if it represents a reference type.
*/
gboolean
mono_class_is_valuetype (MonoClass *klass)
* mono_class_is_enum:
* @klass: the MonoClass to act on
*
- * Returns: true if the MonoClass represents an enumeration.
+ * Use this function to determine if the provided `MonoClass*` represents an enumeration.
+ *
+ * Returns: TRUE if the MonoClass represents an enumeration.
*/
gboolean
mono_class_is_enum (MonoClass *klass)
* mono_class_enum_basetype:
* @klass: the MonoClass to act on
*
- * Returns: the underlying type representation for an enumeration.
+ * Use this function to get the underlying type for an enumeration value.
+ *
+ * Returns: The underlying type representation for an enumeration.
*/
MonoType*
mono_class_enum_basetype (MonoClass *klass)
* mono_class_get_parent
* @klass: the 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)
}
/**
- * mono_class_get_nesting_type;
+ * mono_class_get_nesting_type:
* @klass: the MonoClass to act on
*
- * Returns: the container type where this type is nested or NULL if this type is not a nested type.
+ * Use this function to obtain the class that the provided `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.
*/
MonoClass*
mono_class_get_nesting_type (MonoClass *klass)
* mono_class_get_rank:
* @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)
* see the TYPE_ATTRIBUTE_* definitions on tabledefs.h for the
* different values.
*
- * Returns: the flags from the TypeDef table.
+ * Returns: The flags from the TypeDef table.
*/
guint32
mono_class_get_flags (MonoClass *klass)
* mono_class_get_name
* @klass: the MonoClass to act on
*
- * Returns: the name of the class.
+ * Returns: The name of the class.
*/
const char*
mono_class_get_name (MonoClass *klass)
* mono_class_get_namespace:
* @klass: the MonoClass to act on
*
- * Returns: the namespace of the class.
+ * Returns: The namespace of the class.
*/
const char*
mono_class_get_namespace (MonoClass *klass)
*
* This method returns the internal Type representation for the class.
*
- * Returns: the MonoType from the class.
+ * Returns: The MonoType from the class.
*/
MonoType*
mono_class_get_type (MonoClass *klass)
}
/**
- * mono_class_get_type_token
+ * mono_class_get_type_token:
* @klass: the 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)
* mono_class_num_fields:
* @klass: the 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)
* mono_class_num_methods:
* @klass: the 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)
* mono_class_num_properties
* @klass: the 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)
* mono_class_num_events:
* @klass: the 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)
return NULL;
if (!*iter) {
mono_class_setup_fields_locking (klass);
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return NULL;
/* start from the first */
if (klass->field.count) {
* mono_class_is_delegate
* @klass: the MonoClass to act on
*
- * Returns: true if the MonoClass represents a System.Delegate.
+ * Returns: TRUE if the MonoClass represents a System.Delegate.
*/
mono_bool
mono_class_is_delegate (MonoClass *klass)
* @klass: The MonoClass to act on
* @interface: The interface to check if @klass implements.
*
- * Returns: true if @klass implements @interface.
+ * Returns: TRUE if @klass implements @interface.
*/
mono_bool
mono_class_implements_interface (MonoClass* klass, MonoClass* iface)
* mono_field_get_name:
* @field: the MonoClassField to act on
*
- * Returns: the name of the field.
+ * Returns: The name of the field.
*/
const char*
mono_field_get_name (MonoClassField *field)
* The metadata flags for a field are encoded using the
* FIELD_ATTRIBUTE_* constants. See the tabledefs.h file for details.
*
- * Returns: the flags for the field.
+ * Returns: The flags for the field.
*/
guint32
mono_field_get_flags (MonoClassField *field)
}
/**
- * mono_field_get_offset;
+ * mono_field_get_offset:
* @field: the MonoClassField to act on
*
- * Returns: the field offset.
+ * Returns: The field offset.
*/
guint32
mono_field_get_offset (MonoClassField *field)
}
/**
- * mono_field_get_data;
+ * mono_field_get_data:
* @field: the MonoClassField to act on
*
- * Returns: 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 *
* mono_property_get_name:
* @prop: the MonoProperty to act on
*
- * Returns: the name of the property
+ * Returns: The name of the property
*/
const char*
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)
+ * Returns: The setter method of the property (A MonoMethod)
*/
MonoMethod*
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)
+ * Returns: The setter method of the property (A MonoMethod)
*/
MonoMethod*
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.
+ * Returns: The MonoClass where the property was defined.
*/
MonoClass*
mono_property_get_parent (MonoProperty *prop)
* The metadata flags for a property are encoded using the
* PROPERTY_ATTRIBUTE_* constants. See the tabledefs.h file for details.
*
- * Returns: the flags for the property.
+ * Returns: The flags for the property.
*/
guint32
mono_property_get_flags (MonoProperty *prop)
* mono_event_get_name:
* @event: the MonoEvent to act on
*
- * Returns: the name of the event.
+ * Returns: The name of the event.
*/
const char*
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).
+ * Returns: The @add' method for the event (a MonoMethod).
*/
MonoMethod*
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).
+ * Returns: The @remove method for the event (a MonoMethod).
*/
MonoMethod*
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).
+ * Returns: The @raise method for the event (a MonoMethod).
*/
MonoMethod*
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.
+ * Returns: The MonoClass where the event is defined.
*/
MonoClass*
mono_event_get_parent (MonoEvent *event)
* The metadata flags for an event are encoded using the
* EVENT_* constants. See the tabledefs.h file for details.
*
- * Returns: the flags for the event.
+ * Returns: The flags for the event.
*/
guint32
mono_event_get_flags (MonoEvent *event)
gboolean
mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data)
{
- if (klass->exception_type)
+ if (mono_class_has_failure (klass))
return FALSE;
mono_loader_lock ();
{
gpointer exception_data = mono_class_get_exception_data (klass);
- switch (klass->exception_type) {
+ switch (mono_class_get_failure(klass)) {
case MONO_EXCEPTION_TYPE_LOAD: {
MonoString *name;
MonoException *ex;
case MONO_EXCEPTION_BAD_IMAGE: {
return mono_get_exception_bad_image_format ((const char *)exception_data);
}
+ case MONO_EXCEPTION_INVALID_PROGRAM: {
+ return mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", "");
+ }
default: {
MonoLoaderError *error;
MonoException *ex;
return FALSE;
}
+/**
+ * mono_method_can_access_field:
+ * @method: Method that will attempt to access the field
+ * @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
+ * the accessibility rules of the CLI.
+ */
gboolean
mono_method_can_access_field (MonoMethod *method, MonoClassField *field)
{
return can;
}
+/**
+ * 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.
+ *
+ * Used to determine if the @method is allowed to access the specified @called method.
+ *
+ * Returns: TRUE if the given @method is allowed to invoke the @called while following
+ * the accessibility rules of the CLI.
+ */
gboolean
mono_method_can_access_method (MonoMethod *method, MonoMethod *called)
{
if (!mono_error_ok (error)) {
char *err_msg = g_strdup_printf ("Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
- g_free (err_msg);
}
field->type = mono_class_inflate_generic_type_no_copy (image, gtype, mono_class_get_context (klass), error);
if (!mono_error_ok (error)) {
char *err_msg = g_strdup_printf ("Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
- g_free (err_msg);
}
} else {
const char *sig;
mono_metadata_decode_table_row (image, MONO_TABLE_FIELD, idx, cols, MONO_FIELD_SIZE);
if (!mono_verifier_verify_field_signature (image, cols [MONO_FIELD_SIGNATURE], NULL)) {
- mono_error_set_type_load_class (error, klass, "Could not verify field %s signature", field->name);
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_error_set_type_load_class (error, klass, "Could not verify field %s signature", field->name);;
+ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, g_strdup (mono_error_get_message (error)));
return;
}
mono_metadata_decode_value (sig, &sig);
/* FIELD signature == 0x06 */
g_assert (*sig == 0x06);
- field->type = mono_metadata_parse_type_full (image, container, cols [MONO_FIELD_FLAGS], sig + 1, &sig);
- if (!field->type)
- mono_class_set_failure_from_loader_error (klass, error, g_strdup_printf ("Could not load field %s type", field->name));
+
+ field->type = mono_metadata_parse_type_checked (image, container, cols [MONO_FIELD_FLAGS], FALSE, sig + 1, &sig, error);
+ if (!field->type) {
+ char *err_msg = g_strdup_printf ("Could not load field %d type due to: %s", field_idx, mono_error_get_message (error));
+ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+ }
}
}
return mono_type_full_name (&klass->byval_arg);
}
+/* Declare all shared lazy type lookup functions */
+GENERATE_TRY_GET_CLASS_WITH_CACHE (safehandle, System.Runtime.InteropServices, SafeHandle)