X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Freflection.c;h=0c3d2364822f6823828307a9b66db80e72c149dd;hb=01ea58cbd474d4a9230acbba5571738896539d42;hp=3af1e831822f56e85910122ff0eeb9dd2d7409a5;hpb=455b2f894a2cc899fa469ac6fbe66dca163761b1;p=mono.git diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index 3af1e831822..0c3d2364822 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -6,6 +6,7 @@ * * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Copyright 2011 Rodrigo Kumpera * */ #include @@ -1162,7 +1163,9 @@ lookup_custom_attr (MonoImage *image, gpointer member) if (!res) return NULL; - return g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs); + res = g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs); + res->cached = 0; + return res; } static gboolean @@ -1287,6 +1290,11 @@ mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, Mo switch (mono_metadata_token_table (token)) { case MONO_TABLE_METHOD: type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF; + /* + * fixup_cattrs () needs to fix this up. We can't use image->tokens, since it contains the old token for the + * method, not the one returned by mono_image_create_token (). + */ + mono_g_hash_table_insert (assembly->remapped_tokens, GUINT_TO_POINTER (token), cattr->ctor); break; case MONO_TABLE_MEMBERREF: type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF; @@ -1540,29 +1548,35 @@ mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuild MonoDynamicTable *table; guint32 *values; guint32 tok; + MonoReflectionMethod *m; + int i; - if (!mb->override_method) + if (!mb->override_methods) 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); + for (i = 0; i < mono_array_length (mb->override_methods); ++i) { + m = mono_array_get (mb->override_methods, MonoReflectionMethod*, i); - 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; - break; - case MONO_TABLE_METHOD: - tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF; - break; - default: - g_assert_not_reached (); + 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*)m, FALSE, 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; } - values [MONO_METHODIMPL_DECLARATION] = tok; } #ifndef DISABLE_REFLECTION_EMIT @@ -2667,11 +2681,13 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor if (token) return token; - g_assert (tb->generic_params); - reflection_methodbuilder_from_ctor_builder (&rmb, mb); - parent = create_generic_typespec (assembly, tb); + if (tb->generic_params) + parent = create_generic_typespec (assembly, tb); + else + parent = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)tb)); + name = mono_string_to_utf8 (rmb.name); sig = method_builder_encode_signature (assembly, &rmb); @@ -2741,7 +2757,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoCl if (is_field_on_inst (field)) type = get_field_on_inst_generic_type (field); else - type = field->type; + type = mono_field_get_type (field); } token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg, mono_field_get_name (field), @@ -4318,13 +4334,17 @@ fixup_cattrs (MonoDynamicImage *assembly) if ((type & MONO_CUSTOM_ATTR_TYPE_MASK) == MONO_CUSTOM_ATTR_TYPE_METHODDEF) { idx = type >> MONO_CUSTOM_ATTR_TYPE_BITS; token = mono_metadata_make_token (MONO_TABLE_METHOD, idx); - ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token)); + ctor = mono_g_hash_table_lookup (assembly->remapped_tokens, GUINT_TO_POINTER (token)); g_assert (ctor); if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) { MonoMethod *m = ((MonoReflectionMethod*)ctor)->method; idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m)); values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF; + } else if (!strcmp (ctor->vtable->klass->name, "ConstructorBuilder")) { + MonoMethod *m = ((MonoReflectionCtorBuilder*)ctor)->mhandle; + idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m)); + values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF; } } } @@ -4925,7 +4945,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, if (tb->generic_params) { token = mono_image_get_generic_field_token (assembly, fb); } else { - if ((tb->module->dynamic_image == assembly)) { + if (tb->module->dynamic_image == assembly) { token = fb->table_idx | MONO_TOKEN_FIELD_DEF; } else { token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle); @@ -4939,8 +4959,12 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, type = mono_reflection_type_get_handle ((MonoReflectionType *)obj); token = mono_image_typedef_or_ref_full (assembly, type, TRUE); token = mono_metadata_token_from_dor (token); - } else { + } else if (tb->module->dynamic_image == assembly) { token = tb->table_idx | MONO_TOKEN_TYPE_DEF; + } else { + MonoType *type; + type = mono_reflection_type_get_handle ((MonoReflectionType *)obj); + token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type)); } } else if (strcmp (klass->name, "MonoType") == 0) { MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj); @@ -5100,6 +5124,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c 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); image->gen_params = g_ptr_array_new (); + image->remapped_tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC); /*g_print ("string heap create for image %p (%s)\n", image, module_name);*/ string_heap_init (&image->sheap); @@ -5140,6 +5165,26 @@ free_blob_cache_entry (gpointer key, gpointer val, gpointer user_data) g_free (key); } +static void +release_hashtable (MonoGHashTable **hash) +{ + if (*hash) { + mono_g_hash_table_destroy (*hash); + *hash = NULL; + } +} + +void +mono_dynamic_image_release_gc_roots (MonoDynamicImage *image) +{ + release_hashtable (&image->token_fixups); + release_hashtable (&image->handleref_managed); + release_hashtable (&image->tokens); + release_hashtable (&image->remapped_tokens); + release_hashtable (&image->generic_def_objects); + release_hashtable (&image->methodspec); +} + void mono_dynamic_image_free (MonoDynamicImage *image) { @@ -5159,6 +5204,8 @@ mono_dynamic_image_free (MonoDynamicImage *image) mono_g_hash_table_destroy (di->handleref_managed); if (di->tokens) mono_g_hash_table_destroy (di->tokens); + if (di->remapped_tokens) + mono_g_hash_table_destroy (di->remapped_tokens); if (di->generic_def_objects) mono_g_hash_table_destroy (di->generic_def_objects); if (di->blob_cache) { @@ -6302,104 +6349,6 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind return res; } -static gboolean -mymono_metadata_type_equal (MonoType *t1, MonoType *t2) -{ - if ((t1->type != t2->type) || - (t1->byref != t2->byref)) - return FALSE; - - switch (t1->type) { - case MONO_TYPE_VOID: - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_R4: - case MONO_TYPE_R8: - case MONO_TYPE_STRING: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_OBJECT: - case MONO_TYPE_TYPEDBYREF: - return TRUE; - case MONO_TYPE_VALUETYPE: - case MONO_TYPE_CLASS: - case MONO_TYPE_SZARRAY: - return t1->data.klass == t2->data.klass; - case MONO_TYPE_PTR: - return mymono_metadata_type_equal (t1->data.type, t2->data.type); - case MONO_TYPE_ARRAY: - if (t1->data.array->rank != t2->data.array->rank) - return FALSE; - return t1->data.array->eklass == t2->data.array->eklass; - case MONO_TYPE_GENERICINST: { - int i; - MonoGenericInst *i1 = t1->data.generic_class->context.class_inst; - MonoGenericInst *i2 = t2->data.generic_class->context.class_inst; - if (i1->type_argc != i2->type_argc) - return FALSE; - if (!mono_metadata_type_equal (&t1->data.generic_class->container_class->byval_arg, - &t2->data.generic_class->container_class->byval_arg)) - return FALSE; - /* FIXME: we should probably just compare the instance pointers directly. */ - for (i = 0; i < i1->type_argc; ++i) { - if (!mono_metadata_type_equal (i1->type_argv [i], i2->type_argv [i])) - return FALSE; - } - return TRUE; - } - case MONO_TYPE_VAR: - case MONO_TYPE_MVAR: - return t1->data.generic_param == t2->data.generic_param; - default: - g_error ("implement type compare for %0x!", t1->type); - return FALSE; - } - - return FALSE; -} - -static guint -mymono_metadata_type_hash (MonoType *t1) -{ - guint hash; - - hash = t1->type; - - hash |= t1->byref << 6; /* do not collide with t1->type values */ - switch (t1->type) { - case MONO_TYPE_VALUETYPE: - case MONO_TYPE_CLASS: - case MONO_TYPE_SZARRAY: - /* check if the distribution is good enough */ - return ((hash << 5) - hash) ^ mono_aligned_addr_hash (t1->data.klass); - case MONO_TYPE_PTR: - return ((hash << 5) - hash) ^ mymono_metadata_type_hash (t1->data.type); - case MONO_TYPE_GENERICINST: { - int i; - MonoGenericInst *inst = t1->data.generic_class->context.class_inst; - hash += g_str_hash (t1->data.generic_class->container_class->name); - hash *= 13; - for (i = 0; i < inst->type_argc; ++i) { - hash += mymono_metadata_type_hash (inst->type_argv [i]); - hash *= 13; - } - return hash; - } - case MONO_TYPE_VAR: - case MONO_TYPE_MVAR: - return ((hash << 5) - hash) ^ GPOINTER_TO_UINT (t1->data.generic_param); - } - return hash; -} - static gboolean verify_safe_for_managed_space (MonoType *type) { @@ -6513,8 +6462,8 @@ mono_type_get_object (MonoDomain *domain, MonoType *type) mono_loader_lock (); /*FIXME mono_class_init and mono_class_vtable acquire it*/ mono_domain_lock (domain); if (!domain->type_hash) - domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, - (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC); + domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, + (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC); if ((res = mono_g_hash_table_lookup (domain->type_hash, type))) { mono_domain_unlock (domain); mono_loader_unlock (); @@ -6913,7 +6862,7 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla } if (mspecs [i + 1]) - MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1])); + MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [i + 1])); mono_array_setref (res, i, param); } @@ -6957,6 +6906,10 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method) unsigned char format, flags; int i; + /* for compatibility with .net */ + if (method->dynamic) + mono_raise_exception (mono_get_exception_invalid_operation (NULL)); + if (!System_Reflection_MethodBody) System_Reflection_MethodBody = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MethodBody"); if (!System_Reflection_LocalVariableInfo) @@ -7950,12 +7903,16 @@ handle_type: int etype = *p; p ++; - if (etype == 0x51) - /* See Partition II, Appendix B3 */ - etype = MONO_TYPE_OBJECT; type = MONO_TYPE_SZARRAY; - simple_type.type = etype; - tklass = mono_class_from_mono_type (&simple_type); + if (etype == 0x50) { + tklass = mono_defaults.systemtype_class; + } else { + if (etype == 0x51) + /* See Partition II, Appendix B3 */ + etype = MONO_TYPE_OBJECT; + simple_type.type = etype; + tklass = mono_class_from_mono_type (&simple_type); + } goto handle_enum; } else if (subt == 0x55) { char *n; @@ -7979,7 +7936,7 @@ handle_type: val = load_cattr_value (image, &subc->byval_arg, p, end); obj = mono_object_new (mono_domain_get (), subc); g_assert (!subc->has_references); - memcpy ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL)); + mono_gc_memmove ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL)); g_free (val); return obj; } @@ -9206,8 +9163,8 @@ mono_reflection_register_with_runtime (MonoReflectionType *type) mono_class_setup_supertypes (class); } else { if (!domain->type_hash) - domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, - (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC); + domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, + (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC); mono_g_hash_table_insert (domain->type_hash, res, type); } mono_domain_unlock (domain); @@ -10062,45 +10019,46 @@ mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly, } #endif /* !DISABLE_REFLECTION_EMIT */ -MonoReflectionMarshal* -mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass, +MonoReflectionMarshalAsAttribute* +mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass, MonoMarshalSpec *spec) { - static MonoClass *System_Reflection_Emit_UnmanagedMarshalClass; - MonoReflectionMarshal *minfo; + static MonoClass *System_Reflection_Emit_MarshalAsAttribute; + MonoReflectionMarshalAsAttribute *minfo; MonoType *mtype; - if (!System_Reflection_Emit_UnmanagedMarshalClass) { - System_Reflection_Emit_UnmanagedMarshalClass = mono_class_from_name ( - mono_defaults.corlib, "System.Reflection.Emit", "UnmanagedMarshal"); - g_assert (System_Reflection_Emit_UnmanagedMarshalClass); + if (!System_Reflection_Emit_MarshalAsAttribute) { + System_Reflection_Emit_MarshalAsAttribute = mono_class_from_name ( + mono_defaults.corlib, "System.Runtime.InteropServices", "MarshalAsAttribute"); + g_assert (System_Reflection_Emit_MarshalAsAttribute); } - minfo = (MonoReflectionMarshal*)mono_object_new (domain, System_Reflection_Emit_UnmanagedMarshalClass); - minfo->type = spec->native; + minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new (domain, System_Reflection_Emit_MarshalAsAttribute); + minfo->utype = spec->native; - switch (minfo->type) { + switch (minfo->utype) { case MONO_NATIVE_LPARRAY: - minfo->eltype = spec->data.array_data.elem_type; - minfo->count = spec->data.array_data.num_elem; - minfo->param_num = spec->data.array_data.param_num; + minfo->array_subtype = spec->data.array_data.elem_type; + minfo->size_const = spec->data.array_data.num_elem; + if (spec->data.array_data.param_num != -1) + minfo->size_param_index = spec->data.array_data.param_num; break; case MONO_NATIVE_BYVALTSTR: case MONO_NATIVE_BYVALARRAY: - minfo->count = spec->data.array_data.num_elem; + minfo->size_const = spec->data.array_data.num_elem; break; case MONO_NATIVE_CUSTOM: if (spec->data.custom_data.custom_name) { mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image); if (mtype) - MONO_OBJECT_SETREF (minfo, marshaltyperef, mono_type_get_object (domain, mtype)); + MONO_OBJECT_SETREF (minfo, marshal_type_ref, mono_type_get_object (domain, mtype)); - MONO_OBJECT_SETREF (minfo, marshaltype, mono_string_new (domain, spec->data.custom_data.custom_name)); + MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name)); } if (spec->data.custom_data.cookie) - MONO_OBJECT_SETREF (minfo, mcookie, mono_string_new (domain, spec->data.custom_data.cookie)); + MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie)); break; default: @@ -10151,8 +10109,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, m->slot = -1; m->flags = rmb->attrs; m->iflags = rmb->iattrs; - m->name = mono_string_to_utf8_image (image, rmb->name, &error); - g_assert (mono_error_ok (&error)); + m->name = mono_string_to_utf8_image_ignore (image, rmb->name); m->klass = klass; m->signature = sig; m->sre_method = TRUE; @@ -10673,9 +10630,7 @@ inflate_method (MonoReflectionType *type, MonoObject *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, - MonoArray *events) +mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields) { MonoGenericClass *gclass; MonoDynamicGenericClass *dgclass; @@ -10701,28 +10656,12 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono gklass = gclass->container_class; mono_class_init (gklass); - 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; - dgclass->methods = mono_image_set_new0 (gclass->owner, MonoMethod *, dgclass->count_methods); - dgclass->ctors = mono_image_set_new0 (gclass->owner, MonoMethod *, dgclass->count_ctors); dgclass->fields = mono_image_set_new0 (gclass->owner, MonoClassField, dgclass->count_fields); dgclass->field_objects = mono_image_set_new0 (gclass->owner, MonoObject*, dgclass->count_fields); dgclass->field_generic_types = mono_image_set_new0 (gclass->owner, MonoType*, dgclass->count_fields); - for (i = 0; i < dgclass->count_methods; i++) { - MonoObject *obj = mono_array_get (methods, gpointer, i); - - dgclass->methods [i] = inflate_method ((MonoReflectionType*)type, obj); - } - - for (i = 0; i < dgclass->count_ctors; i++) { - MonoObject *obj = mono_array_get (ctors, gpointer, i); - - dgclass->ctors [i] = inflate_method ((MonoReflectionType*)type, obj); - } - for (i = 0; i < dgclass->count_fields; i++) { MonoObject *obj = mono_array_get (fields, gpointer, i); MonoClassField *field, *inflated_field = NULL; @@ -10963,7 +10902,8 @@ void mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides) { MonoReflectionTypeBuilder *tb; - int i, onum; + int i, j, onum; + MonoReflectionMethod *m; *overrides = NULL; *num_overrides = 0; @@ -10982,8 +10922,8 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides for (i = 0; i < tb->num_methods; ++i) { MonoReflectionMethodBuilder *mb = mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i); - if (mb->override_method) - onum ++; + if (mb->override_methods) + onum += mono_array_length (mb->override_methods); } } @@ -10994,13 +10934,17 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides for (i = 0; i < tb->num_methods; ++i) { MonoReflectionMethodBuilder *mb = mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i); - if (mb->override_method) { - (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject *)mb->override_method); - (*overrides) [onum * 2 + 1] = mb->mhandle; + if (mb->override_methods) { + for (j = 0; j < mono_array_length (mb->override_methods); ++j) { + m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j); + + (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m); + (*overrides) [onum * 2 + 1] = mb->mhandle; - g_assert (mb->mhandle); + g_assert (mb->mhandle); - onum ++; + onum ++; + } } } } @@ -11025,7 +10969,11 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error) mono_error_init (error); if (tb->class_size) { - g_assert ((tb->packing_size & 0xfffffff0) == 0); + if ((tb->packing_size & 0xfffffff0) != 0) { + char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", klass->name, tb->packing_size); + mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg); + return; + } klass->packing_size = tb->packing_size; real_size = klass->instance_size + tb->class_size; } @@ -11048,6 +10996,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error) klass->size_inited = 1; for (i = 0; i < klass->field.count; ++i) { + MonoArray *rva_data; fb = mono_array_get (tb->fields, gpointer, i); field = &klass->fields [i]; field->name = mono_string_to_utf8_image (image, fb->name, error); @@ -11059,8 +11008,14 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error) } else { field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type); } - if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data) - klass->ext->field_def_values [i].data = mono_array_addr (fb->rva_data, char, 0); + + if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) { + char *base = mono_array_addr (rva_data, char, 0); + size_t size = mono_array_length (rva_data); + char *data = mono_image_alloc (klass->image, size); + memcpy (data, base, size); + klass->ext->field_def_values [i].data = data; + } if (fb->offset != -1) field->offset = fb->offset; field->parent = klass; @@ -11330,6 +11285,7 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb) klass->flags = tb->attrs; klass->has_cctor = 1; klass->has_finalize = 1; + klass->has_finalize_inited = 1; /* fool mono_class_setup_parent */ klass->supertypes = NULL; @@ -11532,15 +11488,47 @@ mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig) return result; } +typedef struct { + MonoMethod *handle; + MonoDomain *domain; +} DynamicMethodReleaseData; + +/* + * The runtime automatically clean up those after finalization. +*/ +static MonoReferenceQueue *dynamic_method_queue; + +static void +free_dynamic_method (void *dynamic_method) +{ + DynamicMethodReleaseData *data = dynamic_method; + + mono_runtime_free_method (data->domain, data->handle); + g_free (data); +} + void mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb) { + MonoReferenceQueue *queue; + MonoMethod *handle; + DynamicMethodReleaseData *release_data; ReflectionMethodBuilder rmb; MonoMethodSignature *sig; MonoClass *klass; GSList *l; int i; + if (mono_runtime_is_shutting_down ()) + mono_raise_exception (mono_get_exception_invalid_operation ("")); + + if (!(queue = dynamic_method_queue)) { + mono_loader_lock (); + if (!(queue = dynamic_method_queue)) + queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method); + mono_loader_unlock (); + } + sig = dynamic_method_to_signature (mb); reflection_methodbuilder_from_dynamic_method (&rmb, mb); @@ -11598,7 +11586,12 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb) klass = mb->owner ? mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner)) : mono_defaults.object_class; - mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig); + mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig); + release_data = g_new (DynamicMethodReleaseData, 1); + release_data->handle = handle; + release_data->domain = mono_object_get_domain ((MonoObject*)mb); + if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data)) + g_free (release_data); /* Fix up refs entries pointing at us */ for (l = mb->referenced_by; l; l = l->next) { @@ -11624,16 +11617,6 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb) #endif /* DISABLE_REFLECTION_EMIT */ -void -mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb) -{ - g_assert (mb); - - if (mb->mhandle) - mono_runtime_free_method ( - mono_object_get_domain ((MonoObject*)mb), mb->mhandle); -} - /** * * mono_reflection_is_valid_dynamic_token: @@ -11990,7 +11973,14 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon is_sre_pointer (mono_object_get_class(obj))) { MonoReflectionType *ref_type = (MonoReflectionType *)obj; MonoType *type = mono_reflection_type_get_handle (ref_type); - result = mono_class_from_mono_type (type); + + if (context) { + MonoType *inflated = mono_class_inflate_generic_type (type, context); + result = mono_class_from_mono_type (inflated); + mono_metadata_free_type (inflated); + } else { + result = mono_class_from_mono_type (type); + } *handle_class = mono_defaults.typehandle_class; } else { g_print ("%s\n", obj->vtable->klass->name); @@ -12085,9 +12075,7 @@ mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject } void -mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, - MonoArray *ctors, MonoArray *fields, MonoArray *properties, - MonoArray *events) +mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields) { g_assert_not_reached (); } @@ -12617,3 +12605,18 @@ mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass) else return *(MonoBoolean*)mono_object_unbox (res); } + +/** + * mono_reflection_type_get_type: + * @reftype: the System.Type object + * + * Returns the MonoType* associated with the C# System.Type object @reftype. + */ +MonoType* +mono_reflection_type_get_type (MonoReflectionType *reftype) +{ + g_assert (reftype); + + return mono_reflection_type_get_handle (reftype); +} +