#include <mono/metadata/assembly.h>
#include <mono/metadata/marshal.h>
#include "mono/metadata/debug-helpers.h"
-#include "mono/metadata/marshal.h"
#include <mono/metadata/threads.h>
#include <mono/metadata/threads-types.h>
#include <mono/metadata/environment.h>
#include "mono/metadata/profiler-private.h"
#include "mono/metadata/security-manager.h"
#include "mono/metadata/mono-debug-debugger.h"
-#include <mono/metadata/gc-internals.h>
#include <mono/metadata/verify-internals.h>
#include <mono/metadata/reflection-internals.h>
#include <mono/metadata/w32event.h>
#include <mono/utils/mono-threads.h>
#include <mono/utils/mono-threads-coop.h>
#include "cominterop.h"
+#include <mono/utils/w32api.h>
static void
get_default_field_value (MonoDomain* domain, MonoClassField *field, void *value, MonoError *error);
static char *
mono_string_to_utf8_internal (MonoMemPool *mp, MonoImage *image, MonoString *s, gboolean ignore_error, MonoError *error);
+static void
+array_full_copy_unchecked_size (MonoArray *src, MonoArray *dest, MonoClass *klass, uintptr_t size);
+
+static MonoMethod*
+class_get_virtual_method (MonoClass *klass, MonoMethod *method, gboolean is_proxy, MonoError *error);
+
/* Class lazy loading functions */
-static GENERATE_GET_CLASS_WITH_CACHE (pointer, System.Reflection, Pointer)
-static GENERATE_GET_CLASS_WITH_CACHE (remoting_services, System.Runtime.Remoting, RemotingServices)
-static GENERATE_GET_CLASS_WITH_CACHE (unhandled_exception_event_args, System, UnhandledExceptionEventArgs)
-static GENERATE_GET_CLASS_WITH_CACHE (sta_thread_attribute, System, STAThreadAttribute)
-static GENERATE_GET_CLASS_WITH_CACHE (activation_services, System.Runtime.Remoting.Activation, ActivationServices)
+static GENERATE_GET_CLASS_WITH_CACHE (pointer, "System.Reflection", "Pointer")
+static GENERATE_GET_CLASS_WITH_CACHE (remoting_services, "System.Runtime.Remoting", "RemotingServices")
+static GENERATE_GET_CLASS_WITH_CACHE (unhandled_exception_event_args, "System", "UnhandledExceptionEventArgs")
+static GENERATE_GET_CLASS_WITH_CACHE (sta_thread_attribute, "System", "STAThreadAttribute")
+static GENERATE_GET_CLASS_WITH_CACHE (activation_services, "System.Runtime.Remoting.Activation", "ActivationServices")
#define ldstr_lock() mono_os_mutex_lock (&ldstr_section)
MonoMethod *method = NULL;
MonoClass *klass = this_obj->vtable->klass;
- mono_error_init (error);
+ error_init (error);
method = mono_class_get_method_from_name (klass, ".ctor", 0);
if (!method)
g_error ("Could not lookup zero argument constructor for class %s", mono_type_get_full_name (klass));
MonoNativeThreadId initializing_tid;
guint32 waiting_count;
gboolean done;
- MonoCoopMutex initialization_section;
+ MonoCoopMutex mutex;
+ /* condvar used to wait for 'done' becoming TRUE */
+ MonoCoopCond cond;
} TypeInitializationLock;
/* for locking access to type_initialization_hash and blocked_thread_hash */
{
MONO_REQ_GC_NEUTRAL_MODE;
- mono_coop_mutex_lock (&lock->initialization_section);
+ mono_coop_mutex_lock (&lock->mutex);
}
static void
mono_type_init_unlock (TypeInitializationLock *lock)
{
- mono_coop_mutex_unlock (&lock->initialization_section);
+ mono_coop_mutex_unlock (&lock->mutex);
}
/* from vtable to lock */
mono_error_assert_ok (&error);
}
+/*
+ * Returns TRUE if the lock was freed.
+ * LOCKING: Caller should hold type_initialization_lock.
+ */
+static gboolean
+unref_type_lock (TypeInitializationLock *lock)
+{
+ --lock->waiting_count;
+ if (lock->waiting_count == 0) {
+ mono_coop_mutex_destroy (&lock->mutex);
+ mono_coop_cond_destroy (&lock->cond);
+ g_free (lock);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
/**
* mono_runtime_class_init_full:
* @vtable that neeeds to be initialized
MonoDomain *last_domain = NULL;
MonoException * pending_tae = NULL;
- mono_error_init (error);
+ error_init (error);
if (vtable->initialized)
return TRUE;
tid = mono_native_thread_id_get ();
+ /*
+ * Due some preprocessing inside a global lock. If we are the first thread
+ * trying to initialize this class, create a separate lock+cond var, and
+ * acquire it before leaving the global lock. The other threads will wait
+ * on this cond var.
+ */
+
mono_type_initialization_lock ();
/* double check... */
if (vtable->initialized) {
return FALSE;
}
}
- lock = (TypeInitializationLock *)g_malloc (sizeof (TypeInitializationLock));
- mono_coop_mutex_init_recursive (&lock->initialization_section);
+ lock = (TypeInitializationLock *)g_malloc0 (sizeof (TypeInitializationLock));
+ mono_coop_mutex_init_recursive (&lock->mutex);
+ mono_coop_cond_init (&lock->cond);
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 (mono_native_thread_id_equals (lock->initializing_tid, tid) || lock->done) {
+ if (mono_native_thread_id_equals (lock->initializing_tid, tid)) {
mono_type_initialization_unlock ();
return TRUE;
}
if (do_initialization) {
MonoException *exc = NULL;
+ /* We are holding the per-vtable lock, do the actual initialization */
+
mono_threads_begin_abort_protected_block ();
mono_runtime_try_invoke (method, NULL, NULL, (MonoObject**) &exc, error);
- mono_threads_end_abort_protected_block ();
+ gboolean got_pending_interrupt = mono_threads_end_abort_protected_block ();
//exception extracted, error will be set to the right value later
if (exc == NULL && !mono_error_ok (error))//invoking failed but exc was not set
else
mono_error_cleanup (error);
- mono_error_init (error);
+ error_init (error);
/* If the initialization failed, mark the class as unusable. */
/* Avoid infinite loops */
if (last_domain)
mono_domain_set (last_domain, TRUE);
+
+ /* Signal to the other threads that we are done */
+ mono_type_init_lock (lock);
lock->done = TRUE;
+ mono_coop_cond_broadcast (&lock->cond);
mono_type_init_unlock (lock);
+
+ //This can happen if the cctor self-aborts
if (exc && mono_object_class (exc) == mono_defaults.threadabortexception_class)
pending_tae = exc;
+
//TAEs are blocked around .cctors, they must escape as soon as no cctor is left to run.
- if (!pending_tae && mono_get_eh_callbacks ()->mono_above_abort_threshold ())
+ if (!pending_tae && got_pending_interrupt)
pending_tae = mono_thread_try_resume_interruption ();
} else {
/* this just blocks until the initializing thread is done */
mono_type_init_lock (lock);
+ while (!lock->done)
+ mono_coop_cond_wait (&lock->cond, &lock->mutex);
mono_type_init_unlock (lock);
}
+ /* Do cleanup and setting vtable->initialized inside the global lock again */
mono_type_initialization_lock ();
- if (!mono_native_thread_id_equals (lock->initializing_tid, tid))
+ if (!do_initialization)
g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
- --lock->waiting_count;
- if (lock->waiting_count == 0) {
- mono_coop_mutex_destroy (&lock->initialization_section);
+ gboolean deleted = unref_type_lock (lock);
+ if (deleted)
g_hash_table_remove (type_initialization_hash, vtable);
- g_free (lock);
- }
- mono_memory_barrier ();
- if (!vtable->init_failed)
+ /* Have to set this here since we check it inside the global lock */
+ if (do_initialization && !vtable->init_failed)
vtable->initialized = 1;
mono_type_initialization_unlock ();
* mono_runtime_class_init (). In this case, the exception object is not stored,
* and get_type_init_exception_for_class () needs to be aware of this.
*/
+ mono_type_init_lock (lock);
vtable->init_failed = 1;
+ mono_coop_cond_broadcast (&lock->cond);
mono_type_init_unlock (lock);
- --lock->waiting_count;
- if (lock->waiting_count == 0) {
- mono_coop_mutex_destroy (&lock->initialization_section);
- g_free (lock);
+ gboolean deleted = unref_type_lock (lock);
+ if (deleted)
return TRUE;
- }
}
return FALSE;
}
MONO_REQ_GC_NEUTRAL_MODE
- mono_error_init (error);
+ error_init (error);
g_assert (callbacks.compile_method);
res = callbacks.compile_method (method, error);
MONO_REQ_GC_NEUTRAL_MODE;
- mono_error_init (error);
+ error_init (error);
res = callbacks.create_jump_trampoline (domain, method, add_sync_wrapper, error);
return res;
}
type = mono_type_get_underlying_type (field->type);
switch (type->type) {
+ case MONO_TYPE_U:
case MONO_TYPE_I:
case MONO_TYPE_PTR:
case MONO_TYPE_FNPTR:
break;
- /* only UIntPtr is allowed to be GC-tracked and only in mscorlib */
- case MONO_TYPE_U:
-#ifdef HAVE_SGEN_GC
- break;
-#else
- if (klass->image != mono_defaults.corlib)
- break;
-#endif
case MONO_TYPE_STRING:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_CLASS:
return str;
}
+/* LOCKING: Acquires the loader lock */
void
mono_class_compute_gc_descriptor (MonoClass *klass)
{
gsize *bitmap;
gsize default_bitmap [4] = {0};
static gboolean gcj_inited = FALSE;
+ MonoGCDescriptor gc_descr;
if (!gcj_inited) {
mono_loader_lock ();
if (klass->gc_descr_inited)
return;
- klass->gc_descr_inited = TRUE;
- klass->gc_descr = MONO_GC_DESCRIPTOR_NULL;
-
bitmap = default_bitmap;
if (klass == mono_defaults.string_class) {
- klass->gc_descr = mono_gc_make_descr_for_string (bitmap, 2);
+ gc_descr = mono_gc_make_descr_for_string (bitmap, 2);
} else if (klass->rank) {
mono_class_compute_gc_descriptor (klass->element_class);
if (MONO_TYPE_IS_REFERENCE (&klass->element_class->byval_arg)) {
gsize abm = 1;
- klass->gc_descr = mono_gc_make_descr_for_array (klass->byval_arg.type == MONO_TYPE_SZARRAY, &abm, 1, sizeof (gpointer));
+ gc_descr = mono_gc_make_descr_for_array (klass->byval_arg.type == MONO_TYPE_SZARRAY, &abm, 1, sizeof (gpointer));
/*printf ("new array descriptor: 0x%x for %s.%s\n", class->gc_descr,
class->name_space, class->name);*/
} else {
/* remove the object header */
bitmap = compute_class_bitmap (klass->element_class, default_bitmap, sizeof (default_bitmap) * 8, - (int)(sizeof (MonoObject) / sizeof (gpointer)), &max_set, FALSE);
- klass->gc_descr = mono_gc_make_descr_for_array (klass->byval_arg.type == MONO_TYPE_SZARRAY, bitmap, mono_array_element_size (klass) / sizeof (gpointer), mono_array_element_size (klass));
+ gc_descr = mono_gc_make_descr_for_array (klass->byval_arg.type == MONO_TYPE_SZARRAY, bitmap, mono_array_element_size (klass) / sizeof (gpointer), mono_array_element_size (klass));
/*printf ("new vt array descriptor: 0x%x for %s.%s\n", class->gc_descr,
class->name_space, class->name);*/
if (bitmap != default_bitmap)
if (count++ > 58)
return;*/
bitmap = compute_class_bitmap (klass, default_bitmap, sizeof (default_bitmap) * 8, 0, &max_set, FALSE);
- klass->gc_descr = mono_gc_make_descr_for_object (bitmap, max_set + 1, klass->instance_size);
+ gc_descr = mono_gc_make_descr_for_object (bitmap, max_set + 1, klass->instance_size);
/*
if (class->gc_descr == MONO_GC_DESCRIPTOR_NULL)
g_print ("disabling typed alloc (%d) for %s.%s\n", max_set, class->name_space, class->name);
if (bitmap != default_bitmap)
g_free (bitmap);
}
+
+ /* Publish the data */
+ mono_loader_lock ();
+ klass->gc_descr = gc_descr;
+ mono_memory_barrier ();
+ klass->gc_descr_inited = TRUE;
+ mono_loader_unlock ();
}
/**
MonoClassRuntimeInfo *runtime_info;
- mono_error_init (error);
+ error_init (error);
g_assert (klass);
gpointer iter;
gpointer *interface_offsets;
- mono_error_init (error);
+ error_init (error);
mono_loader_lock (); /*FIXME mono_class_init acquires it*/
mono_domain_lock (domain);
int bcsize;
#endif
- mono_error_init (error);
+ error_init (error);
vt = mono_class_vtable (domain, klass);
g_assert (vt); /*FIXME property handle failure*/
* On failure returns NULL and sets @error
*/
MonoRemoteClass*
-mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class, MonoError *error)
+mono_remote_class (MonoDomain *domain, MonoStringHandle class_name, MonoClass *proxy_class, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
gpointer* key, *mp_key;
char *name;
- mono_error_init (error);
+ error_init (error);
key = create_remote_class_key (NULL, proxy_class);
return rc;
}
- name = mono_string_to_utf8_mp (domain->mp, class_name, error);
+ name = mono_string_to_utf8_mp (domain->mp, MONO_HANDLE_RAW (class_name), error);
if (!is_ok (error)) {
g_free (key);
mono_domain_unlock (domain);
rc->xdomain_vtable = NULL;
rc->proxy_class_name = name;
#ifndef DISABLE_PERFCOUNTERS
- mono_perfcounters->loader_bytes += mono_string_length (class_name) + 1;
+ mono_perfcounters->loader_bytes += mono_string_length (MONO_HANDLE_RAW (class_name)) + 1;
#endif
g_hash_table_insert (domain->proxy_vtable_hash, key, rc);
}
gpointer
-mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRealProxy *rp, MonoError *error)
+mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRealProxyHandle rp, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
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) {
+ gint32 target_domain_id = MONO_HANDLE_GETVAL (rp, target_domain_id);
+ if (target_domain_id != -1) {
if (remote_class->xdomain_vtable == NULL)
remote_class->xdomain_vtable = mono_class_proxy_vtable (domain, remote_class, MONO_REMOTING_TARGET_APPDOMAIN, error);
mono_domain_unlock (domain);
return remote_class->xdomain_vtable;
}
if (remote_class->default_vtable == NULL) {
- MonoType *type;
- MonoClass *klass;
- type = ((MonoReflectionType *)rp->class_to_proxy)->type;
- klass = mono_class_from_mono_type (type);
+ MonoReflectionTypeHandle reftype = MONO_HANDLE_NEW (MonoReflectionType, NULL);
+ MONO_HANDLE_GET (reftype, rp, class_to_proxy);
+
+ MonoType *type = MONO_HANDLE_GETVAL (reftype, type);
+ MonoClass *klass = mono_class_from_mono_type (type);
#ifndef DISABLE_COM
if ((mono_class_is_com_object (klass) || (mono_class_get_com_object_class () && klass == mono_class_get_com_object_class ())) && !mono_vtable_is_remote (mono_class_vtable (mono_domain_get (), klass)))
remote_class->default_vtable = mono_class_proxy_vtable (domain, remote_class, MONO_REMOTING_TARGET_COMINTEROP, error);
* class or an interface. On success returns TRUE, on failure returns FALSE and sets @error.
*/
gboolean
-mono_upgrade_remote_class (MonoDomain *domain, MonoObject *proxy_object, MonoClass *klass, MonoError *error)
+mono_upgrade_remote_class (MonoDomain *domain, MonoObjectHandle proxy_object, MonoClass *klass, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoTransparentProxy *tproxy;
- MonoRemoteClass *remote_class;
- gboolean redo_vtable;
-
- mono_error_init (error);
- mono_loader_lock (); /*FIXME mono_remote_class_vtable requires it.*/
- mono_domain_lock (domain);
+ error_init (error);
- tproxy = (MonoTransparentProxy*) proxy_object;
- remote_class = tproxy->remote_class;
+ MonoTransparentProxyHandle tproxy = MONO_HANDLE_CAST (MonoTransparentProxy, proxy_object);
+ MonoRemoteClass *remote_class = MONO_HANDLE_GETVAL (tproxy, remote_class);
+ gboolean redo_vtable;
if (mono_class_is_interface (klass)) {
int i;
redo_vtable = TRUE;
redo_vtable = (remote_class->proxy_class != klass);
}
+ mono_loader_lock (); /*FIXME mono_remote_class_vtable requires it.*/
+ mono_domain_lock (domain);
if (redo_vtable) {
- tproxy->remote_class = clone_remote_class (domain, remote_class, klass);
- proxy_object->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tproxy->remote_class, tproxy->rp, error);
+ MonoRemoteClass *fresh_remote_class = clone_remote_class (domain, remote_class, klass);
+ MONO_HANDLE_SETVAL (tproxy, remote_class, MonoRemoteClass*, fresh_remote_class);
+ MonoRealProxyHandle real_proxy = MONO_HANDLE_NEW (MonoRealProxy, NULL);
+ MONO_HANDLE_GET (real_proxy, tproxy, rp);
+ MONO_HANDLE_SETVAL (proxy_object, vtable, MonoVTable*, mono_remote_class_vtable (domain, fresh_remote_class, real_proxy, error));
if (!is_ok (error))
goto leave;
}
* the instance of a callvirt of method.
*/
MonoMethod*
-mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method)
+mono_object_get_virtual_method (MonoObject *obj_raw, MonoMethod *method)
{
MONO_REQ_GC_UNSAFE_MODE;
+ HANDLE_FUNCTION_ENTER ();
+ MonoError error;
+ MONO_HANDLE_DCL (MonoObject, obj);
+ MonoMethod *result = mono_object_handle_get_virtual_method (obj, method, &error);
+ mono_error_assert_ok (&error);
+ HANDLE_FUNCTION_RETURN_VAL (result);
+}
- MonoClass *klass;
- MonoMethod **vtable;
- gboolean is_proxy = FALSE;
- MonoMethod *res = NULL;
+/**
+ * mono_object_get_virtual_method:
+ * @obj: object to operate on.
+ * @method: method
+ *
+ * Retrieves the MonoMethod that would be called on obj if obj is passed as
+ * the instance of a callvirt of method.
+ */
+MonoMethod*
+mono_object_handle_get_virtual_method (MonoObjectHandle obj, MonoMethod *method, MonoError *error)
+{
+ error_init (error);
- klass = mono_object_class (obj);
-#ifndef DISABLE_REMOTING
- if (klass == mono_defaults.transparent_proxy_class) {
- klass = ((MonoTransparentProxy *)obj)->remote_class->proxy_class;
+ gboolean is_proxy = FALSE;
+ MonoClass *klass = mono_handle_class (obj);
+ if (mono_class_is_transparent_proxy (klass)) {
+ MonoRemoteClass *remote_class = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoTransparentProxy, obj), remote_class);
+ klass = remote_class->proxy_class;
is_proxy = TRUE;
}
-#endif
+ return class_get_virtual_method (klass, method, is_proxy, error);
+}
+
+static MonoMethod*
+class_get_virtual_method (MonoClass *klass, MonoMethod *method, gboolean is_proxy, MonoError *error)
+{
+ error_init (error);
+
if (!is_proxy && ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)))
return method;
mono_class_setup_vtable (klass);
- vtable = klass->vtable;
+ MonoMethod **vtable = klass->vtable;
if (method->slot == -1) {
/* method->slot might not be set for instances of generic methods */
}
}
+ MonoMethod *res = NULL;
/* check method->slot is a valid index: perform isinstance? */
if (method->slot != -1) {
if (mono_class_is_interface (method->klass)) {
#endif
{
if (method->is_inflated) {
- MonoError error;
/* Have to inflate the result */
- res = mono_class_inflate_generic_method_checked (res, &((MonoMethodInflated*)method)->context, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ res = mono_class_inflate_generic_method_checked (res, &((MonoMethodInflated*)method)->context, error);
}
}
- g_assert (res);
-
return res;
}
g_assert (callbacks.runtime_invoke);
- mono_error_init (error);
+ error_init (error);
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_start_invoke (method);
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoObject *o;
MonoClass *klass;
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
int retval = 0;
const char *p = blob;
mono_metadata_decode_blob_size (p, &p);
MonoTypeEnum def_type;
const char* data;
- mono_error_init (error);
+ error_init (error);
data = mono_class_get_field_default_value (field, &def_type);
mono_get_constant_value_from_blob (domain, def_type, data, value, error);
void *src;
- mono_error_init (error);
+ error_init (error);
g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
MonoObject *exc;
- mono_error_init (error);
+ error_init (error);
do_runtime_invoke (prop->set, obj, params, &exc, error);
if (exc != NULL && is_ok (error))
mono_error_set_exception_instance (error, (MonoException*)exc);
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields (klass);
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoMethod *im;
MonoClass *klass = delegate->vtable->klass;
MonoObject *o;
MonoObject*
mono_runtime_delegate_invoke_checked (MonoObject *delegate, void **params, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
return mono_runtime_delegate_try_invoke (delegate, params, NULL, error);
}
int i;
MonoDomain *domain = mono_domain_get ();
- mono_error_init (error);
+ error_init (error);
res = (MonoArray*)mono_array_new_checked (domain, mono_defaults.string_class, num_main_args, error);
return_val_if_nok (error, NULL);
mono_runtime_run_main_checked (MonoMethod *method, int argc, char* argv[],
MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
MonoArray *args = prepare_run_main (method, argc, argv);
return mono_runtime_exec_main_checked (method, args, error);
}
MonoReflectionType *reflection_type;
MonoTransparentProxy *transparent_proxy;
- mono_error_init (error);
+ error_init (error);
if (!get_proxy_method)
get_proxy_method = mono_class_get_method_from_name (mono_defaults.real_proxy_class, "GetTransparentProxy", 0);
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoObject *deserialized = NULL;
#ifndef DISABLE_REMOTING
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoClass *klass;
gpointer args [2];
MonoMethod *method = NULL;
gpointer pa [1];
int rval;
- mono_error_init (error);
+ error_init (error);
g_assert (args);
pa [0] = args;
int
mono_runtime_exec_main_checked (MonoMethod *method, MonoArray *args, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
prepare_thread_to_exec_main (mono_object_domain (args), method);
return do_exec_main_checked (method, args, error);
}
{
MonoType *t_orig = t;
gpointer result = NULL;
- mono_error_init (error);
+ error_init (error);
again:
switch (t->type) {
case MONO_TYPE_U1:
mono_runtime_invoke_array_checked (MonoMethod *method, void *obj, MonoArray *params,
MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
return mono_runtime_try_invoke_array (method, obj, params, NULL, error);
}
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoMethodSignature *sig = mono_method_signature (method);
gpointer *pa = NULL;
mono_error_assert_ok (error);
g_assert (obj); /*maybe we should raise a TLE instead?*/
#ifndef DISABLE_REMOTING
- if (mono_object_class(obj) == mono_defaults.transparent_proxy_class) {
+ if (mono_object_is_transparent_proxy (obj)) {
method = mono_marshal_get_remoting_invoke (method->slot == -1 ? method : method->klass->vtable [method->slot]);
}
#endif
MonoVTable *vtable;
- mono_error_init (error);
+ error_init (error);
vtable = mono_class_vtable (domain, klass);
g_assert (vtable); /* FIXME don't swallow the error */
MonoObject *o;
- mono_error_init (error);
+ error_init (error);
/* check for is_com_object for COM Interop */
if (mono_vtable_is_remote (vtable) || mono_class_is_com_object (vtable->klass))
MonoObject *o;
- mono_error_init (error);
+ error_init (error);
o = (MonoObject *)mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
MonoObject *o;
- mono_error_init (error);
+ error_init (error);
o = mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
MonoObject *o;
- mono_error_init (error);
+ error_init (error);
o = mono_gc_alloc_mature (vtable, vtable->klass->instance_size);
MonoObject *o;
int size;
- mono_error_init (error);
+ error_init (error);
size = obj->vtable->klass->instance_size;
size = mono_array_length (src);
g_assert (size == mono_array_length (dest));
size *= mono_array_element_size (klass);
+
+ array_full_copy_unchecked_size (src, dest, klass, size);
+}
+
+static void
+array_full_copy_unchecked_size (MonoArray *src, MonoArray *dest, MonoClass *klass, uintptr_t size)
+{
#ifdef HAVE_SGEN_GC
if (klass->element_class->valuetype) {
if (klass->element_class->has_references)
* This routine returns a copy of the array that is hosted on the
* specified MonoDomain. On failure returns NULL and sets @error.
*/
-MonoArray*
-mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array, MonoError *error)
+MonoArrayHandle
+mono_array_clone_in_domain (MonoDomain *domain, MonoArrayHandle array_handle, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoArray *o;
- uintptr_t size, i;
- uintptr_t *sizes;
- MonoClass *klass = array->obj.vtable->klass;
+ MonoArrayHandle result = MONO_HANDLE_NEW (MonoArray, NULL);
+ uintptr_t size = 0;
+ MonoClass *klass = mono_handle_class (array_handle);
- mono_error_init (error);
+ error_init (error);
- if (array->bounds == NULL) {
- size = mono_array_length (array);
- o = mono_array_new_full_checked (domain, klass, &size, NULL, error);
- return_val_if_nok (error, NULL);
-
- size *= mono_array_element_size (klass);
-#ifdef HAVE_SGEN_GC
- if (klass->element_class->valuetype) {
- if (klass->element_class->has_references)
- mono_value_copy_array (o, 0, mono_array_addr_with_size_fast (array, 0, 0), mono_array_length (array));
- else
- mono_gc_memmove_atomic (&o->vector, &array->vector, size);
- } else {
- mono_array_memcpy_refs (o, 0, array, 0, mono_array_length (array));
- }
-#else
- mono_gc_memmove_atomic (&o->vector, &array->vector, size);
-#endif
- return o;
- }
+ /* Pin source array here - if bounds is non-NULL, it's a pointer into the object data */
+ uint32_t src_handle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, array_handle), TRUE);
- sizes = (uintptr_t *)alloca (klass->rank * sizeof(intptr_t) * 2);
- size = mono_array_element_size (klass);
- for (i = 0; i < klass->rank; ++i) {
- sizes [i] = array->bounds [i].length;
- size *= array->bounds [i].length;
- sizes [i + klass->rank] = array->bounds [i].lower_bound;
- }
- o = mono_array_new_full_checked (domain, klass, sizes, (intptr_t*)sizes + klass->rank, error);
- return_val_if_nok (error, NULL);
-#ifdef HAVE_SGEN_GC
- if (klass->element_class->valuetype) {
- if (klass->element_class->has_references)
- mono_value_copy_array (o, 0, mono_array_addr_with_size_fast (array, 0, 0), mono_array_length (array));
- else
- mono_gc_memmove_atomic (&o->vector, &array->vector, size);
+ MonoArrayBounds *array_bounds = MONO_HANDLE_GETVAL (array_handle, bounds);
+ MonoArrayHandle o;
+ if (array_bounds == NULL) {
+ size = mono_array_handle_length (array_handle);
+ o = mono_array_new_full_handle (domain, klass, &size, NULL, error);
+ if (!is_ok (error))
+ goto leave;
+ size *= mono_array_element_size (klass);
} else {
- mono_array_memcpy_refs (o, 0, array, 0, mono_array_length (array));
+ uintptr_t *sizes = (uintptr_t *)alloca (klass->rank * sizeof (uintptr_t));
+ intptr_t *lower_bounds = (intptr_t *)alloca (klass->rank * sizeof (intptr_t));
+ size = mono_array_element_size (klass);
+ for (int i = 0; i < klass->rank; ++i) {
+ sizes [i] = array_bounds [i].length;
+ size *= array_bounds [i].length;
+ lower_bounds [i] = array_bounds [i].lower_bound;
+ }
+ o = mono_array_new_full_handle (domain, klass, sizes, lower_bounds, error);
+ if (!is_ok (error))
+ goto leave;
}
-#else
- mono_gc_memmove_atomic (&o->vector, &array->vector, size);
-#endif
- return o;
+ uint32_t dst_handle = mono_gchandle_from_handle (MONO_HANDLE_CAST (MonoObject, o), TRUE);
+ array_full_copy_unchecked_size (MONO_HANDLE_RAW (array_handle), MONO_HANDLE_RAW (o), klass, size);
+ mono_gchandle_free (dst_handle);
+
+ MONO_HANDLE_ASSIGN (result, o);
+
+leave:
+ mono_gchandle_free (src_handle);
+ return result;
}
/**
* failure returns NULL and sets @error.
*/
MonoArray*
-mono_array_clone_checked (MonoArray *array, MonoError *error)
+mono_array_clone_checked (MonoArray *array_raw, MonoError *error)
{
-
MONO_REQ_GC_UNSAFE_MODE;
- return mono_array_clone_in_domain (((MonoObject *)array)->vtable->domain, array, error);
+ HANDLE_FUNCTION_ENTER ();
+ /* FIXME: callers of mono_array_clone_checked should use handles */
+ error_init (error);
+ MONO_HANDLE_DCL (MonoArray, array);
+ MonoArrayHandle result = mono_array_clone_in_domain (MONO_HANDLE_DOMAIN (array), array, error);
+ HANDLE_FUNCTION_RETURN_OBJ (result);
}
/* helper macros to check for overflow when calculating the size of arrays */
MonoVTable *vtable;
int i;
- mono_error_init (error);
+ error_init (error);
if (!array_class->inited)
mono_class_init (array_class);
{
MonoClass *ac;
- mono_error_init (error);
+ error_init (error);
ac = mono_array_class_get (eclass, 1);
g_assert (ac);
MonoObject *o;
uintptr_t byte_len;
- mono_error_init (error);
+ error_init (error);
if (G_UNLIKELY (n > MONO_ARRAY_MAX_INDEX)) {
mono_error_set_generic_error (error, "System", "OverflowException", "");
* Returns: The same empty string instance as the managed string.Empty
*/
MonoString*
-mono_string_empty_wrapper ()
+mono_string_empty_wrapper (void)
{
MonoDomain *domain = mono_domain_get ();
return mono_string_empty (domain);
MonoString *s;
- mono_error_init (error);
+ error_init (error);
s = mono_string_new_size_checked (domain, len, error);
if (s != NULL)
return s;
}
+/**
+ * mono_string_new_utf16_handle:
+ * @text: a pointer to an utf16 string
+ * @len: the length of the string
+ * @error: written on error.
+ *
+ * Returns: A newly created string object which contains @text.
+ * On error, returns NULL and sets @error.
+ */
+MonoStringHandle
+mono_string_new_utf16_handle (MonoDomain *domain, const guint16 *text, gint32 len, MonoError *error)
+{
+ return MONO_HANDLE_NEW (MonoString, mono_string_new_utf16_checked (domain, text, len, error));
+}
+
/**
* mono_string_new_utf32:
* @text: a pointer to an utf32 string
GError *gerror = NULL;
glong items_written;
- mono_error_init (error);
+ error_init (error);
utf16_output = g_ucs4_to_utf16 (text, len, NULL, &items_written, &gerror);
if (gerror)
MonoVTable *vtable;
size_t size;
- mono_error_init (error);
+ error_init (error);
/* check for overflow */
if (len < 0 || len > ((SIZE_MAX - G_STRUCT_OFFSET (MonoString, chars) - 8) / 2)) {
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
GError *eg_error = NULL;
MonoString *o = NULL;
glong items_written;
int l;
- mono_error_init (error);
+ error_init (error);
l = strlen (text);
int size;
MonoVTable *vtable;
- mono_error_init (error);
+ error_init (error);
g_assert (klass->valuetype);
if (mono_class_is_nullable (klass))
* Returns: @obj if @obj is derived from @klass or NULL otherwise.
*/
MonoObject *
-mono_object_isinst (MonoObject *obj, MonoClass *klass)
+mono_object_isinst (MonoObject *obj_raw, MonoClass *klass)
{
MONO_REQ_GC_UNSAFE_MODE;
+ HANDLE_FUNCTION_ENTER ();
+ MONO_HANDLE_DCL (MonoObject, obj);
MonoError error;
- MonoObject *result = mono_object_isinst_checked (obj, klass, &error);
+ MonoObjectHandle result = mono_object_handle_isinst (obj, klass, &error);
mono_error_cleanup (&error);
- return result;
+ HANDLE_FUNCTION_RETURN_OBJ (result);
}
* On failure returns NULL and sets @error.
*/
MonoObject *
-mono_object_isinst_checked (MonoObject *obj, MonoClass *klass, MonoError *error)
+mono_object_isinst_checked (MonoObject *obj_raw, MonoClass *klass, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
-
- MonoObject *result = NULL;
+ HANDLE_FUNCTION_ENTER ();
+ error_init (error);
+ MONO_HANDLE_DCL (MonoObject, obj);
+ MonoObjectHandle result = mono_object_handle_isinst (obj, klass, error);
+ HANDLE_FUNCTION_RETURN_OBJ (result);
+}
+/**
+ * mono_object_handle_isinst:
+ * @obj: an object
+ * @klass: a pointer to a class
+ * @error: set on error
+ *
+ * Returns: @obj if @obj is derived from @klass or NULL if it isn't.
+ * On failure returns NULL and sets @error.
+ */
+MonoObjectHandle
+mono_object_handle_isinst (MonoObjectHandle obj, MonoClass *klass, MonoError *error)
+{
+ error_init (error);
+
if (!klass->inited)
mono_class_init (klass);
if (mono_class_is_marshalbyref (klass) || mono_class_is_interface (klass)) {
- result = mono_object_isinst_mbyref_checked (obj, klass, error);
- return result;
+ return mono_object_handle_isinst_mbyref (obj, klass, error);
}
- if (!obj)
- return NULL;
+ MonoObjectHandle result = MONO_HANDLE_NEW (MonoObject, NULL);
- return mono_class_is_assignable_from (klass, obj->vtable->klass) ? obj : NULL;
+ if (!MONO_HANDLE_IS_NULL (obj) && mono_class_is_assignable_from (klass, mono_handle_class (obj)))
+ MONO_HANDLE_ASSIGN (result, obj);
+ return result;
}
MonoObject *
-mono_object_isinst_mbyref (MonoObject *obj, MonoClass *klass)
+mono_object_isinst_mbyref (MonoObject *obj_raw, MonoClass *klass)
{
MONO_REQ_GC_UNSAFE_MODE;
+ HANDLE_FUNCTION_ENTER ();
MonoError error;
- MonoObject *result = mono_object_isinst_mbyref_checked (obj, klass, &error);
+ MONO_HANDLE_DCL (MonoObject, obj);
+ MonoObjectHandle result = mono_object_handle_isinst_mbyref (obj, klass, &error);
mono_error_cleanup (&error); /* FIXME better API that doesn't swallow the error */
- return result;
+ HANDLE_FUNCTION_RETURN_OBJ (result);
}
-MonoObject *
-mono_object_isinst_mbyref_checked (MonoObject *obj, MonoClass *klass, MonoError *error)
+MonoObjectHandle
+mono_object_handle_isinst_mbyref (MonoObjectHandle obj, MonoClass *klass, MonoError *error)
{
- MONO_REQ_GC_UNSAFE_MODE;
+ error_init (error);
- MonoVTable *vt;
+ MonoObjectHandle result = MONO_HANDLE_NEW (MonoObject, NULL);
- mono_error_init (error);
-
- if (!obj)
- return NULL;
+ if (MONO_HANDLE_IS_NULL (obj))
+ goto leave;
- vt = obj->vtable;
+ MonoVTable *vt = MONO_HANDLE_GETVAL (obj, vtable);
if (mono_class_is_interface (klass)) {
if (MONO_VTABLE_IMPLEMENTS_INTERFACE (vt, klass->interface_id)) {
- return obj;
+ MONO_HANDLE_ASSIGN (result, obj);
+ goto leave;
}
/* casting an array one of the invariant interfaces that must act as such */
if (klass->is_array_special_interface) {
- if (mono_class_is_assignable_from (klass, vt->klass))
- return obj;
+ if (mono_class_is_assignable_from (klass, vt->klass)) {
+ MONO_HANDLE_ASSIGN (result, obj);
+ goto leave;
+ }
}
/*If the above check fails we are in the slow path of possibly raising an exception. So it's ok to it this way.*/
- else if (mono_class_has_variant_generic_params (klass) && mono_class_is_assignable_from (klass, obj->vtable->klass))
- return obj;
+ else if (mono_class_has_variant_generic_params (klass) && mono_class_is_assignable_from (klass, mono_handle_class (obj))) {
+ MONO_HANDLE_ASSIGN (result, obj);
+ goto leave;
+ }
} else {
MonoClass *oklass = vt->klass;
- if (mono_class_is_transparent_proxy (oklass))
- oklass = ((MonoTransparentProxy *)obj)->remote_class->proxy_class;
+ if (mono_class_is_transparent_proxy (oklass)){
+ MonoRemoteClass *remote_class = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoTransparentProxy, obj), remote_class);
+ oklass = remote_class->proxy_class;
+ }
mono_class_setup_supertypes (klass);
- if ((oklass->idepth >= klass->idepth) && (oklass->supertypes [klass->idepth - 1] == klass))
- return obj;
+ if ((oklass->idepth >= klass->idepth) && (oklass->supertypes [klass->idepth - 1] == klass)) {
+ MONO_HANDLE_ASSIGN (result, obj);
+ goto leave;
+ }
}
#ifndef DISABLE_REMOTING
- if (vt->klass == mono_defaults.transparent_proxy_class && ((MonoTransparentProxy *)obj)->custom_type_info)
+ if (mono_class_is_transparent_proxy (vt->klass))
{
+ MonoBoolean custom_type_info = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoTransparentProxy, obj), custom_type_info);
+ if (!custom_type_info)
+ goto leave;
MonoDomain *domain = mono_domain_get ();
- MonoObject *res;
- MonoObject *rp = (MonoObject *)((MonoTransparentProxy *)obj)->rp;
+ MonoObjectHandle rp = MONO_HANDLE_NEW (MonoObject, NULL);
+ MONO_HANDLE_GET (rp, MONO_HANDLE_CAST (MonoTransparentProxy, obj), rp);
MonoClass *rpklass = mono_defaults.iremotingtypeinfo_class;
MonoMethod *im = NULL;
gpointer pa [2];
im = mono_class_get_method_from_name (rpklass, "CanCastTo", -1);
if (!im) {
mono_error_set_not_supported (error, "Linked away.");
- return NULL;
+ goto leave;
}
- im = mono_object_get_virtual_method (rp, im);
+ im = mono_object_handle_get_virtual_method (rp, im, error);
+ if (!is_ok (error))
+ goto leave;
g_assert (im);
- pa [0] = mono_type_get_object_checked (domain, &klass->byval_arg, error);
- return_val_if_nok (error, NULL);
- pa [1] = obj;
+ MonoReflectionTypeHandle reftype = mono_type_get_object_handle (domain, &klass->byval_arg, error);
+ if (!is_ok (error))
+ goto leave;
- res = mono_runtime_invoke_checked (im, rp, pa, error);
- return_val_if_nok (error, NULL);
+ pa [0] = MONO_HANDLE_RAW (reftype);
+ pa [1] = MONO_HANDLE_RAW (obj);
+ MonoObject *res = mono_runtime_invoke_checked (im, rp, pa, error);
+ if (!is_ok (error))
+ goto leave;
if (*(MonoBoolean *) mono_object_unbox(res)) {
/* Update the vtable of the remote type, so it can safely cast to this new type */
mono_upgrade_remote_class (domain, obj, klass, error);
- return_val_if_nok (error, NULL);
- return obj;
+ if (!is_ok (error))
+ goto leave;
+ MONO_HANDLE_ASSIGN (result, obj);
}
}
#endif /* DISABLE_REMOTING */
- return NULL;
+leave:
+ return result;
}
/**
* Returns: @obj if @obj is derived from @klass, returns NULL otherwise.
*/
MonoObject *
-mono_object_castclass_mbyref (MonoObject *obj, MonoClass *klass)
+mono_object_castclass_mbyref (MonoObject *obj_raw, MonoClass *klass)
{
MONO_REQ_GC_UNSAFE_MODE;
+ HANDLE_FUNCTION_ENTER ();
MonoError error;
-
- if (!obj) return NULL;
- if (mono_object_isinst_mbyref_checked (obj, klass, &error)) return obj;
+ MONO_HANDLE_DCL (MonoObject, obj);
+ MonoObjectHandle result = MONO_HANDLE_NEW (MonoObject, NULL);
+ if (MONO_HANDLE_IS_NULL (obj))
+ goto leave;
+ MONO_HANDLE_ASSIGN (result, mono_object_handle_isinst_mbyref (obj, klass, &error));
mono_error_cleanup (&error);
- return NULL;
+leave:
+ HANDLE_FUNCTION_RETURN_OBJ (result);
}
typedef struct {
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
/* We only need to make a pinned version of a string if this is a moving GC */
if (!mono_gc_is_moving ())
MonoString *s, *res;
MonoDomain *domain;
- mono_error_init (error);
+ error_init (error);
domain = ((MonoObject *)str)->vtable->domain;
ldstr_table = domain->ldstr_table;
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
return mono_string_is_interned_lookup (str, TRUE, error);
}
mono_ldstr_checked (MonoDomain *domain, MonoImage *image, guint32 idx, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
if (image->dynamic) {
MonoString *str = (MonoString *)mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL, error);
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
const char *str = sig;
MonoString *o, *interned;
size_t len2;
char *as;
GError *gerror = NULL;
- mono_error_init (error);
+ error_init (error);
if (!mono_verifier_verify_string_signature (image, idx, NULL))
return NULL; /*FIXME we should probably be raising an exception here*/
char *as;
GError *gerror = NULL;
- mono_error_init (error);
+ error_init (error);
if (s == NULL)
return NULL;
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoDomain *domain = mono_domain_get ();
int len = 0;
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoString* result = NULL;
mono_unichar2 *utf16_output = NULL;
GError *gerror = NULL;
* Same as mono_string_to_utf8, but allocate the string from the image mempool.
*/
char *
-mono_string_to_utf8_image (MonoImage *image, MonoString *s, MonoError *error)
+mono_string_to_utf8_image (MonoImage *image, MonoStringHandle s, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- return mono_string_to_utf8_internal (NULL, image, s, FALSE, error);
+ return mono_string_to_utf8_internal (NULL, image, MONO_HANDLE_RAW (s), FALSE, error); /* FIXME pin the string */
}
/**
gpointer params [1];
static MonoMethod *handle_set;
- mono_error_init (error);
+ error_init (error);
res = (MonoWaitHandle *)mono_object_new_checked (domain, mono_defaults.manualresetevent_class, error);
return_val_if_nok (error, NULL);
RuntimeInvokeFunction runtime_invoke;
- mono_error_init (error);
+ error_init (error);
if (!domain->capture_context_runtime_invoke || !domain->capture_context_method) {
MonoMethod *method = mono_get_context_capture_method ();
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoAsyncResult *res = (MonoAsyncResult *)mono_object_new_checked (domain, mono_defaults.asyncresult_class, error);
return_val_if_nok (error, NULL);
MonoObject *context = mono_runtime_capture_context (domain, error);
if (wait_event != NULL)
mono_w32event_set (wait_event);
- mono_error_init (&error); //the else branch would leave it in an undefined state
+ error_init (&error); //the else branch would leave it in an undefined state
if (ac->cb_method)
mono_runtime_invoke_checked (ac->cb_method, ac->cb_target, (gpointer*) &ares, &error);
g_assert (init_message_method != NULL);
}
- mono_error_init (error);
+ error_init (error);
/* FIXME set domain instead? */
g_assert (domain == mono_domain_get ());
g_assert (exc);
- mono_error_init (error);
+ error_init (error);
/*static MonoObject *(*invoke) (gpointer, gpointer, MonoObject **, MonoArray **) = NULL;*/
MONO_REQ_GC_UNSAFE_MODE;
static MonoClass *object_array_klass;
- mono_error_init (error);
+ error_init (error);
MonoDomain *domain;
MonoMethod *method;
MonoString *
mono_object_to_string_checked (MonoObject *obj, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
void *target;
MonoMethod *method = prepare_to_string_method (obj, &target);
return (MonoString*) mono_runtime_invoke_checked (method, target, NULL, error);
mono_object_try_to_string (MonoObject *obj, MonoObject **exc, MonoError *error)
{
g_assert (exc);
- mono_error_init (error);
+ error_init (error);
void *target;
MonoMethod *method = prepare_to_string_method (obj, &target);
return (MonoString*) mono_runtime_try_invoke (method, target, NULL, exc, error);
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoDelegate *delegate = (MonoDelegate *)this_obj;
g_assert (this_obj);
mono_stats.delegate_creations++;
#ifndef DISABLE_REMOTING
- if (target && target->vtable->klass == mono_defaults.transparent_proxy_class) {
+ if (target && mono_object_is_transparent_proxy (target)) {
g_assert (method);
method = mono_marshal_get_remoting_invoke (method);
delegate->method_ptr = mono_compile_method_checked (method, error);
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoDomain *domain = mono_domain_get ();
MonoJitInfo *ji;
MonoMethod *method = NULL;
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoDomain *domain = mono_domain_get ();
MonoMethodSignature *sig = mono_method_signature (method);
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoMethodSignature *sig = mono_method_signature (method);
int i, j, type, size, out_len;
static MonoMethod *getter = NULL;
- mono_error_init (error);
+ error_init (error);
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
{
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
static MonoMethod *tp_load = NULL;
MONO_REQ_GC_UNSAFE_MODE;
- mono_error_init (error);
+ error_init (error);
MonoDomain *domain = mono_domain_get ();
MonoClass *field_class;
static MonoMethod *tp_store = NULL;
- mono_error_init (error);
+ error_init (error);
g_assert (mono_object_is_transparent_proxy (this_obj));
return s->length;
}
+/**
+ * mono_string_handle_length:
+ * @s: MonoString
+ *
+ * Returns the lenght in characters of the string
+ */
+int
+mono_string_handle_length (MonoStringHandle s)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ return MONO_HANDLE_GETVAL (s, length);
+}
+
+
/**
* mono_array_length:
* @array: a MonoArray*
MonoArray *res;
int len, i;
- mono_error_init (error);
+ error_init (error);
if (!list)
return NULL;