2004-01-19 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 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 (const guchar *msg)
222 {
223         MonoException *ex;
224         MonoDomain *domain;
225         
226         ex = mono_exception_from_name (mono_defaults.corlib, "System",
227                                        "NotImplementedException");
228         domain = ((MonoObject *)ex)->vtable->domain;
229
230         if (msg)
231                 ex->message = mono_string_new (domain, msg);
232
233         return ex;
234 }
235
236 MonoException *
237 mono_get_exception_missing_method ()
238 {
239         return mono_exception_from_name (mono_defaults.corlib, "System",
240                                          "MissingMethodException");
241 }
242
243 MonoException*
244 mono_get_exception_argument_null (const guchar *arg)
245 {
246         MonoException *ex;
247         MonoDomain *domain;
248
249         ex = mono_exception_from_name ( 
250                 mono_defaults.corlib, "System", "ArgumentNullException");
251
252         domain = ((MonoObject *)ex)->vtable->domain;
253
254         if (arg)
255                 ((MonoArgumentException *)ex)->param_name =
256                         mono_string_new (domain, arg);
257         
258         return ex;
259 }
260
261 MonoException *
262 mono_get_exception_argument (const guchar *arg, const guchar *msg)
263 {
264         MonoException *ex;
265         MonoDomain *domain;
266
267         ex = mono_exception_from_name_msg (
268                 mono_defaults.corlib, "System", "ArgumentException", msg);
269
270         domain = ((MonoObject *)ex)->vtable->domain;
271
272         if (arg)
273                 ((MonoArgumentException *)ex)->param_name =
274                         mono_string_new (domain, arg);
275         
276         return ex;
277 }
278
279 MonoException *
280 mono_get_exception_argument_out_of_range (const guchar *arg)
281 {
282         MonoException *ex;
283         MonoDomain *domain;
284
285         ex = mono_exception_from_name (
286                 mono_defaults.corlib, "System", "ArgumentOutOfRangeException");
287
288         domain = ((MonoObject *)ex)->vtable->domain;
289
290         if (arg)
291                 ((MonoArgumentException *)ex)->param_name =
292                         mono_string_new (domain, arg);
293         
294         return ex;
295 }
296
297 MonoException *
298 mono_get_exception_thread_state (const guchar *msg)
299 {
300         return mono_exception_from_name_msg (mono_defaults.corlib, 
301                                                                                  "System.Threading", "ThreadStateException",
302                                                                                  msg);
303 }
304
305 MonoException *
306 mono_get_exception_io (const guchar *msg)
307 {
308         return mono_exception_from_name_msg ( 
309                 mono_defaults.corlib, "System.IO", "IOException", msg);
310 }
311
312 MonoException *
313 mono_get_exception_file_not_found (MonoString *fname)
314 {
315         return mono_exception_from_name_two_strings (
316                 mono_defaults.corlib, "System.IO", "FileNotFoundException", fname, fname);
317 }
318
319 MonoException *
320 mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner)
321 {
322         MonoClass *klass;
323         gpointer args [2];
324         MonoObject *exc;
325         MonoMethod *method;
326         gint i;
327
328         klass = mono_class_from_name (mono_defaults.corlib, "System", "TypeInitializationException");
329         g_assert (klass);
330
331         mono_class_init (klass);
332
333         /* TypeInitializationException only has 1 ctor with 2 args */
334         for (i = 0; i < klass->method.count; ++i) {
335                 method = klass->methods [i];
336                 if (!strcmp (".ctor", method->name) && method->signature->param_count == 2)
337                         break;
338                 method = NULL;
339         }
340
341         g_assert (method);
342
343         args [0] = mono_string_new (mono_domain_get (), type_name);
344         args [1] = inner;
345
346         exc = mono_object_new (mono_domain_get (), klass);
347         mono_runtime_invoke (method, exc, args, NULL);
348
349         return (MonoException *) exc;
350 }
351
352 MonoException *
353 mono_get_exception_synchronization_lock (const guchar *msg)
354 {
355         return mono_exception_from_name_msg (mono_defaults.corlib, "System.Threading", "SynchronizationLockException", msg);
356 }
357
358 MonoException *
359 mono_get_exception_cannot_unload_appdomain (const guchar *msg)
360 {
361         return mono_exception_from_name_msg (mono_defaults.corlib, "System", "CannotUnloadAppDomainException", msg);
362 }
363
364 MonoException *
365 mono_get_exception_appdomain_unloaded (void)
366 {
367         return mono_exception_from_name (mono_defaults.corlib, "System", "AppDomainUnloadedException");
368 }
369
370 MonoException *
371 mono_get_exception_bad_image_format (const guchar *msg)
372 {
373         return mono_exception_from_name_msg (mono_defaults.corlib, "System", "BadImageFormatException", msg);
374 }