[runtime] Move MonoClass::generic_class to MonoClassGenericInst.
[mono.git] / mono / metadata / sre.c
index 2bd9121b9ebf7b54489782ddab54ddcd98f01b5d..9d0c6f86af68015210b4b5be1a8236e3ae12fa17 100644 (file)
@@ -96,7 +96,7 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass)
                return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
        ta = klass->image->assembly;
        if (assembly_is_dynamic (ta) || (ta == ass)) {
-               if (klass->generic_class || klass->generic_container)
+               if (mono_class_is_ginst (klass) || klass->generic_container)
                        /* For generic type definitions, we want T, while REFLECTION returns T<K> */
                        return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
                else
@@ -704,7 +704,7 @@ mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 origina
 static gboolean
 is_field_on_inst (MonoClassField *field)
 {
-       return field->parent->generic_class && field->parent->generic_class->is_dynamic;
+       return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic;
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
@@ -721,9 +721,9 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoCl
        if (token)
                return token;
 
-       if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
+       if (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) {
                int index = field - field->parent->fields;
-               type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]);
+               type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]);
        } else {
                type = mono_field_get_type (field);
        }
@@ -1148,7 +1148,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                        else
                                token = mono_image_get_inflated_method_token (assembly, m->method);
                } else if ((m->method->klass->image == &assembly->image) &&
-                        !m->method->klass->generic_class) {
+                        !mono_class_is_ginst (m->method->klass)) {
                        static guint32 method_table_idx = 0xffffff;
                        if (m->method->klass->wastypebuilder) {
                                /* we use the same token as the one that was assigned
@@ -2298,7 +2298,8 @@ reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error
                return TRUE;
        }
 
-       klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));
+       klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd)));
+       klass->class_kind = MONO_CLASS_DEF;
 
        klass->image = &tb->module->dynamic_image->image;
 
@@ -2416,7 +2417,7 @@ reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error
        klass->generic_container->type_argc = count;
        klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
 
-       klass->is_generic = 1;
+       klass->class_kind = MONO_CLASS_GTD;
 
        for (i = 0; i < count; i++) {
                MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
@@ -2573,7 +2574,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        image = dynamic ? NULL : klass->image;
 
        if (!dynamic)
-               g_assert (!klass->generic_class);
+               g_assert (!mono_class_is_ginst (klass));
 
        mono_loader_lock ();
 
@@ -2702,6 +2703,9 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        container->type_params [i].param.owner = container;
 
                        gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i];
+
+                       MonoClass *gklass = mono_class_from_mono_type (gp_type);
+                       gklass->wastypebuilder = TRUE;
                }
 
                /*
@@ -2900,7 +2904,7 @@ methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb,
 static gboolean
 fix_partial_generic_class (MonoClass *klass, MonoError *error)
 {
-       MonoClass *gklass = klass->generic_class->container_class;
+       MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
        int i;
 
        mono_error_init (error);
@@ -2909,7 +2913,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error)
                return TRUE;
 
        if (klass->parent != gklass->parent) {
-               MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error);
+               MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error);
                if (mono_error_ok (error)) {
                        MonoClass *parent = mono_class_from_mono_type (parent_type);
                        mono_metadata_free_type (parent_type);
@@ -2925,7 +2929,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error)
                }
        }
 
-       if (!klass->generic_class->need_sync)
+       if (!mono_class_get_generic_class (klass)->need_sync)
                return TRUE;
 
        if (klass->method.count != gklass->method.count) {
@@ -2986,7 +2990,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error)
 static gboolean
 ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error)
 {
-       MonoClass *gklass = klass->generic_class->container_class;
+       MonoClass *gklass = mono_class_get_generic_class (klass)->container_class;
 
        mono_error_init (error);
 
@@ -3012,7 +3016,7 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error)
 
        mono_error_init (error);
 
-       if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder)
+       if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder)
                return TRUE;
        if (klass->parent)
                if (!ensure_runtime_vtable (klass->parent, error))
@@ -3051,9 +3055,9 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error)
                        }
                        klass->interfaces_inited = 1;
                }
-       } else if (klass->generic_class){
+       } else if (mono_class_is_ginst (klass)){
                if (!ensure_generic_class_runtime_vtable (klass, error)) {
-                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+                       mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error));
                        return FALSE;
                }
        }
@@ -3167,6 +3171,7 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
        *num_overrides = onum;
 }
 
+/* This initializes the same data as mono_class_setup_fields () */
 static void
 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
 {
@@ -3175,8 +3180,16 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        MonoClassField *field;
        MonoImage *image = klass->image;
        const char *p, *p2;
-       int i;
-       guint32 len, idx, real_size = 0;
+       int i, instance_size, packing_size = 0;
+       guint32 len, idx;
+
+       if (klass->parent) {
+               if (!klass->parent->size_inited)
+                       mono_class_init (klass->parent);
+               instance_size = klass->parent->instance_size;
+       } else {
+               instance_size = sizeof (MonoObject);
+       }
 
        klass->field.count = tb->num_fields;
        klass->field.first = 0;
@@ -3184,18 +3197,8 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        mono_error_init (error);
 
        if (tb->class_size) {
-               if ((tb->packing_size & 0xffffff00) != 0) {
-                       char *err_msg = mono_image_strdup_printf (klass->image, "Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size);
-                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
-                       return;
-               }
-               klass->packing_size = tb->packing_size;
-               real_size = klass->instance_size + tb->class_size;
-       }
-
-       if (!klass->field.count) {
-               klass->instance_size = MAX (klass->instance_size, real_size);
-               return;
+               packing_size = tb->packing_size;
+               instance_size += tb->class_size;
        }
        
        klass->fields = image_g_new0 (image, MonoClassField, klass->field.count);
@@ -3214,6 +3217,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                MonoArray *rva_data;
                fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i);
                field = &klass->fields [i];
+               field->parent = klass;
                field->name = mono_string_to_utf8_image (image, fb->name, error);
                if (!mono_error_ok (error))
                        return;
@@ -3236,13 +3240,9 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                }
                if (fb->offset != -1)
                        field->offset = fb->offset;
-               field->parent = klass;
                fb->handle = field;
                mono_save_custom_attrs (klass->image, field, fb->cattrs);
 
-               if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
-                       klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
-               }
                if (fb->def_value) {
                        MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
                        field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
@@ -3256,8 +3256,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                }
        }
 
-       klass->instance_size = MAX (klass->instance_size, real_size);
-       mono_class_layout_fields (klass, klass->instance_size);
+       mono_class_layout_fields (klass, instance_size, packing_size, TRUE);
 }
 
 static void
@@ -3381,7 +3380,7 @@ remove_instantiations_of_and_ensure_contents (gpointer key,
                MonoClass *inst_klass = mono_class_from_mono_type (type);
                //Ensure it's safe to use it.
                if (!fix_partial_generic_class (inst_klass, error)) {
-                       mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+                       mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error));
                        // Marked the class with failure, but since some other instantiation already failed,
                        // just report that one, and swallow the error from this one.
                        if (already_failed)
@@ -3462,23 +3461,6 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
 
        klass->nested_classes_inited = TRUE;
 
-       /* fields and object layout */
-       if (klass->parent) {
-               if (!klass->parent->size_inited)
-                       mono_class_init (klass->parent);
-               klass->instance_size = klass->parent->instance_size;
-               klass->sizes.class_size = 0;
-               klass->min_align = klass->parent->min_align;
-               /* if the type has no fields we won't call the field_setup
-                * routine which sets up klass->has_references.
-                */
-               klass->has_references |= klass->parent->has_references;
-       } else {
-               klass->instance_size = sizeof (MonoObject);
-               klass->min_align = 1;
-       }
-
-       /* FIXME: handle packing_size and instance_size */
        typebuilder_setup_fields (klass, &error);
        if (!mono_error_ok (&error))
                goto failure;
@@ -3492,6 +3474,16 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
 
        klass->wastypebuilder = TRUE;
 
+       if (tb->generic_params) {
+               for (i = 0; i < mono_array_length (tb->generic_params); i++) {
+                       MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i);
+                       MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, &error);
+                       MonoClass *gklass = mono_class_from_mono_type (param_type);
+
+                       gklass->wastypebuilder = TRUE;
+               }
+       }
+
        /* 
         * If we are a generic TypeBuilder, there might be instantiations in the type cache
         * which have type System.Reflection.MonoGenericClass, but after the type is created, 
@@ -3513,7 +3505,7 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
        mono_loader_unlock ();
 
        if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
-               mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+               mono_class_set_type_load_failure (klass, "Not a valid enumeration");
                mono_error_set_type_load_class (&error, klass, "Not a valid enumeration");
                goto failure_unlocked;
        }
@@ -3527,7 +3519,7 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb)
        return res;
 
 failure:
-       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+       mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (&error));
        klass->wastypebuilder = TRUE;
        mono_domain_unlock (domain);
        mono_loader_unlock ();
@@ -3750,8 +3742,8 @@ ensure_complete_type (MonoClass *klass, MonoError *error)
                //g_assert (klass->wastypebuilder);
        }
 
-       if (klass->generic_class) {
-               MonoGenericInst *inst = klass->generic_class->context.class_inst;
+       if (mono_class_is_ginst (klass)) {
+               MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
                int i;
 
                for (i = 0; i < inst->type_argc; ++i) {