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;
}
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)
int i, blittable = TRUE;
guint32 real_size = 0;
guint32 packing_size = 0;
+ int instance_size;
gboolean explicit_size;
MonoClassField *field;
MonoGenericContainer *container = NULL;
}
}
- klass->instance_size = 0;
+ instance_size = 0;
if (!klass->rank)
klass->sizes.class_size = 0;
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;
return;
}
if (explicit_size && real_size) {
- klass->instance_size = MAX (real_size, klass->instance_size);
+ instance_size = MAX (real_size, instance_size);
}
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:
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;
static void
mono_class_setup_vtable_full (MonoClass *klass, GList *in_setup)
{
+ MonoError error;
MonoMethod **overrides;
MonoGenericContext *context;
guint32 type_token;
* 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. */
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
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");
{
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;
}
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;
}
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);
}
/* 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)) {
gpointer
mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context)
{
+ MonoError error;
MonoClass *handle_class;
- return lookup_dynamic (image, token, TRUE, &handle_class, context);
+ gpointer result = lookup_dynamic (image, token, TRUE, &handle_class, context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return result;
+
}
gpointer
mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context)
{
- return lookup_dynamic (image, token, valid_token, handle_class, context);
+ MonoError error;
+ gpointer result = lookup_dynamic (image, token, valid_token, handle_class, context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return result;
+
}
static MonoGetCachedClassInfo get_cached_class_info = NULL;
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;