383d4ea84cb6e4796174cbdfa5f5c73cd4841eae
[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/object-internals.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, MonoImage *image, 
37                                  const char* name_space, const char *name)
38 {
39         MonoClass *klass;
40         MonoObject *o;
41
42         klass = mono_class_from_name (image, name_space, name);
43
44         o = mono_object_new (domain, klass);
45         g_assert (o != NULL);
46         
47         mono_runtime_object_init (o);
48
49         return (MonoException *)o;
50 }
51
52
53 /**
54  * mono_exception_from_token:
55  * @image: the Mono image where to look for the class
56  * @token: The type token of the class
57  *
58  * Creates an exception of the type given by @token.
59  *
60  * Returns: the initialized exception instance.
61  */
62 MonoException *
63 mono_exception_from_token (MonoImage *image, guint32 token)
64 {
65         MonoClass *klass;
66         MonoObject *o;
67
68         klass = mono_class_get (image, token);
69
70         o = mono_object_new (mono_domain_get (), klass);
71         g_assert (o != NULL);
72         
73         mono_runtime_object_init (o);
74
75         return (MonoException *)o;
76 }
77
78 /**
79  * mono_exception_from_name_two_strings:
80  * @image: the Mono image where to look for the class
81  * @name_space: the namespace for the class
82  * @name: class name
83  * @a1: first string argument to pass
84  * @a2: second string argument to pass
85  *
86  * Creates an exception from a constructor that takes two string
87  * arguments.
88  *
89  * Returns: the initialized exception instance.
90  */
91 MonoException *
92 mono_exception_from_name_two_strings (MonoImage *image, const char *name_space,
93                                       const char *name, MonoString *a1, MonoString *a2)
94 {
95         MonoDomain *domain = mono_domain_get ();
96         MonoClass *klass;
97         MonoMethod *method = NULL;
98         MonoObject *o;
99         int count = 1;
100         gpointer args [2];
101         gpointer iter;
102         MonoMethod *m;
103
104         if (a2 != NULL)
105                 count++;
106         
107         klass = mono_class_from_name (image, name_space, name);
108         o = mono_object_new (domain, klass);
109
110         iter = NULL;
111         while ((m = mono_class_get_methods (klass, &iter))) {
112                 MonoMethodSignature *sig;
113                 
114                 if (strcmp (".ctor", mono_method_get_name (m)))
115                         continue;
116                 sig = mono_method_signature (m);
117                 if (sig->param_count != count)
118                         continue;
119
120                 if (sig->params [0]->type != MONO_TYPE_STRING)
121                         continue;
122                 if (count == 2 && sig->params [1]->type != MONO_TYPE_STRING)
123                         continue;
124                 method = m;
125         }
126
127         args [0] = a1;
128         args [1] = a2;
129         mono_runtime_invoke (method, o, args, NULL);
130         return (MonoException *) o;
131 }
132
133 /**
134  * mono_exception_from_name_msg:
135  * @image: the Mono image where to look for the class
136  * @name_space: the namespace for the class
137  * @name: class name
138  * @msg: the message to embed inside the exception
139  *
140  * Creates an exception and initializes its message field.
141  *
142  * Returns: the initialized exception instance.
143  */
144 MonoException *
145 mono_exception_from_name_msg (MonoImage *image, const char *name_space,
146                               const char *name, const char *msg)
147 {
148         MonoException *ex;
149
150         ex = mono_exception_from_name (image, name_space, name);
151
152         if (msg)
153                 ex->message = mono_string_new (mono_object_get_domain ((MonoObject*)ex), msg);
154
155         return ex;
156 }
157
158 MonoException *
159 mono_get_exception_divide_by_zero ()
160 {
161         return mono_exception_from_name (mono_get_corlib (), "System",
162                                          "DivideByZeroException");
163 }
164
165 MonoException *
166 mono_get_exception_security ()
167 {
168         return mono_exception_from_name (mono_get_corlib (), "System.Security",
169                                          "SecurityException");
170 }
171
172 MonoException *
173 mono_get_exception_thread_abort ()
174 {
175         return mono_exception_from_name (mono_get_corlib (), "System.Threading",
176                                          "ThreadAbortException");
177 }
178
179 MonoException *
180 mono_get_exception_arithmetic ()
181 {
182         return mono_exception_from_name (mono_get_corlib (), "System",
183                                          "ArithmeticException");
184 }
185
186 MonoException *
187 mono_get_exception_overflow ()
188 {
189         return mono_exception_from_name (mono_get_corlib (), "System",
190                                          "OverflowException");
191 }
192
193 MonoException *
194 mono_get_exception_null_reference ()
195 {
196         return mono_exception_from_name (mono_get_corlib (), "System",
197                                          "NullReferenceException");
198 }
199
200 MonoException *
201 mono_get_exception_execution_engine (const char *msg)
202 {
203         return mono_exception_from_name_msg (mono_get_corlib (), "System",
204                                                                                  "ExecutionEngineException", msg);
205 }
206
207 MonoException *
208 mono_get_exception_serialization (const char *msg)
209 {
210         return mono_exception_from_name_msg (mono_get_corlib (), "System.Runtime.Serialization",
211                                                                                  "SerializationException", msg);
212 }
213
214 MonoException *
215 mono_get_exception_invalid_cast ()
216 {
217         return mono_exception_from_name (mono_get_corlib (), "System",
218                                          "InvalidCastException");
219 }
220
221 MonoException *
222 mono_get_exception_invalid_operation (const char *msg)
223 {
224         return mono_exception_from_name_msg (mono_get_corlib (), "System",
225                                         "InvalidOperationException", msg);
226 }
227
228 MonoException *
229 mono_get_exception_index_out_of_range ()
230 {
231         return mono_exception_from_name (mono_get_corlib (), "System",
232                                          "IndexOutOfRangeException");
233 }
234
235 MonoException *
236 mono_get_exception_array_type_mismatch ()
237 {
238         return mono_exception_from_name (mono_get_corlib (), "System",
239                                          "ArrayTypeMismatchException");
240 }
241
242 MonoException *
243 mono_get_exception_type_load (MonoString *class_name, char *assembly_name)
244 {
245         MonoString *s = assembly_name ? mono_string_new (mono_domain_get (), assembly_name) : mono_string_new (mono_domain_get (), "");
246
247         return mono_exception_from_name_two_strings (mono_get_corlib (), "System",
248                                                                                                  "TypeLoadException", class_name, s);
249 }
250
251 MonoException *
252 mono_get_exception_not_implemented (const char *msg)
253 {
254         MonoException *ex;
255         
256         ex = mono_exception_from_name (mono_get_corlib (), "System",
257                                        "NotImplementedException");
258
259         if (msg)
260                 ex->message = mono_string_new (mono_object_get_domain ((MonoObject*)ex), msg);
261
262         return ex;
263 }
264
265 MonoException *
266 mono_get_exception_missing_method (const char *class_name, const char *member_name)
267 {
268         MonoString *s1 = mono_string_new (mono_domain_get (), class_name);
269         MonoString *s2 = mono_string_new (mono_domain_get (), member_name);
270
271         return mono_exception_from_name_two_strings (mono_get_corlib (), "System",
272                                                                                                  "MissingMethodException", s1, s2);
273 }
274
275 MonoException *
276 mono_get_exception_missing_field (const char *class_name, const char *member_name)
277 {
278         MonoString *s1 = mono_string_new (mono_domain_get (), class_name);
279         MonoString *s2 = mono_string_new (mono_domain_get (), member_name);
280
281         return mono_exception_from_name_two_strings (mono_get_corlib (), "System",
282                                                                                                  "MissingFieldException", s1, s2);
283 }
284
285 MonoException*
286 mono_get_exception_argument_null (const char *arg)
287 {
288         MonoException *ex;
289
290         ex = mono_exception_from_name ( 
291                 mono_get_corlib (), "System", "ArgumentNullException");
292
293         if (arg)
294                 ((MonoArgumentException *)ex)->param_name =
295                         mono_string_new (mono_object_get_domain ((MonoObject*)ex), arg);
296         
297         return ex;
298 }
299
300 MonoException *
301 mono_get_exception_argument (const char *arg, const char *msg)
302 {
303         MonoException *ex;
304
305         ex = mono_exception_from_name_msg (
306                 mono_get_corlib (), "System", "ArgumentException", msg);
307
308         if (arg)
309                 ((MonoArgumentException *)ex)->param_name =
310                         mono_string_new (mono_object_get_domain ((MonoObject*)ex), arg);
311         
312         return ex;
313 }
314
315 MonoException *
316 mono_get_exception_argument_out_of_range (const char *arg)
317 {
318         MonoException *ex;
319
320         ex = mono_exception_from_name (
321                 mono_get_corlib (), "System", "ArgumentOutOfRangeException");
322
323         if (arg)
324                 ((MonoArgumentException *)ex)->param_name =
325                         mono_string_new (mono_object_get_domain ((MonoObject*)ex), arg);
326         
327         return ex;
328 }
329
330 MonoException *
331 mono_get_exception_thread_state (const char *msg)
332 {
333         return mono_exception_from_name_msg (
334                 mono_get_corlib (), "System.Threading", "ThreadStateException", msg);
335 }
336
337 MonoException *
338 mono_get_exception_io (const char *msg)
339 {
340         return mono_exception_from_name_msg ( 
341                 mono_get_corlib (), "System.IO", "IOException", msg);
342 }
343
344 MonoException *
345 mono_get_exception_file_not_found (MonoString *fname)
346 {
347         return mono_exception_from_name_two_strings (
348                 mono_get_corlib (), "System.IO", "FileNotFoundException", fname, fname);
349 }
350
351 MonoException *
352 mono_get_exception_file_not_found2 (const char *msg, MonoString *fname)
353 {
354         MonoString *s = mono_string_new (mono_domain_get (), msg);
355
356         return mono_exception_from_name_two_strings (
357                 mono_get_corlib (), "System.IO", "FileNotFoundException", s, fname);
358 }
359
360 MonoException *
361 mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner)
362 {
363         MonoClass *klass;
364         gpointer args [2];
365         MonoObject *exc;
366         MonoMethod *method;
367         gpointer iter;
368
369         klass = mono_class_from_name (mono_get_corlib (), "System", "TypeInitializationException");
370         g_assert (klass);
371
372         mono_class_init (klass);
373
374         /* TypeInitializationException only has 1 ctor with 2 args */
375         iter = NULL;
376         while ((method = mono_class_get_methods (klass, &iter))) {
377                 if (!strcmp (".ctor", mono_method_get_name (method)) && mono_method_signature (method)->param_count == 2)
378                         break;
379                 method = NULL;
380         }
381
382         g_assert (method);
383
384         args [0] = mono_string_new (mono_domain_get (), type_name);
385         args [1] = inner;
386
387         exc = mono_object_new (mono_domain_get (), klass);
388         mono_runtime_invoke (method, exc, args, NULL);
389
390         return (MonoException *) exc;
391 }
392
393 MonoException *
394 mono_get_exception_synchronization_lock (const char *msg)
395 {
396         return mono_exception_from_name_msg (mono_get_corlib (), "System.Threading", "SynchronizationLockException", msg);
397 }
398
399 MonoException *
400 mono_get_exception_cannot_unload_appdomain (const char *msg)
401 {
402         return mono_exception_from_name_msg (mono_get_corlib (), "System", "CannotUnloadAppDomainException", msg);
403 }
404
405 MonoException *
406 mono_get_exception_appdomain_unloaded (void)
407 {
408         return mono_exception_from_name (mono_get_corlib (), "System", "AppDomainUnloadedException");
409 }
410
411 MonoException *
412 mono_get_exception_bad_image_format (const char *msg)
413 {
414         return mono_exception_from_name_msg (mono_get_corlib (), "System", "BadImageFormatException", msg);
415 }       
416
417 MonoException *
418 mono_get_exception_stack_overflow (void)
419 {
420         return mono_exception_from_name (mono_get_corlib (), "System", "StackOverflowException");       
421 }
422
423 MonoException *
424 mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions)
425 {
426         MonoClass *klass;
427         gpointer args [2];
428         MonoObject *exc;
429         MonoMethod *method;
430
431         klass = mono_class_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");
432         g_assert (klass);
433         mono_class_init (klass);
434
435         method = mono_class_get_method_from_name (klass, ".ctor", 2);
436         g_assert (method);
437
438         args [0] = types;
439         args [1] = exceptions;
440
441         exc = mono_object_new (mono_domain_get (), klass);
442         mono_runtime_invoke (method, exc, args, NULL);
443
444         return (MonoException *) exc;
445 }