Turned off inlining for verifyerror
[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 1628 2004-11-30 19:14: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         len = 8 + utf_strlen(m->class->name) +
464                 10 + utf_strlen(m->name) +
465                 13 + utf_strlen(m->descriptor) +
466                 2 + strlen(message) + 1;
467                 
468         msg = MNEW(char, len);
469
470         sprintf(msg, "(class: ");
471         utf_sprint(msg + strlen(msg), m->class->name);
472         sprintf(msg + strlen(msg), ", method: ");
473         utf_sprint(msg + strlen(msg), m->name);
474         sprintf(msg + strlen(msg), ", signature: ");
475         utf_sprint(msg + strlen(msg), m->descriptor);
476         sprintf(msg + strlen(msg), ") %s", message);
477
478         o = new_exception_message(string_java_lang_VerifyError, msg);
479
480         MFREE(msg, u1, len);
481
482         return o;
483 }
484
485
486 /* new_arithmeticexception *****************************************************
487
488    generates a java.lang.ArithmeticException for the jit compiler
489
490 *******************************************************************************/
491
492 java_objectheader *new_arithmeticexception()
493 {
494         java_objectheader *e;
495
496         e = new_exception_message(string_java_lang_ArithmeticException,
497                                                           string_java_lang_ArithmeticException_message);
498
499         if (!e)
500                 return *exceptionptr;
501
502         return e;
503 }
504
505
506 /* new_arrayindexoutofboundsexception ******************************************
507
508    generates a java.lang.ArrayIndexOutOfBoundsException for the jit compiler
509
510 *******************************************************************************/
511
512 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
513 {
514         java_objectheader *e;
515         methodinfo *m;
516         java_lang_String *s;
517
518         /* convert the index into a String, like Sun does */
519
520         m = class_resolveclassmethod(class_java_lang_String,
521                                                                  utf_new_char("valueOf"),
522                                                                  utf_new_char("(I)Ljava/lang/String;"),
523                                                                  class_java_lang_Object,
524                                                                  true);
525
526         if (!m)
527                 return *exceptionptr;
528
529         s = (java_lang_String *) asm_calljavafunction(m,
530 #if POINTERSIZE == 8
531                                                                                                   (void *) (s8) index,
532 #else
533                                                                                                   (void *) index,
534 #endif
535                                                                                                   NULL,
536                                                                                                   NULL,
537                                                                                                   NULL);
538
539         if (!s)
540                 return *exceptionptr;
541
542         e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
543                                                                  s);
544
545         if (!e)
546                 return *exceptionptr;
547
548         return e;
549 }
550
551
552 /* new_arraystoreexception *****************************************************
553
554    generates a java.lang.ArrayStoreException for the jit compiler
555
556 *******************************************************************************/
557
558 java_objectheader *new_arraystoreexception()
559 {
560         java_objectheader *e;
561
562         e = new_exception(string_java_lang_ArrayStoreException);
563
564         if (!e)
565                 return *exceptionptr;
566
567         return e;
568 }
569
570
571 /* new_classcastexception ******************************************************
572
573    generates a java.lang.ClassCastException for the jit compiler
574
575 *******************************************************************************/
576
577 java_objectheader *new_classcastexception()
578 {
579         java_objectheader *e;
580
581         e = new_exception(string_java_lang_ClassCastException);
582
583         if (!e)
584                 return *exceptionptr;
585
586         return e;
587 }
588
589
590 /* new_negativearraysizeexception **********************************************
591
592    generates a java.lang.NegativeArraySizeException for the jit compiler
593
594 *******************************************************************************/
595
596 java_objectheader *new_negativearraysizeexception()
597 {
598         java_objectheader *e;
599
600         e = new_exception(string_java_lang_NegativeArraySizeException);
601
602         if (!e)
603                 return *exceptionptr;
604
605         return e;
606 }
607
608
609 /* new_nullpointerexception ****************************************************
610
611    generates a java.lang.NullPointerException for the jit compiler
612
613 *******************************************************************************/
614
615 java_objectheader *new_nullpointerexception()
616 {
617         java_objectheader *e;
618
619         e = new_exception(string_java_lang_NullPointerException);
620
621         if (!e)
622                 return *exceptionptr;
623
624         return e;
625 }
626
627
628 /*
629  * These are local overrides for various environment variables in Emacs.
630  * Please do not remove this and leave it at the end of the file, where
631  * Emacs will automagically detect them.
632  * ---------------------------------------------------------------------
633  * Local variables:
634  * mode: c
635  * indent-tabs-mode: t
636  * c-basic-offset: 4
637  * tab-width: 4
638  * End:
639  */