* exceptions_handle_exception: Better assert message.
[cacao.git] / src / vm / exceptions.c
1 /* src/vm/exceptions.c - exception related functions
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
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    Changes: Edwin Steiner
30
31    $Id: exceptions.c 3907 2005-12-08 14:25:13Z twisti $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39 #include <string.h>
40 #include <stdarg.h>
41 #include <stdlib.h>
42
43 #include "vm/types.h"
44
45 #include "mm/memory.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_String.h"
48 #include "native/include/java_lang_Throwable.h"
49 #include "toolbox/logging.h"
50 #include "toolbox/util.h"
51 #include "vm/class.h"
52 #include "vm/exceptions.h"
53 #include "vm/global.h"
54 #include "vm/loader.h"
55 #include "vm/options.h"
56 #include "vm/stringlocal.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/jit.h"
59 #include "vm/jit/methodheader.h"
60
61
62 /* for raising exceptions from native methods *********************************/
63
64 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
65 java_objectheader *_no_threads_exceptionptr = NULL;
66 #endif
67
68
69 /* init_system_exceptions ******************************************************
70
71    Load and link exceptions used in the system.
72
73 *******************************************************************************/
74
75 bool exceptions_init(void)
76 {
77         /* java/lang/Throwable */
78
79         if (!(class_java_lang_Throwable =
80                   load_class_bootstrap(utf_java_lang_Throwable)) ||
81                 !link_class(class_java_lang_Throwable))
82                 return false;
83
84
85         /* java/lang/VMThrowable */
86
87         if (!(class_java_lang_VMThrowable =
88                   load_class_bootstrap(utf_java_lang_VMThrowable)) ||
89                 !link_class(class_java_lang_VMThrowable))
90                 return false;
91
92
93         /* java/lang/Error */
94
95         if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
96                 !link_class(class_java_lang_Error))
97                 return false;
98
99         /* java/lang/NoClassDefFoundError */
100
101         if (!(class_java_lang_NoClassDefFoundError =
102                   load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
103                 !link_class(class_java_lang_NoClassDefFoundError))
104                 return false;
105
106         /* java/lang/LinkageError */
107
108         if (!(class_java_lang_LinkageError =
109                   load_class_bootstrap(utf_java_lang_LinkageError)) ||
110                 !link_class(class_java_lang_LinkageError))
111                 return false;
112
113         /* java/lang/NoSuchMethodError */
114
115         if (!(class_java_lang_NoSuchMethodError =
116                   load_class_bootstrap(utf_java_lang_NoSuchMethodError)) ||
117                 !link_class(class_java_lang_NoSuchMethodError))
118                 return false;
119
120         /* java/lang/OutOfMemoryError */
121
122         if (!(class_java_lang_OutOfMemoryError =
123                   load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
124                 !link_class(class_java_lang_OutOfMemoryError))
125                 return false;
126
127
128         /* java/lang/Exception */
129
130         if (!(class_java_lang_Exception =
131                   load_class_bootstrap(utf_java_lang_Exception)) ||
132                 !link_class(class_java_lang_Exception))
133                 return false;
134
135         /* java/lang/ClassNotFoundException */
136
137         if (!(class_java_lang_ClassNotFoundException =
138                   load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
139                 !link_class(class_java_lang_ClassNotFoundException))
140                 return false;
141
142         /* java/lang/IllegalArgumentException */
143
144         if (!(class_java_lang_IllegalArgumentException =
145                   load_class_bootstrap(utf_java_lang_IllegalArgumentException)) ||
146                 !link_class(class_java_lang_IllegalArgumentException))
147                 return false;
148
149         /* java/lang/IllegalMonitorStateException */
150
151         if (!(class_java_lang_IllegalMonitorStateException =
152                   load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
153                 !link_class(class_java_lang_IllegalMonitorStateException))
154                 return false;
155
156         /* java/lang/NullPointerException */
157
158         if (!(class_java_lang_NullPointerException =
159                   load_class_bootstrap(utf_java_lang_NullPointerException)) ||
160                 !link_class(class_java_lang_NullPointerException))
161                 return false;
162
163
164         return true;
165 }
166
167
168 static void throw_exception_exit_intern(bool doexit)
169 {
170         java_objectheader *xptr;
171         classinfo *c;
172         methodinfo *pss;
173
174         xptr = *exceptionptr;
175
176         if (xptr) {
177                 /* clear exception, because we are calling jit code again */
178                 *exceptionptr = NULL;
179
180                 c = xptr->vftbl->class;
181
182                 pss = class_resolveclassmethod(c,
183                                                                            utf_printStackTrace,
184                                                                            utf_void__void,
185                                                                            class_java_lang_Object,
186                                                                            false);
187
188                 /* print the stacktrace */
189                 if (pss) {
190                         asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
191
192                         /* This normally means, we are EXTREMLY out of memory or have a   */
193                         /* serious problem while printStackTrace. But may be another      */
194                         /* exception, so print it.                                        */
195
196                         if (*exceptionptr) {
197                                 java_lang_Throwable *t;
198
199                                 t = (java_lang_Throwable *) *exceptionptr;
200
201                                 fprintf(stderr, "Exception while printStackTrace(): ");
202                                 utf_fprint_classname(stderr, t->header.vftbl->class->name);
203
204                                 if (t->detailMessage) {
205                                         char *buf;
206
207                                         buf = javastring_tochar((java_objectheader *) t->detailMessage);
208                                         fprintf(stderr, ": %s", buf);
209                                         MFREE(buf, char, strlen(buf));
210                                 }
211                                         
212                                 fprintf(stderr, "\n");
213                         }
214
215                 } else {
216                         utf_fprint_classname(stderr, c->name);
217                         fprintf(stderr, ": printStackTrace()V not found!\n");
218                 }
219
220                 fflush(stderr);
221
222                 /* good bye! */
223
224                 if (doexit)
225                         exit(1);
226         }
227 }
228
229
230 void throw_exception(void)
231 {
232         throw_exception_exit_intern(false);
233 }
234
235
236 void throw_exception_exit(void)
237 {
238         throw_exception_exit_intern(true);
239 }
240
241
242 void throw_main_exception(void)
243 {
244         fprintf(stderr, "Exception in thread \"main\" ");
245         fflush(stderr);
246
247         throw_exception_exit_intern(false);
248 }
249
250
251 void throw_main_exception_exit(void)
252 {
253         fprintf(stderr, "Exception in thread \"main\" ");
254         fflush(stderr);
255
256         throw_exception_exit_intern(true);
257 }
258
259
260 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
261 {
262         s4 i;
263         char *tmp;
264         s4 len;
265         va_list ap;
266
267         len = strlen(exception);
268         tmp = MNEW(char, len + 1);
269         strncpy(tmp, exception, len);
270         tmp[len] = '\0';
271
272         /* convert to classname */
273
274         for (i = len - 1; i >= 0; i--)
275                 if (tmp[i] == '/') tmp[i] = '.';
276
277         fprintf(stderr, "Exception in thread \"main\" %s", tmp);
278
279         MFREE(tmp, char, len);
280
281         if (strlen(message) > 0) {
282                 fprintf(stderr, ": ");
283
284                 va_start(ap, message);
285                 vfprintf(stderr, message, ap);
286                 va_end(ap);
287         }
288
289         fprintf(stderr, "\n");
290         fflush(stderr);
291
292         /* good bye! */
293
294         exit(1);
295 }
296
297
298 /* exceptions_throw_outofmemory_exit *******************************************
299
300    Just print an: java.lang.InternalError: Out of memory
301
302 *******************************************************************************/
303
304 void exceptions_throw_outofmemory_exit(void)
305 {
306         throw_cacao_exception_exit(string_java_lang_InternalError,
307                                                            "Out of memory");
308 }
309
310
311 /* new_exception ***************************************************************
312
313    Creates an exception object with the given name and initalizes it.
314
315 *******************************************************************************/
316
317 java_objectheader *new_exception(const char *classname)
318 {
319         java_objectheader *o;
320         classinfo         *c;
321
322         if (!(c = load_class_bootstrap(utf_new_char(classname))))
323                 return *exceptionptr;
324
325         o = native_new_and_init(c);
326
327         if (!o)
328                 return *exceptionptr;
329
330         return o;
331 }
332
333
334 /* new_exception_message *******************************************************
335
336    Creates an exception object with the given name and initalizes it
337    with the given char message.
338
339 *******************************************************************************/
340
341 java_objectheader *new_exception_message(const char *classname,
342                                                                                  const char *message)
343 {
344         java_objectheader *o;
345         classinfo         *c;
346    
347         if (!(c = load_class_bootstrap(utf_new_char(classname))))
348                 return *exceptionptr;
349
350         o = native_new_and_init_string(c, javastring_new_char(message));
351
352         if (!o)
353                 return *exceptionptr;
354
355         return o;
356 }
357
358
359 /* new_exception_throwable *****************************************************
360
361    Creates an exception object with the given name and initalizes it
362    with the given java/lang/Throwable exception.
363
364 *******************************************************************************/
365
366 java_objectheader *new_exception_throwable(const char *classname,
367                                                                                    java_lang_Throwable *throwable)
368 {
369         java_objectheader *o;
370         classinfo         *c;
371    
372         if (!(c = load_class_bootstrap(utf_new_char(classname))))
373                 return *exceptionptr;
374
375         o = native_new_and_init_throwable(c, throwable);
376
377         if (!o)
378                 return *exceptionptr;
379
380         return o;
381 }
382
383
384 /* new_exception_utfmessage ****************************************************
385
386    Creates an exception object with the given name and initalizes it
387    with the given utf message.
388
389 *******************************************************************************/
390
391 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
392 {
393         java_objectheader *o;
394         classinfo         *c;
395    
396         if (!(c = load_class_bootstrap(utf_new_char(classname))))
397                 return *exceptionptr;
398
399         o = native_new_and_init_string(c, javastring_new(message));
400
401         if (!o)
402                 return *exceptionptr;
403
404         return o;
405 }
406
407
408 /* new_exception_javastring ****************************************************
409
410    Creates an exception object with the given name and initalizes it
411    with the given java/lang/String message.
412
413 *******************************************************************************/
414
415 java_objectheader *new_exception_javastring(const char *classname,
416                                                                                         java_lang_String *message)
417 {
418         java_objectheader *o;
419         classinfo         *c;
420    
421         if (!(c = load_class_bootstrap(utf_new_char(classname))))
422                 return *exceptionptr;
423
424         o = native_new_and_init_string(c, message);
425
426         if (!o)
427                 return *exceptionptr;
428
429         return o;
430 }
431
432
433 /* new_exception_int ***********************************************************
434
435    Creates an exception object with the given name and initalizes it
436    with the given int value.
437
438 *******************************************************************************/
439
440 java_objectheader *new_exception_int(const char *classname, s4 i)
441 {
442         java_objectheader *o;
443         classinfo         *c;
444    
445         if (!(c = load_class_bootstrap(utf_new_char(classname))))
446                 return *exceptionptr;
447
448         o = native_new_and_init_int(c, i);
449
450         if (!o)
451                 return *exceptionptr;
452
453         return o;
454 }
455
456
457 /* new_classformaterror ********************************************************
458
459    generates a java.lang.ClassFormatError for the classloader
460
461 *******************************************************************************/
462
463 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
464 {
465         java_objectheader *o;
466         char              *msg;
467         s4                 msglen;
468         va_list            ap;
469
470         /* calculate message length */
471
472         msglen = 0;
473
474         if (c)
475                 msglen += utf_strlen(c->name) + strlen(" (");
476
477         va_start(ap, message);
478         msglen += get_variable_message_length(message, ap);
479         va_end(ap);
480
481         if (c)
482                 msglen += strlen(")");
483
484         msglen += strlen("0");
485
486         /* allocate a buffer */
487
488         msg = MNEW(char, msglen);
489
490         /* print message into allocated buffer */
491
492         if (c) {
493                 utf_sprint_classname(msg, c->name);
494                 strcat(msg, " (");
495         }
496
497         va_start(ap, message);
498         vsprintf(msg + strlen(msg), message, ap);
499         va_end(ap);
500
501         if (c)
502                 strcat(msg, ")");
503
504         o = new_exception_message(string_java_lang_ClassFormatError, msg);
505
506         MFREE(msg, char, msglen);
507
508         return o;
509 }
510
511
512 /* new_classnotfoundexception **************************************************
513
514    Generates a java.lang.ClassNotFoundException for the classloader.
515
516 *******************************************************************************/
517
518 java_objectheader *new_classnotfoundexception(utf *name)
519 {
520         java_objectheader *o;
521
522         o = native_new_and_init_string(class_java_lang_ClassNotFoundException,
523                                                                    javastring_new(name));
524
525         if (!o)
526                 return *exceptionptr;
527
528         return o;
529 }
530
531
532 /* new_noclassdeffounderror ****************************************************
533
534    Generates a java.lang.NoClassDefFoundError
535
536 *******************************************************************************/
537
538 java_objectheader *new_noclassdeffounderror(utf *name)
539 {
540         java_objectheader *o;
541
542         o = native_new_and_init_string(class_java_lang_NoClassDefFoundError,
543                                                                    javastring_new(name));
544
545         if (!o)
546                 return *exceptionptr;
547
548         return o;
549 }
550
551
552 /* classnotfoundexception_to_noclassdeffounderror ******************************
553
554    Check the *exceptionptr for a ClassNotFoundException. If it is one,
555    convert it to a NoClassDefFoundError.
556
557 *******************************************************************************/
558
559 void classnotfoundexception_to_noclassdeffounderror(void)
560 {
561         java_objectheader *xptr;
562         java_objectheader *cause;
563
564         /* get the cause */
565
566         cause = *exceptionptr;
567
568         /* convert ClassNotFoundException's to NoClassDefFoundError's */
569
570         if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
571                 /* clear exception, because we are calling jit code again */
572
573                 *exceptionptr = NULL;
574
575                 /* create new error */
576
577                 xptr =
578                         new_exception_javastring(string_java_lang_NoClassDefFoundError,
579                                         ((java_lang_Throwable *) cause)->detailMessage);
580
581                 /* we had an exception while creating the error */
582
583                 if (*exceptionptr)
584                         return;
585
586                 /* set new exception */
587
588                 *exceptionptr = xptr;
589         }
590 }
591
592
593 /* new_internalerror ***********************************************************
594
595    Generates a java.lang.InternalError for the VM.
596
597 *******************************************************************************/
598
599 java_objectheader *new_internalerror(const char *message, ...)
600 {
601         java_objectheader *o;
602         va_list            ap;
603         char              *msg;
604         s4                 msglen;
605
606         /* calculate exception message length */
607
608         va_start(ap, message);
609         msglen = get_variable_message_length(message, ap);
610         va_end(ap);
611
612         /* allocate memory */
613
614         msg = MNEW(char, msglen);
615
616         /* generate message */
617
618         va_start(ap, message);
619         vsprintf(msg, message, ap);
620         va_end(ap);
621
622         /* create exception object */
623
624         o = new_exception_message(string_java_lang_InternalError, msg);
625
626         /* free memory */
627
628         MFREE(msg, char, msglen);
629
630         return o;
631 }
632
633
634 /* exceptions_new_linkageerror *************************************************
635
636    Generates a java.lang.LinkageError with an error message.
637    If c != NULL, the name of c is appended to the error message.
638
639 *******************************************************************************/
640
641 java_objectheader *exceptions_new_linkageerror(const char *message,
642                                                                                            classinfo *c)
643 {
644         java_objectheader *o;
645         char              *msg;
646         s4                 msglen;
647
648         /* calculate exception message length */
649
650         msglen = strlen(message) + 1;
651         if (c) {
652                 msglen += utf_strlen(c->name);
653         }
654                 
655         /* allocate memory */
656
657         msg = MNEW(char, msglen);
658
659         /* generate message */
660
661         strcpy(msg,message);
662         if (c) {
663                 utf_strcat(msg, c->name);
664         }
665
666         o = native_new_and_init_string(class_java_lang_LinkageError,
667                                                                    javastring_new_char(msg));
668
669         /* free memory */
670
671         MFREE(msg, char, msglen);
672
673         return o;
674 }
675
676
677 /* exceptions_new_nosuchmethoderror ********************************************
678
679    Generates a java.lang.NoSuchMethodError with an error message.
680
681 *******************************************************************************/
682
683 java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
684                                                                                                         utf *name, utf *desc)
685 {
686         java_objectheader *o;
687         char              *msg;
688         s4                 msglen;
689
690         /* calculate exception message length */
691
692         msglen = utf_strlen(c->name) + strlen(".") + utf_strlen(name) +
693                 utf_strlen(desc) + strlen("0");
694
695         /* allocate memory */
696
697         msg = MNEW(char, msglen);
698
699         /* generate message */
700
701         utf_sprint(msg, c->name);
702         strcat(msg, ".");
703         utf_strcat(msg, name);
704         utf_strcat(msg, desc);
705
706         o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
707                                                                    javastring_new_char(msg));
708
709         /* free memory */
710
711         MFREE(msg, char, msglen);
712
713         return o;
714 }
715
716
717 /* new_unsupportedclassversionerror ********************************************
718
719    generates a java.lang.UnsupportedClassVersionError for the classloader
720
721 *******************************************************************************/
722
723 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
724 {
725         java_objectheader *o;
726         va_list            ap;
727         char              *msg;
728     s4                 msglen;
729
730         /* calculate exception message length */
731
732         msglen = utf_strlen(c->name) + strlen(" (") + strlen(")") + strlen("0");
733
734         va_start(ap, message);
735         msglen += get_variable_message_length(message, ap);
736         va_end(ap);
737
738         /* allocate memory */
739
740         msg = MNEW(char, msglen);
741
742         /* generate message */
743
744         utf_sprint_classname(msg, c->name);
745         strcat(msg, " (");
746
747         va_start(ap, message);
748         vsprintf(msg + strlen(msg), message, ap);
749         va_end(ap);
750
751         strcat(msg, ")");
752
753         /* create exception object */
754
755         o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
756                                                           msg);
757
758         /* free memory */
759
760         MFREE(msg, char, msglen);
761
762         return o;
763 }
764
765
766 /* new_verifyerror *************************************************************
767
768    generates a java.lang.VerifyError for the jit compiler
769
770 *******************************************************************************/
771
772 java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
773 {
774         java_objectheader *o;
775         va_list            ap;
776         char              *msg;
777         s4                 msglen;
778
779         useinlining = false; /* at least until sure inlining works with exceptions*/
780
781         /* calculate exception message length */
782
783         msglen = 0;
784
785         if (m)
786                 msglen = strlen("(class: ") + utf_strlen(m->class->name) +
787                         strlen(", method: ") + utf_strlen(m->name) +
788                         strlen(" signature: ") + utf_strlen(m->descriptor) +
789                         strlen(") ") + strlen("0");
790
791         va_start(ap, message);
792         msglen += get_variable_message_length(message, ap);
793         va_end(ap);
794
795         /* allocate memory */
796
797         msg = MNEW(char, msglen);
798
799         /* generate message */
800
801         if (m) {
802                 strcpy(msg, "(class: ");
803                 utf_strcat(msg, m->class->name);
804                 strcat(msg, ", method: ");
805                 utf_strcat(msg, m->name);
806                 strcat(msg, " signature: ");
807                 utf_strcat(msg, m->descriptor);
808                 strcat(msg, ") ");
809         }
810
811         va_start(ap, message);
812         vsprintf(msg + strlen(msg), message, ap);
813         va_end(ap);
814
815         /* create exception object */
816
817         o = new_exception_message(string_java_lang_VerifyError, msg);
818
819         /* free memory */
820
821         MFREE(msg, char, msglen);
822
823         return o;
824 }
825
826
827 /* new_arithmeticexception *****************************************************
828
829    Generates a java.lang.ArithmeticException for the jit compiler.
830
831 *******************************************************************************/
832
833 java_objectheader *new_arithmeticexception(void)
834 {
835         java_objectheader *e;
836
837         e = new_exception_message(string_java_lang_ArithmeticException,
838                                                           string_java_lang_ArithmeticException_message);
839
840         if (!e)
841                 return *exceptionptr;
842
843         return e;
844 }
845
846
847 /* new_arrayindexoutofboundsexception ******************************************
848
849    Generates a java.lang.ArrayIndexOutOfBoundsException for the JIT
850    compiler.
851
852 *******************************************************************************/
853
854 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
855 {
856         java_objectheader *e;
857         methodinfo *m;
858         java_lang_String *s;
859
860         /* convert the index into a String, like Sun does */
861
862         m = class_resolveclassmethod(class_java_lang_String,
863                                                                  utf_new_char("valueOf"),
864                                                                  utf_new_char("(I)Ljava/lang/String;"),
865                                                                  class_java_lang_Object,
866                                                                  true);
867
868         if (!m)
869                 return *exceptionptr;
870
871         s = (java_lang_String *) asm_calljavafunction(m,
872                                                                                                   (void *) (ptrint) index,
873                                                                                                   NULL,
874                                                                                                   NULL,
875                                                                                                   NULL);
876
877         if (!s)
878                 return *exceptionptr;
879
880         e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
881                                                                  s);
882
883         if (!e)
884                 return *exceptionptr;
885
886         return e;
887 }
888
889
890 /* new_arraystoreexception *****************************************************
891
892    generates a java.lang.ArrayStoreException for the jit compiler
893
894 *******************************************************************************/
895
896 java_objectheader *new_arraystoreexception(void)
897 {
898         java_objectheader *e;
899
900         e = new_exception(string_java_lang_ArrayStoreException);
901 /*      e = native_new_and_init(class_java_lang_ArrayStoreException); */
902
903         if (!e)
904                 return *exceptionptr;
905
906         return e;
907 }
908
909
910 /* new_classcastexception ******************************************************
911
912    generates a java.lang.ClassCastException for the jit compiler
913
914 *******************************************************************************/
915
916 java_objectheader *new_classcastexception(void)
917 {
918         java_objectheader *e;
919
920         e = new_exception(string_java_lang_ClassCastException);
921
922         if (!e)
923                 return *exceptionptr;
924
925         return e;
926 }
927
928
929 /* new_illegalargumentexception ************************************************
930
931    Generates a java.lang.IllegalArgumentException for the VM system.
932
933 *******************************************************************************/
934
935 java_objectheader *new_illegalargumentexception(void)
936 {
937         java_objectheader *e;
938
939         if (!(e = native_new_and_init(class_java_lang_IllegalArgumentException)))
940                 return *exceptionptr;
941
942         return e;
943 }
944
945
946 /* new_illegalmonitorstateexception ********************************************
947
948    Generates a java.lang.IllegalMonitorStateException for the VM
949    thread system.
950
951 *******************************************************************************/
952
953 java_objectheader *new_illegalmonitorstateexception(void)
954 {
955         java_objectheader *e;
956
957         if (!(e = native_new_and_init(class_java_lang_IllegalMonitorStateException)))
958                 return *exceptionptr;
959
960         return e;
961 }
962
963
964 /* new_negativearraysizeexception **********************************************
965
966    generates a java.lang.NegativeArraySizeException for the jit compiler
967
968 *******************************************************************************/
969
970 java_objectheader *new_negativearraysizeexception(void)
971 {
972         java_objectheader *e;
973
974         e = new_exception(string_java_lang_NegativeArraySizeException);
975
976         if (!e)
977                 return *exceptionptr;
978
979         return e;
980 }
981
982
983 /* new_nullpointerexception ****************************************************
984
985    generates a java.lang.NullPointerException for the jit compiler
986
987 *******************************************************************************/
988
989 java_objectheader *new_nullpointerexception(void)
990 {
991         java_objectheader *e;
992
993         e = native_new_and_init(class_java_lang_NullPointerException);
994
995         if (!e)
996                 return *exceptionptr;
997
998         return e;
999 }
1000
1001
1002 /* exceptions_handle_exception *************************************************
1003
1004    XXX
1005
1006 *******************************************************************************/
1007
1008 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1009 {
1010         methodinfo            *m;
1011         s4                     framesize;
1012         s4                     issync;
1013         exceptionentry        *ex;
1014         s4                     exceptiontablelength;
1015         s4                     i;
1016         classref_or_classinfo  cr;
1017         classinfo             *c;
1018         java_objectheader     *o;
1019
1020         /* get methodinfo pointer from method header */
1021
1022         m                    = *((methodinfo **)    (pv + MethodPointer));
1023         framesize            = *((s4 *)             (pv + FrameSize));
1024         issync               = *((s4 *)             (pv + IsSync));
1025         ex                   =   (exceptionentry *) (pv + ExTableStart);
1026         exceptiontablelength = *((s4 *)             (pv + ExTableSize));
1027
1028 /*      if (m != NULL) { */
1029 /*              printf("exceptions_handle_exception: "); */
1030 /*              utf_display(m->class->name); */
1031 /*              printf("."); */
1032 /*              utf_display(m->name); */
1033 /*              utf_display(m->descriptor); */
1034 /*              printf(", %d\n", exceptiontablelength); */
1035 /*      } */
1036
1037         builtin_trace_exception(xptr, m, xpc, 1);
1038
1039         for (i = 0; i < exceptiontablelength; i++) {
1040                 /* ATTENTION: keep this here, as we need to decrement the
1041            pointer before the loop executes! */
1042
1043                 ex--;
1044
1045                 /* is the xpc is the current catch range */
1046
1047                 if (ex->startpc <= xpc && xpc < ex->endpc) {
1048                         cr = ex->catchtype;
1049
1050                         /* NULL catches everything */
1051
1052                         if (cr.any == NULL)
1053                                 return ex->handlerpc;
1054
1055                         /* resolve or load/link the exception class */
1056
1057                         if (IS_CLASSREF(cr)) {
1058                                 c = resolve_classref_eager(cr.ref);
1059
1060                         } else {
1061                                 c = cr.cls;
1062
1063                                 if (!(c->state & CLASS_LOADED))
1064                                         /* use the methods' classloader */
1065                                         if (!load_class_from_classloader(c->name,
1066                                                                                                          m->class->classloader))
1067                                                 return NULL;
1068
1069                                 if (!(c->state & CLASS_LINKED))
1070                                         if (!link_class(c))
1071                                                 return NULL;
1072                         }
1073
1074                         /* is the thrown exception an instance of the catch class? */
1075
1076                         if (builtin_instanceof(xptr, c))
1077                                 return ex->handlerpc;
1078                 }
1079         }
1080
1081 #if defined(USE_THREADS)
1082         /* is this method synchronized? */
1083
1084         if (issync) {
1085                 /* get synchronization object */
1086
1087                 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1088
1089                 assert(o != NULL);
1090
1091                 builtin_monitorexit(o);
1092         }
1093 #endif
1094
1095         /* none of the exceptions catch this one */
1096
1097         return NULL;
1098 }
1099
1100
1101 /* exceptions_print_exception **************************************************
1102
1103    Prints an exception, the detail message and the cause, if
1104    available, with CACAO internal functions to stdout.
1105
1106 *******************************************************************************/
1107
1108 void exceptions_print_exception(java_objectheader *xptr)
1109 {
1110         java_lang_Throwable   *t;
1111         java_lang_Throwable   *cause;
1112         utf                   *u;
1113
1114         t = (java_lang_Throwable *) xptr;
1115         cause = t->cause;
1116
1117         /* print the root exception */
1118
1119         utf_display_classname(t->header.vftbl->class->name);
1120
1121         if (t->detailMessage) {
1122                 u = javastring_toutf(t->detailMessage, false);
1123
1124                 printf(": ");
1125                 utf_display(u);
1126         }
1127
1128         putc('\n', stdout);
1129
1130         /* print the cause if available */
1131
1132         if (cause && (cause != t)) {
1133                 printf("Caused by: ");
1134                 utf_display_classname(cause->header.vftbl->class->name);
1135
1136                 if (cause->detailMessage) {
1137                         u = javastring_toutf(cause->detailMessage, false);
1138
1139                         printf(": ");
1140                         utf_display(u);
1141                 }
1142
1143                 putc('\n', stdout);
1144         }
1145 }
1146
1147
1148 /*
1149  * These are local overrides for various environment variables in Emacs.
1150  * Please do not remove this and leave it at the end of the file, where
1151  * Emacs will automagically detect them.
1152  * ---------------------------------------------------------------------
1153  * Local variables:
1154  * mode: c
1155  * indent-tabs-mode: t
1156  * c-basic-offset: 4
1157  * tab-width: 4
1158  * End:
1159  */