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