Merge pull request #2408 from tastywheattasteslikechicken/MoreInterfaceSupport
[mono.git] / mono / metadata / class-internals.h
index f6db61641fdd8e0540ade5784a27d14bbd434435..0c14ec3b04236557fbc37d94da1ab3f042768355 100644 (file)
@@ -1,5 +1,6 @@
 /* 
  * Copyright 2012 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #ifndef __MONO_METADATA_CLASS_INTERNALS_H__
 #define __MONO_METADATA_CLASS_INTERNALS_H__
@@ -15,7 +16,7 @@
 
 #define MONO_CLASS_IS_ARRAY(c) ((c)->rank)
 
-#define MONO_CLASS_HAS_STATIC_METADATA(klass) ((klass)->type_token && !(klass)->image->dynamic && !(klass)->generic_class)
+#define MONO_CLASS_HAS_STATIC_METADATA(klass) ((klass)->type_token && !(klass)->image->dynamic && !mono_class_is_ginst (klass))
 
 #define MONO_DEFAULT_SUPERTABLE_SIZE 6
 
@@ -193,7 +194,7 @@ struct _MonoEvent {
 };
 
 /* type of exception being "on hold" for later processing (see exception_type) */
-enum {
+typedef enum {
        MONO_EXCEPTION_NONE = 0,
        MONO_EXCEPTION_INVALID_PROGRAM = 3,
        MONO_EXCEPTION_UNVERIFIABLE_IL = 4,
@@ -210,7 +211,7 @@ enum {
        MONO_EXCEPTION_INLINE_FAILED = 15,
        MONO_EXCEPTION_MONO_ERROR = 16,
        /* add other exception type */
-};
+} MonoExceptionType;
 
 /* This struct collects the info needed for the runtime use of a class,
  * like the vtables for a domain, the GC descriptor, etc.
@@ -255,6 +256,15 @@ typedef struct {
        GList      *nested_classes;
 } MonoClassExt;
 
+typedef enum {
+       MONO_CLASS_DEF = 1, /* non-generic type */
+       MONO_CLASS_GTD, /* generic type definition */
+       MONO_CLASS_GINST, /* generic instantiation */
+       MONO_CLASS_GPARAM, /* generic parameter */
+       MONO_CLASS_ARRAY, /* vector or array, bounded or not */
+       MONO_CLASS_POINTER, /* pointer of function pointer*/
+} MonoTypeKind;
+
 struct _MonoClass {
        /* element class for arrays and enum basetype for enums */
        MonoClass *element_class; 
@@ -271,8 +281,6 @@ struct _MonoClass {
        int        instance_size; /* object instance size */
 
        guint inited          : 1;
-       /* We use init_pending to detect cyclic calls to mono_class_init */
-       guint init_pending    : 1;
 
        /* A class contains static and non static data. Static data can be
         * of the same type as the class itselfs, but it does not influence
@@ -316,19 +324,12 @@ struct _MonoClass {
        guint nested_classes_inited : 1; /* Whenever nested_class is initialized */
 
        /* next byte*/
+       guint class_kind : 3; /* One of the values from MonoTypeKind */
        guint interfaces_inited : 1; /* interfaces is initialized */
        guint simd_type : 1; /* class is a simd intrinsic type */
-       guint is_generic : 1; /* class is a generic type definition */
-       guint is_inflated : 1; /* class is a generic instance */
        guint has_finalize_inited    : 1; /* has_finalize is initialized */
-       guint fields_inited : 1; /* fields is initialized */
-       guint setup_fields_called : 1; /* to prevent infinite loops in setup_fields */
-
-       guint8     exception_type;      /* MONO_EXCEPTION_* */
-
-       /* Additional information about the exception */
-       /* Stored as property MONO_CLASS_PROP_EXCEPTION_DATA */
-       //void       *exception_data;
+       guint fields_inited : 1; /* setup_fields () has finished */
+       guint has_failure : 1; /* See MONO_CLASS_PROP_EXCEPTION_DATA for a MonoErrorBoxed with the details */
 
        MonoClass  *parent;
        MonoClass  *nested_in;
@@ -364,14 +365,20 @@ struct _MonoClass {
        /*
         * From the TypeDef table
         */
-       guint32    flags;
        struct {
 #if MONO_SMALL_CONFIG
-               guint16 first, count;
+               guint16 count;
 #else
-               guint32 first, count;
+               guint32 count;
 #endif
-       } field, method;
+       } field;
+       struct {
+#if MONO_SMALL_CONFIG
+               guint16 count;
+#else
+               guint32 count;
+#endif
+       } method;
 
        /* A GC handle pointing to the corresponding type builder/generic param builder */
        guint32 ref_info_handle;
@@ -390,16 +397,10 @@ struct _MonoClass {
        MonoType this_arg;
        MonoType byval_arg;
 
-       MonoGenericClass *generic_class;
-       MonoGenericContainer *generic_container;
-
        MonoGCDescriptor gc_descr;
 
        MonoClassRuntimeInfo *runtime_info;
 
-       /* next element in the class_cache hash list (in MonoImage) */
-       MonoClass *next_class_cache;
-
        /* Generic vtable. Initialized by a call to mono_class_setup_vtable () */
        MonoMethod **vtable;
 
@@ -407,6 +408,40 @@ struct _MonoClass {
        MonoClassExt *ext;
 };
 
+typedef struct {
+       MonoClass class;
+       guint32 flags;
+       /*
+        * From the TypeDef table
+        */
+       guint32 first_method_idx;
+       guint32 first_field_idx;
+       /* next element in the class_cache hash list (in MonoImage) */
+       MonoClass *next_class_cache;
+} MonoClassDef;
+
+typedef struct {
+       MonoClassDef class;
+       MonoGenericContainer *generic_container;
+} MonoClassGtd;
+
+typedef struct {
+       MonoClass class;
+       MonoGenericClass *generic_class;
+} MonoClassGenericInst;
+
+typedef struct {
+       MonoClass class;
+} MonoClassGenericParam;
+
+typedef struct {
+       MonoClass class;
+} MonoClassArray;
+
+typedef struct {
+       MonoClass class;
+} MonoClassPointer;
+
 #ifdef COMPRESSED_INTERFACE_BITMAP
 int mono_compress_bitmap (uint8_t *dest, const uint8_t *bitmap, int size);
 int mono_class_interface_match (const uint8_t *bitmap, int id);
@@ -517,7 +552,6 @@ struct _MonoMethodInflated {
                MonoMethod method;
                MonoMethodPInvoke pinvoke;
        } method;
-       MonoMethodHeader *header;
        MonoMethod *declaring;          /* the generic method definition. */
        MonoGenericContext context;     /* The current instantiation */
        MonoImageSet *owner; /* The image set that the inflated method belongs to. */
@@ -529,8 +563,9 @@ struct _MonoMethodInflated {
 struct _MonoGenericClass {
        MonoClass *container_class;     /* the generic type definition */
        MonoGenericContext context;     /* a context that contains the type instantiation doesn't contain any method instantiation */ /* FIXME: Only the class_inst member of "context" is ever used, so this field could be replaced with just a monogenericinst */
-       guint is_dynamic  : 1;          /* We're a MonoDynamicGenericClass */
+       guint is_dynamic  : 1;          /* Contains dynamic types */
        guint is_tb_open  : 1;          /* This is the fully open instantiation for a type_builder. Quite ugly, but it's temporary.*/
+       guint need_sync   : 1;      /* Only if dynamic. Need to be synchronized with its container class after its finished. */
        MonoClass *cached_class;        /* if present, the MonoClass corresponding to the instantiation.  */
 
        /* 
@@ -541,21 +576,6 @@ struct _MonoGenericClass {
        MonoImageSet *owner;
 };
 
-/*
- * This is used when instantiating a generic type definition which is
- * a TypeBuilder.
- */
-struct _MonoDynamicGenericClass {
-       MonoGenericClass generic_class;
-       int count_fields;
-       MonoClassField *fields;
-       guint initialized;
-       /* The non-inflated types of the fields */
-       MonoType **field_generic_types;
-       /* The managed objects representing the fields */
-       MonoObject **field_objects;
-};
-
 /*
  * A type parameter.
  */
@@ -573,6 +593,7 @@ struct _MonoGenericParam {
 };
 
 /* Additional details about a MonoGenericParam */
+/* Keep in sync with managed Mono.RuntimeStructs.GenericParamInfo */
 typedef struct {
        MonoClass *pklass;              /* The corresponding `MonoClass'. */
        const char *name;
@@ -721,21 +742,11 @@ typedef struct {
        gboolean no_raise;
 } MonoJitICallInfo;
 
-typedef struct {
-       guint8 exception_type;
-       char *class_name; /* If kind == TYPE */
-       char *assembly_name; /* If kind == TYPE or ASSEMBLY */
-       MonoClass *klass; /* If kind != TYPE */
-       const char *member_name; /* If kind != TYPE */
-       gboolean ref_only; /* If kind == ASSEMBLY */
-       char *msg; /* If kind == BAD_IMAGE */
-} MonoLoaderError;
-
 void
 mono_class_setup_supertypes (MonoClass *klass);
 
 void
-mono_class_setup_fields_locking (MonoClass *klass);
+mono_class_setup_fields (MonoClass *klass);
 
 /* WARNING
  * Only call this function if you can ensure both @klass and @parent
@@ -794,7 +805,7 @@ typedef struct {
        size_t imt_slots_with_collisions;
        size_t imt_max_collisions_in_slot;
        size_t imt_method_count_when_max_collisions;
-       size_t imt_thunks_size;
+       size_t imt_trampolines_size;
        size_t jit_info_table_insert_count;
        size_t jit_info_table_remove_count;
        size_t jit_info_table_lookup_count;
@@ -915,13 +926,9 @@ typedef struct {
 
 extern MonoStats mono_stats;
 
-typedef gpointer (*MonoTrampoline)       (MonoMethod *method);
-typedef gpointer (*MonoJumpTrampoline)       (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper);
-typedef gpointer (*MonoRemotingTrampoline)       (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target);
+typedef gpointer (*MonoRemotingTrampoline)       (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target, MonoError *error);
 typedef gpointer (*MonoDelegateTrampoline)       (MonoDomain *domain, MonoClass *klass);
 
-typedef gpointer (*MonoLookupDynamicToken) (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context);
-
 typedef gboolean (*MonoGetCachedClassInfo) (MonoClass *klass, MonoCachedClassInfo *res);
 
 typedef gboolean (*MonoGetClassFromName) (MonoImage *image, const char *name_space, const char *name, MonoClass **res);
@@ -943,7 +950,7 @@ void
 mono_classes_cleanup (void);
 
 void
-mono_class_layout_fields   (MonoClass *klass);
+mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_size, gboolean sre);
 
 void
 mono_class_setup_interface_offsets (MonoClass *klass);
@@ -1009,26 +1016,17 @@ mono_class_get_field_default_value (MonoClassField *field, MonoTypeEnum *def_typ
 const char*
 mono_class_get_property_default_value (MonoProperty *property, MonoTypeEnum *def_type);
 
-void
-mono_install_trampoline (MonoTrampoline func);
-
-void
-mono_install_jump_trampoline (MonoJumpTrampoline func);
-
 void
 mono_install_delegate_trampoline (MonoDelegateTrampoline func);
 
 gpointer
-mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context);
+mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context, MonoError *error);
 
 gpointer
-mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean check_token, MonoClass **handle_class, MonoGenericContext *context);
-
-void
-mono_install_lookup_dynamic_token (MonoLookupDynamicToken func);
+mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean check_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error);
 
 gpointer
-mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper);
+mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper, MonoError *error);
 
 gpointer
 mono_runtime_create_delegate_trampoline (MonoClass *klass);
@@ -1082,9 +1080,6 @@ mono_metadata_get_inflated_signature (MonoMethodSignature *sig, MonoGenericConte
 MonoType*
 mono_class_inflate_generic_type_with_mempool (MonoImage *image, MonoType *type, MonoGenericContext *context, MonoError *error);
 
-MonoClass*
-mono_class_inflate_generic_class (MonoClass *gklass, MonoGenericContext *context);
-
 MonoType*
 mono_class_inflate_generic_type_checked (MonoType *type, MonoGenericContext *context, MonoError *error);
 
@@ -1123,7 +1118,6 @@ typedef struct {
        MonoClass *fieldhandle_class;
        MonoClass *methodhandle_class;
        MonoClass *systemtype_class;
-       MonoClass *monotype_class;
        MonoClass *runtimetype_class;
        MonoClass *exception_class;
        MonoClass *threadabortexception_class;
@@ -1147,16 +1141,12 @@ typedef struct {
        MonoClass *typed_reference_class;
        MonoClass *argumenthandle_class;
        MonoClass *monitor_class;
-       MonoClass *runtimesecurityframe_class;
-       MonoClass *executioncontext_class;
-       MonoClass *internals_visible_class;
        MonoClass *generic_ilist_class;
        MonoClass *generic_nullable_class;
-       MonoClass *safehandle_class;
        MonoClass *handleref_class;
        MonoClass *attribute_class;
        MonoClass *customattribute_data_class;
-       MonoClass *critical_finalizer_object;
+       MonoClass *critical_finalizer_object; /* MAYBE NULL */
        MonoClass *generic_ireadonlylist_class;
        MonoClass *threadpool_wait_callback_class;
        MonoMethod *threadpool_perform_wait_callback_method;
@@ -1168,7 +1158,7 @@ typedef struct {
 #define mono_object_is_transparent_proxy(object) (FALSE)
 #else
 MonoRemoteClass*
-mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class);
+mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class, MonoError *error);
 
 void
 mono_install_remoting_trampoline (MonoRemotingTrampoline func);
@@ -1182,6 +1172,9 @@ mono_install_remoting_trampoline (MonoRemotingTrampoline func);
 #define GENERATE_GET_CLASS_WITH_CACHE_DECL(shortname) \
 MonoClass* mono_class_get_##shortname##_class (void);
 
+#define GENERATE_TRY_GET_CLASS_WITH_CACHE_DECL(shortname) \
+MonoClass* mono_class_try_get_##shortname##_class (void);
+
 #define GENERATE_GET_CLASS_WITH_CACHE(shortname,namespace,name) \
 MonoClass*     \
 mono_class_get_##shortname##_class (void)      \
@@ -1189,17 +1182,31 @@ mono_class_get_##shortname##_class (void)       \
        static MonoClass *tmp_class;    \
        MonoClass *klass = tmp_class;   \
        if (!klass) {   \
-               klass = mono_class_from_name (mono_defaults.corlib, #namespace, #name); \
-               g_assert (klass);       \
+               klass = mono_class_load_from_name (mono_defaults.corlib, #namespace, #name);    \
                mono_memory_barrier (); \
                tmp_class = klass;      \
        }       \
        return klass;   \
 }
 
-#define GENERATE_STATIC_GET_CLASS_WITH_CACHE(shortname,namespace,name) \
-static GENERATE_GET_CLASS_WITH_CACHE (shortname,namespace,name)
+#define GENERATE_TRY_GET_CLASS_WITH_CACHE(shortname,namespace,name) \
+MonoClass*     \
+mono_class_try_get_##shortname##_class (void)  \
+{      \
+       static volatile MonoClass *tmp_class;   \
+       static volatile gboolean inited;        \
+       MonoClass *klass = (MonoClass *)tmp_class;      \
+       mono_memory_barrier (); \
+       if (!inited) {  \
+               klass = mono_class_try_load_from_name (mono_defaults.corlib, #namespace, #name);        \
+               tmp_class = klass;      \
+               mono_memory_barrier (); \
+               inited = TRUE;  \
+       }       \
+       return klass;   \
+}
 
+GENERATE_TRY_GET_CLASS_WITH_CACHE_DECL (safehandle)
 
 #ifndef DISABLE_COM
 
@@ -1237,32 +1244,6 @@ mono_loader_lock_if_inited (void);
 void
 mono_loader_unlock_if_inited (void);
 
-void
-mono_loader_set_error_assembly_load (const char *assembly_name, gboolean ref_only);
-
-void
-mono_loader_set_error_type_load (const char *class_name, const char *assembly_name);
-
-void
-mono_loader_set_error_method_load (const char *class_name, const char *member_name);
-
-void
-mono_loader_set_error_field_load (MonoClass *klass, const char *member_name);
-void
-mono_loader_set_error_bad_image (char *msg);
-
-MonoException *
-mono_loader_error_prepare_exception (MonoLoaderError *error);
-
-MonoLoaderError *
-mono_loader_get_last_error (void);
-
-void
-mono_loader_clear_error    (void);
-
-void
-mono_loader_assert_no_error (void);
-
 void
 mono_reflection_init       (void);
 
@@ -1311,10 +1292,7 @@ const char*
 mono_lookup_jit_icall_symbol (const char *name);
 
 gboolean
-mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data);
-
-gpointer
-mono_class_get_exception_data (MonoClass *klass);
+mono_class_set_type_load_failure (MonoClass *klass, const char * fmt, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
 
 MonoException*
 mono_class_get_exception_for_failure (MonoClass *klass);
@@ -1326,7 +1304,10 @@ char*
 mono_type_get_full_name (MonoClass *klass);
 
 char *
-mono_method_get_name_full (MonoMethod *method, gboolean signature, MonoTypeNameFormat format);
+mono_method_get_name_full (MonoMethod *method, gboolean signature, gboolean ret, MonoTypeNameFormat format);
+
+char *
+mono_method_get_full_name (MonoMethod *method);
 
 MonoArrayType *mono_dup_array_type (MonoImage *image, MonoArrayType *a);
 MonoMethodSignature *mono_metadata_signature_deep_dup (MonoImage *image, MonoMethodSignature *sig);
@@ -1397,8 +1378,11 @@ mono_class_setup_interface_id (MonoClass *klass);
 MonoGenericContainer*
 mono_class_get_generic_container (MonoClass *klass);
 
-MonoGenericClass*
-mono_class_get_generic_class (MonoClass *klass);
+gpointer
+mono_class_alloc (MonoClass *klass, int size);
+
+gpointer
+mono_class_alloc0 (MonoClass *klass, int size);
 
 void
 mono_class_alloc_ext (MonoClass *klass);
@@ -1410,7 +1394,7 @@ MonoClassField*
 mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoType *type);
 
 MonoVTable*
-mono_class_vtable_full (MonoDomain *domain, MonoClass *klass, gboolean raise_on_error);
+mono_class_vtable_full (MonoDomain *domain, MonoClass *klass, MonoError *error);
 
 gboolean
 mono_class_is_assignable_from_slow (MonoClass *target, MonoClass *candidate);
@@ -1439,7 +1423,7 @@ void
 mono_unload_interface_id (MonoClass *klass);
 
 GPtrArray*
-mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoException **ex);
+mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error);
 
 char*
 mono_class_full_name (MonoClass *klass);
@@ -1474,4 +1458,47 @@ get_image_for_generic_param (MonoGenericParam *param);
 char *
 make_generic_name_string (MonoImage *image, int num);
 
+MonoClass *
+mono_class_load_from_name (MonoImage *image, const char* name_space, const char *name) MONO_LLVM_INTERNAL;
+
+MonoClass*
+mono_class_try_load_from_name (MonoImage *image, const char* name_space, const char *name);
+
+void
+mono_error_set_for_class_failure (MonoError *orerror, const MonoClass *klass);
+
+gboolean
+mono_class_has_failure (const MonoClass *klass);
+
+/* Kind specific accessors */
+MonoGenericClass*
+mono_class_get_generic_class (MonoClass *klass);
+
+MonoGenericClass*
+mono_class_try_get_generic_class (MonoClass *klass);
+
+void
+mono_class_set_flags (MonoClass *klass, guint32 flags);
+
+MonoGenericContainer*
+mono_class_try_get_generic_container (MonoClass *klass);
+
+void
+mono_class_set_generic_container (MonoClass *klass, MonoGenericContainer *container);
+
+guint32
+mono_class_get_first_method_idx (MonoClass *klass);
+
+void
+mono_class_set_first_method_idx (MonoClass *klass, guint32 idx);
+
+guint32
+mono_class_get_first_field_idx (MonoClass *klass);
+
+void
+mono_class_set_first_field_idx (MonoClass *klass, guint32 idx);
+
+/*Now that everything has been defined, let's include the inline functions */
+#include <mono/metadata/class-inlines.h>
+
 #endif /* __MONO_METADATA_CLASS_INTERNALS_H__ */