2003-12-20 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / metadata / exception.c
1 /*
2  * exception.c: Exception handling
3  *
4  * Authors:
5  *      Paolo Molaro    (lupus@ximian.com)
6  *      Dietmar Maurer  (dietmar@ximian.com)
7  *      Dick Porter     (dick@ximian.com)
8  *      Miguel de Icaza (miguel@ximian.com)
9  *
10  * (C) 2001, 2002 Ximian, Inc.
11  */
12
13 #include <mono/metadata/exception.h>
14 #include <mono/metadata/class.h>
15 #include <mono/metadata/appdomain.h>
16 #include <string.h>
17
18 /**
19  * mono_exception_from_name:
20  * @image: the Mono image where to look for the class
21  * @name_space: the namespace for the class
22  * @name: class name
23  *
24  * Creates an exception of the given namespace/name class.
25  *
26  * Returns: the initialized exception instance.
27  */
28 MonoException *
29 mono_exception_from_name (MonoImage *image, const char *name_space,
30                           const char *name)
31 {
32         return mono_exception_from_name_domain (mono_domain_get (), image, name_space, name);
33 }
34
35 MonoException *
36 mono_exception_from_name_domain (MonoDomain *domain,
37                                                                  MonoImage *image, 
38                                                                  const char* name_space, 
39                                                                  const char *name)
40 {
41         MonoClass *klass;
42         MonoObject *o;
43
44         klass = mono_class_from_name (image, name_space, name);
45
46         o = mono_object_new (domain, klass);
47         g_assert (o != NULL);
48         
49         mono_runtime_object_init (o);
50
51         return (MonoException *)o;
52 }
53
54 /**
55  * mono_exception_from_name_two_strings:
56  * @image: the Mono image where to look for the class
57  * @name_space: the namespace for the class
58  * @name: class name
59  * @a1: first string argument to pass
60  * @a2: second string argument to pass
61  *
62  * Creates an exception from a constructor that takes two string
63  * arguments.
64  *
65  * Returns: the initialized exception instance.
66  */
67 static MonoException *
68 mono_exception_from_name_two_strings (MonoImage *image, const char *name_space,
69                                                                           const char *name, MonoString *a1, MonoString *a2)
70 {
71         MonoDomain *domain = mono_domain_get ();
72         MonoClass *klass;
73         MonoMethod *method = NULL;
74         MonoObject *o;
75         int i;
76         gpointer args [2];
77         
78         klass = mono_class_from_name (image, name_space, name);
79         o = mono_object_new (domain, klass);
80
81         for (i = 0; i < klass->method.count; ++i) {
82                 MonoMethodSignature *sig;
83                 
84                 if (strcmp (".ctor", klass->methods [i]->name))
85                         continue;
86                 sig = klass->methods [i]->signature;
87                 if (sig->param_count != 2)
88                         continue;
89
90                 if (sig->params [0]->type != MONO_TYPE_STRING ||
91                     sig->params [1]->type != MONO_TYPE_STRING)
92                         continue;
93                 method = klass->methods [i];
94         }
95
96         args [0] = a1;
97         args [1] = a2;
98         mono_runtime_invoke (method, o, args, NULL);
99         return (MonoException *) o;
100 }
101
102 /**
103  * mono_exception_from_name_msg:
104  * @image: the Mono image where to look for the class
105  * @name_space: the namespace for the class
106  * @name: class name
107  * @msg: the message to embed inside the exception
108  *
109  * Creates an exception and initializes its message field.
110  *
111  * Returns: the initialized exception instance.
112  */
113 static MonoException *
114 mono_exception_from_name_msg (MonoImage *image, const char *name_space,
115                                                           const char *name, const guchar *msg)
116 {
117         MonoException *ex;
118         MonoDomain *domain;
119
120     ex = mono_exception_from_name (image, name_space, name);
121
122         domain = ((MonoObject *)ex)->vtable->domain;
123
124         if (msg)
125                 ex->message = mono_string_new (domain, msg);
126
127         return ex;
128 }
129
130 MonoException *
131 mono_get_exception_divide_by_zero ()
132 {
133         return mono_exception_from_name (mono_defaults.corlib, "System",
134                                          "DivideByZeroException");
135 }
136
137 MonoException *
138 mono_get_exception_security ()
139 {
140         return mono_exception_from_name (mono_defaults.corlib, "System",
141                                          "SecurityException");
142 }
143
144 MonoException *
145 mono_get_exception_thread_abort ()
146 {
147         return mono_exception_from_name (mono_defaults.corlib, "System.Threading",
148                                          "ThreadAbortException");
149 }
150
151 MonoException *
152 mono_get_exception_arithmetic ()
153 {
154         return mono_exception_from_name (mono_defaults.corlib, "System",
155                                          "ArithmeticException");
156 }
157
158 MonoException *
159 mono_get_exception_overflow ()
160 {
161         return mono_exception_from_name (mono_defaults.corlib, "System",
162                                          "OverflowException");
163 }
164
165 MonoException *
166 mono_get_exception_null_reference ()
167 {
168         return mono_exception_from_name (mono_defaults.corlib, "System",
169                                          "NullReferenceException");
170 }
171
172 MonoException *
173 mono_get_exception_execution_engine (const guchar *msg)
174 {
175         return mono_exception_from_name_msg (mono_defaults.corlib, "System",
176                                                                                  "ExecutionEngineException", msg);
177 }
178
179 MonoException *
180 mono_get_exception_serialization (const guchar *msg)
181 {
182         return mono_exception_from_name_msg (mono_defaults.corlib, "System.Runtime.Serialization",
183                                                                                  "SerializationException", msg);
184 }
185
186 MonoException *
187 mono_get_exception_invalid_cast ()
188 {
189         return mono_exception_from_name (mono_defaults.corlib, "System",
190                                          "InvalidCastException");
191 }
192
193 MonoException *
194 mono_get_exception_index_out_of_range ()
195 {
196         return mono_exception_from_name (mono_defaults.corlib, "System",
197                                          "IndexOutOfRangeException");
198 }
199
200 MonoException *
201 mono_get_exception_array_type_mismatch ()
202 {
203         return mono_exception_from_name (mono_defaults.corlib, "System",
204                                          "ArrayTypeMismatchException");
205 }
206
207 MonoException *
208 mono_get_exception_type_load (MonoString *type_name)
209 {
210         MonoTypeLoadException *exc;
211         
212         exc = (MonoTypeLoadException *) mono_exception_from_name (mono_defaults.corlib,
213                                         "System",
214                                         "TypeLoadException");
215
216         exc->type_name = type_name;
217         return (MonoException *) exc;
218 }
219
220 MonoException *
221 mono_get_exception_not_implemented ()
222 {
223         return mono_exception_from_name (mono_defaults.corlib, "System",
224                                          "NotImplementedException");
225 }
226
227 MonoException *
228 mono_get_exception_missing_method ()
229 {
230         return mono_exception_from_name (mono_defaults.corlib, "System",
231                                          "MissingMethodException");
232 }
233
234 MonoException*
235 mono_get_exception_argument_null (const guchar *arg)
236 {
237         MonoException *ex;
238         MonoDomain *domain;
239
240         ex = mono_exception_from_name ( 
241                 mono_defaults.corlib, "System", "ArgumentNullException");
242
243         domain = ((MonoObject *)ex)->vtable->domain;
244
245         if (arg)
246                 ((MonoArgumentException *)ex)->param_name =
247                         mono_string_new (domain, arg);
248         
249         return ex;
250 }
251
252 MonoException *
253 mono_get_exception_argument (const guchar *arg, const guchar *msg)
254 {
255         MonoException *ex;
256         MonoDomain *domain;
257
258         ex = mono_exception_from_name_msg (
259                 mono_defaults.corlib, "System", "ArgumentException", msg);
260
261         domain = ((MonoObject *)ex)->vtable->domain;
262
263         if (arg)
264                 ((MonoArgumentException *)ex)->param_name =
265                         mono_string_new (domain, arg);
266         
267         return ex;
268 }
269
270 MonoException *
271 mono_get_exception_argument_out_of_range (const guchar *arg)
272 {
273         MonoException *ex;
274         MonoDomain *domain;
275
276         ex = mono_exception_from_name (
277                 mono_defaults.corlib, "System", "ArgumentOutOfRangeException");
278
279         domain = ((MonoObject *)ex)->vtable->domain;
280
281         if (arg)
282                 ((MonoArgumentException *)ex)->param_name =
283                         mono_string_new (domain, arg);
284         
285         return ex;
286 }
287
288 MonoException *
289 mono_get_exception_thread_state (const guchar *msg)
290 {
291         return mono_exception_from_name_msg (mono_defaults.corlib, 
292                                                                                  "System.Threading", "ThreadStateException",
293                                                                                  msg);
294 }
295
296 MonoException *
297 mono_get_exception_io (const guchar *msg)
298 {
299         return mono_exception_from_name_msg ( 
300                 mono_defaults.corlib, "System.IO", "IOException", msg);
301 }
302
303 MonoException *
304 mono_get_exception_file_not_found (MonoString *fname)
305 {
306         return mono_exception_from_name_two_strings (
307                 mono_defaults.corlib, "System.IO", "FileNotFoundException", fname, fname);
308 }
309
310 MonoException *
311 mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner)
312 {
313         MonoClass *klass;
314         gpointer args [2];
315         MonoObject *exc;
316         MonoMethod *method;
317         gint i;
318
319         klass = mono_class_from_name (mono_defaults.corlib, "System", "TypeInitializationException");
320         g_assert (klass);
321
322         mono_class_init (klass);
323
324         /* TypeInitializationException only has 1 ctor with 2 args */
325         for (i = 0; i < klass->method.count; ++i) {
326                 method = klass->methods [i];
327                 if (!strcmp (".ctor", method->name) && method->signature->param_count == 2)
328                         break;
329                 method = NULL;
330         }
331
332         g_assert (method);
333
334         args [0] = mono_string_new (mono_domain_get (), type_name);
335         args [1] = inner;
336
337         exc = mono_object_new (mono_domain_get (), klass);
338         mono_runtime_invoke (method, exc, args, NULL);
339
340         return (MonoException *) exc;
341 }
342
343 MonoException *
344 mono_get_exception_synchronization_lock (const guchar *msg)
345 {
346         return mono_exception_from_name_msg (mono_defaults.corlib, "System.Threading", "SynchronizationLockException", msg);
347 }
348
349 MonoException *
350 mono_get_exception_cannot_unload_appdomain (const guchar *msg)
351 {
352         return mono_exception_from_name_msg (mono_defaults.corlib, "System", "CannotUnloadAppDomainException", msg);
353 }
354
355 MonoException *
356 mono_get_exception_appdomain_unloaded (void)
357 {
358         return mono_exception_from_name (mono_defaults.corlib, "System", "AppDomainUnloadedException");
359 }
360
361 MonoException *
362 mono_get_exception_bad_image_format (const guchar *msg)
363 {
364         return mono_exception_from_name_msg (mono_defaults.corlib, "System", "BadImageFormatException", msg);
365 }