X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Freflection.c;h=91061a8a32f2a03794637fde8786e4d289ccac07;hb=f374af4097e95561173c5d59a05552c0337d4792;hp=f0a95f1b5f52a112d2f449baf0358bcb2db2862f;hpb=caf158912a0a55a17fb9b089dfff0bb42a9fd1ff;p=mono.git diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index f0a95f1b5f5..91061a8a32f 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -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));