/** * mono_error_set_from_boxed: * \param oerror The error that will be set to the contents of the box. * \param box A mempool-allocated error. * Sets the error condition in the oerror from the contents of the * given boxed error. Does not alter the boxed error, so it can be * used in a future call to \c mono_error_set_from_boxed as needed. The * \p oerror should've been previously initialized with \c mono_error_init, * as usual. * \returns TRUE on success or FALSE on failure. */ gboolean mono_error_set_from_boxed (MonoError *oerror, const MonoErrorBoxed *box) { MonoErrorInternal* to = (MonoErrorInternal*)oerror; MonoErrorInternal* from = (MonoErrorInternal*)&box->error; g_assert (!is_managed_exception (from)); mono_error_prepare (to); to->flags |= MONO_ERROR_FREE_STRINGS; #define DUP_STR(field) do { \ if (from->field) { \ if (!(to->field = g_strdup (from->field))) \ to->flags |= MONO_ERROR_INCOMPLETE; \ } else { \ to->field = NULL; \ } \ } while (0) to->error_code = from->error_code; DUP_STR (type_name); DUP_STR (assembly_name); DUP_STR (member_name); DUP_STR (exception_name_space); DUP_STR (exception_name); DUP_STR (full_message); DUP_STR (full_message_with_fields); DUP_STR (first_argument); to->exn.klass = from->exn.klass; #undef DUP_STR return (to->flags & MONO_ERROR_INCOMPLETE) == 0 ; }
/** * mono_error_box: * \param ierror The input error that will be boxed. * \param image The mempool of this image will hold the boxed error. * Creates a new boxed error in the given mempool from \c MonoError. * It does not alter \p ierror, so you still have to clean it up with * \c mono_error_cleanup or \c mono_error_convert_to_exception or another such function. * \returns the boxed error, or NULL if the mempool could not allocate. */ MonoErrorBoxed* mono_error_box (const MonoError *ierror, MonoImage *image) { MonoErrorInternal *from = (MonoErrorInternal*)ierror; /* Don't know how to box a gchandle */ g_assert (!is_managed_exception (from)); MonoErrorBoxed* box = (MonoErrorBoxed*)mono_image_alloc (image, sizeof (MonoErrorBoxed)); box->image = image; mono_error_init_flags (&box->error, MONO_ERROR_MEMPOOL_BOXED); MonoErrorInternal *to = (MonoErrorInternal*)&box->error; #define DUP_STR(field) do { \ if (from->field) { \ if (!(to->field = mono_image_strdup (image, from->field))) \ to->flags |= MONO_ERROR_INCOMPLETE; \ } else { \ to->field = NULL; \ } \ } while (0) to->error_code = from->error_code; DUP_STR (type_name); DUP_STR (assembly_name); DUP_STR (member_name); DUP_STR (exception_name_space); DUP_STR (exception_name); DUP_STR (full_message); DUP_STR (full_message_with_fields); DUP_STR (first_argument); to->exn.klass = from->exn.klass; #undef DUP_STR return box; }
static void mono_error_set_class (MonoError *oerror, MonoClass *klass) { MonoErrorInternal *error = (MonoErrorInternal*)oerror; if (is_managed_exception (error)) return; error->exn.klass = klass; }
static MonoClass* get_class (MonoErrorInternal *error) { MonoClass *klass = NULL; if (is_managed_exception (error)) klass = mono_object_class (mono_gchandle_get_target (error->exn.instance_handle)); else klass = error->exn.klass; return klass; }
void mono_error_cleanup (MonoError *oerror) { MonoErrorInternal *error = (MonoErrorInternal*)oerror; 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); /* Mempool stored error shouldn't be cleaned up */ g_assert (!is_boxed (error)); /* 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 (has_instance_handle) mono_gchandle_free (error->exn.instance_handle); g_free ((char*)error->full_message); g_free ((char*)error->full_message_with_fields); 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->assembly_name); g_free ((char*)error->member_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; }
void mono_error_cleanup (MonoError *oerror) { MonoErrorInternal *error = (MonoErrorInternal*)oerror; if (error->error_code == MONO_ERROR_NONE) return; if (is_managed_exception (error)) 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 return; g_free ((char*)error->type_name); g_free ((char*)error->assembly_name); g_free ((char*)error->member_name); g_free ((char*)error->exception_name_space); g_free ((char*)error->exception_name); g_free ((char*)error->first_argument); }