X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Freflection.c;h=09903644eda911f6ff7caaa00febe1d200abe71b;hb=86ea70695089e3a2abd48259da93fd55a09b15d0;hp=853869b6718ad9927e684e5dda91e867b477b53f;hpb=abd9a3dbe594de4a2ca8006077def618cc394b54;p=mono.git diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index 853869b6718..09903644eda 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -9,6 +9,7 @@ */ #include #include "mono/utils/mono-digest.h" +#include "mono/utils/mono-membar.h" #include "mono/metadata/reflection.h" #include "mono/metadata/tabledefs.h" #include "mono/metadata/metadata-internals.h" @@ -31,9 +32,9 @@ #include #include "image.h" #include "cil-coff.h" -#include "rawbuffer.h" #include "mono-endian.h" #include +#include typedef struct { char *p; @@ -137,7 +138,7 @@ static void reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type); static guint32 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec); static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method); -static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb); +static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec); static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb); static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper); static void mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly); @@ -151,6 +152,7 @@ static void get_default_param_value_blobs (MonoMethod *method, char **blobs, gui static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob); static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t); static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve); +static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method); #define mono_reflection_lock() EnterCriticalSection (&reflection_mutex) #define mono_reflection_unlock() LeaveCriticalSection (&reflection_mutex) @@ -820,12 +822,6 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen) int i; sigbuffer_init (&buf, 32); - table = &assembly->tables [MONO_TABLE_STANDALONESIG]; - idx = table->next_idx ++; - table->rows ++; - alloc_table (table, table->rows); - values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE; - sigbuffer_add_value (&buf, 0x07); sigbuffer_add_value (&buf, nl); for (i = 0; i < nl; ++i) { @@ -839,8 +835,22 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen) sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf); sigbuffer_free (&buf); + if (assembly->standalonesig_cache == NULL) + assembly->standalonesig_cache = g_hash_table_new (NULL, NULL); + idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx))); + if (idx) + return idx; + + table = &assembly->tables [MONO_TABLE_STANDALONESIG]; + idx = table->next_idx ++; + table->rows ++; + alloc_table (table, table->rows); + values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE; + values [MONO_STAND_ALONE_SIGNATURE] = sig_idx; + g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx)); + return idx; } @@ -863,7 +873,7 @@ method_count_clauses (MonoReflectionILGen *ilgen) } static MonoExceptionClause* -method_encode_clauses (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses) +method_encode_clauses (MonoMemPool *mp, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses) { MonoExceptionClause *clauses; MonoExceptionClause *clause; @@ -872,7 +882,7 @@ method_encode_clauses (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, g guint32 finally_start; int i, j, clause_index;; - clauses = g_new0 (MonoExceptionClause, num_clauses); + clauses = mp_g_new0 (mp, MonoExceptionClause, num_clauses); clause_index = 0; for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) { @@ -1085,29 +1095,22 @@ find_index_in_table (MonoDynamicImage *assembly, int table_idx, int col, guint32 return 0; } -/* protected by reflection_mutex: - * maps a mono runtime reflection handle to MonoCustomAttrInfo* +/* + * LOCKING: Acquires the loader lock. */ -static GHashTable *dynamic_custom_attrs = NULL; - static MonoCustomAttrInfo* -lookup_custom_attr (void *member) +lookup_custom_attr (MonoImage *image, gpointer member) { - MonoCustomAttrInfo *ainfo, *res; - int size; + MonoCustomAttrInfo* res; - mono_reflection_lock (); - ainfo = g_hash_table_lookup (dynamic_custom_attrs, member); - mono_reflection_unlock (); + mono_loader_lock (); + res = mono_property_hash_lookup (image->property_hash, member, MONO_PROP_DYNAMIC_CATTR); + mono_loader_unlock (); - if (ainfo) { - /* Need to copy since it will be freed later */ - size = sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (ainfo->num_attrs - MONO_ZERO_LEN_ARRAY); - res = g_malloc0 (size); - memcpy (res, ainfo, size); - return res; - } - return NULL; + if (!res) + return NULL; + + return g_memdup (res, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (res->num_attrs - MONO_ZERO_LEN_ARRAY)); } static gboolean @@ -1125,7 +1128,7 @@ custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr) } static MonoCustomAttrInfo* -mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs) +mono_custom_attrs_from_builders (MonoMemPool *mp, MonoImage *image, MonoArray *cattrs) { int i, index, count, not_visible; MonoCustomAttrInfo *ainfo; @@ -1147,16 +1150,17 @@ mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs) } count -= not_visible; - ainfo = g_malloc0 (sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY)); + ainfo = mp_g_malloc0 (mp, sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY)); ainfo->image = image; ainfo->num_attrs = count; + ainfo->cached = mp != NULL; index = 0; mono_loader_lock (); for (i = 0; i < count; ++i) { cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i); if (custom_attr_visible (image, cattr)) { - unsigned char *saved = mono_mempool_alloc (image->mempool, mono_array_length (cattr->data)); + unsigned char *saved = mono_image_alloc (image, mono_array_length (cattr->data)); memcpy (saved, mono_array_addr (cattr->data, char, 0), mono_array_length (cattr->data)); ainfo->attrs [index].ctor = cattr->ctor->method; ainfo->attrs [index].data = saved; @@ -1169,21 +1173,24 @@ mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs) return ainfo; } +/* + * LOCKING: Acquires the loader lock. + */ static void mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs) { - MonoCustomAttrInfo *ainfo = mono_custom_attrs_from_builders (image, cattrs); + MonoCustomAttrInfo *ainfo, *tmp; - if (!ainfo) + if (!cattrs || !mono_array_length (cattrs)) return; - mono_reflection_lock (); - if (!dynamic_custom_attrs) - dynamic_custom_attrs = g_hash_table_new (NULL, NULL); - - g_hash_table_insert (dynamic_custom_attrs, obj, ainfo); - ainfo->cached = TRUE; - mono_reflection_unlock (); + ainfo = mono_custom_attrs_from_builders (image->mempool, image, cattrs); + mono_loader_lock (); + tmp = mono_property_hash_lookup (image->property_hash, obj, MONO_PROP_DYNAMIC_CATTR); + if (tmp) + mono_custom_attrs_free (tmp); + mono_property_hash_insert (image->property_hash, obj, MONO_PROP_DYNAMIC_CATTR, ainfo); + mono_loader_unlock (); } void @@ -1220,7 +1227,7 @@ mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, Mo for (i = 0; i < count; ++i) { cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i); values [MONO_CUSTOM_ATTR_PARENT] = idx; - token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE); + token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE, FALSE); type = mono_metadata_token_index (token); type <<= MONO_CUSTOM_ATTR_TYPE_BITS; switch (mono_metadata_token_table (token)) { @@ -1488,7 +1495,7 @@ mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuild values [MONO_METHODIMPL_CLASS] = tb->table_idx; values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS); - tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE); + tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE, FALSE); switch (mono_metadata_token_table (tok)) { case MONO_TABLE_MEMBERREF: tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF; @@ -1582,7 +1589,8 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass) { return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION); ta = klass->image->assembly; if (ta->dynamic || (ta == ass)) { - if (klass->generic_class) + if (klass->generic_class || klass->generic_container) + /* For generic type definitions, we want T, while REFLECTION returns T */ return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME); else return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION); @@ -1595,7 +1603,7 @@ static guint32 fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type) { SigBuffer buf; - guint32 idx; + guint32 idx, i; if (!assembly->save) return 0; @@ -1604,6 +1612,16 @@ fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type) sigbuffer_add_value (&buf, 0x06); /* encode custom attributes before the type */ + /* FIXME: This should probably go in encode_type () */ + if (type->num_mods) { + for (i = 0; i < type->num_mods; ++i) { + if (type->modifiers [i].required) + sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD); + else + sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT); + sigbuffer_add_value (&buf, type->modifiers [i].token); + } + } encode_type (assembly, type, &buf); idx = sigbuffer_add_to_blob_cached (assembly, &buf); sigbuffer_free (&buf); @@ -2346,6 +2364,34 @@ mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method) return token; } +static guint32 +mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method) +{ + guint32 token; + ReflectionMethodBuilder rmb; + char *name; + + token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method)); + if (token) + return token; + + name = mono_string_to_utf8 (method->name); + reflection_methodbuilder_from_method_builder (&rmb, method); + + /* + * A methodref signature can't contain an unmanaged calling convention. + * Since some flags are encoded as part of call_conv, we need to check against it. + */ + if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG) + rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT; + token = mono_image_get_memberref_token (assembly, ((MonoReflectionTypeBuilder*)rmb.type)->type.type, + name, method_builder_encode_signature (assembly, &rmb)); + + g_free (name); + g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token)); + return token; +} + static guint32 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original, const gchar *name, guint32 sig) @@ -2371,19 +2417,83 @@ mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 origina } static guint32 -mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb) +encode_generic_method_definition_sig (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb) +{ + SigBuffer buf; + int i; + guint32 nparams = mono_array_length (mb->generic_params); + guint32 idx; + + if (!assembly->save) + return 0; + + sigbuffer_init (&buf, 32); + + sigbuffer_add_value (&buf, 0xa); + sigbuffer_add_value (&buf, nparams); + + for (i = 0; i < nparams; i++) { + sigbuffer_add_value (&buf, MONO_TYPE_MVAR); + sigbuffer_add_value (&buf, i); + } + + idx = sigbuffer_add_to_blob_cached (assembly, &buf); + sigbuffer_free (&buf); + return idx; +} + +static guint32 +mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb) +{ + MonoDynamicTable *table; + guint32 *values; + guint32 token, mtoken = 0; + + token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb)); + if (token) + return token; + + table = &assembly->tables [MONO_TABLE_METHODSPEC]; + + mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb); + switch (mono_metadata_token_table (mtoken)) { + case MONO_TABLE_MEMBERREF: + mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF; + break; + case MONO_TABLE_METHOD: + mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF; + break; + default: + g_assert_not_reached (); + } + + if (assembly->save) { + alloc_table (table, table->rows + 1); + values = table->values + table->next_idx * MONO_METHODSPEC_SIZE; + values [MONO_METHODSPEC_METHOD] = mtoken; + values [MONO_METHODSPEC_SIGNATURE] = encode_generic_method_definition_sig (assembly, mb); + } + + token = MONO_TOKEN_METHOD_SPEC | table->next_idx; + table->next_idx ++; + + mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token)); + return token; +} + +static guint32 +mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec) { guint32 token; - ReflectionMethodBuilder rmb; + if (mb->generic_params && create_methodspec) + return mono_image_get_methodspec_token_for_generic_method_definition (assembly, mb); + token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, mb)); if (token) return token; - reflection_methodbuilder_from_method_builder (&rmb, mb); - - token = mono_image_get_memberref_token (assembly, ((MonoReflectionTypeBuilder*)rmb.type)->type.type, - mono_string_to_utf8 (rmb.name), method_builder_encode_signature (assembly, &rmb)); + token = mono_image_get_methodref_token_for_methodbuilder (assembly, mb); g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token)); return token; } @@ -2393,6 +2503,7 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor { guint32 token; ReflectionMethodBuilder rmb; + char *name; token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, mb)); if (token) @@ -2400,29 +2511,162 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor reflection_methodbuilder_from_ctor_builder (&rmb, mb); + name = mono_string_to_utf8 (rmb.name); token = mono_image_get_memberref_token (assembly, ((MonoReflectionTypeBuilder*)rmb.type)->type.type, - mono_string_to_utf8 (rmb.name), method_builder_encode_signature (assembly, &rmb)); + name, method_builder_encode_signature (assembly, &rmb)); + + g_free (name); g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token)); return token; } +static gboolean +is_field_on_inst (MonoClassField *field) +{ + return (field->parent->generic_class && field->parent->generic_class->is_dynamic && ((MonoDynamicGenericClass*)field->parent->generic_class)->fields); +} + +/* + * If FIELD is a field of a MonoDynamicGenericClass, return its non-inflated type. + */ +static MonoType* +get_field_on_inst_generic_type (MonoClassField *field) +{ + MonoDynamicGenericClass *dgclass; + int field_index; + + g_assert (is_field_on_inst (field)); + + dgclass = (MonoDynamicGenericClass*)field->parent->generic_class; + field_index = field - dgclass->fields; + + g_assert (field_index >= 0 && field_index < dgclass->count_fields); + return dgclass->field_generic_types [field_index]; +} + static guint32 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *f) { MonoType *type; guint32 token; + MonoClassField *field; token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f)); if (token) return token; g_assert (f->field->parent); - type = f->field->generic_info ? f->field->generic_info->generic_type : f->field->type; + + field = f->field; + if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) { + int index = field - field->parent->fields; + type = field->parent->generic_class->container_class->fields [index].type; + } else { + if (is_field_on_inst (f->field)) + type = get_field_on_inst_generic_type (f->field); + else + type = f->field->type; + } token = mono_image_get_memberref_token (assembly, &f->field->parent->byval_arg, - f->field->name, fieldref_encode_signature (assembly, type)); + mono_field_get_name (f->field), + fieldref_encode_signature (assembly, type)); g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token)); return token; } +static guint32 +mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFieldOnTypeBuilderInst *f) +{ + guint32 token; + MonoClass *klass; + MonoGenericClass *gclass; + MonoDynamicGenericClass *dgclass; + MonoReflectionFieldBuilder *fb = f->fb; + char *name; + + token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f)); + if (token) + return token; + klass = mono_class_from_mono_type (f->inst->type.type); + gclass = f->inst->type.type->data.generic_class; + g_assert (gclass->is_dynamic); + dgclass = (MonoDynamicGenericClass *) gclass; + + name = mono_string_to_utf8 (fb->name); + token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, + field_encode_signature (assembly, fb)); + g_free (name); + g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER (token)); + return token; +} + +static guint32 +mono_image_get_ctor_on_inst_token (MonoDynamicImage *assembly, MonoReflectionCtorOnTypeBuilderInst *c, gboolean create_methodspec) +{ + guint32 sig, token; + MonoClass *klass; + MonoGenericClass *gclass; + MonoDynamicGenericClass *dgclass; + MonoReflectionCtorBuilder *cb = c->cb; + ReflectionMethodBuilder rmb; + char *name; + + /* A ctor cannot be a generic method, so we can ignore create_methodspec */ + + token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, c)); + if (token) + return token; + klass = mono_class_from_mono_type (c->inst->type.type); + gclass = c->inst->type.type->data.generic_class; + g_assert (gclass->is_dynamic); + dgclass = (MonoDynamicGenericClass *) gclass; + + reflection_methodbuilder_from_ctor_builder (&rmb, cb); + + name = mono_string_to_utf8 (rmb.name); + + sig = method_builder_encode_signature (assembly, &rmb); + + token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig); + g_free (name); + + g_hash_table_insert (assembly->handleref, c, GUINT_TO_POINTER (token)); + return token; +} + +static guint32 +mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec) +{ + guint32 sig, token; + MonoClass *klass; + MonoGenericClass *gclass; + MonoReflectionMethodBuilder *mb = m->mb; + ReflectionMethodBuilder rmb; + char *name; + + if (create_methodspec && mb->generic_params) + // FIXME: + g_assert_not_reached (); + + token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m)); + if (token) + return token; + klass = mono_class_from_mono_type (m->inst->type.type); + gclass = m->inst->type.type->data.generic_class; + g_assert (gclass->is_dynamic); + + reflection_methodbuilder_from_method_builder (&rmb, mb); + + name = mono_string_to_utf8 (rmb.name); + + sig = method_builder_encode_signature (assembly, &rmb); + + token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig); + g_free (name); + + g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER (token)); + return token; +} + static guint32 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context) { @@ -2594,11 +2838,56 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder * return token; } +/* + * Return a copy of TYPE, adding the custom modifiers in MODREQ and MODOPT. + */ +static MonoType* +add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt) +{ + int i, count, len, pos; + MonoType *t; + + count = 0; + if (modreq) + count += mono_array_length (modreq); + if (modopt) + count += mono_array_length (modopt); + + if (count == 0) + return mono_metadata_type_dup (NULL, type); + + len = sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod); + t = g_malloc (len); + memcpy (t, type, len); + + t->num_mods = count; + pos = 0; + if (modreq) { + for (i = 0; i < mono_array_length (modreq); ++i) { + MonoReflectionType *mod = mono_array_get (modreq, MonoReflectionType*, i); + t->modifiers [pos].required = 1; + t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod->type); + pos ++; + } + } + if (modopt) { + for (i = 0; i < mono_array_length (modopt); ++i) { + MonoReflectionType *mod = mono_array_get (modopt, MonoReflectionType*, i); + t->modifiers [pos].required = 0; + t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod->type); + pos ++; + } + } + + return t; +} + static guint32 mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb) { MonoDynamicTable *table; MonoClass *klass; + MonoType *custom = NULL; guint32 *values; guint32 token, pclass, parent, sig; gchar *name; @@ -2610,7 +2899,15 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi klass = mono_class_from_mono_type (fb->typeb->type); name = mono_string_to_utf8 (fb->name); - sig = fieldref_encode_signature (assembly, fb->type->type); + /* fb->type does not include the custom modifiers */ + /* FIXME: We should do this in one place when a fieldbuilder is created */ + if (fb->modreq || fb->modopt) { + custom = add_custom_modifiers (assembly, fb->type->type, fb->modreq, fb->modopt); + sig = fieldref_encode_signature (assembly, custom); + g_free (custom); + } else { + sig = fieldref_encode_signature (assembly, fb->type->type); + } parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb); g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC); @@ -2631,6 +2928,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)); + g_free (name); return token; } @@ -3231,6 +3529,8 @@ mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder values [MONO_EXP_TYPE_IMPLEMENTATION] = (idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF; values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name); values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space); + + table->next_idx++; } } } @@ -3311,6 +3611,19 @@ compare_declsecurity_attrs (const void *a, const void *b) return a_values [MONO_DECL_SECURITY_PARENT] - b_values [MONO_DECL_SECURITY_PARENT]; } +static int +compare_interface_impl (const void *a, const void *b) +{ + const guint32 *a_values = a; + const guint32 *b_values = b; + + int klass = a_values [MONO_INTERFACEIMPL_CLASS] - b_values [MONO_INTERFACEIMPL_CLASS]; + if (klass) + return klass; + + return a_values [MONO_INTERFACEIMPL_INTERFACE] - b_values [MONO_INTERFACEIMPL_INTERFACE]; +} + static void pad_heap (MonoDynamicStream *sh) { @@ -3373,7 +3686,8 @@ build_compressed_metadata (MonoDynamicImage *assembly) | ((guint64)1 << MONO_TABLE_FIELDLAYOUT) | ((guint64)1 << MONO_TABLE_FIELDRVA) | ((guint64)1 << MONO_TABLE_IMPLMAP) | ((guint64)1 << MONO_TABLE_NESTEDCLASS) | ((guint64)1 << MONO_TABLE_METHODIMPL) | ((guint64)1 << MONO_TABLE_CUSTOMATTRIBUTE) - | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM); + | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM) + | ((guint64)1 << MONO_TABLE_INTERFACEIMPL); /* Compute table sizes */ /* the MonoImage has already been created in mono_image_basic_init() */ @@ -3462,9 +3776,7 @@ build_compressed_metadata (MonoDynamicImage *assembly) *int32val = GUINT32_TO_LE (0); /* reserved */ p += 4; - if ((assembly->tables [MONO_TABLE_GENERICPARAM].rows > 0) || - (assembly->tables [MONO_TABLE_METHODSPEC].rows > 0) || - (assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT].rows > 0)) { + if (mono_framework_version () > 1) { *p++ = 2; /* version */ *p++ = 0; } else { @@ -3512,6 +3824,9 @@ build_compressed_metadata (MonoDynamicImage *assembly) table = &assembly->tables [MONO_TABLE_DECLSECURITY]; if (table->rows) qsort (table->values + MONO_DECL_SECURITY_SIZE, table->rows, sizeof (guint32) * MONO_DECL_SECURITY_SIZE, compare_declsecurity_attrs); + table = &assembly->tables [MONO_TABLE_INTERFACEIMPL]; + if (table->rows) + qsort (table->values + MONO_INTERFACEIMPL_SIZE, table->rows, sizeof (guint32) * MONO_INTERFACEIMPL_SIZE, compare_interface_impl); /* compress the tables */ for (i = 0; i < MONO_TABLE_NUM; i++){ @@ -3567,7 +3882,8 @@ build_compressed_metadata (MonoDynamicImage *assembly) * tokens for the method with ILGenerator @ilgen. */ static void -fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *assembly) { +fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *assembly) +{ guint32 code_idx = GPOINTER_TO_UINT (value); MonoReflectionILTokenInfo *iltoken; MonoReflectionFieldBuilder *field; @@ -3629,11 +3945,17 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse continue; } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) { MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field; - g_assert (f->generic_info); + g_assert (is_field_on_inst (f)); continue; } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder") || !strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) { continue; + } else if (!strcmp (iltoken->member->vtable->klass->name, "FieldOnTypeBuilderInst")) { + continue; + } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodOnTypeBuilderInst")) { + continue; + } else if (!strcmp (iltoken->member->vtable->klass->name, "ConstructorOnTypeBuilderInst")) { + continue; } else { g_assert_not_reached (); } @@ -3643,6 +3965,8 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method; g_assert (mono_method_signature (m)->generic_param_count); continue; + } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) { + continue; } else { g_assert_not_reached (); } @@ -3914,6 +4238,8 @@ mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb) } } +#ifndef DISABLE_REFLECTION_EMIT_SAVE + /* * mono_image_build_metadata() will fill the info in all the needed metadata tables * for the modulebuilder @moduleb. @@ -4063,6 +4389,18 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb) fixup_cattrs (assembly); } +#else /* DISABLE_REFLECTION_EMIT_SAVE */ + +void +mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb) +{ + g_error ("This mono runtime was configured with --enable-minimal=reflection_emit_save, so saving of dynamic assemblies is not supported."); +} + +#endif /* DISABLE_REFLECTION_EMIT_SAVE */ + +#ifndef DISABLE_REFLECTION_EMIT + /* * mono_image_insert_string: * @module: module builder object @@ -4158,20 +4496,23 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj; ReflectionMethodBuilder rmb; guint32 parent, sig; - + char *name; + reflection_methodbuilder_from_method_builder (&rmb, mb); rmb.opt_types = opt_param_types; sig = method_builder_encode_signature (assembly, &rmb); - parent = mono_image_create_token (assembly, obj, TRUE); + parent = mono_image_create_token (assembly, obj, TRUE, TRUE); g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD); parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS; parent |= MONO_MEMBERREF_PARENT_METHODDEF; + name = mono_string_to_utf8 (rmb.name); token = mono_image_get_varargs_method_token ( - assembly, parent, mono_string_to_utf8 (rmb.name), sig); + assembly, parent, name, sig); + g_free (name); } else { g_error ("requested method token for %s\n", klass->name); } @@ -4183,27 +4524,16 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon * mono_image_create_token: * @assembly: a dynamic assembly * @obj: + * @register_token: Whenever to register the token in the assembly->tokens hash. * * Get a token to insert in the IL code stream for the given MemberInfo. - * @obj can be one of: - * ConstructorBuilder - * EnumBuilder - * FieldBuilder - * GenericTypeParameterBuilder - * MethodBuilder - * MonoArrayMethod - * MonoCMethod - * MonoMethod - * MonoField - * MonoGenericClass - * MonoGenericMethod - * MonoGenericCMethod - * MonoType - * SignatureHelperxo - * TypeBuilder + * The metadata emission routines need to pass FALSE as REGISTER_TOKEN, since by that time, + * the table_idx-es were recomputed, so registering the token would overwrite an existing + * entry. */ guint32 -mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, gboolean create_methodspec) +mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, + gboolean create_methodspec, gboolean register_token) { MonoClass *klass; guint32 token = 0; @@ -4213,10 +4543,10 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, gboolean c MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj; MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type; - if (tb->module->dynamic_image == assembly && !tb->generic_params) + if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params) token = mb->table_idx | MONO_TOKEN_METHOD_DEF; else - token = mono_image_get_methodbuilder_token (assembly, mb); + token = mono_image_get_methodbuilder_token (assembly, mb, create_methodspec); /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/ } else if (strcmp (klass->name, "ConstructorBuilder") == 0) { MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj; @@ -4285,7 +4615,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, gboolean c /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/ } else if (strcmp (klass->name, "MonoField") == 0) { MonoReflectionField *f = (MonoReflectionField *)obj; - if ((f->field->parent->image == &assembly->image) && !f->field->generic_info) { + if ((f->field->parent->image == &assembly->image) && !is_field_on_inst (f->field)) { static guint32 field_table_idx = 0xffffff; field_table_idx --; token = MONO_TOKEN_FIELD_DEF | field_table_idx; @@ -4303,15 +4633,45 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, gboolean c MonoReflectionType *tb = (MonoReflectionType *)obj; token = mono_metadata_token_from_dor ( mono_image_typedef_or_ref (assembly, tb->type)); + } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) { + MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj; + token = mono_image_get_field_on_inst_token (assembly, f); + } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) { + MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj; + token = mono_image_get_ctor_on_inst_token (assembly, c, create_methodspec); + } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) { + MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj; + token = mono_image_get_method_on_inst_token (assembly, m, create_methodspec); } else { g_error ("requested token for %s\n", klass->name); } - mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj); + if (register_token) + mono_image_register_token (assembly, token, obj); return token; } +/* + * mono_image_register_token: + * + * Register the TOKEN->OBJ mapping in the mapping table in ASSEMBLY. This is required for + * the Module.ResolveXXXToken () methods to work. + */ +void +mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj) +{ + MonoObject *prev = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token)); + if (prev) { + /* There could be multiple MethodInfo objects with the same token */ + //g_assert (prev == obj); + } else { + mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj); + } +} + +#endif /* DISABLE_REFLECTION_EMIT */ + typedef struct { guint32 import_lookup_table; guint32 timestamp; @@ -4334,7 +4694,12 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c MonoDynamicImage *image; int i; - const char *version = mono_get_runtime_info ()->runtime_version; + const char *version; + + if (!strcmp (mono_get_runtime_info ()->framework_version, "2.1")) + version = "v2.0.50727"; /* HACK: SL 2 enforces the .net 2 metadata version */ + else + version = mono_get_runtime_info ()->runtime_version; #if HAVE_BOEHM_GC image = GC_MALLOC (sizeof (MonoDynamicImage)); @@ -4365,6 +4730,8 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c image->method_aux_hash = g_hash_table_new (NULL, NULL); image->handleref = g_hash_table_new (NULL, NULL); image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC); + image->generic_def_objects = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC); + image->methodspec = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC); 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 = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal); @@ -4402,6 +4769,85 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c return image; } +static void +free_blob_cache_entry (gpointer key, gpointer val, gpointer user_data) +{ + g_free (key); +} + +void +mono_dynamic_image_free (MonoDynamicImage *image) +{ + MonoDynamicImage *di = image; + GList *list; + int i; + + if (di->methodspec) + mono_g_hash_table_destroy (di->methodspec); + if (di->typespec) + g_hash_table_destroy (di->typespec); + if (di->typeref) + g_hash_table_destroy (di->typeref); + if (di->handleref) + g_hash_table_destroy (di->handleref); + if (di->tokens) + mono_g_hash_table_destroy (di->tokens); + if (di->generic_def_objects) + mono_g_hash_table_destroy (di->generic_def_objects); + if (di->blob_cache) { + g_hash_table_foreach (di->blob_cache, free_blob_cache_entry, NULL); + g_hash_table_destroy (di->blob_cache); + } + if (di->standalonesig_cache) + g_hash_table_destroy (di->standalonesig_cache); + for (list = di->array_methods; list; list = list->next) { + ArrayMethod *am = (ArrayMethod *)list->data; + g_free (am->sig); + g_free (am->name); + g_free (am); + } + g_list_free (di->array_methods); + if (di->gen_params) { + for (i = 0; i < di->gen_params->len; i++) { + GenericParamTableEntry *entry = g_ptr_array_index (di->gen_params, i); + if (entry->gparam->type.type) { + MonoGenericParam *param = entry->gparam->type.type->data.generic_param; + g_free ((char*)param->name); + g_free (param); + g_free (entry->gparam->type.type); + } + g_free (entry); + } + g_ptr_array_free (di->gen_params, TRUE); + } + if (di->token_fixups) + mono_g_hash_table_destroy (di->token_fixups); + if (di->method_to_table_idx) + g_hash_table_destroy (di->method_to_table_idx); + if (di->field_to_table_idx) + g_hash_table_destroy (di->field_to_table_idx); + if (di->method_aux_hash) + g_hash_table_destroy (di->method_aux_hash); + g_free (di->strong_name); + g_free (di->win32_res); + if (di->public_key) + g_free (di->public_key); + + /*g_print ("string heap destroy for image %p\n", di);*/ + mono_dynamic_stream_reset (&di->sheap); + mono_dynamic_stream_reset (&di->code); + mono_dynamic_stream_reset (&di->resources); + mono_dynamic_stream_reset (&di->us); + mono_dynamic_stream_reset (&di->blob); + mono_dynamic_stream_reset (&di->tstream); + mono_dynamic_stream_reset (&di->guid); + for (i = 0; i < MONO_TABLE_NUM; ++i) { + g_free (di->tables [i].values); + } +} + +#ifndef DISABLE_REFLECTION_EMIT + /* * mono_image_basic_init: * @assembly: an assembly builder object @@ -4476,18 +4922,20 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb) mono_assembly_invoke_load_hook ((MonoAssembly*)assembly); } +#endif /* DISABLE_REFLECTION_EMIT */ + static int calc_section_size (MonoDynamicImage *assembly) { int nsections = 0; /* alignment constraints */ - assembly->code.index += 3; - assembly->code.index &= ~3; + mono_image_add_stream_zero (&assembly->code, 4 - (assembly->code.index % 4)); + g_assert ((assembly->code.index % 4) == 0); assembly->meta_size += 3; assembly->meta_size &= ~3; - assembly->resources.index += 3; - assembly->resources.index &= ~3; + mono_image_add_stream_zero (&assembly->resources, 4 - (assembly->resources.index % 4)); + g_assert ((assembly->resources.index % 4) == 0); assembly->sections [MONO_SECTION_TEXT].size = assembly->meta_size + assembly->code.index + assembly->resources.index + assembly->strong_name_size; assembly->sections [MONO_SECTION_TEXT].attrs = SECT_FLAGS_HAS_CODE | SECT_FLAGS_MEM_EXECUTE | SECT_FLAGS_MEM_READ; @@ -4602,6 +5050,7 @@ resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf) MonoPEResourceDirEntry dir_entry; MonoPEResourceDataEntry data_entry; GSList *l; + guint32 res_id_entries; /* * For the format of the resource directory, see the article @@ -4620,32 +5069,35 @@ resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf) node->offset = p - begin; /* IMAGE_RESOURCE_DIRECTORY */ - dir.res_id_entries = GUINT32_TO_LE (g_slist_length (node->children)); + res_id_entries = g_slist_length (node->children); + dir.res_id_entries = GUINT16_TO_LE (res_id_entries); memcpy (p, &dir, sizeof (dir)); p += sizeof (dir); /* Reserve space for entries */ entries = p; - p += sizeof (dir_entry) * dir.res_id_entries; + p += sizeof (dir_entry) * res_id_entries; /* Write children */ for (l = node->children; l; l = l->next) { ResTreeNode *child = (ResTreeNode*)l->data; if (child->win32_res) { + guint32 size; child->offset = p - begin; /* IMAGE_RESOURCE_DATA_ENTRY */ data_entry.rde_data_offset = GUINT32_TO_LE (p - begin + sizeof (data_entry)); - data_entry.rde_size = mono_array_length (child->win32_res->res_data); + size = mono_array_length (child->win32_res->res_data); + data_entry.rde_size = GUINT32_TO_LE (size); memcpy (p, &data_entry, sizeof (data_entry)); p += sizeof (data_entry); - memcpy (p, mono_array_addr (child->win32_res->res_data, char, 0), data_entry.rde_size); - p += data_entry.rde_size; + memcpy (p, mono_array_addr (child->win32_res->res_data, char, 0), size); + p += size; } else { resource_tree_encode (child, begin, p, &p); } @@ -4654,10 +5106,9 @@ resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf) /* IMAGE_RESOURCE_ENTRY */ for (l = node->children; l; l = l->next) { ResTreeNode *child = (ResTreeNode*)l->data; - dir_entry.name_offset = GUINT32_TO_LE (child->id); - dir_entry.is_dir = child->win32_res ? 0 : 1; - dir_entry.dir_offset = GUINT32_TO_LE (child->offset); + MONO_PE_RES_DIR_ENTRY_SET_NAME (dir_entry, FALSE, child->id); + MONO_PE_RES_DIR_ENTRY_SET_DIR (dir_entry, !child->win32_res, child->offset); memcpy (entries, &dir_entry, sizeof (dir_entry)); entries += sizeof (dir_entry); @@ -4666,6 +5117,16 @@ resource_tree_encode (ResTreeNode *node, char *begin, char *p, char **endbuf) *endbuf = p; } +static void +resource_tree_free (ResTreeNode * node) +{ + GSList * list; + for (list = node->children; list; list = list->next) + resource_tree_free ((ResTreeNode*)list->data); + g_slist_free(node->children); + g_free (node); +} + static void assembly_add_win32_resources (MonoDynamicImage *assembly, MonoReflectionAssemblyBuilder *assemblyb) { @@ -4707,6 +5168,7 @@ assembly_add_win32_resources (MonoDynamicImage *assembly, MonoReflectionAssembly memcpy (assembly->win32_res, buf, p - buf); g_free (buf); + resource_tree_free (tree); } static void @@ -4716,10 +5178,10 @@ fixup_resource_directory (char *res_section, char *p, guint32 rva) int i; p += sizeof (MonoPEResourceDir); - for (i = 0; i < dir->res_named_entries + dir->res_id_entries; ++i) { + for (i = 0; i < GUINT16_FROM_LE (dir->res_named_entries) + GUINT16_FROM_LE (dir->res_id_entries); ++i) { MonoPEResourceDirEntry *dir_entry = (MonoPEResourceDirEntry*)p; - char *child = res_section + (GUINT32_FROM_LE (dir_entry->dir_offset)); - if (dir_entry->is_dir) { + char *child = res_section + MONO_PE_RES_DIR_ENTRY_DIR_OFFSET (*dir_entry); + if (MONO_PE_RES_DIR_ENTRY_IS_DIR (*dir_entry)) { fixup_resource_directory (res_section, child, rva); } else { MonoPEResourceDataEntry *data_entry = (MonoPEResourceDataEntry*)child; @@ -4738,6 +5200,8 @@ checked_write_file (HANDLE f, gconstpointer buffer, guint32 numbytes) g_error ("WriteFile returned %d\n", GetLastError ()); } +#ifndef DISABLE_REFLECTION_EMIT_SAVE + /* * mono_image_create_pefile: * @mb: a module builder object @@ -4746,7 +5210,8 @@ checked_write_file (HANDLE f, gconstpointer buffer, guint32 numbytes) * assembly->pefile where it can be easily retrieved later in chunks. */ void -mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file) { +mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file) +{ MonoMSDOSHeader *msdos; MonoDotNetHeader *header; MonoSectionTable *section; @@ -4964,6 +5429,10 @@ mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file) { cli_header = (MonoCLIHeader*)(assembly->code.data + assembly->cli_header_offset); cli_header->ch_size = GUINT32_FROM_LE (72); cli_header->ch_runtime_major = GUINT16_FROM_LE (2); + if (mono_framework_version () > 1) + cli_header->ch_runtime_minor = GUINT16_FROM_LE (5); + else + cli_header->ch_runtime_minor = GUINT16_FROM_LE (0); cli_header->ch_flags = GUINT32_FROM_LE (assemblyb->pe_kind); if (assemblyb->entry_point) { guint32 table_idx = 0; @@ -5094,6 +5563,18 @@ mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file) { assembly->blob_cache = NULL; } +#else /* DISABLE_REFLECTION_EMIT_SAVE */ + +void +mono_image_create_pefile (MonoReflectionModuleBuilder *mb, HANDLE file) +{ + g_assert_not_reached (); +} + +#endif /* DISABLE_REFLECTION_EMIT_SAVE */ + +#ifndef DISABLE_REFLECTION_EMIT + MonoReflectionModule * mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName) { @@ -5149,6 +5630,8 @@ mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *f return mono_module_get_object (mono_domain_get (), image); } +#endif /* DISABLE_REFLECTION_EMIT */ + /* * We need to return always the same object for MethodInfo, FieldInfo etc.. * but we need to consider the reflected type. @@ -5229,6 +5712,8 @@ register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynam CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL); } +#ifndef DISABLE_REFLECTION_EMIT + void mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb) { @@ -5266,6 +5751,8 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb) } } +#endif + /* * mono_assembly_get_object: * @domain: an app domain @@ -5543,6 +6030,30 @@ mono_type_get_object (MonoDomain *domain, MonoType *type) MonoReflectionType *res; MonoClass *klass = mono_class_from_mono_type (type); + /*we must avoid using @type as it might have come + * from a mono_metadata_type_dup and the caller + * expects that is can be freed. + * Using the right type from + */ + type = klass->byval_arg.byref == type->byref ? &klass->byval_arg : &klass->this_arg; + + /* void is very common */ + if (type->type == MONO_TYPE_VOID && domain->typeof_void) + return (MonoReflectionType*)domain->typeof_void; + + /* + * If the vtable of the given class was already created, we can use + * the MonoType from there and avoid all locking and hash table lookups. + * + * We cannot do this for TypeBuilders as mono_reflection_create_runtime_class expects + * that the resulting object is diferent. + */ + if (type == &klass->byval_arg && !klass->image->dynamic) { + MonoVTable *vtable = mono_class_try_get_vtable (domain, klass); + if (vtable && vtable->type) + return vtable->type; + } + mono_domain_lock (domain); if (!domain->type_hash) domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, @@ -5572,6 +6083,7 @@ mono_type_get_object (MonoDomain *domain, MonoType *type) return klass->reflection_info; } } + // FIXME: Get rid of this, do it in the icalls for Type mono_class_init (klass); #ifdef HAVE_SGEN_GC res = (MonoReflectionType *)mono_gc_alloc_pinned_obj (mono_class_vtable (domain, mono_defaults.monotype_class), mono_class_instance_size (mono_defaults.monotype_class)); @@ -5580,6 +6092,10 @@ mono_type_get_object (MonoDomain *domain, MonoType *type) #endif res->type = type; mono_g_hash_table_insert (domain->type_hash, type, res); + + if (type->type == MONO_TYPE_VOID) + MONO_OBJECT_SETREF (domain, typeof_void, res); + mono_domain_unlock (domain); return res; } @@ -5606,6 +6122,13 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl MonoClass *klass; MonoReflectionMethod *ret; + /* + * Don't let static RGCTX invoke wrappers get into + * MonoReflectionMethods. + */ + if (method->wrapper_type == MONO_WRAPPER_STATIC_RGCTX_INVOKE) + method = mono_marshal_method_from_wrapper (method); + if (method->is_inflated) { MonoReflectionGenericMethod *gret; @@ -5668,9 +6191,9 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie res = (MonoReflectionField *)mono_object_new (domain, monofield_klass); res->klass = klass; res->field = field; - MONO_OBJECT_SETREF (res, name, mono_string_new (domain, field->name)); - if (field->generic_info) - res->attrs = field->generic_info->generic_type->attrs; + MONO_OBJECT_SETREF (res, name, mono_string_new (domain, mono_field_get_name (field))); + if (is_field_on_inst (field)) + res->attrs = get_field_on_inst_generic_type (field)->attrs; else res->attrs = field->type->attrs; MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type)); @@ -5781,6 +6304,7 @@ MonoArray* mono_param_get_objects (MonoDomain *domain, MonoMethod *method) { static MonoClass *System_Reflection_ParameterInfo; + static MonoClass *System_Reflection_ParameterInfo_array; MonoArray *res = NULL; MonoReflectionMethod *member = NULL; MonoReflectionParameter *param = NULL; @@ -5791,14 +6315,23 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method) MonoObject *missing = NULL; MonoMarshalSpec **mspecs; MonoMethodSignature *sig; + MonoVTable *pinfo_vtable; int i; - if (!System_Reflection_ParameterInfo) - System_Reflection_ParameterInfo = mono_class_from_name ( - mono_defaults.corlib, "System.Reflection", "ParameterInfo"); + if (!System_Reflection_ParameterInfo_array) { + MonoClass *klass; + + klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "ParameterInfo"); + mono_memory_barrier (); + System_Reflection_ParameterInfo = klass; + + klass = mono_array_class_get (klass, 1); + mono_memory_barrier (); + System_Reflection_ParameterInfo_array = klass; + } if (!mono_method_signature (method)->param_count) - return mono_array_new (domain, System_Reflection_ParameterInfo, 0); + return mono_array_new_specific (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), 0); /* Note: the cache is based on the address of the signature into the method * since we already cache MethodInfos with the method as keys. @@ -5813,9 +6346,10 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method) mspecs = g_new (MonoMarshalSpec*, sig->param_count + 1); mono_method_get_marshal_info (method, mspecs); - res = mono_array_new (domain, System_Reflection_ParameterInfo, sig->param_count); + res = mono_array_new_specific (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), sig->param_count); + pinfo_vtable = mono_class_vtable (domain, System_Reflection_ParameterInfo); for (i = 0; i < sig->param_count; ++i) { - param = (MonoReflectionParameter *)mono_object_new (domain, System_Reflection_ParameterInfo); + param = (MonoReflectionParameter *)mono_object_new_specific (pinfo_vtable); MONO_OBJECT_SETREF (param, ClassImpl, mono_type_get_object (domain, sig->params [i])); MONO_OBJECT_SETREF (param, MemberImpl, (MonoObject*)member); MONO_OBJECT_SETREF (param, NameImpl, mono_string_new (domain, names [i])); @@ -6215,6 +6749,8 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed, /* last_point separates the namespace from the name */ last_point = NULL; + /* Skips spaces */ + while (*p == ' ') p++, start++, w++, name++; while (*p) { switch (*p) { @@ -6352,7 +6888,9 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed, break; if (*p == ',') rank++; - else if (*p != '*') /* '*' means unknown lower bound */ + else if (*p == '*') /* '*' means unknown lower bound */ + info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (-2)); + else return 0; ++p; } @@ -6411,6 +6949,12 @@ _mono_reflection_get_type_from_info (MonoTypeNameParse *info, MonoImage *image, if (info->assembly.name) { MonoAssembly *assembly = mono_assembly_loaded (&info->assembly); + if (!assembly && image && image->assembly && mono_assembly_names_equal (&info->assembly, &image->assembly->aname)) + /* + * This could happen in the AOT compiler case when the search hook is not + * installed. + */ + assembly = image->assembly; if (!assembly) { /* then we must load the assembly ourselve - see #60439 */ assembly = mono_assembly_load (&info->assembly, NULL, NULL); @@ -6437,6 +6981,7 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT MonoClass *klass; GList *mod; int modval; + gboolean bounded = FALSE; if (!image) image = mono_defaults.corlib; @@ -6448,13 +6993,13 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT if (!klass) return NULL; for (mod = info->nested; mod; mod = mod->next) { - GList *nested; + gpointer iter = NULL; + MonoClass *parent; - mono_class_init (klass); - nested = klass->nested_classes; - klass = NULL; - while (nested) { - klass = nested->data; + parent = klass; + mono_class_init (parent); + + while ((klass = mono_class_get_nested_types (parent, &iter))) { if (ignorecase) { if (g_strcasecmp (klass->name, mod->data) == 0) break; @@ -6462,8 +7007,6 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT if (strcmp (klass->name, mod->data) == 0) break; } - klass = NULL; - nested = nested->next; } if (!klass) break; @@ -6506,8 +7049,10 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT return &klass->this_arg; } else if (modval == -1) { klass = mono_ptr_class_get (&klass->byval_arg); + } else if (modval == -2) { + bounded = TRUE; } else { /* array rank */ - klass = mono_array_class_get (klass, modval); + klass = mono_bounded_array_class_get (klass, modval, bounded); } mono_class_init (klass); } @@ -6686,7 +7231,7 @@ mono_reflection_get_token (MonoObject *obj) MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj; /* Call mono_image_create_token so the object gets added to the tokens hash table */ - token = mono_image_create_token (((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image, obj, FALSE); + token = mono_image_create_token (((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image, obj, FALSE, TRUE); } else if (strcmp (klass->name, "TypeBuilder") == 0) { MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj; token = tb->table_idx | MONO_TOKEN_TYPE_DEF; @@ -6707,9 +7252,15 @@ mono_reflection_get_token (MonoObject *obj) } else if (strcmp (klass->name, "MonoField") == 0) { MonoReflectionField *f = (MonoReflectionField*)obj; - if (f->field->generic_info && f->field->generic_info->reflection_info) - return mono_reflection_get_token (f->field->generic_info->reflection_info); + if (is_field_on_inst (f->field)) { + MonoDynamicGenericClass *dgclass = (MonoDynamicGenericClass*)f->field->parent->generic_class; + int field_index = f->field - dgclass->fields; + MonoObject *obj; + g_assert (field_index >= 0 && field_index < dgclass->count_fields); + obj = dgclass->field_objects [field_index]; + return mono_reflection_get_token (obj); + } token = mono_class_get_field_token (f->field); } else if (strcmp (klass->name, "MonoProperty") == 0) { MonoReflectionProperty *p = (MonoReflectionProperty*)obj; @@ -7285,6 +7836,10 @@ mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo) result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs); for (i = 0; i < cinfo->num_attrs; ++i) { + if (!cinfo->attrs [i].ctor) + /* The cattr type is not finished yet */ + /* We should include the type name but cinfo doesn't contain it */ + mono_raise_exception (mono_get_exception_type_load (NULL, NULL)); attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size); mono_array_setref (result, i, attr); } @@ -7397,7 +7952,6 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx) MonoCustomAttrInfo* mono_custom_attrs_from_method (MonoMethod *method) { - MonoCustomAttrInfo *cinfo; guint32 idx; /* @@ -7409,8 +7963,9 @@ mono_custom_attrs_from_method (MonoMethod *method) if (method->is_inflated) method = ((MonoMethodInflated *) method)->declaring; - if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (method))) - return cinfo; + if (method->dynamic || method->klass->image->dynamic) + return lookup_custom_attr (method->klass->image, method); + idx = mono_method_get_index (method); idx <<= MONO_CUSTOM_ATTR_BITS; idx |= MONO_CUSTOM_ATTR_METHODDEF; @@ -7420,28 +7975,33 @@ mono_custom_attrs_from_method (MonoMethod *method) MonoCustomAttrInfo* mono_custom_attrs_from_class (MonoClass *klass) { - MonoCustomAttrInfo *cinfo; guint32 idx; if (klass->generic_class) klass = klass->generic_class->container_class; - - if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (klass))) - return cinfo; - idx = mono_metadata_token_index (klass->type_token); - idx <<= MONO_CUSTOM_ATTR_BITS; - idx |= MONO_CUSTOM_ATTR_TYPEDEF; + + if (klass->image->dynamic) + return lookup_custom_attr (klass->image, klass); + + if (klass->byval_arg.type == MONO_TYPE_VAR || klass->byval_arg.type == MONO_TYPE_MVAR) { + idx = mono_metadata_token_index (klass->sizes.generic_param_token); + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_GENERICPAR; + } else { + idx = mono_metadata_token_index (klass->type_token); + idx <<= MONO_CUSTOM_ATTR_BITS; + idx |= MONO_CUSTOM_ATTR_TYPEDEF; + } return mono_custom_attrs_from_index (klass->image, idx); } MonoCustomAttrInfo* mono_custom_attrs_from_assembly (MonoAssembly *assembly) { - MonoCustomAttrInfo *cinfo; guint32 idx; - if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (assembly))) - return cinfo; + if (assembly->image->dynamic) + return lookup_custom_attr (assembly->image, assembly); idx = 1; /* there is only one assembly */ idx <<= MONO_CUSTOM_ATTR_BITS; idx |= MONO_CUSTOM_ATTR_ASSEMBLY; @@ -7451,11 +8011,10 @@ mono_custom_attrs_from_assembly (MonoAssembly *assembly) static MonoCustomAttrInfo* mono_custom_attrs_from_module (MonoImage *image) { - MonoCustomAttrInfo *cinfo; guint32 idx; - if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (image))) - return cinfo; + if (image->dynamic) + return lookup_custom_attr (image, image); idx = 1; /* there is only one module */ idx <<= MONO_CUSTOM_ATTR_BITS; idx |= MONO_CUSTOM_ATTR_MODULE; @@ -7465,11 +8024,12 @@ mono_custom_attrs_from_module (MonoImage *image) MonoCustomAttrInfo* mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property) { - MonoCustomAttrInfo *cinfo; guint32 idx; - if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (property))) - return cinfo; + if (klass->image->dynamic) { + property = mono_metadata_get_corresponding_property_from_generic_type_definition (property); + return lookup_custom_attr (klass->image, property); + } idx = find_property_index (klass, property); idx <<= MONO_CUSTOM_ATTR_BITS; idx |= MONO_CUSTOM_ATTR_PROPERTY; @@ -7479,11 +8039,12 @@ mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property) MonoCustomAttrInfo* mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event) { - MonoCustomAttrInfo *cinfo; guint32 idx; - if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (event))) - return cinfo; + if (klass->image->dynamic) { + event = mono_metadata_get_corresponding_event_from_generic_type_definition (event); + return lookup_custom_attr (klass->image, event); + } idx = find_event_index (klass, event); idx <<= MONO_CUSTOM_ATTR_BITS; idx |= MONO_CUSTOM_ATTR_EVENT; @@ -7493,11 +8054,11 @@ mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event) MonoCustomAttrInfo* mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field) { - MonoCustomAttrInfo *cinfo; guint32 idx; - - if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (field))) - return cinfo; + if (klass->image->dynamic) { + field = mono_metadata_get_corresponding_field_from_generic_type_definition (field); + return lookup_custom_attr (klass->image, field); + } idx = find_field_index (klass, field); idx <<= MONO_CUSTOM_ATTR_BITS; idx |= MONO_CUSTOM_ATTR_FIELDDEF; @@ -7649,22 +8210,22 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj) cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1); } else if (strcmp ("AssemblyBuilder", klass->name) == 0) { MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj; - cinfo = mono_custom_attrs_from_builders (assemblyb->assembly.assembly->image, assemblyb->cattrs); + cinfo = mono_custom_attrs_from_builders (NULL, assemblyb->assembly.assembly->image, assemblyb->cattrs); } else if (strcmp ("TypeBuilder", klass->name) == 0) { MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj; - cinfo = mono_custom_attrs_from_builders (&tb->module->dynamic_image->image, tb->cattrs); + cinfo = mono_custom_attrs_from_builders (NULL, &tb->module->dynamic_image->image, tb->cattrs); } else if (strcmp ("ModuleBuilder", klass->name) == 0) { MonoReflectionModuleBuilder *mb = (MonoReflectionModuleBuilder*)obj; - cinfo = mono_custom_attrs_from_builders (&mb->dynamic_image->image, mb->cattrs); + cinfo = mono_custom_attrs_from_builders (NULL, &mb->dynamic_image->image, mb->cattrs); } else if (strcmp ("ConstructorBuilder", klass->name) == 0) { MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj; - cinfo = mono_custom_attrs_from_builders (cb->mhandle->klass->image, cb->cattrs); + cinfo = mono_custom_attrs_from_builders (NULL, cb->mhandle->klass->image, cb->cattrs); } else if (strcmp ("MethodBuilder", klass->name) == 0) { MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj; - cinfo = mono_custom_attrs_from_builders (mb->mhandle->klass->image, mb->cattrs); + cinfo = mono_custom_attrs_from_builders (NULL, mb->mhandle->klass->image, mb->cattrs); } else if (strcmp ("FieldBuilder", klass->name) == 0) { MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj; - cinfo = mono_custom_attrs_from_builders (&((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs); + cinfo = mono_custom_attrs_from_builders (NULL, &((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs); } else if (strcmp ("MonoGenericClass", klass->name) == 0) { MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)obj; cinfo = mono_reflection_get_custom_attrs_info ((MonoObject*)gclass->generic_type); @@ -7857,7 +8418,7 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type) *type = fb->type->type; } else { MonoReflectionField *f = (MonoReflectionField *)field; - *name = g_strdup (f->field->name); + *name = g_strdup (mono_field_get_name (f->field)); *type = f->field->type; } } @@ -8177,6 +8738,8 @@ encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char *retbuffer = buffer; } +#ifndef DISABLE_REFLECTION_EMIT + /* * mono_reflection_get_custom_attrs_blob: * @ctor: custom attribute constructor @@ -8318,7 +8881,7 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb) return; } - klass = mono_mempool_alloc0 (tb->module->dynamic_image->image.mempool, sizeof (MonoClass)); + klass = mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass)); klass->image = &tb->module->dynamic_image->image; @@ -8398,7 +8961,7 @@ mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb) if (tb->generic_container) return; - tb->generic_container = g_new0 (MonoGenericContainer, 1); + tb->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer)); tb->generic_container->owner.klass = klass; } @@ -8425,14 +8988,19 @@ mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb) g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass)); - klass->generic_container = tb->generic_container; + klass->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer)); + klass->generic_container->owner.klass = klass; klass->generic_container->type_argc = count; - klass->generic_container->type_params = g_new0 (MonoGenericParam, count); + klass->generic_container->type_params = mono_image_alloc0 (klass->image, sizeof (MonoGenericParam) * count); for (i = 0; i < count; i++) { MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i); klass->generic_container->type_params [i] = *gparam->type.type->data.generic_param; + /*Make sure we are a diferent type instance */ + klass->generic_container->type_params [i].owner = klass->generic_container; + klass->generic_container->type_params [i].pklass = NULL; + g_assert (klass->generic_container->type_params [i].owner); } @@ -8490,13 +9058,15 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb) mono_loader_unlock (); } +#endif /* DISABLE_REFLECTION_EMIT */ + static MonoMarshalSpec* -mono_marshal_spec_from_builder (MonoAssembly *assembly, +mono_marshal_spec_from_builder (MonoMemPool *mp, MonoAssembly *assembly, MonoReflectionMarshal *minfo) { MonoMarshalSpec *res; - res = g_new0 (MonoMarshalSpec, 1); + res = mp_g_new0 (mp, MonoMarshalSpec, 1); res->native = minfo->type; switch (minfo->type) { @@ -8637,7 +9207,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) { m->signature->pinvoke = 1; - method_aux = g_new0 (MonoReflectionMethodAux, 1); + method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1); method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_mp (mp, rmb->dllentry) : mono_mempool_strdup (mp, m->name); method_aux->dll = mono_string_to_utf8_mp (mp, rmb->dll); @@ -8699,7 +9269,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, header->num_clauses = num_clauses; if (num_clauses) { - header->clauses = method_encode_clauses ((MonoDynamicImage*)klass->image, + header->clauses = method_encode_clauses (mp, (MonoDynamicImage*)klass->image, rmb->ilgen, num_clauses); } @@ -8710,9 +9280,13 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, int count = mono_array_length (rmb->generic_params); MonoGenericContainer *container; - m->generic_container = container = rmb->generic_container; + container = rmb->generic_container; + if (container) { + m->is_generic = TRUE; + mono_method_set_generic_container (m, container); + } container->type_argc = count; - container->type_params = g_new0 (MonoGenericParam, count); + container->type_params = mp_g_new0 (mp, MonoGenericParam, count); container->owner.method = m; for (i = 0; i < count; i++) { @@ -8754,8 +9328,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) { if ((i > 0) && (pb->attrs)) { /* Make a copy since it might point to a shared type structure */ - /* FIXME: Alloc this from a mempool */ - m->signature->params [i - 1] = mono_metadata_type_dup (NULL, m->signature->params [i - 1]); + m->signature->params [i - 1] = mono_metadata_type_dup (mp, m->signature->params [i - 1]); m->signature->params [i - 1]->attrs = pb->attrs; } @@ -8785,7 +9358,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, if (pb->cattrs) { if (!method_aux->param_cattr) method_aux->param_cattr = mp_g_new0 (mp, MonoCustomAttrInfo*, m->signature->param_count + 1); - method_aux->param_cattr [i] = mono_custom_attrs_from_builders (klass->image, pb->cattrs); + method_aux->param_cattr [i] = mono_custom_attrs_from_builders (mp, klass->image, pb->cattrs); } } } @@ -8801,7 +9374,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, if (specs == NULL) specs = mp_g_new0 (mp, MonoMarshalSpec*, sig->param_count + 1); specs [pb->position] = - mono_marshal_spec_from_builder (klass->image->assembly, pb->marshal_info); + mono_marshal_spec_from_builder (mp, klass->image->assembly, pb->marshal_info); } } } @@ -8870,37 +9443,28 @@ static MonoClassField* fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* fb) { MonoClassField *field; - const char *p, *p2; - guint32 len, idx; + MonoType *custom; field = g_new0 (MonoClassField, 1); field->name = mono_string_to_utf8 (fb->name); - if (fb->attrs) { - /* FIXME: handle type modifiers */ - field->type = g_memdup (fb->type->type, sizeof (MonoType)); + if (fb->attrs || fb->modreq || fb->modopt) { + field->type = mono_metadata_type_dup (NULL, fb->type->type); field->type->attrs = fb->attrs; + + g_assert (klass->image->dynamic); + custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt); + g_free (field->type); + field->type = custom; } else { field->type = fb->type->type; } - if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data) - field->data = mono_array_addr (fb->rva_data, char, 0); /* FIXME: GC pin array */ if (fb->offset != -1) field->offset = fb->offset; field->parent = klass; mono_save_custom_attrs (klass->image, field, fb->cattrs); - if (fb->def_value) { - MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image; - field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT; - idx = encode_constant (assembly, fb->def_value, &field->def_type); - /* Copy the data from the blob since it might get realloc-ed */ - p = assembly->blob.data + idx; - len = mono_metadata_decode_blob_size (p, &p2); - len += p2 - p; - field->data = g_malloc (len); - memcpy ((gpointer)field->data, p, len); - } + // FIXME: Can't store fb->def_value/RVA, is it needed for field_on_insts ? return field; } @@ -8979,7 +9543,9 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M int count, i; MONO_ARCH_SAVE_REGS; + if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) { +#ifndef DISABLE_REFLECTION_EMIT MonoReflectionTypeBuilder *tb; MonoClass *klass; @@ -8988,6 +9554,10 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M klass = mono_class_from_mono_type (tb->type.type); method = methodbuilder_to_mono_method (klass, mb); +#else + g_assert_not_reached (); + method = NULL; +#endif } else { method = rmethod->method; } @@ -9015,27 +9585,58 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M inflated = mono_class_inflate_generic_method (method, &tmp_context); imethod = (MonoMethodInflated *) inflated; - MOVING_GC_REGISTER (&imethod->reflection_info); - imethod->reflection_info = rmethod; - + if (method->klass->image->dynamic) { + MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image; + /* + * This table maps metadata structures representing inflated methods/fields + * to the reflection objects representing their generic definitions. + */ + mono_loader_lock (); + mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod); + mono_loader_unlock (); + } + return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL); } +#ifndef DISABLE_REFLECTION_EMIT + static MonoMethod * -inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj) +inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj) { MonoMethodInflated *imethod; MonoGenericContext *context; - MonoClass *klass; + int i; + + /* + * With generic code sharing the klass might not be inflated. + * This can happen because classes inflated with their own + * type arguments are "normalized" to the uninflated class. + */ + if (!klass->generic_class) + return method; - klass = mono_class_from_mono_type (type->type.type); - g_assert (klass->generic_class); context = mono_class_get_context (klass); - imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full (method, klass, context); - if (method->generic_container) { - MOVING_GC_REGISTER (&imethod->reflection_info); - imethod->reflection_info = obj; + if (klass->method.count) { + /* Find the already created inflated method */ + for (i = 0; i < klass->method.count; ++i) { + g_assert (klass->methods [i]->is_inflated); + if (((MonoMethodInflated*)klass->methods [i])->declaring == method) + break; + } + g_assert (i < klass->method.count); + imethod = (MonoMethodInflated*)klass->methods [i]; + } else { + imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full (method, klass, context); + } + + if (method->is_generic && method->klass->image->dynamic) { + MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image; + + mono_loader_lock (); + mono_g_hash_table_insert (image->generic_def_objects, imethod, obj); + mono_loader_unlock (); } return (MonoMethod *) imethod; } @@ -9049,7 +9650,10 @@ inflate_method (MonoReflectionGenericClass *type, MonoObject *obj) gklass = mono_class_from_mono_type (type->generic_type->type.type); if (!strcmp (obj->vtable->klass->name, "MethodBuilder")) - method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj); + if (((MonoReflectionMethodBuilder*)obj)->mhandle) + method = ((MonoReflectionMethodBuilder*)obj)->mhandle; + else + method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj); else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj); else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod")) @@ -9059,9 +9663,10 @@ inflate_method (MonoReflectionGenericClass *type, MonoObject *obj) g_assert_not_reached (); } - return inflate_mono_method (type, method, obj); + return inflate_mono_method (mono_class_from_mono_type (type->type.type), method, obj); } +/*TODO avoid saving custom attrs for generic classes as it's enough to have them on the generic type definition.*/ void mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, MonoArray *ctors, MonoArray *fields, MonoArray *properties, @@ -9098,6 +9703,8 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono dgclass->fields = g_new0 (MonoClassField, dgclass->count_fields); dgclass->properties = g_new0 (MonoProperty, dgclass->count_properties); dgclass->events = g_new0 (MonoEvent, dgclass->count_events); + dgclass->field_objects = g_new0 (MonoObject*, dgclass->count_fields); + dgclass->field_generic_types = g_new0 (MonoType*, dgclass->count_fields); for (i = 0; i < dgclass->count_methods; i++) { MonoObject *obj = mono_array_get (methods, gpointer, i); @@ -9113,11 +9720,10 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono for (i = 0; i < dgclass->count_fields; i++) { MonoObject *obj = mono_array_get (fields, gpointer, i); - MonoClassField *field; - MonoInflatedField *ifield; + MonoClassField *field, *inflated_field = NULL; if (!strcmp (obj->vtable->klass->name, "FieldBuilder")) - field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj); + inflated_field = field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj); else if (!strcmp (obj->vtable->klass->name, "MonoField")) field = ((MonoReflectionField *) obj)->field; else { @@ -9125,16 +9731,19 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono g_assert_not_reached (); } - ifield = g_new0 (MonoInflatedField, 1); - ifield->generic_type = field->type; - MOVING_GC_REGISTER (&ifield->reflection_info); - ifield->reflection_info = obj; - dgclass->fields [i] = *field; dgclass->fields [i].parent = klass; - dgclass->fields [i].generic_info = ifield; dgclass->fields [i].type = mono_class_inflate_generic_type ( field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass)); + dgclass->field_generic_types [i] = field->type; + MOVING_GC_REGISTER (&dgclass->field_objects [i]); + dgclass->field_objects [i] = obj; + + if (inflated_field) { + g_free (inflated_field); + } else { + dgclass->fields [i].name = g_strdup (dgclass->fields [i].name); + } } for (i = 0; i < dgclass->count_properties; i++) { @@ -9153,11 +9762,12 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono property->set = inflate_method (type, (MonoObject *) pb->set_method); } else if (!strcmp (obj->vtable->klass->name, "MonoProperty")) { *property = *((MonoReflectionProperty *) obj)->property; + property->name = g_strdup (property->name); if (property->get) - property->get = inflate_mono_method (type, property->get, NULL); + property->get = inflate_mono_method (klass, property->get, NULL); if (property->set) - property->set = inflate_mono_method (type, property->set, NULL); + property->set = inflate_mono_method (klass, property->set, NULL); } else g_assert_not_reached (); } @@ -9178,11 +9788,12 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono event->remove = inflate_method (type, (MonoObject *) eb->remove_method); } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) { *event = *((MonoReflectionEvent *) obj)->event; + event->name = g_strdup (event->name); if (event->add) - event->add = inflate_mono_method (type, event->add, NULL); + event->add = inflate_mono_method (klass, event->add, NULL); if (event->remove) - event->remove = inflate_mono_method (type, event->remove, NULL); + event->remove = inflate_mono_method (klass, event->remove, NULL); } else g_assert_not_reached (); } @@ -9204,7 +9815,7 @@ ensure_runtime_vtable (MonoClass *klass) num = tb->ctors? mono_array_length (tb->ctors): 0; num += tb->num_methods; klass->method.count = num; - klass->methods = mono_mempool_alloc (klass->image->mempool, sizeof (MonoMethod*) * num); + klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * num); num = tb->ctors? mono_array_length (tb->ctors): 0; for (i = 0; i < num; ++i) klass->methods [i] = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i)); @@ -9215,7 +9826,7 @@ ensure_runtime_vtable (MonoClass *klass) if (tb->interfaces) { klass->interface_count = mono_array_length (tb->interfaces); - klass->interfaces = mono_mempool_alloc (klass->image->mempool, sizeof (MonoClass*) * klass->interface_count); + klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count); for (i = 0; i < klass->interface_count; ++i) { MonoReflectionType *iface = mono_array_get (tb->interfaces, gpointer, i); klass->interfaces [i] = mono_class_from_mono_type (iface->type); @@ -9300,31 +9911,40 @@ typebuilder_setup_fields (MonoClass *klass) MonoReflectionTypeBuilder *tb = klass->reflection_info; MonoReflectionFieldBuilder *fb; MonoClassField *field; + MonoMemPool *mp = klass->image->mempool; const char *p, *p2; int i; - guint32 len, idx; + guint32 len, idx, real_size = 0; klass->field.count = tb->num_fields; klass->field.first = 0; - if (!klass->field.count) + if (tb->class_size) { + g_assert ((tb->packing_size & 0xfffffff0) == 0); + klass->packing_size = tb->packing_size; + real_size = klass->instance_size + tb->class_size; + } + + if (!klass->field.count) { + klass->instance_size = MAX (klass->instance_size, real_size); return; + } - klass->fields = g_new0 (MonoClassField, klass->field.count); + klass->fields = mp_g_new0 (mp, MonoClassField, klass->field.count); + klass->field_def_values = mp_g_new0 (mp, MonoFieldDefaultValue, klass->field.count); for (i = 0; i < klass->field.count; ++i) { fb = mono_array_get (tb->fields, gpointer, i); field = &klass->fields [i]; - field->name = mono_string_to_utf8 (fb->name); + field->name = mp_string_to_utf8 (mp, fb->name); if (fb->attrs) { - /* FIXME: handle type modifiers */ - field->type = g_memdup (fb->type->type, sizeof (MonoType)); + field->type = mono_metadata_type_dup (mp, fb->type->type); field->type->attrs = fb->attrs; } else { field->type = fb->type->type; } if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data) - field->data = mono_array_addr (fb->rva_data, char, 0); + klass->field_def_values [i].data = mono_array_addr (fb->rva_data, char, 0); if (fb->offset != -1) field->offset = fb->offset; field->parent = klass; @@ -9334,15 +9954,17 @@ typebuilder_setup_fields (MonoClass *klass) if (fb->def_value) { MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image; field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT; - idx = encode_constant (assembly, fb->def_value, &field->def_type); + idx = encode_constant (assembly, fb->def_value, &klass->field_def_values [i].def_type); /* Copy the data from the blob since it might get realloc-ed */ p = assembly->blob.data + idx; len = mono_metadata_decode_blob_size (p, &p2); len += p2 - p; - field->data = g_malloc (len); - memcpy ((gpointer)field->data, p, len); + klass->field_def_values [i].data = mono_mempool_alloc (mp, len); + memcpy ((gpointer)klass->field_def_values [i].data, p, len); } } + + klass->instance_size = MAX (klass->instance_size, real_size); mono_class_layout_fields (klass); } @@ -9351,17 +9973,18 @@ typebuilder_setup_properties (MonoClass *klass) { MonoReflectionTypeBuilder *tb = klass->reflection_info; MonoReflectionPropertyBuilder *pb; + MonoMemPool *mp = klass->image->mempool; int i; klass->property.count = tb->properties ? mono_array_length (tb->properties) : 0; klass->property.first = 0; - klass->properties = g_new0 (MonoProperty, klass->property.count); + klass->properties = mp_g_new0 (mp, 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); + klass->properties [i].name = mp_string_to_utf8 (mp, pb->name); if (pb->get_method) klass->properties [i].get = pb->get_method->mhandle; if (pb->set_method) @@ -9408,17 +10031,18 @@ typebuilder_setup_events (MonoClass *klass) { MonoReflectionTypeBuilder *tb = klass->reflection_info; MonoReflectionEventBuilder *eb; + MonoMemPool *mp = klass->image->mempool; int i, j; klass->event.count = tb->events ? mono_array_length (tb->events) : 0; klass->event.first = 0; - klass->events = g_new0 (MonoEvent, klass->event.count); + klass->events = mp_g_new0 (mp, 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); + klass->events [i].name = mp_string_to_utf8 (mp, eb->name); if (eb->add_method) klass->events [i].add = eb->add_method->mhandle; if (eb->remove_method) @@ -9427,7 +10051,7 @@ typebuilder_setup_events (MonoClass *klass) klass->events [i].raise = eb->raise_method->mhandle; if (eb->other_methods) { - klass->events [i].other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods) + 1); + klass->events [i].other = mp_g_new0 (mp, MonoMethod*, mono_array_length (eb->other_methods) + 1); for (j = 0; j < mono_array_length (eb->other_methods); ++j) { MonoReflectionMethodBuilder *mb = mono_array_get (eb->other_methods, @@ -9435,6 +10059,7 @@ typebuilder_setup_events (MonoClass *klass) klass->events [i].other [j] = mb->mhandle; } } + mono_save_custom_attrs (klass->image, &klass->events [i], eb->cattrs); } } @@ -9505,10 +10130,12 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb) if (tb->subtypes) { for (i = 0; i < mono_array_length (tb->subtypes); ++i) { MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i); - klass->nested_classes = g_list_prepend (klass->nested_classes, my_mono_class_from_mono_type (subtb->type.type)); + klass->nested_classes = g_list_prepend_mempool (klass->image->mempool, klass->nested_classes, my_mono_class_from_mono_type (subtb->type.type)); } } + klass->nested_classes_inited = TRUE; + /* fields and object layout */ if (klass->parent) { if (!klass->parent->size_inited) @@ -9568,7 +10195,9 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam if (gparam->mbuilder) { if (!gparam->mbuilder->generic_container) { - gparam->mbuilder->generic_container = g_new0 (MonoGenericContainer, 1); + MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)gparam->mbuilder->type; + MonoClass *klass = my_mono_class_from_mono_type (tb->type.type); + gparam->mbuilder->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer)); gparam->mbuilder->generic_container->is_method = TRUE; } param->owner = gparam->mbuilder->generic_container; @@ -9727,6 +10356,8 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb) mb->ilgen = NULL; } +#endif /* DISABLE_REFLECTION_EMIT */ + void mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb) { @@ -9750,6 +10381,8 @@ mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token) return mono_g_hash_table_lookup (image->tokens, GUINT_TO_POINTER (token)) != NULL; } +#ifndef DISABLE_REFLECTION_EMIT + /** * mono_reflection_lookup_dynamic_token: * @@ -9803,7 +10436,8 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 || strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) { result = ((MonoReflectionMethod*)obj)->method; - result = mono_class_inflate_generic_method (result, context); + if (context) + result = mono_class_inflate_generic_method (result, context); *handle_class = mono_defaults.methodhandle_class; g_assert (result); } else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) { @@ -9825,7 +10459,8 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon */ result = mb->mhandle; } - result = mono_class_inflate_generic_method (result, context); + if (context) + result = mono_class_inflate_generic_method (result, context); *handle_class = mono_defaults.methodhandle_class; } else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) { MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj; @@ -9837,7 +10472,8 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb); result = cb->mhandle; } - result = mono_class_inflate_generic_method (result, context); + if (context) + result = mono_class_inflate_generic_method (result, context); *handle_class = mono_defaults.methodhandle_class; } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) { result = ((MonoReflectionField*)obj)->field; @@ -9856,10 +10492,12 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon if (fb->handle && fb->handle->parent->generic_container) { MonoClass *klass = fb->handle->parent; - MonoClass *inflated = mono_class_from_mono_type (mono_class_inflate_generic_type (&klass->byval_arg, context)); + MonoType *type = mono_class_inflate_generic_type (&klass->byval_arg, context); + MonoClass *inflated = mono_class_from_mono_type (type); - result = mono_class_get_field_from_name (inflated, fb->handle->name); + result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle)); g_assert (result); + mono_metadata_free_type (type); } *handle_class = mono_defaults.fieldhandle_class; } else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) { @@ -9917,14 +10555,47 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon *handle_class = mono_defaults.methodhandle_class; } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) { MonoReflectionType *tb = (MonoReflectionType*)obj; - result = mono_class_from_mono_type (mono_class_inflate_generic_type (tb->type, context)); + MonoType *type = mono_class_inflate_generic_type (tb->type, context); + result = mono_class_from_mono_type (type); *handle_class = mono_defaults.typehandle_class; g_assert (result); + mono_metadata_free_type (type); } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) { MonoReflectionGenericClass *ref = (MonoReflectionGenericClass*)obj; - result = mono_class_from_mono_type (mono_class_inflate_generic_type (ref->type.type, context)); + MonoType *type = mono_class_inflate_generic_type (ref->type.type, context); + result = mono_class_from_mono_type (type); *handle_class = mono_defaults.typehandle_class; g_assert (result); + mono_metadata_free_type (type); + } else if (strcmp (obj->vtable->klass->name, "FieldOnTypeBuilderInst") == 0) { + MonoReflectionFieldOnTypeBuilderInst *f = (MonoReflectionFieldOnTypeBuilderInst*)obj; + MonoClass *inflated; + MonoType *type; + + type = mono_class_inflate_generic_type (f->inst->type.type, context); + inflated = mono_class_from_mono_type (type); + + g_assert (f->fb->handle); + result = mono_class_get_field_from_name (inflated, mono_field_get_name (f->fb->handle)); + g_assert (result); + mono_metadata_free_type (type); + *handle_class = mono_defaults.fieldhandle_class; + } else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) { + MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj; + MonoType *type = mono_class_inflate_generic_type (c->inst->type.type, context); + MonoClass *inflated_klass = mono_class_from_mono_type (type); + g_assert (c->cb->mhandle); + result = inflate_mono_method (inflated_klass, c->cb->mhandle, (MonoObject*)c->cb); + *handle_class = mono_defaults.methodhandle_class; + mono_metadata_free_type (type); + } else if (strcmp (obj->vtable->klass->name, "MethodOnTypeBuilderInst") == 0) { + MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj; + MonoType *type = mono_class_inflate_generic_type (m->inst->type.type, context); + MonoClass *inflated_klass = mono_class_from_mono_type (type); + g_assert (m->mb->mhandle); + result = inflate_mono_method (inflated_klass, m->mb->mhandle, (MonoObject*)m->mb); + *handle_class = mono_defaults.methodhandle_class; + mono_metadata_free_type (type); } else { g_print (obj->vtable->klass->name); g_assert_not_reached (); @@ -9932,6 +10603,146 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon return result; } +#else /* DISABLE_REFLECTION_EMIT */ + +MonoArray* +mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) +{ + g_assert_not_reached (); + return NULL; +} + +void +mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb) +{ + g_assert_not_reached (); +} + +void +mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb) +{ + g_assert_not_reached (); +} + +void +mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb) +{ + g_assert_not_reached (); +} + +void +mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb) +{ + g_assert_not_reached (); +} + +void +mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb) +{ + g_error ("This mono runtime was configured with --enable-minimal=reflection_emit, so System.Reflection.Emit is not supported."); +} + +void +mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb) +{ + g_assert_not_reached (); +} + +MonoReflectionModule * +mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName) +{ + g_assert_not_reached (); + return NULL; +} + +guint32 +mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str) +{ + g_assert_not_reached (); + return 0; +} + +guint32 +mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types) +{ + g_assert_not_reached (); + return 0; +} + +guint32 +mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, + gboolean create_methodspec, gboolean register_token) +{ + g_assert_not_reached (); + return 0; +} + +void +mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj) +{ +} + +void +mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, + MonoArray *ctors, MonoArray *fields, MonoArray *properties, + MonoArray *events) +{ + g_assert_not_reached (); +} + +void +mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides) +{ + *overrides = NULL; + *num_overrides = 0; +} + +MonoReflectionEvent * +mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb) +{ + g_assert_not_reached (); + return NULL; +} + +MonoReflectionType* +mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb) +{ + g_assert_not_reached (); + return NULL; +} + +void +mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam) +{ + g_assert_not_reached (); +} + +MonoArray * +mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig) +{ + g_assert_not_reached (); + return NULL; +} + +MonoArray * +mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig) +{ + g_assert_not_reached (); + return NULL; +} + +void +mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb) +{ +} + +gpointer +mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context) +{ + return NULL; +} + +#endif /* DISABLE_REFLECTION_EMIT */ /* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */ const static guint32 declsec_flags_map[] = {