[runtime] Make helper to set MonoError directly from MonoClass error
authorAlexander Kyte <alexmkyte@fastmail.com>
Tue, 31 May 2016 21:04:33 +0000 (17:04 -0400)
committerAlexander Kyte <alexmkyte@fastmail.com>
Fri, 3 Jun 2016 15:24:32 +0000 (11:24 -0400)
mono/metadata/class-internals.h
mono/metadata/class.c
mono/utils/mono-error-internals.h
mono/utils/mono-error.c
mono/utils/mono-error.h

index b8f4aca8f8e091ad0aad3cd9c60628a61c5a5327..b72657fda72f1e55b2195782581692a490447c74 100644 (file)
@@ -1443,6 +1443,9 @@ mono_class_load_from_name (MonoImage *image, const char* name_space, const char
 MonoClass*
 mono_class_try_load_from_name (MonoImage *image, const char* name_space, const char *name);
 
+void
+mono_error_set_for_class_failure (MonoError *orerror, MonoClass *klass);
+
 static inline guint8
 mono_class_get_failure (MonoClass *klass)
 {
index 17da478b5e9c1f089d76de0bc275da6ab5e21077..d21c7939816bbd155fd6bb239513e510b902b209 100644 (file)
@@ -1369,6 +1369,53 @@ mono_type_has_exceptions (MonoType *type)
        }
 }
 
+void
+mono_error_set_for_class_failure (MonoError *oerror, MonoClass *klass)
+{
+       gpointer exception_data = mono_class_get_exception_data (klass);
+
+       switch (mono_class_get_failure(klass)) {
+       case MONO_EXCEPTION_TYPE_LOAD: {
+               mono_error_set_type_load_class (oerror, klass, "Error Loading class");
+               return;
+       }
+       case MONO_EXCEPTION_MISSING_METHOD: {
+               char *class_name = (char *)exception_data;
+               char *member_name = class_name + strlen (class_name) + 1;
+
+               mono_error_set_method_load (oerror, klass, member_name, "Error Loading Method");
+               return;
+       }
+       case MONO_EXCEPTION_MISSING_FIELD: {
+               char *class_name = (char *)exception_data;
+               char *member_name = class_name + strlen (class_name) + 1;
+
+               mono_error_set_field_load (oerror, klass, member_name, "Error Loading Field");
+               return;
+       }
+       case MONO_EXCEPTION_FILE_NOT_FOUND: {
+               char *msg_format = (char *)exception_data;
+               char *assembly_name = msg_format + strlen (msg_format) + 1;
+               char *msg = g_strdup_printf (msg_format, assembly_name);
+
+               mono_error_set_assembly_load (oerror, assembly_name, msg);
+               return;
+       }
+       case MONO_EXCEPTION_BAD_IMAGE: {
+               mono_error_set_bad_image (oerror, NULL, (const char *)exception_data);
+               return;
+       }
+       case MONO_EXCEPTION_INVALID_PROGRAM: {
+               mono_error_set_invalid_program (oerror, (const char *)exception_data);
+               return;
+       }
+       default: {
+               g_assert_not_reached ();
+       }
+       }
+}
+
+
 /*
  * mono_class_alloc:
  *
index 63607a8fb89eb962ba99887b2941a5963cd6a7ed..8e926b7ceada05635e97e951d73b79a0db64da64 100644 (file)
@@ -113,6 +113,9 @@ mono_error_set_invalid_operation (MonoError *error, const char *msg_format, ...)
 void
 mono_error_set_exception_instance (MonoError *error, MonoException *exc);
 
+void
+mono_error_set_invalid_program (MonoError *oerror, const char *msg_format, ...);
+
 MonoException*
 mono_error_prepare_exception (MonoError *error, MonoError *error_out);
 
index 7488c9ca6c9f64df7ed65b17c3c911efc1f22968..94d4e99c60e22631cbc09d6f6a23aaf3f4c09e21 100644 (file)
@@ -440,6 +440,17 @@ mono_error_set_invalid_operation (MonoError *oerror, const char *msg_format, ...
        va_end (args);
 }
 
+void
+mono_error_set_invalid_program (MonoError *oerror, const char *msg_format, ...)
+{
+       MonoErrorInternal *error = (MonoErrorInternal*)oerror;
+
+       mono_error_prepare (error);
+       error->error_code = MONO_ERROR_INVALID_PROGRAM;
+
+       set_error_message ();
+}
+
 void
 mono_error_set_exception_instance (MonoError *oerror, MonoException *exc)
 {
@@ -687,6 +698,14 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out)
        case MONO_ERROR_CLEANUP_CALLED_SENTINEL:
                mono_error_set_execution_engine (error_out, "MonoError reused after mono_error_cleanup");
                break;
+
+       case MONO_ERROR_INVALID_PROGRAM: {
+               gboolean lacks_message = error->flags & MONO_ERROR_INCOMPLETE;
+               if (lacks_message)
+                       return mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", "");
+               else
+                       return mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", error->full_message);
+       }
        default:
                mono_error_set_execution_engine (error_out, "Invalid error-code %d", error->error_code);
        }
index 2a98d4839fc45f4ca02b7a8fa247f8bc642fff70..0aba0e1d61abb4219d6cfc15a9a8ead976c1ceaa 100644 (file)
@@ -26,6 +26,8 @@ enum {
        MONO_ERROR_ARGUMENT = 7,
        MONO_ERROR_ARGUMENT_NULL = 11,
        MONO_ERROR_NOT_VERIFIABLE = 8,
+       MONO_ERROR_INVALID_PROGRAM = 12,
+
        /*
         * 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.