X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Freflection.c;h=eaa9669aa9ca92ff2f32fb754f80224137f405bd;hb=ea0d1aad6b88126e8280f93597793929e3af056b;hp=41fb94b5cf678d301aa6e24555cb8a1bee2252f5;hpb=94ce5c5aaf912e55f106bbf3250612b02ac850b5;p=mono.git diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index 41fb94b5cf6..eaa9669aa9c 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -13,6 +13,7 @@ #include "mono/metadata/tabledefs.h" #include "mono/metadata/metadata-internals.h" #include "mono/metadata/class-internals.h" +#include "mono/metadata/gc-internal.h" #include "mono/metadata/tokentype.h" #include "mono/metadata/domain-internals.h" #include "mono/metadata/opcodes.h" @@ -55,6 +56,7 @@ typedef struct { MonoObject *type; MonoString *name; MonoBoolean init_locals; + MonoBoolean skip_visibility; MonoArray *return_modreq; MonoArray *return_modopt; MonoArray *param_modreq; @@ -142,6 +144,42 @@ 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 inline MonoType *dup_type (const MonoType *original); +/** + * mp_g_alloc: + * + * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate memory + * from the C heap. + */ +static gpointer +mp_g_malloc (MonoMemPool *mp, guint size) +{ + if (mp) + return mono_mempool_alloc (mp, size); + else + return g_malloc (size); +} + +/** + * mp_g_alloc0: + * + * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate memory + * from the C heap. + */ +static gpointer +mp_g_malloc0 (MonoMemPool *mp, guint size) +{ + if (mp) + return mono_mempool_alloc0 (mp, size); + else + return g_malloc0 (size); +} + +#define mp_g_new(mp,struct_type, n_structs) \ + ((struct_type *) mp_g_malloc (mp, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs)))) + +#define mp_g_new0(mp,struct_type, n_structs) \ + ((struct_type *) mp_g_malloc0 (mp, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs)))) + static void alloc_table (MonoDynamicTable *table, guint nrows) { @@ -285,7 +323,7 @@ add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int guint32 idx; char *copy; gpointer oldkey, oldval; - + copy = g_malloc (s1+s2); memcpy (copy, b1, s1); memcpy (copy + s1, b2, s2); @@ -836,7 +874,8 @@ method_encode_clauses (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, g for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) { ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i); finally_start = ex_info->start + ex_info->len; - g_assert (ex_info->handlers); + if (!ex_info->handlers) + continue; for (j = 0; j < mono_array_length (ex_info->handlers); ++j) { ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j); clause = &(clauses [clause_index]); @@ -1118,10 +1157,8 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs) void mono_custom_attrs_free (MonoCustomAttrInfo *ainfo) { - /* they are cached, so we don't free them */ - if (dynamic_custom_attrs && g_hash_table_lookup (dynamic_custom_attrs, ainfo)) - return; - g_free (ainfo); + if (!ainfo->cached) + g_free (ainfo); } /* @@ -1387,6 +1424,7 @@ reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, Mono rmb->name = mb->name; rmb->table_idx = NULL; rmb->init_locals = mb->init_locals; + rmb->skip_visibility = mb->skip_visibility; rmb->return_modreq = NULL; rmb->return_modopt = NULL; rmb->param_modreq = NULL; @@ -1397,6 +1435,38 @@ reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, Mono rmb->refs = NULL; } +static void +mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb) +{ + MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type; + MonoDynamicTable *table; + guint32 *values; + guint32 tok; + + if (!mb->override_method) + return; + + table = &assembly->tables [MONO_TABLE_METHODIMPL]; + table->rows ++; + alloc_table (table, table->rows); + values = table->values + table->rows * MONO_METHODIMPL_SIZE; + 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); + switch (mono_metadata_token_table (tok)) { + case MONO_TABLE_MEMBERREF: + tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF; + break; + case MONO_TABLE_METHOD: + tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF; + break; + default: + g_assert_not_reached (); + } + values [MONO_METHODIMPL_DECLARATION] = tok; +} + static void mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *assembly) { @@ -1441,30 +1511,6 @@ mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *a } } - if (mb->override_method) { - MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type; - guint32 tok; - table = &assembly->tables [MONO_TABLE_METHODIMPL]; - table->rows ++; - alloc_table (table, table->rows); - values = table->values + table->rows * MONO_METHODIMPL_SIZE; - 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); - switch (mono_metadata_token_table (tok)) { - case MONO_TABLE_MEMBERREF: - tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF; - break; - case MONO_TABLE_METHOD: - tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF; - break; - default: - g_assert_not_reached (); - } - values [MONO_METHODIMPL_DECLARATION] = tok; - } - if (mb->generic_params) { table = &assembly->tables [MONO_TABLE_GENERICPARAM]; table->rows += mono_array_length (mb->generic_params); @@ -2028,7 +2074,7 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o entry = g_new0 (GenericParamTableEntry, 1); entry->owner = owner; - entry->gparam = gparam; + entry->gparam = gparam; /* FIXME: GC object stored in unmanaged mem */ g_ptr_array_add (assembly->gen_params, entry); } @@ -2908,7 +2954,7 @@ collect_types (GPtrArray *types, MonoReflectionTypeBuilder *type) { int i; - g_ptr_array_add (types, type); + g_ptr_array_add (types, type); /* FIXME: GC object added to unmanaged memory */ if (!type->subtypes) return; @@ -3161,6 +3207,44 @@ mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModu } } +static void +mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly) +{ + MonoDynamicTable *table; + MonoClass *klass; + guint32 *values; + guint32 scope, idx; + int i; + + table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE]; + + if (assemblyb->type_forwarders) { + for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) { + MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType*, i); + if (!t) + continue; + + g_assert (t->type); + + klass = mono_class_from_mono_type (t->type); + + scope = resolution_scope_from_image (assembly, klass->image); + g_assert ((scope & MONO_RESOLTION_SCOPE_MASK) == MONO_RESOLTION_SCOPE_ASSEMBLYREF); + idx = scope >> MONO_RESOLTION_SCOPE_BITS; + + table->rows++; + alloc_table (table, table->rows); + values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE; + + values [MONO_EXP_TYPE_FLAGS] = TYPE_ATTRIBUTE_FORWARDER; + values [MONO_EXP_TYPE_TYPEDEF] = 0; + 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); + } + } +} + #define align_pointer(base,p)\ do {\ guint32 __diff = (unsigned char*)(p)-(unsigned char*)(base);\ @@ -3616,42 +3700,6 @@ fixup_cattrs (MonoDynamicImage *assembly) } } -/* - * fixup_methodimpl: - * - * The METHODIMPL table might contain METHODDEF tokens whose final - * value is not known when the table is emitted. - */ -static void -fixup_methodimpl (MonoDynamicImage *assembly) -{ - MonoDynamicTable *table; - guint32 *values; - guint32 decl, i, idx, token; - MonoObject *method; - - table = &assembly->tables [MONO_TABLE_METHODIMPL]; - - for (i = 0; i < table->rows; ++i) { - values = table->values + ((i + 1) * MONO_METHODIMPL_SIZE); - decl = values [MONO_METHODIMPL_DECLARATION]; - - idx = decl >> MONO_METHODDEFORREF_BITS; - if ((decl & MONO_METHODDEFORREF_MASK) != MONO_METHODDEFORREF_METHODDEF) - continue; - - token = mono_metadata_make_token (MONO_TABLE_METHOD, idx); - method = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token)); - g_assert (method); - - if (!strcmp (method->vtable->klass->name, "MethodBuilder")) { - token = mono_image_create_token (assembly, method, FALSE); - idx = mono_metadata_token_index (token); - values [MONO_METHODIMPL_DECLARATION] = (idx << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF; - } - } -} - static void assembly_add_resource_manifest (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, guint32 implementation) { @@ -3847,6 +3895,8 @@ mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb) mono_image_fill_export_table_from_module (domain, file_module, module_index, assembly); } } + if (assemblyb->type_forwarders) + mono_image_fill_export_table_from_type_forwarders (assemblyb, assembly); /* Emit MANIFESTRESOURCE table */ module_index = 0; @@ -3881,8 +3931,9 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb) MonoDynamicImage *assembly; MonoReflectionAssemblyBuilder *assemblyb; MonoDomain *domain; + GPtrArray *types; guint32 *values; - int i; + int i, j; assemblyb = moduleb->assemblyb; assembly = moduleb->dynamic_image; @@ -3937,48 +3988,44 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb) alloc_table (table, 1); mono_image_fill_module_table (domain, moduleb, assembly); - /* Emit types */ - { - /* Collect all types into a list sorted by their table_idx */ - GPtrArray *types = g_ptr_array_new (); + /* Collect all types into a list sorted by their table_idx */ + types = g_ptr_array_new (); - if (moduleb->types) - for (i = 0; i < moduleb->num_types; ++i) { - MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i); - collect_types (types, type); - } + if (moduleb->types) + for (i = 0; i < moduleb->num_types; ++i) { + MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i); + collect_types (types, type); + } - g_ptr_array_sort (types, (GCompareFunc)compare_types_by_table_idx); - table = &assembly->tables [MONO_TABLE_TYPEDEF]; - table->rows += types->len; - alloc_table (table, table->rows); + g_ptr_array_sort (types, (GCompareFunc)compare_types_by_table_idx); + table = &assembly->tables [MONO_TABLE_TYPEDEF]; + table->rows += types->len; + alloc_table (table, table->rows); - /* - * Emit type names + namespaces at one place inside the string heap, - * so load_class_names () needs to touch fewer pages. - */ - for (i = 0; i < types->len; ++i) { - MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i); - char *n; + /* + * Emit type names + namespaces at one place inside the string heap, + * so load_class_names () needs to touch fewer pages. + */ + for (i = 0; i < types->len; ++i) { + MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i); + char *n; - n = mono_string_to_utf8 (tb->nspace); - string_heap_insert (&assembly->sheap, n); - g_free (n); - } - for (i = 0; i < types->len; ++i) { - MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i); - char *n; + n = mono_string_to_utf8 (tb->nspace); + string_heap_insert (&assembly->sheap, n); + g_free (n); + } + for (i = 0; i < types->len; ++i) { + MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i); + char *n; - n = mono_string_to_utf8 (tb->name); - string_heap_insert (&assembly->sheap, n); - g_free (n); - } + n = mono_string_to_utf8 (tb->name); + string_heap_insert (&assembly->sheap, n); + g_free (n); + } - for (i = 0; i < types->len; ++i) { - MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i); - mono_image_get_type_info (domain, type, assembly); - } - g_ptr_array_free (types, TRUE); + for (i = 0; i < types->len; ++i) { + MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i); + mono_image_get_type_info (domain, type, assembly); } /* @@ -3999,8 +4046,33 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb) /* fixup tokens */ mono_g_hash_table_foreach (assembly->token_fixups, (GHFunc)fixup_method, assembly); + + /* Create the MethodImpl table. We do this after emitting all methods so we already know + * the final tokens and don't need another fixup pass. */ + + if (moduleb->global_methods) { + for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) { + MonoReflectionMethodBuilder *mb = mono_array_get ( + moduleb->global_methods, MonoReflectionMethodBuilder*, i); + mono_image_add_methodimpl (assembly, mb); + } + } + + for (i = 0; i < types->len; ++i) { + MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i); + if (type->methods) { + for (j = 0; j < type->num_methods; ++j) { + MonoReflectionMethodBuilder *mb = mono_array_get ( + type->methods, MonoReflectionMethodBuilder*, j); + + mono_image_add_methodimpl (assembly, mb); + } + } + } + + g_ptr_array_free (types, TRUE); + fixup_cattrs (assembly); - fixup_methodimpl (assembly); } /* @@ -4270,23 +4342,22 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c image->image.name = assembly_name; image->image.assembly_name = image->image.name; /* they may be different */ image->image.module_name = module_name; - image->image.version = version; + image->image.version = g_strdup (version); image->image.md_version_major = 1; image->image.md_version_minor = 1; image->image.dynamic = TRUE; - image->image.ref_count = 1; image->image.references = g_new0 (MonoAssembly*, 1); image->image.references [0] = NULL; mono_image_init (&image->image); - image->token_fixups = mono_g_hash_table_new (NULL, NULL); + image->token_fixups = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC); image->method_to_table_idx = g_hash_table_new (NULL, NULL); image->field_to_table_idx = g_hash_table_new (NULL, NULL); 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 (NULL, NULL); + image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_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); @@ -4358,19 +4429,21 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb) assembly->assembly.aname.culture = g_strdup (""); if (assemblyb->version) { - char **version = g_strsplit (mono_string_to_utf8 (assemblyb->version), ".", 4); - char **parts = version; - assembly->assembly.aname.major = atoi (*parts++); - assembly->assembly.aname.minor = atoi (*parts++); - assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0; - assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0; - - g_strfreev (version); + char *vstr = mono_string_to_utf8 (assemblyb->version); + char **version = g_strsplit (vstr, ".", 4); + char **parts = version; + assembly->assembly.aname.major = atoi (*parts++); + assembly->assembly.aname.minor = atoi (*parts++); + assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0; + assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0; + + g_strfreev (version); + g_free (vstr); } else { - assembly->assembly.aname.major = 0; - assembly->assembly.aname.minor = 0; - assembly->assembly.aname.build = 0; - assembly->assembly.aname.revision = 0; + assembly->assembly.aname.major = 0; + assembly->assembly.aname.minor = 0; + assembly->assembly.aname.build = 0; + assembly->assembly.aname.revision = 0; } assembly->run = assemblyb->access != 2; @@ -4457,6 +4530,7 @@ resource_tree_create (MonoArray *win32_resources) /* Create node */ + /* FIXME: BUG: this stores managed references in unmanaged memory */ lang_node = g_new0 (ResTreeNode, 1); lang_node->id = win32_res->lang_id; lang_node->win32_res = win32_res; @@ -5040,6 +5114,7 @@ mono_image_load_module (MonoReflectionAssemblyBuilder *ab, MonoString *fileName) if (image->assembly->image->modules) memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *)); new_modules [module_count] = image; + mono_image_addref (image); g_free (image->assembly->image->modules); image->assembly->image->modules = new_modules; @@ -5076,7 +5151,7 @@ reflected_equal (gconstpointer a, gconstpointer b) { static guint reflected_hash (gconstpointer a) { const ReflectedEntry *ea = a; - return GPOINTER_TO_UINT (ea->item); + return mono_aligned_addr_hash (ea->item); } #define CHECK_OBJECT(t,p,k) \ @@ -5087,7 +5162,7 @@ reflected_hash (gconstpointer a) { e.refclass = (k); \ mono_domain_lock (domain); \ if (!domain->refobject_hash) \ - domain->refobject_hash = mono_g_hash_table_new (reflected_hash, reflected_equal); \ + domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC); \ if ((_obj = mono_g_hash_table_lookup (domain->refobject_hash, &e))) { \ mono_domain_unlock (domain); \ return _obj; \ @@ -5097,6 +5172,8 @@ reflected_hash (gconstpointer a) { #if HAVE_BOEHM_GC #define ALLOC_REFENTRY GC_MALLOC (sizeof (ReflectedEntry)) +#elif HAVE_SGEN_GC +#define ALLOC_REFENTRY mono_gc_alloc_fixed (sizeof (ReflectedEntry), NULL) #else #define ALLOC_REFENTRY mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry)) #endif @@ -5109,7 +5186,7 @@ reflected_hash (gconstpointer a) { pe.refclass = (k); \ mono_domain_lock (domain); \ if (!domain->refobject_hash) \ - domain->refobject_hash = mono_g_hash_table_new (reflected_hash, reflected_equal); \ + domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC); \ _obj = mono_g_hash_table_lookup (domain->refobject_hash, &pe); \ if (!_obj) { \ ReflectedEntry *e = ALLOC_REFENTRY; \ @@ -5163,6 +5240,7 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb) if (ass->modules) memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *)); new_modules [module_count] = &image->image; + mono_image_addref (&image->image); g_free (ass->modules); ass->modules = new_modules; @@ -5209,11 +5287,12 @@ mono_module_get_object (MonoDomain *domain, MonoImage *image) res = (MonoReflectionModule *)mono_object_new (domain, System_Reflection_Module); res->image = image; - res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly); + MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly)); - res->fqname = mono_string_new (domain, image->name); - res->name = mono_string_new (domain, basename = g_path_get_basename (image->name)); - res->scopename = mono_string_new (domain, image->module_name); + MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, image->name)); + basename = g_path_get_basename (image->name); + MONO_OBJECT_SETREF (res, name, mono_string_new (domain, basename)); + MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, image->module_name)); g_free (basename); @@ -5230,8 +5309,6 @@ mono_module_get_object (MonoDomain *domain, MonoImage *image) g_assert (res->token); } - mono_image_addref (image); - CACHE_OBJECT (MonoReflectionModule *, image, res, NULL); } @@ -5255,8 +5332,8 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind g_assert (table_index < table->rows); mono_metadata_decode_row (table, table_index, cols, MONO_FILE_SIZE); - res->image = 0; - res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly); + res->image = NULL; + MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly)); name = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]); /* Check whenever the row has a corresponding row in the moduleref table */ @@ -5268,9 +5345,9 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind res->image = image->modules [i]; } - res->fqname = mono_string_new (domain, name); - res->name = mono_string_new (domain, name); - res->scopename = mono_string_new (domain, name); + MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, name)); + MONO_OBJECT_SETREF (res, name, mono_string_new (domain, name)); + MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, name)); res->is_resource = cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA; res->token = mono_metadata_make_token (MONO_TABLE_FILE, table_index + 1); @@ -5385,6 +5462,7 @@ mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst) gclass = mono_get_inflated_generic_class (geninst->data.generic_class); gklass = gclass->generic_class.container_class; + g_assert (gklass->generic_container); mono_class_init (gclass->klass); @@ -5392,14 +5470,42 @@ mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst) res->type.type = geninst; if (gklass->wastypebuilder && gklass->reflection_info) - res->generic_type = gklass->reflection_info; + MONO_OBJECT_SETREF (res, generic_type, gklass->reflection_info); else - res->generic_type = mono_type_get_object ( - domain, &gclass->generic_class.container_class->byval_arg); + MONO_OBJECT_SETREF (res, generic_type, mono_type_get_object (domain, &gklass->byval_arg)); return res; } +static gboolean +verify_safe_for_managed_space (MonoType *type) +{ + switch (type->type) { +#ifdef DEBUG_HARDER + case MONO_TYPE_ARRAY: + return verify_safe_for_managed_space (&type->data.array->eklass->byval_arg); + case MONO_TYPE_PTR: + return verify_safe_for_managed_space (type->data.type); + case MONO_TYPE_SZARRAY: + return verify_safe_for_managed_space (&type->data.klass->byval_arg); + case MONO_TYPE_GENERICINST: { + MonoGenericInst *inst = type->data.generic_class->inst; + int i; + if (!inst->is_open) + break; + for (i = 0; i < inst->type_argc; ++i) + if (!verify_safe_for_managed_space (inst->type_argv [i])) + return FALSE; + break; + } +#endif + case MONO_TYPE_VAR: + case MONO_TYPE_MVAR: + return TRUE; + } + return TRUE; +} + /* * mono_type_get_object: * @domain: an app domain @@ -5415,8 +5521,8 @@ mono_type_get_object (MonoDomain *domain, MonoType *type) mono_domain_lock (domain); if (!domain->type_hash) - domain->type_hash = mono_g_hash_table_new ((GHashFunc)mymono_metadata_type_hash, - (GCompareFunc)mymono_metadata_type_equal); + domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, + (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC); if ((res = mono_g_hash_table_lookup (domain->type_hash, type))) { mono_domain_unlock (domain); return res; @@ -5427,6 +5533,12 @@ mono_type_get_object (MonoDomain *domain, MonoType *type) mono_domain_unlock (domain); return res; } + + if (!verify_safe_for_managed_space (type)) { + mono_domain_unlock (domain); + mono_raise_exception (mono_get_exception_invalid_operation ("This type cannot be propagated to managed space")); + } + if (klass->reflection_info && !klass->wastypebuilder) { /* g_assert_not_reached (); */ /* should this be considered an error condition? */ @@ -5436,7 +5548,11 @@ mono_type_get_object (MonoDomain *domain, MonoType *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)); +#else res = (MonoReflectionType *)mono_object_new (domain, mono_defaults.monotype_class); +#endif res->type = type; mono_g_hash_table_insert (domain->type_hash, type, res); mono_domain_unlock (domain); @@ -5465,6 +5581,7 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl if (method->is_inflated) { MonoReflectionGenericMethod *gret; + method = mono_get_inflated_method (method); refclass = method->klass; CHECK_OBJECT (MonoReflectionMethod *, method, refclass); if ((*method->name == '.') && (!strcmp (method->name, ".ctor") || !strcmp (method->name, ".cctor"))) @@ -5475,8 +5592,8 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl gret = (MonoReflectionGenericMethod*)mono_object_new (domain, klass); gret->method.method = method; - gret->method.name = mono_string_new (domain, method->name); - gret->method.reftype = mono_type_get_object (domain, &refclass->byval_arg); + MONO_OBJECT_SETREF (gret, method.name, mono_string_new (domain, method->name)); + MONO_OBJECT_SETREF (gret, method.reftype, mono_type_get_object (domain, &refclass->byval_arg)); CACHE_OBJECT (MonoReflectionMethod *, method, (MonoReflectionMethod*)gret, refclass); } @@ -5492,8 +5609,8 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl ret = (MonoReflectionMethod*)mono_object_new (domain, klass); ret->method = method; - ret->name = mono_string_new (domain, method->name); - ret->reftype = mono_type_get_object (domain, &refclass->byval_arg); + MONO_OBJECT_SETREF (ret, name, mono_string_new (domain, method->name)); + MONO_OBJECT_SETREF (ret, reftype, mono_type_get_object (domain, &refclass->byval_arg)); CACHE_OBJECT (MonoReflectionMethod *, method, ret, refclass); } @@ -5517,12 +5634,12 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie res = (MonoReflectionField *)mono_object_new (domain, oklass); res->klass = klass; res->field = field; - res->name = mono_string_new (domain, field->name); + MONO_OBJECT_SETREF (res, name, mono_string_new (domain, field->name)); if (field->generic_info) res->attrs = field->generic_info->generic_type->attrs; else res->attrs = field->type->attrs; - res->type = mono_type_get_object (domain, field->type); + MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type)); CACHE_OBJECT (MonoReflectionField *, field, res, klass); } @@ -5592,6 +5709,7 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method) MonoType *type = NULL; MonoObject *dbnull = mono_get_dbnull_object (domain); MonoMarshalSpec **mspecs; + MonoMethodSignature *sig; int i; if (!System_Reflection_ParameterInfo) @@ -5606,29 +5724,30 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method) */ CHECK_OBJECT (MonoArray*, &(method->signature), NULL); + sig = mono_method_signature (method); member = mono_method_get_object (domain, method, NULL); - names = g_new (char *, mono_method_signature (method)->param_count); + names = g_new (char *, sig->param_count); mono_method_get_param_names (method, (const char **) names); - mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1); + mspecs = g_new (MonoMarshalSpec*, sig->param_count + 1); mono_method_get_marshal_info (method, mspecs); - res = mono_array_new (domain, System_Reflection_ParameterInfo, mono_method_signature (method)->param_count); - for (i = 0; i < mono_method_signature (method)->param_count; ++i) { + res = mono_array_new (domain, System_Reflection_ParameterInfo, sig->param_count); + for (i = 0; i < sig->param_count; ++i) { param = (MonoReflectionParameter *)mono_object_new (domain, System_Reflection_ParameterInfo); - param->ClassImpl = mono_type_get_object (domain, mono_method_signature (method)->params [i]); - param->MemberImpl = (MonoObject*)member; - param->NameImpl = mono_string_new (domain, names [i]); + 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])); param->PositionImpl = i; - param->AttrsImpl = mono_method_signature (method)->params [i]->attrs; + param->AttrsImpl = sig->params [i]->attrs; if (!(param->AttrsImpl & PARAM_ATTRIBUTE_HAS_DEFAULT)) { - param->DefaultValueImpl = dbnull; + MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull); } else { if (!blobs) { - blobs = g_new0 (char *, mono_method_signature (method)->param_count); - types = g_new0 (guint32, mono_method_signature (method)->param_count); + blobs = g_new0 (char *, sig->param_count); + types = g_new0 (guint32, sig->param_count); get_default_param_value_blobs (method, blobs, types); } @@ -5639,21 +5758,26 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method) type->data.klass = NULL; if (types [i] == MONO_TYPE_CLASS) type->data.klass = mono_defaults.object_class; - else + else if ((sig->params [i]->type == MONO_TYPE_VALUETYPE) && sig->params [i]->data.klass->enumtype) { + /* For enums, types [i] contains the base type */ + + type->type = MONO_TYPE_VALUETYPE; + type->data.klass = mono_class_from_mono_type (sig->params [i]); + } else type->data.klass = mono_class_from_mono_type (type); - - param->DefaultValueImpl = mono_get_object_from_blob (domain, type, blobs [i]); + + MONO_OBJECT_SETREF (param, DefaultValueImpl, mono_get_object_from_blob (domain, type, blobs [i])); /* Type in the Constant table is MONO_TYPE_CLASS for nulls */ if (types [i] != MONO_TYPE_CLASS && !param->DefaultValueImpl) - param->DefaultValueImpl = dbnull; + MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull); } if (mspecs [i + 1]) - param->MarshalAsImpl = (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]); + MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1])); - mono_array_set (res, gpointer, i, param); + mono_array_setref (res, i, param); } g_free (names); g_free (blobs); @@ -5731,21 +5855,21 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method) ret->init_locals = header->init_locals; ret->max_stack = header->max_stack; ret->local_var_sig_token = local_var_sig_token; - ret->il = mono_array_new (domain, mono_defaults.byte_class, header->code_size); - memcpy (mono_array_addr (ret->il, guint8*, 0), header->code, header->code_size); + MONO_OBJECT_SETREF (ret, il, mono_array_new (domain, mono_defaults.byte_class, header->code_size)); + memcpy (mono_array_addr (ret->il, guint8, 0), header->code, header->code_size); /* Locals */ - ret->locals = mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals); + MONO_OBJECT_SETREF (ret, locals, mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals)); for (i = 0; i < header->num_locals; ++i) { MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new (domain, System_Reflection_LocalVariableInfo); - info->local_type = mono_type_get_object (domain, header->locals [i]); + MONO_OBJECT_SETREF (info, local_type, mono_type_get_object (domain, header->locals [i])); info->is_pinned = header->locals [i]->pinned; info->local_index = i; - mono_array_set (ret->locals, MonoReflectionLocalVariableInfo*, i, info); + mono_array_setref (ret->locals, i, info); } /* Exceptions */ - ret->clauses = mono_array_new (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses); + MONO_OBJECT_SETREF (ret, clauses, mono_array_new (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses)); for (i = 0; i < header->num_clauses; ++i) { MonoReflectionExceptionHandlingClause *info = (MonoReflectionExceptionHandlingClause*)mono_object_new (domain, System_Reflection_ExceptionHandlingClause); MonoExceptionClause *clause = &header->clauses [i]; @@ -5758,9 +5882,9 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method) if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) info->filter_offset = clause->data.filter_offset; else if (clause->data.catch_class) - info->catch_type = mono_type_get_object (mono_domain_get (), &clause->data.catch_class->byval_arg); + MONO_OBJECT_SETREF (info, catch_type, mono_type_get_object (mono_domain_get (), &clause->data.catch_class->byval_arg)); - mono_array_set (ret->clauses, MonoReflectionExceptionHandlingClause*, i, info); + mono_array_setref (ret->clauses, i, info); } CACHE_OBJECT (MonoReflectionMethodBody *, method, ret, NULL); @@ -6443,12 +6567,7 @@ mono_reflection_get_token (MonoObject *obj) token = mb->table_idx | MONO_TOKEN_METHOD_DEF; } else if (strcmp (klass->name, "FieldBuilder") == 0) { MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj; - MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb; - if (tb->generic_params) { - g_assert_not_reached (); - } else { - token = fb->table_idx | MONO_TOKEN_FIELD_DEF; - } + token = fb->table_idx | MONO_TOKEN_FIELD_DEF; } else if (strcmp (klass->name, "TypeBuilder") == 0) { MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj; token = tb->table_idx | MONO_TOKEN_TYPE_DEF; @@ -6456,20 +6575,22 @@ mono_reflection_get_token (MonoObject *obj) MonoReflectionType *tb = (MonoReflectionType *)obj; token = mono_class_from_mono_type (tb->type)->type_token; } else if (strcmp (klass->name, "MonoCMethod") == 0 || - strcmp (klass->name, "MonoMethod") == 0) { + strcmp (klass->name, "MonoMethod") == 0 || + strcmp (klass->name, "MonoGenericMethod") == 0 || + strcmp (klass->name, "MonoGenericCMethod") == 0) { MonoReflectionMethod *m = (MonoReflectionMethod *)obj; if (m->method->is_inflated) { - g_assert_not_reached (); - } else if (mono_method_signature (m->method)->generic_param_count) { - g_assert_not_reached (); - } else if (m->method->klass->generic_class) { - g_assert_not_reached (); + MonoMethodInflated *inflated = (MonoMethodInflated *) m->method; + return inflated->declaring->token; } else { token = m->method->token; } } 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); + token = mono_class_get_field_token (f->field); } else if (strcmp (klass->name, "MonoProperty") == 0) { MonoReflectionProperty *p = (MonoReflectionProperty*)obj; @@ -6503,6 +6624,8 @@ static void* load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end) { int slen, type = t->type; + MonoClass *tklass = t->data.klass; + handle_enum: switch (type) { case MONO_TYPE_U1: @@ -6593,6 +6716,15 @@ handle_type: } else if (subt == 0x0E) { type = MONO_TYPE_STRING; goto handle_enum; + } else if (subt == 0x1D) { + MonoType simple_type = {{0}}; + int etype = *p; + p ++; + + type = MONO_TYPE_SZARRAY; + simple_type.type = etype; + tklass = mono_class_from_mono_type (&simple_type); + goto handle_enum; } else if (subt == 0x55) { char *n; MonoType *t; @@ -6627,8 +6759,8 @@ handle_type: *end = p; return NULL; } - arr = mono_array_new (mono_domain_get(), t->data.klass, alen); - basetype = t->data.klass->byval_arg.type; + arr = mono_array_new (mono_domain_get(), tklass, alen); + basetype = tklass->byval_arg.type; switch (basetype) { case MONO_TYPE_U1: @@ -6670,8 +6802,8 @@ handle_type: case MONO_TYPE_OBJECT: case MONO_TYPE_STRING: for (i = 0; i < alen; i++) { - MonoObject *item = load_cattr_value (image, &t->data.klass->byval_arg, p, &p); - mono_array_set (arr, gpointer, i, item); + MonoObject *item = load_cattr_value (image, &tklass->byval_arg, p, &p); + mono_array_setref (arr, i, item); } break; default: @@ -6807,9 +6939,9 @@ find_event_index (MonoClass *klass, MonoEvent *event) { } static MonoObject* -create_custom_attr (MonoImage *image, MonoMethod *method, const char *data, guint32 len) +create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len) { - const char *p = data; + const char *p = (const char*)data; const char *named; guint32 i, j, num_named; MonoObject *attr; @@ -6899,7 +7031,7 @@ create_custom_attr (MonoImage *image, MonoMethod *method, const char *data, guin } static MonoObject* -create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data, guint32 len) +create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len) { MonoArray *typedargs, *namedargs; MonoClass *attrklass; @@ -6907,7 +7039,7 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data, static MonoMethod *ctor; MonoDomain *domain; MonoObject *attr; - const char *p = data; + const char *p = (const char*)data; const char *named; guint32 i, j, num_named; void *params [3]; @@ -6944,7 +7076,7 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data, obj = type_is_reference (mono_method_signature (method)->params [i]) ? val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val); typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj); - mono_array_set (typedargs, void*, i, typedarg); + mono_array_setref (typedargs, i, typedarg); if (!type_is_reference (mono_method_signature (method)->params [i])) g_free (val); @@ -6989,7 +7121,7 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data, obj = type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val); typedarg = create_cattr_typed_arg (field->type, obj); namedarg = create_cattr_named_arg (minfo, typedarg); - mono_array_set (namedargs, void*, j, namedarg); + mono_array_setref (namedargs, j, namedarg); if (!type_is_reference (field->type)) g_free (val); } else if (named_type == 0x54) { @@ -7005,7 +7137,7 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data, obj = type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val); typedarg = create_cattr_typed_arg (prop_type, obj); namedarg = create_cattr_named_arg (minfo, typedarg); - mono_array_set (namedargs, void*, j, namedarg); + mono_array_setref (namedargs, j, namedarg); if (!type_is_reference (prop_type)) g_free (val); } @@ -7031,12 +7163,12 @@ mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo) result = mono_array_new (mono_domain_get (), klass, cinfo->num_attrs); for (i = 0; i < cinfo->num_attrs; ++i) { attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size); - mono_array_set (result, gpointer, i, attr); + mono_array_setref (result, i, attr); } return result; } -MonoArray* +static MonoArray* mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass) { MonoArray *result; @@ -7056,14 +7188,14 @@ mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_ for (i = 0; i < cinfo->num_attrs; ++i) { if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) { attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size); - mono_array_set (result, gpointer, n, attr); + mono_array_setref (result, n, attr); n ++; } } return result; } -MonoArray* +static MonoArray* mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo) { MonoArray *result; @@ -7077,7 +7209,7 @@ mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo) result = mono_array_new (mono_domain_get (), klass, cinfo->num_attrs); for (i = 0; i < cinfo->num_attrs; ++i) { attr = create_custom_attr_data (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size); - mono_array_set (result, gpointer, i, attr); + mono_array_setref (result, i, attr); } return result; } @@ -7129,7 +7261,7 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx) g_error ("Can't find custom attr constructor image: %s mtoken: 0x%08x", image->name, mtoken); data = mono_metadata_blob_heap (image, cols [MONO_CUSTOM_ATTR_VALUE]); ainfo->attrs [i].data_size = mono_metadata_decode_value (data, &data); - ainfo->attrs [i].data = data; + ainfo->attrs [i].data = (guchar*)data; } g_list_free (list); @@ -7461,14 +7593,17 @@ mono_reflection_get_custom_attrs_data (MonoObject *obj) return result; } +/** + * LOCKING: Assumes the loader lock is held. + */ static MonoMethodSignature* -parameters_to_signature (MonoArray *parameters) { +parameters_to_signature (MonoMemPool *mp, MonoArray *parameters) { MonoMethodSignature *sig; int count, i; count = parameters? mono_array_length (parameters): 0; - sig = g_malloc0 (sizeof (MonoMethodSignature) + sizeof (MonoType*) * count); + sig = mp_g_malloc0 (mp, sizeof (MonoMethodSignature) + sizeof (MonoType*) * count); sig->param_count = count; sig->sentinelpos = -1; /* FIXME */ for (i = 0; i < count; ++i) { @@ -7478,21 +7613,27 @@ parameters_to_signature (MonoArray *parameters) { return sig; } +/** + * LOCKING: Assumes the loader lock is held. + */ static MonoMethodSignature* -ctor_builder_to_signature (MonoReflectionCtorBuilder *ctor) { +ctor_builder_to_signature (MonoMemPool *mp, MonoReflectionCtorBuilder *ctor) { MonoMethodSignature *sig; - sig = parameters_to_signature (ctor->parameters); + sig = parameters_to_signature (mp, ctor->parameters); sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1; sig->ret = &mono_defaults.void_class->byval_arg; return sig; } +/** + * LOCKING: Assumes the loader lock is held. + */ static MonoMethodSignature* -method_builder_to_signature (MonoReflectionMethodBuilder *method) { +method_builder_to_signature (MonoMemPool *mp, MonoReflectionMethodBuilder *method) { MonoMethodSignature *sig; - sig = parameters_to_signature (method->parameters); + sig = parameters_to_signature (mp, method->parameters); sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1; sig->ret = method->rtype? method->rtype->type: &mono_defaults.void_class->byval_arg; sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0; @@ -7503,7 +7644,7 @@ static MonoMethodSignature* dynamic_method_to_signature (MonoReflectionDynamicMethod *method) { MonoMethodSignature *sig; - sig = parameters_to_signature (method->parameters); + sig = parameters_to_signature (NULL, method->parameters); sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1; sig->ret = method->rtype? method->rtype->type: &mono_defaults.void_class->byval_arg; sig->generic_param_count = 0; @@ -7672,7 +7813,19 @@ handle_type: *retbuffer = buffer; eclass = type->data.klass; arg_eclass = mono_object_class (arg)->element_class; - if (eclass->valuetype && arg_eclass->valuetype) { + + if (!eclass) { + /* Happens when we are called from the MONO_TYPE_OBJECT case below */ + eclass = mono_defaults.object_class; + } + if (eclass == mono_defaults.object_class && arg_eclass->valuetype) { + char *elptr = mono_array_addr ((MonoArray*)arg, char, 0); + int elsize = mono_class_array_element_size (arg_eclass); + for (i = 0; i < len; ++i) { + encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr); + elptr += elsize; + } + } else if (eclass->valuetype && arg_eclass->valuetype) { char *elptr = mono_array_addr ((MonoArray*)arg, char, 0); int elsize = mono_class_array_element_size (eclass); for (i = 0; i < len; ++i) { @@ -7686,12 +7839,17 @@ handle_type: } break; } - /* it may be a boxed value or a Type */ case MONO_TYPE_OBJECT: { MonoClass *klass; char *str; guint32 slen; + /* + * The parameter type is 'object' but the type of the actual + * argument is not. So we have to add type information to the blob + * too. This is completely undocumented in the spec. + */ + if (arg == NULL) { *p++ = MONO_TYPE_STRING; // It's same hack as MS uses *p++ = 0xFF; @@ -7700,7 +7858,7 @@ handle_type: klass = mono_object_class (arg); - if (mono_object_isinst (arg, mono_defaults.monotype_class)) { + if (mono_object_isinst (arg, mono_defaults.systemtype_class)) { *p++ = 0x50; goto handle_type; } else if (klass->enumtype) { @@ -7709,6 +7867,11 @@ handle_type: simple_type = MONO_TYPE_STRING; *p++ = 0x0E; goto handle_enum; + } else if (klass->rank == 1) { + simple_type = MONO_TYPE_SZARRAY; + *p++ = 0x1D; + *p++ = klass->element_class->byval_arg.type; + goto handle_enum; } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) { *p++ = simple_type = klass->byval_arg.type; goto handle_enum; @@ -7819,10 +7982,12 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj MONO_ARCH_SAVE_REGS; if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) { - sig = ctor_builder_to_signature ((MonoReflectionCtorBuilder*)ctor); + /* sig is freed later so allocate it in the heap */ + sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor); } else { sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method); } + g_assert (mono_array_length (ctorArgs) == sig->param_count); buflen = 256; p = buffer = g_malloc (buflen); @@ -7879,6 +8044,10 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj return result; } +#if HAVE_SGEN_GC +static void* reflection_info_desc = NULL; +#endif + /* * mono_reflection_setup_internal_class: * @tb: a TypeBuilder object @@ -7913,26 +8082,33 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb) klass = mono_class_from_mono_type (tb->type.type); klass->parent = NULL; /* fool mono_class_setup_parent */ - g_free (klass->supertypes); klass->supertypes = NULL; mono_class_setup_parent (klass, parent); mono_class_setup_mono_type (klass); mono_loader_unlock (); return; } - - klass = g_new0 (MonoClass, 1); + + klass = mono_mempool_alloc0 (tb->module->dynamic_image->image.mempool, sizeof (MonoClass)); klass->image = &tb->module->dynamic_image->image; klass->inited = 1; /* we lie to the runtime */ - klass->name = mono_string_to_utf8 (tb->name); - klass->name_space = mono_string_to_utf8 (tb->nspace); + klass->name = mono_string_to_utf8_mp (klass->image->mempool, tb->name); + klass->name_space = mono_string_to_utf8_mp (klass->image->mempool, tb->nspace); klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx; klass->flags = tb->attrs; klass->element_class = klass; - klass->reflection_info = tb; /* need to pin. */ + +#if HAVE_SGEN_GC + if (!reflection_info_desc) { + gsize bmap = 1; + reflection_info_desc = mono_gc_make_descr_from_bitmap (&bmap, 1); + } + mono_gc_register_root (&klass->reflection_info, sizeof (gpointer), reflection_info_desc); +#endif + klass->reflection_info = tb; /* Put into cache so mono_class_get () will find it */ mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx); @@ -8161,12 +8337,12 @@ mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass, if (spec->data.custom_data.custom_name) { mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image); if (mtype) - minfo->marshaltyperef = mono_type_get_object (domain, mtype); + MONO_OBJECT_SETREF (minfo, marshaltyperef, mono_type_get_object (domain, mtype)); - minfo->marshaltype = mono_string_new (domain, spec->data.custom_data.custom_name); + MONO_OBJECT_SETREF (minfo, marshaltype, mono_string_new (domain, spec->data.custom_data.custom_name)); } if (spec->data.custom_data.cookie) - minfo->mcookie = mono_string_new (domain, spec->data.custom_data.cookie); + MONO_OBJECT_SETREF (minfo, mcookie, mono_string_new (domain, spec->data.custom_data.cookie)); break; default: @@ -8185,24 +8361,39 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, MonoMethodNormal *pm; MonoMarshalSpec **specs; MonoReflectionMethodAux *method_aux; + MonoMemPool *mp; + gboolean dynamic; int i; + g_assert (!klass->generic_class); + + /* + * Methods created using a MethodBuilder should have their memory allocated + * inside the image mempool, while dynamic methods should have their memory + * malloc'd. + */ + dynamic = rmb->refs != NULL; + mp = dynamic ? NULL : klass->image->mempool; + + mono_loader_lock (); + if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) || (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) - m = (MonoMethod *)g_new0 (MonoMethodPInvoke, 1); + m = (MonoMethod *)mp_g_new0 (mp, MonoMethodPInvoke, 1); else if (rmb->refs) - m = (MonoMethod *)g_new0 (MonoMethodWrapper, 1); + m = (MonoMethod *)mp_g_new0 (mp, MonoMethodWrapper, 1); else - m = (MonoMethod *)g_new0 (MonoMethodNormal, 1); + m = (MonoMethod *)mp_g_new0 (mp, MonoMethodNormal, 1); pm = (MonoMethodNormal*)m; m->slot = -1; m->flags = rmb->attrs; m->iflags = rmb->iattrs; - m->name = mono_string_to_utf8 (rmb->name); + m->name = dynamic ? mono_string_to_utf8 (rmb->name) : mono_string_to_utf8_mp (mp, rmb->name); m->klass = klass; m->signature = sig; + m->skip_visibility = rmb->skip_visibility; if (rmb->table_idx) m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx); @@ -8216,17 +8407,18 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, method_aux = g_new0 (MonoReflectionMethodAux, 1); - method_aux->dllentry = rmb->dllentry ? g_strdup (mono_string_to_utf8 (rmb->dllentry)) : g_strdup (m->name); - method_aux->dll = g_strdup (mono_string_to_utf8 (rmb->dll)); + 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); ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags; if (klass->image->dynamic) g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux); + mono_loader_unlock (); + return m; - } else if (!m->klass->dummy && - !(m->flags & METHOD_ATTRIBUTE_ABSTRACT) && + } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) && !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) { MonoMethodHeader *header; guint32 code_size; @@ -8256,10 +8448,10 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, } } - header = g_malloc0 (sizeof (MonoMethodHeader) + + header = mp_g_malloc0 (mp, sizeof (MonoMethodHeader) + (num_locals - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*)); header->code_size = code_size; - header->code = g_malloc (code_size); + header->code = mp_g_malloc (mp, code_size); memcpy ((char*)header->code, code, code_size); header->max_stack = max_stack; header->init_locals = rmb->init_locals; @@ -8269,7 +8461,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionLocalBuilder *lb = mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i); - header->locals [i] = g_new0 (MonoType, 1); + header->locals [i] = mp_g_new0 (mp, MonoType, 1); memcpy (header->locals [i], lb->type->type, sizeof (MonoType)); } @@ -8285,6 +8477,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, if (rmb->generic_params) { int count = mono_array_length (rmb->generic_params); MonoGenericContainer *container; + MonoGenericContext *context; m->generic_container = container = rmb->generic_container; container->type_argc = count; @@ -8295,7 +8488,16 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i); container->type_params [i] = *gp->type.type->data.generic_param; + container->type_params [i].method = m; } + + context = &container->context; + context->container = container; + if (klass->generic_container) { + container->parent = klass->generic_container; + context->gclass = klass->generic_container->context.gclass; + } + context->gmethod = mono_get_shared_generic_method (container); } if (rmb->refs) { @@ -8305,7 +8507,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD; - mw->method_data = data = g_new (gpointer, rmb->nrefs + 1); + mw->method_data = data = mp_g_new (mp, gpointer, rmb->nrefs + 1); data [0] = GUINT_TO_POINTER (rmb->nrefs); for (i = 0; i < rmb->nrefs; ++i) data [i + 1] = rmb->refs [i]; @@ -8316,13 +8518,14 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, /* Parameter info */ if (rmb->pinfo) { if (!method_aux) - method_aux = g_new0 (MonoReflectionMethodAux, 1); - method_aux->param_names = g_new0 (char *, mono_method_signature (m)->param_count + 1); + method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1); + method_aux->param_names = mp_g_new0 (mp, char *, mono_method_signature (m)->param_count + 1); for (i = 0; i <= m->signature->param_count; ++i) { MonoReflectionParamBuilder *pb; 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] = g_memdup (m->signature->params [i - 1], sizeof (MonoType) + ((m->signature->params [i - 1]->num_mods - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod))); m->signature->params [i - 1]->attrs = pb->attrs; } @@ -8334,8 +8537,8 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, const char *p2; if (!method_aux->param_defaults) { - method_aux->param_defaults = g_new0 (guint8*, m->signature->param_count + 1); - method_aux->param_default_types = g_new0 (guint32, m->signature->param_count + 1); + method_aux->param_defaults = mp_g_new0 (mp, guint8*, m->signature->param_count + 1); + method_aux->param_default_types = mp_g_new0 (mp, guint32, m->signature->param_count + 1); } assembly = (MonoDynamicImage*)klass->image; idx = encode_constant (assembly, pb->def_value, &def_type); @@ -8343,16 +8546,16 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, p = assembly->blob.data + idx; len = mono_metadata_decode_blob_size (p, &p2); len += p2 - p; - method_aux->param_defaults [i] = g_malloc (len); + method_aux->param_defaults [i] = mp_g_malloc (mp, len); method_aux->param_default_types [i] = def_type; memcpy ((gpointer)method_aux->param_defaults [i], p, len); } if (pb->name) - method_aux->param_names [i] = mono_string_to_utf8 (pb->name); + method_aux->param_names [i] = dynamic ? mono_string_to_utf8 (pb->name) : mono_string_to_utf8_mp (mp, 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 = mp_g_new0 (mp, MonoCustomAttrInfo*, m->signature->param_count + 1); method_aux->param_cattr [i] = mono_custom_attrs_from_builders (klass->image, pb->cattrs); } } @@ -8367,7 +8570,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) { if (pb->marshal_info) { if (specs == NULL) - specs = g_new0 (MonoMarshalSpec*, sig->param_count + 1); + specs = mp_g_new0 (mp, MonoMarshalSpec*, sig->param_count + 1); specs [pb->position] = mono_marshal_spec_from_builder (klass->image->assembly, pb->marshal_info); } @@ -8375,13 +8578,15 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, } if (specs != NULL) { if (!method_aux) - method_aux = g_new0 (MonoReflectionMethodAux, 1); + method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1); method_aux->param_marshall = specs; } if (klass->image->dynamic && method_aux) g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux); + mono_loader_unlock (); + return m; } @@ -8391,7 +8596,9 @@ ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb) ReflectionMethodBuilder rmb; MonoMethodSignature *sig; - sig = ctor_builder_to_signature (mb); + mono_loader_lock (); + sig = ctor_builder_to_signature (klass->image->mempool, mb); + mono_loader_unlock (); reflection_methodbuilder_from_ctor_builder (&rmb, mb); @@ -8412,7 +8619,9 @@ methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb) ReflectionMethodBuilder rmb; MonoMethodSignature *sig; - sig = method_builder_to_signature (mb); + mono_loader_lock (); + sig = method_builder_to_signature (klass->image->mempool, mb); + mono_loader_unlock (); reflection_methodbuilder_from_method_builder (&rmb, mb); @@ -8433,9 +8642,6 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* const char *p, *p2; guint32 len, idx; - if (fb->handle) - return fb->handle; - field = g_new0 (MonoClassField, 1); field->name = mono_string_to_utf8 (fb->name); @@ -8447,11 +8653,10 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* 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); + 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; - fb->handle = field; mono_save_custom_attrs (klass->image, field, fb->cattrs); if (fb->def_value) { @@ -8469,9 +8674,8 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder* return field; } -static MonoType* -do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types, - MonoType *parent) +MonoType* +mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types) { MonoClass *klass; MonoReflectionTypeBuilder *tb = NULL; @@ -8481,7 +8685,7 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a gboolean is_dynamic = FALSE; MonoDomain *domain; MonoType *geninst; - int icount, i; + int i; klass = mono_class_from_mono_type (type->type); if (!klass->generic_container && !klass->generic_class && @@ -8495,7 +8699,6 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) { tb = (MonoReflectionTypeBuilder *) type; - icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0; is_dynamic = TRUE; } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericClass")) { MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type; @@ -8504,15 +8707,11 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a g_assert (!strcmp (((MonoObject *) rgt)->vtable->klass->name, "TypeBuilder")); tb = (MonoReflectionTypeBuilder *) rgt; - icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0; is_dynamic = TRUE; } else if (klass->wastypebuilder) { tb = (MonoReflectionTypeBuilder *) klass->reflection_info; - icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0; is_dynamic = TRUE; - } else { - icount = klass->interface_count; } if (is_dynamic) { @@ -8608,82 +8807,11 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a gclass->context->container = gclass->container_class->generic_container; gclass->context->gclass = gclass; - if (is_dynamic) { - dgclass->parent = parent; - dgclass->ifaces = g_new0 (MonoType *, icount); - dgclass->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); - dgclass->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types); - if (!dgclass->ifaces [i]) - dgclass->ifaces [i] = itype->type; - } - } - mono_loader_unlock (); return geninst; } -MonoType* -mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types) -{ - MonoClass *klass, *pklass = NULL; - MonoReflectionType *parent = NULL; - MonoType *the_parent = NULL, *geninst; - MonoReflectionTypeBuilder *tb = NULL; - MonoGenericClass *gclass; - MonoDomain *domain; - - domain = mono_object_domain (type); - klass = mono_class_from_mono_type (type->type); - - if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) { - tb = (MonoReflectionTypeBuilder *) type; - - if (tb->parent) { - parent = tb->parent; - pklass = mono_class_from_mono_type (parent->type); - } - } else if (klass->wastypebuilder) { - tb = (MonoReflectionTypeBuilder *) klass->reflection_info; - if (tb->parent) { - parent = tb->parent; - pklass = mono_class_from_mono_type (parent->type); - } - } else { - pklass = klass->parent; - if (pklass) - parent = mono_type_get_object (domain, &pklass->byval_arg); - else if (klass->generic_class && klass->generic_class->is_dynamic) { - MonoDynamicGenericClass *dgclass; - - dgclass = (MonoDynamicGenericClass *) klass->generic_class; - if (dgclass->parent) { - parent = mono_type_get_object (domain, dgclass->parent); - pklass = mono_class_from_mono_type (dgclass->parent); - } - } - } - - if (pklass && pklass->generic_class) - the_parent = mono_reflection_bind_generic_parameters (parent, type_argc, types); - - geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types, the_parent); - if (!geninst) - return NULL; - - gclass = geninst->data.generic_class; - - return geninst; -} - MonoType* mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **types) { @@ -8691,7 +8819,7 @@ mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **ty MonoGenericClass *gclass, *cached; MonoInflatedGenericClass *igclass; MonoType *geninst; - int icount, i; + int i; klass = mono_class_from_mono_type (type); if (!klass->generic_container && !klass->generic_class && @@ -8700,8 +8828,6 @@ mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **ty mono_loader_lock (); - icount = klass->interface_count; - igclass = g_new0 (MonoInflatedGenericClass, 1); gclass = &igclass->generic_class; gclass->is_inflated = TRUE; @@ -8885,32 +9011,41 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M static MonoMethod * inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj) { - MonoGenericMethod *gmethod; + MonoGenericMethod *gmethod = NULL; MonoInflatedGenericClass *gclass; MonoGenericContext *context; - int i; + MonoClass *klass; + int i, n; + klass = mono_class_from_mono_type (type->type.type); gclass = mono_get_inflated_generic_class (type->type.type->data.generic_class); + n = mono_method_signature (method)->generic_param_count; - gmethod = g_new0 (MonoGenericMethod, 1); - gmethod->generic_class = &gclass->generic_class; - gmethod->inst = g_new0 (MonoGenericInst, 1); - gmethod->reflection_info = obj; + context = gclass->generic_class.context; + g_assert (context && context->container); + if (n) { + gmethod = g_new0 (MonoGenericMethod, 1); + gmethod->generic_class = &gclass->generic_class; + gmethod->container = method->generic_container; + gmethod->reflection_info = obj; - gmethod->inst->type_argc = mono_method_signature (method)->generic_param_count; - gmethod->inst->type_argv = g_new0 (MonoType *, gmethod->inst->type_argc); + gmethod->inst = g_new0 (MonoGenericInst, 1); + gmethod->inst->type_argc = n; + gmethod->inst->type_argv = g_new0 (MonoType *, n); - for (i = 0; i < gmethod->inst->type_argc; i++) { - MonoGenericParam *gparam = &method->generic_container->type_params [i]; + for (i = 0; i < n; i++) { + MonoGenericParam *gparam = &method->generic_container->type_params [i]; + g_assert (gparam->pklass); + gmethod->inst->type_argv [i] = &gparam->pklass->byval_arg; + } - g_assert (gparam->pklass); - gmethod->inst->type_argv [i] = &gparam->pklass->byval_arg; - } + g_assert (gmethod->container->parent == context->container); - context = g_new0 (MonoGenericContext, 1); - context->container = gclass->generic_class.container_class->generic_container; - context->gclass = &gclass->generic_class; - context->gmethod = gmethod; + context = g_new0 (MonoGenericContext, 1); + context->container = gmethod->container; + context->gclass = &gclass->generic_class; + context->gmethod = gmethod; + } return mono_class_inflate_generic_method (method, context); } @@ -8919,14 +9054,14 @@ static MonoMethod * inflate_method (MonoReflectionGenericClass *type, MonoObject *obj) { MonoMethod *method; - MonoClass *klass; + MonoClass *gklass; - klass = mono_class_from_mono_type (type->type.type); + gklass = mono_class_from_mono_type (type->generic_type->type); if (!strcmp (obj->vtable->klass->name, "MethodBuilder")) - method = methodbuilder_to_mono_method (klass, (MonoReflectionMethodBuilder *) obj); + method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj); else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder")) - method = ctorbuilder_to_mono_method (klass, (MonoReflectionCtorBuilder *) obj); + method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj); else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod")) method = ((MonoReflectionMethod *) obj)->method; else { @@ -8944,7 +9079,7 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono { MonoGenericClass *gclass; MonoDynamicGenericClass *dgclass; - MonoClass *klass, *gklass, *pklass; + MonoClass *klass, *gklass; int i; MONO_ARCH_SAVE_REGS; @@ -8961,11 +9096,6 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono gklass = gclass->container_class; mono_class_init (gklass); - if (dgclass->parent) - pklass = mono_class_from_mono_type (dgclass->parent); - else - pklass = gklass->parent; - dgclass->count_methods = methods ? mono_array_length (methods) : 0; dgclass->count_ctors = ctors ? mono_array_length (ctors) : 0; dgclass->count_fields = fields ? mono_array_length (fields) : 0; @@ -9082,7 +9212,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 = g_new (MonoMethod*, num); + klass->methods = mono_mempool_alloc (klass->image->mempool, 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)); @@ -9093,16 +9223,19 @@ ensure_runtime_vtable (MonoClass *klass) if (tb->interfaces) { klass->interface_count = mono_array_length (tb->interfaces); - klass->interfaces = g_new (MonoClass*, klass->interface_count); + klass->interfaces = mono_mempool_alloc (klass->image->mempool, 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); } } - if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) + if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) { for (i = 0; i < klass->method.count; ++i) klass->methods [i]->slot = i; + + mono_class_setup_interface_offsets (klass); + } /* * The generic vtable is needed even if image->run is not set since some @@ -9241,6 +9374,8 @@ typebuilder_setup_properties (MonoClass *klass) klass->properties [i].get = pb->get_method->mhandle; if (pb->set_method) klass->properties [i].set = pb->set_method->mhandle; + + mono_save_custom_attrs (klass->image, &klass->properties [i], pb->cattrs); } } @@ -9372,8 +9507,8 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb) if (klass->parent) { if (!klass->parent->size_inited) mono_class_init (klass->parent); - klass->instance_size += klass->parent->instance_size; - klass->class_size += klass->parent->class_size; + klass->instance_size = klass->parent->instance_size; + klass->class_size = 0; klass->min_align = klass->parent->min_align; /* if the type has no fields we won't call the field_setup * routine which sets up klass->has_references. @@ -9397,6 +9532,7 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb) res = mono_type_get_object (mono_object_domain (tb), &klass->byval_arg); g_assert (res != (MonoReflectionType*)tb); + return res; } @@ -9426,7 +9562,7 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam image = &gparam->tbuilder->module->dynamic_image->image; mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL); - param->pklass->reflection_info = gparam; + param->pklass->reflection_info = gparam; /* FIXME: GC pin gparam */ gparam->type.type = g_new0 (MonoType, 1); gparam->type.type->type = gparam->mbuilder ? MONO_TYPE_MVAR : MONO_TYPE_VAR; @@ -9522,7 +9658,7 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb) mono_raise_exception (mono_get_exception_type_load (NULL, NULL)); return; } - rmb.refs [i] = ref; + rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */ rmb.refs [i + 1] = handle_class; } @@ -9668,6 +9804,12 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class) result = sig; *handle_class = NULL; + } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) { + MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj; + /* Already created by the managed code */ + g_assert (method->mhandle); + result = method->mhandle; + *handle_class = mono_defaults.methodhandle_class; } else { g_print (obj->vtable->klass->name); g_assert_not_reached (); @@ -9885,7 +10027,7 @@ mono_declsec_get_demands (MonoMethod *method, MonoDeclSecurityActions* demands) return FALSE; /* we want the original as the wrapper is "free" of the security informations */ - if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) { + if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE || method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) { method = mono_marshal_method_from_wrapper (method); if (!method) return FALSE; @@ -9933,7 +10075,7 @@ mono_declsec_get_linkdemands (MonoMethod *method, MonoDeclSecurityActions* klass return FALSE; /* we want the original as the wrapper is "free" of the security informations */ - if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) { + if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE || method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) { method = mono_marshal_method_from_wrapper (method); if (!method) return FALSE; @@ -10008,7 +10150,7 @@ mono_declsec_get_inheritdemands_method (MonoMethod *method, MonoDeclSecurityActi return FALSE; /* we want the original as the wrapper is "free" of the security informations */ - if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) { + if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE || method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) { method = mono_marshal_method_from_wrapper (method); if (!method) return FALSE;