Do TLS using pthreads if __thread keyword not supported.
[mono.git] / mono / metadata / reflection.c
index 96f065aa7dda5281526ede3a6dd5ab57f7e9c5ba..6b4774950563ea069e7672c68458dc527079a13f 100644 (file)
@@ -36,6 +36,7 @@
 #include "mono-endian.h"
 #include <mono/metadata/gc-internal.h>
 #include <mono/metadata/mempool-internals.h>
+#include <mono/metadata/security-core-clr.h>
 
 #if HAVE_SGEN_GC
 static void* reflection_info_desc = NULL;
@@ -50,18 +51,6 @@ static void* reflection_info_desc = NULL;
 #define MOVING_GC_REGISTER(addr)
 #endif
 
-static void
-check_array_for_usertypes (MonoArray *arr)
-{
-       int i;
-
-       if (!arr)
-               return;
-
-       for (i = 0; i < mono_array_length (arr); ++i)
-               CHECK_MONOTYPE (mono_array_get (arr, gpointer, i));
-}
-
 typedef struct {
        char *p;
        char *buf;
@@ -159,27 +148,31 @@ const unsigned char table_sizes [MONO_TABLE_NUM] = {
 
 };
 
-static void reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb);
-static void reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb);
-static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
-static guint32 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec);
+#ifndef DISABLE_REFLECTION_EMIT
 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
 static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec);
 static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb);
 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper);
+static void    ensure_runtime_vtable (MonoClass *klass);
+static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context);
+static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method);
+static guint32 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context);
+static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
+#endif
+
+static void reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb);
+static void reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb);
+static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
+static guint32 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec);
 static void    mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly);
 static guint32 encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo);
 static guint32 encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type);
 static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
-static void    ensure_runtime_vtable (MonoClass *klass);
-static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context);
 static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
 static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
 static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
 static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t);
 static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve);
-static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method);
-static guint32 encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context);
 
 void
 mono_reflection_init (void)
@@ -236,6 +229,7 @@ sigbuffer_free (SigBuffer *buf)
        g_free (buf->buf);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 /**
  * mp_g_alloc:
  *
@@ -250,6 +244,7 @@ image_g_malloc (MonoImage *image, guint size)
        else
                return g_malloc (size);
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 /**
  * image_g_alloc0:
@@ -266,6 +261,7 @@ image_g_malloc0 (MonoImage *image, guint size)
                return g_malloc0 (size);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static char*
 image_strdup (MonoImage *image, const char *s)
 {
@@ -274,6 +270,7 @@ image_strdup (MonoImage *image, const char *s)
        else
                return g_strdup (s);
 }
+#endif
 
 #define image_g_new(image,struct_type, n_structs)              \
     ((struct_type *) image_g_malloc (image, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
@@ -351,6 +348,7 @@ string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str)
        return idx;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static void
 string_heap_init (MonoDynamicStream *sh)
 {
@@ -360,6 +358,7 @@ string_heap_init (MonoDynamicStream *sh)
        sh->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
        string_heap_insert (sh, "");
 }
+#endif
 
 static guint32
 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
@@ -400,6 +399,7 @@ stream_data_align (MonoDynamicStream *stream)
                mono_image_add_stream_data (stream, buf, 4 - count);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static int
 mono_blob_entry_hash (const char* str)
 {
@@ -428,7 +428,7 @@ mono_blob_entry_equal (const char *str1, const char *str2) {
                return 0;
        return memcmp (end1, end2, len) == 0;
 }
-
+#endif
 static guint32
 add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int s2)
 {
@@ -531,25 +531,7 @@ add_mono_string_to_blob_cached (MonoDynamicImage *assembly, MonoString *str)
        return idx;
 }
 
-/* modified version needed to handle building corlib */
-static MonoClass*
-my_mono_class_from_mono_type (MonoType *type) {
-       switch (type->type) {
-       case MONO_TYPE_ARRAY:
-       case MONO_TYPE_PTR:
-       case MONO_TYPE_SZARRAY:
-       case MONO_TYPE_GENERICINST:
-               return mono_class_from_mono_type (type);
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:
-               g_assert (type->data.generic_param->pklass);
-               return type->data.generic_param->pklass;
-       default:
-               /* should be always valid when we reach this case... */
-               return type->data.klass;
-       }
-}
-
+#ifndef DISABLE_REFLECTION_EMIT
 static MonoClass *
 default_class_from_mono_type (MonoType *type)
 {
@@ -595,6 +577,7 @@ default_class_from_mono_type (MonoType *type)
        
        return NULL;
 }
+#endif
 
 static void
 encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
@@ -692,7 +675,7 @@ encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                sigbuffer_add_value (buf, type->type);
-               sigbuffer_add_value (buf, type->data.generic_param->num);
+               sigbuffer_add_value (buf, mono_type_get_generic_param_num (type));
                break;
        default:
                g_error ("need to encode type %x", type->type);
@@ -738,6 +721,7 @@ encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArra
        }
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static guint32
 method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
 {
@@ -772,6 +756,7 @@ method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
        sigbuffer_free (&buf);
        return idx;
 }
+#endif
 
 static guint32
 method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
@@ -889,6 +874,7 @@ method_count_clauses (MonoReflectionILGen *ilgen)
        return num_clauses;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static MonoExceptionClause*
 method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses)
 {
@@ -936,6 +922,7 @@ method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflect
 
        return clauses;
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 static guint32
 method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
@@ -1186,6 +1173,7 @@ mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArr
        return ainfo;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 /*
  * LOCKING: Acquires the loader lock. 
  */
@@ -1207,6 +1195,7 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
        mono_loader_unlock ();
 
 }
+#endif
 
 void
 mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
@@ -1461,6 +1450,7 @@ reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoRe
        rmb->refs = NULL;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static void
 reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
 {
@@ -1491,6 +1481,7 @@ reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, Mono
        rmb->nrefs = 0;
        rmb->refs = NULL;
 }      
+#endif
 
 static void
 mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
@@ -1599,7 +1590,7 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
        MonoClass *klass;
        MonoAssembly *ta;
 
-       klass = my_mono_class_from_mono_type (type);
+       klass = mono_class_from_mono_type (type);
        if (!klass) 
                return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
        ta = klass->image->assembly;
@@ -1614,6 +1605,7 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
        return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static guint32
 fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
 {
@@ -1642,6 +1634,7 @@ fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
        sigbuffer_free (&buf);
        return idx;
 }
+#endif
 
 static guint32
 field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
@@ -2115,8 +2108,8 @@ write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *e
 
        values [MONO_GENERICPARAM_OWNER] = entry->owner;
        values [MONO_GENERICPARAM_FLAGS] = entry->gparam->attrs;
-       values [MONO_GENERICPARAM_NUMBER] = param->num;
-       values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, param->name);
+       values [MONO_GENERICPARAM_NUMBER] = mono_generic_param_num (param);
+       values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, mono_generic_param_info (param)->name);
 
        mono_image_add_cattrs (assembly, table_idx, MONO_CUSTOM_ATTR_GENERICPAR, entry->gparam->cattrs);
 
@@ -2259,7 +2252,7 @@ mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboo
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
        if (token)
                return token;
-       klass = my_mono_class_from_mono_type (type);
+       klass = mono_class_from_mono_type (type);
        if (!klass)
                klass = mono_class_from_mono_type (type);
 
@@ -2306,6 +2299,7 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
        return mono_image_typedef_or_ref_full (assembly, type, TRUE);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 /*
  * Insert a memberef row into the metadata: the token that point to the memberref
  * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
@@ -2564,6 +2558,7 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor
        g_hash_table_insert (assembly->handleref, mb, GUINT_TO_POINTER(token));
        return token;
 }
+#endif
 
 static gboolean
 is_field_on_inst (MonoClassField *field)
@@ -2589,6 +2584,7 @@ get_field_on_inst_generic_type (MonoClassField *field)
        return dgclass->field_generic_types [field_index];
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static guint32
 mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *f)
 {
@@ -3039,7 +3035,7 @@ mono_reflection_encode_sighelper (MonoDynamicImage *assembly, MonoReflectionSigH
 
        return idx;
 }
-       
+
 static guint32 
 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper)
 {
@@ -3070,6 +3066,7 @@ reflection_cc_to_file (int call_conv) {
        }
        return 0;
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 typedef struct {
        MonoType *parent;
@@ -3078,6 +3075,7 @@ typedef struct {
        guint32 token;
 } ArrayMethod;
 
+#ifndef DISABLE_REFLECTION_EMIT
 static guint32
 mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m)
 {
@@ -3121,6 +3119,7 @@ mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMetho
        m->table_idx = am->token & 0xffffff;
        return am->token;
 }
+#endif
 
 /*
  * Insert into the metadata tables all the info about the TypeBuilder tb.
@@ -3641,8 +3640,8 @@ compare_genericparam (const void *a, const void *b)
 
        if ((*b_entry)->owner == (*a_entry)->owner)
                return 
-                       (*a_entry)->gparam->type.type->data.generic_param->num - 
-                       (*b_entry)->gparam->type.type->data.generic_param->num;
+                       mono_type_get_generic_param_num ((*a_entry)->gparam->type.type) -
+                       mono_type_get_generic_param_num ((*b_entry)->gparam->type.type);
        else
                return (*a_entry)->owner - (*b_entry)->owner;
 }
@@ -4444,6 +4443,20 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
 
 #endif /* DISABLE_REFLECTION_EMIT_SAVE */
 
+
+typedef struct {
+       guint32 import_lookup_table;
+       guint32 timestamp;
+       guint32 forwarder;
+       guint32 name_rva;
+       guint32 import_address_table_rva;
+} MonoIDT;
+
+typedef struct {
+       guint32 name_rva;
+       guint32 flags;
+} MonoILT;
+
 #ifndef DISABLE_REFLECTION_EMIT
 
 /*
@@ -4721,23 +4734,6 @@ mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject
        }
 }
 
-#endif /* DISABLE_REFLECTION_EMIT */
-
-typedef struct {
-       guint32 import_lookup_table;
-       guint32 timestamp;
-       guint32 forwarder;
-       guint32 name_rva;
-       guint32 import_address_table_rva;
-} MonoIDT;
-
-typedef struct {
-       guint32 name_rva;
-       guint32 flags;
-} MonoILT;
-
-static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
-
 static MonoDynamicImage*
 create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, char *module_name)
 {
@@ -4775,14 +4771,14 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
 
        mono_image_init (&image->image);
 
-       image->token_fixups = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
+       image->token_fixups = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, 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_type (NULL, NULL, MONO_HASH_VALUE_GC);
        image->generic_def_objects = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
-       image->methodspec = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
+       image->methodspec = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
        image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
@@ -4819,6 +4815,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
 
        return image;
 }
+#endif
 
 static void
 free_blob_cache_entry (gpointer key, gpointer val, gpointer user_data)
@@ -4863,7 +4860,7 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                        GenericParamTableEntry *entry = g_ptr_array_index (di->gen_params, i);
                        if (entry->gparam->type.type) {
                                MonoGenericParam *param = entry->gparam->type.type->data.generic_param;
-                               g_free ((char*)param->name);
+                               g_free ((char*)mono_generic_param_info (param)->name);
                                g_free (param);
                        }
                        g_free (entry);
@@ -4972,7 +4969,7 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
        mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
 }
 
-#endif /* DISABLE_REFLECTION_EMIT */
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 #ifndef DISABLE_REFLECTION_EMIT_SAVE
 
@@ -5724,8 +5721,10 @@ reflected_hash (gconstpointer a) {
        } while (0)
 
 #ifdef HAVE_BOEHM_GC
-#define ALLOC_REFENTRY mono_gc_alloc_fixed (sizeof (ReflectedEntry), NULL)
-#define FREE_REFENTRY(entry) mono_gc_free_fixed ((entry))
+/* ReflectedEntry doesn't need to be GC tracked */
+#define ALLOC_REFENTRY g_new0 (ReflectedEntry, 1)
+#define FREE_REFENTRY(entry) g_free ((entry))
+#define REFENTRY_REQUIRES_CLEANUP
 #else
 #define ALLOC_REFENTRY mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry))
 /* FIXME: */
@@ -5771,6 +5770,28 @@ clear_cached_object (MonoDomain *domain, gpointer o, MonoClass *klass)
        mono_domain_unlock (domain);
 }
 
+#ifdef REFENTRY_REQUIRES_CLEANUP
+static void
+cleanup_refobject_hash (gpointer key, gpointer value, gpointer user_data)
+{
+       FREE_REFENTRY (key);
+}
+#endif
+
+void
+mono_reflection_cleanup_domain (MonoDomain *domain)
+{
+       if (domain->refobject_hash) {
+/*let's avoid scanning the whole hashtable if not needed*/
+#ifdef REFENTRY_REQUIRES_CLEANUP
+               mono_g_hash_table_foreach (domain->refobject_hash, cleanup_refobject_hash, NULL);
+#endif
+               mono_g_hash_table_destroy (domain->refobject_hash);
+               domain->refobject_hash = NULL;
+       }
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
 static gpointer
 register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
 {
@@ -5783,8 +5804,6 @@ register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynam
        CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
-
 void
 mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
 {
@@ -6328,14 +6347,16 @@ MonoReflectionEvent*
 mono_event_get_object (MonoDomain *domain, MonoClass *klass, MonoEvent *event)
 {
        MonoReflectionEvent *res;
+       MonoReflectionMonoEvent *mono_event;
        static MonoClass *monoevent_klass;
 
        CHECK_OBJECT (MonoReflectionEvent *, event, klass);
        if (!monoevent_klass)
                monoevent_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoEvent");
-       res = (MonoReflectionEvent *)mono_object_new (domain, monoevent_klass);
-       res->klass = klass;
-       res->event = event;
+       mono_event = (MonoReflectionMonoEvent *)mono_object_new (domain, monoevent_klass);
+       mono_event->klass = klass;
+       mono_event->event = event;
+       res = (MonoReflectionEvent*)mono_event;
        CACHE_OBJECT (MonoReflectionEvent *, event, res, klass);
 }
 
@@ -6392,7 +6413,7 @@ get_reflection_missing (MonoDomain *domain, MonoObject **reflection_missing)
  * in the method @method.
  */
 MonoArray*
-mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
+mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoClass *refclass)
 {
        static MonoClass *System_Reflection_ParameterInfo;
        static MonoClass *System_Reflection_ParameterInfo_array;
@@ -6427,10 +6448,10 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
        /* Note: the cache is based on the address of the signature into the method
         * since we already cache MethodInfos with the method as keys.
         */
-       CHECK_OBJECT (MonoArray*, &(method->signature), NULL);
+       CHECK_OBJECT (MonoArray*, &(method->signature), refclass);
 
        sig = mono_method_signature (method);
-       member = mono_method_get_object (domain, method, NULL);
+       member = mono_method_get_object (domain, method, refclass);
        names = g_new (char *, sig->param_count);
        mono_method_get_param_names (method, (const char **) names);
 
@@ -6502,7 +6523,13 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
                        mono_metadata_free_marshal_spec (mspecs [i]);
        g_free (mspecs);
        
-       CACHE_OBJECT (MonoArray *, &(method->signature), res, NULL);
+       CACHE_OBJECT (MonoArray *, &(method->signature), res, refclass);
+}
+
+MonoArray*
+mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
+{
+       return mono_param_get_objects_internal (domain, method, NULL);
 }
 
 /*
@@ -7358,7 +7385,7 @@ mono_reflection_get_token (MonoObject *obj)
 
                token = mono_class_get_property_token (p->property);
        } else if (strcmp (klass->name, "MonoEvent") == 0) {
-               MonoReflectionEvent *p = (MonoReflectionEvent*)obj;
+               MonoReflectionMonoEvent *p = (MonoReflectionMonoEvent*)obj;
 
                token = mono_class_get_event_token (p->event);
        } else if (strcmp (klass->name, "ParameterInfo") == 0) {
@@ -7934,7 +7961,7 @@ mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
        MonoObject *attr;
        int i;
 
-       result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs);
+       result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs);
        for (i = 0; i < cinfo->num_attrs; ++i) {
                if (!cinfo->attrs [i].ctor)
                        /* The cattr type is not finished yet */
@@ -7959,7 +7986,7 @@ mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_
                        n ++;
        }
 
-       result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, n);
+       result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, n);
        n = 0;
        for (i = 0; i < cinfo->num_attrs; ++i) {
                if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
@@ -8066,6 +8093,10 @@ mono_custom_attrs_from_method (MonoMethod *method)
        if (method->dynamic || method->klass->image->dynamic)
                return lookup_custom_attr (method->klass->image, method);
 
+       if (!method->token)
+               /* Synthetic methods */
+               return NULL;
+
        idx = mono_method_get_index (method);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_METHODDEF;
@@ -8234,7 +8265,7 @@ mono_custom_attrs_has_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass)
        MonoClass *klass;
        for (i = 0; i < ainfo->num_attrs; ++i) {
                klass = ainfo->attrs [i].ctor->klass;
-               if (mono_class_has_parent (klass, attr_klass))
+               if (mono_class_has_parent (klass, attr_klass) || (MONO_CLASS_IS_INTERFACE (attr_klass) && mono_class_is_assignable_from (attr_klass, klass)))
                        return TRUE;
        }
        return FALSE;
@@ -8295,7 +8326,7 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
                MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
                cinfo = mono_custom_attrs_from_property (rprop->property->parent, rprop->property);
        } else if (strcmp ("MonoEvent", klass->name) == 0) {
-               MonoReflectionEvent *revent = (MonoReflectionEvent*)obj;
+               MonoReflectionMonoEvent *revent = (MonoReflectionMonoEvent*)obj;
                cinfo = mono_custom_attrs_from_event (revent->event->parent, revent->event);
        } else if (strcmp ("MonoField", klass->name) == 0) {
                MonoReflectionField *rfield = (MonoReflectionField*)obj;
@@ -8364,7 +8395,7 @@ mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass
        } else {
                if (mono_loader_get_last_error ())
                        return NULL;
-               result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, 0);
+               result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, 0);
        }
 
        return result;
@@ -8421,6 +8452,7 @@ mono_reflection_type_get_underlying_system_type (MonoReflectionType* t)
         return (MonoReflectionType *) mono_runtime_invoke (method_get_underlying_system_type, t, NULL, NULL);
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static MonoType*
 mono_reflection_type_get_handle (MonoReflectionType* t)
 {
@@ -8524,6 +8556,7 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
                *type = f->field->type;
        }
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 /*
  * Encode a value in a custom attribute stream of bytes.
@@ -8802,6 +8835,7 @@ encode_field_or_prop_type (MonoType *type, char *p, char **retp)
        *retp = p;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static void
 encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value)
 {
@@ -8840,8 +8874,6 @@ encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char
        *retbuffer = buffer;
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
-
 /*
  * mono_reflection_get_custom_attrs_blob:
  * @ctor: custom attribute constructor
@@ -8954,7 +8986,7 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
                        /* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
                        parent = monotype_cast (tb->parent)->type->data.klass;
                } else {
-                       parent = my_mono_class_from_mono_type (monotype_cast (tb->parent)->type);
+                       parent = mono_class_from_mono_type (monotype_cast (tb->parent)->type);
                }
        } else {
                parent = NULL;
@@ -9060,7 +9092,7 @@ mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
 
        MONO_ARCH_SAVE_REGS;
 
-       klass = my_mono_class_from_mono_type (tb->type.type);
+       klass = mono_class_from_mono_type (tb->type.type);
 
        count = tb->generic_params ? mono_array_length (tb->generic_params) : 0;
 
@@ -9073,18 +9105,19 @@ mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
 
        klass->generic_container->owner.klass = klass;
        klass->generic_container->type_argc = count;
-       klass->generic_container->type_params = mono_image_alloc0 (klass->image, sizeof (MonoGenericParam) * count);
+       klass->generic_container->type_params = mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count);
 
        klass->is_generic = 1;
 
        for (i = 0; i < count; i++) {
                MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i);
-               klass->generic_container->type_params [i] = *gparam->type.type->data.generic_param;
+               MonoGenericParamFull *param = (MonoGenericParamFull *) gparam->type.type->data.generic_param;
+               klass->generic_container->type_params [i] = *param;
                /*Make sure we are a diferent type instance */
-               klass->generic_container->type_params [i].owner = klass->generic_container;
-               klass->generic_container->type_params [i].pklass = NULL;
+               klass->generic_container->type_params [i].param.owner = klass->generic_container;
+               klass->generic_container->type_params [i].info.pklass = NULL;
 
-               g_assert (klass->generic_container->type_params [i].owner);
+               g_assert (klass->generic_container->type_params [i].param.owner);
        }
 
        klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container);
@@ -9103,7 +9136,7 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
 
        MONO_ARCH_SAVE_REGS;
 
-       klass = my_mono_class_from_mono_type (tb->type.type);
+       klass = mono_class_from_mono_type (tb->type.type);
 
        mono_loader_lock ();
        if (klass->enumtype && mono_class_enum_basetype (klass) == NULL) {
@@ -9122,7 +9155,7 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
                }
 
                enum_basetype = monotype_cast (fb->type)->type;
-               klass->element_class = my_mono_class_from_mono_type (enum_basetype);
+               klass->element_class = mono_class_from_mono_type (enum_basetype);
                if (!klass->element_class)
                        klass->element_class = mono_class_from_mono_type (enum_basetype);
 
@@ -9142,8 +9175,6 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
        mono_loader_unlock ();
 }
 
-#endif /* DISABLE_REFLECTION_EMIT */
-
 static MonoMarshalSpec*
 mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
                                                                MonoReflectionMarshal *minfo)
@@ -9187,6 +9218,7 @@ mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
 
        return res;
 }
+#endif /* !DISABLE_REFLECTION_EMIT */
 
 MonoReflectionMarshal*
 mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
@@ -9236,6 +9268,7 @@ mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
        return minfo;
 }
 
+#ifndef DISABLE_REFLECTION_EMIT
 static MonoMethod*
 reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                         ReflectionMethodBuilder *rmb,
@@ -9370,14 +9403,14 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        mono_method_set_generic_container (m, container);
                }
                container->type_argc = count;
-               container->type_params = image_g_new0 (image, MonoGenericParam, count);
+               container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
                container->owner.method = m;
 
                for (i = 0; i < count; i++) {
                        MonoReflectionGenericParam *gp =
                                mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
-
-                       container->type_params [i] = *gp->type.type->data.generic_param;
+                       MonoGenericParamFull *param = (MonoGenericParamFull *) gp->type.type->data.generic_param;
+                       container->type_params [i] = *param;
                }
 
                if (klass->generic_container) {
@@ -9552,6 +9585,7 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
 
        return field;
 }
+#endif
 
 MonoType*
 mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
@@ -9620,7 +9654,6 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        MonoClass *klass;
        MonoMethod *method, *inflated;
        MonoMethodInflated *imethod;
-       MonoReflectionMethodBuilder *mb = NULL;
        MonoGenericContext tmp_context;
        MonoGenericInst *ginst;
        MonoType **type_argv;
@@ -9630,6 +9663,7 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
 
        if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
 #ifndef DISABLE_REFLECTION_EMIT
+               MonoReflectionMethodBuilder *mb = NULL;
                MonoReflectionTypeBuilder *tb;
                MonoClass *klass;
 
@@ -9871,7 +9905,7 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
                        if (eb->remove_method)
                                event->remove = inflate_method (type, (MonoObject *) eb->remove_method);
                } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) {
-                       *event = *((MonoReflectionEvent *) obj)->event;
+                       *event = *((MonoReflectionMonoEvent *) obj)->event;
                        event->name = g_strdup (event->name);
 
                        if (event->add)
@@ -10134,7 +10168,7 @@ mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, Mon
        MonoClass *klass;
        int j;
 
-       klass = my_mono_class_from_mono_type (tb->type.type);
+       klass = mono_class_from_mono_type (tb->type.type);
 
        event->parent = klass;
        event->attrs = eb->attrs;
@@ -10215,6 +10249,18 @@ remove_instantiations_of (gpointer key,
                return FALSE;
 }
 
+static void
+check_array_for_usertypes (MonoArray *arr)
+{
+       int i;
+
+       if (!arr)
+               return;
+
+       for (i = 0; i < mono_array_length (arr); ++i)
+               CHECK_MONOTYPE (mono_array_get (arr, gpointer, i));
+}
+
 MonoReflectionType*
 mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
 {
@@ -10226,7 +10272,7 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        MONO_ARCH_SAVE_REGS;
 
        domain = mono_object_domain (tb);
-       klass = my_mono_class_from_mono_type (tb->type.type);
+       klass = mono_class_from_mono_type (tb->type.type);
 
        /*
         * Check for user defined Type subclasses.
@@ -10318,7 +10364,7 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
                for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
                        MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);
                        mono_class_alloc_ext (klass);
-                       klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, my_mono_class_from_mono_type (subtb->type.type));
+                       klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtb->type.type));
                }
        }
 
@@ -10374,40 +10420,41 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
 void
 mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
 {
-       MonoGenericParam *param;
+       MonoGenericParamFull *param;
        MonoImage *image;
+       MonoClass *pklass;
 
        MONO_ARCH_SAVE_REGS;
 
-       param = g_new0 (MonoGenericParam, 1);
+       param = g_new0 (MonoGenericParamFull, 1);
 
        if (gparam->mbuilder) {
                if (!gparam->mbuilder->generic_container) {
                        MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)gparam->mbuilder->type;
-                       MonoClass *klass = my_mono_class_from_mono_type (tb->type.type);
+                       MonoClass *klass = mono_class_from_mono_type (tb->type.type);
                        gparam->mbuilder->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
                        gparam->mbuilder->generic_container->is_method = TRUE;
                }
-               param->owner = gparam->mbuilder->generic_container;
+               param->param.owner = gparam->mbuilder->generic_container;
        } else if (gparam->tbuilder) {
                if (!gparam->tbuilder->generic_container) {
-                       MonoClass *klass = my_mono_class_from_mono_type (gparam->tbuilder->type.type);
+                       MonoClass *klass = mono_class_from_mono_type (gparam->tbuilder->type.type);
                        gparam->tbuilder->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
                        gparam->tbuilder->generic_container->owner.klass = klass;
                }
-               param->owner = gparam->tbuilder->generic_container;
+               param->param.owner = gparam->tbuilder->generic_container;
        }
 
-       param->name = mono_string_to_utf8 (gparam->name);
-       param->num = gparam->index;
+       param->info.name = mono_string_to_utf8 (gparam->name);
+       param->param.num = gparam->index;
 
        image = &gparam->tbuilder->module->dynamic_image->image;
-       mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL);
+       pklass = mono_class_from_generic_parameter ((MonoGenericParam *) param, image, gparam->mbuilder != NULL);
 
-       gparam->type.type = &param->pklass->byval_arg;
+       gparam->type.type = &pklass->byval_arg;
 
-       MOVING_GC_REGISTER (&param->pklass->reflection_info);
-       param->pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
+       MOVING_GC_REGISTER (&pklass->reflection_info);
+       pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
 }
 
 MonoArray *
@@ -10511,10 +10558,16 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
                        }
                        handle_class = mono_defaults.methodhandle_class;
                } else {
+                       MonoException *ex = NULL;
                        ref = resolve_object (mb->module->image, obj, &handle_class, NULL);
-                       if (!ref) {
+                       if (!ref)
+                               ex = mono_get_exception_type_load (NULL, NULL);
+                       else if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+                               ex = mono_security_core_clr_ensure_dynamic_method_resolved_object (ref, handle_class);
+
+                       if (ex) {
                                g_free (rmb.refs);
-                               mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
+                               mono_raise_exception (ex);
                                return;
                        }
                }
@@ -10608,6 +10661,34 @@ mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean
        return resolve_object (image, obj, handle_class, context);
 }
 
+/*
+ * ensure_complete_type:
+ *
+ *   Ensure that KLASS is completed if it is a dynamic type, or references
+ * dynamic types.
+ */
+static void
+ensure_complete_type (MonoClass *klass)
+{
+       if (klass->image->dynamic && !klass->wastypebuilder) {
+               MonoReflectionTypeBuilder *tb = klass->reflection_info;
+
+               mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
+
+               // Asserting here could break a lot of code
+               //g_assert (klass->wastypebuilder);
+       }
+
+       if (klass->generic_class) {
+               MonoGenericInst *inst = klass->generic_class->context.class_inst;
+               int i;
+
+               for (i = 0; i < inst->type_argc; ++i) {
+                       ensure_complete_type (mono_class_from_mono_type (inst->type_argv [i]));
+               }
+       }
+}
+
 static gpointer
 resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context)
 {
@@ -10674,6 +10755,8 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                *handle_class = mono_defaults.methodhandle_class;
        } else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
                MonoClassField *field = ((MonoReflectionField*)obj)->field;
+
+               ensure_complete_type (field->parent);
                if (context) {
                        MonoType *inflated = mono_class_inflate_generic_type (&field->parent->byval_arg, context);
                        MonoClass *class = mono_class_from_mono_type (inflated);