2004-05-11 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / metadata / reflection.c
index ec146d21a1563ddd90c3f623eacc8ecf29a4d7a6..d7c958f1bd2442d782558548316f59bfe94b7882 100644 (file)
@@ -138,6 +138,8 @@ 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)
@@ -531,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)
 {
@@ -538,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;
@@ -647,6 +738,10 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen)
        mono_metadata_encode_value (nl, p, &p);
        for (i = 0; i < nl; ++i) {
                MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
+               
+               if (lb->is_pinned)
+                       mono_metadata_encode_value (MONO_TYPE_PINNED, p, &p);
+               
                encode_reflection_type (assembly, lb->type, p, &p);
        }
        g_assert (p - buf < size);
@@ -1287,11 +1382,11 @@ type_get_fully_qualified_name (MonoType *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",
+       result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%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");
+               ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral",
+               ta->aname.public_tok_value ? ta->aname.public_tok_value : "null");
        g_free (name);
        return result;
 }
@@ -1456,7 +1551,16 @@ encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
                mono_metadata_encode_value (minfo->type, p, &p);
                mono_metadata_encode_value (minfo->count, p, &p);
                break;
-               /* FIXME: handle ARRAY and other unmanaged types that need extra info */
+       case MONO_NATIVE_LPARRAY:
+               mono_metadata_encode_value (minfo->type, p, &p);
+               if (minfo->eltype || (minfo->count > 0)) {
+                       mono_metadata_encode_value (minfo->eltype, p, &p);
+                       if (minfo->count > 0) {
+                               mono_metadata_encode_value (0, p, &p);
+                               mono_metadata_encode_value (minfo->count, p, &p);
+                       }
+               }
+               break;
        case MONO_NATIVE_CUSTOM:
                mono_metadata_encode_value (minfo->type, p, &p);
                if (minfo->guid) {
@@ -1744,6 +1848,75 @@ mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *ass
        }
 }
 
+static void
+encode_new_constraint (MonoDynamicImage *assembly, guint32 owner)
+{
+       static MonoClass *NewConstraintAttr;
+       static MonoMethod *NewConstraintAttr_ctor;
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 token, type;
+       char blob_size [4] = { 0x01, 0x00, 0x00, 0x00 };
+       char *buf, *p;
+
+       if (!NewConstraintAttr)
+               NewConstraintAttr = mono_class_from_name (
+                       mono_defaults.corlib, "System.Runtime.CompilerServices",
+                       "NewConstraintAttribute");
+       g_assert (NewConstraintAttr);
+
+       if (!NewConstraintAttr_ctor) {
+               int i;
+
+               for (i = 0; i < NewConstraintAttr->method.count; i++) {
+                       MonoMethod *m = NewConstraintAttr->methods [i];
+
+                       if (strcmp (m->name, ".ctor"))
+                               continue;
+
+                       NewConstraintAttr_ctor = m;
+                       break;
+               }
+
+               g_assert (NewConstraintAttr_ctor);
+       }
+
+       table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+       table->rows += 1;
+       alloc_table (table, table->rows);
+
+       values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
+       owner <<= CUSTOM_ATTR_BITS;
+       owner |= CUSTOM_ATTR_GENERICPAR;
+       values [MONO_CUSTOM_ATTR_PARENT] = owner;
+
+       token = mono_image_get_methodref_token (assembly, NewConstraintAttr_ctor);
+
+       type = mono_metadata_token_index (token);
+       type <<= CUSTOM_ATTR_TYPE_BITS;
+       switch (mono_metadata_token_table (token)) {
+       case MONO_TABLE_METHOD:
+               type |= CUSTOM_ATTR_TYPE_METHODDEF;
+               break;
+       case MONO_TABLE_MEMBERREF:
+               type |= CUSTOM_ATTR_TYPE_MEMBERREF;
+               break;
+       default:
+               g_warning ("got wrong token in custom attr");
+               return;
+       }
+       values [MONO_CUSTOM_ATTR_TYPE] = type;
+
+       buf = p = g_malloc (1);
+       mono_metadata_encode_value (4, p, &p);
+       g_assert (p-buf == 1);
+
+       values [MONO_CUSTOM_ATTR_VALUE] = add_to_blob_cached (assembly, buf, 1, blob_size, 4);
+
+       values += MONO_CUSTOM_ATTR_SIZE;
+       ++table->next_idx;
+}
+
 static void
 encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
 {
@@ -1753,19 +1926,36 @@ encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynam
        guint32 table_idx;
 
        table = &assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
-       num_constraints = gparam ? mono_array_length (gparam->constraints) : 0;
+       num_constraints = gparam->iface_constraints ?
+               mono_array_length (gparam->iface_constraints) : 0;
        table->rows += num_constraints;
+       if (gparam->base_type)
+               table->rows++;
        alloc_table (table, table->rows);
 
+       if (gparam->base_type) {
+               table_idx = table->next_idx ++;
+               values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
+
+               values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
+               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (
+                       assembly, gparam->base_type->type);
+       }
+
        for (i = 0; i < num_constraints; i++) {
-               MonoReflectionType *constraint = mono_array_get (gparam->constraints, gpointer, i);
+               MonoReflectionType *constraint = mono_array_get (
+                       gparam->iface_constraints, gpointer, i);
 
                table_idx = table->next_idx ++;
                values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
 
                values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
-               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (assembly, constraint->type);
+               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (
+                       assembly, constraint->type);
        }
+
+       if (gparam->has_ctor_constraint)
+               encode_new_constraint (assembly, owner);
 }
 
 static void
@@ -1783,14 +1973,17 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
        param = gparam->type.type->data.generic_param;
 
        values [MONO_GENERICPARAM_OWNER] = owner;
-       values [MONO_GENERICPARAM_FLAGS] = param->flags;
+       if (gparam->has_value_type)
+               values [MONO_GENERICPARAM_FLAGS] = 0x18;
+       else if (gparam->has_reference_type)
+               values [MONO_GENERICPARAM_FLAGS] = 0x04;
+       else
+               values [MONO_GENERICPARAM_FLAGS] = 0x00;
        values [MONO_GENERICPARAM_NUMBER] = param->num;
        values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, param->name);
        values [MONO_GENERICPARAM_KIND] = 0;
-       values [MONO_GENERICPARAM_DEPRECATED_CONSTRAINT] = 0;
 
-       if (gparam->constraints)
-               encode_constraints (gparam, table_idx, assembly);
+       encode_constraints (gparam, table_idx, assembly);
 }
 
 static guint32
@@ -1835,10 +2028,7 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
        table->rows ++;
        alloc_table (table, table->rows);
        values = table->values + token * MONO_ASSEMBLYREF_SIZE;
-       if (strcmp ("corlib", image->assembly_name) == 0)
-               values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, "mscorlib");
-       else
-               values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
+       values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
        values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
        values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
        values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
@@ -1847,6 +2037,11 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
        values [MONO_ASSEMBLYREF_CULTURE] = 0;
        values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
 
+       if (strcmp ("", image->assembly->aname.culture)) {
+               values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
+                               image->assembly->aname.culture);
+       }
+
        if ((pubkey = mono_image_get_public_key (image, &publen))) {
                guchar pubtoken [9];
                pubtoken [0] = 8;
@@ -1861,8 +2056,7 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
                 * recognized by ms, yuck!
                 * FIXME: need to add more assembly names, as needed.
                 */
-               if (strcmp (image->assembly_name, "corlib") == 0 ||
-                               strcmp (image->assembly_name, "mscorlib") == 0 ||
+               if (strcmp (image->assembly_name, "mscorlib") == 0 ||
                                strcmp (image->assembly_name, "System") == 0 ||
                                strcmp (image->assembly_name, "System.Runtime.Remoting") == 0 ||
                                strcmp (image->assembly_name, "System.Xml") == 0 ||
@@ -2113,19 +2307,19 @@ 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));
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
        if (token)
                return token;
-       field->parent = klass;
-       type = field->generic_type ? field->generic_type : field->type;
-       token = mono_image_get_memberref_token (assembly, &klass->byval_arg, 
-               field->name,  fieldref_encode_signature (assembly, type));
-       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;
 }
 
@@ -2168,20 +2362,20 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
        MonoDynamicTable *table;
        guint32 *values;
        guint32 token, mtoken = 0, sig;
-       MonoGenericMethod *gmethod;
+       MonoMethodInflated *imethod;
        MonoMethod *declaring;
 
        table = &assembly->tables [MONO_TABLE_METHODSPEC];
 
-       g_assert ((gmethod = method->signature->gen_method) != NULL);
-       declaring = gmethod->generic_method;
-       if (declaring->signature->gen_method)
-               declaring = declaring->signature->gen_method->generic_method;
+       g_assert (method->signature->is_inflated);
+       imethod = (MonoMethodInflated *) method;
+       declaring = imethod->declaring;
+
        sig = method_encode_signature (assembly, declaring->signature);
        mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
                                                 declaring->name, sig);
 
-       if (!gmethod->generic_method->signature->generic_param_count)
+       if (!declaring->signature->generic_param_count)
                return mtoken;
 
        switch (mono_metadata_token_table (mtoken)) {
@@ -2195,7 +2389,7 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
                g_assert_not_reached ();
        }
 
-       sig = encode_generic_method_sig (assembly, gmethod);
+       sig = encode_generic_method_sig (assembly, imethod->context->gmethod);
 
        if (assembly->save) {
                alloc_table (table, table->rows + 1);
@@ -2213,21 +2407,23 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
 static guint32
 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *m)
 {
-       MonoGenericMethod *gmethod;
+       MonoMethodInflated *imethod;
        guint32 token;
        
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m));
        if (token)
                return token;
 
-       g_assert ((gmethod = m->signature->gen_method) != NULL);
+       g_assert (m->signature->is_inflated);
+       imethod = (MonoMethodInflated *) m;
 
-       if (gmethod->generic_method->signature->generic_param_count)
+       if (imethod->declaring->signature->generic_param_count)
                token = method_encode_methodspec (assembly, m);
        else {
-               guint32 sig = method_encode_signature (assembly, gmethod->generic_method->signature);
+               guint32 sig = method_encode_signature (
+                       assembly, imethod->declaring->signature);
                token = mono_image_get_memberref_token (
-                       assembly, &m->klass->byval_arg, gmethod->generic_method->name, sig);
+                       assembly, &m->klass->byval_arg, m->name, sig);
        }
 
        g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER(token));
@@ -2247,6 +2443,16 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *
        char *b = blob_size;
        int count, i;
 
+       /*
+        * We're creating a TypeSpec for the TypeBuilder of a generic type declaration,
+        * ie. what we'd normally use as the generic type in a TypeSpec signature.
+        * Because of this, we must not insert it into the `typeref' hash table.
+        */
+
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, tb->type.type));
+       if (token)
+               return token;
+
        g_assert (tb->generic_params);
        klass = mono_class_from_mono_type (tb->type.type);
 
@@ -2274,7 +2480,7 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *
        }
 
        token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS);
-       g_hash_table_insert (assembly->typeref, tb->type.type, GUINT_TO_POINTER(token));
+       g_hash_table_insert (assembly->typespec, tb->type.type, GUINT_TO_POINTER(token));
        table->next_idx ++;
        return token;
 }
@@ -2288,6 +2494,10 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
        guint32 token, pclass, parent, sig;
        gchar *name;
 
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, fb));
+       if (token)
+               return token;
+
        klass = mono_class_from_mono_type (fb->typeb->type);
        name = mono_string_to_utf8 (fb->name);
 
@@ -2311,7 +2521,7 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
 
        token = MONO_TOKEN_MEMBER_REF | table->next_idx;
        table->next_idx ++;
-
+       g_hash_table_insert (assembly->handleref, fb, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -3030,8 +3240,17 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        int32val = (guint32*)p;
        *int32val = GUINT32_TO_LE (0); /* reserved */
        p += 4;
-       *p++ = 1; /* version */
-       *p++ = 0;
+
+       if ((assembly->tables [MONO_TABLE_GENERICPARAM].rows > 0) ||
+           (assembly->tables [MONO_TABLE_METHODSPEC].rows > 0) ||
+           (assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT].rows > 0)) {
+               *p++ = 1; /* version */
+               *p++ = 1;
+       } else {
+               *p++ = 1; /* version */
+               *p++ = 0;
+       }
+
        if (meta->idx_string_wide)
                *p |= 0x01;
        if (meta->idx_guid_wide)
@@ -3654,7 +3873,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
                token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
        }
        else if (strcmp (klass->name, "MonoType") == 0 ||
-                strcmp (klass->name, "MonoGenericParam") == 0) {
+                strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
                MonoReflectionType *tb = (MonoReflectionType *)obj;
                token = mono_metadata_token_from_dor (
                        mono_image_typedef_or_ref (assembly, tb->type));
@@ -3667,7 +3886,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
        else if (strcmp (klass->name, "MonoCMethod") == 0 ||
                        strcmp (klass->name, "MonoMethod") == 0) {
                MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
-               if (m->method->signature->gen_method) {
+               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 ();
@@ -3692,7 +3911,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
                        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) {
@@ -3766,6 +3985,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly,
        image->method_aux_hash = mono_g_hash_table_new (NULL, NULL);
        image->handleref = g_hash_table_new (NULL, NULL);
        image->tokens = mono_g_hash_table_new (NULL, NULL);
+       image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->blob_cache = mono_g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
 
@@ -4735,6 +4955,8 @@ mono_generic_inst_get_object (MonoDomain *domain, MonoType *geninst)
        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;
@@ -4767,7 +4989,7 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                mono_domain_unlock (domain);
                return res;
        }
-       if (type->type == MONO_TYPE_GENERICINST) {
+       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);
@@ -4960,7 +5182,8 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
        memset (assembly, 0, sizeof (MonoAssemblyName));
        assembly->name = p;
        assembly->culture = "";
-       
+       assembly->public_tok_value = NULL;
+
        while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@'))
                p++;
        found_sep = 0;
@@ -4973,7 +5196,7 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
        if (!found_sep)
                return 1;
        while (*p) {
-               if (*p == 'V' && strncmp (p, "Version=", 8) == 0) {
+               if (*p == 'V' && g_ascii_strncasecmp (p, "Version=", 8) == 0) {
                        p += 8;
                        assembly->major = strtoul (p, &s, 10);
                        if (s == p || *s != '.')
@@ -4990,10 +5213,11 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
                        assembly->revision = strtoul (p, &s, 10);
                        if (s == p)
                                return 1;
-               } else if (*p == 'C' && strncmp (p, "Culture=", 8) == 0) {
+                       p = s;
+               } else if (*p == 'C' && g_ascii_strncasecmp (p, "Culture=", 8) == 0) {
                        p += 8;
-                       if (strncmp (p, "neutral", 7) == 0) {
-                               assembly->culture = "";
+                       if (g_ascii_strncasecmp (p, "neutral", 7) == 0) {
+                               assembly->culture = g_strdup ("");
                                p += 7;
                        } else {
                                assembly->culture = p;
@@ -5001,26 +5225,16 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
                                        p++;
                                }
                        }
-               } else if (*p == 'P' && strncmp (p, "PublicKeyToken=", 15) == 0) {
+               } else if (*p == 'P' && g_ascii_strncasecmp (p, "PublicKeyToken=", 15) == 0) {
                        p += 15;
-                       s = p;
-                       while (*s && isxdigit (*s)) {
-                               *s = tolower (*s);
-                               s++;
-                       }
-                       assembly->hash_len = s - p;
-                       if (!(s-p) || ((s-p) & 1))
-                               return 1;
-                       assembly->hash_value = s = p;
-                       while (*s && isxdigit (*s)) {
-                               int val;
-                               val = *s >= '0' && *s <= '9'? *s - '0': *s - 'a' + 10;
-                               s++;
-                               *p = val << 4;
-                               *p |= *s >= '0' && *s <= '9'? *s - '0': *s - 'a' + 10;
-                               p++;
+                       if (strncmp (p, "null", 4) == 0) {
+                               p += 4;
+                       } else {
+                               assembly->public_tok_value = p;
+                               while (*p && *p != ',') {
+                                       p++;
+                               }
                        }
-                       p = s;
                } else {
                        while (*p && *p != ',')
                                p++;
@@ -5263,9 +5477,36 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig
        assembly = 
                mono_domain_try_type_resolve (
                        mono_domain_get (), fullName->str, NULL);
-       if (assembly && (!image || (assembly->assembly->image == image)))
-               type = mono_reflection_get_type_internal (assembly->assembly->image, 
-                                                                                info, ignorecase);
+       if (assembly && (!image || (assembly->assembly->image == image))) {
+
+               if (assembly->assembly->dynamic) {
+                       /* Enumerate all modules */
+                       MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
+                       int i;
+
+                       type = NULL;
+                       if (abuilder->modules) {
+                               for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
+                                       MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
+                                       type = mono_reflection_get_type_internal (&mb->dynamic_image->image, info, ignorecase);
+                                       if (type)
+                                               break;
+                               }
+                       }
+
+                       if (!type && abuilder->loaded_modules) {
+                               for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
+                                       MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
+                                       type = mono_reflection_get_type_internal (mod->image, info, ignorecase);
+                                       if (type)
+                                               break;
+                               }
+                       }
+               }
+               else
+                       type = mono_reflection_get_type_internal (assembly->assembly->image, 
+                                                                                                         info, ignorecase);
+       }
        g_string_free (fullName, TRUE);
        return type;
 }
@@ -5612,10 +5853,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);
@@ -5931,13 +6179,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);
@@ -6470,8 +6718,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);
 }
 
 /*
@@ -6801,35 +7047,35 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
        return field;
 }
 
-MonoType*
-mono_reflection_bind_generic_parameters (MonoType *type, MonoArray *types)
+static MonoType*
+do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc,
+                                           MonoType **types)
 {
-       MonoClass *klass, *pklass = NULL;
+       MonoClass *klass;
        MonoReflectionTypeBuilder *tb = NULL;
        MonoGenericInst *ginst;
-       MonoType *geninst, *parent = NULL;
+       MonoDomain *domain;
+       MonoType *geninst;
        int icount, i;
 
-       klass = mono_class_from_mono_type (type);
-       if (!klass->gen_params && !klass->generic_inst)
+       klass = mono_class_from_mono_type (type->type);
+       if (!klass->gen_params && !klass->generic_inst &&
+           !(klass->nested_in && klass->nested_in->gen_params))
                return NULL;
 
        mono_loader_lock ();
 
+       domain = mono_object_domain (type);
+
        ginst = g_new0 (MonoGenericInst, 1);
-       ginst->is_dynamic = 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;
@@ -6842,12 +7088,8 @@ mono_reflection_bind_generic_parameters (MonoType *type, MonoArray *types)
                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);
@@ -6860,52 +7102,50 @@ mono_reflection_bind_generic_parameters (MonoType *type, MonoArray *types)
 
        geninst = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
        if (geninst) {
-               g_free (ginst->type_argv);
                g_free (ginst);
                mono_loader_unlock ();
                return geninst;
        }
 
-       if (klass->wastypebuilder && klass->reflection_info) {
-               tb = klass->reflection_info;
-
-               if (tb->parent) {
-                       parent = tb->parent->type;
-                       pklass = mono_class_from_mono_type (parent);
-               }
-       } else {
-               pklass = klass->parent;
-               if (pklass)
-                       parent = &pklass->byval_arg;
-       }
+       ginst->context = g_new0 (MonoGenericContext, 1);
+       ginst->context->ginst = ginst;
 
        geninst = g_new0 (MonoType, 1);
        geninst->type = MONO_TYPE_GENERICINST;
        geninst->data.generic_inst = ginst;
 
-       if (pklass && pklass->generic_inst)
-               parent = mono_reflection_bind_generic_parameters (parent, types);
+       if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
+               tb = (MonoReflectionTypeBuilder *) type;
 
-       if (tb)
                icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
-       else
+               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++) {
-               MonoType *itype;
+               MonoReflectionType *itype;
 
                if (tb)
-                       itype = mono_array_get (tb->interfaces, MonoReflectionType *, i)->type;
+                       itype = mono_array_get (tb->interfaces, MonoReflectionType *, i);
                else
-                       itype = &klass->interfaces [i]->byval_arg;
-               ginst->ifaces [i] = mono_reflection_bind_generic_parameters (itype, types);
+                       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;
+                       ginst->ifaces [i] = itype->type;
        }
 
-       ginst->parent = parent;
-
        mono_class_create_generic (ginst);
 
        g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst);
@@ -6915,12 +7155,51 @@ mono_reflection_bind_generic_parameters (MonoType *type, MonoArray *types)
        return geninst;
 }
 
+MonoType*
+mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
+{
+       MonoClass *klass, *pklass = NULL;
+       MonoReflectionType *parent = NULL;
+       MonoType *geninst;
+       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);
+               }
+       } else {
+               pklass = klass->parent;
+               if (pklass)
+                       parent = mono_type_get_object (domain, &pklass->byval_arg);
+       }
+
+       geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types);
+       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;
+}
+
 MonoReflectionMethod*
 mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types)
 {
        MonoMethod *method, *inflated;
        MonoReflectionMethodBuilder *mb = NULL;
        MonoGenericMethod *gmethod;
+       MonoGenericContext *context;
        int count, i;
 
        MONO_ARCH_SAVE_REGS;
@@ -6941,7 +7220,6 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                return NULL;
 
        gmethod = g_new0 (MonoGenericMethod, 1);
-       gmethod->generic_method = method;
        gmethod->mtype_argc = count;
        gmethod->mtype_argv = g_new0 (MonoType *, count);
        for (i = 0; i < count; i++) {
@@ -6949,27 +7227,45 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                gmethod->mtype_argv [i] = garg->type;
        }
 
-       gmethod->generic_inst = method->klass->generic_inst;
+       context = g_new0 (MonoGenericContext, 1);
+       context->ginst = method->klass->generic_inst;
+       context->gmethod = gmethod;
 
-       inflated = mono_class_inflate_generic_method (method, gmethod, NULL);
+       inflated = mono_class_inflate_generic_method (method, context, NULL);
 
        return mono_method_get_object (
                mono_object_domain (rmethod), inflated, NULL);
 }
 
 static MonoMethod *
-inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method)
+inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method, MonoObject *obj)
 {
        MonoGenericMethod *gmethod;
        MonoGenericInst *ginst;
+       MonoGenericContext *context;
+       int i;
 
        ginst = type->type.type->data.generic_inst;
 
        gmethod = g_new0 (MonoGenericMethod, 1);
-       gmethod->generic_method = method;
-       gmethod->generic_inst = ginst;
+       gmethod->reflection_info = obj;
+
+       gmethod->mtype_argc = method->signature->generic_param_count;
+       gmethod->mtype_argv = g_new0 (MonoType *, gmethod->mtype_argc);
+
+       for (i = 0; i < gmethod->mtype_argc; i++) {
+               MonoMethodNormal *mn = (MonoMethodNormal *) method;
+               MonoGenericParam *gparam = &mn->header->gen_params [i];
+
+               g_assert (gparam->pklass);
+               gmethod->mtype_argv [i] = &gparam->pklass->byval_arg;
+       }
 
-       return mono_class_inflate_generic_method (method, gmethod, ginst->klass);
+       context = g_new0 (MonoGenericContext, 1);
+       context->ginst = ginst;
+       context->gmethod = gmethod;
+
+       return mono_class_inflate_generic_method (method, context, ginst->klass);
 }
 
 static MonoMethod *
@@ -6987,16 +7283,19 @@ inflate_method (MonoReflectionGenericInst *type, MonoObject *obj)
        else if (!strcmp (obj->vtable->klass->name, "MonoMethod") ||
                 !strcmp (obj->vtable->klass->name, "MonoCMethod"))
                method = ((MonoReflectionMethod *) obj)->method;
-       else
+       else {
+               method = NULL; /* prevent compiler warning */
                g_assert_not_reached ();
+       }
 
-       return inflate_mono_method (type, method);
+       return inflate_mono_method (type, method, obj);
 }
 
 void
 mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
                                         MonoArray *methods, MonoArray *ctors,
-                                        MonoArray *fields, MonoArray *properties)
+                                        MonoArray *fields, MonoArray *properties,
+                                        MonoArray *events)
 {
        MonoGenericInst *ginst;
        MonoDynamicGenericInst *dginst;
@@ -7027,11 +7326,13 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
        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;
 
        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);
 
        for (i = 0; i < dginst->count_methods; i++) {
                MonoObject *obj = mono_array_get (methods, gpointer, i);
@@ -7053,12 +7354,14 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
                        field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
                else if (!strcmp (obj->vtable->klass->name, "MonoField"))
                        field = ((MonoReflectionField *) obj)->field;
-               else
+               else {
+                       field = NULL; /* prevent compiler warning */
                        g_assert_not_reached ();
+               }
 
                dginst->fields [i] = *field;
                dginst->fields [i].generic_type = field->type;
-               dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst, NULL);
+               dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst->context);
        }
 
        for (i = 0; i < dginst->count_properties; i++) {
@@ -7068,6 +7371,7 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
                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)
@@ -7078,9 +7382,34 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
                        *property = *((MonoReflectionProperty *) obj)->property;
 
                        if (property->get)
-                               property->get = inflate_mono_method (type, property->get);
+                               property->get = inflate_mono_method (type, property->get, NULL);
                        if (property->set)
-                               property->set = inflate_mono_method (type, 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 ();
        }
@@ -7229,6 +7558,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)
@@ -7238,6 +7568,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)
 {
@@ -7252,6 +7614,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)
@@ -7326,74 +7689,29 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        return res;
 }
 
-MonoReflectionGenericParam *
-mono_reflection_define_generic_parameter (MonoReflectionTypeBuilder *tb, MonoReflectionMethodBuilder *mb, MonoString *name, guint32 index)
-{
-       static MonoClass *System_Reflection_MonoGenericParam;
-       MonoImage *image;
-       MonoGenericParam *param;
-       MonoReflectionGenericParam *res;
-       MonoDomain *domain;
-
-       if (!System_Reflection_MonoGenericParam) {
-               System_Reflection_MonoGenericParam = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "MonoGenericParam");
-               g_assert (System_Reflection_MonoGenericParam);
-       }
-
-       param = g_new0 (MonoGenericParam, 1);
-
-       if (mb)
-               tb = (MonoReflectionTypeBuilder *) mb->type;
-
-       domain = mono_object_domain (tb);
-       image = (MonoImage*)tb->module->dynamic_image;
-
-       param->method = NULL;
-       param->name = mono_string_to_utf8 (name);
-       param->num = index;
-
-       res = (MonoReflectionGenericParam *)mono_object_new (domain, System_Reflection_MonoGenericParam);
-       res->type.type = g_new0 (MonoType, 1);
-       res->type.type->type = mb ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
-       res->type.type->data.generic_param = param;
-
-       res->refobj = mb ? (MonoObject *) mb : (MonoObject *) tb;
-       res->index = index;
-       res->name = name;
-
-       return res;
-}
-
 void
 mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
 {
        MonoGenericParam *param;
-       MonoReflectionMethodBuilder *mb = NULL;
-       MonoReflectionTypeBuilder *tb;
        MonoImage *image;
-       int count, i;
 
-       param = gparam->type.type->data.generic_param;
-       count = gparam->constraints ? mono_array_length (gparam->constraints) : 0;
-       param->constraints = g_new0 (MonoClass *, count + 1);
-       for (i = 0; i < count; i++) {
-               MonoReflectionType *constraint = mono_array_get (gparam->constraints, MonoReflectionType *, i);
+       MONO_ARCH_SAVE_REGS;
 
-               param->constraints [i] = mono_class_from_mono_type (constraint->type);
-       }
+       param = g_new0 (MonoGenericParam, 1);
 
-       if (!strcmp (gparam->refobj->vtable->klass->name, "MethodBuilder")) {
-               mb = (MonoReflectionMethodBuilder *) gparam->refobj;
-               tb = (MonoReflectionTypeBuilder *) mb->type;
-       } else
-               tb = (MonoReflectionTypeBuilder *) gparam->refobj;
+       param->method = NULL;
+       param->name = mono_string_to_utf8 (gparam->name);
+       param->num = gparam->index;
 
-       image = (MonoImage*)tb->module->dynamic_image;
+       image = &gparam->tbuilder->module->dynamic_image->image;
+       mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL);
 
-       param->pklass = mono_class_from_generic_parameter (param, image, mb != NULL);
+       param->pklass->reflection_info = gparam;
 
-       gparam->initialized = TRUE;
+       gparam->type.type = g_new0 (MonoType, 1);
+       gparam->type.type->type = gparam->mbuilder ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
+       gparam->type.type->attrs = TYPE_ATTRIBUTE_PUBLIC;
+       gparam->type.type->data.generic_param = param;
 }
 
 MonoArray *