2009-11-05 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Thu, 5 Nov 2009 21:37:11 +0000 (21:37 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Thu, 5 Nov 2009 21:37:11 +0000 (21:37 -0000)
* mono-error-internals.h: Add mono_error_set_argument and mono_error_raise_exception.

* mono-error.h: Add new MONO_ERROR_ARGUMENT constant for
ArgumentException.

* mono-error.c: Implement mono_error_set_argument, mono_error_raise_exception.

  * mono-error.c (mono_error_prepare_exception) Init error_out at the beginning. Add support
for MONO_ERROR_ARGUMENT.

svn path=/trunk/mono/; revision=145538

mono/utils/ChangeLog
mono/utils/mono-error-internals.h
mono/utils/mono-error.c
mono/utils/mono-error.h

index 07cb1fcf455cc3194174e9428fe8cb93f69604f0..5612381ac90eaa60f1e6d20f7d4775aac93066dc 100644 (file)
@@ -1,3 +1,15 @@
+2009-11-05 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * mono-error-internals.h: Add mono_error_set_argument and mono_error_raise_exception.
+
+       * mono-error.h: Add new MONO_ERROR_ARGUMENT constant for
+       ArgumentException.
+
+       * mono-error.c: Implement mono_error_set_argument, mono_error_raise_exception.
+
+       * mono-error.c (mono_error_prepare_exception) Init error_out at the beginning. Add support
+       for MONO_ERROR_ARGUMENT.
+
 2009-10-30 Gonzalo Paniagua Javier <gonzalo@novell.com>
 
        * mono-proclib.c: hz is only multiplied by the number of cpus when
index b7e61376ad5ed50cbb1f55b8fe609173d7e79f2a..c5a1c12c580f0e693240ce270d49cea9c4db3eed 100644 (file)
@@ -9,6 +9,7 @@ typedef struct {
        unsigned short error_code;
     unsigned short flags;
 
+       /*These name are suggestions of their content. MonoError internals might use them for something else.*/
        const char *type_name;
        const char *assembly_name;
        const char *member_name;
@@ -49,10 +50,16 @@ mono_error_set_bad_image (MonoError *error, const char *file_name, const char *m
 void
 mono_error_set_out_of_memory (MonoError *error, const char *msg_format, ...) MONO_INTERNAL;
 
+void
+mono_error_set_argument (MonoError *error, const char *argument, const char *msg_format, ...) MONO_INTERNAL;
+
 void
 mono_error_set_generic_error (MonoError *error, const char * name_space, const char *name, const char *msg_format, ...) MONO_INTERNAL;
 
 MonoException*
 mono_error_prepare_exception (MonoError *error, MonoError *error_out) MONO_INTERNAL;
 
+void
+mono_error_raise_exception (MonoError *error) MONO_INTERNAL;
+
 #endif
index 0ee5c420ecf216c0b3aa395e36fec721a1a003c5..d539d47a16837393073ee2be8ae6d64d00070785 100644 (file)
@@ -267,6 +267,18 @@ mono_error_set_out_of_memory (MonoError *oerror, const char *msg_format, ...)
        va_end (args);
 }
 
+void
+mono_error_set_argument (MonoError *oerror, const char *argument, const char *msg_format, ...)
+{
+       MonoErrorInternal *error = (MonoErrorInternal*)oerror;
+       mono_error_prepare (error);
+
+       error->error_code = MONO_ERROR_ARGUMENT;
+       error->type_name = argument; /*use the first available string slot*/
+
+       set_error_message ();
+}
+
 static MonoString*
 get_type_name_as_mono_string (MonoErrorInternal *error, MonoDomain *domain, MonoError *error_out)
 {
@@ -297,6 +309,7 @@ set_message_on_exception (MonoException *exception, MonoErrorInternal *error, Mo
                mono_error_set_out_of_memory (error_out, "Could not allocate exception object");
 }
 
+/*Can fail with out-of-memory*/
 MonoException*
 mono_error_prepare_exception (MonoError *oerror, MonoError *error_out)
 {
@@ -306,6 +319,7 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out)
        MonoString *assembly_name = NULL, *type_name = NULL, *method_name = NULL, *field_name = NULL, *msg = NULL;
        MonoDomain *domain = mono_domain_get ();
 
+       mono_error_init (error_out);
 
        switch (error->error_code) {
        case MONO_ERROR_NONE:
@@ -406,6 +420,10 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out)
                exception = mono_get_exception_out_of_memory ();
                break;
 
+       case MONO_ERROR_ARGUMENT:
+               exception = mono_get_exception_argument (error->type_name, mono_internal_error_get_message (error));
+               break;
+
        case MONO_ERROR_GENERIC:
                if (!error->exception_name_space || !error->exception_name)
                        mono_error_set_generic_error (error_out, "System", "ExecutionEngineException", "MonoError with generic error but no exception name was supplied");
@@ -423,3 +441,32 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out)
                mono_error_set_out_of_memory (error_out, "Could not allocate exception object");
        return exception;
 }
+
+/*
+Raises the exception of @error.
+Does nothing if @error has a success error code.
+Aborts in case of a double fault. This happens when it can't recover from an error caused by trying
+to construct the first exception object.
+The error object @error is cleaned up. 
+*/
+void
+mono_error_raise_exception (MonoError *target_error)
+{
+       MonoError error;
+
+       if (mono_error_ok (target_error))
+               return;
+
+       MonoException *ex = mono_error_prepare_exception (target_error, &error);
+       if (!mono_error_ok (&error)) {
+               MonoError second_chance;
+               /*Try to produce the exception for the second error. FIXME maybe we should log about the original one*/
+               ex = mono_error_prepare_exception (&error, &second_chance);
+
+               g_assert (mono_error_ok (&second_chance)); /*We can't reasonable handle double faults, maybe later.*/
+               mono_error_cleanup (&error);
+       }
+       mono_error_cleanup (target_error);
+
+       mono_raise_exception (ex);      
+}
index bb969a15acca4f61bcbda6080d8a70680651e77c..75e3df27266bba5e8423765c96a04824eaf07e91 100644 (file)
@@ -21,11 +21,12 @@ enum {
        MONO_ERROR_FILE_NOT_FOUND = 4,
        MONO_ERROR_BAD_IMAGE = 5,
        MONO_ERROR_OUT_OF_MEMORY = 6,
+       MONO_ERROR_ARGUMENT = 7,
        /*
         * This is a generic error mechanism is you need to raise an arbitrary corlib exception.
         * You must pass the exception name otherwise prepare_exception will fail with internal execution. 
         */
-       MONO_ERROR_GENERIC = 7
+       MONO_ERROR_GENERIC = 8
 };
 
 /*Keep in sync with MonoErrorInternal*/