Merge pull request #2820 from kumpera/license-change-rebased
[mono.git] / mono / metadata / object.c
index fdb00751ccd909b2f7fcbfac24451c47f8e9b6ba..dc20b4e83212449db9ba9826eb4a0be57d796369 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2011 Novell, Inc (http://www.novell.com)
  * Copyright 2001 Xamarin Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 #include <config.h>
 #ifdef HAVE_ALLOCA_H
@@ -23,6 +24,7 @@
 #include <mono/metadata/object.h>
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
 #include <mono/metadata/domain-internals.h>
 #include "mono/metadata/metadata-internals.h"
 #include "mono/metadata/class-internals.h"
@@ -71,15 +73,39 @@ static GENERATE_GET_CLASS_WITH_CACHE (activation_services, System.Runtime.Remoti
 #define ldstr_unlock() mono_os_mutex_unlock (&ldstr_section)
 static mono_mutex_t ldstr_section;
 
+/**
+ * mono_runtime_object_init:
+ * @this_obj: the object to initialize
+ *
+ * This function calls the zero-argument constructor (which must
+ * exist) for the given object.
+ */
 void
 mono_runtime_object_init (MonoObject *this_obj)
+{
+       MonoError error;
+       mono_runtime_object_init_checked (this_obj, &error);
+       mono_error_assert_ok (&error);
+}
+
+/**
+ * mono_runtime_object_init_checked:
+ * @this_obj: the object to initialize
+ * @error: set on error.
+ *
+ * This function calls the zero-argument constructor (which must
+ * exist) for the given object and returns TRUE on success, or FALSE
+ * on error and sets @error.
+ */
+gboolean
+mono_runtime_object_init_checked (MonoObject *this_obj, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoError error;
        MonoMethod *method = NULL;
        MonoClass *klass = this_obj->vtable->klass;
 
+       mono_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));
@@ -87,8 +113,8 @@ mono_runtime_object_init (MonoObject *this_obj)
        if (method->klass->valuetype)
                this_obj = (MonoObject *)mono_object_unbox (this_obj);
 
-       mono_runtime_invoke_checked (method, this_obj, NULL, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       mono_runtime_invoke_checked (method, this_obj, NULL, error);
+       return is_ok (error);
 }
 
 /* The pseudo algorithm for type initialization from the spec
@@ -233,6 +259,7 @@ get_type_init_exception_for_vtable (MonoVTable *vtable)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
+       MonoError error;
        MonoDomain *domain = vtable->domain;
        MonoClass *klass = vtable->klass;
        MonoException *ex;
@@ -256,12 +283,14 @@ get_type_init_exception_for_vtable (MonoVTable *vtable)
                        full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
                else
                        full_name = g_strdup (klass->name);
-               ex = mono_get_exception_type_initialization (full_name, NULL);
+               ex = mono_get_exception_type_initialization_checked (full_name, NULL, &error);
                g_free (full_name);
+               return_val_if_nok (&error, NULL);
        }
 
        return ex;
 }
+
 /*
  * mono_runtime_class_init:
  * @vtable: vtable that needs to be initialized
@@ -272,24 +301,25 @@ void
 mono_runtime_class_init (MonoVTable *vtable)
 {
        MONO_REQ_GC_UNSAFE_MODE;
+       MonoError error;
 
-       mono_runtime_class_init_full (vtable, TRUE);
+       mono_runtime_class_init_full (vtable, &error);
+       mono_error_assert_ok (&error);
 }
 
-/*
+/**
  * mono_runtime_class_init_full:
  * @vtable that neeeds to be initialized
- * @raise_exception is TRUE, exceptions are raised intead of returned 
+ * @error set on error
+ *
+ * returns TRUE if class constructor .cctor has been initialized successfully, or FALSE otherwise and sets @error.
  * 
  */
-MonoException *
-mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
+gboolean
+mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoError error;
-       MonoException *exc;
-       MonoException *exc_to_throw;
        MonoMethod *method = NULL;
        MonoClass *klass;
        gchar *full_name;
@@ -299,39 +329,35 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
        int do_initialization = 0;
        MonoDomain *last_domain = NULL;
 
+       mono_error_init (error);
+
        if (vtable->initialized)
-               return NULL;
+               return TRUE;
 
-       exc = NULL;
        klass = vtable->klass;
 
        if (!klass->image->checked_module_cctor) {
                mono_image_check_for_module_cctor (klass->image);
                if (klass->image->has_module_cctor) {
-                       MonoError error;
                        MonoClass *module_klass;
                        MonoVTable *module_vtable;
 
-                       module_klass = mono_class_get_checked (klass->image, MONO_TOKEN_TYPE_DEF | 1, &error);
+                       module_klass = mono_class_get_checked (klass->image, MONO_TOKEN_TYPE_DEF | 1, error);
                        if (!module_klass) {
-                               exc = mono_error_convert_to_exception (&error);
-                               if (raise_exception)
-                                       mono_raise_exception (exc);
-                               return exc; 
+                               return FALSE;
                        }
                                
-                       module_vtable = mono_class_vtable_full (vtable->domain, module_klass, raise_exception);
+                       module_vtable = mono_class_vtable_full (vtable->domain, module_klass, error);
                        if (!module_vtable)
-                               return NULL;
-                       exc = mono_runtime_class_init_full (module_vtable, raise_exception);
-                       if (exc)
-                               return exc;
+                               return FALSE;
+                       if (!mono_runtime_class_init_full (module_vtable, error))
+                               return FALSE;
                }
        }
        method = mono_class_get_cctor (klass);
        if (!method) {
                vtable->initialized = 1;
-               return NULL;
+               return TRUE;
        }
 
        tid = mono_native_thread_id_get ();
@@ -340,15 +366,14 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
        /* double check... */
        if (vtable->initialized) {
                mono_type_initialization_unlock ();
-               return NULL;
+               return TRUE;
        }
        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);
+               mono_error_set_exception_instance (error, get_type_init_exception_for_vtable (vtable));
+               return FALSE;
        }
        lock = (TypeInitializationLock *)g_hash_table_lookup (type_initialization_hash, vtable);
        if (lock == NULL) {
@@ -359,9 +384,8 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
                        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 ();
+                               mono_error_set_exception_instance (error, mono_get_exception_appdomain_unloaded ());
+                               return FALSE;
                        }
                }
                lock = (TypeInitializationLock *)g_malloc (sizeof (TypeInitializationLock));
@@ -380,7 +404,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
 
                if (mono_native_thread_id_equals (lock->initializing_tid, tid) || lock->done) {
                        mono_type_initialization_unlock ();
-                       return NULL;
+                       return TRUE;
                }
                /* see if the thread doing the initialization is already blocked on this thread */
                blocked = GUINT_TO_POINTER (MONO_NATIVE_THREAD_ID_TO_UINT (lock->initializing_tid));
@@ -388,7 +412,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
                        if (mono_native_thread_id_equals (pending_lock->initializing_tid, tid)) {
                                if (!pending_lock->done) {
                                        mono_type_initialization_unlock ();
-                                       return NULL;
+                                       return TRUE;
                                } 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
@@ -405,15 +429,15 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
        mono_type_initialization_unlock ();
 
        if (do_initialization) {
-               mono_runtime_try_invoke (method, NULL, NULL, (MonoObject**) &exc, &error);
-               if (exc == NULL && !mono_error_ok (&error))
-                       exc = mono_error_convert_to_exception (&error);
-               else
-                       mono_error_cleanup (&error);
+               MonoException *exc = NULL;
+               mono_runtime_try_invoke (method, NULL, NULL, (MonoObject**) &exc, error);
+               if (exc != NULL && mono_error_ok (error)) {
+                       mono_error_set_exception_instance (error, exc);
+               }
 
                /* If the initialization failed, mark the class as unusable. */
                /* Avoid infinite loops */
-               if (!(exc == NULL ||
+               if (!(mono_error_ok(error) ||
                          (klass->image == mono_defaults.corlib &&
                           !strcmp (klass->name_space, "System") &&
                           !strcmp (klass->name, "TypeInitializationException")))) {
@@ -423,9 +447,17 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
                                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);
+
+                       MonoException *exc_to_throw = mono_get_exception_type_initialization_checked (full_name, exc, error);
                        g_free (full_name);
+                       return_val_if_nok (error, FALSE);
 
+                       mono_error_set_exception_instance (error, exc_to_throw);
+
+                       MonoException *exc_to_store = mono_error_convert_to_exception (error);
+                       /* What we really want to do here is clone the error object and store one copy in the
+                        * domain's exception hash and use the other one to error out here. */
+                       mono_error_set_exception_instance (error, exc_to_store);
                        /*
                         * Store the exception object so it could be thrown on subsequent
                         * accesses.
@@ -433,7 +465,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
                        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_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_store);
                        mono_domain_unlock (domain);
                }
 
@@ -463,11 +495,10 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
 
        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);
+               mono_error_set_exception_instance (error, get_type_init_exception_for_vtable (vtable));
+               return FALSE;
        }
-       return NULL;
+       return TRUE;
 }
 
 static
@@ -507,20 +538,6 @@ mono_release_type_locks (MonoInternalThread *thread)
        mono_type_initialization_unlock ();
 }
 
-static gpointer
-default_trampoline (MonoMethod *method)
-{
-       return method;
-}
-
-static gpointer
-default_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
-{
-       g_assert_not_reached ();
-
-       return NULL;
-}
-
 #ifndef DISABLE_REMOTING
 
 static gpointer
@@ -540,8 +557,6 @@ default_delegate_trampoline (MonoDomain *domain, MonoClass *klass)
        return NULL;
 }
 
-static MonoTrampoline arch_create_jit_trampoline = default_trampoline;
-static MonoJumpTrampoline arch_create_jump_trampoline = default_jump_trampoline;
 static MonoDelegateTrampoline arch_create_delegate_trampoline = default_delegate_trampoline;
 static MonoImtThunkBuilder imt_thunk_builder;
 static gboolean always_build_imt_thunks;
@@ -562,18 +577,6 @@ mono_get_runtime_callbacks (void)
        return &callbacks;
 }
 
-void
-mono_install_trampoline (MonoTrampoline func) 
-{
-       arch_create_jit_trampoline = func? func: default_trampoline;
-}
-
-void
-mono_install_jump_trampoline (MonoJumpTrampoline func) 
-{
-       arch_create_jump_trampoline = func? func: default_jump_trampoline;
-}
-
 #ifndef DISABLE_REMOTING
 void
 mono_install_remoting_trampoline (MonoRemotingTrampoline func) 
@@ -627,9 +630,15 @@ mono_compile_method (MonoMethod *method)
 gpointer
 mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
 {
-       MONO_REQ_GC_NEUTRAL_MODE
+       MonoError error;
+       gpointer res;
 
-       return arch_create_jump_trampoline (domain, method, add_sync_wrapper);
+       MONO_REQ_GC_NEUTRAL_MODE;
+
+       res = callbacks.create_jump_trampoline (domain, method, add_sync_wrapper, &error);
+       if (!mono_error_ok (&error))
+               mono_error_raise_exception (&error); /* FIXME: Don't raise here */
+       return res;
 }
 
 gpointer
@@ -1054,9 +1063,11 @@ field_is_special_static (MonoClass *fklass, MonoClassField *field)
 {
        MONO_REQ_GC_NEUTRAL_MODE;
 
+       MonoError error;
        MonoCustomAttrInfo *ainfo;
        int i;
-       ainfo = mono_custom_attrs_from_field (fklass, field);
+       ainfo = mono_custom_attrs_from_field_checked (fklass, field, &error);
+       mono_error_cleanup (&error); /* FIXME don't swallow the error? */
        if (!ainfo)
                return FALSE;
        for (i = 0; i < ainfo->num_attrs; ++i) {
@@ -1837,7 +1848,7 @@ mono_method_add_generic_virtual_invocation (MonoDomain *domain, MonoVTable *vtab
        mono_domain_unlock (domain);
 }
 
-static MonoVTable *mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean raise_on_error);
+static MonoVTable *mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, MonoError *error);
 
 /**
  * mono_class_vtable:
@@ -1851,30 +1862,34 @@ static MonoVTable *mono_class_create_runtime_vtable (MonoDomain *domain, MonoCla
 MonoVTable *
 mono_class_vtable (MonoDomain *domain, MonoClass *klass)
 {
-       return mono_class_vtable_full (domain, klass, FALSE);
+       MonoError error;
+       MonoVTable* vtable = mono_class_vtable_full (domain, klass, &error);
+       mono_error_cleanup (&error);
+       return vtable;
 }
 
 /**
  * mono_class_vtable_full:
  * @domain: the application domain
  * @class: the class to initialize
- * @raise_on_error if an exception should be raised on failure or not
+ * @error set on failure.
  *
  * VTables are domain specific because we create domain specific code, and 
  * they contain the domain specific static class data.
  */
 MonoVTable *
-mono_class_vtable_full (MonoDomain *domain, MonoClass *klass, gboolean raise_on_error)
+mono_class_vtable_full (MonoDomain *domain, MonoClass *klass, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
        MonoClassRuntimeInfo *runtime_info;
 
+       mono_error_init (error);
+
        g_assert (klass);
 
        if (mono_class_has_failure (klass)) {
-               if (raise_on_error)
-                       mono_raise_exception (mono_class_get_exception_for_failure (klass));
+               mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
                return NULL;
        }
 
@@ -1882,7 +1897,7 @@ mono_class_vtable_full (MonoDomain *domain, MonoClass *klass, gboolean raise_on_
        runtime_info = klass->runtime_info;
        if (runtime_info && runtime_info->max_domain >= domain->domain_id && runtime_info->domain_vtables [domain->domain_id])
                return runtime_info->domain_vtables [domain->domain_id];
-       return mono_class_create_runtime_vtable (domain, klass, raise_on_error);
+       return mono_class_create_runtime_vtable (domain, klass, error);
 }
 
 /**
@@ -1932,11 +1947,10 @@ alloc_vtable (MonoDomain *domain, size_t vtable_size, size_t imt_table_bytes)
 }
 
 static MonoVTable *
-mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean raise_on_error)
+mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoError error;
        MonoVTable *vt;
        MonoClassRuntimeInfo *runtime_info, *old_info;
        MonoClassField *field;
@@ -1948,6 +1962,8 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean
        gpointer iter;
        gpointer *interface_offsets;
 
+       mono_error_init (error);
+
        mono_loader_lock (); /*FIXME mono_class_init acquires it*/
        mono_domain_lock (domain);
        runtime_info = klass->runtime_info;
@@ -1960,8 +1976,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean
                if (!mono_class_init (klass) || mono_class_has_failure (klass)) {
                        mono_domain_unlock (domain);
                        mono_loader_unlock ();
-                       if (raise_on_error)
-                               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+                       mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
                        return NULL;
                }
        }
@@ -1982,8 +1997,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean
                                mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
                        mono_domain_unlock (domain);
                        mono_loader_unlock ();
-                       if (raise_on_error)
-                               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+                       mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
                        return NULL;
                }
        }
@@ -2004,8 +2018,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean
        if (mono_class_has_failure (klass)) {
                mono_domain_unlock (domain);
                mono_loader_unlock ();
-               if (raise_on_error)
-                       mono_raise_exception (mono_class_get_exception_for_failure (klass));
+               mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
                return NULL;
        }
 
@@ -2165,8 +2178,15 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean
                for (i = 0; i < klass->vtable_size; ++i) {
                        MonoMethod *cm;
 
-                       if ((cm = klass->vtable [i]))
-                               vt->vtable [i] = arch_create_jit_trampoline (cm);
+                       cm = klass->vtable [i];
+                       if (cm) {
+                               vt->vtable [i] = callbacks.create_jit_trampoline (domain, cm, error);
+                               if (!is_ok (error)) {
+                                       mono_domain_unlock (domain);
+                                       mono_loader_unlock ();
+                                       return NULL;
+                               }
+                       }
                }
        }
 
@@ -2182,9 +2202,12 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean
         */
        /* Special case System.MonoType to avoid infinite recursion */
        if (klass != mono_defaults.monotype_class) {
-               /*FIXME check for OOM*/
-               vt->type = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               vt->type = mono_type_get_object_checked (domain, &klass->byval_arg, error);
+               if (!is_ok (error)) {
+                       mono_domain_unlock (domain);
+                       mono_loader_unlock ();
+                       return NULL;
+               }
 
                if (mono_object_get_class ((MonoObject *)vt->type) != mono_defaults.monotype_class)
                        /* This is unregistered in
@@ -2238,9 +2261,12 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean
        }
 
        if (klass == mono_defaults.monotype_class) {
-               /*FIXME check for OOM*/
-               vt->type = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               vt->type = mono_type_get_object_checked (domain, &klass->byval_arg, error);
+               if (!is_ok (error)) {
+                       mono_domain_unlock (domain);
+                       mono_loader_unlock ();
+                       return NULL;
+               }
 
                if (mono_object_get_class ((MonoObject *)vt->type) != mono_defaults.monotype_class)
                        /* This is unregistered in
@@ -2255,7 +2281,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, gboolean
        /* make sure the parent is initialized */
        /*FIXME shouldn't this fail the current type?*/
        if (klass->parent)
-               mono_class_vtable_full (domain, klass->parent, raise_on_error);
+               mono_class_vtable_full (domain, klass->parent, error);
 
        return vt;
 }
@@ -2566,21 +2592,23 @@ copy_remote_class_key (MonoDomain *domain, gpointer *key)
  * mono_remote_class:
  * @domain: the application domain
  * @class_name: name of the remote class
+ * @error: set on error
  *
  * Creates and initializes a MonoRemoteClass object for a remote type. 
  *
- * Can raise an exception on failure. 
+ * On failure returns NULL and sets @error
  */
 MonoRemoteClass*
-mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class)
+mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoError error;
        MonoRemoteClass *rc;
        gpointer* key, *mp_key;
        char *name;
        
+       mono_error_init (error);
+
        key = create_remote_class_key (NULL, proxy_class);
        
        mono_domain_lock (domain);
@@ -2592,11 +2620,11 @@ mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_
                return rc;
        }
 
-       name = mono_string_to_utf8_mp (domain->mp, class_name, &error);
-       if (!mono_error_ok (&error)) {
+       name = mono_string_to_utf8_mp (domain->mp, class_name, error);
+       if (!is_ok (error)) {
                g_free (key);
                mono_domain_unlock (domain);
-               mono_error_raise_exception (&error);
+               return NULL;
        }
 
        mp_key = copy_remote_class_key (domain, key);
@@ -3340,9 +3368,30 @@ mono_field_get_value (MonoObject *obj, MonoClassField *field, void *value)
 MonoObject *
 mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObject *obj)
 {      
+       MonoError error;
+       MonoObject* result = mono_field_get_value_object_checked (domain, field, obj, &error);
+       mono_error_assert_ok (&error);
+       return result;
+}
+
+/**
+ * mono_field_get_value_object_checked:
+ * @domain: domain where the object will be created (if boxing)
+ * @field: MonoClassField describing the field to fetch information from
+ * @obj: The object instance for the field.
+ * @error: Set on error.
+ *
+ * Returns: a new MonoObject with the value from the given field.  If the
+ * field represents a value type, the value is boxed.  On error returns NULL and sets @error.
+ *
+ */
+MonoObject *
+mono_field_get_value_object_checked (MonoDomain *domain, MonoClassField *field, MonoObject *obj, MonoError *error)
+{
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoError error;
+       mono_error_init (error);
+
        MonoObject *o;
        MonoClass *klass;
        MonoVTable *vtable = NULL;
@@ -3351,10 +3400,9 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
        gboolean is_ref = FALSE;
        gboolean is_literal = FALSE;
        gboolean is_ptr = FALSE;
-       MonoType *type = mono_field_get_type_checked (field, &error);
+       MonoType *type = mono_field_get_type_checked (field, error);
 
-       if (!mono_error_ok (&error))
-               mono_error_raise_exception (&error);
+       return_val_if_nok (error, NULL);
 
        switch (type->type) {
        case MONO_TYPE_STRING:
@@ -3400,9 +3448,13 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
                is_static = TRUE;
 
                if (!is_literal) {
-                       vtable = mono_class_vtable_full (domain, field->parent, TRUE);
-                       if (!vtable->initialized)
-                               mono_runtime_class_init (vtable);
+                       vtable = mono_class_vtable_full (domain, field->parent, error);
+                       return_val_if_nok (error, NULL);
+
+                       if (!vtable->initialized) {
+                               mono_runtime_class_init_full (vtable, error);
+                               return_val_if_nok (error, NULL);
+                       }
                }
        } else {
                g_assert (obj);
@@ -3442,11 +3494,11 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
 
                /* MONO_TYPE_PTR is passed by value to runtime_invoke () */
                args [0] = ptr ? *ptr : NULL;
-               args [1] = mono_type_get_object_checked (mono_domain_get (), type, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               args [1] = mono_type_get_object_checked (mono_domain_get (), type, error);
+               return_val_if_nok (error, NULL);
 
-               o = mono_runtime_invoke_checked (m, NULL, args, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               o = mono_runtime_invoke_checked (m, NULL, args, error);
+               return_val_if_nok (error, NULL);
 
                return o;
        }
@@ -3455,10 +3507,10 @@ mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObje
        klass = mono_class_from_mono_type (type);
 
        if (mono_class_is_nullable (klass))
-               return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass);
+               return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass, error);
 
-       o = mono_object_new_checked (domain, klass, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       o = mono_object_new_checked (domain, klass, error);
+       return_val_if_nok (error, NULL);
        v = ((gchar *) o) + sizeof (MonoObject);
 
        if (is_literal) {
@@ -3683,17 +3735,17 @@ mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass)
  * mono_nullable_box:
  * @buf: The buffer representing the data to be boxed
  * @klass: the type to box it as.
+ * @error: set on oerr
  *
  * Creates a boxed vtype or NULL from the Nullable structure pointed to by
- * @buf.
+ * @buf.  On failure returns NULL and sets @error
  */
 MonoObject*
-mono_nullable_box (guint8 *buf, MonoClass *klass)
+mono_nullable_box (guint8 *buf, MonoClass *klass, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoError error;
-       
+       mono_error_init (error);
        MonoClass *param_class = klass->cast_class;
 
        mono_class_setup_fields_locking (klass);
@@ -3703,8 +3755,8 @@ mono_nullable_box (guint8 *buf, MonoClass *klass)
        g_assert (mono_class_from_mono_type (klass->fields [1].type) == mono_defaults.boolean_class);
 
        if (*(guint8*)(buf + klass->fields [1].offset - sizeof (MonoObject))) {
-               MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, error);
+               return_val_if_nok (error, NULL);
                if (param_class->has_references)
                        mono_gc_wbarrier_value_copy (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), 1, param_class);
                else
@@ -4286,6 +4338,7 @@ mono_unhandled_exception (MonoObject *exc)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
+       MonoError error;
        MonoClassField *field;
        MonoDomain *current_domain, *root_domain;
        MonoObject *current_appdomain_delegate = NULL, *root_appdomain_delegate = NULL;
@@ -4299,18 +4352,14 @@ mono_unhandled_exception (MonoObject *exc)
        current_domain = mono_domain_get ();
        root_domain = mono_get_root_domain ();
 
-       root_appdomain_delegate = mono_field_get_value_object (root_domain, field, (MonoObject*) root_domain->domain);
-       if (current_domain != root_domain)
-               current_appdomain_delegate = mono_field_get_value_object (current_domain, field, (MonoObject*) current_domain->domain);
+       root_appdomain_delegate = mono_field_get_value_object_checked (root_domain, field, (MonoObject*) root_domain->domain, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       if (current_domain != root_domain) {
+               current_appdomain_delegate = mono_field_get_value_object_checked (current_domain, field, (MonoObject*) current_domain->domain, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
+       }
 
-       /* set exitcode only if we will abort the process */
        if (!current_appdomain_delegate && !root_appdomain_delegate) {
-               if ((main_thread && mono_thread_internal_current () == main_thread->internal_thread)
-                    || mono_runtime_unhandled_exception_policy_get () == MONO_UNHANDLED_POLICY_CURRENT)
-               {
-                       mono_environment_exitcode_set (1);
-               }
-
                mono_print_unhandled_exception (exc);
        } else {
                if (root_appdomain_delegate)
@@ -4318,6 +4367,13 @@ mono_unhandled_exception (MonoObject *exc)
                if (current_appdomain_delegate)
                        call_unhandled_exception_delegate (current_domain, current_appdomain_delegate, exc);
        }
+
+       /* set exitcode only if we will abort the process */
+       if ((main_thread && mono_thread_internal_current () == main_thread->internal_thread)
+                || mono_runtime_unhandled_exception_policy_get () == MONO_UNHANDLED_POLICY_CURRENT)
+       {
+               mono_environment_exitcode_set (1);
+       }
 }
 
 /**
@@ -4387,7 +4443,8 @@ mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
                }
        }
 
-       cinfo = mono_custom_attrs_from_method (method);
+       cinfo = mono_custom_attrs_from_method_checked (method, &error);
+       mono_error_cleanup (&error); /* FIXME warn here? */
        if (cinfo) {
                has_stathread_attribute = mono_custom_attrs_has_attr (cinfo, mono_class_get_sta_thread_attribute_class ());
                if (!cinfo->cached)
@@ -4544,7 +4601,8 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
                                                 * boxed object in the arg array with the copy.
                                                 */
                                                MonoObject *orig = mono_array_get (params, MonoObject*, i);
-                                               MonoObject *copy = mono_value_box (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig));
+                                               MonoObject *copy = mono_value_box_checked (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig), &error);
+                                               mono_error_raise_exception (&error); /* FIXME don't raise here */
                                                mono_array_setref (params, i, copy);
                                        }
                                                
@@ -4596,8 +4654,11 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
 
                        if (!params)
                                return NULL;
-                       else
-                               return mono_value_box (mono_domain_get (), method->klass->cast_class, pa [0]);
+                       else {
+                               MonoObject *result = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, pa [0], &error);
+                               mono_error_raise_exception (&error); /* FIXME don't raise here */
+                               return result;
+                       }
                }
 
                if (!obj) {
@@ -4613,7 +4674,8 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
                        else
                                o = obj;
                } else if (method->klass->valuetype) {
-                       obj = mono_value_box (mono_domain_get (), method->klass, obj);
+                       obj = mono_value_box_checked (mono_domain_get (), method->klass, obj, &error);
+                       mono_error_raise_exception (&error); /* FIXME don't raise here */
                }
 
                if (exc) {
@@ -4636,7 +4698,9 @@ mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
                        nullable = mono_object_new_checked (mono_domain_get (), method->klass, &error);
                        mono_error_raise_exception (&error); /* FIXME don't raise here */
 
-                       mono_nullable_init ((guint8 *)mono_object_unbox (nullable), mono_value_box (mono_domain_get (), method->klass->cast_class, obj), method->klass);
+                       MonoObject *boxed = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, obj, &error);
+                       mono_error_raise_exception (&error); /* FIXME don't raise here */
+                       mono_nullable_init ((guint8 *)mono_object_unbox (nullable), boxed, method->klass);
                        obj = mono_object_unbox (nullable);
                }
 
@@ -4780,7 +4844,7 @@ mono_object_new_pinned (MonoDomain *domain, MonoClass *klass, MonoError *error)
        if (G_UNLIKELY (!o))
                mono_error_set_out_of_memory (error, "Could not allocate %i bytes", mono_class_instance_size (klass));
        else if (G_UNLIKELY (vtable->klass->has_finalize))
-               mono_object_register_finalizer (o);
+               mono_object_register_finalizer (o, error);
 
        return o;
 }
@@ -4825,7 +4889,7 @@ mono_object_new_specific_checked (MonoVTable *vtable, MonoError *error)
 
                        im = mono_class_get_method_from_name (klass, "CreateProxyForType", 1);
                        if (!im) {
-                               mono_error_set_generic_error (error, "System", "NotSupportedException", "Linked away.");
+                               mono_error_set_not_supported (error, "Linked away.");
                                return NULL;
                        }
                        vtable->domain->create_proxy_for_type_method = im;
@@ -4910,7 +4974,7 @@ mono_object_new_alloc_specific_checked (MonoVTable *vtable, MonoError *error)
        if (G_UNLIKELY (!o))
                mono_error_set_out_of_memory (error, "Could not allocate %i bytes", vtable->klass->instance_size);
        else if (G_UNLIKELY (vtable->klass->has_finalize))
-               mono_object_register_finalizer (o);
+               mono_object_register_finalizer (o, error);
 
        return o;
 }
@@ -4998,7 +5062,7 @@ mono_object_new_mature (MonoVTable *vtable, MonoError *error)
        if (G_UNLIKELY (!o))
                mono_error_set_out_of_memory (error, "Could not allocate %i bytes", vtable->klass->instance_size);
        else if (G_UNLIKELY (vtable->klass->has_finalize))
-               mono_object_register_finalizer (o);
+               mono_object_register_finalizer (o, error);
 
        return o;
 }
@@ -5113,7 +5177,7 @@ mono_object_clone_checked (MonoObject *obj, MonoError *error)
        mono_gc_wbarrier_object_copy (o, obj);
 
        if (obj->vtable->klass->has_finalize)
-               mono_object_register_finalizer (o);
+               mono_object_register_finalizer (o, error);
        return o;
 }
 
@@ -5354,7 +5418,9 @@ mono_array_new_full_checked (MonoDomain *domain, MonoClass *array_class, uintptr
         * Following three lines almost taken from mono_object_new ():
         * they need to be kept in sync.
         */
-       vtable = mono_class_vtable_full (domain, array_class, TRUE);
+       vtable = mono_class_vtable_full (domain, array_class, error);
+       return_val_if_nok (error, NULL);
+
        if (bounds_size)
                o = (MonoObject *)mono_gc_alloc_array (vtable, byte_len, len, bounds_size);
        else
@@ -5400,7 +5466,10 @@ mono_array_new (MonoDomain *domain, MonoClass *eclass, uintptr_t n)
        ac = mono_array_class_get (eclass, 1);
        g_assert (ac);
 
-       arr = mono_array_new_specific_checked (mono_class_vtable_full (domain, ac, TRUE), n, &error);
+       MonoVTable *vtable = mono_class_vtable_full (domain, ac, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+       arr = mono_array_new_specific_checked (vtable, n, &error);
        mono_error_raise_exception (&error); /* FIXME don't raise here */
 
        return arr;
@@ -5737,23 +5806,42 @@ mono_string_new_wrapper (const char *text)
 MonoObject *
 mono_value_box (MonoDomain *domain, MonoClass *klass, gpointer value)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
        MonoError error;
+       MonoObject *result = mono_value_box_checked (domain, klass, value, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+
+/**
+ * mono_value_box_checked:
+ * @domain: the domain of the new object
+ * @class: the class of the value
+ * @value: a pointer to the unboxed data
+ * @error: set on error
+ *
+ * Returns: A newly created object which contains @value. On failure
+ * returns NULL and sets @error.
+ */
+MonoObject *
+mono_value_box_checked (MonoDomain *domain, MonoClass *klass, gpointer value, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
        MonoObject *res;
        int size;
        MonoVTable *vtable;
 
+       mono_error_init (error);
+
        g_assert (klass->valuetype);
        if (mono_class_is_nullable (klass))
-               return mono_nullable_box ((guint8 *)value, klass);
+               return mono_nullable_box ((guint8 *)value, klass, error);
 
        vtable = mono_class_vtable (domain, klass);
        if (!vtable)
                return NULL;
        size = mono_class_instance_size (klass);
-       res = mono_object_new_alloc_specific_checked (vtable, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       res = mono_object_new_alloc_specific_checked (vtable, error);
+       return_val_if_nok (error, NULL);
 
        size = size - sizeof (MonoObject);
 
@@ -5782,8 +5870,10 @@ mono_value_box (MonoDomain *domain, MonoClass *klass, gpointer value)
        }
 #endif
 #endif
-       if (klass->has_finalize)
-               mono_object_register_finalizer (res);
+       if (klass->has_finalize) {
+               mono_object_register_finalizer (res, error);
+               return_val_if_nok (error, NULL);
+       }
        return res;
 }
 
@@ -5907,18 +5997,45 @@ mono_object_unbox (MonoObject *obj)
  * @obj: an object
  * @klass: a pointer to a class 
  *
- * Returns: @obj if @obj is derived from @klass
+ * Returns: @obj if @obj is derived from @klass or NULL otherwise.
  */
 MonoObject *
 mono_object_isinst (MonoObject *obj, MonoClass *klass)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
+       MonoError error;
+       MonoObject *result = mono_object_isinst_checked (obj, klass, &error);
+       mono_error_cleanup (&error);
+       return result;
+}
+       
+
+/**
+ * mono_object_isinst_checked:
+ * @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.
+ */
+MonoObject *
+mono_object_isinst_checked (MonoObject *obj, MonoClass *klass, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
+       mono_error_init (error);
+       
+       MonoObject *result = NULL;
+
        if (!klass->inited)
                mono_class_init (klass);
 
-       if (mono_class_is_marshalbyref (klass) || (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
-               return mono_object_isinst_mbyref (obj, klass);
+       if (mono_class_is_marshalbyref (klass) || (klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
+               result = mono_object_isinst_mbyref_checked (obj, klass, error);
+               return result;
+       }
 
        if (!obj)
                return NULL;
@@ -5932,8 +6049,20 @@ mono_object_isinst_mbyref (MonoObject *obj, MonoClass *klass)
        MONO_REQ_GC_UNSAFE_MODE;
 
        MonoError error;
+       MonoObject *result = mono_object_isinst_mbyref_checked (obj, klass, &error);
+       mono_error_cleanup (&error); /* FIXME better API that doesn't swallow the error */
+       return result;
+}
+
+MonoObject *
+mono_object_isinst_mbyref_checked (MonoObject *obj, MonoClass *klass, MonoError *error)
+{
+       MONO_REQ_GC_UNSAFE_MODE;
+
        MonoVTable *vt;
 
+       mono_error_init (error);
+
        if (!obj)
                return NULL;
 
@@ -5972,12 +6101,12 @@ mono_object_isinst_mbyref (MonoObject *obj, MonoClass *klass)
                im = mono_object_get_virtual_method (rp, im);
                g_assert (im);
        
-               pa [0] = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               pa [0] = mono_type_get_object_checked (domain, &klass->byval_arg, error);
+               return_val_if_nok (error, NULL);
                pa [1] = obj;
 
-               res = mono_runtime_invoke_checked (im, rp, pa, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               res = mono_runtime_invoke_checked (im, rp, pa, error);
+               return_val_if_nok (error, NULL);
 
                if (*(MonoBoolean *) mono_object_unbox(res)) {
                        /* Update the vtable of the remote type, so it can safely cast to this new type */
@@ -5994,19 +6123,17 @@ mono_object_isinst_mbyref (MonoObject *obj, MonoClass *klass)
  * @obj: an object
  * @klass: a pointer to a class 
  *
- * Returns: @obj if @obj is derived from @klass, throws an exception otherwise
+ * Returns: @obj if @obj is derived from @klass, returns NULL otherwise.
  */
 MonoObject *
 mono_object_castclass_mbyref (MonoObject *obj, MonoClass *klass)
 {
        MONO_REQ_GC_UNSAFE_MODE;
+       MonoError error;
 
        if (!obj) return NULL;
-       if (mono_object_isinst_mbyref (obj, klass)) return obj;
-               
-       mono_raise_exception (mono_exception_from_name (mono_defaults.corlib,
-                                                       "System",
-                                                       "InvalidCastException"));
+       if (mono_object_isinst_mbyref_checked (obj, klass, &error)) return obj;
+       mono_error_cleanup (&error);
        return NULL;
 }
 
@@ -6051,15 +6178,16 @@ mono_string_get_pinned (MonoString *str, MonoError *error)
 }
 
 static MonoString*
-mono_string_is_interned_lookup (MonoString *str, int insert)
+mono_string_is_interned_lookup (MonoString *str, int insert, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoError error;
        MonoGHashTable *ldstr_table;
        MonoString *s, *res;
        MonoDomain *domain;
        
+       mono_error_init (error);
+
        domain = ((MonoObject *)str)->vtable->domain;
        ldstr_table = domain->ldstr_table;
        ldstr_lock ();
@@ -6071,8 +6199,8 @@ mono_string_is_interned_lookup (MonoString *str, int insert)
        if (insert) {
                /* Allocate outside the lock */
                ldstr_unlock ();
-               s = mono_string_get_pinned (str, &error);
-               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               s = mono_string_get_pinned (str, error);
+               return_val_if_nok (error, NULL);
                if (s) {
                        ldstr_lock ();
                        res = (MonoString *)mono_g_hash_table_lookup (ldstr_table, str);
@@ -6114,9 +6242,11 @@ mono_string_is_interned_lookup (MonoString *str, int insert)
 MonoString*
 mono_string_is_interned (MonoString *o)
 {
-       MONO_REQ_GC_UNSAFE_MODE;
-
-       return mono_string_is_interned_lookup (o, FALSE);
+       MonoError error;
+       MonoString *result = mono_string_is_interned_lookup (o, FALSE, &error);
+       /* This function does not fail. */
+       mono_error_assert_ok (&error);
+       return result;
 }
 
 /**
@@ -6128,10 +6258,29 @@ mono_string_is_interned (MonoString *o)
  */
 MonoString*
 mono_string_intern (MonoString *str)
+{
+       MonoError error;
+       MonoString *result = mono_string_intern_checked (str, &error);
+       mono_error_assert_ok (&error);
+       return result;
+}
+
+/**
+ * mono_string_intern_checked:
+ * @o: String to intern
+ * @error: set on error.
+ *
+ * Interns the string passed.
+ * Returns: The interned string.  On failure returns NULL and sets @error
+ */
+MonoString*
+mono_string_intern_checked (MonoString *str, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       return mono_string_is_interned_lookup (str, TRUE);
+       mono_error_init (error);
+
+       return mono_string_is_interned_lookup (str, TRUE, error);
 }
 
 /**
@@ -6147,9 +6296,11 @@ MonoString*
 mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx)
 {
        MONO_REQ_GC_UNSAFE_MODE;
+       MonoError error;
 
        if (image->dynamic) {
-               MonoString *str = (MonoString *)mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL);
+               MonoString *str = (MonoString *)mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
                return str;
        } else {
                if (!mono_verifier_verify_string_signature (image, idx, NULL))
@@ -6816,22 +6967,26 @@ mono_message_init (MonoDomain *domain,
  * Returns: the result object.
  */
 MonoObject *
-mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg, 
-                     MonoObject **exc, MonoArray **out_args)
+mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg, MonoObject **exc, MonoArray **out_args, MonoError *error)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       MonoError error;
        MonoObject *o;
        MonoMethod *im = real_proxy->vtable->domain->private_invoke_method;
        gpointer pa [4];
 
+       g_assert (exc);
+
+       mono_error_init (error);
+
        /*static MonoObject *(*invoke) (gpointer, gpointer, MonoObject **, MonoArray **) = NULL;*/
 
        if (!im) {
                im = mono_class_get_method_from_name (mono_defaults.real_proxy_class, "PrivateInvoke", 4);
-               if (!im)
-                       mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
+               if (!im) {
+                       mono_error_set_not_supported (error, "Linked away.");
+                       return NULL;
+               }
                real_proxy->vtable->domain->private_invoke_method = im;
        }
 
@@ -6840,12 +6995,8 @@ mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg,
        pa [2] = exc;
        pa [3] = out_args;
 
-       if (exc) {
-               o = mono_runtime_try_invoke (im, NULL, pa, exc, &error);
-       } else {
-               o = mono_runtime_invoke_checked (im, NULL, pa, &error);
-       }
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       o = mono_runtime_try_invoke (im, NULL, pa, exc, error);
+       return_val_if_nok (error, NULL);
 
        return o;
 }
@@ -6872,7 +7023,10 @@ mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
                if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
                        target = tp->rp->unwrapped_server;
                } else {
-                       return mono_remoting_invoke ((MonoObject *)tp->rp, msg, exc, out_args);
+                       ret = mono_remoting_invoke ((MonoObject *)tp->rp, msg, exc, out_args, &error);
+                       mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+                       return ret;
                }
        }
 #endif
@@ -7150,9 +7304,10 @@ mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *
 
                klass = mono_class_from_mono_type (sig->params [i]);
 
-               if (klass->valuetype)
-                       arg = mono_value_box (domain, klass, vpos);
-               else 
+               if (klass->valuetype) {
+                       arg = mono_value_box_checked (domain, klass, vpos, &error);
+                       mono_error_raise_exception (&error); /* FIXME don't raise here */
+               } else 
                        arg = *((MonoObject **)vpos);
                      
                mono_array_setref (msg->args, i, arg);
@@ -7280,7 +7435,8 @@ mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *
        mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
        g_free (full_name);
 
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args);
+       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
 
        if (exc) mono_raise_exception ((MonoException *)exc);
 
@@ -7355,7 +7511,8 @@ mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFie
        mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
        g_free (full_name);
 
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args);
+       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
 
        if (exc) mono_raise_exception ((MonoException *)exc);
 
@@ -7411,9 +7568,10 @@ mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField
                        mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
        }
 
-       if (field_class->valuetype)
-               arg = mono_value_box (domain, field_class, val);
-       else 
+       if (field_class->valuetype) {
+               arg = mono_value_box_checked (domain, field_class, val, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
+       } else 
                arg = *((MonoObject **)val);
                
 
@@ -7429,7 +7587,8 @@ mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField
        mono_array_setref (msg->args, 2, arg);
        g_free (full_name);
 
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args);
+       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
 
        if (exc) mono_raise_exception ((MonoException *)exc);
 }
@@ -7487,7 +7646,8 @@ mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFi
        mono_array_setref (msg->args, 2, arg);
        g_free (full_name);
 
-       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args);
+       mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
 
        if (exc) mono_raise_exception ((MonoException *)exc);
 }