5 #ifndef __MONO_ERROR_INTERNALS_H__
6 #define __MONO_ERROR_INTERNALS_H__
8 #include <mono/metadata/object-forward.h>
9 #include "mono/utils/mono-compiler.h"
11 /*Keep in sync with MonoError*/
13 unsigned short error_code
;
16 /*These name are suggestions of their content. MonoError internals might use them for something else.*/
17 const char *type_name
;
18 const char *assembly_name
;
19 const char *member_name
;
20 const char *exception_name_space
;
21 const char *exception_name
;
23 /* Valid if error_code != MONO_ERROR_EXCEPTION_INSTANCE.
24 * Used by type or field load errors and generic error specified by class.
27 /* Valid if error_code == MONO_ERROR_EXCEPTION_INSTANCE.
28 * Generic error specified by a managed instance.
30 uint32_t instance_handle
;
32 const char *full_message
;
33 const char *full_message_with_fields
;
34 const char *first_argument
;
39 /* Invariant: the error strings are allocated in the mempool of the given image */
40 struct _MonoErrorBoxed
{
46 Historically MonoError initialization was deferred, but always had to occur,
47 even in success paths, as cleanup could be done unconditionally.
51 This is the overwhelmingly common case.
52 Declare and initialize a local variable, named "error",
53 pointing to an initialized MonoError (named "error_value",
56 ERROR_DECL_VALUE (foo)
57 Declare and initialize a local variable, named "foo";
58 no pointer is produced for it.
61 This is used for MonoError in/out parameter on a public interface,
62 which must be presumed uninitialized. These are often
63 marked with MONO_API, MONO_RT_EXTERNAL_ONLY, MONO_PROFILER_API, etc.
64 Tnis includes functions called from dis, profiler, pedump, and driver.
65 dis, profiler, and pedump make sense, these are actually external and
66 uninitialized. Driver less so.
69 Initialize a MonoError. These are historical and usually
70 but not always redundant, and should be reduced/eliminated.
71 All the non-redundant ones should be renamed and all the redundant
75 This indicates an error has been cleaned up and will be reused.
76 Consider also changing mono_error_cleanup to call error_init_internal,
77 and then remove these.
80 Rare cases without a better name.
81 For example, setting up an icall frame, or initializing member data.
84 A zeroed MonoError is valid and initialized.
85 Zeroing an entire MonoError is overkill, unless it is near other
88 All initialization is actually bottlenecked to error_init_internal.
89 Different names indicate different scenarios, but the same code.
91 #define ERROR_DECL_VALUE(x) MonoError x; error_init_internal (&x)
92 #define ERROR_DECL(x) ERROR_DECL_VALUE (x##_value); MonoError * const x = &x##_value
93 #define error_init_internal(error) ((void)((error)->init = 0))
94 #define MONO_API_ERROR_INIT(error) error_init_internal (error)
95 #define error_init_reuse(error) error_init_internal (error)
97 // Historical deferred initialization was called error_init.
99 // possible bug detection that did not work
100 //#define error_init(error) (is_ok (error))
102 // FIXME Eventually all error_init should be removed, however it is prudent
103 // to leave them in for now, at least most of them, while we sort out
104 // the few that are needed and to experiment with adding them back in bulk,
105 // i.e. in an entire source file. Some are obviously not needed.
106 //#define error_init(error) // nothing
107 #define error_init(error) error_init_internal (error)
108 // Function for experimentation, should go away.
109 //void error_init(MonoError*);
111 #define is_ok(error) ((error)->error_code == MONO_ERROR_NONE)
113 #define return_if_nok(error) do { if (!is_ok ((error))) return; } while (0)
114 #define return_val_if_nok(error,val) do { if (!is_ok ((error))) return (val); } while (0)
116 #define goto_if(expr, label) do { if (expr) goto label; } while (0)
117 #define goto_if_ok(error, label) goto_if (is_ok (error), label)
118 #define goto_if_nok(error, label) goto_if (!is_ok (error), label)
120 /* Only use this in icalls */
121 #define return_val_and_set_pending_if_nok(error, value) \
123 if (mono_error_set_pending_exception ((error))) \
128 * Three macros to assert that a MonoError is ok:
129 * 1. mono_error_assert_ok(e) when you just want to print the error's message on failure
130 * 2. mono_error_assert_ok(e,msg) when you want to print "msg, due to <e's message>"
131 * 3. mono_error_assertf_ok(e,fmt,args...) when you want to print "<formatted msg>, due to <e's message>"
132 * (fmt should specify the formatting just for args).
134 * What's the difference between mono_error_assert_msg_ok (e, "foo") and
135 * mono_error_assertf_ok (e, "foo") ? The former works as you expect, the
136 * latter unhelpfully expands to
138 * g_assertf (is_ok (e), "foo, due to %s", , mono_error_get_message (err)).
140 * Note the double commas. Turns out that to get rid of that extra comma
141 * portably we would have to write really ugly preprocessor macros.
143 #define mono_error_assert_ok(error) g_assertf (is_ok (error), "%s", mono_error_get_message (error))
144 #define mono_error_assert_msg_ok(error, msg) g_assertf (is_ok (error), msg ", due to %s", mono_error_get_message (error))
145 #define mono_error_assertf_ok(error, fmt, ...) g_assertf (is_ok (error), fmt ", due to %s", __VA_ARGS__, mono_error_get_message (error))
148 mono_error_dup_strings (MonoError
*error
, gboolean dup_strings
);
150 /* This function is not very useful as you can't provide any details beyond the message.*/
152 mono_error_set_error (MonoError
*error
, int error_code
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(3,4);
155 mono_error_set_type_load_class (MonoError
*error
, MonoClass
*klass
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(3,4);
158 mono_error_vset_type_load_class (MonoError
*error
, MonoClass
*klass
, const char *msg_format
, va_list args
);
161 mono_error_set_type_load_name (MonoError
*error
, const char *type_name
, const char *assembly_name
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(4,5);
164 mono_error_set_out_of_memory (MonoError
*error
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
167 mono_error_set_argument (MonoError
*error
, const char *argument
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(3,4);
170 mono_error_set_argument_null (MonoError
*oerror
, const char *argument
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(3,4);
173 mono_error_set_not_verifiable (MonoError
*oerror
, MonoMethod
*method
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(3,4);
176 mono_error_set_generic_error (MonoError
*error
, const char * name_space
, const char *name
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(4,5);
179 mono_error_set_execution_engine (MonoError
*error
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
182 mono_error_set_not_implemented (MonoError
*error
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
185 mono_error_set_not_supported (MonoError
*error
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
188 mono_error_set_invalid_operation (MonoError
*error
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
191 mono_error_set_exception_instance (MonoError
*error
, MonoException
*exc
);
194 mono_error_set_invalid_program (MonoError
*oerror
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
197 mono_error_set_member_access (MonoError
*error
, const char *msg_format
, ...) MONO_ATTR_FORMAT_PRINTF(2,3);
200 mono_error_set_invalid_cast (MonoError
*oerror
);
203 mono_error_set_remoting (MonoError
*error
, const char *message
)
205 mono_error_set_generic_error (error
, "System.Runtime.Remoting", "RemotingException", "%s", message
);
209 mono_error_set_divide_by_zero (MonoError
*error
)
211 mono_error_set_generic_error (error
, "System", "DivideByZeroException", "");
215 mono_error_set_index_out_of_range (MonoError
*error
)
217 mono_error_set_generic_error (error
, "System", "IndexOutOfRangeException", "");
221 mono_error_set_overflow (MonoError
*error
)
223 mono_error_set_generic_error (error
, "System", "OverflowException", "");
227 mono_error_set_synchronization_lock (MonoError
*error
, const char *message
)
229 mono_error_set_generic_error (error
, "System.Threading", "SynchronizationLockException", "%s", message
);
233 mono_error_set_thread_interrupted (MonoError
*error
)
235 mono_error_set_generic_error (error
, "System.Threading", "ThreadInterruptedException", "");
239 mono_error_set_null_reference (MonoError
*error
)
241 mono_error_set_generic_error (error
, "System", "NullReferenceException", "");
245 mono_error_set_argument_out_of_range (MonoError
*error
, const char *name
);
248 mono_error_prepare_exception (MonoError
*error
, MonoError
*error_out
);
251 mono_error_convert_to_exception (MonoError
*error
);
254 mono_error_move (MonoError
*dest
, MonoError
*src
);
257 mono_error_box (const MonoError
*error
, MonoImage
*image
);
260 mono_error_set_from_boxed (MonoError
*error
, const MonoErrorBoxed
*from
);
263 mono_error_get_exception_name (MonoError
*oerror
);
266 mono_error_set_specific (MonoError
*error
, int error_code
, const char *missing_method
);
269 mono_error_set_first_argument (MonoError
*oerror
, const char *first_argument
);