#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-error-internals.h>
#include <mono/utils/mono-memory-model.h>
+#include <mono/utils/checked-build.h>
#include "cominterop.h"
static void
void
mono_runtime_object_init (MonoObject *this)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethod *method = NULL;
MonoClass *klass = this->vtable->klass;
} TypeInitializationLock;
/* for locking access to type_initialization_hash and blocked_thread_hash */
-#define mono_type_initialization_lock() mono_mutex_lock (&type_initialization_section)
-#define mono_type_initialization_unlock() mono_mutex_unlock (&type_initialization_section)
static mono_mutex_t type_initialization_section;
+static inline void
+mono_type_initialization_lock (void)
+{
+ /* The critical sections protected by this lock in mono_runtime_class_init_full () can block */
+ MONO_PREPARE_BLOCKING;
+ mono_mutex_lock (&type_initialization_section);
+ MONO_FINISH_BLOCKING;
+}
+
+static inline void
+mono_type_initialization_unlock (void)
+{
+ mono_mutex_unlock (&type_initialization_section);
+}
static void
mono_type_init_lock (TypeInitializationLock *lock)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MONO_TRY_BLOCKING;
mono_mutex_lock (&lock->initialization_section);
MONO_FINISH_TRY_BLOCKING;
void
mono_thread_set_main (MonoThread *thread)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static gboolean registered = FALSE;
if (!registered) {
- MONO_GC_REGISTER_ROOT_SINGLE (main_thread);
+ MONO_GC_REGISTER_ROOT_SINGLE (main_thread, MONO_ROOT_SOURCE_THREADING, "main thread object");
registered = TRUE;
}
MonoThread*
mono_thread_get_main (void)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return main_thread;
}
static MonoException*
get_type_init_exception_for_vtable (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = vtable->domain;
MonoClass *klass = vtable->klass;
MonoException *ex;
void
mono_runtime_class_init (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_runtime_class_init_full (vtable, TRUE);
}
MonoException *
mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoException *exc;
MonoException *exc_to_throw;
MonoMethod *method = NULL;
MonoClass *klass;
gchar *full_name;
+ MonoDomain *domain = vtable->domain;
+ TypeInitializationLock *lock;
+ guint32 tid;
+ int do_initialization = 0;
+ MonoDomain *last_domain = NULL;
if (vtable->initialized)
return NULL;
}
}
method = mono_class_get_cctor (klass);
+ if (!method) {
+ vtable->initialized = 1;
+ return NULL;
+ }
+
+ tid = GetCurrentThreadId ();
- if (method) {
- MonoDomain *domain = vtable->domain;
- TypeInitializationLock *lock;
- guint32 tid = GetCurrentThreadId();
- int do_initialization = 0;
- MonoDomain *last_domain = NULL;
+ mono_type_initialization_lock ();
+ /* double check... */
+ if (vtable->initialized) {
+ mono_type_initialization_unlock ();
+ return NULL;
+ }
+ if (vtable->init_failed) {
+ mono_type_initialization_unlock ();
- mono_type_initialization_lock ();
- /* double check... */
- if (vtable->initialized) {
+ /* The type initialization already failed once, rethrow the same exception */
+ if (raise_exception)
+ mono_raise_exception (get_type_init_exception_for_vtable (vtable));
+ return get_type_init_exception_for_vtable (vtable);
+ }
+ lock = g_hash_table_lookup (type_initialization_hash, vtable);
+ if (lock == NULL) {
+ /* This thread will get to do the initialization */
+ if (mono_domain_get () != domain) {
+ /* Transfer into the target domain */
+ last_domain = mono_domain_get ();
+ if (!mono_domain_set (domain, FALSE)) {
+ vtable->initialized = 1;
+ mono_type_initialization_unlock ();
+ if (raise_exception)
+ mono_raise_exception (mono_get_exception_appdomain_unloaded ());
+ return mono_get_exception_appdomain_unloaded ();
+ }
+ }
+ lock = g_malloc (sizeof(TypeInitializationLock));
+ mono_mutex_init_recursive (&lock->initialization_section);
+ lock->initializing_tid = tid;
+ lock->waiting_count = 1;
+ lock->done = FALSE;
+ /* grab the vtable lock while this thread still owns type_initialization_section */
+ /* This is why type_initialization_lock needs to enter blocking mode */
+ mono_type_init_lock (lock);
+ g_hash_table_insert (type_initialization_hash, vtable, lock);
+ do_initialization = 1;
+ } else {
+ gpointer blocked;
+ TypeInitializationLock *pending_lock;
+
+ if (lock->initializing_tid == tid || lock->done) {
mono_type_initialization_unlock ();
return NULL;
}
- if (vtable->init_failed) {
- mono_type_initialization_unlock ();
-
- /* The type initialization already failed once, rethrow the same exception */
- if (raise_exception)
- mono_raise_exception (get_type_init_exception_for_vtable (vtable));
- return get_type_init_exception_for_vtable (vtable);
- }
- lock = g_hash_table_lookup (type_initialization_hash, vtable);
- if (lock == NULL) {
- /* This thread will get to do the initialization */
- if (mono_domain_get () != domain) {
- /* Transfer into the target domain */
- last_domain = mono_domain_get ();
- if (!mono_domain_set (domain, FALSE)) {
- vtable->initialized = 1;
+ /* see if the thread doing the initialization is already blocked on this thread */
+ blocked = GUINT_TO_POINTER (lock->initializing_tid);
+ while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
+ if (pending_lock->initializing_tid == tid) {
+ if (!pending_lock->done) {
mono_type_initialization_unlock ();
- if (raise_exception)
- mono_raise_exception (mono_get_exception_appdomain_unloaded ());
- return mono_get_exception_appdomain_unloaded ();
- }
- }
- lock = g_malloc (sizeof(TypeInitializationLock));
- mono_mutex_init_recursive (&lock->initialization_section);
- lock->initializing_tid = tid;
- lock->waiting_count = 1;
- lock->done = FALSE;
- /* grab the vtable lock while this thread still owns type_initialization_section */
- mono_type_init_lock (lock);
- g_hash_table_insert (type_initialization_hash, vtable, lock);
- do_initialization = 1;
- } else {
- gpointer blocked;
- TypeInitializationLock *pending_lock;
-
- if (lock->initializing_tid == tid || lock->done) {
- mono_type_initialization_unlock ();
- return NULL;
- }
- /* see if the thread doing the initialization is already blocked on this thread */
- blocked = GUINT_TO_POINTER (lock->initializing_tid);
- while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
- if (pending_lock->initializing_tid == tid) {
- if (!pending_lock->done) {
- mono_type_initialization_unlock ();
- return NULL;
- } else {
- /* the thread doing the initialization is blocked on this thread,
- but on a lock that has already been freed. It just hasn't got
- time to awake */
- break;
- }
+ return NULL;
+ } else {
+ /* the thread doing the initialization is blocked on this thread,
+ but on a lock that has already been freed. It just hasn't got
+ time to awake */
+ break;
}
- blocked = GUINT_TO_POINTER (pending_lock->initializing_tid);
}
- ++lock->waiting_count;
- /* record the fact that we are waiting on the initializing thread */
- g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
+ blocked = GUINT_TO_POINTER (pending_lock->initializing_tid);
}
- mono_type_initialization_unlock ();
-
- if (do_initialization) {
- mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
-
- /* If the initialization failed, mark the class as unusable. */
- /* Avoid infinite loops */
- if (!(exc == NULL ||
- (klass->image == mono_defaults.corlib &&
- !strcmp (klass->name_space, "System") &&
- !strcmp (klass->name, "TypeInitializationException")))) {
- vtable->init_failed = 1;
+ ++lock->waiting_count;
+ /* record the fact that we are waiting on the initializing thread */
+ g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
+ }
+ mono_type_initialization_unlock ();
- if (klass->name_space && *klass->name_space)
- full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
- else
- full_name = g_strdup (klass->name);
- exc_to_throw = mono_get_exception_type_initialization (full_name, exc);
- g_free (full_name);
+ if (do_initialization) {
+ mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
- /*
- * Store the exception object so it could be thrown on subsequent
- * accesses.
- */
- mono_domain_lock (domain);
- if (!domain->type_init_exception_hash)
- domain->type_init_exception_hash = mono_g_hash_table_new_type (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC);
- mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_throw);
- mono_domain_unlock (domain);
- }
+ /* If the initialization failed, mark the class as unusable. */
+ /* Avoid infinite loops */
+ if (!(exc == NULL ||
+ (klass->image == mono_defaults.corlib &&
+ !strcmp (klass->name_space, "System") &&
+ !strcmp (klass->name, "TypeInitializationException")))) {
+ vtable->init_failed = 1;
- if (last_domain)
- mono_domain_set (last_domain, TRUE);
- lock->done = TRUE;
- mono_type_init_unlock (lock);
- } else {
- /* this just blocks until the initializing thread is done */
- mono_type_init_lock (lock);
- mono_type_init_unlock (lock);
- }
+ if (klass->name_space && *klass->name_space)
+ full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
+ else
+ full_name = g_strdup (klass->name);
+ exc_to_throw = mono_get_exception_type_initialization (full_name, exc);
+ g_free (full_name);
- mono_type_initialization_lock ();
- if (lock->initializing_tid != tid)
- g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
- --lock->waiting_count;
- if (lock->waiting_count == 0) {
- mono_mutex_destroy (&lock->initialization_section);
- g_hash_table_remove (type_initialization_hash, vtable);
- g_free (lock);
+ /*
+ * Store the exception object so it could be thrown on subsequent
+ * accesses.
+ */
+ mono_domain_lock (domain);
+ if (!domain->type_init_exception_hash)
+ domain->type_init_exception_hash = mono_g_hash_table_new_type (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, "type initialization exceptions table");
+ mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_throw);
+ mono_domain_unlock (domain);
}
- mono_memory_barrier ();
- if (!vtable->init_failed)
- vtable->initialized = 1;
- mono_type_initialization_unlock ();
- if (vtable->init_failed) {
- /* Either we were the initializing thread or we waited for the initialization */
- if (raise_exception)
- mono_raise_exception (get_type_init_exception_for_vtable (vtable));
- return get_type_init_exception_for_vtable (vtable);
- }
+ if (last_domain)
+ mono_domain_set (last_domain, TRUE);
+ lock->done = TRUE;
+ mono_type_init_unlock (lock);
} else {
+ /* this just blocks until the initializing thread is done */
+ mono_type_init_lock (lock);
+ mono_type_init_unlock (lock);
+ }
+
+ mono_type_initialization_lock ();
+ if (lock->initializing_tid != tid)
+ g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
+ --lock->waiting_count;
+ if (lock->waiting_count == 0) {
+ mono_mutex_destroy (&lock->initialization_section);
+ g_hash_table_remove (type_initialization_hash, vtable);
+ g_free (lock);
+ }
+ mono_memory_barrier ();
+ if (!vtable->init_failed)
vtable->initialized = 1;
- return NULL;
+ mono_type_initialization_unlock ();
+
+ if (vtable->init_failed) {
+ /* Either we were the initializing thread or we waited for the initialization */
+ if (raise_exception)
+ mono_raise_exception (get_type_init_exception_for_vtable (vtable));
+ return get_type_init_exception_for_vtable (vtable);
}
return NULL;
}
static
gboolean release_type_locks (gpointer key, gpointer value, gpointer user)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoVTable *vtable = (MonoVTable*)key;
TypeInitializationLock *lock = (TypeInitializationLock*) value;
void
mono_release_type_locks (MonoInternalThread *thread)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_type_initialization_lock ();
g_hash_table_foreach_remove (type_initialization_hash, release_type_locks, (gpointer)(gsize)(thread->tid));
mono_type_initialization_unlock ();
gpointer
mono_compile_method (MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!default_mono_compile_method) {
g_error ("compile method called on uninitialized runtime");
return NULL;
gpointer
mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
return arch_create_jump_trampoline (domain, method, add_sync_wrapper);
}
gpointer
mono_runtime_create_delegate_trampoline (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
return arch_create_delegate_trampoline (mono_domain_get (), klass);
}
void
mono_runtime_free_method (MonoDomain *domain, MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (default_mono_free_method != NULL)
default_mono_free_method (domain, method);
static gsize*
compute_class_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int *max_set, gboolean static_fields)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoClassField *field;
MonoClass *p;
guint32 pos;
if (field->type->byref)
break;
- if (static_fields && field->offset == -1)
- /* special static */
+ // Special static fields do not have a domain-level static slot
+ if (static_fields && mono_class_field_is_special_static (field))
continue;
pos = field->offset / sizeof (gpointer);
gsize*
mono_class_compute_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int *max_set, gboolean static_fields)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
return compute_class_bitmap (class, bitmap, size, offset, max_set, static_fields);
}
MonoString*
mono_string_alloc (int length)
{
+ MONO_REQ_GC_UNSAFE_MODE;
return mono_string_new_size (mono_domain_get (), length);
}
void
mono_class_compute_gc_descriptor (MonoClass *class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int max_set = 0;
gsize *bitmap;
gsize default_bitmap [4] = {0};
static gint32
field_is_special_static (MonoClass *fklass, MonoClassField *field)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoCustomAttrInfo *ainfo;
int i;
ainfo = mono_custom_attrs_from_field (fklass, field);
guint32
mono_method_get_imt_slot (MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethodSignature *sig;
int hashes_count;
guint32 *hashes_start, *hashes;
static void
add_imt_builder_entry (MonoImtBuilderEntry **imt_builder, MonoMethod *method, guint32 *imt_collisions_bitmap, int vtable_slot, int slot_num) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 imt_slot = mono_method_get_imt_slot (method);
MonoImtBuilderEntry *entry;
static int
imt_emit_ir (MonoImtBuilderEntry **sorted_array, int start, int end, GPtrArray *out_array)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int count = end - start;
int chunk_start = out_array->len;
if (count < 4) {
static GPtrArray*
imt_sort_slot_entries (MonoImtBuilderEntry *entries) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int number_of_entries = entries->children + 1;
MonoImtBuilderEntry **sorted_array = malloc (sizeof (MonoImtBuilderEntry*) * number_of_entries);
GPtrArray *result = g_ptr_array_new ();
static gpointer
initialize_imt_slot (MonoVTable *vtable, MonoDomain *domain, MonoImtBuilderEntry *imt_builder_entry, gpointer fail_tramp)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (imt_builder_entry != NULL) {
if (imt_builder_entry->children == 0 && !fail_tramp) {
/* No collision, return the vtable slot contents */
static void
build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer* imt, GSList *extra_interfaces, int slot_num)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
GSList *list_item;
guint32 imt_collisions_bitmap = 0;
static void
build_imt (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer* imt, GSList *extra_interfaces) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
build_imt_slots (klass, vt, domain, imt, extra_interfaces, -1);
}
void
mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
gpointer *imt = (gpointer*)vtable;
imt -= MONO_IMT_SIZE;
g_assert (imt_slot >= 0 && imt_slot < MONO_IMT_SIZE);
static void
init_thunk_free_lists (MonoDomain *domain)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (domain->thunk_free_lists)
return;
domain->thunk_free_lists = mono_domain_alloc0 (domain, sizeof (gpointer) * NUM_FREE_LISTS);
gpointer
mono_method_alloc_generic_virtual_thunk (MonoDomain *domain, int size)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
static gboolean inited = FALSE;
static int generic_virtual_thunks_size = 0;
static void
invalidate_generic_virtual_thunk (MonoDomain *domain, gpointer code)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 *p = code;
MonoThunkFreeList *l = (MonoThunkFreeList*)(p - 1);
gboolean found = FALSE;
static MonoImtBuilderEntry*
get_generic_virtual_entries (MonoDomain *domain, gpointer *vtable_slot)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
GenericVirtualCase *list;
MonoImtBuilderEntry *entries;
gpointer *vtable_slot,
MonoMethod *method, gpointer code)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
static gboolean inited = FALSE;
static int num_added = 0;
MonoVTable *
mono_class_vtable_full (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClassRuntimeInfo *runtime_info;
g_assert (class);
MonoVTable *
mono_class_try_get_vtable (MonoDomain *domain, MonoClass *class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoClassRuntimeInfo *runtime_info;
g_assert (class);
static gpointer*
alloc_vtable (MonoDomain *domain, size_t vtable_size, size_t imt_table_bytes)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
size_t alloc_offset;
/*
static MonoVTable *
mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vt;
MonoClassRuntimeInfo *runtime_info, *old_info;
MonoClassField *field;
bitmap = compute_class_bitmap (class, default_bitmap, sizeof (default_bitmap) * 8, 0, &max_set, TRUE);
/*g_print ("bitmap 0x%x for %s.%s (size: %d)\n", bitmap [0], class->name_space, class->name, class_size);*/
statics_gc_descr = mono_gc_make_descr_from_bitmap (bitmap, max_set + 1);
- vt->vtable [class->vtable_size] = mono_gc_alloc_fixed (class_size, statics_gc_descr);
+ vt->vtable [class->vtable_size] = mono_gc_alloc_fixed (class_size, statics_gc_descr, MONO_ROOT_SOURCE_STATIC, "managed static variables");
mono_domain_add_class_static_data (domain, class, vt->vtable [class->vtable_size], NULL);
if (bitmap != default_bitmap)
g_free (bitmap);
/* This is unregistered in
unregister_vtable_reflection_type() in
domain.c. */
- MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type);
+ MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type, MONO_ROOT_SOURCE_REFLECTION, "vtable reflection type");
}
mono_vtable_set_is_remote (vt, mono_class_is_contextbound (class));
/* This is unregistered in
unregister_vtable_reflection_type() in
domain.c. */
- MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type);
+ MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type, MONO_ROOT_SOURCE_REFLECTION, "vtable reflection type");
}
mono_domain_unlock (domain);
static MonoVTable *
mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRemotingTarget target_type)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoVTable *vt, *pvt;
int i, j, vtsize, max_interface_id, extra_interface_vtsize = 0;
gboolean
mono_class_field_is_special_static (MonoClassField *field)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
return FALSE;
if (mono_field_is_deleted (field))
return FALSE;
if (!(field->type->attrs & FIELD_ATTRIBUTE_LITERAL)) {
+ if (field->offset == -1)
+ return TRUE;
if (field_is_special_static (field->parent, field) != SPECIAL_STATIC_NONE)
return TRUE;
}
guint32
mono_class_field_get_special_static_type (MonoClassField *field)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
return SPECIAL_STATIC_NONE;
if (mono_field_is_deleted (field))
gboolean
mono_class_has_special_static_fields (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
MonoClassField *field;
gpointer iter;
static gpointer*
create_remote_class_key (MonoRemoteClass *remote_class, MonoClass *extra_class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
gpointer *key;
int i, j;
static gpointer*
copy_remote_class_key (MonoDomain *domain, gpointer *key)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
int key_size = (GPOINTER_TO_UINT (key [0]) + 1) * sizeof (gpointer);
gpointer *mp_key = mono_domain_alloc (domain, key_size);
MonoRemoteClass*
mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoRemoteClass *rc;
gpointer* key, *mp_key;
static MonoRemoteClass*
clone_remote_class (MonoDomain *domain, MonoRemoteClass* remote_class, MonoClass *extra_class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoRemoteClass *rc;
gpointer* key, *mp_key;
gpointer
mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRealProxy *rp)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_loader_lock (); /*FIXME mono_class_from_mono_type and mono_class_proxy_vtable take it*/
mono_domain_lock (domain);
if (rp->target_domain_id != -1) {
void
mono_upgrade_remote_class (MonoDomain *domain, MonoObject *proxy_object, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoTransparentProxy *tproxy;
MonoRemoteClass *remote_class;
gboolean redo_vtable;
MonoMethod*
mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *klass;
MonoMethod **vtable;
gboolean is_proxy = FALSE;
MonoObject*
mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *result;
if (mono_runtime_get_no_exec ())
gpointer
mono_method_get_unmanaged_thunk (MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+ MONO_REQ_API_ENTRYPOINT;
+
+ gpointer res;
+
+ MONO_PREPARE_RESET_BLOCKING
method = mono_marshal_get_thunk_invoke_wrapper (method);
- return mono_compile_method (method);
+ res = mono_compile_method (method);
+ MONO_FINISH_RESET_BLOCKING
+
+ return res;
}
void
mono_copy_value (MonoType *type, void *dest, void *value, int deref_pointer)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int t;
if (type->byref) {
/* object fields cannot be byref, so we don't need a
void
mono_field_set_value (MonoObject *obj, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *dest;
g_return_if_fail (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC));
void
mono_field_static_set_value (MonoVTable *vt, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *dest;
g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
void *
mono_vtable_get_static_field_data (MonoVTable *vt)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!vt->has_static_fields)
return NULL;
return vt->vtable [vt->klass->vtable_size];
static guint8*
mono_field_get_addr (MonoObject *obj, MonoVTable *vt, MonoClassField *field)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
guint8 *src;
if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
void
mono_field_get_value (MonoObject *obj, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *src;
g_assert (obj);
MonoObject *
mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
MonoClass *klass;
MonoVTable *vtable = NULL;
int
mono_get_constant_value_from_blob (MonoDomain* domain, MonoTypeEnum type, const char *blob, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int retval = 0;
const char *p = blob;
mono_metadata_decode_blob_size (p, &p);
static void
get_default_field_value (MonoDomain* domain, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoTypeEnum def_type;
const char* data;
void
mono_field_static_get_value_for_thread (MonoInternalThread *thread, MonoVTable *vt, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *src;
g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
void
mono_field_static_get_value (MonoVTable *vt, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
mono_field_static_get_value_for_thread (mono_thread_internal_current (), vt, field, value);
}
void
mono_property_set_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
default_mono_runtime_invoke (prop->set, obj, params, exc);
}
MonoObject*
mono_property_get_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return default_mono_runtime_invoke (prop->get, obj, params, exc);
}
void
mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields_locking (klass);
MonoObject*
mono_nullable_box (guint8 *buf, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields_locking (klass);
MonoMethod *
mono_get_delegate_invoke (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethod *im;
/* This is called at runtime, so avoid the slower search in metadata */
MonoMethod *
mono_get_delegate_begin_invoke (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethod *im;
/* This is called at runtime, so avoid the slower search in metadata */
MonoMethod *
mono_get_delegate_end_invoke (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethod *im;
/* This is called at runtime, so avoid the slower search in metadata */
MonoObject*
mono_runtime_delegate_invoke (MonoObject *delegate, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethod *im;
MonoClass *klass = delegate->vtable->klass;
MonoArray*
mono_runtime_get_main_args (void)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoArray *res;
int i;
MonoDomain *domain = mono_domain_get ();
static void
free_main_args (void)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
for (i = 0; i < num_main_args; ++i)
int
mono_runtime_set_main_args (int argc, char* argv[])
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
free_main_args ();
mono_runtime_run_main (MonoMethod *method, int argc, char* argv[],
MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int i;
MonoArray *args = NULL;
MonoDomain *domain = mono_domain_get ();
static MonoObject*
deserialize_object (MonoObject *obj, gboolean *failure, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *deserialize_method;
void *params [1];
static MonoObject*
make_transparent_proxy (MonoObject *obj, gboolean *failure, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *get_proxy_method;
MonoDomain *domain = mono_domain_get ();
MonoObject*
mono_object_xdomain_representation (MonoObject *obj, MonoDomain *target_domain, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *deserialized = NULL;
gboolean failure = FALSE;
static MonoObject *
create_unhandled_exception_eventargs (MonoObject *exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *klass;
gpointer args [2];
MonoMethod *method = NULL;
/* Used in mono_unhandled_exception */
static void
call_unhandled_exception_delegate (MonoDomain *domain, MonoObject *delegate, MonoObject *exc) {
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *e = NULL;
gpointer pa [2];
MonoDomain *current_domain = mono_domain_get ();
void
mono_unhandled_exception (MonoObject *exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *current_domain = mono_domain_get ();
MonoDomain *root_domain = mono_get_root_domain ();
MonoClassField *field;
int
mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain;
gpointer pa [1];
int rval;
mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethodSignature *sig = mono_method_signature (method);
gpointer *pa = NULL;
MonoObject *res;
static void
arith_overflow (void)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_raise_exception (mono_get_exception_overflow ());
}
MonoObject *
mono_object_new (MonoDomain *domain, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vtable;
vtable = mono_class_vtable (domain, klass);
MonoObject *
mono_object_new_pinned (MonoDomain *domain, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vtable;
vtable = mono_class_vtable (domain, klass);
MonoObject *
mono_object_new_specific (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
/* check for is_com_object for COM Interop */
mono_class_init (klass);
im = mono_class_get_method_from_name (klass, "CreateProxyForType", 1);
- g_assert (im);
+ if (!im)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
vtable->domain->create_proxy_for_type_method = im;
}
MonoObject *
mono_object_new_alloc_specific (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o = mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
if (G_UNLIKELY (vtable->klass->has_finalize))
MonoObject*
mono_object_new_fast (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
}
void*
mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *pass_size_in_words)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
*pass_size_in_words = FALSE;
if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
MonoObject *
mono_object_new_from_token (MonoDomain *domain, MonoImage *image, guint32 token)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoClass *class;
MonoObject *
mono_object_clone (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
int size = obj->vtable->klass->instance_size;
void
mono_array_full_copy (MonoArray *src, MonoArray *dest)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
uintptr_t size;
MonoClass *klass = src->obj.vtable->klass;
MonoArray*
mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoArray *o;
uintptr_t size, i;
uintptr_t *sizes;
MonoArray*
mono_array_clone (MonoArray *array)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_array_clone_in_domain (((MonoObject *)array)->vtable->domain, array);
}
gboolean
mono_array_calc_byte_len (MonoClass *class, uintptr_t len, uintptr_t *res)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
uintptr_t byte_len;
byte_len = mono_array_element_size (class);
MonoArray*
mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
uintptr_t byte_len = 0, len, bounds_size;
MonoObject *o;
MonoArray *array;
MonoArray *
mono_array_new (MonoDomain *domain, MonoClass *eclass, uintptr_t n)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *ac;
ac = mono_array_class_get (eclass, 1);
MonoArray *
mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
MonoArray *ao;
uintptr_t byte_len;
MonoString *
mono_string_new_utf16 (MonoDomain *domain, const guint16 *text, gint32 len)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
s = mono_string_new_size (domain, len);
MonoString *
mono_string_new_utf32 (MonoDomain *domain, const mono_unichar4 *text, gint32 len)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
mono_unichar2 *utf16_output = NULL;
gint32 utf16_len = 0;
MonoString *
mono_string_new_size (MonoDomain *domain, gint32 len)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
MonoVTable *vtable;
size_t size;
MonoString*
mono_string_new_len (MonoDomain *domain, const char *text, guint length)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
GError *error = NULL;
MonoString *o = NULL;
guint16 *ut;
MonoString*
mono_string_new (MonoDomain *domain, const char *text)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
GError *error = NULL;
MonoString *o = NULL;
guint16 *ut;
MonoString*
mono_string_new_wrapper (const char *text)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
if (text)
MonoObject *
mono_value_box (MonoDomain *domain, MonoClass *class, gpointer value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *res;
int size;
MonoVTable *vtable;
void
mono_value_copy (gpointer dest, gpointer src, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_gc_wbarrier_value_copy (dest, src, 1, klass);
}
void
mono_value_copy_array (MonoArray *dest, int dest_idx, gpointer src, int count)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int size = mono_array_element_size (dest->obj.vtable->klass);
char *d = mono_array_addr_with_size_fast (dest, size, dest_idx);
g_assert (size == mono_class_value_size (mono_object_class (dest)->element_class, NULL));
MonoDomain*
mono_object_get_domain (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_object_domain (obj);
}
MonoClass*
mono_object_get_class (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_object_class (obj);
}
/**
guint
mono_object_get_size (MonoObject* o)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass* klass = mono_object_class (o);
if (klass == mono_defaults.string_class) {
return sizeof (MonoString) + 2 * mono_string_length ((MonoString*) o) + 2;
gpointer
mono_object_unbox (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
/* add assert for valuetypes? */
g_assert (obj->vtable->klass->valuetype);
return ((char*)obj) + sizeof (MonoObject);
MonoObject *
mono_object_isinst (MonoObject *obj, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (!klass->inited)
mono_class_init (klass);
MonoObject *
mono_object_isinst_mbyref (MonoObject *obj, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vt;
if (!obj)
gpointer pa [2];
im = mono_class_get_method_from_name (rpklass, "CanCastTo", -1);
+ if (!im)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
im = mono_object_get_virtual_method (rp, im);
g_assert (im);
MonoObject *
mono_object_castclass_mbyref (MonoObject *obj, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (!obj) return NULL;
if (mono_object_isinst_mbyref (obj, klass)) return obj;
static void
str_lookup (MonoDomain *domain, gpointer user_data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
LDStrInfo *info = user_data;
if (info->res || domain == info->orig_domain)
return;
static MonoString*
mono_string_get_pinned (MonoString *str)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int size;
MonoString *news;
size = sizeof (MonoString) + 2 * (mono_string_length (str) + 1);
static MonoString*
mono_string_is_interned_lookup (MonoString *str, int insert)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoGHashTable *ldstr_table;
MonoString *s, *res;
MonoDomain *domain;
MonoString*
mono_string_is_interned (MonoString *o)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_is_interned_lookup (o, FALSE);
}
MonoString*
mono_string_intern (MonoString *str)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_is_interned_lookup (str, TRUE);
}
MonoString*
mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (image->dynamic) {
MonoString *str = mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL);
return str;
static MonoString*
mono_ldstr_metadata_sig (MonoDomain *domain, const char* sig)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
const char *str = sig;
MonoString *o, *interned;
size_t len2;
char *
mono_string_to_utf8 (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
char *result = mono_string_to_utf8_checked (s, &error);
char *
mono_string_to_utf8_checked (MonoString *s, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
long written = 0;
char *as;
GError *gerror = NULL;
char *
mono_string_to_utf8_ignore (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
long written = 0;
char *as;
char *
mono_string_to_utf8_image_ignore (MonoImage *image, MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (NULL, image, s, TRUE, NULL);
}
char *
mono_string_to_utf8_mp_ignore (MonoMemPool *mp, MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (mp, NULL, s, TRUE, NULL);
}
mono_unichar2*
mono_string_to_utf16 (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char *as;
if (s == NULL)
mono_unichar4*
mono_string_to_utf32 (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_unichar4 *utf32_output = NULL;
GError *error = NULL;
glong items_written;
MonoString *
mono_string_from_utf16 (gunichar2 *data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
int len = 0;
MonoString *
mono_string_from_utf32 (mono_unichar4 *data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString* result = NULL;
mono_unichar2 *utf16_output = NULL;
GError *error = NULL;
static char *
mono_string_to_utf8_internal (MonoMemPool *mp, MonoImage *image, MonoString *s, gboolean ignore_error, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char *r;
char *mp_s;
int len;
char *
mono_string_to_utf8_image (MonoImage *image, MonoString *s, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (NULL, image, s, FALSE, error);
}
char *
mono_string_to_utf8_mp (MonoMemPool *mp, MonoString *s, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (mp, NULL, s, FALSE, error);
}
void
mono_raise_exception (MonoException *ex)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
/*
* NOTE: Do NOT annotate this function with G_GNUC_NORETURN, since
* that will cause gcc to omit the function epilog, causing problems when
void
mono_raise_exception_with_context (MonoException *ex, MonoContext *ctx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
eh_callbacks.mono_raise_exception_with_ctx (ex, ctx);
}
MonoWaitHandle *
mono_wait_handle_new (MonoDomain *domain, HANDLE handle)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoWaitHandle *res;
gpointer params [1];
static MonoMethod *handle_set;
HANDLE
mono_wait_handle_get_handle (MonoWaitHandle *handle)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoClassField *f_os_handle;
static MonoClassField *f_safe_handle;
static MonoObject*
mono_runtime_capture_context (MonoDomain *domain)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
RuntimeInvokeFunction runtime_invoke;
if (!domain->capture_context_runtime_invoke || !domain->capture_context_method) {
*
*/
MonoAsyncResult *
-mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data)
+mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data, MonoObject *object_data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoAsyncResult *res = (MonoAsyncResult *)mono_object_new (domain, mono_defaults.asyncresult_class);
MonoObject *context = mono_runtime_capture_context (domain);
/* we must capture the execution context from the original thread */
}
res->data = data;
+ MONO_OBJECT_SETREF (res, object_data, object_data);
MONO_OBJECT_SETREF (res, async_state, state);
if (handle != NULL)
MONO_OBJECT_SETREF (res, handle, (MonoObject *) mono_wait_handle_new (domain, handle));
return res;
}
+MonoObject *
+ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *ares)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ MonoAsyncCall *ac;
+ MonoObject *res;
+
+ g_assert (ares);
+ g_assert (ares->async_delegate);
+
+ ac = (MonoAsyncCall*) ares->object_data;
+ if (!ac) {
+ res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, NULL);
+ } else {
+ gpointer wait_event = NULL;
+
+ ac->msg->exc = NULL;
+ res = mono_message_invoke (ares->async_delegate, ac->msg, &ac->msg->exc, &ac->out_args);
+ MONO_OBJECT_SETREF (ac, res, res);
+
+ mono_monitor_enter ((MonoObject*) ares);
+ ares->completed = 1;
+ if (ares->handle)
+ wait_event = mono_wait_handle_get_handle ((MonoWaitHandle*) ares->handle);
+ mono_monitor_exit ((MonoObject*) ares);
+
+ if (wait_event != NULL)
+ SetEvent (wait_event);
+
+ if (ac->cb_method) {
+ /* we swallow the excepton as it is the behavior on .NET */
+ MonoObject *exc = NULL;
+ mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, &exc);
+ if (exc)
+ mono_unhandled_exception (exc);
+ }
+ }
+
+ return res;
+}
+
void
mono_message_init (MonoDomain *domain,
MonoMethodMessage *this_obj,
MonoReflectionMethod *method,
MonoArray *out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoClass *object_array_klass;
static MonoClass *byte_array_klass;
static MonoClass *string_array_klass;
mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg,
MonoObject **exc, MonoArray **out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethod *im = real_proxy->vtable->domain->private_invoke_method;
gpointer pa [4];
if (!im) {
im = mono_class_get_method_from_name (mono_defaults.real_proxy_class, "PrivateInvoke", 4);
- g_assert (im);
+ if (!im)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
real_proxy->vtable->domain->private_invoke_method = im;
}
#endif
MonoObject *
-ves_icall_System_Runtime_Remoting_Messaging_MonoMethodMessage_Invoke (MonoMethodMessage *this,
- MonoObject *target, MonoArray **out_args)
+mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
+ MonoObject **exc, MonoArray **out_args)
{
- static MonoClass *object_array_klass = NULL;
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ static MonoClass *object_array_klass;
+ MonoDomain *domain;
MonoMethod *method;
MonoMethodSignature *sig;
MonoObject *ret;
- int i, j, out_args_count = 0;
+ int i, j, outarg_count = 0;
#ifndef DISABLE_REMOTING
if (target && mono_object_is_transparent_proxy (target)) {
if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
target = tp->rp->unwrapped_server;
} else {
- MonoObject *exc = NULL;
- MonoObject *ret = mono_remoting_invoke ((MonoObject *)tp->rp, this, &exc, out_args);
- if (exc)
- mono_raise_exception (exc);
- return ret;
+ return mono_remoting_invoke ((MonoObject *)tp->rp, msg, exc, out_args);
}
}
#endif
- g_assert (out_args);
-
- if (!object_array_klass)
- object_array_klass = mono_array_class_get (mono_defaults.object_class, 1);
- g_assert (object_array_klass);
+ domain = mono_domain_get ();
+ method = msg->method->method;
+ sig = mono_method_signature (method);
- method = this->method->method;
+ for (i = 0; i < sig->param_count; i++) {
+ if (sig->params [i]->byref)
+ outarg_count++;
+ }
- if (method->klass->valuetype)
- ret = mono_runtime_invoke_array (method, mono_object_unbox (target), this->args, NULL);
- else
- ret = mono_runtime_invoke_array (method, target, this->args, NULL);
+ if (!object_array_klass) {
+ MonoClass *klass;
- sig = mono_method_signature (method);
+ klass = mono_array_class_get (mono_defaults.object_class, 1);
+ g_assert (klass);
- for (i = 0; i < sig->param_count; i++) {
- if (sig->params [i]->byref)
- out_args_count++;
+ mono_memory_barrier ();
+ object_array_klass = klass;
}
- mono_gc_wbarrier_generic_store (out_args, (MonoObject*) mono_array_new_specific (mono_class_vtable (mono_domain_get (), object_array_klass), out_args_count));
+ mono_gc_wbarrier_generic_store (out_args, (MonoObject*) mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count));
+ *exc = NULL;
+
+ ret = mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc);
for (i = 0, j = 0; i < sig->param_count; i++) {
- if (sig->params [i]->byref)
- mono_array_setref (*out_args, j++, mono_array_get (this->args, gpointer, i));
+ if (sig->params [i]->byref) {
+ MonoObject* arg;
+ arg = mono_array_get (msg->args, gpointer, i);
+ mono_array_setref (*out_args, j, arg);
+ j++;
+ }
}
return ret;
MonoString *
mono_object_to_string (MonoObject *obj, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *to_string = NULL;
MonoMethod *method;
void *target = obj;
void
mono_print_unhandled_exception (MonoObject *exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString * str;
char *message = (char*)"";
gboolean free_message = FALSE;
void
mono_delegate_ctor_with_method (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoMethod *method)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDelegate *delegate = (MonoDelegate *)this_obj;
g_assert (this_obj);
void
mono_delegate_ctor (MonoObject *this_obj, MonoObject *target, gpointer addr)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
MonoJitInfo *ji;
MonoMethod *method = NULL;
mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *invoke,
MonoDelegate **cb, MonoObject **state)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
MonoMethodSignature *sig = mono_method_signature (method);
MonoMethodMessage *msg;
void
mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethodSignature *sig = mono_method_signature (method);
int i, j, type, size, out_len;
gpointer
mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer *res)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *getter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
if (!getter) {
getter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldGetter", -1);
- g_assert (getter);
+ if (!getter)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
field_class = mono_class_from_mono_type (field->type);
MonoObject *
mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *getter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
if (!getter) {
getter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldGetter", -1);
- g_assert (getter);
+ if (!getter)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
void
mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer val)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *setter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
if (!setter) {
setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
- g_assert (setter);
+ if (!setter)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
if (field_class->valuetype)
void
mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *setter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
if (!setter) {
setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1);
- g_assert (setter);
+ if (!setter)
+ mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
msg = (MonoMethodMessage *)mono_object_new (domain, mono_defaults.mono_method_message_class);
gunichar2 *
mono_string_chars (MonoString *s)
{
+ // MONO_REQ_GC_UNSAFE_MODE; //FIXME too much trouble for now
+
return s->chars;
}
int
mono_string_length (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return s->length;
}
uintptr_t
mono_array_length (MonoArray *array)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return array->max_length;
}
char*
mono_array_addr_with_size (MonoArray *array, int size, uintptr_t idx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return ((char*)(array)->vector) + size * idx;
}