d6bfba6d19eb7625ea7b7ee7722eb86598600bcd
[cacao.git] / src / vm / exceptions.c
1 /* vm/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 1630 2004-11-30 19:33:41Z carolyn $
30
31 */
32
33
34 #include <string.h>
35 #include <stdarg.h>
36 #include <stdlib.h>
37
38 #include "mm/memory.h"
39 #include "native/native.h"
40 #include "native/include/java_lang_String.h"
41 #include "native/include/java_lang_Throwable.h"
42 #include "toolbox/logging.h"
43 #include "vm/global.h"
44 #include "vm/loader.h"
45 #include "vm/tables.h"
46 #include "vm/jit/asmpart.h"
47 #include "vm/jit/jit.h"
48 #include "vm/options.h"
49
50
51 /* system exception classes required in cacao */
52
53 classinfo *class_java_lang_Throwable;
54 classinfo *class_java_lang_Exception;
55 classinfo *class_java_lang_Error;
56 classinfo *class_java_lang_OutOfMemoryError;
57
58
59 /* exception/error super class */
60
61 char *string_java_lang_Throwable =
62     "java/lang/Throwable";
63
64 char *string_java_lang_VMThrowable =
65     "java/lang/VMThrowable";
66
67
68 /* specify some exception strings for code generation */
69
70 char *string_java_lang_ArithmeticException =
71     "java/lang/ArithmeticException";
72
73 char *string_java_lang_ArithmeticException_message =
74     "/ by zero";
75
76 char *string_java_lang_ArrayIndexOutOfBoundsException =
77     "java/lang/ArrayIndexOutOfBoundsException";
78
79 char *string_java_lang_ArrayStoreException =
80     "java/lang/ArrayStoreException";
81
82 char *string_java_lang_ClassCastException =
83     "java/lang/ClassCastException";
84
85 char *string_java_lang_ClassNotFoundException =
86         "java/lang/ClassNotFoundException";
87
88 char *string_java_lang_CloneNotSupportedException =
89     "java/lang/CloneNotSupportedException";
90
91 char *string_java_lang_Exception =
92     "java/lang/Exception";
93
94 char *string_java_lang_IllegalArgumentException =
95     "java/lang/IllegalArgumentException";
96
97 char *string_java_lang_IllegalMonitorStateException =
98     "java/lang/IllegalMonitorStateException";
99
100 char *string_java_lang_IndexOutOfBoundsException =
101     "java/lang/IndexOutOfBoundsException";
102
103 char *string_java_lang_InterruptedException =
104     "java/lang/InterruptedException";
105
106 char *string_java_lang_NegativeArraySizeException =
107     "java/lang/NegativeArraySizeException";
108
109 char *string_java_lang_NoSuchFieldException =
110         "java/lang/NoSuchFieldException";
111
112 char *string_java_lang_NoSuchMethodException =
113         "java/lang/NoSuchMethodException";
114
115 char *string_java_lang_NullPointerException =
116     "java/lang/NullPointerException";
117
118
119 /* specify some error strings for code generation */
120
121 char *string_java_lang_AbstractMethodError =
122     "java/lang/AbstractMethodError";
123
124 char *string_java_lang_ClassCircularityError =
125     "java/lang/ClassCircularityError";
126
127 char *string_java_lang_ClassFormatError =
128     "java/lang/ClassFormatError";
129
130 char *string_java_lang_Error =
131     "java/lang/Error";
132
133 char *string_java_lang_ExceptionInInitializerError =
134     "java/lang/ExceptionInInitializerError";
135
136 char *string_java_lang_IncompatibleClassChangeError =
137     "java/lang/IncompatibleClassChangeError";
138
139 char *string_java_lang_InternalError =
140     "java/lang/InternalError";
141
142 char *string_java_lang_LinkageError =
143     "java/lang/LinkageError";
144
145 char *string_java_lang_NoClassDefFoundError =
146     "java/lang/NoClassDefFoundError";
147
148 char *string_java_lang_NoSuchFieldError =
149         "java/lang/NoSuchFieldError";
150
151 char *string_java_lang_NoSuchMethodError =
152         "java/lang/NoSuchMethodError";
153
154 char *string_java_lang_OutOfMemoryError =
155     "java/lang/OutOfMemoryError";
156
157 char *string_java_lang_UnsupportedClassVersionError =
158     "java/lang/UnsupportedClassVersionError";
159
160 char *string_java_lang_VerifyError =
161     "java/lang/VerifyError";
162
163 char *string_java_lang_VirtualMachineError =
164     "java/lang/VirtualMachineError";
165
166
167 /* init_system_exceptions *****************************************************
168
169    load, link and compile exceptions used in the system
170
171 *******************************************************************************/
172
173 bool init_system_exceptions(void)
174 {
175         /* java/lang/Throwable */
176
177         class_java_lang_Throwable =
178                 class_new(utf_new_char(string_java_lang_Throwable));
179
180         if (!class_load(class_java_lang_Throwable))
181                 return false;
182
183         if (!class_link(class_java_lang_Throwable))
184                 return false;
185
186
187         /* java/lang/Exception */
188
189         class_java_lang_Exception =
190                 class_new(utf_new_char(string_java_lang_Exception));
191
192         if (!class_load(class_java_lang_Exception))
193                 return false;
194
195         if (!class_link(class_java_lang_Exception))
196                 return false;
197
198
199         /* java/lang/Error */
200
201         class_java_lang_Error =
202                 class_new(utf_new_char(string_java_lang_Error));
203
204         if (!class_load(class_java_lang_Error))
205                 return false;
206
207         if (!class_link(class_java_lang_Error))
208                 return false;
209
210
211         /* java/lang/OutOfMemoryError */
212
213         class_java_lang_OutOfMemoryError =
214                 class_new(utf_new_char(string_java_lang_OutOfMemoryError));
215
216         if (!class_load(class_java_lang_OutOfMemoryError))
217                 return false;
218
219         if (!class_link(class_java_lang_OutOfMemoryError))
220                 return false;
221
222         return true;
223 }
224
225
226 static void throw_exception_exit_intern(bool doexit)
227 {
228         java_objectheader *xptr;
229         classinfo *c;
230         methodinfo *pss;
231
232         xptr = *exceptionptr;
233
234         if (xptr) {
235                 /* clear exception, because we are calling jit code again */
236                 *exceptionptr = NULL;
237
238                 c = xptr->vftbl->class;
239
240                 pss = class_resolveclassmethod(c,
241                                                                            utf_new_char("printStackTrace"),
242                                                                            utf_new_char("()V"),
243                                                                            class_java_lang_Object,
244                                                                            false);
245
246                 /* print the stacktrace */
247                 if (pss) {
248                         asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
249
250                         /* this normally means, we are EXTREMLY out of memory, but may be
251                            any other exception */
252                         if (*exceptionptr) {
253                                 utf_fprint_classname(stderr, c->name);
254                                 fprintf(stderr, "\n");
255                         }
256
257                 } else {
258                         utf_fprint_classname(stderr, c->name);
259                         fprintf(stderr, ": printStackTrace()V not found!\n");
260                 }
261
262                 fflush(stderr);
263
264                 /* good bye! */
265                 if (doexit) {
266                         exit(1);
267                 }
268         }
269 }
270
271
272 void throw_exception()
273 {
274         throw_exception_exit_intern(false);
275 }
276
277
278 void throw_exception_exit()
279 {
280         throw_exception_exit_intern(true);
281 }
282
283
284 void throw_main_exception()
285 {
286         fprintf(stderr, "Exception in thread \"main\" ");
287         fflush(stderr);
288
289         throw_exception_exit_intern(false);
290 }
291
292
293 void throw_main_exception_exit()
294 {
295         fprintf(stderr, "Exception in thread \"main\" ");
296         fflush(stderr);
297
298         throw_exception_exit_intern(true);
299 }
300
301
302 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
303 {
304         s4 i;
305         char *tmp;
306         s4 len;
307         va_list ap;
308
309         len = strlen(exception);
310         tmp = MNEW(char, len + 1);
311         strncpy(tmp, exception, len);
312         tmp[len] = '\0';
313
314         /* convert to classname */
315
316         for (i = len - 1; i >= 0; i--) {
317                 if (tmp[i] == '/') tmp[i] = '.';
318         }
319
320         fprintf(stderr, "Exception in thread \"main\" %s", tmp);
321
322         MFREE(tmp, char, len);
323
324         if (strlen(message) > 0) {
325                 fprintf(stderr, ": ");
326
327                 va_start(ap, message);
328                 vfprintf(stderr, message, ap);
329                 va_end(ap);
330         }
331
332         fprintf(stderr, "\n");
333         fflush(stderr);
334
335         /* good bye! */
336         exit(1);
337 }
338
339
340 #if 1
341 #define CREATENEW_EXCEPTION(ex) \
342     return ex;
343 #else
344 #define CREATENEW_EXCEPTION(ex) \
345         java_objectheader *newEx; \
346         java_objectheader *oldexception=*exceptionptr;\
347         *exceptionptr=0;\
348         newEx=ex;\
349         *exceptionptr=oldexception;\
350         return newEx;
351 #endif
352
353 java_objectheader *new_exception(char *classname)
354 {
355         classinfo *c = class_new(utf_new_char(classname));
356
357         CREATENEW_EXCEPTION(native_new_and_init(c));
358 }
359
360 java_objectheader *new_exception_message(char *classname, char *message)
361 {
362         classinfo *c = class_new(utf_new_char(classname));
363
364         CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new_char(message)));
365 }
366
367
368 java_objectheader *new_exception_throwable(char *classname, java_lang_Throwable *throwable)
369 {
370         classinfo *c = class_new(utf_new_char(classname));
371
372         CREATENEW_EXCEPTION(native_new_and_init_throwable(c, throwable));
373 }
374
375
376 java_objectheader *new_exception_utfmessage(char *classname, utf *message)
377 {
378         classinfo *c = class_new(utf_new_char(classname));
379
380         CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new(message)));
381 }
382
383
384 java_objectheader *new_exception_javastring(char *classname, java_lang_String *message)
385 {
386         classinfo *c = class_new(utf_new_char(classname));
387
388         CREATENEW_EXCEPTION(native_new_and_init_string(c, message));
389 }
390
391
392 java_objectheader *new_exception_int(char *classname, s4 i)
393 {
394         classinfo *c;
395
396         c = class_new(utf_new_char(classname));
397
398         CREATENEW_EXCEPTION(native_new_and_init_int(c, i));
399 }
400
401
402 /* new_classformaterror ********************************************************
403
404    generates a java.lang.ClassFormatError for the classloader
405
406 *******************************************************************************/
407
408 java_objectheader *new_classformaterror(classinfo *c, char *message, ...)
409 {
410         char msg[MAXLOGTEXT];
411         va_list ap;
412
413         utf_sprint_classname(msg, c->name);
414         sprintf(msg + strlen(msg), " (");
415
416         va_start(ap, message);
417         vsprintf(msg + strlen(msg), message, ap);
418         va_end(ap);
419
420         sprintf(msg + strlen(msg), ")");
421
422         return new_exception_message(string_java_lang_ClassFormatError, msg);
423 }
424
425
426 /* new_unsupportedclassversionerror ********************************************
427
428    generates a java.lang.UnsupportedClassVersionError for the classloader
429
430 *******************************************************************************/
431
432 java_objectheader *new_unsupportedclassversionerror(classinfo *c, char *message, ...)
433 {
434         char msg[MAXLOGTEXT];
435         va_list ap;
436
437         utf_sprint_classname(msg, c->name);
438         sprintf(msg + strlen(msg), " (");
439
440         va_start(ap, message);
441         vsprintf(msg + strlen(msg), message, ap);
442         va_end(ap);
443
444         sprintf(msg + strlen(msg), ")");
445
446         return new_exception_message(string_java_lang_UnsupportedClassVersionError,
447                                                                  msg);
448 }
449
450
451 /* new_verifyerror *************************************************************
452
453    generates a java.lang.VerifyError for the jit compiler
454
455 *******************************************************************************/
456
457 java_objectheader *new_verifyerror(methodinfo *m, char *message)
458 {
459         java_objectheader *o;
460         char *msg;
461         s4 len;
462
463         useinlining = false; /* at least until sure inlining works with exceptions*/
464         len = 8 + utf_strlen(m->class->name) +
465                 10 + utf_strlen(m->name) +
466                 13 + utf_strlen(m->descriptor) +
467                 2 + strlen(message) + 1;
468                 
469         msg = MNEW(char, len);
470
471         sprintf(msg, "(class: ");
472         utf_sprint(msg + strlen(msg), m->class->name);
473         sprintf(msg + strlen(msg), ", method: ");
474         utf_sprint(msg + strlen(msg), m->name);
475         sprintf(msg + strlen(msg), ", signature: ");
476         utf_sprint(msg + strlen(msg), m->descriptor);
477         sprintf(msg + strlen(msg), ") %s", message);
478
479         o = new_exception_message(string_java_lang_VerifyError, msg);
480
481         MFREE(msg, u1, len);
482
483         return o;
484 }
485
486
487 /* new_arithmeticexception *****************************************************
488
489    generates a java.lang.ArithmeticException for the jit compiler
490
491 *******************************************************************************/
492
493 java_objectheader *new_arithmeticexception()
494 {
495         java_objectheader *e;
496
497         e = new_exception_message(string_java_lang_ArithmeticException,
498                                                           string_java_lang_ArithmeticException_message);
499
500         if (!e)
501                 return *exceptionptr;
502
503         return e;
504 }
505
506
507 /* new_arrayindexoutofboundsexception ******************************************
508
509    generates a java.lang.ArrayIndexOutOfBoundsException for the jit compiler
510
511 *******************************************************************************/
512
513 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
514 {
515         java_objectheader *e;
516         methodinfo *m;
517         java_lang_String *s;
518
519         /* convert the index into a String, like Sun does */
520
521         m = class_resolveclassmethod(class_java_lang_String,
522                                                                  utf_new_char("valueOf"),
523                                                                  utf_new_char("(I)Ljava/lang/String;"),
524                                                                  class_java_lang_Object,
525                                                                  true);
526
527         if (!m)
528                 return *exceptionptr;
529
530         s = (java_lang_String *) asm_calljavafunction(m,
531 #if POINTERSIZE == 8
532                                                                                                   (void *) (s8) index,
533 #else
534                                                                                                   (void *) index,
535 #endif
536                                                                                                   NULL,
537                                                                                                   NULL,
538                                                                                                   NULL);
539
540         if (!s)
541                 return *exceptionptr;
542
543         e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
544                                                                  s);
545
546         if (!e)
547                 return *exceptionptr;
548
549         return e;
550 }
551
552
553 /* new_arraystoreexception *****************************************************
554
555    generates a java.lang.ArrayStoreException for the jit compiler
556
557 *******************************************************************************/
558
559 java_objectheader *new_arraystoreexception()
560 {
561         java_objectheader *e;
562
563         e = new_exception(string_java_lang_ArrayStoreException);
564
565         if (!e)
566                 return *exceptionptr;
567
568         return e;
569 }
570
571
572 /* new_classcastexception ******************************************************
573
574    generates a java.lang.ClassCastException for the jit compiler
575
576 *******************************************************************************/
577
578 java_objectheader *new_classcastexception()
579 {
580         java_objectheader *e;
581
582         e = new_exception(string_java_lang_ClassCastException);
583
584         if (!e)
585                 return *exceptionptr;
586
587         return e;
588 }
589
590
591 /* new_negativearraysizeexception **********************************************
592
593    generates a java.lang.NegativeArraySizeException for the jit compiler
594
595 *******************************************************************************/
596
597 java_objectheader *new_negativearraysizeexception()
598 {
599         java_objectheader *e;
600
601         e = new_exception(string_java_lang_NegativeArraySizeException);
602
603         if (!e)
604                 return *exceptionptr;
605
606         return e;
607 }
608
609
610 /* new_nullpointerexception ****************************************************
611
612    generates a java.lang.NullPointerException for the jit compiler
613
614 *******************************************************************************/
615
616 java_objectheader *new_nullpointerexception()
617 {
618         java_objectheader *e;
619
620         e = new_exception(string_java_lang_NullPointerException);
621
622         if (!e)
623                 return *exceptionptr;
624
625         return e;
626 }
627
628
629 /*
630  * These are local overrides for various environment variables in Emacs.
631  * Please do not remove this and leave it at the end of the file, where
632  * Emacs will automagically detect them.
633  * ---------------------------------------------------------------------
634  * Local variables:
635  * mode: c
636  * indent-tabs-mode: t
637  * c-basic-offset: 4
638  * tab-width: 4
639  * End:
640  */