*/
#include <glib.h>
+#include <config.h>
#include "mono-error.h"
#include "mono-error-internals.h"
#include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/object-internals.h>
static void
mono_error_prepare (MonoErrorInternal *error)
{
+ /* mono_error_set_* after a mono_error_cleanup without an intervening init */
+ g_assert (error->error_code != MONO_ERROR_CLEANUP_CALLED_SENTINEL);
if (error->error_code != MONO_ERROR_NONE)
return;
mono_error_cleanup (MonoError *oerror)
{
MonoErrorInternal *error = (MonoErrorInternal*)oerror;
- if (error->error_code == MONO_ERROR_NONE)
+ short int orig_error_code = error->error_code;
+ gboolean free_strings = error->flags & MONO_ERROR_FREE_STRINGS;
+ gboolean has_instance_handle = is_managed_exception (error);
+
+ /* Two cleanups in a row without an intervening init. */
+ g_assert (orig_error_code != MONO_ERROR_CLEANUP_CALLED_SENTINEL);
+
+ /* Mark it as cleaned up. */
+ error->error_code = MONO_ERROR_CLEANUP_CALLED_SENTINEL;
+ error->flags = 0;
+
+ if (orig_error_code == MONO_ERROR_NONE)
return;
- if (is_managed_exception (error))
+
+ if (has_instance_handle)
mono_gchandle_free (error->exn.instance_handle);
+
g_free ((char*)error->full_message);
g_free ((char*)error->full_message_with_fields);
- if (!(error->flags & MONO_ERROR_FREE_STRINGS)) //no memory was allocated
+ error->full_message = NULL;
+ error->full_message_with_fields = NULL;
+ if (!free_strings) //no memory was allocated
return;
g_free ((char*)error->type_name);
g_free ((char*)error->exception_name_space);
g_free ((char*)error->exception_name);
g_free ((char*)error->first_argument);
+ error->type_name = error->assembly_name = error->member_name = error->exception_name_space = error->exception_name = error->first_argument = NULL;
+ error->exn.klass = NULL;
+
}
gboolean
}
/**
- * mono_error_set_execution_engine:
+ * mono_error_set_not_supported:
*
* System.NotSupportedException
*/
va_end (args);
}
+/**
+ * mono_error_set_invalid_operation:
+ *
+ * System.InvalidOperationException
+ */
+void
+mono_error_set_invalid_operation (MonoError *oerror, const char *msg_format, ...)
+{
+ va_list args;
+ va_start (args, msg_format);
+ mono_error_set_generic_errorv (oerror, "System", "InvalidOperationException", msg_format, args);
+ 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)
{
break;
}
- exception = mono_exception_from_name_two_strings (mono_defaults.corlib, "System", "MissingMethodException", type_name, method_name);
+ exception = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "MissingMethodException", type_name, method_name, error_out);
if (exception)
set_message_on_exception (exception, error, error_out);
} else {
break;
}
- exception = mono_exception_from_name_two_strings (mono_defaults.corlib, "System", "MissingFieldException", type_name, field_name);
+ exception = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "MissingFieldException", type_name, field_name, error_out);
if (exception)
set_message_on_exception (exception, error, error_out);
} else {
}
}
- exception = mono_exception_from_name_two_strings (mono_get_corlib (), "System", "TypeLoadException", type_name, assembly_name);
+ exception = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", "TypeLoadException", type_name, assembly_name, error_out);
if (exception)
set_message_on_exception (exception, error, error_out);
} else {
}
if (error->error_code == MONO_ERROR_FILE_NOT_FOUND)
- exception = mono_exception_from_name_two_strings (mono_get_corlib (), "System.IO", "FileNotFoundException", msg, assembly_name);
+ exception = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System.IO", "FileNotFoundException", msg, assembly_name, error_out);
else
- exception = mono_exception_from_name_two_strings (mono_defaults.corlib, "System", "BadImageFormatException", msg, assembly_name);
+ exception = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, "System", "BadImageFormatException", msg, assembly_name, error_out);
} else {
if (error->error_code == MONO_ERROR_FILE_NOT_FOUND)
exception = mono_exception_from_name_msg (mono_get_corlib (), "System.IO", "FileNotFoundException", error->full_message);
exception = (MonoException*) mono_gchandle_get_target (error->exn.instance_handle);
break;
+ 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);
}