Done?
[cacao.git] / exceptions.c
1 /* exceptions.c - exception related functions
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Christian Thalinger
28
29    $Id: exceptions.c 1370 2004-08-01 21:54:20Z stefan $
30
31 */
32
33
34 #include <string.h>
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include "asmpart.h"
38 #include "global.h"
39 #include "loader.h"
40 #include "native.h"
41 #include "tables.h"
42 #include "jit/jit.h"
43 #include "toolbox/logging.h"
44 #include "toolbox/memory.h"
45 #include "nat/java_lang_String.h"
46 #include "nat/java_lang_Throwable.h"
47
48
49 /* system exception classes required in cacao */
50
51 classinfo *class_java_lang_Throwable;
52 classinfo *class_java_lang_Exception;
53 classinfo *class_java_lang_Error;
54 classinfo *class_java_lang_OutOfMemoryError;
55
56
57 /* exception/error super class */
58
59 char *string_java_lang_Throwable =
60     "java/lang/Throwable";
61
62 char *string_java_lang_VMThrowable =
63     "java/lang/VMThrowable";
64
65
66 /* specify some exception strings for code generation */
67
68 char *string_java_lang_ArithmeticException =
69     "java/lang/ArithmeticException";
70
71 char *string_java_lang_ArithmeticException_message =
72     "/ by zero";
73
74 char *string_java_lang_ArrayIndexOutOfBoundsException =
75     "java/lang/ArrayIndexOutOfBoundsException";
76
77 char *string_java_lang_ArrayStoreException =
78     "java/lang/ArrayStoreException";
79
80 char *string_java_lang_ClassCastException =
81     "java/lang/ClassCastException";
82
83 char *string_java_lang_ClassNotFoundException =
84         "java/lang/ClassNotFoundException";
85
86 char *string_java_lang_CloneNotSupportedException =
87     "java/lang/CloneNotSupportedException";
88
89 char *string_java_lang_Exception =
90     "java/lang/Exception";
91
92 char *string_java_lang_IllegalArgumentException =
93     "java/lang/IllegalArgumentException";
94
95 char *string_java_lang_IllegalMonitorStateException =
96     "java/lang/IllegalMonitorStateException";
97
98 char *string_java_lang_InterruptedException =
99     "java/lang/InterruptedException";
100
101 char *string_java_lang_NegativeArraySizeException =
102     "java/lang/NegativeArraySizeException";
103
104 char *string_java_lang_NoSuchFieldException =
105         "java/lang/NoSuchFieldException";
106
107 char *string_java_lang_NoSuchMethodException =
108         "java/lang/NoSuchMethodException";
109
110 char *string_java_lang_NullPointerException =
111     "java/lang/NullPointerException";
112
113
114 /* specify some error strings for code generation */
115
116 char *string_java_lang_AbstractMethodError =
117     "java/lang/AbstractMethodError";
118
119 char *string_java_lang_ClassCircularityError =
120     "java/lang/ClassCircularityError";
121
122 char *string_java_lang_ClassFormatError =
123     "java/lang/ClassFormatError";
124
125 char *string_java_lang_Error =
126     "java/lang/Error";
127
128 char *string_java_lang_ExceptionInInitializerError =
129     "java/lang/ExceptionInInitializerError";
130
131 char *string_java_lang_IncompatibleClassChangeError =
132     "java/lang/IncompatibleClassChangeError";
133
134 char *string_java_lang_InternalError =
135     "java/lang/InternalError";
136
137 char *string_java_lang_LinkageError =
138     "java/lang/LinkageError";
139
140 char *string_java_lang_NoClassDefFoundError =
141     "java/lang/NoClassDefFoundError";
142
143 char *string_java_lang_NoSuchFieldError =
144         "java/lang/NoSuchFieldError";
145
146 char *string_java_lang_NoSuchMethodError =
147         "java/lang/NoSuchMethodError";
148
149 char *string_java_lang_OutOfMemoryError =
150     "java/lang/OutOfMemoryError";
151
152 char *string_java_lang_VerifyError =
153     "java/lang/VerifyError";
154
155 char *string_java_lang_VirtualMachineError =
156     "java/lang/VirtualMachineError";
157
158
159 /* init_system_exceptions *****************************************************
160
161    load, link and compile exceptions used in the system
162
163 *******************************************************************************/
164
165 void init_system_exceptions()
166 {
167         /* java/lang/Throwable */
168
169         class_java_lang_Throwable =
170                 class_new(utf_new_char(string_java_lang_Throwable));
171         class_load(class_java_lang_Throwable);
172         class_link(class_java_lang_Throwable);
173
174         /* java/lang/Exception */
175
176         class_java_lang_Exception =
177                 class_new(utf_new_char(string_java_lang_Exception));
178         class_load(class_java_lang_Exception);
179         class_link(class_java_lang_Exception);
180
181         /* java/lang/Error */
182
183         class_java_lang_Error =
184                 class_new(utf_new_char(string_java_lang_Error));
185         class_load(class_java_lang_Error);
186         class_link(class_java_lang_Error);
187
188         /* java/lang/OutOfMemoryError */
189
190         class_java_lang_OutOfMemoryError =
191                 class_new(utf_new_char(string_java_lang_OutOfMemoryError));
192         class_load(class_java_lang_OutOfMemoryError);
193         class_link(class_java_lang_OutOfMemoryError);
194 }
195
196
197 static void throw_exception_exit_intern(bool doexit)
198 {
199         java_objectheader *xptr;
200         classinfo *c;
201         methodinfo *pss;
202
203         if (*exceptionptr) {
204                 xptr = *exceptionptr;
205
206                 /* clear exception, because we are calling jit code again */
207                 *exceptionptr = NULL;
208
209                 c = xptr->vftbl->class;
210
211                 pss = class_resolveclassmethod(c,
212                                                                            utf_new_char("printStackTrace"),
213                                                                            utf_new_char("()V"),
214                                                                            class_java_lang_Object,
215                                                                            false);
216
217                 /* print the stacktrace */
218                 if (pss) {
219                         asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
220
221                         /* this normally means, we are EXTREMLY out of memory, but may be
222                            any other exception */
223                         if (*exceptionptr) {
224                                 utf_fprint_classname(stderr, c->name);
225                                 fprintf(stderr, "\n");
226                         }
227
228                 } else {
229                         utf_fprint_classname(stderr, c->name);
230                         fprintf(stderr, ": printStackTrace()V not found!\n");
231                 }
232
233                 fflush(stderr);
234
235                 /* good bye! */
236                 if (doexit) {
237                         exit(1);
238                 }
239         }
240 }
241
242
243 void throw_exception()
244 {
245         throw_exception_exit_intern(false);
246 }
247
248
249 void throw_exception_exit()
250 {
251         throw_exception_exit_intern(true);
252 }
253
254
255 void throw_main_exception()
256 {
257         fprintf(stderr, "Exception in thread \"main\" ");
258         fflush(stderr);
259
260         throw_exception_exit_intern(false);
261 }
262
263
264 void throw_main_exception_exit()
265 {
266         fprintf(stderr, "Exception in thread \"main\" ");
267         fflush(stderr);
268
269         throw_exception_exit_intern(true);
270 }
271
272
273 void throw_cacao_exception_exit(char *exception, char *message)
274 {
275         s4 i;
276         char *tmp;
277         s4 len;
278
279         len = strlen(exception);
280         tmp = MNEW(char, len);
281         strncpy(tmp, exception, len);
282
283         /* convert to classname */
284
285         for (i = len - 1; i >= 0; i--) {
286                 if (tmp[i] == '/') tmp[i] = '.';
287         }
288
289         fprintf(stderr, "Exception in thread \"main\" %s", tmp);
290
291         MFREE(tmp, char, len);
292
293         if (strlen(message) > 0)
294                 fprintf(stderr, ": %s", message);
295
296         fprintf(stderr, "\n");
297         fflush(stderr);
298
299         /* good bye! */
300         exit(1);
301 }
302
303
304 #define CREATENEW_EXCEPTION(ex) \
305         java_objectheader *newEx; \
306         java_objectheader *oldexception=*exceptionptr;\
307         *exceptionptr=0;\
308         newEx=ex;\
309         *exceptionptr=oldexception;\
310         return newEx;
311
312 java_objectheader *new_exception(char *classname)
313 {
314         classinfo *c = class_new(utf_new_char(classname));
315
316         CREATENEW_EXCEPTION(native_new_and_init(c));
317 }
318
319 java_objectheader *new_exception_message(char *classname, char *message)
320 {
321         classinfo *c = class_new(utf_new_char(classname));
322
323         CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new_char(message)));
324 }
325
326
327 java_objectheader *new_exception_throwable(char *classname, java_lang_Throwable *throwable)
328 {
329         classinfo *c = class_new(utf_new_char(classname));
330
331         CREATENEW_EXCEPTION(native_new_and_init_throwable(c, throwable));
332 }
333
334
335 java_objectheader *new_exception_utfmessage(char *classname, utf *message)
336 {
337         classinfo *c = class_new(utf_new_char(classname));
338
339         CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new(message)));
340 }
341
342
343 java_objectheader *new_exception_javastring(char *classname, java_lang_String *message)
344 {
345         classinfo *c = class_new(utf_new_char(classname));
346
347         CREATENEW_EXCEPTION(native_new_and_init_string(c, message));
348 }
349
350
351 java_objectheader *new_exception_int(char *classname, s4 i)
352 {
353         classinfo *c = class_new(utf_new_char(classname));
354
355         CREATENEW_EXCEPTION(native_new_and_init_int(c, i));
356 }
357
358
359 /* new_classformaterror ********************************************************
360
361    generates an java.lang.ClassFormatError for the classloader
362
363 *******************************************************************************/
364
365 java_objectheader *new_classformaterror(classinfo *c, char *message, ...)
366 {
367         char msg[MAXLOGTEXT];
368         va_list ap;
369
370         utf_sprint_classname(msg, c->name);
371         sprintf(msg + strlen(msg), " (");
372
373         va_start(ap, message);
374         vsprintf(msg + strlen(msg), message, ap);
375         va_end(ap);
376
377         sprintf(msg + strlen(msg), ")");
378
379         return new_exception_message(string_java_lang_ClassFormatError, msg);
380 }
381
382
383 /* new_verifyerror *************************************************************
384
385    generates an java.lang.VerifyError for the jit compiler
386
387 *******************************************************************************/
388
389 java_objectheader *new_verifyerror(methodinfo *m, char *message)
390 {
391         java_objectheader *o;
392         char *msg;
393         s4 len;
394
395         len = 8 + utf_strlen(m->class->name) +
396                 10 + utf_strlen(m->name) +
397                 13 + utf_strlen(m->descriptor) +
398                 2 + strlen(message) + 1;
399                 
400         msg = MNEW(char, len);
401
402         sprintf(msg, "(class: ");
403         utf_sprint(msg + strlen(msg), m->class->name);
404         sprintf(msg + strlen(msg), ", method: ");
405         utf_sprint(msg + strlen(msg), m->name);
406         sprintf(msg + strlen(msg), ", signature: ");
407         utf_sprint(msg + strlen(msg), m->descriptor);
408         sprintf(msg + strlen(msg), ") %s", message);
409
410         o = new_exception_message(string_java_lang_VerifyError, msg);
411
412         MFREE(msg, u1, len);
413
414         return o;
415 }
416
417
418 /*
419  * These are local overrides for various environment variables in Emacs.
420  * Please do not remove this and leave it at the end of the file, where
421  * Emacs will automagically detect them.
422  * ---------------------------------------------------------------------
423  * Local variables:
424  * mode: c
425  * indent-tabs-mode: t
426  * c-basic-offset: 4
427  * tab-width: 4
428  * End:
429  */