Merge pull request #2670 from lambdageek/dev/monoerror-mono_runtime_object_init
[mono.git] / mono / metadata / object.c
index 0a082351a7d547587ba08cb33afc446fb0ace05d..00ec533a19490dbee8626d7f070cf7aff8eb832c 100644 (file)
@@ -23,6 +23,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 +72,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 +112,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 +258,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,8 +282,9 @@ 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;
@@ -419,8 +446,12 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
                                full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
                        else
                                full_name = g_strdup (klass->name);
-                       mono_error_set_exception_instance (error, 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