Merge pull request #2680 from lambdageek/dev/reflection-no-loadererror
authormonojenkins <jo.shields+jenkins@xamarin.com>
Mon, 29 Feb 2016 21:15:43 +0000 (21:15 +0000)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Mon, 29 Feb 2016 21:15:43 +0000 (21:15 +0000)
[reflection] Get rid of loader error in reflection.c

Get rid of (direct and indirect) calls to `mono_loader_set_error_from_mono_error` in reflection.c:

- `mono_custom_attrs_from_index`
- `mono_custom_attrs_from_method`
- `mono_custom_attrs_from_class`
- `mono_custom_attrs_from_assembly`
- `mono_custom_attrs_from_module`
- `mono_custom_attrs_from_property`
- `mono_custom_attrs_from_event`
- `mono_custom_attrs_from_field`
- `mono_custom_attrs_from_param`

In all the functions, add a `_checked` variant that has a `MonoError*` out argument and for the  MONO_API functions.  The public API versions just clean up the error and return NULL.  Loader error isn't touched anymore.

1  2 
mono/metadata/cominterop.c
mono/metadata/marshal.c
mono/metadata/object.c
mono/metadata/reflection.c
mono/mini/method-to-ir.c

index 85f86b76fdb31f795107eff14cb2aef53eb45c2f,a22b2c18de41ae559d216a60012a3181b14b7592..2adee418f37749a9f80db8f8f49a95e75d0b8640
@@@ -300,12 -300,13 +300,13 @@@ cominterop_object_is_rcw (MonoObject *o
  static int
  cominterop_get_com_slot_begin (MonoClass* klass)
  {
+       MonoError error;
        MonoCustomAttrInfo *cinfo = NULL;
        MonoInterfaceTypeAttribute* itf_attr = NULL; 
  
-       cinfo = mono_custom_attrs_from_class (klass);
+       cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+       mono_error_assert_ok (&error);
        if (cinfo) {
-               MonoError error;
                itf_attr = (MonoInterfaceTypeAttribute*)mono_custom_attrs_get_attr_checked (cinfo, mono_class_get_interface_type_attribute_class (), &error);
                g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
                if (!cinfo->cached)
@@@ -405,11 -406,12 +406,12 @@@ cominterop_mono_string_to_guid (MonoStr
  static gboolean
  cominterop_class_guid (MonoClass* klass, guint8* guid)
  {
+       MonoError error;
        MonoCustomAttrInfo *cinfo;
  
-       cinfo = mono_custom_attrs_from_class (klass);   
+       cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+       mono_error_assert_ok (&error);
        if (cinfo) {
-               MonoError error;
                MonoReflectionGuidAttribute *attr = (MonoReflectionGuidAttribute*)mono_custom_attrs_get_attr_checked (cinfo, mono_class_get_guid_attribute_class (), &error);
                g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
  
@@@ -432,9 -434,9 +434,9 @@@ cominterop_com_visible (MonoClass* klas
        GPtrArray *ifaces;
        MonoBoolean visible = 1;
  
-       cinfo = mono_custom_attrs_from_class (klass);
+       cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+       mono_error_assert_ok (&error);
        if (cinfo) {
-               MonoError error;
                MonoReflectionComVisibleAttribute *attr = (MonoReflectionComVisibleAttribute*)mono_custom_attrs_get_attr_checked (cinfo, mono_class_get_guid_attribute_class (), &error);
                g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
  
@@@ -1628,9 -1630,7 +1630,9 @@@ ves_icall_System_ComObject_CreateRCW (M
         * is called by the corresponding real proxy to create the real RCW.
         * Constructor does not need to be called. Will be called later.
        */
 -      obj = mono_object_new_alloc_specific_checked (mono_class_vtable_full (domain, klass, TRUE), &error);
 +      MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
 +      mono_error_raise_exception (&error);
 +      obj = mono_object_new_alloc_specific_checked (vtable, &error);
        mono_error_raise_exception (&error);
  
        return obj;
@@@ -1906,11 -1906,11 +1908,12 @@@ cominterop_get_ccw (MonoObject* object
                g_hash_table_insert (ccw_hash, GINT_TO_POINTER (mono_object_hash (object)), ccw_list);
                mono_cominterop_unlock ();
                /* register for finalization to clean up ccw */
 -              mono_object_register_finalizer (object);
 +              mono_object_register_finalizer (object, &error);
 +              mono_error_raise_exception (&error); /* FIXME don't raise here */
        }
  
-       cinfo = mono_custom_attrs_from_class (itf);
+       cinfo = mono_custom_attrs_from_class_checked (itf, &error);
+       mono_error_assert_ok (&error);
        if (cinfo) {
                static MonoClass* coclass_attribute = NULL;
                if (!coclass_attribute)
@@@ -2448,6 -2448,7 +2451,7 @@@ cominterop_ccw_get_ids_of_names (MonoCC
                                                                                         guint32 lcid, gint32 *rgDispId)
  {
        static MonoClass *ComDispIdAttribute = NULL;
+       MonoError error;
        MonoCustomAttrInfo *cinfo = NULL;
        int i,ret = MONO_S_OK;
        MonoMethod* method;
  
                method = mono_class_get_method_from_name(klass, methodname, -1);
                if (method) {
-                       cinfo = mono_custom_attrs_from_method (method);
+                       cinfo = mono_custom_attrs_from_method_checked (method, &error);
+                       mono_error_assert_ok (&error); /* FIXME what's reasonable to do here */
                        if (cinfo) {
-                               MonoError error;
                                MonoObject *result = mono_custom_attrs_get_attr_checked (cinfo, ComDispIdAttribute, &error);
                                g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/;
  
diff --combined mono/metadata/marshal.c
index 259e51ed02479622b5ca839d9876ada284c0ff7c,0f78d5434da696a18055044cb49516c7375be286..05a3be5582aea5fd1b3e7b7d137a58c988326526
@@@ -330,11 -330,9 +330,11 @@@ mono_marshal_unlock_internal (void
        mono_marshal_unlock ();
  }
  
 +/* This is a JIT icall, it sets the pending exception and return NULL on error */
  gpointer
  mono_delegate_to_ftnptr (MonoDelegate *delegate)
  {
 +      MonoError error;
        MonoMethod *method, *wrapper;
        MonoClass *klass;
        uint32_t target_handle = 0;
                ftnptr = mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
                if (!ftnptr) {
                        g_assert (exc_class);
 -                      mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
 +                      mono_set_pending_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
 +                      return NULL;
                }
                return ftnptr;
        }
        delegate_hash_table_add (delegate);
  
        /* when the object is collected, collect the dynamic method, too */
 -      mono_object_register_finalizer ((MonoObject*)delegate);
 +      mono_object_register_finalizer ((MonoObject*)delegate, &error);
 +      if (!mono_error_ok (&error)) {
 +              mono_error_set_pending_exception (&error);
 +              return NULL;
 +      }
  
        return delegate->delegate_trampoline;
  }
@@@ -450,6 -443,7 +450,7 @@@ mono_marshal_use_aot_wrappers (gboolea
  static void
  parse_unmanaged_function_pointer_attr (MonoClass *klass, MonoMethodPInvoke *piinfo)
  {
+       MonoError error;
        MonoCustomAttrInfo *cinfo;
        MonoReflectionUnmanagedFunctionPointerAttribute *attr;
  
                 * The pinvoke attributes are stored in a real custom attribute so we have to
                 * construct it.
                 */
-               cinfo = mono_custom_attrs_from_class (klass);
+               cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+               if (!mono_error_ok (&error)) {
+                       g_warning ("Could not load UnmanagedFunctionPointerAttribute due to %s", mono_error_get_message (&error));
+                       mono_error_cleanup (&error);
+               }
                if (cinfo && !mono_runtime_get_no_exec ()) {
-                       MonoError error;
                        attr = (MonoReflectionUnmanagedFunctionPointerAttribute*)mono_custom_attrs_get_attr_checked (cinfo, mono_class_try_get_unmanaged_function_pointer_attribute_class (), &error);
                        if (attr) {
                                piinfo->piflags = (attr->call_conv << 8) | (attr->charset ? (attr->charset - 1) * 2 : 1) | attr->set_last_error;
        }
  }
  
 +/* This is a JIT icall, it sets the pending exception and returns NULL on error */
  MonoDelegate*
  mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn)
  {
                }
  
                d = (MonoDelegate*)mono_object_new_checked (mono_domain_get (), klass, &error);
 -              mono_error_raise_exception (&error); /* FIXME don't raise here */
 +              if (!mono_error_ok (&error)) {
 +                      mono_error_set_pending_exception (&error);
 +                      return NULL;
 +              }
                mono_delegate_ctor_with_method ((MonoObject*)d, this_obj, mono_compile_method (wrapper), wrapper);
        }
  
 -      if (d->object.vtable->domain != mono_domain_get ())
 -              mono_raise_exception (mono_get_exception_not_supported ("Delegates cannot be marshalled from native code into a domain other than their home domain"));
 +      if (d->object.vtable->domain != mono_domain_get ()) {
 +              mono_set_pending_exception (mono_get_exception_not_supported ("Delegates cannot be marshalled from native code into a domain other than their home domain"));
 +              return NULL;
 +      }
  
        return d;
  }
@@@ -603,7 -594,6 +607,7 @@@ mono_string_from_byvalstr (const char *
        return mono_string_new_len (domain, data, len);
  }
  
 +/* This is a JIT icall, it sets the pending exception and return NULL on error */
  static MonoString *
  mono_string_from_byvalwstr (gunichar2 *data, int max_len)
  {
        while (data [len]) len++;
  
        res = mono_string_new_utf16_checked (domain, data, MIN (len, max_len), &error);
 -      mono_error_raise_exception (&error);
 +      if (!mono_error_ok (&error)) {
 +              mono_error_set_pending_exception (&error);
 +              return NULL;
 +      }
        return res;
  }
  
@@@ -744,7 -731,6 +748,7 @@@ mono_byvalarray_to_byte_array (MonoArra
        mono_byvalarray_to_array (arr, native_arr, mono_defaults.byte_class, elnum);
  }
  
 +/* This is a JIT icall, it sets the pending exception and returns on error */
  static void
  mono_array_to_byvalarray (gpointer native_arr, MonoArray *arr, MonoClass *elclass, guint32 elnum)
  {
  
                as = g_utf16_to_utf8 (mono_array_addr (arr, gunichar2, 0), mono_array_length (arr), NULL, NULL, &error);
                if (error) {
 -                      MonoException *exc = mono_get_exception_argument ("string", error->message);
 +                      mono_set_pending_exception (mono_get_exception_argument ("string", error->message));
                        g_error_free (error);
 -                      mono_raise_exception (exc);
 +                      return;
                }
  
                memcpy (native_arr, as, MIN (strlen (as), elnum));
@@@ -906,8 -892,6 +910,8 @@@ mono_string_utf16_to_builder (MonoStrin
   * Returns: a utf8 string with the contents of the StringBuilder.
   *
   * The return value must be released with g_free.
 + *
 + * This is a JIT icall, it sets the pending exception and returns NULL on error.
   */
  gchar*
  mono_string_builder_to_utf8 (MonoStringBuilder *sb)
        if (!sb)
                return NULL;
  
 -
        gunichar2 *str_utf16 = mono_string_builder_to_utf16 (sb);
  
        guint str_len = mono_string_builder_string_length (sb);
        if (gerror) {
                g_error_free (gerror);
                g_free (str_utf16);
 -              mono_raise_exception (mono_get_exception_execution_engine ("Failed to convert StringBuilder from utf16 to utf8"));
 +              mono_set_pending_exception (mono_get_exception_execution_engine ("Failed to convert StringBuilder from utf16 to utf8"));
                return NULL;
        } else {
                guint len = mono_string_builder_capacity (sb) + 1;
                if (!mono_error_ok (&error)) {
                        g_free (str_utf16);
                        g_free (tmp);
 -                      mono_error_raise_exception (&error);
 +                      mono_error_set_pending_exception (&error);
 +                      return NULL;
                }
  
                g_assert (str_len < len);
   * Returns: a utf16 string with the contents of the StringBuilder.
   *
   * The return value must not be freed.
 + * This is a JIT icall, it sets the pending exception and returns NULL on error.
   */
  gunichar2*
  mono_string_builder_to_utf16 (MonoStringBuilder *sb)
                len = 1;
  
        gunichar2 *str = (gunichar2 *)mono_marshal_alloc ((len + 1) * sizeof (gunichar2), &error);
 -      mono_error_raise_exception (&error);
 +      if (!mono_error_ok (&error)) {
 +              mono_error_set_pending_exception (&error);
 +              return NULL;
 +      }
  
        str[len] = '\0';
  
        return str;
  }
  
 +/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
  static gpointer
  mono_string_to_lpstr (MonoString *s)
  {
        if (error) {
                MonoException *exc = mono_get_exception_argument ("string", error->message);
                g_error_free (error);
 -              mono_raise_exception(exc);
 +              mono_set_pending_exception (exc);
                return NULL;
        } else {
                as = CoTaskMemAlloc (len + 1);
@@@ -2143,7 -2122,6 +2147,7 @@@ mono_marshal_emit_thread_force_interrup
  
  #endif /* DISABLE_JIT */
  
 +/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
  static MonoAsyncResult *
  mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params)
  {
  
        g_assert (delegate);
        mcast_delegate = (MonoMulticastDelegate *) delegate;
 -      if (mcast_delegate->delegates != NULL)
 -              mono_raise_exception (mono_get_exception_argument (NULL, "The delegate must have only one target"));
 +      if (mcast_delegate->delegates != NULL) {
 +              mono_set_pending_exception (mono_get_exception_argument (NULL, "The delegate must have only one target"));
 +              return NULL;
 +      }
  
  #ifndef DISABLE_REMOTING
        if (delegate->target && mono_object_class (delegate->target) == mono_defaults.transparent_proxy_class) {
 -
                MonoTransparentProxy* tp = (MonoTransparentProxy *)delegate->target;
                if (!mono_class_is_contextbound (tp->remote_class->proxy_class) || tp->rp->context != (MonoObject *) mono_context_get ()) {
 -
                        /* If the target is a proxy, make a direct call. Is proxy's work
                        // to make the call asynchronous.
                        */
                        exc = NULL;
                        mono_remoting_invoke ((MonoObject *)tp->rp, msg, &exc, &out_args);
                        if (exc)
 -                              mono_raise_exception ((MonoException *) exc);
 +                              mono_set_pending_exception ((MonoException *) exc);
                        return ares;
                }
        }
@@@ -2859,7 -2837,6 +2863,7 @@@ mono_marshal_get_delegate_begin_invoke 
        return res;
  }
  
 +/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
  static MonoObject *
  mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params)
  {
        if (!delegate->method_info) {
                g_assert (delegate->method);
                MonoReflectionMethod *rm = mono_method_get_object_checked (domain, delegate->method, NULL, &error);
 -              mono_error_raise_exception (&error); /* FIXME don't raise here */
 +              if (!mono_error_ok (&error)) {
 +                      mono_error_set_pending_exception (&error);
 +                      return NULL;
 +              }
                MONO_OBJECT_SETREF (delegate, method_info, rm);
        }
  
  
        ares = (MonoAsyncResult *)mono_array_get (msg->args, gpointer, sig->param_count - 1);
        if (ares == NULL) {
 -              mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System.Runtime.Remoting", "RemotingException", "The async result object is null or of an unexpected type."));
 +              mono_set_pending_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System.Runtime.Remoting", "RemotingException", "The async result object is null or of an unexpected type."));
                return NULL;
        }
  
        if (ares->async_delegate != (MonoObject*)delegate) {
 -              mono_raise_exception (mono_get_exception_invalid_operation (
 +              mono_set_pending_exception (mono_get_exception_invalid_operation (
                        "The IAsyncResult object provided does not match this delegate."));
                return NULL;
        }
        if (delegate->target && mono_object_is_transparent_proxy (delegate->target)) {
                MonoTransparentProxy* tp = (MonoTransparentProxy *)delegate->target;
                msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
 -              mono_error_raise_exception (&error); /* FIXME don't raise here */
 +              if (!mono_error_ok (&error)) {
 +                      mono_error_set_pending_exception (&error);
 +                      return NULL;
 +              }
                mono_message_init (domain, msg, delegate->method_info, NULL);
                msg->call_type = CallType_EndInvoke;
                MONO_OBJECT_SETREF (msg, async_result, ares);
                        MONO_OBJECT_SETREF (((MonoException*)exc), stack_trace, mono_string_new (domain, tmp));
                        g_free (tmp);
                }
 -              mono_raise_exception ((MonoException*)exc);
 +              mono_set_pending_exception ((MonoException*)exc);
        }
  
        mono_method_return_message_restore (method, params, out_args);
@@@ -8122,6 -8093,7 +8126,7 @@@ mono_marshal_set_callconv_from_modopt (
  MonoMethod *
  mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, uint32_t target_handle)
  {
+       MonoError error;
        MonoMethodSignature *sig, *csig, *invoke_sig;
        MonoMethodBuilder *mb;
        MonoMethod *res, *invoke;
                 * contents of the attribute without constructing it, as that might not be
                 * possible when running in cross-compiling mode.
                 */
-               cinfo = mono_custom_attrs_from_class (delegate_klass);
+               cinfo = mono_custom_attrs_from_class_checked (delegate_klass, &error);
+               mono_error_assert_ok (&error);
                attr = NULL;
                if (cinfo) {
                        for (i = 0; i < cinfo->num_attrs; ++i) {
@@@ -10207,16 -10180,12 +10213,16 @@@ mono_marshal_alloc (gulong size, MonoEr
        return res;
  }
  
 +/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
  static void*
  ves_icall_marshal_alloc (gulong size)
  {
        MonoError error;
        void *ret = mono_marshal_alloc (size, &error);
 -      mono_error_raise_exception (&error);
 +      if (!mono_error_ok (&error)) {
 +              mono_error_set_pending_exception (&error);
 +              return NULL;
 +      }
  
        return ret;
  }
@@@ -10250,7 -10219,6 +10256,7 @@@ mono_marshal_string_to_utf16 (MonoStrin
        return s ? mono_string_chars (s) : NULL;
  }
  
 +/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
  static void *
  mono_marshal_string_to_utf16_copy (MonoString *s)
  {
        } else {
                MonoError error;
                gunichar2 *res = (gunichar2 *)mono_marshal_alloc ((mono_string_length (s) * 2) + 2, &error);
 -              mono_error_raise_exception (&error); /* FIXME don't raise here */
 +              if (!mono_error_ok (&error)) {
 +                      mono_error_set_pending_exception (&error);
 +                      return NULL;
 +              }
                memcpy (res, mono_string_chars (s), mono_string_length (s) * 2);
                res [mono_string_length (s)] = 0;
                return res;
@@@ -10398,10 -10363,7 +10404,10 @@@ ves_icall_System_Runtime_InteropService
                len++;
  
        res = mono_string_new_utf16_checked (domain, ptr, len, &error);
 -      mono_error_raise_exception (&error);
 +      if (!mono_error_ok (&error)) {
 +              mono_error_set_pending_exception (&error);
 +              return NULL;
 +      }
        return res;
  }
  
@@@ -10483,31 -10445,29 +10489,31 @@@ ves_icall_System_Runtime_InteropService
        pa [2] = &delete_old;
  
        mono_runtime_invoke_checked (method, NULL, pa, &error);
 -      mono_error_raise_exception (&error);
 +      if (!mono_error_ok (&error))
 +              mono_error_set_pending_exception (&error);
  }
  
  static void
 -ptr_to_structure (gpointer src, MonoObject *dst)
 +ptr_to_structure (gpointer src, MonoObject *dst, MonoError *error)
  {
 -      MonoError error;
        MonoMethod *method;
        gpointer pa [2];
  
 +      mono_error_init (error);
 +
        method = mono_marshal_get_ptr_to_struct (dst->vtable->klass);
  
        pa [0] = &src;
        pa [1] = dst;
  
 -      mono_runtime_invoke_checked (method, NULL, pa, &error);
 -      mono_error_raise_exception (&error); /* FIXME don't raise here */
 +      mono_runtime_invoke_checked (method, NULL, pa, error);
  }
  
  void
  ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure (gpointer src, MonoObject *dst)
  {
        MonoType *t;
 +      MonoError error;
  
        MONO_CHECK_ARG_NULL (src,);
        MONO_CHECK_ARG_NULL (dst,);
                return;
        }
  
 -      ptr_to_structure (src, dst);
 +      ptr_to_structure (src, dst, &error);
 +      if (!mono_error_ok (&error))
 +              mono_error_set_pending_exception (&error);
  }
  
  MonoObject *
@@@ -10550,16 -10508,9 +10556,16 @@@ ves_icall_System_Runtime_InteropService
        }
  
        res = mono_object_new_checked (domain, klass, &error);
 -      mono_error_raise_exception (&error);
 +      if (!mono_error_ok (&error)) {
 +              mono_error_set_pending_exception (&error);
 +              return NULL;
 +      }
  
 -      ptr_to_structure (src, res);
 +      ptr_to_structure (src, res, &error);
 +      if (!mono_error_ok (&error)) {
 +              mono_error_set_pending_exception (&error);
 +              return NULL;
 +      }
  
        return res;
  }
@@@ -10742,10 -10693,8 +10748,10 @@@ ves_icall_System_Runtime_InteropService
  #else
        res = g_try_malloc (s);
  #endif
 -      if (!res)
 -              mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
 +      if (!res) {
 +              mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
 +              return NULL;
 +      }
  
        return res;
  }
@@@ -10757,7 -10706,7 +10763,7 @@@ ves_icall_System_Runtime_InteropService
        size_t s = (size_t)size;
  
        if (ptr == NULL) {
 -              mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
 +              mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
                return NULL;
        }
  
  #else
        res = g_try_realloc (ptr, s);
  #endif
 -      if (!res)
 -              mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
 +      if (!res) {
 +              mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
 +              return NULL;
 +      }
  
        return res;
  }
@@@ -10798,10 -10745,8 +10804,10 @@@ ves_icall_System_Runtime_InteropService
  
        res = g_try_malloc ((gulong)size);
  #endif
 -      if (!res)
 -              mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
 +      if (!res) {
 +              mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
 +              return NULL;
 +      }
        return res;
  }
  
@@@ -10825,10 -10770,8 +10831,10 @@@ ves_icall_System_Runtime_InteropService
  #else
        res = g_try_realloc (ptr, (gulong)size);
  #endif
 -      if (!res)
 -              mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
 +      if (!res) {
 +              mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
 +              return NULL;
 +      }
        return res;
  }
  
@@@ -11232,7 -11175,6 +11238,7 @@@ mono_marshal_type_size (MonoType *type
        return 0;
  }
  
 +/* This is a JIT icall, it sets the pending exception and return NULL on error */
  gpointer
  mono_marshal_asany (MonoObject *o, MonoMarshalNative string_encoding, int param_attrs)
  {
                        return mono_object_unbox (o);
  
                res = mono_marshal_alloc (mono_class_native_size (klass, NULL), &error);
 -              mono_error_raise_exception (&error); /* FIXME don't raise here */
 +              if (!mono_error_ok (&error)) {
 +                      mono_error_set_pending_exception (&error);
 +                      return NULL;
 +              }
  
                if (!((param_attrs & PARAM_ATTRIBUTE_OUT) && !(param_attrs & PARAM_ATTRIBUTE_IN))) {
                        method = mono_marshal_get_struct_to_ptr (o->vtable->klass);
                        pa [2] = &delete_old;
  
                        mono_runtime_invoke_checked (method, NULL, pa, &error);
 -                      mono_error_raise_exception (&error); /* FIXME don't raise here */
 +                      if (!mono_error_ok (&error)) {
 +                              mono_error_set_pending_exception (&error);
 +                              return NULL;
 +                      }
                }
  
                return res;
        default:
                break;
        }
 -      mono_raise_exception (mono_get_exception_argument ("", "No PInvoke conversion exists for value passed to Object-typed parameter."));
 +      mono_set_pending_exception (mono_get_exception_argument ("", "No PInvoke conversion exists for value passed to Object-typed parameter."));
        return NULL;
  }
  
 +/* This is a JIT icall, it sets the pending exception */
  void
  mono_marshal_free_asany (MonoObject *o, gpointer ptr, MonoMarshalNative string_encoding, int param_attrs)
  {
                        pa [1] = o;
  
                        mono_runtime_invoke_checked (method, NULL, pa, &error);
 -                      mono_error_raise_exception (&error); /* FIXME don't raise here */
 +                      if (!mono_error_ok (&error)) {
 +                              mono_error_set_pending_exception (&error);
 +                              return;
 +                      }
                }
  
                if (!((param_attrs & PARAM_ATTRIBUTE_OUT) && !(param_attrs & PARAM_ATTRIBUTE_IN))) {
diff --combined mono/metadata/object.c
index 95ab77990c96d92f8b3a7e4bb40d5516917ce41b,623cccef8552dfb34d3c0ebf826b9a787eb93f6a..39c126f8c9feb9496dca7597c798ff2b8b9430b9
@@@ -262,7 -262,6 +262,7 @@@ get_type_init_exception_for_vtable (Mon
  
        return ex;
  }
 +
  /*
   * mono_runtime_class_init:
   * @vtable: vtable that needs to be initialized
@@@ -273,25 -272,24 +273,25 @@@ voi
  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;
        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 ();
        /* 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) {
                        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));
  
                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));
                        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
        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")))) {
                                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);
 +                      mono_error_set_exception_instance (error, mono_get_exception_type_initialization (full_name, exc));
                        g_free (full_name);
  
 +                      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.
                        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);
                }
  
  
        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
@@@ -1045,9 -1046,11 +1045,11 @@@ field_is_special_static (MonoClass *fkl
  {
        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) {
@@@ -1828,7 -1831,7 +1830,7 @@@ mono_method_add_generic_virtual_invocat
        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:
  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;
        }
  
        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);
  }
  
  /**
@@@ -1927,10 -1926,11 +1929,10 @@@ alloc_vtable (MonoDomain *domain, size_
  }
  
  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;
        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;
                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;
                }
        }
                                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;
                }
        }
        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;
        }
  
  
                        cm = klass->vtable [i];
                        if (cm) {
 -                              vt->vtable [i] = callbacks.create_jit_trampoline (domain, cm, &error);
 -                              if (!mono_error_ok (&error))
 -                                      mono_error_raise_exception (&error); /* FIXME: Don't raise here */
 +                              vt->vtable [i] = callbacks.create_jit_trampoline (domain, cm, error);
 +                              mono_error_raise_exception (error); /* FIXME: Don't raise here */
                        }
                }
        }
         */
        /* 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
        }
  
        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
        /* 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;
  }
@@@ -3356,7 -3352,7 +3358,7 @@@ mono_field_get_value_object (MonoDomai
        MonoType *type = mono_field_get_type_checked (field, &error);
  
        if (!mono_error_ok (&error))
 -              mono_error_raise_exception (&error);
 +              mono_error_raise_exception (&error);  /* FIXME don't raise here */
  
        switch (type->type) {
        case MONO_TYPE_STRING:
                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);
 +                      mono_error_raise_exception (&error);  /* FIXME don't raise here */
 +
 +                      if (!vtable->initialized) {
 +                              mono_runtime_class_init_full (vtable, &error);
 +                              mono_error_raise_exception (&error);  /* FIXME don't raise here */
 +                      }
                }
        } else {
                g_assert (obj);
@@@ -4393,7 -4385,8 +4395,8 @@@ mono_runtime_exec_main (MonoMethod *met
                }
        }
  
-       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)
@@@ -4786,7 -4779,7 +4789,7 @@@ mono_object_new_pinned (MonoDomain *dom
        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;
  }
@@@ -4916,7 -4909,7 +4919,7 @@@ mono_object_new_alloc_specific_checked 
        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;
  }
@@@ -5004,7 -4997,7 +5007,7 @@@ mono_object_new_mature (MonoVTable *vta
        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;
  }
@@@ -5119,7 -5112,7 +5122,7 @@@ mono_object_clone_checked (MonoObject *
        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;
  }
  
@@@ -5360,9 -5353,7 +5363,9 @@@ mono_array_new_full_checked (MonoDomai
         * 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
@@@ -5408,10 -5399,7 +5411,10 @@@ mono_array_new (MonoDomain *domain, Mon
        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;
@@@ -5793,10 -5781,8 +5796,10 @@@ mono_value_box (MonoDomain *domain, Mon
        }
  #endif
  #endif
 -      if (klass->has_finalize)
 -              mono_object_register_finalizer (res);
 +      if (klass->has_finalize) {
 +              mono_object_register_finalizer (res, &error);
 +              mono_error_raise_exception (&error); /* FIXME don't raise here */
 +      }
        return res;
  }
  
@@@ -6064,16 -6050,15 +6067,16 @@@ mono_string_get_pinned (MonoString *str
  }
  
  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 ();
        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);
  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;
  }
  
  /**
   */
  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);
  }
  
  /**
index cedd69aae9e9388a07b8ce1104773f1d5e17ecf6,dcdd090db3371167d20dcb6a3e8d31f9a18191d6..687926aa14c61f145666deb08a60ef93a2a258ac
@@@ -1468,7 -1468,7 +1468,7 @@@ mono_custom_attrs_free (MonoCustomAttrI
  {
        MONO_REQ_GC_NEUTRAL_MODE;
  
-       if (!ainfo->cached)
+       if (ainfo && !ainfo->cached)
                g_free (ainfo);
  }
  
@@@ -9497,6 -9497,19 +9497,19 @@@ mono_custom_attrs_data_construct (MonoC
   */
  MonoCustomAttrInfo*
  mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
+ {
+       MonoError error;
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_index_checked (image, idx, &error);
+       mono_error_cleanup (&error); /* FIXME a better public API that doesn't swallow the error. */
+       return result;
+ }
+ /**
+  * mono_custom_attrs_from_index_checked:
+  *
+  * Returns: NULL if no attributes are found.  On error returns NULL and sets @error.
+  */
+ MonoCustomAttrInfo*
+ mono_custom_attrs_from_index_checked (MonoImage *image, guint32 idx, MonoError *error)
  {
        guint32 mtoken, i, len;
        guint32 cols [MONO_CUSTOM_ATTR_SIZE];
        const char *data;
        MonoCustomAttrEntry* attr;
  
+       mono_error_init (error);
        ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
  
        i = mono_metadata_custom_attrs_from_index (image, idx);
        ainfo->num_attrs = len;
        ainfo->image = image;
        for (i = len, tmp = list; i != 0; --i, tmp = tmp->next) {
-               MonoError error;
                mono_metadata_decode_row (ca, GPOINTER_TO_UINT (tmp->data), cols, MONO_CUSTOM_ATTR_SIZE);
                mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS;
                switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) {
                        break;
                }
                attr = &ainfo->attrs [i - 1];
-               attr->ctor = mono_get_method_checked (image, mtoken, NULL, NULL, &error);
+               attr->ctor = mono_get_method_checked (image, mtoken, NULL, NULL, error);
                if (!attr->ctor) {
-                       g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to %s", image->name, mtoken, mono_error_get_message (&error));
-                       mono_loader_set_error_from_mono_error (&error);
+                       g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to %s", image->name, mtoken, mono_error_get_message (error));
                        g_list_free (list);
                        g_free (ainfo);
                        return NULL;
  
  MonoCustomAttrInfo*
  mono_custom_attrs_from_method (MonoMethod *method)
+ {
+       MonoError error;
+       MonoCustomAttrInfo* result = mono_custom_attrs_from_method_checked  (method, &error);
+       mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+       return result;
+ }
+ MonoCustomAttrInfo*
+ mono_custom_attrs_from_method_checked (MonoMethod *method, MonoError *error)
  {
        guint32 idx;
  
+       mono_error_init (error);
        /*
         * An instantiated method has the same cattrs as the generic method definition.
         *
        idx = mono_method_get_index (method);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_METHODDEF;
-       return mono_custom_attrs_from_index (method->klass->image, idx);
+       return mono_custom_attrs_from_index_checked (method->klass->image, idx, error);
  }
  
  MonoCustomAttrInfo*
  mono_custom_attrs_from_class (MonoClass *klass)
+ {
+       MonoError error;
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_class_checked (klass, &error);
+       mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+       return result;
+ }
+ MonoCustomAttrInfo*
+ mono_custom_attrs_from_class_checked (MonoClass *klass, MonoError *error)
  {
        guint32 idx;
  
+       mono_error_init (error);
        if (klass->generic_class)
                klass = klass->generic_class->container_class;
  
                idx <<= MONO_CUSTOM_ATTR_BITS;
                idx |= MONO_CUSTOM_ATTR_TYPEDEF;
        }
-       return mono_custom_attrs_from_index (klass->image, idx);
+       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
  }
  
  MonoCustomAttrInfo*
  mono_custom_attrs_from_assembly (MonoAssembly *assembly)
+ {
+       MonoError error;
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_assembly_checked (assembly, &error);
+       mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+       return result;
+ }
+ MonoCustomAttrInfo*
+ mono_custom_attrs_from_assembly_checked (MonoAssembly *assembly, MonoError *error)
  {
        guint32 idx;
        
+       mono_error_init (error);
        if (image_is_dynamic (assembly->image))
                return lookup_custom_attr (assembly->image, assembly);
        idx = 1; /* there is only one assembly */
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
-       return mono_custom_attrs_from_index (assembly->image, idx);
+       return mono_custom_attrs_from_index_checked (assembly->image, idx, error);
  }
  
  static MonoCustomAttrInfo*
- mono_custom_attrs_from_module (MonoImage *image)
+ mono_custom_attrs_from_module (MonoImage *image, MonoError *error)
  {
        guint32 idx;
        
        idx = 1; /* there is only one module */
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_MODULE;
-       return mono_custom_attrs_from_index (image, idx);
+       return mono_custom_attrs_from_index_checked (image, idx, error);
  }
  
  MonoCustomAttrInfo*
  mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
+ {
+       MonoError error;
+       MonoCustomAttrInfo * result = mono_custom_attrs_from_property_checked (klass, property, &error);
+       mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+       return result;
+ }
+ MonoCustomAttrInfo*
+ mono_custom_attrs_from_property_checked (MonoClass *klass, MonoProperty *property, MonoError *error)
  {
        guint32 idx;
        
        idx = find_property_index (klass, property);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_PROPERTY;
-       return mono_custom_attrs_from_index (klass->image, idx);
+       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
  }
  
  MonoCustomAttrInfo*
  mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
+ {
+       MonoError error;
+       MonoCustomAttrInfo * result = mono_custom_attrs_from_event_checked (klass, event, &error);
+       mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+       return result;
+ }
+ MonoCustomAttrInfo*
+ mono_custom_attrs_from_event_checked (MonoClass *klass, MonoEvent *event, MonoError *error)
  {
        guint32 idx;
        
        idx = find_event_index (klass, event);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_EVENT;
-       return mono_custom_attrs_from_index (klass->image, idx);
+       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
  }
  
  MonoCustomAttrInfo*
  mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field)
+ {
+       MonoError error;
+       MonoCustomAttrInfo * result = mono_custom_attrs_from_field_checked (klass, field, &error);
+       mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+       return result;
+ }
+ MonoCustomAttrInfo*
+ mono_custom_attrs_from_field_checked (MonoClass *klass, MonoClassField *field, MonoError *error)
  {
        guint32 idx;
+       mono_error_init (error);
        if (image_is_dynamic (klass->image)) {
                field = mono_metadata_get_corresponding_field_from_generic_type_definition (field);
                return lookup_custom_attr (klass->image, field);
        idx = find_field_index (klass, field);
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_FIELDDEF;
-       return mono_custom_attrs_from_index (klass->image, idx);
+       return mono_custom_attrs_from_index_checked (klass->image, idx, error);
  }
  
  /**
   */
  MonoCustomAttrInfo*
  mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
+ {
+       MonoError error;
+       MonoCustomAttrInfo *result = mono_custom_attrs_from_param_checked (method, param, &error);
+       mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+       return result;
+ }
+ /**
+  * mono_custom_attrs_from_param_checked:
+  * @method: handle to the method that we want to retrieve custom parameter information from
+  * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
+  * @error: set on error
+  *
+  * The result must be released with mono_custom_attrs_free().
+  *
+  * Returns: the custom attribute object for the specified parameter, or NULL if there are none.  On failure returns NULL and sets @error.
+  */
+ MonoCustomAttrInfo*
+ mono_custom_attrs_from_param_checked (MonoMethod *method, guint32 param, MonoError *error)
  {
        MonoTableInfo *ca;
        guint32 i, idx, method_index;
        MonoImage *image;
        MonoReflectionMethodAux *aux;
  
+       mono_error_init (error);
        /*
         * An instantiated method has the same cattrs as the generic method definition.
         *
        idx = i;
        idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= MONO_CUSTOM_ATTR_PARAMDEF;
-       return mono_custom_attrs_from_index (image, idx);
+       return mono_custom_attrs_from_index_checked (image, idx, error);
  }
  
  gboolean
@@@ -9851,34 -9947,43 +9947,43 @@@ mono_reflection_get_custom_attrs_info_c
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
                klass = mono_class_from_mono_type (type);
                /*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
-               cinfo = mono_custom_attrs_from_class (klass);
+               cinfo = mono_custom_attrs_from_class_checked (klass, error);
+               return_val_if_nok (error, NULL);
        } else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
                MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
-               cinfo = mono_custom_attrs_from_assembly (rassembly->assembly);
+               cinfo = mono_custom_attrs_from_assembly_checked (rassembly->assembly, error);
+               return_val_if_nok (error, NULL);
        } else if (strcmp ("Module", klass->name) == 0 || strcmp ("MonoModule", klass->name) == 0) {
                MonoReflectionModule *module = (MonoReflectionModule*)obj;
-               cinfo = mono_custom_attrs_from_module (module->image);
+               cinfo = mono_custom_attrs_from_module (module->image, error);
+               return_val_if_nok (error, NULL);
        } else if (strcmp ("MonoProperty", klass->name) == 0) {
                MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
-               cinfo = mono_custom_attrs_from_property (rprop->property->parent, rprop->property);
+               cinfo = mono_custom_attrs_from_property_checked (rprop->property->parent, rprop->property, error);
+               return_val_if_nok (error, NULL);
        } else if (strcmp ("MonoEvent", klass->name) == 0) {
                MonoReflectionMonoEvent *revent = (MonoReflectionMonoEvent*)obj;
-               cinfo = mono_custom_attrs_from_event (revent->event->parent, revent->event);
+               cinfo = mono_custom_attrs_from_event_checked (revent->event->parent, revent->event, error);
+               return_val_if_nok (error, NULL);
        } else if (strcmp ("MonoField", klass->name) == 0) {
                MonoReflectionField *rfield = (MonoReflectionField*)obj;
-               cinfo = mono_custom_attrs_from_field (rfield->field->parent, rfield->field);
+               cinfo = mono_custom_attrs_from_field_checked (rfield->field->parent, rfield->field, error);
+               return_val_if_nok (error, NULL);
        } else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
                MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
-               cinfo = mono_custom_attrs_from_method (rmethod->method);
+               cinfo = mono_custom_attrs_from_method_checked (rmethod->method, error);
+               return_val_if_nok (error, NULL);
        } else if ((strcmp ("MonoGenericMethod", klass->name) == 0) || (strcmp ("MonoGenericCMethod", klass->name) == 0)) {
                MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
-               cinfo = mono_custom_attrs_from_method (rmethod->method);
+               cinfo = mono_custom_attrs_from_method_checked (rmethod->method, error);
+               return_val_if_nok (error, NULL);
        } else if (strcmp ("ParameterInfo", klass->name) == 0 || strcmp ("MonoParameterInfo", klass->name) == 0) {
                MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
                MonoClass *member_class = mono_object_class (param->MemberImpl);
                if (mono_class_is_reflection_method_or_constructor (member_class)) {
                        MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
-                       cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1);
+                       cinfo = mono_custom_attrs_from_param_checked (rmethod->method, param->PositionImpl + 1, error);
+                       return_val_if_nok (error, NULL);
                } else if (is_sr_mono_property (member_class)) {
                        MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
                        MonoMethod *method;
                                method = prop->property->set;
                        g_assert (method);
  
-                       cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+                       cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
+                       return_val_if_nok (error, NULL);
                } 
  #ifndef DISABLE_REFLECTION_EMIT
                else if (is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
                        MonoMethod *method = mono_reflection_method_on_tb_inst_get_handle ((MonoReflectionMethodOnTypeBuilderInst*)param->MemberImpl, error);
                        return_val_if_nok (error, NULL);
-                       cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+                       cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
+                       return_val_if_nok (error, NULL);
                } else if (is_sre_ctor_on_tb_inst (member_class)) { /*XX This is a workaround for Compiler Context*/
                        MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)param->MemberImpl;
                        MonoMethod *method = NULL;
                        else
                                g_error ("mono_reflection_get_custom_attrs_info:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (member_class));
  
-                       cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+                       cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
+                       return_val_if_nok (error, NULL);
                } 
  #endif
                else {
@@@ -9969,11 -10077,7 +10077,7 @@@ mono_reflection_get_custom_attrs_by_typ
                if (!cinfo->cached)
                        mono_custom_attrs_free (cinfo);
        } else {
-               /* FIXME add MonoError to mono_reflection_get_custom_attrs_info */
-               if (mono_loader_get_last_error ()) {
-                       mono_error_set_from_loader_error (error);
-                       return NULL;
-               }
+               mono_loader_assert_no_error ();
                result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, 0);
        }
  
@@@ -12904,8 -13008,7 +13008,8 @@@ resolve_object (MonoImage *image, MonoO
        gpointer result = NULL;
  
        if (strcmp (obj->vtable->klass->name, "String") == 0) {
 -              result = mono_string_intern ((MonoString*)obj);
 +              result = mono_string_intern_checked ((MonoString*)obj, &error);
 +              mono_error_raise_exception (&error); /* FIXME don't raise here */
                *handle_class = mono_defaults.string_class;
                g_assert (result);
        } else if (strcmp (obj->vtable->klass->name, "MonoType") == 0) {
diff --combined mono/mini/method-to-ir.c
index 20fb34e56baad496154f04bd1dc2acce152bcdd6,3d459697a27d2eefb1f3a60215cc2e076f44390f..8fe1c0a76d088007567b1b33190dd679076dc84f
@@@ -5326,11 -5326,8 +5326,11 @@@ mono_method_check_inlining (MonoCompil
                        vtable = mono_class_vtable (cfg->domain, method->klass);
                        if (!vtable)
                                return FALSE;
 -                      if (!cfg->compile_aot)
 -                              mono_runtime_class_init (vtable);
 +                      if (!cfg->compile_aot) {
 +                              MonoError error;
 +                              if (!mono_runtime_class_init_full (vtable, &error))
 +                                      mono_error_raise_exception (&error); /* FIXME don't raise here */
 +                      }
                } else if (method->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) {
                        if (cfg->run_cctors && method->klass->has_cctor) {
                                /*FIXME it would easier and lazier to just use mono_class_try_get_vtable */
                                /* running with a specific order... */
                                if (! vtable->initialized)
                                        return FALSE;
 -                              mono_runtime_class_init (vtable);
 +                              MonoError error;
 +                              if (!mono_runtime_class_init_full (vtable, &error))
 +                                      mono_error_raise_exception (&error); /* FIXME don't raise here */
                        }
                } else if (mono_class_needs_cctor_run (method->klass, NULL)) {
                        if (!method->klass->runtime_info)
@@@ -7899,6 -7894,7 +7899,7 @@@ is_exception_class (MonoClass *klass
  static gboolean
  is_jit_optimizer_disabled (MonoMethod *m)
  {
+       MonoError error;
        MonoAssembly *ass = m->klass->image->assembly;
        MonoCustomAttrInfo* attrs;
        MonoClass *klass;
                return FALSE;
        }
  
-       attrs = mono_custom_attrs_from_assembly (ass);
+       attrs = mono_custom_attrs_from_assembly_checked (ass, &error);
+       mono_error_cleanup (&error); /* FIXME don't swallow the error */
        if (attrs) {
                for (i = 0; i < attrs->num_attrs; ++i) {
                        MonoCustomAttrEntry *attr = &attrs->attrs [i];
@@@ -11629,14 -11626,17 +11631,14 @@@ mono_method_to_ir (MonoCompile *cfg, Mo
                                                }
                                        } else {
                                                if (cfg->run_cctors) {
 -                                                      MonoException *ex;
                                                        /* This makes so that inline cannot trigger */
                                                        /* .cctors: too many apps depend on them */
                                                        /* running with a specific order... */
                                                        g_assert (vtable);
                                                        if (! vtable->initialized)
                                                                INLINE_FAILURE ("class init");
 -                                                      ex = mono_runtime_class_init_full (vtable, FALSE);
 -                                                      if (ex) {
 +                                                      if (!mono_runtime_class_init_full (vtable, &cfg->error)) {
                                                                mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
 -                                                              mono_error_set_exception_instance (&cfg->error, ex);
                                                                g_assert_not_reached ();
                                                                goto exception_exit;
                                                        }