static gboolean mutex_handle_own (MonoW32Handle *handle_data, gboolean *abandoned) { HANDLE_FUNCTION_ENTER (); MonoW32HandleMutex *mutex_handle; *abandoned = FALSE; mutex_handle = (MonoW32HandleMutex*) handle_data->specific; mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: owning %s handle %p, before: [tid: %p, recursion: %d], after: [tid: %p, recursion: %d], abandoned: %s", __func__, mono_w32handle_get_typename (handle_data->type), handle_data, (gpointer) mutex_handle->tid, mutex_handle->recursion, (gpointer) pthread_self (), mutex_handle->recursion + 1, mutex_handle->abandoned ? "true" : "false"); if (mutex_handle->recursion != 0) { g_assert (pthread_equal (pthread_self (), mutex_handle->tid)); mutex_handle->recursion++; } else { mutex_handle->tid = pthread_self (); mutex_handle->recursion = 1; thread_own_mutex (mono_thread_internal_current_handle (), handle_data, handle_data); } if (mutex_handle->abandoned) { mutex_handle->abandoned = FALSE; *abandoned = TRUE; } mono_w32handle_set_signal_state (handle_data, FALSE, FALSE); HANDLE_FUNCTION_RETURN_VAL (TRUE); }
void mono_w32mutex_abandon (MonoInternalThread *internal_raw) { HANDLE_FUNCTION_ENTER () MONO_HANDLE_DCL (MonoInternalThread, internal); g_assert (mono_thread_internal_is_current_handle (internal)); if (!MONO_HANDLE_GETVAL (internal, owned_mutexes)) goto exit; while (MONO_HANDLE_GETVAL (internal, owned_mutexes)->len) { MonoW32Handle *handle_data; MonoW32HandleMutex *mutex_handle; MonoNativeThreadId tid; gpointer handle; handle = g_ptr_array_index (MONO_HANDLE_GETVAL (internal, owned_mutexes), 0); if (!mono_w32handle_lookup_and_ref (handle, &handle_data)) g_error ("%s: unkown handle %p", __func__, handle); if (handle_data->type != MONO_W32TYPE_MUTEX && handle_data->type != MONO_W32TYPE_NAMEDMUTEX) g_error ("%s: unkown mutex handle %p", __func__, handle); mutex_handle = (MonoW32HandleMutex*) handle_data->specific; mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoning %s handle %p", __func__, mono_w32handle_get_typename (handle_data->type), handle); tid = MONO_UINT_TO_NATIVE_THREAD_ID (MONO_HANDLE_GETVAL (internal, tid)); if (!pthread_equal (mutex_handle->tid, tid)) g_error ("%s: trying to release mutex %p acquired by thread %p from thread %p", __func__, handle, (gpointer) mutex_handle->tid, (gpointer) tid); mono_w32handle_lock (handle_data); mutex_handle->recursion = 0; mutex_handle->tid = 0; mutex_handle->abandoned = TRUE; mono_w32handle_set_signal_state (handle_data, TRUE, FALSE); thread_disown_mutex (internal, handle); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoned %s handle %p", __func__, mono_w32handle_get_typename (handle_data->type), handle); mono_w32handle_unlock (handle_data); mono_w32handle_unref (handle_data); } g_ptr_array_free (MONO_HANDLE_GETVAL (internal, owned_mutexes), TRUE); MONO_HANDLE_SETVAL(internal, owned_mutexes, GPtrArray*, NULL); exit: HANDLE_FUNCTION_RETURN (); }
MonoExceptionHandle mono_get_exception_runtime_wrapped_handle (MonoObjectHandle wrapped_exception, MonoError *error) { HANDLE_FUNCTION_ENTER (); MonoClass *klass; MonoMethod *method; klass = mono_class_load_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", "RuntimeWrappedException"); MonoObjectHandle o = mono_object_new_handle (mono_domain_get (), klass, error); mono_error_assert_ok (error); g_assert (!MONO_HANDLE_IS_NULL (o)); method = mono_class_get_method_from_name_checked (klass, ".ctor", 1, 0, error); mono_error_assert_ok (error); g_assert (method); gpointer args [ ] = { MONO_HANDLE_RAW (wrapped_exception) }; mono_runtime_invoke_handle (method, o, args, error); goto_if_nok (error, return_null); goto exit; return_null: o = mono_new_null (); exit: HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, o)); }
/** * mono_exception_new_by_name_domain: * \param domain Domain where the return object will be created. * \param image the Mono image where to look for the class * \param name_space the namespace for the class * \param name class name * * Creates an exception object of the given namespace/name class on * the given domain. * * \returns the initialized exception instance. */ static MonoExceptionHandle mono_exception_new_by_name_domain (MonoDomain *domain, MonoImage *image, const char* name_space, const char *name, MonoError *error) { HANDLE_FUNCTION_ENTER (); MonoDomain * const caller_domain = mono_domain_get (); MonoClass * const klass = mono_class_load_from_name (image, name_space, name); MonoObjectHandle o = mono_object_new_handle (domain, klass, error); goto_if_nok (error, return_null); if (domain != caller_domain) mono_domain_set_internal (domain); mono_runtime_object_init_handle (o, error); mono_error_assert_ok (error); // Restore domain in success and error path. if (domain != caller_domain) mono_domain_set_internal (caller_domain); goto_if_ok (error, exit); return_null: MONO_HANDLE_ASSIGN (o, NULL_HANDLE); exit: HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, o)); }
static MonoExceptionHandle mono_error_prepare_exception_handle (MonoError *oerror, MonoError *error_out) // Can fail with out-of-memory { HANDLE_FUNCTION_ENTER (); MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, mono_error_prepare_exception (oerror, error_out)); HANDLE_FUNCTION_RETURN_REF (MonoException, ex); }
/** * mono_get_exception_argument_internal: * \param type the actual type * \param arg the name of the argument that is invalid or null, etc. * \param msg optional message * \returns a new instance of the \c System.ArgumentException or derived */ static MonoException* mono_get_exception_argument_internal (const char *type, const char *arg, const char *msg) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MonoExceptionHandle ex = mono_exception_new_argument_internal (type, arg, msg, error); mono_error_cleanup (error); HANDLE_FUNCTION_RETURN_OBJ (ex); }
/** * mono_exception_from_name_domain: * \param domain Domain where the return object will be created. * \param image the Mono image where to look for the class * \param name_space the namespace for the class * \param name class name * * Creates an exception object of the given namespace/name class on * the given domain. * * \returns the initialized exception instance. */ MonoException * mono_exception_from_name_domain (MonoDomain *domain, MonoImage *image, const char* name_space, const char *name) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MonoExceptionHandle ret = mono_exception_new_by_name_domain (domain, image, name_space, name, error); mono_error_assert_ok (error); HANDLE_FUNCTION_RETURN_OBJ (ret); }
/** * mono_get_exception_file_not_found: * \param fname the name of the file not found. * \returns a new instance of the \c System.IO.FileNotFoundException */ MonoException * mono_get_exception_file_not_found (MonoString *fname_raw) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MONO_HANDLE_DCL (MonoString, fname); MonoExceptionHandle ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System.IO", "FileNotFoundException", fname, fname, error); mono_error_assert_ok (error); HANDLE_FUNCTION_RETURN_OBJ (ret); }
/** * mono_exception_from_token_two_strings: * * Same as mono_exception_from_name_two_strings, but lookup the exception class using * IMAGE and TOKEN. */ MonoException * mono_exception_from_token_two_strings (MonoImage *image, guint32 token, MonoString *arg1_raw, MonoString *arg2_raw) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MONO_HANDLE_DCL (MonoString, arg1); MONO_HANDLE_DCL (MonoString, arg2); MonoExceptionHandle ret = mono_exception_from_token_two_strings_checked (image, token, arg1, arg2, error); mono_error_cleanup (error); HANDLE_FUNCTION_RETURN_OBJ (ret); }
/** * mono_exception_from_name_two_strings: * \param image the Mono image where to look for the class * \param name_space the namespace for the class * \param name class name * \param a1 first string argument to pass * \param a2 second string argument to pass * * Creates an exception from a constructor that takes two string * arguments. * * \returns the initialized exception instance. */ MonoException * mono_exception_from_name_two_strings (MonoImage *image, const char *name_space, const char *name, MonoString *a1_raw, MonoString *a2_raw) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MONO_HANDLE_DCL (MonoString, a1); MONO_HANDLE_DCL (MonoString, a2); MonoExceptionHandle ret = mono_exception_from_name_two_strings_checked (image, name_space, name, a1, a2, error); mono_error_cleanup (error); HANDLE_FUNCTION_RETURN_OBJ (ret); }
/** * mono_get_exception_reflection_type_load: * \param types an array of types that were defined in the moduled loaded. * \param exceptions an array of exceptions that were thrown during the type loading. * \returns a new instance of the \c System.Reflection.ReflectionTypeLoadException */ MonoException * mono_get_exception_reflection_type_load (MonoArray *types_raw, MonoArray *exceptions_raw) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MONO_HANDLE_DCL (MonoArray, types); MONO_HANDLE_DCL (MonoArray, exceptions); MonoExceptionHandle ret = mono_get_exception_reflection_type_load_checked (types, exceptions, error); if (!is_ok (error)) ret = MONO_HANDLE_CAST (MonoException, mono_new_null ()); mono_error_cleanup (error); HANDLE_FUNCTION_RETURN_OBJ (ret); }
/** * mono_exception_from_name_msg: * \param image the Mono image where to look for the class * \param name_space the namespace for the class * \param name class name * \param msg the message to embed inside the exception * * Creates an exception and initializes its message field. * * \returns the initialized exception instance. */ MonoException * mono_exception_from_name_msg (MonoImage *image, const char *name_space, const char *name, const char *msg) { HANDLE_FUNCTION_ENTER (); MonoExceptionHandle ex; MONO_ENTER_GC_UNSAFE; ERROR_DECL (error); ex = mono_exception_new_by_name_msg (image, name_space, name, msg, error); mono_error_cleanup (error); MONO_EXIT_GC_UNSAFE; HANDLE_FUNCTION_RETURN_OBJ (ex); }
/** * mono_get_exception_type_initialization: * \param type_name the name of the type that failed to initialize. * \param inner the inner exception. * \returns a new instance of the \c System.TypeInitializationException */ MonoException * mono_get_exception_type_initialization (const gchar *type_name, MonoException* inner_raw) { HANDLE_FUNCTION_ENTER (); MONO_HANDLE_DCL (MonoException, inner); ERROR_DECL (error); MonoExceptionHandle ret = mono_get_exception_type_initialization_handle (type_name, inner, error); if (!is_ok (error)) { ret = MONO_HANDLE_CAST (MonoException, mono_new_null ()); mono_error_cleanup (error); } HANDLE_FUNCTION_RETURN_OBJ (ret); }
/** * mono_get_exception_runtime_wrapped: */ MonoException * mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception_raw) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MONO_HANDLE_DCL (MonoObject, wrapped_exception); MonoExceptionHandle ret = mono_get_exception_runtime_wrapped_handle (wrapped_exception, error); if (!is_ok (error)) { mono_error_cleanup (error); ret = MONO_HANDLE_CAST (MonoException, mono_new_null ()); } HANDLE_FUNCTION_RETURN_OBJ (ret); }
/** * mono_exception_from_name_two_strings_checked: * \param image the Mono image where to look for the class * \param name_space the namespace for the class * \param name class name * \param a1 first string argument to pass * \param a2 second string argument to pass * \param error set on error * * Creates an exception from a constructor that takes two string * arguments. * * \returns the initialized exception instance. On failure returns * NULL and sets \p error. */ MonoExceptionHandle mono_exception_from_name_two_strings_checked (MonoImage *image, const char *name_space, const char *name, MonoStringHandle a1, MonoStringHandle a2, MonoError *error) { HANDLE_FUNCTION_ENTER (); MonoClass *klass; error_init (error); klass = mono_class_load_from_name (image, name_space, name); HANDLE_FUNCTION_RETURN_REF (MonoException, create_exception_two_strings (klass, a1, a2, error)); }
/** * mono_get_exception_file_not_found2: * \param msg an informative message for the user. * \param fname the name of the file not found. * \returns a new instance of the \c System.IO.FileNotFoundException */ MonoException * mono_get_exception_file_not_found2 (const char *msg, MonoString *fname_raw) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MONO_HANDLE_DCL (MonoString, fname); MonoStringHandle s = NULL_HANDLE_STRING; if (msg) { s = mono_string_new_handle (mono_domain_get (), msg, error); mono_error_assert_ok (error); } MonoExceptionHandle ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System.IO", "FileNotFoundException", s, fname, error); mono_error_assert_ok (error); HANDLE_FUNCTION_RETURN_OBJ (ret); }
// For efficiency, call mono_error_set_pending_exception instead of mono_error_set_pending_exception_slow. gboolean mono_error_set_pending_exception_slow (MonoError *error) { if (is_ok (error)) return FALSE; HANDLE_FUNCTION_ENTER (); MonoExceptionHandle ex = mono_error_convert_to_exception_handle (error); gboolean const result = !MONO_HANDLE_IS_NULL (ex); if (result) mono_set_pending_exception_handle (ex); HANDLE_FUNCTION_RETURN_VAL (result); }
/** * mono_get_exception_missing_member: * \param exception_type the specific exception type for the specific member type, i.e. field or method * \param class_name the class where the lookup was performed. * \param member_name the name of the missing method. * \returns a new instance of the \c exception_type (MissingFieldException or MissingMethodException) */ static MonoException* mono_get_exception_missing_member (const char *exception_type, const char *class_name, const char *member_name) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MonoDomain * const domain = mono_domain_get (); MonoStringHandle s1 = mono_string_new_handle (domain, class_name, error); mono_error_assert_ok (error); MonoStringHandle s2 = mono_string_new_handle (domain, member_name, error); mono_error_assert_ok (error); MonoExceptionHandle ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", exception_type, s1, s2, error); mono_error_assert_ok (error); HANDLE_FUNCTION_RETURN_OBJ (ret); }
/** * mono_exception_from_token_two_strings_checked: * * Same as mono_exception_from_name_two_strings, but lookup the exception class using * IMAGE and TOKEN. */ MonoExceptionHandle mono_exception_from_token_two_strings_checked (MonoImage *image, guint32 token, MonoStringHandle a1, MonoStringHandle a2, MonoError *error) { HANDLE_FUNCTION_ENTER (); MonoClass *klass; error_init (error); klass = mono_class_get_checked (image, token, error); mono_error_assert_ok (error); /* FIXME handle the error. */ HANDLE_FUNCTION_RETURN_REF (MonoException, create_exception_two_strings (klass, a1, a2, error)); }
/** * mono_exception_from_token: * \param image the Mono image where to look for the class * \param token The type token of the class * * Creates an exception of the type given by \p token. * * \returns the initialized exception instance. */ MonoException * mono_exception_from_token (MonoImage *image, guint32 token) { HANDLE_FUNCTION_ENTER (); ERROR_DECL (error); MonoClass *klass; klass = mono_class_get_checked (image, token, error); mono_error_assert_ok (error); MonoObjectHandle o = mono_object_new_handle (mono_domain_get (), klass, error); mono_error_assert_ok (error); mono_runtime_object_init_handle (o, error); mono_error_assert_ok (error); HANDLE_FUNCTION_RETURN_OBJ (MONO_HANDLE_CAST (MonoException, o)); }
/** * mono_get_exception_type_load: * \param class_name the name of the class that could not be loaded * \param assembly_name the assembly where the class was looked up. * \returns a new instance of the \c System.TypeLoadException */ MonoException * mono_get_exception_type_load (MonoString *class_name_raw, char *assembly_name) { ERROR_DECL (error); HANDLE_FUNCTION_ENTER (); MONO_HANDLE_DCL (MonoString, class_name); MonoStringHandle s = NULL_HANDLE_STRING; MonoDomain * const domain = mono_domain_get (); if (assembly_name) { s = mono_string_new_handle (domain, assembly_name, error); mono_error_assert_ok (error); } else s = mono_string_empty_handle (domain); MonoExceptionHandle ret = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", "TypeLoadException", class_name, s, error); mono_error_assert_ok (error); HANDLE_FUNCTION_RETURN_OBJ (ret); }
MonoExceptionHandle mono_get_exception_type_initialization_handle (const gchar *type_name, MonoExceptionHandle inner, MonoError *error) { HANDLE_FUNCTION_ENTER (); MonoClass *klass; MonoMethod *method; gpointer iter; error_init (error); klass = mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException"); mono_class_init_internal (klass); iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if (!strcmp (".ctor", mono_method_get_name (method))) { MonoMethodSignature *sig = mono_method_signature_internal (method); if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_STRING && mono_class_from_mono_type_internal (sig->params [1]) == mono_defaults.exception_class) break; } method = NULL; } g_assert (method); MonoDomain * const domain = mono_domain_get (); MonoStringHandle type_name_str = mono_string_new_handle (domain, type_name, error); mono_error_assert_ok (error); gpointer args [ ] = { MONO_HANDLE_RAW (type_name_str), MONO_HANDLE_RAW (inner) }; MonoObjectHandle exc = mono_object_new_handle (domain, klass, error); mono_error_assert_ok (error); mono_runtime_invoke_handle (method, exc, args, error); goto_if_nok (error, return_null); goto exit; return_null: exc = mono_new_null (); exit: HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, exc)); }
MonoExceptionHandle mono_get_exception_reflection_type_load_checked (MonoArrayHandle types, MonoArrayHandle exceptions, MonoError *error) { HANDLE_FUNCTION_ENTER (); MonoClass *klass; MonoMethod *method; gpointer iter; error_init (error); klass = mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException"); mono_class_init_internal (klass); /* Find the Type[], Exception[] ctor */ iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if (!strcmp (".ctor", mono_method_get_name (method))) { MonoMethodSignature *sig = mono_method_signature_internal (method); if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_SZARRAY && sig->params [1]->type == MONO_TYPE_SZARRAY) break; } method = NULL; } g_assert (method); MonoExceptionHandle exc = MONO_HANDLE_CAST (MonoException, MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (mono_domain_get (), klass, error))); mono_error_assert_ok (error); gpointer args [ ] = { MONO_HANDLE_RAW (types), MONO_HANDLE_RAW (exceptions) }; mono_runtime_invoke_checked (method, MONO_HANDLE_RAW (exc), args, error); goto_if_nok (error, return_null); goto exit; return_null: exc = MONO_HANDLE_CAST (MonoException, mono_new_null ()); exit: HANDLE_FUNCTION_RETURN_REF (MonoException, exc); }
static MonoExceptionHandle create_exception_two_strings (MonoClass *klass, MonoStringHandle a1, MonoStringHandle a2, MonoError *error) { HANDLE_FUNCTION_ENTER (); MonoMethod *method = NULL; int const count = 1 + !MONO_HANDLE_IS_NULL (a2); gpointer iter; MonoMethod *m; MonoObjectHandle o = mono_object_new_handle (mono_domain_get (), klass, error); mono_error_assert_ok (error); iter = NULL; while ((m = mono_class_get_methods (klass, &iter))) { MonoMethodSignature *sig; if (strcmp (".ctor", mono_method_get_name (m))) continue; sig = mono_method_signature_internal (m); if (sig->param_count != count) continue; if (sig->params [0]->type != MONO_TYPE_STRING) continue; if (count == 2 && sig->params [1]->type != MONO_TYPE_STRING) continue; method = m; break; } gpointer args [ ] = { MONO_HANDLE_RAW (a1), MONO_HANDLE_RAW (a2) }; mono_runtime_invoke_handle (method, o, args, error); if (!is_ok (error)) o = mono_new_null (); HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, o)); }
/** * mono_exception_new_by_name_msg: * \param image the Mono image where to look for the class * \param name_space the namespace for the class * \param name class name * \param msg the message to embed inside the exception * * Creates an exception and initializes its message field. * * \returns the initialized exception instance. */ MonoExceptionHandle mono_exception_new_by_name_msg (MonoImage *image, const char *name_space, const char *name, const char *msg, MonoError *error) { HANDLE_FUNCTION_ENTER (); MonoExceptionHandle ex = mono_exception_new_by_name (image, name_space, name, error); goto_if_nok (error, return_null); if (msg) { MonoStringHandle msg_str = mono_string_new_handle (MONO_HANDLE_DOMAIN (ex), msg, error); // FIXME? Maybe just ignore this error, the exception is close to correct. goto_if_nok (error, return_null); // ex->message = msg_str; MONO_HANDLE_SET (ex, message, msg_str); } goto exit; return_null: MONO_HANDLE_ASSIGN (ex, NULL_HANDLE); exit: HANDLE_FUNCTION_RETURN_REF (MonoException, ex) }
static void mutex_handle_signal (MonoW32Handle *handle_data) { HANDLE_FUNCTION_ENTER (); MonoW32HandleMutex *mutex_handle; pthread_t tid; mutex_handle = (MonoW32HandleMutex*) handle_data->specific; mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: signalling %s handle %p, tid: %p recursion: %d", __func__, mono_w32handle_get_typename (handle_data->type), handle_data, (gpointer) mutex_handle->tid, mutex_handle->recursion); tid = pthread_self (); if (mutex_handle->abandoned) { mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: %s handle %p is abandoned", __func__, mono_w32handle_get_typename (handle_data->type), handle_data); } else if (!pthread_equal (mutex_handle->tid, tid)) { mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: we don't own %s handle %p (owned by %ld, me %ld)", __func__, mono_w32handle_get_typename (handle_data->type), handle_data, (long)mutex_handle->tid, (long)tid); } else { /* OK, we own this mutex */ mutex_handle->recursion--; if (mutex_handle->recursion == 0) { thread_disown_mutex (mono_thread_internal_current_handle (), handle_data); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: unlocking %s handle %p, tid: %p recusion : %d", __func__, mono_w32handle_get_typename (handle_data->type), handle_data, (gpointer) mutex_handle->tid, mutex_handle->recursion); mutex_handle->tid = 0; mono_w32handle_set_signal_state (handle_data, TRUE, FALSE); } } HANDLE_FUNCTION_RETURN (); }
MonoExceptionHandle mono_corlib_exception_new_with_args (const char *name_space, const char *name, const char *arg_0, const char *arg_1, MonoError *error) { HANDLE_FUNCTION_ENTER (); MonoStringHandle str_0 = NULL_HANDLE_STRING; MonoStringHandle str_1 = NULL_HANDLE_STRING; MonoExceptionHandle ex = MONO_HANDLE_CAST (MonoException, NULL_HANDLE); MonoDomain * const domain = mono_domain_get (); str_0 = arg_0 ? mono_string_new_handle (domain, arg_0, error) : NULL_HANDLE_STRING; goto_if_nok (error, return_null); str_1 = arg_1 ? mono_string_new_handle (domain, arg_1, error) : NULL_HANDLE_STRING; goto_if_nok (error, return_null); ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, name_space, name, str_0, str_1, error); goto exit; return_null: ex = MONO_HANDLE_CAST (MonoException, mono_new_null ()); exit: HANDLE_FUNCTION_RETURN_REF (MonoException, ex); }
static MonoStringHandle get_type_name_as_mono_string (MonoErrorInternal *error, MonoDomain *domain, MonoError *error_out) { HANDLE_FUNCTION_ENTER (); MonoStringHandle res = NULL_HANDLE_STRING; if (error->type_name) { res = string_new_cleanup (domain, error->type_name); } else { MonoClass *klass = get_class (error); if (klass) { char *name = mono_type_full_name (m_class_get_byval_arg (klass)); if (name) { res = string_new_cleanup (domain, name); g_free (name); } } } if (MONO_HANDLE_IS_NULL (res)) mono_error_set_out_of_memory (error_out, "Could not allocate type name"); HANDLE_FUNCTION_RETURN_REF (MonoString, res); }
/*Can fail with out-of-memory*/ MonoException* mono_error_prepare_exception (MonoError *oerror, MonoError *error_out) { HANDLE_FUNCTION_ENTER (); MonoErrorInternal *error = (MonoErrorInternal*)oerror; MonoExceptionHandle exception = MONO_HANDLE_CAST (MonoException, mono_new_null ()); MonoDomain *domain = mono_domain_get (); char *type_name = NULL; char *message = NULL; error_init (error_out); const guint16 error_code = error->error_code; g_assert (error_code != MONO_ERROR_CLEANUP_CALLED_SENTINEL); switch (error_code) { case MONO_ERROR_NONE: goto exit; case MONO_ERROR_MISSING_METHOD: exception = mono_corlib_exception_new_with_args ("System", "MissingMethodException", error->full_message, error->first_argument, error_out); break; case MONO_ERROR_BAD_IMAGE: exception = mono_corlib_exception_new_with_args ("System", "BadImageFormatException", error->full_message, error->first_argument, error_out); break; case MONO_ERROR_FILE_NOT_FOUND: exception = mono_corlib_exception_new_with_args ("System.IO", "FileNotFoundException", error->full_message, error->first_argument, error_out); break; case MONO_ERROR_MISSING_FIELD: exception = mono_corlib_exception_new_with_args ("System", "MissingFieldException", error->full_message, error->first_argument, error_out); break; case MONO_ERROR_MEMBER_ACCESS: exception = mono_exception_new_by_name_msg (mono_defaults.corlib, "System", "MemberAccessException", error->full_message, error_out); break; case MONO_ERROR_TYPE_LOAD: { MonoStringHandle assembly_name; MonoStringHandle type_name; if ((error->type_name && error->assembly_name) || error->exn.klass) { type_name = get_type_name_as_mono_string (error, domain, error_out); if (!mono_error_ok (error_out)) break; if (error->assembly_name) { assembly_name = string_new_cleanup (domain, error->assembly_name); if (MONO_HANDLE_IS_NULL (assembly_name)) { mono_error_set_out_of_memory (error_out, "Could not allocate assembly name"); break; } } else { assembly_name = mono_string_empty_handle (domain); } exception = mono_exception_from_name_two_strings_checked (mono_get_corlib (), "System", "TypeLoadException", type_name, assembly_name, error_out); if (!MONO_HANDLE_IS_NULL (exception)) { const char *full_message = error->full_message; if (full_message && full_message [0]) { MonoStringHandle msg = string_new_cleanup (mono_domain_get (), full_message); if (!MONO_HANDLE_IS_NULL (msg)) MONO_HANDLE_SET (exception, message, msg); else mono_error_set_out_of_memory (error_out, "Could not allocate exception object"); } } } else { exception = mono_exception_new_by_name_msg (mono_defaults.corlib, "System", "TypeLoadException", error->full_message, error_out); } } break; case MONO_ERROR_OUT_OF_MEMORY: if (domain) exception = MONO_HANDLE_NEW (MonoException, domain->out_of_memory_ex); if (MONO_HANDLE_IS_NULL (exception)) exception = mono_get_exception_out_of_memory_handle (); break; case MONO_ERROR_ARGUMENT: exception = mono_exception_new_argument (error->first_argument, error->full_message, error_out); break; case MONO_ERROR_ARGUMENT_NULL: exception = mono_exception_new_argument_null (error->first_argument, error_out); break; case MONO_ERROR_ARGUMENT_OUT_OF_RANGE: exception = mono_exception_new_argument_out_of_range(error->first_argument, error->full_message, error_out); break; case MONO_ERROR_NOT_VERIFIABLE: if (error->exn.klass) { type_name = mono_type_get_full_name (error->exn.klass); if (!type_name) goto out_of_memory; } message = g_strdup_printf ("Error in %s:%s %s", type_name, error->member_name, error->full_message); if (!message) goto out_of_memory; exception = mono_exception_new_by_name_msg (mono_defaults.corlib, "System.Security", "VerificationException", message, error_out); break; case MONO_ERROR_GENERIC: if (!error->exception_name_space || !error->exception_name) mono_error_set_execution_engine (error_out, "MonoError with generic error but no exception name was supplied"); else exception = mono_exception_new_by_name_msg (mono_defaults.corlib, error->exception_name_space, error->exception_name, error->full_message, error_out); break; case MONO_ERROR_EXCEPTION_INSTANCE: exception = MONO_HANDLE_CAST (MonoException, mono_gchandle_get_target_handle (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: exception = mono_exception_new_by_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", (error->flags & MONO_ERROR_INCOMPLETE) ? "" : error->full_message, error_out); break; default: mono_error_set_execution_engine (error_out, "Invalid error-code %d", error->error_code); } if (!mono_error_ok (error_out)) goto return_null; if (MONO_HANDLE_IS_NULL (exception)) mono_error_set_out_of_memory (error_out, "Could not allocate exception object"); goto exit; out_of_memory: mono_error_set_out_of_memory (error_out, "Could not allocate message"); goto exit; return_null: exception = MONO_HANDLE_CAST (MonoException, mono_new_null ()); exit: g_free (message); g_free (type_name); HANDLE_FUNCTION_RETURN_OBJ (exception); }