2008-01-09 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / metadata / class-internals.h
index 126ba0441a2b8a3d181ebf66a2d6ad76582ed384..59299e00a6cd90a032fde0d011eb4e09c652bc96 100644 (file)
@@ -19,38 +19,11 @@ typedef struct _MonoMethodWrapper MonoMethodWrapper;
 typedef struct _MonoMethodInflated MonoMethodInflated;
 typedef struct _MonoMethodPInvoke MonoMethodPInvoke;
 
-/*
- * remember to update wrapper_type_names if you change something here
- */
 typedef enum {
-       MONO_WRAPPER_NONE,
-       MONO_WRAPPER_DELEGATE_INVOKE,
-       MONO_WRAPPER_DELEGATE_BEGIN_INVOKE,
-       MONO_WRAPPER_DELEGATE_END_INVOKE,
-       MONO_WRAPPER_RUNTIME_INVOKE,
-       MONO_WRAPPER_NATIVE_TO_MANAGED,
-       MONO_WRAPPER_MANAGED_TO_NATIVE,
-       MONO_WRAPPER_MANAGED_TO_MANAGED,
-       MONO_WRAPPER_REMOTING_INVOKE,
-       MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK,
-       MONO_WRAPPER_XDOMAIN_INVOKE,
-       MONO_WRAPPER_XDOMAIN_DISPATCH,
-       MONO_WRAPPER_LDFLD,
-       MONO_WRAPPER_STFLD,
-       MONO_WRAPPER_LDFLD_REMOTE,
-       MONO_WRAPPER_STFLD_REMOTE,
-       MONO_WRAPPER_SYNCHRONIZED,
-       MONO_WRAPPER_DYNAMIC_METHOD,
-       MONO_WRAPPER_ISINST,
-       MONO_WRAPPER_CASTCLASS,
-       MONO_WRAPPER_PROXY_ISINST,
-       MONO_WRAPPER_STELEMREF,
-       MONO_WRAPPER_UNBOX,
-       MONO_WRAPPER_LDFLDA,
-       MONO_WRAPPER_WRITE_BARRIER,
-       MONO_WRAPPER_UNKNOWN,
-       MONO_WRAPPER_COMINTEROP_INVOKE,
-       MONO_WRAPPER_COMINTEROP
+#define WRAPPER(e,n) MONO_WRAPPER_ ## e,
+#include "wrapper-types.h"
+#undef WRAPPER
+       MONO_WRAPPER_NUM
 } MonoWrapperType;
 
 typedef enum {
@@ -105,19 +78,6 @@ struct _MonoMethodPInvoke {
        guint16 implmap_idx;  /* index into IMPLMAP */
 };
 
-/*
- * Inflated generic method.
- */
-struct _MonoMethodInflated {
-       union {
-               MonoMethod method;
-               MonoMethodNormal normal;
-               MonoMethodPInvoke pinvoke;
-       } method;
-       MonoGenericContext *context;    /* The current context. */
-       MonoMethod *declaring;          /* the generic method definition. */
-};
-
 typedef struct {
        MonoType *generic_type;
        gpointer reflection_info;
@@ -211,7 +171,12 @@ enum {
        MONO_EXCEPTION_UNVERIFIABLE_IL = 4,
        MONO_EXCEPTION_MISSING_METHOD = 5,
        MONO_EXCEPTION_MISSING_FIELD = 6,
-       MONO_EXCEPTION_TYPE_LOAD = 7
+       MONO_EXCEPTION_TYPE_LOAD = 7,
+       MONO_EXCEPTION_FILE_NOT_FOUND = 8,
+       MONO_EXCEPTION_METHOD_ACCESS = 9,
+       MONO_EXCEPTION_FIELD_ACCESS = 10,
+       MONO_EXCEPTION_GENERIC_SHARING_FAILED = 11,
+       MONO_EXCEPTION_BAD_IMAGE = 12
        /* add other exception type */
 };
 
@@ -225,17 +190,20 @@ typedef struct {
 } MonoClassRuntimeInfo;
 
 struct _MonoClass {
-       MonoImage *image;
-
-       /* The underlying type of the enum */
-       MonoType *enum_basetype;
        /* element class for arrays and enum */
        MonoClass *element_class; 
        /* used for subtype checks */
        MonoClass *cast_class; 
+
+       /* for fast subtype checks */
+       MonoClass **supertypes;
+       guint16     idepth;
+
        /* array dimension */
        guint8     rank;          
 
+       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;
@@ -278,31 +246,33 @@ struct _MonoClass {
 
        guint8     exception_type;      /* MONO_EXCEPTION_* */
        void*      exception_data;      /* Additional information about the exception */
-       guint32    declsec_flags;       /* declarative security attributes flags */
 
        MonoClass  *parent;
        MonoClass  *nested_in;
        GList      *nested_classes;
 
-       guint32    type_token;
+       MonoImage *image;
        const char *name;
        const char *name_space;
-       
-       /* for fast subtype checks */
-       MonoClass **supertypes;
-       guint16     idepth;
+
+       /* The underlying type of the enum */
+       MonoType *enum_basetype;
+
+       guint32    declsec_flags;       /* declarative security attributes flags */
+       guint32    type_token;
+       int        vtable_size; /* number of slots */
 
        guint16     interface_count;
        guint16     interface_id;        /* unique inderface id (for interfaces) */
        guint16     max_interface_id;
-        gint       *interface_offsets;   
+       
+       guint16     interface_offsets_count;
+       MonoClass **interfaces_packed;
+       guint16    *interface_offsets_packed;
+       guint8     *interface_bitmap;
+       
        MonoClass **interfaces;
 
-       /*
-        * Computed object instance size, total.
-        */
-       int        instance_size;
-       int        vtable_size; /* number of slots */
        union {
                int class_size; /* size of area for static fields */
                int element_size; /* for array types */
@@ -345,10 +315,33 @@ struct _MonoClass {
 
        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;    
 };
 
+#define MONO_CLASS_IMPLEMENTS_INTERFACE(k,uiid) (((uiid) <= (k)->max_interface_id) && ((k)->interface_bitmap [(uiid) >> 3] & (1 << ((uiid)&7))))
+int mono_class_interface_offset (MonoClass *klass, MonoClass *itf);
+
+typedef struct {
+       gpointer static_data;
+       MonoClass *klass;
+       MonoVTable *vtable;
+} MonoRuntimeGenericSuperInfo;
+
+typedef struct {
+       gpointer static_data;
+       MonoClass *klass;
+       MonoVTable *vtable;
+} MonoRuntimeGenericArgInfo;
+
+typedef struct {
+       MonoDomain *domain;
+       MonoRuntimeGenericArgInfo arg_infos [MONO_ZERO_LEN_ARRAY];
+} MonoRuntimeGenericContext;
+
 /* the interface_offsets array is stored in memory before this struct */
 struct MonoVTable {
        MonoClass  *klass;
@@ -360,15 +353,20 @@ struct MonoVTable {
        MonoDomain *domain;  /* each object/vtable belongs to exactly one domain */
         gpointer    data; /* to store static class data */
         gpointer    type; /* System.Type type for klass */
+       guint8     *interface_bitmap;
        guint16     max_interface_id;
        guint8      rank;
        guint remote          : 1; /* class is remotely activated */
        guint initialized     : 1; /* cctor has been run */
        guint init_failed     : 1; /* cctor execution failed */
+       guint32     imt_collisions_bitmap;
+       MonoRuntimeGenericContext *runtime_generic_context;
        /* do not add any fields after vtable, the structure is dynamically extended */
         gpointer    vtable [MONO_ZERO_LEN_ARRAY];      
 };
 
+#define MONO_VTABLE_IMPLEMENTS_INTERFACE(vt,uiid) (((uiid) <= (vt)->max_interface_id) && ((vt)->interface_bitmap [(uiid) >> 3] & (1 << ((uiid)&7))))
+
 /*
  * Generic instantiation data type encoding.
  */
@@ -383,30 +381,46 @@ struct _MonoGenericInst {
        guint id;                       /* unique ID for debugging */
        guint type_argc    : 22;        /* number of type arguments */
        guint is_open      :  1;        /* if this is an open type */
-       guint is_reference :  1;        /* if this is a reference type */
        MonoType **type_argv;
 };
 
 /*
- * A particular instantiation of a generic type.
+ * The generic context: an instantiation of a set of class and method generic parameters.
+ *
+ * NOTE: Never allocate this directly on the heap.  It have to be either allocated on the stack,
+ *      or embedded within other objects.  Don't store pointers to this, because it may be on the stack.
+ *      If you really have to, ensure you store a pointer to the embedding object along with it.
  */
-struct _MonoGenericClass {
-       MonoGenericInst *inst;          /* the instantiation */
-       MonoClass *container_class;     /* the generic type definition */
-       MonoGenericContext *cached_context;     /* if present, a "trivial" context that doesn't contain any method instantiation */
-       guint is_dynamic  : 1;          /* We're a MonoDynamicGenericClass */
-       guint is_inflated : 1;          /* We're a MonoInflatedGenericClass */
+struct _MonoGenericContext {
+       /* The instantiation corresponding to the class generic parameters */
+       MonoGenericInst *class_inst;
+       /* The instantiation corresponding to the method generic parameters */
+       MonoGenericInst *method_inst;
 };
 
 /*
- * Performance optimization:
- * We don't create the `MonoClass' for a `MonoGenericClass' until we really
- * need it.
+ * Inflated generic method.
  */
-struct _MonoInflatedGenericClass {
-       MonoGenericClass generic_class;
-       guint is_initialized   : 1;
-       MonoClass *klass;
+struct _MonoMethodInflated {
+       union {
+               MonoMethod method;
+               MonoMethodNormal normal;
+               MonoMethodPInvoke pinvoke;
+       } method;
+       MonoMethod *declaring;          /* the generic method definition. */
+       MonoGenericContext context;     /* The current instantiation */
+       gpointer reflection_info;
+};
+
+/*
+ * A particular instantiation of a generic type.
+ */
+struct _MonoGenericClass {
+       MonoClass *container_class;     /* the generic type definition */
+       MonoGenericContext context;     /* a context that contains the type instantiation doesn't contain any method instantiation */
+       guint is_dynamic  : 1;          /* We're a MonoDynamicGenericClass */
+       guint is_tb_open  : 1;          /* This is the fully open instantiation for a type_builder. Quite ugly, but it's temporary.*/
+       MonoClass *cached_class;        /* if present, the MonoClass corresponding to the instantiation.  */
 };
 
 /*
@@ -414,7 +428,7 @@ struct _MonoInflatedGenericClass {
  * a TypeBuilder.
  */
 struct _MonoDynamicGenericClass {
-       MonoInflatedGenericClass generic_class;
+       MonoGenericClass generic_class;
        int count_methods;
        MonoMethod **methods;
        int count_ctors;
@@ -428,26 +442,6 @@ struct _MonoDynamicGenericClass {
        guint initialized;
 };
 
-/*
- * A particular instantiation of a generic method.
- */
-struct _MonoGenericMethod {
-       MonoGenericInst *inst;                  /* the instantiation */
-       MonoGenericClass *generic_class;        /* if we're in a generic type */
-       MonoGenericContainer *container;        /* type parameters */
-       gpointer reflection_info;
-};
-
-/*
- * The generic context: an instantiation of a set of class and method generic parameters.
- */
-struct _MonoGenericContext {
-       /* The current generic class */
-       MonoGenericClass *gclass;
-       /* The current generic method */
-       MonoGenericMethod *gmethod;
-};
-
 /*
  * The generic container.
  *
@@ -458,11 +452,12 @@ struct _MonoGenericContainer {
        /* If we're a generic method definition in a generic type definition,
           the generic container of the containing class. */
        MonoGenericContainer *parent;
-       /* If we're a generic method definition, caches all their instantiations. */
-       GHashTable *method_hash;
-       /* If we're a generic type definition, its `MonoClass'. */
-       MonoClass *klass;
-       int type_argc    : 6;
+       /* the generic type definition or the generic method definition corresponding to this container */
+       union {
+               MonoClass *klass;
+               MonoMethod *method;
+       } owner;
+       int type_argc    : 31;
        /* If true, we're a generic method, otherwise a generic type definition. */
        /* Invariant: parent != NULL => is_method */
        int is_method    : 1;
@@ -476,7 +471,6 @@ struct _MonoGenericContainer {
 struct _MonoGenericParam {
        MonoGenericContainer *owner;    /* Type or method this parameter was defined in. */
        MonoClass *pklass;              /* The corresponding `MonoClass'. */
-       MonoMethod *method;             /* If we're a method type parameter, the method. */
        const char *name;
        guint16 flags;
        guint16 num;
@@ -516,23 +510,14 @@ typedef struct {
        MonoMethodSignature *sig;
 } MonoJitICallInfo;
 
-/*
- * Information about a type load error encountered by the loader.
- */
-typedef enum {
-       MONO_LOADER_ERROR_TYPE,
-       MONO_LOADER_ERROR_METHOD,
-       MONO_LOADER_ERROR_FIELD,
-       MONO_LOADER_ERROR_ASSEMBLY
-} MonoLoaderErrorKind;
-
 typedef struct {
-       MonoLoaderErrorKind kind;
+       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;
 
 #define mono_class_has_parent(klass,parent) (((klass)->idepth >= (parent)->idepth) && ((klass)->supertypes [(parent)->idepth - 1] == (parent)))
@@ -551,6 +536,29 @@ typedef struct {
        gulong inflated_method_count_2;
        gulong inflated_type_count;
        gulong generics_metadata_size;
+       gulong dynamic_code_alloc_count;
+       gulong dynamic_code_bytes_count;
+       gulong dynamic_code_frees_count;
+       gulong delegate_creations;
+       gulong imt_tables_size;
+       gulong imt_number_of_tables;
+       gulong imt_number_of_methods;
+       gulong imt_used_slots;
+       gulong imt_slots_with_collisions;
+       gulong imt_max_collisions_in_slot;
+       gulong imt_method_count_when_max_collisions;
+       gulong imt_thunks_size;
+       gulong jit_info_table_insert_count;
+       gulong jit_info_table_remove_count;
+       gulong jit_info_table_lookup_count;
+       gulong hazardous_pointer_count;
+       gulong generics_sharable_methods;
+       gulong generics_unsharable_methods;
+       gulong generics_shared_methods;
+       gulong minor_gc_count;
+       gulong major_gc_count;
+       gulong minor_gc_time_usecs;
+       gulong major_gc_time_usecs;
        gboolean enabled;
 } MonoStats;
 
@@ -564,13 +572,28 @@ typedef struct {
        void       *handle;
 } MonoSafeHandle;
 
+/*
+ * Keep in sync with HandleRef.cs
+ */
+typedef struct {
+       MonoObject *wrapper;
+       void       *handle;
+} MonoHandleRef;
+
+enum {
+       MONO_GENERIC_SHARING_NONE,
+       MONO_GENERIC_SHARING_CORLIB,
+       MONO_GENERIC_SHARING_ALL
+};
+
 extern MonoStats mono_stats MONO_INTERNAL;
 
 typedef gpointer (*MonoTrampoline)       (MonoMethod *method);
+typedef gpointer (*MonoJumpTrampoline)       (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper);
 typedef gpointer (*MonoRemotingTrampoline)       (MonoMethod *method, MonoRemotingTarget target);
-typedef gpointer (*MonoDelegateTrampoline)       (MonoMethod *method, gpointer addr);
+typedef gpointer (*MonoDelegateTrampoline)       (MonoClass *klass);
 
-typedef gpointer (*MonoLookupDynamicToken) (MonoImage *image, guint32 token, MonoClass **handle_class);
+typedef gpointer (*MonoLookupDynamicToken) (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context);
 
 typedef gboolean (*MonoGetCachedClassInfo) (MonoClass *klass, MonoCachedClassInfo *res);
 
@@ -628,9 +651,15 @@ mono_class_needs_cctor_run (MonoClass *klass, MonoMethod *caller) MONO_INTERNAL;
 gboolean
 mono_class_has_special_static_fields (MonoClass *klass) MONO_INTERNAL;
 
+const char*
+mono_class_get_field_default_value (MonoClassField *field, MonoTypeEnum *def_type) MONO_INTERNAL;
+
 void
 mono_install_trampoline (MonoTrampoline func) MONO_INTERNAL;
 
+void
+mono_install_jump_trampoline (MonoJumpTrampoline func) MONO_INTERNAL;
+
 void
 mono_install_remoting_trampoline (MonoRemotingTrampoline func) MONO_INTERNAL;
 
@@ -638,32 +667,49 @@ void
 mono_install_delegate_trampoline (MonoDelegateTrampoline func) MONO_INTERNAL;
 
 gpointer
-mono_lookup_dynamic_token (MonoImage *image, guint32 token) MONO_INTERNAL;
+mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context) MONO_INTERNAL;
 
 gpointer
-mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, MonoClass **handle_class) MONO_INTERNAL;
+mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean check_token, MonoClass **handle_class, MonoGenericContext *context) MONO_INTERNAL;
 
 void
 mono_install_lookup_dynamic_token (MonoLookupDynamicToken func) MONO_INTERNAL;
 
+gpointer
+mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper) MONO_INTERNAL;
+
+gpointer
+mono_runtime_create_delegate_trampoline (MonoClass *klass) MONO_INTERNAL;
+
 void
 mono_install_get_cached_class_info (MonoGetCachedClassInfo func) MONO_INTERNAL;
 
 void
 mono_install_get_class_from_name (MonoGetClassFromName func) MONO_INTERNAL;
 
-MonoInflatedGenericClass*
-mono_get_inflated_generic_class (MonoGenericClass *gclass) MONO_INTERNAL;
-
-MonoGenericContext *
+MonoGenericContext*
 mono_class_get_context (MonoClass *class) MONO_INTERNAL;
 
-MonoGenericContext *
+MonoGenericContext*
+mono_method_get_context (MonoMethod *method) MONO_INTERNAL;
+
+MonoGenericContext*
 mono_generic_class_get_context (MonoGenericClass *gclass) MONO_INTERNAL;
 
+MonoClass*
+mono_generic_class_get_class (MonoGenericClass *gclass) MONO_INTERNAL;
+
 MonoMethod*
 mono_class_inflate_generic_method_full (MonoMethod *method, MonoClass *klass_hint, MonoGenericContext *context);
 
+MonoMethodInflated*
+mono_method_inflated_lookup (MonoMethodInflated* method, gboolean cache) MONO_INTERNAL;
+
+MonoMethodSignature *
+mono_metadata_get_inflated_signature (MonoMethodSignature *sig, MonoGenericContext *context);
+
+void
+mono_metadata_free_inflated_signature (MonoMethodSignature *sig);
 
 typedef struct {
        MonoImage *corlib;
@@ -725,7 +771,12 @@ typedef struct {
        MonoClass *variant_class;
        MonoClass *com_object_class;
        MonoClass *com_interop_proxy_class;
+       MonoClass *iunknown_class;
+       MonoClass *idispatch_class;
        MonoClass *safehandle_class;
+       MonoClass *handleref_class;
+       MonoClass *attribute_class;
+       MonoClass *customattribute_data_class;
 } MonoDefaults;
 
 extern MonoDefaults mono_defaults MONO_INTERNAL;
@@ -753,6 +804,8 @@ mono_loader_set_error_method_load (const char *class_name, const char *member_na
 
 void
 mono_loader_set_error_field_load (MonoClass *klass, const char *member_name) MONO_INTERNAL;
+void
+mono_loader_set_error_bad_image (char *msg) MONO_INTERNAL;
 
 MonoException *
 mono_loader_error_prepare_exception (MonoLoaderError *error) MONO_INTERNAL;
@@ -763,6 +816,9 @@ mono_loader_get_last_error (void) MONO_INTERNAL;
 void
 mono_loader_clear_error    (void) MONO_INTERNAL;
 
+void
+mono_reflection_init       (void) MONO_INTERNAL;
+
 void
 mono_icall_init            (void) MONO_INTERNAL;
 
@@ -801,15 +857,6 @@ mono_find_jit_icall_by_name (const char *name) MONO_INTERNAL;
 MonoJitICallInfo *
 mono_find_jit_icall_by_addr (gconstpointer addr) MONO_INTERNAL;
 
-MonoGenericInst *
-mono_get_shared_generic_inst (MonoGenericContainer *container) MONO_INTERNAL;
-
-MonoGenericClass *
-mono_get_shared_generic_class (MonoGenericContainer *container, gboolean is_dynamic) MONO_INTERNAL;
-
-MonoGenericMethod *
-mono_get_shared_generic_method (MonoGenericContainer *container) MONO_INTERNAL;
-
 gboolean
 mono_class_set_failure (MonoClass *klass, guint32 ex_type, void *ex_data) MONO_INTERNAL;
 
@@ -837,5 +884,24 @@ void mono_object_describe_fields (MonoObject *obj);
 void mono_value_describe_fields  (MonoClass* klass, const char* addr);
 void mono_class_describe_statics (MonoClass* klass);
 
+/*Enum validation related functions*/
+gboolean
+mono_type_is_valid_enum_basetype (MonoType * type);
+
+gboolean
+mono_class_is_valid_enum (MonoClass *klass);
+
+MonoType *
+mono_type_get_full        (MonoImage *image, guint32 type_token, MonoGenericContext *context) MONO_INTERNAL;
+
+gboolean
+mono_generic_class_is_generic_type_definition (MonoGenericClass *gklass) MONO_INTERNAL;
+
+MonoType*
+mono_type_get_basic_type_from_generic (MonoType *type) MONO_INTERNAL;
+
+gboolean
+mono_class_generic_sharing_enabled (MonoClass *class) MONO_INTERNAL;
+
 #endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */