We may get called to create the parent of a dynamic generic instance; in this
[mono.git] / mono / metadata / reflection.c
index f0a95f1b5f52a112d2f449baf0358bcb2db2862f..91061a8a32f2a03794637fde8786e4d289ccac07 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * reflection.c: Routines for creating an image at runtime.
  * 
@@ -138,6 +137,9 @@ static guint32 encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMa
 static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
 static void    ensure_runtime_vtable (MonoClass *klass);
 static gpointer resolve_object (MonoImage *image, MonoObject *obj);
+static void    encode_type (MonoDynamicImage *assembly, MonoType *type, char *p, char **endbuf);
+static guint32 type_get_signature_size (MonoType *type);
+
 
 static void
 alloc_table (MonoDynamicTable *table, guint nrows)
@@ -396,6 +398,25 @@ my_mono_class_from_mono_type (MonoType *type) {
        }
 }
 
+static void
+encode_generic_inst (MonoDynamicImage *assembly, MonoGenericInst *ginst, char *p, char **endbuf)
+{
+       int i;
+
+       if (!ginst) {
+               g_assert_not_reached ();
+               return;
+       }
+
+       mono_metadata_encode_value (MONO_TYPE_GENERICINST, p, &p);
+       encode_type (assembly, ginst->generic_type, p, &p);
+       mono_metadata_encode_value (ginst->type_argc, p, &p);
+       for (i = 0; i < ginst->type_argc; ++i)
+               encode_type (assembly, ginst->type_argv [i], p, &p);
+
+       *endbuf = p;
+}
+
 static void
 encode_type (MonoDynamicImage *assembly, MonoType *type, char *p, char **endbuf)
 {
@@ -457,16 +478,9 @@ encode_type (MonoDynamicImage *assembly, MonoType *type, char *p, char **endbuf)
                mono_metadata_encode_value (0, p, &p); /* FIXME: set to 0 for now */
                mono_metadata_encode_value (0, p, &p);
                break;
-       case MONO_TYPE_GENERICINST: {
-               int i;
-               mono_metadata_encode_value (type->type, p, &p);
-               encode_type (assembly, type->data.generic_inst->generic_type, p, &p);
-               mono_metadata_encode_value (type->data.generic_inst->type_argc, p, &p);
-               for (i = 0; i < type->data.generic_inst->type_argc; ++i) {
-                       encode_type (assembly, type->data.generic_inst->type_argv [i], p, &p);
-               }
+       case MONO_TYPE_GENERICINST:
+               encode_generic_inst (assembly, type->data.generic_inst, p, &p);
                break;
-       }
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                mono_metadata_encode_value (type->type, p, &p);
@@ -519,6 +533,95 @@ encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArra
        *endbuf = p;
 }
 
+static guint32
+generic_inst_get_signature_size (MonoGenericInst *ginst)
+{
+       guint32 size = 0;
+       int i;
+
+       if (!ginst) {
+               g_assert_not_reached ();
+       }
+
+       size += 1 + type_get_signature_size (ginst->generic_type);
+       size += 4;
+       for (i = 0; i < ginst->type_argc; ++i)
+               size += type_get_signature_size (ginst->type_argv [i]);
+
+       return size;
+}
+
+static guint32
+type_get_signature_size (MonoType *type)
+{
+       guint32 size = 0;
+
+       if (!type) {
+               g_assert_not_reached ();
+       }
+               
+       if (type->byref)
+               size++;
+
+       switch (type->type){
+       case MONO_TYPE_VOID:
+       case MONO_TYPE_BOOLEAN:
+       case MONO_TYPE_CHAR:
+       case MONO_TYPE_I1:
+       case MONO_TYPE_U1:
+       case MONO_TYPE_I2:
+       case MONO_TYPE_U2:
+       case MONO_TYPE_I4:
+       case MONO_TYPE_U4:
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+       case MONO_TYPE_R4:
+       case MONO_TYPE_R8:
+       case MONO_TYPE_I:
+       case MONO_TYPE_U:
+       case MONO_TYPE_STRING:
+       case MONO_TYPE_OBJECT:
+       case MONO_TYPE_TYPEDBYREF:
+               return size + 1;
+       case MONO_TYPE_PTR:
+               return size + 1 + type_get_signature_size (type->data.type);
+       case MONO_TYPE_SZARRAY:
+               return size + 1 + type_get_signature_size (&type->data.klass->byval_arg);
+
+       case MONO_TYPE_VALUETYPE:
+       case MONO_TYPE_CLASS:
+               return size + 5;
+
+       case MONO_TYPE_ARRAY:
+               return size + 7 + type_get_signature_size (&type->data.array->eklass->byval_arg);
+       case MONO_TYPE_GENERICINST:
+               return size + generic_inst_get_signature_size (type->data.generic_inst);
+       case MONO_TYPE_VAR:
+       case MONO_TYPE_MVAR:
+               return size + 5;
+
+       default:
+               g_error ("need to encode type %x", type->type);
+               return size;
+       }
+}
+
+static guint32
+method_get_signature_size (MonoMethodSignature *sig)
+{
+       guint32 size;
+       int i;
+
+       size = type_get_signature_size (sig->ret);
+       for (i = 0; i < sig->param_count; i++)
+               size += type_get_signature_size (sig->params [i]);
+
+       if (sig->generic_param_count)
+               size += 4;
+
+       return size;    
+}
+
 static guint32
 method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
 {
@@ -526,7 +629,7 @@ method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
        char *p;
        int i;
        guint32 nparams =  sig->param_count;
-       guint32 size = 10 + nparams * 10;
+       guint32 size = 11 + method_get_signature_size (sig);
        guint32 idx;
        char blob_size [6];
        char *b = blob_size;
@@ -747,8 +850,14 @@ method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
                        num_exception = method_count_clauses (mb->ilgen);
        } else {
                code = mb->code;
-               if (code == NULL)
-                       mono_raise_exception (mono_get_exception_argument (NULL, "a method does not have any IL associated"));
+               if (code == NULL){
+                       char *name = mono_string_to_utf8 (mb->name);
+                       char *str = g_strdup_printf ("Method %s does not have any IL associated", name);
+                       MonoException *exception = mono_get_exception_argument (NULL, "a method does not have any IL associated");
+                       g_free (str);
+                       g_free (name);
+                       mono_raise_exception (exception);
+               }
 
                code_size = mono_array_length (code);
                max_stack = 8; /* we probably need to run a verifier on the code... */
@@ -1259,6 +1368,38 @@ mono_image_get_ctor_info (MonoDomain *domain, MonoReflectionCtorBuilder *mb, Mon
        mono_image_basic_method (&rmb, assembly);
 }
 
+static char*
+type_get_fully_qualified_name (MonoType *type) {
+       char *name, *result;
+       MonoClass *klass;
+       MonoAssembly *ta;
+
+       name = mono_type_get_name (type);
+       klass = my_mono_class_from_mono_type (type);
+       ta = klass->image->assembly;
+
+       /* missing public key */
+       result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s",
+               name, ta->aname.name,
+               ta->aname.major, ta->aname.minor, ta->aname.build, ta->aname.revision,
+               ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral");
+       g_free (name);
+       return result;
+}
+
+static char*
+type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
+       MonoClass *klass;
+       MonoAssembly *ta;
+
+       klass = my_mono_class_from_mono_type (type);
+       ta = klass->image->assembly;
+       if (ta == ass || klass->image == mono_defaults.corlib)
+               return mono_type_get_name (type);
+
+       return type_get_fully_qualified_name (type);
+}
+
 static guint32
 fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
 {
@@ -1436,7 +1577,7 @@ encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
                        mono_metadata_encode_value (0, p, &p);
                }
                if (minfo->marshaltyperef) {
-                       str = type_get_qualified_name (minfo->marshaltyperef->type, assembly->image.assembly);
+                       str = type_get_fully_qualified_name (minfo->marshaltyperef->type);
                        len = strlen (str);
                        mono_metadata_encode_value (len, p, &p);
                        if (p + len >= buf + bufsize) {
@@ -1518,7 +1659,7 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *ass
                values [MONO_CONSTANT_TYPE] = field_type;
                values [MONO_CONSTANT_PADDING] = 0;
        }
-       if (fb->rva_data) {
+       if (fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) {
                guint32 rva_idx;
                table = &assembly->tables [MONO_TABLE_FIELDRVA];
                table->rows ++;
@@ -1528,7 +1669,10 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *ass
                /*
                 * We store it in the code section because it's simpler for now.
                 */
-               rva_idx = mono_image_add_stream_data (&assembly->code, mono_array_addr (fb->rva_data, char, 0), mono_array_length (fb->rva_data));
+               if (fb->rva_data)
+                       rva_idx = mono_image_add_stream_data (&assembly->code, mono_array_addr (fb->rva_data, char, 0), mono_array_length (fb->rva_data));
+               else
+                       rva_idx = mono_image_add_stream_zero (&assembly->code, mono_class_value_size (fb->handle->parent, NULL));
                values [MONO_FIELD_RVA_RVA] = rva_idx + assembly->text_rva;
        }
        if (fb->marshal_info) {
@@ -1881,7 +2025,7 @@ create_typespec (MonoDynamicImage *assembly, MonoType *type)
                MonoClass *k = mono_class_from_mono_type (type);
                if (!k || !k->generic_inst)
                        return 0;
-               encode_type (assembly, k->generic_inst, p, &p);
+               encode_generic_inst (assembly, k->generic_inst, p, &p);
                break;
        }
        default:
@@ -2060,55 +2204,29 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor
 }
 
 static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field, MonoClass *klass)
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *f)
 {
+       MonoType *type;
        guint32 token;
-       
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
-       if (token)
-               return token;
-       field->parent = klass;
-       token = mono_image_get_memberref_token (assembly, &klass->byval_arg, 
-               field->name,  fieldref_encode_signature (assembly, field->type));
-       g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
-       return token;
-}
-
-static guint32
-field_encode_inflated_field (MonoDynamicImage *assembly, MonoReflectionInflatedField *field)
-{
-       guint32 sig, token;
-       MonoClass *klass;
-       const gchar *name;
-
-       klass = field->rfield.klass;
-       name = field->rfield.field->name;
-       sig = fieldref_encode_signature (assembly, field->declaring->type);
-       token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
 
-       return token;
-}
-
-static guint32
-mono_image_get_inflated_field_token (MonoDynamicImage *assembly, MonoReflectionInflatedField *field)
-{
-       guint32 token;
-       
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field->rfield.field));
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
        if (token)
                return token;
-       token = field_encode_inflated_field (assembly, field);
-       g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
+       g_assert (f->field->parent);
+       type = f->field->generic_type ? f->field->generic_type : f->field->type;
+       token = mono_image_get_memberref_token (assembly, &f->klass->byval_arg, 
+               f->field->name,  fieldref_encode_signature (assembly, type));
+       g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
        return token;
 }
 
 static guint32
-encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericInst *ginst)
+encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericMethod *gmethod)
 {
        char *buf;
        char *p;
        int i;
-       guint32 nparams =  ginst->type_argc;
+       guint32 nparams =  gmethod->mtype_argc;
        guint32 size = 10 + nparams * 10;
        guint32 idx;
        char blob_size [6];
@@ -2125,7 +2243,7 @@ encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericInst *ginst)
        mono_metadata_encode_value (nparams, p, &p);
 
        for (i = 0; i < nparams; i++)
-               encode_type (assembly, ginst->type_argv [i], p, &p);
+               encode_type (assembly, gmethod->mtype_argv [i], p, &p);
 
        /* store length */
        g_assert (p - buf < size);
@@ -2136,27 +2254,26 @@ encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericInst *ginst)
 }
 
 static guint32
-method_encode_methodspec (MonoDynamicImage *assembly, MonoGenericInst *ginst)
+method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
 {
        MonoDynamicTable *table;
        guint32 *values;
        guint32 token, mtoken = 0, sig;
+       MonoMethodInflated *imethod;
+       MonoMethod *declaring;
 
        table = &assembly->tables [MONO_TABLE_METHODSPEC];
 
-       g_assert (ginst);
-       if (ginst->generic_method) {
-               MonoMethod *gm = ginst->generic_method;
-               MonoClass *k = ginst->klass ? ginst->klass : gm->klass;
+       g_assert (method->signature->is_inflated);
+       imethod = (MonoMethodInflated *) method;
+       declaring = imethod->declaring;
 
-               sig = method_encode_signature (assembly, gm->signature);
-               mtoken = mono_image_get_memberref_token (assembly, &k->byval_arg, gm->name, sig);
+       sig = method_encode_signature (assembly, declaring->signature);
+       mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
+                                                declaring->name, sig);
 
-               if (!ginst->generic_method->signature->generic_param_count)
-                       return mtoken;
-       }
-       else
-               g_assert_not_reached ();
+       if (!declaring->signature->generic_param_count)
+               return mtoken;
 
        switch (mono_metadata_token_table (mtoken)) {
        case MONO_TABLE_MEMBERREF:
@@ -2169,7 +2286,7 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoGenericInst *ginst)
                g_assert_not_reached ();
        }
 
-       sig = encode_generic_method_sig (assembly, ginst);
+       sig = encode_generic_method_sig (assembly, imethod->context->gmethod);
 
        if (assembly->save) {
                alloc_table (table, table->rows + 1);
@@ -2185,15 +2302,28 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoGenericInst *ginst)
 }
 
 static guint32
-mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method, MonoGenericInst *ginst)
+mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *m)
 {
+       MonoMethodInflated *imethod;
        guint32 token;
        
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m));
        if (token)
                return token;
-       token = method_encode_methodspec (assembly, ginst);
-       g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
+
+       g_assert (m->signature->is_inflated);
+       imethod = (MonoMethodInflated *) m;
+
+       if (imethod->declaring->signature->generic_param_count)
+               token = method_encode_methodspec (assembly, m);
+       else {
+               guint32 sig = method_encode_signature (
+                       assembly, imethod->declaring->signature);
+               token = mono_image_get_memberref_token (
+                       assembly, &m->klass->byval_arg, m->name, sig);
+       }
+
+       g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -2552,6 +2682,11 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
                        mono_image_get_property_info (
                                mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly);
        }
+
+       mono_image_add_decl_security (assembly, 
+                                                                 mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx),
+                                                                 tb->permissions);
+
        if (tb->subtypes) {
                MonoDynamicTable *ntable;
                
@@ -3134,12 +3269,12 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse
                                MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
                                g_assert (m->klass->generic_inst);
                                continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoInflatedMethod") ||
-                                  !strcmp (iltoken->member->vtable->klass->name, "MonoInflatedCtor") ||
-                                  !strcmp (iltoken->member->vtable->klass->name, "MonoInflatedField")) {
-                               continue;
                        } else if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
                                continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
+                               MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
+                               g_assert (f->generic_type);
+                               continue;
                        } else {
                                g_assert_not_reached ();
                        }
@@ -3149,9 +3284,6 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse
                                MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
                                g_assert (m->signature->generic_param_count);
                                continue;
-                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoInflatedMethod") ||
-                                  !strcmp (iltoken->member->vtable->klass->name, "MonoInflatedCtor")) {
-                               continue;
                        } else {
                                g_assert_not_reached ();
                        }
@@ -3165,6 +3297,41 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse
        }
 }
 
+/*
+ * fixup_cattrs:
+ *
+ *   The CUSTOM_ATTRIBUTE table might contain METHODDEF tokens whose final
+ * value is not known when the table is emitted.
+ */
+static void
+fixup_cattrs (MonoDynamicImage *assembly)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 type, i, idx, token;
+       MonoObject *ctor;
+
+       table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+
+       for (i = 0; i < table->rows; ++i) {
+               values = table->values + ((i + 1) * MONO_CUSTOM_ATTR_SIZE);
+
+               type = values [MONO_CUSTOM_ATTR_TYPE];
+               if ((type & CUSTOM_ATTR_TYPE_MASK) == CUSTOM_ATTR_TYPE_METHODDEF) {
+                       idx = type >> CUSTOM_ATTR_TYPE_BITS;
+                       token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
+                       ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
+                       g_assert (ctor);
+
+                       if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
+                               MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
+                               idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, m));
+                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << CUSTOM_ATTR_TYPE_BITS) | CUSTOM_ATTR_TYPE_METHODDEF;
+                       }
+               }
+       }
+}
+
 static void
 assembly_add_resource_manifest (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, guint32 implementation)
 {
@@ -3474,6 +3641,7 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
 
        /* fixup tokens */
        mono_g_hash_table_foreach (assembly->token_fixups, (GHFunc)fixup_method, assembly);
+       fixup_cattrs (assembly);
 }
 
 /*
@@ -3584,12 +3752,18 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
                token = mono_metadata_token_from_dor (
                        mono_image_typedef_or_ref (assembly, tb->type));
        }
+       else if (strcmp (klass->name, "MonoGenericInst") == 0) {
+               MonoReflectionType *tb = (MonoReflectionType *)obj;
+               token = mono_metadata_token_from_dor (
+                       mono_image_typedef_or_ref (assembly, tb->type));
+       }
        else if (strcmp (klass->name, "MonoCMethod") == 0 ||
                        strcmp (klass->name, "MonoMethod") == 0) {
                MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
-               if (m->method->signature->generic_param_count) {
+               if (m->method->signature->is_inflated) {
+                       token = mono_image_get_methodspec_token (assembly, m->method);
+               } else if (m->method->signature->generic_param_count) {
                        g_assert_not_reached ();
-                       token = mono_image_get_methodspec_token (assembly, m->method, NULL);
                } else if ((m->method->klass->image == &assembly->image) &&
                         !m->method->klass->generic_inst) {
                        static guint32 method_table_idx = 0xffffff;
@@ -3604,23 +3778,14 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
                        token = mono_image_get_methodref_token (assembly, m->method);
                /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
        }
-       else if (strcmp (klass->name, "MonoInflatedMethod") == 0 ||
-                strcmp (klass->name, "MonoInflatedCtor") == 0) {
-               MonoReflectionInflatedMethod *m = (MonoReflectionInflatedMethod *)obj;
-               token = mono_image_get_methodspec_token (assembly, m->rmethod.method, m->ginst);
-       }
-       else if (strcmp (klass->name, "MonoInflatedField") == 0) {
-               MonoReflectionInflatedField *f = (MonoReflectionInflatedField *)obj;
-               token = mono_image_get_inflated_field_token (assembly, f);
-       }
        else if (strcmp (klass->name, "MonoField") == 0) {
                MonoReflectionField *f = (MonoReflectionField *)obj;
-               if (f->klass->image == &assembly->image) {
+               if ((f->klass->image == &assembly->image) && !f->field->generic_type) {
                        static guint32 field_table_idx = 0xffffff;
                        field_table_idx --;
                        token = MONO_TOKEN_FIELD_DEF | field_table_idx;
                } else
-                       token = mono_image_get_fieldref_token (assembly, f->field, f->klass);
+                       token = mono_image_get_fieldref_token (assembly, f);
                /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
        }
        else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
@@ -4244,8 +4409,16 @@ mono_image_create_pefile (MonoReflectionModuleBuilder *mb) {
        cli_header->ch_size = GUINT32_FROM_LE (72);
        cli_header->ch_runtime_major = GUINT16_FROM_LE (2);
        cli_header->ch_flags = GUINT32_FROM_LE (CLI_FLAGS_ILONLY);
-       if (assemblyb->entry_point) 
-               cli_header->ch_entry_point = GUINT32_FROM_LE (assemblyb->entry_point->table_idx | MONO_TOKEN_METHOD_DEF);
+       if (assemblyb->entry_point) {
+               guint32 table_idx = 0;
+               if (!strcmp (assemblyb->entry_point->object.vtable->klass->name, "MethodBuilder")) {
+                       MonoReflectionMethodBuilder *methodb = (MonoReflectionMethodBuilder*)assemblyb->entry_point;
+                       table_idx = methodb->table_idx;
+               }
+               else
+                       table_idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, assemblyb->entry_point->method));
+               cli_header->ch_entry_point = GUINT32_FROM_LE (table_idx | MONO_TOKEN_METHOD_DEF);
+       }                       
        else
                cli_header->ch_entry_point = GUINT32_FROM_LE (0);
        /* The embedded managed resources */
@@ -4638,6 +4811,36 @@ mymono_metadata_type_hash (MonoType *t1)
        return hash;
 }
 
+static MonoReflectionGenericInst*
+mono_generic_inst_get_object (MonoDomain *domain, MonoType *geninst)
+{
+       static MonoClass *System_Reflection_MonoGenericInst;
+       MonoReflectionGenericInst *res;
+       MonoGenericInst *ginst;
+       MonoClass *gklass;
+
+       if (!System_Reflection_MonoGenericInst) {
+               System_Reflection_MonoGenericInst = mono_class_from_name (
+                       mono_defaults.corlib, "System.Reflection", "MonoGenericInst");
+               g_assert (System_Reflection_MonoGenericInst);
+       }
+
+       ginst = geninst->data.generic_inst;
+       gklass = mono_class_from_mono_type (ginst->generic_type);
+
+       mono_class_init (ginst->klass);
+
+       res = (MonoReflectionGenericInst *) mono_object_new (domain, System_Reflection_MonoGenericInst);
+
+       res->type.type = geninst;
+       if (gklass->wastypebuilder && gklass->reflection_info)
+               res->generic_type = gklass->reflection_info;
+       else
+               res->generic_type = mono_type_get_object (domain, ginst->generic_type);
+
+       return res;
+}
+
 /*
  * mono_type_get_object:
  * @domain: an app domain
@@ -4659,6 +4862,12 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                mono_domain_unlock (domain);
                return res;
        }
+       if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_inst->is_dynamic) {
+               res = (MonoReflectionType *)mono_generic_inst_get_object (domain, type);
+               mono_g_hash_table_insert (domain->type_hash, type, res);
+               mono_domain_unlock (domain);
+               return res;
+       }
        if (klass->reflection_info && !klass->wastypebuilder) {
                //g_assert_not_reached ();
                /* should this be considered an error condition? */
@@ -5498,10 +5707,17 @@ create_custom_attr (MonoImage *image, MonoMethod *method,
        MonoObject *attr;
        void **params;
 
+       mono_class_init (method->klass);
+
+       if (len == 0) {
+               attr = mono_object_new (mono_domain_get (), method->klass);
+               mono_runtime_invoke (method, attr, NULL, NULL);
+               return attr;
+       }
+
        if (len < 2 || read16 (p) != 0x0001) /* Prolog */
                return NULL;
 
-       mono_class_init (method->klass);
        /*g_print ("got attr %s\n", method->klass->name);*/
        
        params = g_new (void*, method->signature->param_count);
@@ -5681,7 +5897,7 @@ mono_custom_attrs_from_assembly (MonoAssembly *assembly)
        return mono_custom_attrs_from_index (assembly->image, idx);
 }
 
-MonoCustomAttrInfo*
+static MonoCustomAttrInfo*
 mono_custom_attrs_from_module (MonoImage *image)
 {
        MonoCustomAttrInfo *cinfo;
@@ -5744,10 +5960,15 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
        guint32 i, idx, method_index;
        guint32 param_list, param_last, param_pos, found;
        MonoImage *image;
-       
-       /* FIXME: handle dynamic custom attrs for parameters */
-       /*if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, field)))
-               return cinfo;*/
+       MonoReflectionMethodAux *aux;
+
+       if (method->klass->image->dynamic) {
+               aux = mono_g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+               if (!aux || !aux->param_cattr)
+                       return NULL;
+               return aux->param_cattr [param];
+       }
+
        image = method->klass->image;
        method_index = find_method_index (method);
        ca = &image->tables [MONO_TABLE_METHOD];
@@ -5812,13 +6033,13 @@ mono_reflection_get_custom_attrs (MonoObject *obj)
                cinfo = mono_custom_attrs_from_module (module->image);
        } else if (strcmp ("MonoProperty", klass->name) == 0) {
                MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
-               cinfo = mono_custom_attrs_from_property (rprop->klass, rprop->property);
+               cinfo = mono_custom_attrs_from_property (rprop->property->parent, rprop->property);
        } else if (strcmp ("MonoEvent", klass->name) == 0) {
                MonoReflectionEvent *revent = (MonoReflectionEvent*)obj;
-               cinfo = mono_custom_attrs_from_event (revent->klass, revent->event);
+               cinfo = mono_custom_attrs_from_event (revent->event->parent, revent->event);
        } else if (strcmp ("MonoField", klass->name) == 0) {
                MonoReflectionField *rfield = (MonoReflectionField*)obj;
-               cinfo = mono_custom_attrs_from_field (rfield->klass, rfield->field);
+               cinfo = mono_custom_attrs_from_field (rfield->field->parent, rfield->field);
        } else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
                MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
                cinfo = mono_custom_attrs_from_method (rmethod->method);
@@ -5928,27 +6149,6 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
        }
 }
 
-static char*
-type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
-       char *name, *result;
-       MonoClass *klass;
-       MonoAssembly *ta;
-
-       name = mono_type_get_name (type);
-       klass = my_mono_class_from_mono_type (type);
-       ta = klass->image->assembly;
-       if (ta == ass || klass->image == mono_defaults.corlib)
-               return name;
-
-       /* missing public key */
-       result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s",
-               name, ta->aname.name,
-               ta->aname.major, ta->aname.minor, ta->aname.build, ta->aname.revision,
-               ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral");
-       g_free (name);
-       return result;
-}
-
 static void
 encode_cattr_value (char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg)
 {
@@ -6372,8 +6572,6 @@ mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
                MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i);
                klass->gen_params [i] = *gparam->type.type->data.generic_param;
        }
-
-       ensure_runtime_vtable (klass);
 }
 
 /*
@@ -6438,8 +6636,7 @@ mono_marshal_spec_from_builder (MonoAssembly *assembly,
        case MONO_NATIVE_CUSTOM:
                if (minfo->marshaltyperef)
                        res->data.custom_data.custom_name =
-                               type_get_qualified_name (minfo->marshaltyperef->type, 
-                                                                                assembly);
+                               type_get_fully_qualified_name (minfo->marshaltyperef->type);
                if (minfo->mcookie)
                        res->data.custom_data.cookie = mono_string_to_utf8 (minfo->mcookie);
                break;
@@ -6453,8 +6650,8 @@ mono_marshal_spec_from_builder (MonoAssembly *assembly,
 
 static MonoMethod*
 reflection_methodbuilder_to_mono_method (MonoClass *klass,
-                                                                                ReflectionMethodBuilder *rmb,
-                                                                                MonoMethodSignature *sig)
+                                        ReflectionMethodBuilder *rmb,
+                                        MonoMethodSignature *sig)
 {
        MonoMethod *m;
        MonoMethodNormal *pm;
@@ -6543,8 +6740,20 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                header->num_clauses = num_clauses;
                if (num_clauses) {
                        header->clauses = method_encode_clauses ((MonoDynamicImage*)klass->image,
-                                                                                                        rmb->ilgen,
-                                                                                                        num_clauses);
+                                                                rmb->ilgen,
+                                                                num_clauses);
+               }
+
+               if (rmb->generic_params) {
+                       int count = mono_array_length (rmb->generic_params);
+                       header->gen_params = g_new0 (MonoGenericParam, count);
+                       for (i = 0; i < count; i++) {
+                               MonoReflectionGenericParam *gp =
+                                       mono_array_get (rmb->generic_params,
+                                                       MonoReflectionGenericParam*, i);
+
+                               header->gen_params [i] = *gp->type.type->data.generic_param;
+                       }
                }
 
                pm->header = header;
@@ -6563,15 +6772,20 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        method_aux = NULL;
 
        /* Parameter names */
-       if (rmb->parameters) {
+       if (rmb->pinfo) {
                if (!method_aux)
                        method_aux = g_new0 (MonoReflectionMethodAux, 1);
-               method_aux->param_names = g_new0 (char *, m->signature->param_count);
-               for (i = 0; i < m->signature->param_count; ++i) {
+               method_aux->param_names = g_new0 (char *, m->signature->param_count + 1);
+               for (i = 0; i <= m->signature->param_count; ++i) {
                        MonoReflectionParamBuilder *pb;
-                       if ((pb = mono_array_get (rmb->parameters, MonoReflectionParamBuilder*, i))) {
+                       if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
                                if (pb->name)
                                        method_aux->param_names [i] = mono_string_to_utf8 (pb->name);
+                               if (pb->cattrs) {
+                                       if (!method_aux->param_cattr)
+                                               method_aux->param_cattr = g_new0 (MonoCustomAttrInfo*, m->signature->param_count + 1);
+                                       method_aux->param_cattr [i] = mono_custom_attrs_from_builders (klass->image, pb->cattrs);
+                               }
                        }
                }
        }
@@ -6687,116 +6901,40 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
        return field;
 }
 
-static MonoReflectionInflatedMethod*
-inflated_method_get_object (MonoDomain *domain, MonoMethod *method, MonoReflectionMethod *declaring,
-                           MonoGenericInst *ginst)
-{
-       const char *cname;
-       MonoClass *klass, *refclass;
-       MonoReflectionInflatedMethod *ret;
-
-       refclass = method->klass;
-
-       CHECK_OBJECT (MonoReflectionInflatedMethod *, method, refclass);
-       if (*method->name == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
-               cname = "MonoInflatedCtor";
-       else
-               cname = "MonoInflatedMethod";
-       klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", cname);
-       g_assert (klass);
-
-       ret = (MonoReflectionInflatedMethod*)mono_object_new (domain, klass);
-       ret->rmethod.method = method;
-       ret->rmethod.name = mono_string_new (domain, method->name);
-       ret->rmethod.reftype = mono_type_get_object (domain, &refclass->byval_arg);
-       ret->declaring = declaring;
-       ret->ginst = ginst;
-       CACHE_OBJECT (method, ret, refclass);
-       return ret;
-}
-
-MonoReflectionGenericInst*
-mono_reflection_bind_generic_parameters (MonoReflectionType *type, MonoArray *types)
+static MonoType*
+do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc,
+                                           MonoType **types, MonoType *nested_in)
 {
-       static MonoClass *System_Reflection_MonoGenericInst;
+       MonoClass *klass;
+       MonoReflectionTypeBuilder *tb = NULL;
+       MonoGenericInst *ginst;
        MonoDomain *domain;
        MonoType *geninst;
-       MonoGenericInst *ginst;
-       MonoArray *ifaces = NULL;
-       MonoReflectionType *ptype = NULL;
-       MonoClass *klass, *iklass, *pklass = NULL;
-       MonoReflectionGenericInst *res, *parent = NULL;
-       MonoReflectionTypeBuilder *tb = NULL;
-       int i;
-
-       domain = mono_object_domain (type);
+       int icount, i;
 
        klass = mono_class_from_mono_type (type->type);
-       if (!klass->gen_params && !klass->generic_inst)
+       if (!klass->gen_params && !klass->generic_inst &&
+           !(klass->nested_in && klass->nested_in->gen_params))
                return NULL;
 
-       if (!System_Reflection_MonoGenericInst) {
-               System_Reflection_MonoGenericInst = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "MonoGenericInst");
-               g_assert (System_Reflection_MonoGenericInst);
-       }
-
-       if (klass->wastypebuilder && klass->reflection_info) {
-               tb = klass->reflection_info;
+       mono_loader_lock ();
 
-               ptype = tb->parent;
-               if (ptype)
-                       pklass = mono_class_from_mono_type (ptype->type);
-       } else {
-               pklass = klass->parent;
-               if (pklass)
-                       ptype = mono_type_get_object (domain, &pklass->byval_arg);
-       }
-
-       if (pklass && pklass->generic_inst)
-               parent = mono_reflection_bind_generic_parameters (ptype, types);
-       else if (!pklass) {
-               int icount;
-
-               pklass = mono_defaults.object_class;
-
-               icount = klass->interface_count;
-               ifaces = mono_array_new (domain, System_Reflection_MonoGenericInst, icount);
-
-               for (i = 0; i < icount; i++) {
-                       MonoReflectionGenericInst *iface;
-                       MonoReflectionType *itype;
-
-                       if (tb)
-                               itype = mono_array_get (tb->interfaces, gpointer, i);
-                       else
-                               itype = mono_type_get_object (domain, &klass->interfaces [i]->byval_arg);
-                       iface = mono_reflection_bind_generic_parameters (itype, types);
-
-                       mono_array_set (ifaces, gpointer, i, iface);
-               }
-       }
+       domain = mono_object_domain (type);
 
-       geninst = g_new0 (MonoType, 1);
-       geninst->type = MONO_TYPE_GENERICINST;
-       geninst->data.generic_inst = ginst = g_new0 (MonoGenericInst, 1);
+       ginst = g_new0 (MonoGenericInst, 1);
 
-       if (klass->gen_params) {
-               ginst->type_argc = mono_array_length (types);
-               ginst->type_argv = g_new0 (MonoType *, ginst->type_argc);
+       if (!klass->generic_inst) {
+               ginst->type_argc = type_argc;
+               ginst->type_argv = types;
 
                for (i = 0; i < ginst->type_argc; ++i) {
-                       MonoReflectionType *garg = mono_array_get (types, gpointer, i);
-
-                       ginst->type_argv [i] = garg->type;
-
                        if (!ginst->is_open)
-                               ginst->is_open = mono_class_is_open_constructed_type (garg->type);
+                               ginst->is_open = mono_class_is_open_constructed_type (types [i]);
                }
 
                ginst->generic_type = &klass->byval_arg;
        } else {
-               MonoGenericInst *kginst = klass->generic_inst->data.generic_inst;
+               MonoGenericInst *kginst = klass->generic_inst;
 
                ginst->type_argc = kginst->type_argc;
                ginst->type_argv = g_new0 (MonoType *, ginst->type_argc);
@@ -6804,12 +6942,8 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, MonoArray *ty
                for (i = 0; i < ginst->type_argc; i++) {
                        MonoType *t = kginst->type_argv [i];
 
-                       if (t->type == MONO_TYPE_VAR) {
-                               int num = t->data.generic_param->num;
-                               MonoReflectionType *garg = mono_array_get (types, gpointer, num);
-
-                               t = garg->type;
-                       }
+                       if (t->type == MONO_TYPE_VAR)
+                               t = types [t->data.generic_param->num];
 
                        if (!ginst->is_open)
                                ginst->is_open = mono_class_is_open_constructed_type (t);
@@ -6820,28 +6954,169 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, MonoArray *ty
                ginst->generic_type = kginst->generic_type;
        }
 
-       iklass = mono_class_from_generic (geninst, FALSE);
+       geninst = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
+       if (geninst) {
+               g_free (ginst);
+               mono_loader_unlock ();
+               return geninst;
+       }
 
-       mono_class_setup_parent (iklass, parent ? parent->klass : pklass);
-       mono_class_setup_mono_type (iklass);
+       ginst->context = g_new0 (MonoGenericContext, 1);
+       ginst->context->ginst = ginst;
 
-       res = (MonoReflectionGenericInst *)mono_object_new (domain, System_Reflection_MonoGenericInst);
+       geninst = g_new0 (MonoType, 1);
+       geninst->type = MONO_TYPE_GENERICINST;
+       geninst->data.generic_inst = ginst;
 
-       res->type.type = iklass->generic_inst;
-       res->klass = iklass;
-       res->parent = parent;
-       res->generic_type = type;
-       res->interfaces = ifaces;
+       if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
+               tb = (MonoReflectionTypeBuilder *) type;
 
-       return res;
+               icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
+               ginst->is_dynamic = TRUE;
+       } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericInst")) {
+               MonoReflectionGenericInst *rgi = (MonoReflectionGenericInst *) type;
+               MonoReflectionType *rgt = rgi->generic_type;
+
+               g_assert (!strcmp (((MonoObject *) rgt)->vtable->klass->name, "TypeBuilder"));
+               tb = (MonoReflectionTypeBuilder *) rgt;
+
+               icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
+               ginst->is_dynamic = TRUE;
+       } else
+               icount = klass->interface_count;
+
+       ginst->ifaces = g_new0 (MonoType *, icount);
+       ginst->count_ifaces = icount;
+
+       for (i = 0; i < icount; i++) {
+               MonoReflectionType *itype;
+
+               if (tb)
+                       itype = mono_array_get (tb->interfaces, MonoReflectionType *, i);
+               else
+                       itype = mono_type_get_object (domain, &klass->interfaces [i]->byval_arg);
+               ginst->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types);
+               if (!ginst->ifaces [i])
+                       ginst->ifaces [i] = itype->type;
+       }
+
+       ginst->nested_in = nested_in;
+
+       mono_class_create_generic (ginst);
+
+       g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst);
+
+       mono_loader_unlock ();
+
+       return geninst;
+}
+
+MonoType*
+mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
+{
+       MonoClass *klass, *pklass = NULL, *oklass = NULL;
+       MonoReflectionType *parent = NULL, *outer = NULL;
+       MonoType *geninst, *nested_in = NULL;
+       MonoReflectionTypeBuilder *tb = NULL;
+       MonoGenericInst *ginst;
+       MonoDomain *domain;
+
+       domain = mono_object_domain (type);
+       klass = mono_class_from_mono_type (type->type);
+
+       if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
+               tb = (MonoReflectionTypeBuilder *) type;
+
+               if (tb->parent) {
+                       parent = tb->parent;
+                       pklass = mono_class_from_mono_type (parent->type);
+               }
+               if (tb->nesting_type) {
+                       outer = tb->nesting_type;
+                       oklass = mono_class_from_mono_type (outer->type);
+               }
+       } else {
+               pklass = klass->parent;
+               if (pklass)
+                       parent = mono_type_get_object (domain, &pklass->byval_arg);
+               oklass = klass->nested_in;
+               if (oklass)
+                       outer = mono_type_get_object (domain, &oklass->byval_arg);
+       }
+
+       if (oklass)
+               nested_in = mono_reflection_bind_generic_parameters (outer, oklass->num_gen_params, types);
+
+       geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types, nested_in);
+       if (!geninst)
+               return NULL;
+
+       ginst = geninst->data.generic_inst;
+
+       if (pklass && pklass->generic_inst)
+               ginst->parent = mono_reflection_bind_generic_parameters (parent, type_argc, types);
+
+       return geninst;
 }
 
-MonoReflectionInflatedMethod*
+void
+mono_reflection_generic_inst_get_nested_types (MonoReflectionGenericInst *type)
+{
+       MonoReflectionTypeBuilder *tb;
+       MonoGenericInst *ginst;
+       int i;
+
+       ginst = type->type.type->data.generic_inst;
+       if (ginst->nested)
+               return;
+
+       if (strcmp (((MonoObject *) type->generic_type)->vtable->klass->name, "TypeBuilder"))
+               return;
+
+       tb = (MonoReflectionTypeBuilder *) type->generic_type;
+
+       ginst->count_nested = tb->subtypes ? mono_array_length (tb->subtypes) : 0;
+       ginst->nested = g_new0 (MonoType *, ginst->count_nested);
+
+       for (i = 0; i < ginst->count_nested; i++) {
+               MonoReflectionTypeBuilder *ntype;
+               MonoType **ntypes;
+               int ntype_argc, j;
+
+               ntype = mono_array_get (tb->subtypes, gpointer, i);
+               ntype_argc = ntype->generic_params ? mono_array_length (ntype->generic_params) : 0;
+
+               if (ntype_argc > ginst->type_argc) {
+                       ntypes = g_new0 (MonoType *, ntype_argc);
+
+                       for (j = 0; j < ginst->type_argc; j++)
+                               ntypes [j] = ginst->type_argv [j];
+
+                       for (j = ginst->type_argc; j < ntype_argc; j++) {
+                               MonoReflectionGenericParam *ngparam;
+                               MonoType *pt = g_new0 (MonoType, 1);
+
+                               ngparam = mono_array_get (ntype->generic_params, gpointer, j);
+
+                               pt->type = MONO_TYPE_VAR;
+                               pt->data.generic_param = ngparam->type.type->data.generic_param;
+
+                               ntypes [j] = pt;
+                       }
+               } else
+                       ntypes = ginst->type_argv;
+
+               ginst->nested [i] = mono_reflection_bind_generic_parameters ((MonoReflectionType *) ntype, ntype_argc, ntypes);
+       }
+}
+
+MonoReflectionMethod*
 mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types)
 {
        MonoMethod *method, *inflated;
        MonoReflectionMethodBuilder *mb = NULL;
-       MonoGenericInst *ginst;
+       MonoGenericMethod *gmethod;
+       MonoGenericContext *context;
        int count, i;
 
        MONO_ARCH_SAVE_REGS;
@@ -6861,34 +7136,50 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        if (count != mono_array_length (types))
                return NULL;
 
-       ginst = g_new0 (MonoGenericInst, 1);
-       ginst->generic_method = method;
-       ginst->type_argc = count;
-       ginst->type_argv = g_new0 (MonoType *, count);
+       gmethod = g_new0 (MonoGenericMethod, 1);
+       gmethod->mtype_argc = count;
+       gmethod->mtype_argv = g_new0 (MonoType *, count);
        for (i = 0; i < count; i++) {
                MonoReflectionType *garg = mono_array_get (types, gpointer, i);
-               ginst->type_argv [i] = garg->type;
+               gmethod->mtype_argv [i] = garg->type;
        }
 
-       inflated = mono_class_inflate_generic_method (method, ginst);
+       context = g_new0 (MonoGenericContext, 1);
+       context->ginst = method->klass->generic_inst;
+       context->gmethod = gmethod;
+
+       inflated = mono_class_inflate_generic_method (method, context, NULL);
 
-       return inflated_method_get_object (mono_object_domain (rmethod), inflated, rmethod, ginst);
+       return mono_method_get_object (
+               mono_object_domain (rmethod), inflated, NULL);
 }
 
-MonoReflectionInflatedMethod*
-mono_reflection_inflate_method_or_ctor (MonoReflectionGenericInst *declaring_type,
-                                       MonoReflectionGenericInst *reflected_type,
-                                       MonoObject *obj)
+static MonoMethod *
+inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method, MonoObject *obj)
 {
-       MonoGenericInst *ginst, *type_ginst;
-       MonoMethod *method = NULL, *inflated;
-       MonoReflectionInflatedMethod *res;
-       MonoClass *klass;
+       MonoGenericMethod *gmethod;
+       MonoGenericInst *ginst;
+       MonoGenericContext *context;
 
-       MONO_ARCH_SAVE_REGS;
+       ginst = type->type.type->data.generic_inst;
 
-       klass = mono_class_from_mono_type (reflected_type->type.type);
-       type_ginst = reflected_type->type.type->data.generic_inst;
+       gmethod = g_new0 (MonoGenericMethod, 1);
+       gmethod->reflection_info = obj;
+
+       context = g_new0 (MonoGenericContext, 1);
+       context->ginst = ginst;
+       context->gmethod = gmethod;
+
+       return mono_class_inflate_generic_method (method, context, ginst->klass);
+}
+
+static MonoMethod *
+inflate_method (MonoReflectionGenericInst *type, MonoObject *obj)
+{
+       MonoMethod *method;
+       MonoClass *klass;
+
+       klass = mono_class_from_mono_type (type->type.type);
 
        if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
                method = methodbuilder_to_mono_method (klass, (MonoReflectionMethodBuilder *) obj);
@@ -6897,87 +7188,138 @@ mono_reflection_inflate_method_or_ctor (MonoReflectionGenericInst *declaring_typ
        else if (!strcmp (obj->vtable->klass->name, "MonoMethod") ||
                 !strcmp (obj->vtable->klass->name, "MonoCMethod"))
                method = ((MonoReflectionMethod *) obj)->method;
-       else if (!strcmp (obj->vtable->klass->name, "MonoInflatedMethod") ||
-                !strcmp (obj->vtable->klass->name, "MonoInflatedCtor"))
-               method = ((MonoReflectionInflatedMethod *) obj)->rmethod.method;
-       else
+       else {
+               method = NULL; /* prevent compiler warning */
                g_assert_not_reached ();
+       }
 
-       ginst = g_new0 (MonoGenericInst, 1);
-       ginst->generic_method = method;
-       ginst->generic_type = reflected_type->type.type;
-       ginst->type_argc = type_ginst->type_argc;
-       ginst->type_argv = type_ginst->type_argv;
-       ginst->is_open = type_ginst->is_open;
+       return inflate_mono_method (type, method, obj);
+}
+
+void
+mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
+                                        MonoArray *methods, MonoArray *ctors,
+                                        MonoArray *fields, MonoArray *properties,
+                                        MonoArray *events)
+{
+       MonoGenericInst *ginst;
+       MonoDynamicGenericInst *dginst;
+       MonoClass *klass, *gklass, *pklass;
+       int i;
+
+       MONO_ARCH_SAVE_REGS;
+
+       klass = mono_class_from_mono_type (type->type.type);
+       ginst = type->type.type->data.generic_inst;
+
+       if (ginst->initialized)
+               return;
 
-       ginst->klass = mono_class_from_generic (ginst->generic_type, FALSE);
+       dginst = ginst->dynamic_info = g_new0 (MonoDynamicGenericInst, 1);
 
-       if (type_ginst->is_open)
-               inflated = method;
+       gklass = mono_class_from_mono_type (ginst->generic_type);
+       mono_class_init (gklass);
+
+       if (ginst->parent)
+               pklass = mono_class_from_mono_type (ginst->parent);
        else
-               inflated = mono_class_inflate_generic_method (method, ginst);
+               pklass = gklass->parent;
 
-       res = inflated_method_get_object (
-               mono_object_domain (reflected_type), inflated, (MonoReflectionMethod *) obj, ginst);
+       mono_class_setup_parent (klass, pklass);
 
-       res->declaring_type = declaring_type;
-       res->reflected_type = reflected_type;
+       dginst->count_methods = methods ? mono_array_length (methods) : 0;
+       dginst->count_ctors = ctors ? mono_array_length (ctors) : 0;
+       dginst->count_fields = fields ? mono_array_length (fields) : 0;
+       dginst->count_properties = properties ? mono_array_length (properties) : 0;
+       dginst->count_events = events ? mono_array_length (events) : 0;
 
-       return res;
-}
+       dginst->methods = g_new0 (MonoMethod *, dginst->count_methods);
+       dginst->ctors = g_new0 (MonoMethod *, dginst->count_ctors);
+       dginst->fields = g_new0 (MonoClassField, dginst->count_fields);
+       dginst->properties = g_new0 (MonoProperty, dginst->count_properties);
+       dginst->events = g_new0 (MonoEvent, dginst->count_events);
 
-MonoReflectionInflatedField*
-mono_reflection_inflate_field (MonoReflectionGenericInst *declaring_type,
-                              MonoReflectionGenericInst *reflected_type,
-                              MonoObject *obj)
-{
-       static MonoClass *System_Reflection_MonoInflatedField;
-       MonoGenericInst *ginst, *type_ginst;
-       MonoClassField *field = NULL, *inflated;
-       MonoReflectionInflatedField *res;
-       MonoDomain *domain;
-       MonoClass *klass;
+       for (i = 0; i < dginst->count_methods; i++) {
+               MonoObject *obj = mono_array_get (methods, gpointer, i);
 
-       MONO_ARCH_SAVE_REGS;
+               dginst->methods [i] = inflate_method (type, obj);
+       }
+
+       for (i = 0; i < dginst->count_ctors; i++) {
+               MonoObject *obj = mono_array_get (ctors, gpointer, i);
 
-       if (!System_Reflection_MonoInflatedField) {
-               System_Reflection_MonoInflatedField = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "MonoInflatedField");
-               g_assert (System_Reflection_MonoInflatedField);
+               dginst->ctors [i] = inflate_method (type, obj);
        }
 
-       klass = mono_class_from_mono_type (reflected_type->type.type);
-       type_ginst = reflected_type->type.type->data.generic_inst;
+       for (i = 0; i < dginst->count_fields; i++) {
+               MonoObject *obj = mono_array_get (fields, gpointer, i);
+               MonoClassField *field;
 
-       if (!strcmp (obj->vtable->klass->name, "FieldBuilder")) {
-               field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
-       } else if (!strcmp (obj->vtable->klass->name, "MonoField"))
-               field = ((MonoReflectionField *) obj)->field;
-       else
-               g_assert_not_reached ();
+               if (!strcmp (obj->vtable->klass->name, "FieldBuilder"))
+                       field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
+               else if (!strcmp (obj->vtable->klass->name, "MonoField"))
+                       field = ((MonoReflectionField *) obj)->field;
+               else {
+                       field = NULL; /* prevent compiler warning */
+                       g_assert_not_reached ();
+               }
 
-       ginst = g_new0 (MonoGenericInst, 1);
-       ginst->generic_type = reflected_type->type.type;
-       ginst->type_argc = type_ginst->type_argc;
-       ginst->type_argv = type_ginst->type_argv;
-
-       inflated = g_new0 (MonoClassField, 1);
-       *inflated = *field;
-       inflated->type = mono_class_inflate_generic_type (field->type, ginst);
-
-       domain = mono_object_domain (obj);
-
-       res = (MonoReflectionInflatedField *)mono_object_new (domain, System_Reflection_MonoInflatedField);
-       res->declaring = field;
-       res->declaring_type = declaring_type;
-       res->reflected_type = reflected_type;
-       res->rfield.klass = klass;
-       res->rfield.field = inflated;
-       res->rfield.name = mono_string_new (domain, inflated->name);
-       res->rfield.attrs = inflated->type->attrs;
-       res->rfield.type = mono_type_get_object (domain, inflated->type);
-       CACHE_OBJECT (inflated, res, field->parent);
-       return res;
+               dginst->fields [i] = *field;
+               dginst->fields [i].generic_type = field->type;
+               dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst->context);
+       }
+
+       for (i = 0; i < dginst->count_properties; i++) {
+               MonoObject *obj = mono_array_get (properties, gpointer, i);
+               MonoProperty *property = &dginst->properties [i];
+
+               if (!strcmp (obj->vtable->klass->name, "PropertyBuilder")) {
+                       MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *) obj;
+
+                       property->parent = klass;
+                       property->attrs = pb->attrs;
+                       property->name = mono_string_to_utf8 (pb->name);
+                       if (pb->get_method)
+                               property->get = inflate_method (type, (MonoObject *) pb->get_method);
+                       if (pb->set_method)
+                               property->set = inflate_method (type, (MonoObject *) pb->set_method);
+               } else if (!strcmp (obj->vtable->klass->name, "MonoProperty")) {
+                       *property = *((MonoReflectionProperty *) obj)->property;
+
+                       if (property->get)
+                               property->get = inflate_mono_method (type, property->get, NULL);
+                       if (property->set)
+                               property->set = inflate_mono_method (type, property->set, NULL);
+               } else
+                       g_assert_not_reached ();
+       }
+
+       for (i = 0; i < dginst->count_events; i++) {
+               MonoObject *obj = mono_array_get (events, gpointer, i);
+               MonoEvent *event = &dginst->events [i];
+
+               if (!strcmp (obj->vtable->klass->name, "EventBuilder")) {
+                       MonoReflectionEventBuilder *eb = (MonoReflectionEventBuilder *) obj;
+
+                       event->parent = klass;
+                       event->attrs = eb->attrs;
+                       event->name = mono_string_to_utf8 (eb->name);
+                       if (eb->add_method)
+                               event->add = inflate_method (type, (MonoObject *) eb->add_method);
+                       if (eb->remove_method)
+                               event->remove = inflate_method (type, (MonoObject *) eb->remove_method);
+               } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) {
+                       *event = *((MonoReflectionEvent *) obj)->event;
+
+                       if (event->add)
+                               event->add = inflate_mono_method (type, event->add, NULL);
+                       if (event->remove)
+                               event->remove = inflate_mono_method (type, event->remove, NULL);
+               } else
+                       g_assert_not_reached ();
+       }
+
+       ginst->initialized = TRUE;
 }
 
 static void
@@ -7121,6 +7463,7 @@ typebuilder_setup_properties (MonoClass *klass)
        klass->properties = g_new0 (MonoProperty, klass->property.count);
        for (i = 0; i < klass->property.count; ++i) {
                pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
+               klass->properties [i].parent = klass;
                klass->properties [i].attrs = pb->attrs;
                klass->properties [i].name = mono_string_to_utf8 (pb->name);
                if (pb->get_method)
@@ -7130,6 +7473,38 @@ typebuilder_setup_properties (MonoClass *klass)
        }
 }
 
+MonoReflectionEvent *
+mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
+{
+       MonoEvent *event = g_new0 (MonoEvent, 1);
+       MonoClass *klass;
+       int j;
+
+       klass = my_mono_class_from_mono_type (tb->type.type);
+
+       event->parent = klass;
+       event->attrs = eb->attrs;
+       event->name = mono_string_to_utf8 (eb->name);
+       if (eb->add_method)
+               event->add = eb->add_method->mhandle;
+       if (eb->remove_method)
+               event->remove = eb->remove_method->mhandle;
+       if (eb->raise_method)
+               event->raise = eb->raise_method->mhandle;
+
+       if (eb->other_methods) {
+               event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods));
+               for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
+                       MonoReflectionMethodBuilder *mb = 
+                               mono_array_get (eb->other_methods,
+                                               MonoReflectionMethodBuilder*, j);
+                       event->other [j] = mb->mhandle;
+               }
+       }
+
+       return mono_event_get_object (mono_object_domain (tb), klass, event);
+}
+
 static void
 typebuilder_setup_events (MonoClass *klass)
 {
@@ -7144,6 +7519,7 @@ typebuilder_setup_events (MonoClass *klass)
        klass->events = g_new0 (MonoEvent, klass->event.count);
        for (i = 0; i < klass->event.count; ++i) {
                eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
+               klass->events [i].parent = klass;
                klass->events [i].attrs = eb->attrs;
                klass->events [i].name = mono_string_to_utf8 (eb->name);
                if (eb->add_method)
@@ -7363,7 +7739,7 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
        rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
        for (i = 0; i < mb->nrefs; ++i) {
                gpointer ref = resolve_object (mb->module->image, 
-                                                                          mono_array_get (mb->refs, MonoObject*, i));
+                                              mono_array_get (mb->refs, MonoObject*, i));
                if (!ref) {
                        g_free (rmb.refs);
                        mono_raise_exception (mono_get_exception_type_load (NULL));