2006-08-30 Martin Baulig <martin@ximian.com>
[mono.git] / mono / metadata / reflection.c
index 583b4b1106e35f5d763dedb8528d683319c60467..74b9bd4fb6b15611a45d6bf29656857d62739909 100644 (file)
@@ -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"
@@ -872,7 +873,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]);
@@ -1154,10 +1156,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);
 }
 
 /*
@@ -4356,12 +4356,12 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
 
        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);
@@ -5155,7 +5155,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)    \
@@ -5166,7 +5166,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;    \
@@ -5176,6 +5176,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
@@ -5188,7 +5190,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;         \
@@ -5523,8 +5525,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;
@@ -5550,7 +5552,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);
@@ -6930,9 +6936,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;
@@ -7022,7 +7028,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;
@@ -7030,7 +7036,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];
@@ -7252,7 +7258,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);
 
@@ -7804,8 +7810,12 @@ handle_type:
                *retbuffer = buffer;
                eclass = type->data.klass;
                arg_eclass = mono_object_class (arg)->element_class;
-               if (eclass == mono_defaults.object_class && 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) {
@@ -8031,6 +8041,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
@@ -8083,7 +8097,15 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
        klass->flags = tb->attrs;
 
        klass->element_class = klass;
-       klass->reflection_info = tb; /* FIXME: GC 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);
@@ -8392,8 +8414,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                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;
@@ -9349,6 +9370,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);
        }
 }
 
@@ -9480,8 +9503,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.
@@ -9631,7 +9654,7 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
                        mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
                        return;
                }
-               rmb.refs [i] = ref; /* FIXME: GC object stored in unamanged memory (change also resolve_object() signature) */
+               rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
                rmb.refs [i + 1] = handle_class;
        }               
 
@@ -9777,6 +9800,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 ();
@@ -9994,7 +10023,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;
@@ -10042,7 +10071,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;
@@ -10117,7 +10146,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;