2009-07-22 Mark Probst <mark.probst@gmail.com>
[mono.git] / mono / metadata / object-internals.h
index d62330e3996d6ef4d1ad36938206cc52112765d5..84e447426a05438314648eb25bd4fe228653152b 100644 (file)
@@ -5,9 +5,30 @@
 #include <mono/metadata/threads.h>
 #include <mono/metadata/reflection.h>
 #include <mono/metadata/mempool.h>
+#include <mono/metadata/class-internals.h>
 #include <mono/io-layer/io-layer.h>
 #include "mono/utils/mono-compiler.h"
 
+/* 
+ * We should find a better place for this stuff. We can't put it in mono-compiler.h,
+ * since that is included by libgc.
+ */
+#ifndef G_LIKELY
+#define G_LIKELY(a) (a)
+#define G_UNLIKELY(a) (a)
+#endif
+
+/*
+ * glib defines this macro and uses it in the definition of G_LIKELY, and thus,
+ * g_assert (). The macro expands to a complex piece of code, preventing some
+ * gcc versions like 4.3.0 from handling the __builtin_expect construct properly,
+ * causing the generation of the unlikely branch into the middle of the code.
+ */
+#ifdef _G_BOOLEAN_EXPR
+#undef _G_BOOLEAN_EXPR
+#define _G_BOOLEAN_EXPR(expr) (gsize)(expr)
+#endif
+
 #if 1
 #ifdef __GNUC__
 #define mono_assert(expr)                 G_STMT_START{                  \
                mono_raise_exception (ex);                                \
        };                              }G_STMT_END
 
-
 /* 16 == default capacity */
 #define mono_stringbuilder_capacity(sb) ((sb)->str ? ((sb)->str->length) : 16)
 
+/* 
+ * Macros which cache the results of lookups locally.
+ * These should be used instead of the original versions, if the __GNUC__
+ * restriction is acceptable.
+ */
+
+#ifdef __GNUC__
+
+/* namespace and name should be a constant */
+#define mono_class_from_name_cached(image,namespace,name) ({ \
+                       static MonoClass *tmp_klass; \
+                       if (!tmp_klass) { \
+                               tmp_klass = mono_class_from_name ((image), (namespace), (name)); \
+                               g_assert (tmp_klass); \
+                       }; \
+                       tmp_klass; })
+/* name should be a compile-time constant */
+#define mono_class_get_field_from_name_cached(klass,name) ({ \
+                       static MonoClassField *tmp_field; \
+                       if (!tmp_field) { \
+                               tmp_field = mono_class_get_field_from_name ((klass), (name)); \
+                               g_assert (tmp_field); \
+                       }; \
+                       tmp_field; })
+/* eclass should be a run-time constant */
+#define mono_array_class_get_cached(eclass,rank) ({    \
+                       static MonoClass *tmp_klass; \
+                       if (!tmp_klass) { \
+                               tmp_klass = mono_array_class_get ((eclass), (rank));    \
+                               g_assert (tmp_klass); \
+                       }; \
+                       tmp_klass; })
+/* eclass should be a run-time constant */
+#define mono_array_new_cached(domain, eclass, size) mono_array_new_specific (mono_class_vtable ((domain), mono_array_class_get_cached ((eclass), 1)), (size))
+
+#else
+
+#define mono_class_from_name_cached(image,namespace,name) mono_class_from_name ((image), (namespace), (name))
+#define mono_class_get_field_from_name_cached(klass,name) mono_class_get_field_from_name ((klass), (name))
+#define mono_array_class_get_cached(eclass,rank) mono_array_class_get ((eclass), (rank))
+#define mono_array_new_cached(domain, eclass, size) mono_array_new_specific (mono_class_vtable ((domain), mono_array_class_get_cached ((eclass), 1)), (size))
+
+#endif
+
 typedef struct {
        MonoObject obj;
        MonoObject *identity;
@@ -120,6 +184,8 @@ typedef struct {
 
 struct _MonoException {
        MonoObject object;
+       /* Stores the IPs and the generic sharing infos
+          (vtable/MRGCTX) of the frames. */
        MonoArray  *trace_ips;
        MonoObject *inner_ex;
        MonoString *message;
@@ -177,11 +243,17 @@ typedef enum {
        CallType_OneWay = 3
 } MonoCallType;
 
+/* This corresponds to System.Type */
 struct _MonoReflectionType {
        MonoObject object;
        MonoType  *type;
 };
 
+typedef struct {
+       MonoReflectionType type;
+       MonoObject *type_info;
+} MonoReflectionMonoType;
+
 typedef struct {
        MonoObject  object;
        MonoReflectionType *class_to_proxy;     
@@ -248,7 +320,7 @@ struct _MonoThread {
        guint32     name_len;
        guint32     state;
        MonoException *abort_exc;
-       MonoObject *abort_state;
+       int abort_state_handle;
        guint64 tid;    /* This is accessed as a gsize in the code (so it can hold a 64bit pointer on systems that need it), but needs to reserve 64 bits of space on all machines as it corresponds to a field in managed code */
        HANDLE      start_notify;
        gpointer stack_ptr;
@@ -259,7 +331,8 @@ struct _MonoThread {
        int stack_size;
        MonoObject *start_obj;
        GSList *appdomain_refs;
-       MonoBoolean interruption_requested;
+       /* This is modified using atomic ops, so keep it a gint32 */
+       gint32 interruption_requested;
        gpointer suspend_event;
        gpointer suspended_event;
        gpointer resume_event;
@@ -268,20 +341,24 @@ struct _MonoThread {
        guint32 serialized_culture_info_len;
        guint8* serialized_ui_culture_info;
        guint32 serialized_ui_culture_info_len;
-       MonoObject *execution_context;
-       /* 
-        * These fields are used to avoid having to increment corlib versions
-        * when a new field is added to the unmanaged MonoThread structure.
-        */
        MonoBoolean thread_dump_requested;
        gpointer end_stack; /* This is only used when running in the debugger. */
        MonoBoolean thread_interrupt_requested;
        guint8  apartment_state;
-       gssize small_id;    /* A small, unique id, used for the hazard
-                              pointer table.  Should be changed to a
-                              guint32 at the next corlib version bump. */
+       gint32 critical_region_level;
+       guint32 small_id; /* A small, unique id, used for the hazard pointer table. */
        MonoThreadManageCallback manage_callback;
-       gpointer unused7;
+       MonoException *pending_exception;
+       MonoObject *ec_to_set;
+       /* 
+        * These fields are used to avoid having to increment corlib versions
+        * when a new field is added to the unmanaged MonoThread structure.
+        */
+       gpointer interrupt_on_stop;
+       gpointer unused3;
+       gpointer unused4;
+       gpointer unused5;
+       gpointer unused6;
 };
 
 typedef struct {
@@ -419,15 +496,27 @@ typedef struct {
 
 typedef struct {
        MonoObject object;
-       guint16 intType;
+       guint32 intType;
 } MonoInterfaceTypeAttribute;
 
+/* 
+ * Callbacks supplied by the runtime and called by the modules in metadata/
+ * This interface is easier to extend than adding a new function type +
+ * a new 'install' function for every callback.
+ */
+typedef struct {
+       gpointer (*create_ftnptr) (MonoDomain *domain, gpointer addr);
+       gpointer (*get_addr_from_ftnptr) (gpointer descr);
+} MonoRuntimeCallbacks;
+
 /* used to free a dynamic method */
 typedef void        (*MonoFreeMethodFunc)       (MonoDomain *domain, MonoMethod *method);
 
 /* Used to initialize the method pointers inside vtables */
 typedef gboolean    (*MonoInitVTableFunc)    (MonoVTable *vtable);
 
+void mono_set_pending_exception (MonoException *exc) MONO_INTERNAL;
+
 /* remoting and async support */
 
 MonoAsyncResult *
@@ -459,6 +548,9 @@ mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *
 void
 mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args) MONO_INTERNAL;
 
+void
+mono_delegate_ctor_with_method (MonoObject *this, MonoObject *target, gpointer addr, MonoMethod *method) MONO_INTERNAL;
+
 void
 mono_delegate_ctor         (MonoObject *this_obj, MonoObject *target, gpointer addr) MONO_INTERNAL;
 
@@ -484,7 +576,7 @@ void
 mono_install_free_method    (MonoFreeMethodFunc func) MONO_INTERNAL;
 
 void
-mono_install_init_vtable    (MonoInitVTableFunc func) MONO_INTERNAL;
+mono_install_callbacks      (MonoRuntimeCallbacks *cbs) MONO_INTERNAL;
 
 void
 mono_type_initialization_init (void) MONO_INTERNAL;
@@ -506,6 +598,43 @@ mono_domain_get_tls_offset (void) MONO_INTERNAL;
 
 /* Reflection and Reflection.Emit support */
 
+/*
+ * Handling System.Type objects:
+ *
+ *   Fields defined as System.Type in managed code should be defined as MonoObject* 
+ * in unmanaged structures, and the monotype_cast () function should be used for 
+ * casting them to MonoReflectionType* to avoid crashes/security issues when 
+ * encountering instances of user defined subclasses of System.Type.
+ */
+
+#define IS_MONOTYPE(obj) (!(obj) || (((MonoObject*)(obj))->vtable->klass->image == mono_defaults.corlib && ((MonoReflectionType*)(obj))->type != NULL))
+
+/* 
+ * Make sure the argument, which should be a System.Type is a System.MonoType object 
+ * or equivalent, and not an instance of 
+ * a user defined subclass of System.Type. This should be used in places were throwing
+ * an exception is safe.
+ */
+#define CHECK_MONOTYPE(obj) do { \
+       if (!IS_MONOTYPE (obj)) \
+               mono_raise_exception (mono_get_exception_not_supported ("User defined subclasses of System.Type are not yet supported")); \
+       } while (0)
+
+/* This should be used for accessing members of Type[] arrays */
+#define mono_type_array_get(arr,index) monotype_cast (mono_array_get ((arr), gpointer, (index)))
+
+/*
+ * Cast an object to MonoReflectionType, making sure it is a System.MonoType or
+ * a subclass of it.
+ */
+static inline MonoReflectionType*
+monotype_cast (MonoObject *obj)
+{
+       g_assert (IS_MONOTYPE (obj));
+
+       return (MonoReflectionType*)obj;
+}
+
 /*
  * The following structure must match the C# implementation in our corlib.
  */
@@ -524,15 +653,21 @@ struct _MonoReflectionGenericMethod {
 
 struct _MonoDelegate {
        MonoObject object;
+       /* The compiled code of the target method */
        gpointer method_ptr;
+       /* The invoke code */
        gpointer invoke_impl;
        MonoObject *target;
        MonoMethod *method;
-       MonoObject *target_type;
-       MonoString *method_name;
        gpointer delegate_trampoline;
+       /* 
+        * If non-NULL, this points to a memory location which stores the address of 
+        * the compiled code of the method, or NULL if it is not yet compiled.
+        */
+       guint8 **method_code;
        MonoReflectionMethod *method_info;
        MonoReflectionMethod *original_method_info;
+       MonoObject *data;
 };
 
 typedef struct _MonoMulticastDelegate MonoMulticastDelegate;
@@ -556,11 +691,17 @@ struct _MonoReflectionProperty {
        MonoProperty *property;
 };
 
+/*This is System.EventInfo*/
 struct _MonoReflectionEvent {
        MonoObject object;
+       MonoObject *cached_add_event;
+};
+
+typedef struct {
+       MonoReflectionEvent object;
        MonoClass *klass;
        MonoEvent *event;
-};
+} MonoReflectionMonoEvent;
 
 typedef struct {
        MonoObject object;
@@ -667,7 +808,7 @@ typedef struct {
 } MonoILExceptionInfo;
 
 typedef struct {
-       MonoReflectionType *extype;
+       MonoObject *extype;
        gint32 type;
        gint32 start;
        gint32 len;
@@ -676,7 +817,7 @@ typedef struct {
 
 typedef struct {
        MonoObject object;
-       MonoReflectionType *catch_type;
+       MonoObject *catch_type;
        gint32 filter_offset;
        gint32 flags;
        gint32 try_offset;
@@ -698,7 +839,7 @@ typedef struct {
         * LocalBuilder inherits from it under net 2.0.
         */
        MonoObject object;
-       MonoReflectionType *type;
+       MonoObject *type;
        MonoBoolean is_pinned;
        guint16 local_index;
        MonoString *name;
@@ -712,7 +853,7 @@ typedef struct {
        MonoString *guid;
        MonoString *mcookie;
        MonoString *marshaltype;
-       MonoReflectionType *marshaltyperef;
+       MonoObject *marshaltyperef;
        gint32 param_num;
        MonoBoolean has_size;
 } MonoReflectionMarshal;
@@ -750,7 +891,7 @@ typedef struct {
 typedef struct {
        MonoObject object;
        MonoMethod *mhandle;
-       MonoReflectionType *rtype;
+       MonoObject *rtype;
        MonoArray *parameters;
        guint32 attrs;
        guint32 iattrs;
@@ -837,12 +978,13 @@ typedef struct {
        gint32 machine;
        MonoBoolean corlib_internal;
        MonoArray *type_forwarders;
+       MonoArray *pktoken; /* as hexadecimal byte[] */
 } MonoReflectionAssemblyBuilder;
 
 typedef struct {
        MonoObject object;
        guint32 attrs;
-       MonoReflectionType *type;
+       MonoObject *type;
        MonoString *name;
        MonoObject *def_value;
        gint32 offset;
@@ -860,7 +1002,7 @@ typedef struct {
        MonoObject object;
        guint32 attrs;
        MonoString *name;
-       MonoReflectionType *type;
+       MonoObject *type;
        MonoArray *parameters;
        MonoArray *cattrs;
        MonoObject *def_value;
@@ -899,7 +1041,7 @@ typedef struct {
        MonoReflectionType type;
        MonoString *name;
        MonoString *nspace;
-       MonoReflectionType *parent;
+       MonoObject *parent;
        MonoReflectionType *nesting_type;
        MonoArray *interfaces;
        gint32     num_methods;
@@ -922,6 +1064,17 @@ typedef struct {
        MonoReflectionType *created;
 } MonoReflectionTypeBuilder;
 
+typedef struct {
+       MonoReflectionType type;
+       MonoReflectionType *element_type;
+       int rank;
+} MonoReflectionArrayType;
+
+typedef struct {
+       MonoReflectionType type;
+       MonoReflectionType *element_type;
+} MonoReflectionDerivedType;
+
 typedef struct {
        MonoReflectionType type;
        MonoReflectionTypeBuilder *tbuilder;
@@ -937,6 +1090,8 @@ typedef struct {
 typedef struct _MonoReflectionGenericClass MonoReflectionGenericClass;
 struct _MonoReflectionGenericClass {
        MonoReflectionType type;
+       /* From System.MonoType */
+       MonoObject *type_info;
        MonoReflectionTypeBuilder *generic_type;
        guint32 initialized;
 };
@@ -1052,6 +1207,11 @@ typedef struct {
        MonoReflectionMethodBuilder *mb;
 } MonoReflectionMethodOnTypeBuilderInst;
 
+typedef struct {
+       MonoObject object;
+       MonoBoolean visible;
+} MonoReflectionComVisibleAttribute;
+
 enum {
        RESOURCE_LOCATION_EMBEDDED = 1,
        RESOURCE_LOCATION_ANOTHER_ASSEMBLY = 2,
@@ -1065,6 +1225,12 @@ typedef struct {
        guint32 location;
 } MonoManifestResourceInfo;
 
+/* A boxed IntPtr */
+typedef struct {
+       MonoObject object;
+       gpointer m_value;
+} MonoIntPtr;
+
 /* Keep in sync with System.GenericParameterAttributes */
 typedef enum {
        GENERIC_PARAMETER_ATTRIBUTE_NON_VARIANT         = 0,
@@ -1083,11 +1249,12 @@ void          mono_image_create_pefile (MonoReflectionModuleBuilder *module, HAN
 void          mono_image_basic_init (MonoReflectionAssemblyBuilder *assembly) MONO_INTERNAL;
 MonoReflectionModule * mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *assembly, MonoString *file_name) MONO_INTERNAL;
 guint32       mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str) MONO_INTERNAL;
-guint32       mono_image_create_token  (MonoDynamicImage *assembly, MonoObject *obj, gboolean create_methodspec) MONO_INTERNAL;
+guint32       mono_image_create_token  (MonoDynamicImage *assembly, MonoObject *obj, gboolean create_methodspec, gboolean register_token) MONO_INTERNAL;
 guint32       mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types) MONO_INTERNAL;
 void          mono_image_module_basic_init (MonoReflectionModuleBuilder *module) MONO_INTERNAL;
 void          mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj) MONO_INTERNAL;
 void          mono_dynamic_image_free (MonoDynamicImage *image) MONO_INTERNAL;
+void          mono_image_set_wrappers_type (MonoReflectionModuleBuilder *mb, MonoReflectionType *type) MONO_INTERNAL;
 
 void        mono_reflection_setup_internal_class  (MonoReflectionTypeBuilder *tb) MONO_INTERNAL;
 
@@ -1105,6 +1272,9 @@ void mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *m) MONO
 void mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb) MONO_INTERNAL;
 
 void        mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam) MONO_INTERNAL;
+void        mono_reflection_create_unmanaged_type (MonoReflectionType *type) MONO_INTERNAL;
+
+MonoArray* mono_param_get_objects_internal  (MonoDomain *domain, MonoMethod *method, MonoClass *refclass) MONO_INTERNAL;
 
 MonoClass*
 mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic) MONO_INTERNAL;
@@ -1132,6 +1302,9 @@ mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass) MONO
 gboolean
 mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token) MONO_INTERNAL;
 
+MonoType*
+mono_reflection_type_get_handle (MonoReflectionType *ref) MONO_INTERNAL;
+
 void
 mono_image_build_metadata (MonoReflectionModuleBuilder *module) MONO_INTERNAL;
 
@@ -1144,6 +1317,10 @@ mono_release_type_locks (MonoThread *thread) MONO_INTERNAL;
 char *
 mono_string_to_utf8_mp (MonoMemPool *mp, MonoString *s) MONO_INTERNAL;
 
+char *
+mono_string_to_utf8_image (MonoImage *image, MonoString *s) MONO_INTERNAL;
+
+
 MonoArray*
 mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array) MONO_INTERNAL;
 
@@ -1170,28 +1347,36 @@ mono_nullable_box (guint8 *buf, MonoClass *klass) MONO_INTERNAL;
 
 #define MONO_IMT_SIZE 19
 
+typedef union {
+       int vtable_slot;
+       gpointer target_code;
+} MonoImtItemValue;
+
 typedef struct _MonoImtBuilderEntry {
-       MonoMethod *method;
+       gpointer key;
        struct _MonoImtBuilderEntry *next;
-       int vtable_slot;
+       MonoImtItemValue value;
        int children;
+       guint8 has_target_code : 1;
 } MonoImtBuilderEntry;
 
 typedef struct _MonoIMTCheckItem MonoIMTCheckItem;
 
 struct _MonoIMTCheckItem {
-       MonoMethod       *method;
+       gpointer          key;
        int               check_target_idx;
-       int               vtable_slot;
+       MonoImtItemValue  value;
        guint8           *jmp_code;
        guint8           *code_target;
        guint8            is_equals;
        guint8            compare_done;
        guint8            chunk_size;
        guint8            short_branch;
+       guint8            has_target_code;
 };
 
-typedef gpointer (*MonoImtThunkBuilder) (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count);
+typedef gpointer (*MonoImtThunkBuilder) (MonoVTable *vtable, MonoDomain *domain,
+               MonoIMTCheckItem **imt_entries, int count, gpointer fail_trunk);
 
 void
 mono_install_imt_thunk_builder (MonoImtThunkBuilder func) MONO_INTERNAL;
@@ -1208,9 +1393,17 @@ mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot) MONO_INTERNAL;
 guint32
 mono_method_get_imt_slot (MonoMethod *method) MONO_INTERNAL;
 
+void
+mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtable,
+                                                                                       gpointer *vtable_slot,
+                                                                                       MonoMethod *method, gpointer code) MONO_INTERNAL;
+
+gpointer
+mono_method_alloc_generic_virtual_thunk (MonoDomain *domain, int size) MONO_INTERNAL;
+
 typedef enum {
-       MONO_UNHANLED_POLICY_LEGACY,
-       MONO_UNHANLED_POLICY_CURRENT
+       MONO_UNHANDLED_POLICY_LEGACY,
+       MONO_UNHANDLED_POLICY_CURRENT
 } MonoRuntimeUnhandledExceptionPolicy;
 
 MonoRuntimeUnhandledExceptionPolicy
@@ -1218,5 +1411,18 @@ mono_runtime_unhandled_exception_policy_get (void) MONO_INTERNAL;
 void
 mono_runtime_unhandled_exception_policy_set (MonoRuntimeUnhandledExceptionPolicy policy) MONO_INTERNAL;
 
+MonoVTable *
+mono_class_try_get_vtable (MonoDomain *domain, MonoClass *class) MONO_INTERNAL;
+
+MonoException *
+mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception) MONO_INTERNAL;
+
+void
+mono_method_clear_object (MonoDomain *domain, MonoMethod *method) MONO_INTERNAL;
+
+void
+mono_class_compute_gc_descriptor (MonoClass *class) MONO_INTERNAL;
+
 #endif /* __MONO_OBJECT_INTERNALS_H__ */
 
+