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