#define __MONO_OBJECT_INTERNALS_H__
#include <mono/metadata/object.h>
+#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;
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;
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;
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;
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;
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;
+ 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;
- gpointer unused7;
};
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 *
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;
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;
/* 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.
*/
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;
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;
} MonoILExceptionInfo;
typedef struct {
- MonoReflectionType *extype;
+ MonoObject *extype;
gint32 type;
gint32 start;
gint32 len;
typedef struct {
MonoObject object;
- MonoReflectionType *catch_type;
+ MonoObject *catch_type;
gint32 filter_offset;
gint32 flags;
gint32 try_offset;
* LocalBuilder inherits from it under net 2.0.
*/
MonoObject object;
- MonoReflectionType *type;
+ MonoObject *type;
MonoBoolean is_pinned;
guint16 local_index;
MonoString *name;
MonoString *guid;
MonoString *mcookie;
MonoString *marshaltype;
- MonoReflectionType *marshaltyperef;
+ MonoObject *marshaltyperef;
gint32 param_num;
MonoBoolean has_size;
} MonoReflectionMarshal;
typedef struct {
MonoObject object;
MonoMethod *mhandle;
- MonoReflectionType *rtype;
+ MonoObject *rtype;
MonoArray *parameters;
guint32 attrs;
guint32 iattrs;
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;
MonoObject object;
guint32 attrs;
MonoString *name;
- MonoReflectionType *type;
+ MonoObject *type;
MonoArray *parameters;
MonoArray *cattrs;
MonoObject *def_value;
MonoReflectionType type;
MonoString *name;
MonoString *nspace;
- MonoReflectionType *parent;
+ MonoObject *parent;
MonoReflectionType *nesting_type;
MonoArray *interfaces;
gint32 num_methods;
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;
typedef struct _MonoReflectionGenericClass MonoReflectionGenericClass;
struct _MonoReflectionGenericClass {
MonoReflectionType type;
+ /* From System.MonoType */
+ MonoObject *type_info;
MonoReflectionTypeBuilder *generic_type;
guint32 initialized;
};
MonoReflectionFieldBuilder *fb;
} MonoReflectionFieldOnTypeBuilderInst;
+typedef struct {
+ MonoObject object;
+ MonoReflectionGenericClass *inst;
+ MonoReflectionCtorBuilder *cb;
+} MonoReflectionCtorOnTypeBuilderInst;
+
+typedef struct {
+ MonoObject object;
+ MonoReflectionGenericClass *inst;
+ MonoReflectionMethodBuilder *mb;
+} MonoReflectionMethodOnTypeBuilderInst;
+
+typedef struct {
+ MonoObject object;
+ MonoBoolean visible;
+} MonoReflectionComVisibleAttribute;
+
enum {
RESOURCE_LOCATION_EMBEDDED = 1,
RESOURCE_LOCATION_ANOTHER_ASSEMBLY = 2,
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,
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;
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;
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;
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;
#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;
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
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__ */
+