Line data Source code
1 : /* src/vm/exceptions.cpp - exception related functions
2 :
3 : Copyright (C) 1996-2014
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 : #include "vm/exceptions.hpp"
26 : #include <stdint.h> // for uintptr_t
27 : #include <cassert> // for assert
28 : #include <cstring>
29 : #include <cstdio> // for fprintf, printf, putc, etc
30 : #include <cstdarg> // for va_list
31 : #include "config.h"
32 : #include "md-abi.hpp"
33 : #include "jit/code.hpp" // for codeinfo, etc
34 : #include "native/llni.hpp"
35 : #include "native/native.hpp" // for native_new_and_init_string, etc
36 : #include "threads/lock.hpp" // for lock_monitor_exit
37 : #include "threads/thread.hpp" // for threadobject, etc
38 : #include "toolbox/buffer.hpp" // for Buffer
39 : #include "toolbox/logging.hpp" // for log_finish, log_print, etc
40 : #include "vm/class.hpp" // for classinfo, etc
41 : #include "vm/global.hpp" // for java_handle_t, etc
42 : #include "vm/globals.hpp" // for class_java_lang_Object, etc
43 : #include "vm/javaobjects.hpp" // for java_lang_Throwable, etc
44 : #include "vm/jit/asmpart.hpp"
45 : #include "vm/jit/builtin.hpp" // for builtin_new, etc
46 : #include "vm/jit/exceptiontable.hpp" // for exceptiontable_entry_t, etc
47 : #include "vm/jit/methodheader.hpp"
48 : #include "vm/jit/patcher-common.hpp"
49 : #include "vm/jit/show.hpp"
50 : #include "vm/jit/stacktrace.hpp" // for stacktrace_print_exception, etc
51 : #include "vm/jit/trace.hpp" // for trace_exception
52 : #include "vm/linker.hpp" // for link_class
53 : #include "vm/loader.hpp" // for load_class_bootstrap, etc
54 : #include "vm/method.hpp" // for methodinfo
55 : #include "vm/options.hpp" // for opt_TraceExceptions, etc
56 : #include "vm/os.hpp" // for os
57 : #include "vm/references.hpp" // for classref_or_classinfo
58 : #include "vm/resolve.hpp" // for resolve_classref_eager
59 : #include "vm/string.hpp" // for JavaString
60 : #include "vm/types.hpp" // for s4, u1, u4
61 : #include "vm/vm.hpp" // for VM, vm_call_method
62 :
63 : #define DEBUG_NAME "exceptions"
64 :
65 : /***
66 : * Get the the name of a classinfo* for an exception message
67 : */
68 : static inline Utf8String get_classname_for_exception(classinfo *c);
69 :
70 : /* exceptions_get_exception ****************************************************
71 :
72 : Returns the current exception pointer of the current thread.
73 :
74 : *******************************************************************************/
75 :
76 3216564 : java_handle_t *exceptions_get_exception(void)
77 : {
78 3216564 : threadobject *t = THREADOBJECT;
79 :
80 : /* Get the exception. */
81 :
82 : LLNI_CRITICAL_START;
83 :
84 3216564 : java_object_t *o = t->_exceptionptr;
85 3216564 : java_handle_t *e = LLNI_WRAP(o);
86 :
87 : LLNI_CRITICAL_END;
88 :
89 : /* Return the exception. */
90 :
91 3216564 : return e;
92 : }
93 :
94 :
95 : /* exceptions_set_exception ****************************************************
96 :
97 : Sets the exception pointer of the current thread.
98 :
99 : *******************************************************************************/
100 :
101 20918 : void exceptions_set_exception(java_handle_t *e)
102 : {
103 20918 : threadobject *t = THREADOBJECT;
104 :
105 : /* Set the exception. */
106 :
107 : LLNI_CRITICAL_START;
108 :
109 20918 : java_object_t *o = LLNI_UNWRAP(e);
110 :
111 : LOG("[exceptions_set_exception : t=" << (void *) t
112 : << ", o=" << (void *) o
113 : << ", class=" << o->vftbl->clazz << "]" << cacao::nl);
114 :
115 20918 : t->_exceptionptr = o;
116 :
117 : LLNI_CRITICAL_END;
118 20918 : }
119 :
120 :
121 : /* exceptions_clear_exception **************************************************
122 :
123 : Clears the current exception pointer of the current thread.
124 :
125 : *******************************************************************************/
126 :
127 39195 : void exceptions_clear_exception(void)
128 : {
129 39195 : threadobject *t = THREADOBJECT;
130 :
131 : /* Set the exception. */
132 :
133 : LOG("[exceptions_clear_exception: t=" << (void *) t << cacao::nl);
134 :
135 39195 : t->_exceptionptr = NULL;
136 39195 : }
137 :
138 :
139 : /* exceptions_get_and_clear_exception ******************************************
140 :
141 : Gets the exception pointer of the current thread and clears it.
142 : This function may return NULL.
143 :
144 : *******************************************************************************/
145 :
146 3116701 : java_handle_t *exceptions_get_and_clear_exception(void)
147 : {
148 : java_handle_t *o;
149 :
150 : /* Get the exception... */
151 :
152 3116701 : o = exceptions_get_exception();
153 :
154 : /* ...and clear the exception if it is set. */
155 :
156 3117080 : if (o != NULL)
157 20869 : exceptions_clear_exception();
158 :
159 : /* return the exception */
160 :
161 3117080 : return o;
162 : }
163 :
164 :
165 : /* exceptions_abort ************************************************************
166 :
167 : Prints exception to be thrown and aborts.
168 :
169 : IN:
170 : classname....class name
171 : message......exception message
172 :
173 : *******************************************************************************/
174 :
175 0 : static void exceptions_abort(Utf8String classname, Utf8String message)
176 : {
177 0 : log_println("exception thrown while VM is initializing: ");
178 :
179 0 : log_start();
180 0 : utf_display_printable_ascii_classname(classname);
181 :
182 0 : if (message != NULL) {
183 0 : log_print(": ");
184 0 : utf_display_printable_ascii_classname(message);
185 : }
186 :
187 0 : log_finish();
188 :
189 0 : os::abort("Aborting...");
190 0 : }
191 :
192 :
193 : /* exceptions_new_class_Utf8String ***************************************************
194 :
195 : Creates an exception object with the given class and initalizes it
196 : with the given utf message.
197 :
198 : IN:
199 : c ......... exception class
200 : message ... the message as an Utf8String
201 :
202 : RETURN VALUE:
203 : an exception pointer (in any case -- either it is the newly
204 : created exception, or an exception thrown while trying to create
205 : it).
206 :
207 : *******************************************************************************/
208 :
209 839 : static java_handle_t *exceptions_new_class_utf(classinfo *c, Utf8String message)
210 : {
211 : java_handle_t *s;
212 : java_handle_t *o;
213 :
214 839 : if (VM::get_current()->is_initializing()) {
215 : /* This can happen when global class variables are used which
216 : are not initialized yet. */
217 :
218 0 : if (c == NULL)
219 0 : exceptions_abort(NULL, message);
220 : else
221 0 : exceptions_abort(c->name, message);
222 : }
223 :
224 839 : s = JavaString::from_utf8(message);
225 :
226 839 : if (s == NULL)
227 0 : return exceptions_get_exception();
228 :
229 839 : o = native_new_and_init_string(c, s);
230 :
231 839 : if (o == NULL)
232 0 : return exceptions_get_exception();
233 :
234 839 : return o;
235 : }
236 :
237 :
238 : /* exceptions_new_Utf8String *********************************************************
239 :
240 : Creates an exception object with the given name and initalizes it.
241 :
242 : IN:
243 : classname....class name in UTF-8
244 :
245 : *******************************************************************************/
246 :
247 20040 : static java_handle_t *exceptions_new_utf(Utf8String classname)
248 : {
249 : classinfo *c;
250 : java_handle_t *o;
251 :
252 20040 : if (VM::get_current()->is_initializing())
253 0 : exceptions_abort(classname, NULL);
254 :
255 20040 : c = load_class_bootstrap(classname);
256 :
257 20040 : if (c == NULL)
258 0 : return exceptions_get_exception();
259 :
260 20040 : o = native_new_and_init(c);
261 :
262 20040 : if (o == NULL)
263 0 : return exceptions_get_exception();
264 :
265 20040 : return o;
266 : }
267 :
268 :
269 : /* exceptions_new_utf_javastring ***********************************************
270 :
271 : Creates an exception object with the given name and initalizes it
272 : with the given java/lang/String message.
273 :
274 : IN:
275 : classname....class name in UTF-8
276 : message......the message as a java.lang.String
277 :
278 : RETURN VALUE:
279 : an exception pointer (in any case -- either it is the newly created
280 : exception, or an exception thrown while trying to create it).
281 :
282 : *******************************************************************************/
283 :
284 25 : static java_handle_t *exceptions_new_utf_javastring(Utf8String classname,
285 : java_handle_t *message)
286 : {
287 : java_handle_t *o;
288 : classinfo *c;
289 :
290 25 : if (VM::get_current()->is_initializing())
291 0 : exceptions_abort(classname, NULL);
292 :
293 25 : c = load_class_bootstrap(classname);
294 :
295 25 : if (c == NULL)
296 0 : return exceptions_get_exception();
297 :
298 25 : o = native_new_and_init_string(c, message);
299 :
300 25 : if (o == NULL)
301 0 : return exceptions_get_exception();
302 :
303 25 : return o;
304 : }
305 :
306 :
307 : /* exceptions_new_utf_Utf8String *****************************************************
308 :
309 : Creates an exception object with the given name and initalizes it
310 : with the given utf message.
311 :
312 : IN:
313 : classname....class name in UTF-8
314 : message......the message as an Utf8String
315 :
316 : RETURN VALUE:
317 : an exception pointer (in any case -- either it is the newly created
318 : exception, or an exception thrown while trying to create it).
319 :
320 : *******************************************************************************/
321 :
322 839 : static java_handle_t *exceptions_new_utf_utf(Utf8String classname, Utf8String message)
323 : {
324 : classinfo *c;
325 : java_handle_t *o;
326 :
327 839 : if (VM::get_current()->is_initializing())
328 0 : exceptions_abort(classname, message);
329 :
330 839 : c = load_class_bootstrap(classname);
331 :
332 839 : if (c == NULL)
333 0 : return exceptions_get_exception();
334 :
335 839 : o = exceptions_new_class_utf(c, message);
336 :
337 839 : return o;
338 : }
339 :
340 :
341 : /* exceptions_throw_Utf8String *******************************************************
342 :
343 : Creates an exception object with the given name, initalizes and
344 : throws it.
345 :
346 : IN:
347 : classname....class name in UTF-8
348 :
349 : *******************************************************************************/
350 :
351 20011 : static void exceptions_throw_utf(Utf8String classname)
352 : {
353 : java_handle_t *o;
354 :
355 20011 : o = exceptions_new_utf(classname);
356 :
357 20011 : if (o == NULL)
358 0 : return;
359 :
360 20011 : exceptions_set_exception(o);
361 : }
362 :
363 :
364 : /* exceptions_throw_utf_throwable **********************************************
365 :
366 : Creates an exception object with the given name and initalizes it
367 : with the given java/lang/Throwable exception.
368 :
369 : IN:
370 : classname....class name in UTF-8
371 : cause........the given Throwable
372 :
373 : *******************************************************************************/
374 :
375 14 : static void exceptions_throw_utf_throwable(Utf8String classname,
376 : java_handle_t *cause)
377 : {
378 : classinfo *c;
379 : methodinfo *m;
380 :
381 14 : if (VM::get_current()->is_initializing())
382 0 : exceptions_abort(classname, NULL);
383 :
384 14 : java_lang_Throwable jlt(cause);
385 :
386 14 : c = load_class_bootstrap(classname);
387 :
388 14 : if (c == NULL)
389 : return;
390 :
391 : /* create object */
392 :
393 14 : java_handle_t* h = builtin_new(c);
394 :
395 14 : if (h == NULL)
396 : return;
397 :
398 : /* call initializer */
399 :
400 : m = class_resolveclassmethod(c,
401 : utf8::init,
402 : utf8::java_lang_Throwable__void,
403 : NULL,
404 14 : true);
405 :
406 14 : if (m == NULL)
407 : return;
408 :
409 14 : (void) vm_call_method(m, h, jlt.get_handle());
410 :
411 14 : exceptions_set_exception(h);
412 : }
413 :
414 :
415 : /* exceptions_throw_utf_exception **********************************************
416 :
417 : Creates an exception object with the given name and initalizes it
418 : with the given java/lang/Exception exception.
419 :
420 : IN:
421 : classname....class name in UTF-8
422 : exception....the given Exception
423 :
424 : *******************************************************************************/
425 :
426 0 : static void exceptions_throw_utf_exception(Utf8String classname,
427 : java_handle_t *exception)
428 : {
429 : classinfo *c;
430 : java_handle_t *o;
431 : methodinfo *m;
432 :
433 0 : if (VM::get_current()->is_initializing())
434 0 : exceptions_abort(classname, NULL);
435 :
436 0 : c = load_class_bootstrap(classname);
437 :
438 0 : if (c == NULL)
439 0 : return;
440 :
441 : /* create object */
442 :
443 0 : o = builtin_new(c);
444 :
445 0 : if (o == NULL)
446 0 : return;
447 :
448 : /* call initializer */
449 :
450 : m = class_resolveclassmethod(c,
451 : utf8::init,
452 : utf8::java_lang_Exception__V,
453 : NULL,
454 0 : true);
455 :
456 0 : if (m == NULL)
457 0 : return;
458 :
459 0 : (void) vm_call_method(m, o, exception);
460 :
461 0 : exceptions_set_exception(o);
462 : }
463 :
464 :
465 : /* exceptions_throw_utf_cause **************************************************
466 :
467 : Creates an exception object with the given name and initalizes it
468 : with the given java/lang/Throwable exception with initCause.
469 :
470 : IN:
471 : classname....class name in UTF-8
472 : cause........the given Throwable
473 :
474 : *******************************************************************************/
475 :
476 3 : static void exceptions_throw_utf_cause(Utf8String classname, java_handle_t *cause)
477 : {
478 3 : if (VM::get_current()->is_initializing())
479 0 : exceptions_abort(classname, NULL);
480 :
481 3 : java_lang_Throwable jltcause(cause);
482 :
483 3 : classinfo* c = load_class_bootstrap(classname);
484 :
485 3 : if (c == NULL)
486 : return;
487 :
488 : /* create object */
489 :
490 3 : java_handle_t* h = builtin_new(c);
491 :
492 3 : if (h == NULL)
493 : return;
494 :
495 : /* call initializer */
496 :
497 : methodinfo* m = class_resolveclassmethod(c,
498 : utf8::init,
499 : utf8::java_lang_String__void,
500 : NULL,
501 3 : true);
502 :
503 3 : if (m == NULL)
504 : return;
505 :
506 3 : (void) vm_call_method(m, h, jltcause.get_detailMessage());
507 :
508 : /* call initCause */
509 :
510 : m = class_resolveclassmethod(c,
511 : utf8::initCause,
512 : utf8::java_lang_Throwable__java_lang_Throwable,
513 : NULL,
514 3 : true);
515 :
516 3 : if (m == NULL)
517 : return;
518 :
519 3 : (void) vm_call_method(m, h, jltcause.get_handle());
520 :
521 3 : exceptions_set_exception(h);
522 : }
523 :
524 :
525 : /* exceptions_throw_utf_Utf8String ***************************************************
526 :
527 : Creates an exception object with the given name, initalizes and
528 : throws it with the given utf message.
529 :
530 : IN:
531 : classname....class name in UTF-8
532 : message......the message as an Utf8String
533 :
534 : *******************************************************************************/
535 :
536 821 : static void exceptions_throw_utf_utf(Utf8String classname, Utf8String message)
537 : {
538 : java_handle_t *o;
539 :
540 821 : o = exceptions_new_utf_utf(classname, message);
541 :
542 821 : exceptions_set_exception(o);
543 821 : }
544 :
545 :
546 : /* exceptions_new_abstractmethoderror ****************************************
547 :
548 : Generates a java.lang.AbstractMethodError for the VM.
549 :
550 : *******************************************************************************/
551 :
552 1 : java_handle_t *exceptions_new_abstractmethoderror(void)
553 : {
554 : java_handle_t *o;
555 :
556 1 : o = exceptions_new_utf(utf8::java_lang_AbstractMethodError);
557 :
558 1 : return o;
559 : }
560 :
561 :
562 : /* exceptions_new_error ********************************************************
563 :
564 : Generates a java.lang.Error for the VM.
565 :
566 : *******************************************************************************/
567 :
568 : #if defined(ENABLE_JAVAME_CLDC1_1)
569 : static java_handle_t *exceptions_new_error(Utf8String message)
570 : {
571 : java_handle_t *o;
572 :
573 : o = exceptions_new_utf_utf(utf8::java_lang_Error, message);
574 :
575 : return o;
576 : }
577 : #endif
578 :
579 :
580 : /* exceptions_new_arraystoreexception ******************************************
581 :
582 : Generates a java.lang.ArrayStoreException for the VM.
583 :
584 : *******************************************************************************/
585 :
586 6 : java_handle_t *exceptions_new_arraystoreexception(void)
587 : {
588 : java_handle_t *o;
589 :
590 6 : o = exceptions_new_utf(utf8::java_lang_ArrayStoreException);
591 :
592 6 : return o;
593 : }
594 :
595 :
596 : /* exceptions_throw_abstractmethoderror ****************************************
597 :
598 : Generates and throws a java.lang.AbstractMethodError for the VM.
599 :
600 : *******************************************************************************/
601 :
602 0 : void exceptions_throw_abstractmethoderror(void)
603 : {
604 0 : exceptions_throw_utf(utf8::java_lang_AbstractMethodError);
605 0 : }
606 :
607 :
608 : /* exceptions_throw_classcircularityerror **************************************
609 :
610 : Generates and throws a java.lang.ClassCircularityError for the
611 : classloader.
612 :
613 : IN:
614 : c....the class in which the error was found
615 :
616 : *******************************************************************************/
617 :
618 0 : void exceptions_throw_classcircularityerror(classinfo *c)
619 : {
620 0 : exceptions_throw_utf_utf(utf8::java_lang_ClassCircularityError, c->name);
621 0 : }
622 :
623 :
624 : /* exceptions_throw_classformaterror *******************************************
625 :
626 : Generates and throws a java.lang.ClassFormatError for the VM.
627 :
628 : IN:
629 : c............the class in which the error was found
630 : message......UTF-8 format string
631 :
632 : *******************************************************************************/
633 :
634 0 : void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
635 : {
636 : va_list ap;
637 :
638 : /* allocate a buffer */
639 :
640 0 : Buffer<> buf;
641 :
642 : /* print message into allocated buffer */
643 :
644 0 : if (c != NULL)
645 0 : buf.write_slash_to_dot(c->name).write('(');
646 :
647 0 : va_start(ap, message);
648 0 : buf.writevf(message,ap);
649 0 : va_end(ap);
650 :
651 0 : if (c != NULL)
652 0 : buf.write(')');
653 :
654 0 : Utf8String u = buf.utf8_str();
655 0 : assert(u);
656 :
657 : /* throw exception */
658 :
659 0 : exceptions_throw_classformaterror(c, u);
660 0 : }
661 :
662 0 : void exceptions_throw_classformaterror(classinfo *c, Utf8String message)
663 : {
664 : /* throw exception */
665 :
666 0 : assert(message);
667 :
668 0 : exceptions_throw_utf_utf(utf8::java_lang_ClassFormatError, message);
669 0 : }
670 :
671 : /* exceptions_throw_classnotfoundexception *************************************
672 :
673 : Generates and throws a java.lang.ClassNotFoundException for the
674 : VM.
675 :
676 : IN:
677 : name.........name of the class not found as a Utf8String
678 :
679 : *******************************************************************************/
680 :
681 769 : void exceptions_throw_classnotfoundexception(Utf8String name)
682 : {
683 : // We can't use the cached class_java_lang_ClassNotFoundException because
684 : // when there are bootstrap classpath problems it has not been set yet,
685 : // which leads to confusing error messages.
686 :
687 769 : exceptions_throw_utf_utf(utf8::java_lang_ClassNotFoundException, name);
688 769 : }
689 :
690 :
691 : /* exceptions_throw_noclassdeffounderror ***************************************
692 :
693 : Generates and throws a java.lang.NoClassDefFoundError.
694 :
695 : IN:
696 : name.........name of the class not found as a Utf8String
697 :
698 : *******************************************************************************/
699 :
700 0 : void exceptions_throw_noclassdeffounderror(Utf8String name)
701 : {
702 0 : exceptions_throw_utf_utf(utf8::java_lang_NoClassDefFoundError, name);
703 0 : }
704 :
705 :
706 : /* exceptions_throw_noclassdeffounderror_cause *********************************
707 :
708 : Generates and throws a java.lang.NoClassDefFoundError with the
709 : given cause.
710 :
711 : *******************************************************************************/
712 :
713 3 : void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
714 : {
715 3 : exceptions_throw_utf_cause(utf8::java_lang_NoClassDefFoundError, cause);
716 3 : }
717 :
718 :
719 : /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
720 :
721 : Generates and throws a java.lang.NoClassDefFoundError with a
722 : specific message:
723 :
724 : IN:
725 : name.........name of the class not found as a Utf8String
726 :
727 : *******************************************************************************/
728 :
729 0 : void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, Utf8String name)
730 : {
731 0 : Buffer<> buf;
732 :
733 : buf.write_slash_to_dot(c->name)
734 : .write(" (wrong name: ", 14)
735 : .write_slash_to_dot(name)
736 0 : .write(')');
737 :
738 0 : exceptions_throw_noclassdeffounderror(buf.utf8_str());
739 0 : }
740 :
741 :
742 : /* exceptions_throw_exceptionininitializererror ********************************
743 :
744 : Generates and throws a java.lang.ExceptionInInitializerError for
745 : the VM.
746 :
747 : IN:
748 : cause......cause exception object
749 :
750 : *******************************************************************************/
751 :
752 3 : void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
753 : {
754 : exceptions_throw_utf_throwable(utf8::java_lang_ExceptionInInitializerError,
755 3 : cause);
756 3 : }
757 :
758 :
759 : /* exceptions_throw_incompatibleclasschangeerror *******************************
760 :
761 : Generates and throws a java.lang.IncompatibleClassChangeError for
762 : the VM.
763 :
764 : IN:
765 : message......UTF-8 message format string
766 :
767 : *******************************************************************************/
768 :
769 0 : void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
770 : {
771 : /* allocate memory */
772 :
773 0 : Buffer<> buf;
774 :
775 : buf.write_slash_to_dot(c->name)
776 0 : .write(message);
777 :
778 : /* throw exception */
779 :
780 0 : exceptions_throw_utf_utf(utf8::java_lang_IncompatibleClassChangeError, buf.utf8_str());
781 0 : }
782 :
783 :
784 : /* exceptions_throw_instantiationerror *****************************************
785 :
786 : Generates and throws a java.lang.InstantiationError for the VM.
787 :
788 : *******************************************************************************/
789 :
790 0 : void exceptions_throw_instantiationerror(classinfo *c)
791 : {
792 0 : exceptions_throw_utf_utf(utf8::java_lang_InstantiationError, c->name);
793 0 : }
794 :
795 :
796 : /* exceptions_throw_internalerror **********************************************
797 :
798 : Generates and throws a java.lang.InternalError for the VM.
799 :
800 : IN:
801 : message......UTF-8 message format string
802 :
803 : *******************************************************************************/
804 :
805 0 : void exceptions_throw_internalerror(const char *message, ...)
806 : {
807 : va_list ap;
808 0 : Buffer<> buf;
809 :
810 : /* generate message */
811 :
812 0 : va_start(ap, message);
813 0 : buf.writevf(message,ap);
814 0 : va_end(ap);
815 :
816 : /* throw exception */
817 :
818 0 : exceptions_throw_utf_utf(utf8::java_lang_InternalError, buf.utf8_str());
819 0 : }
820 :
821 :
822 : /* exceptions_throw_linkageerror ***********************************************
823 :
824 : Generates and throws java.lang.LinkageError with an error message.
825 :
826 : IN:
827 : message......UTF-8 message, can be freed after the call
828 : c............class related to the error. If this is != NULL
829 : the name of c is appended to the error message.
830 :
831 : *******************************************************************************/
832 :
833 8 : void exceptions_throw_linkageerror(const char *message, classinfo *c)
834 : {
835 : /* generate message */
836 :
837 8 : Buffer<> buf;
838 :
839 8 : if (c) {
840 : buf.write_slash_to_dot(c->name)
841 3 : .write(": ");
842 : }
843 :
844 8 : buf.write(message);
845 :
846 8 : Utf8String msg = buf.utf8_str();
847 :
848 8 : exceptions_throw_utf_utf(utf8::java_lang_LinkageError, msg);
849 8 : }
850 :
851 :
852 : /* exceptions_throw_nosuchfielderror *******************************************
853 :
854 : Generates and throws a java.lang.NoSuchFieldError with an error
855 : message.
856 :
857 : IN:
858 : c............class in which the field was not found
859 : name.........name of the field
860 :
861 : *******************************************************************************/
862 :
863 4 : void exceptions_throw_nosuchfielderror(classinfo *c, Utf8String name)
864 : {
865 : /* generate message */
866 :
867 4 : Buffer<> buf;
868 :
869 : buf.write_slash_to_dot(c->name)
870 : .write('.')
871 4 : .write(name);
872 :
873 4 : exceptions_throw_utf_utf(utf8::java_lang_NoSuchFieldError, buf.utf8_str());
874 4 : }
875 :
876 :
877 : /* exceptions_throw_nosuchmethoderror ******************************************
878 :
879 : Generates and throws a java.lang.NoSuchMethodError with an error
880 : message.
881 :
882 : IN:
883 : c............class in which the method was not found
884 : name.........name of the method
885 : desc.........descriptor of the method
886 :
887 : *******************************************************************************/
888 :
889 0 : void exceptions_throw_nosuchmethoderror(classinfo *c, Utf8String name, Utf8String desc)
890 : {
891 : /* generate message */
892 :
893 0 : Buffer<> buf;
894 :
895 : buf.write_slash_to_dot(c->name)
896 : .write('.')
897 : .write(name)
898 0 : .write(desc);
899 :
900 : #if defined(ENABLE_JAVASE)
901 0 : exceptions_throw_utf_utf(utf8::java_lang_NoSuchMethodError, buf.utf8_str());
902 : #else
903 : exceptions_throw_utf_utf(utf8::java_lang_Error, buf.utf8_str());
904 : #endif
905 0 : }
906 :
907 :
908 : /* exceptions_throw_outofmemoryerror *******************************************
909 :
910 : Generates and throws an java.lang.OutOfMemoryError for the VM.
911 :
912 : *******************************************************************************/
913 :
914 3 : void exceptions_throw_outofmemoryerror(void)
915 : {
916 : exceptions_throw_utf_utf(utf8::java_lang_OutOfMemoryError,
917 3 : Utf8String::from_utf8("Java heap space"));
918 3 : }
919 :
920 :
921 : /* exceptions_throw_unsatisfiedlinkerror ***************************************
922 :
923 : Generates and throws a java.lang.UnsatisfiedLinkError for the
924 : classloader.
925 :
926 : IN:
927 : name......UTF-8 name string
928 :
929 : *******************************************************************************/
930 :
931 1 : void exceptions_throw_unsatisfiedlinkerror(Utf8String name)
932 : {
933 : #if defined(ENABLE_JAVASE)
934 1 : exceptions_throw_utf_utf(utf8::java_lang_UnsatisfiedLinkError, name);
935 : #else
936 : exceptions_throw_utf_utf(utf8::java_lang_Error, name);
937 : #endif
938 1 : }
939 :
940 :
941 : /* exceptions_throw_unsupportedclassversionerror *******************************
942 :
943 : Generates and throws a java.lang.UnsupportedClassVersionError for
944 : the classloader.
945 :
946 : *******************************************************************************/
947 :
948 0 : void exceptions_throw_unsupportedclassversionerror(classinfo *c)
949 : {
950 : /* generate message */
951 :
952 0 : Buffer<> buf;
953 :
954 : buf.write_slash_to_dot(c->name)
955 0 : .writef(" (Unsupported major.minor version %d.%d)", c->version.majr(), c->version.minr());
956 :
957 : /* throw exception */
958 :
959 0 : exceptions_throw_utf_utf(utf8::java_lang_UnsupportedClassVersionError, buf.utf8_str());
960 0 : }
961 :
962 :
963 : /* exceptions_throw_verifyerror ************************************************
964 :
965 : Generates and throws a java.lang.VerifyError for the JIT compiler.
966 :
967 : IN:
968 : m............method in which the error was found
969 : message......UTF-8 format string
970 :
971 : *******************************************************************************/
972 :
973 28 : void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
974 : {
975 : va_list ap;
976 28 : Buffer<> buf;
977 :
978 : /* generate message */
979 :
980 28 : if (m != NULL) {
981 : buf.write("(class: ")
982 : .write_slash_to_dot(m->clazz->name)
983 : .write(", method: ")
984 : .write(m->name)
985 : .write(" signature: ")
986 : .write(m->descriptor)
987 28 : .write(") ");
988 : }
989 :
990 28 : va_start(ap, message);
991 28 : buf.writevf(message, ap);
992 28 : va_end(ap);
993 :
994 : /* throw exception */
995 :
996 28 : exceptions_throw_utf_utf(utf8::java_lang_VerifyError, buf.utf8_str());
997 28 : }
998 :
999 :
1000 : /* exceptions_throw_verifyerror_for_stack **************************************
1001 :
1002 : throws a java.lang.VerifyError for an invalid stack slot type
1003 :
1004 : IN:
1005 : m............method in which the error was found
1006 : type.........the expected type
1007 :
1008 : RETURN VALUE:
1009 : an exception pointer (in any case -- either it is the newly created
1010 : exception, or an exception thrown while trying to create it).
1011 :
1012 : *******************************************************************************/
1013 :
1014 8 : void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1015 : {
1016 : /* generate message */
1017 :
1018 8 : Buffer<> buf;
1019 :
1020 8 : if (m != NULL) {
1021 : buf.write("(class: ")
1022 : .write_slash_to_dot(m->clazz->name)
1023 : .write(", method: ")
1024 : .write(m->name)
1025 : .write(" signature: ")
1026 : .write(m->descriptor)
1027 8 : .write(") ");
1028 : }
1029 :
1030 8 : buf.write("Expecting to find ");
1031 :
1032 8 : switch (type) {
1033 1 : case TYPE_INT: buf.write("integer"); break;
1034 0 : case TYPE_LNG: buf.write("long"); break;
1035 0 : case TYPE_FLT: buf.write("float"); break;
1036 0 : case TYPE_DBL: buf.write("double"); break;
1037 7 : case TYPE_ADR: buf.write("object/array"); break;
1038 0 : case TYPE_RET: buf.write("returnAddress"); break;
1039 0 : default: buf.write("<INVALID>"); assert(0); break;
1040 : }
1041 :
1042 8 : buf.write(" on stack");
1043 :
1044 : /* throw exception */
1045 :
1046 8 : exceptions_throw_utf_utf(utf8::java_lang_VerifyError, buf.utf8_str());
1047 8 : }
1048 :
1049 :
1050 : /* exceptions_new_arithmeticexception ******************************************
1051 :
1052 : Generates a java.lang.ArithmeticException for the JIT compiler.
1053 :
1054 : *******************************************************************************/
1055 :
1056 8 : java_handle_t *exceptions_new_arithmeticexception(void)
1057 : {
1058 : java_handle_t *o;
1059 :
1060 : o = exceptions_new_utf_utf(utf8::java_lang_ArithmeticException,
1061 8 : utf8::division_by_zero);
1062 :
1063 8 : return o;
1064 : }
1065 :
1066 :
1067 : /* exceptions_new_arrayindexoutofboundsexception *******************************
1068 :
1069 : Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1070 : system.
1071 :
1072 : *******************************************************************************/
1073 :
1074 25 : java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
1075 : {
1076 : java_handle_t *o;
1077 : methodinfo *m;
1078 : java_handle_t *s;
1079 :
1080 : /* convert the index into a String, like Sun does */
1081 :
1082 : m = class_resolveclassmethod(class_java_lang_String,
1083 : Utf8String::from_utf8("valueOf"),
1084 : Utf8String::from_utf8("(I)Ljava/lang/String;"),
1085 : class_java_lang_Object,
1086 25 : true);
1087 :
1088 25 : if (m == NULL)
1089 0 : return exceptions_get_exception();
1090 :
1091 25 : s = vm_call_method(m, NULL, index);
1092 :
1093 25 : if (s == NULL)
1094 0 : return exceptions_get_exception();
1095 :
1096 : o = exceptions_new_utf_javastring(utf8::java_lang_ArrayIndexOutOfBoundsException,
1097 25 : s);
1098 :
1099 25 : if (o == NULL)
1100 0 : return exceptions_get_exception();
1101 :
1102 25 : return o;
1103 : }
1104 :
1105 :
1106 : /* exceptions_throw_arrayindexoutofboundsexception *****************************
1107 :
1108 : Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1109 : the VM.
1110 :
1111 : *******************************************************************************/
1112 :
1113 1 : void exceptions_throw_arrayindexoutofboundsexception(void)
1114 : {
1115 1 : exceptions_throw_utf(utf8::java_lang_ArrayIndexOutOfBoundsException);
1116 1 : }
1117 :
1118 :
1119 : /* exceptions_throw_arraystoreexception ****************************************
1120 :
1121 : Generates and throws a java.lang.ArrayStoreException for the VM.
1122 :
1123 : *******************************************************************************/
1124 :
1125 1 : void exceptions_throw_arraystoreexception(void)
1126 : {
1127 1 : exceptions_throw_utf(utf8::java_lang_ArrayStoreException);
1128 1 : }
1129 :
1130 :
1131 : /* exceptions_new_classcastexception *******************************************
1132 :
1133 : Generates a java.lang.ClassCastException for the JIT compiler.
1134 :
1135 : *******************************************************************************/
1136 :
1137 10 : java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
1138 : {
1139 : classinfo *c;
1140 :
1141 10 : LLNI_class_get(o, c);
1142 :
1143 10 : Utf8String classname = get_classname_for_exception(c);
1144 :
1145 10 : return exceptions_new_utf_utf(utf8::java_lang_ClassCastException, classname);
1146 : }
1147 :
1148 :
1149 : /* exceptions_throw_clonenotsupportedexception *********************************
1150 :
1151 : Generates and throws a java.lang.CloneNotSupportedException for the
1152 : VM.
1153 :
1154 : *******************************************************************************/
1155 :
1156 0 : void exceptions_throw_clonenotsupportedexception(void)
1157 : {
1158 0 : exceptions_throw_utf(utf8::java_lang_CloneNotSupportedException);
1159 0 : }
1160 :
1161 :
1162 : /* exceptions_throw_illegalaccessexception *************************************
1163 :
1164 : Generates and throws a java.lang.IllegalAccessException for the VM.
1165 :
1166 : *******************************************************************************/
1167 :
1168 0 : void exceptions_throw_illegalaccessexception(Utf8String message)
1169 : {
1170 0 : exceptions_throw_utf_utf(utf8::java_lang_IllegalAccessException, message);
1171 0 : }
1172 :
1173 :
1174 : /* exceptions_throw_illegalargumentexception ***********************************
1175 :
1176 : Generates and throws a java.lang.IllegalArgumentException for the
1177 : VM.
1178 :
1179 : *******************************************************************************/
1180 :
1181 1 : void exceptions_throw_illegalargumentexception(void)
1182 : {
1183 1 : exceptions_throw_utf(utf8::java_lang_IllegalArgumentException);
1184 1 : }
1185 :
1186 :
1187 : /* exceptions_throw_illegalmonitorstateexception *******************************
1188 :
1189 : Generates and throws a java.lang.IllegalMonitorStateException for
1190 : the VM.
1191 :
1192 : *******************************************************************************/
1193 :
1194 0 : void exceptions_throw_illegalmonitorstateexception(void)
1195 : {
1196 0 : exceptions_throw_utf(utf8::java_lang_IllegalMonitorStateException);
1197 0 : }
1198 :
1199 :
1200 : /* exceptions_throw_instantiationexception *************************************
1201 :
1202 : Generates and throws a java.lang.InstantiationException for the VM.
1203 :
1204 : *******************************************************************************/
1205 :
1206 0 : void exceptions_throw_instantiationexception(classinfo *c)
1207 : {
1208 0 : exceptions_throw_utf_utf(utf8::java_lang_InstantiationException, c->name);
1209 0 : }
1210 :
1211 :
1212 : /* exceptions_throw_interruptedexception ***************************************
1213 :
1214 : Generates and throws a java.lang.InterruptedException for the VM.
1215 :
1216 : *******************************************************************************/
1217 :
1218 20000 : void exceptions_throw_interruptedexception(void)
1219 : {
1220 20000 : exceptions_throw_utf(utf8::java_lang_InterruptedException);
1221 20000 : }
1222 :
1223 :
1224 : /* exceptions_throw_invocationtargetexception **********************************
1225 :
1226 : Generates and throws a java.lang.reflect.InvocationTargetException
1227 : for the VM.
1228 :
1229 : IN:
1230 : cause......cause exception object
1231 :
1232 : *******************************************************************************/
1233 :
1234 11 : void exceptions_throw_invocationtargetexception(java_handle_t *cause)
1235 : {
1236 : exceptions_throw_utf_throwable(utf8::java_lang_reflect_InvocationTargetException,
1237 11 : cause);
1238 11 : }
1239 :
1240 :
1241 : /* exceptions_throw_negativearraysizeexception *********************************
1242 :
1243 : Generates and throws a java.lang.NegativeArraySizeException for the
1244 : VM.
1245 :
1246 : *******************************************************************************/
1247 :
1248 5 : void exceptions_throw_negativearraysizeexception(void)
1249 : {
1250 5 : exceptions_throw_utf(utf8::java_lang_NegativeArraySizeException);
1251 5 : }
1252 :
1253 :
1254 : /* exceptions_new_nullpointerexception *****************************************
1255 :
1256 : Generates a java.lang.NullPointerException for the VM system.
1257 :
1258 : *******************************************************************************/
1259 :
1260 22 : java_handle_t *exceptions_new_nullpointerexception(void)
1261 : {
1262 : java_handle_t *o;
1263 :
1264 22 : o = exceptions_new_utf(utf8::java_lang_NullPointerException);
1265 :
1266 22 : return o;
1267 : }
1268 :
1269 :
1270 : /* exceptions_throw_nullpointerexception ***************************************
1271 :
1272 : Generates a java.lang.NullPointerException for the VM system and
1273 : throw it in the VM system.
1274 :
1275 : *******************************************************************************/
1276 :
1277 3 : void exceptions_throw_nullpointerexception(void)
1278 : {
1279 3 : exceptions_throw_utf(utf8::java_lang_NullPointerException);
1280 3 : }
1281 :
1282 :
1283 : /* exceptions_throw_privilegedactionexception **********************************
1284 :
1285 : Generates and throws a java.security.PrivilegedActionException.
1286 :
1287 : *******************************************************************************/
1288 :
1289 0 : void exceptions_throw_privilegedactionexception(java_handle_t *exception)
1290 : {
1291 : exceptions_throw_utf_exception(utf8::java_security_PrivilegedActionException,
1292 0 : exception);
1293 0 : }
1294 :
1295 :
1296 : /* exceptions_throw_stringindexoutofboundsexception ****************************
1297 :
1298 : Generates and throws a java.lang.StringIndexOutOfBoundsException
1299 : for the VM.
1300 :
1301 : *******************************************************************************/
1302 :
1303 0 : void exceptions_throw_stringindexoutofboundsexception(void)
1304 : {
1305 0 : exceptions_throw_utf(utf8::java_lang_StringIndexOutOfBoundsException);
1306 0 : }
1307 :
1308 :
1309 : /* exceptions_fillinstacktrace *************************************************
1310 :
1311 : Calls the fillInStackTrace-method of the currently thrown
1312 : exception.
1313 :
1314 : *******************************************************************************/
1315 :
1316 3 : java_handle_t *exceptions_fillinstacktrace(void)
1317 : {
1318 : java_handle_t *o;
1319 : classinfo *c;
1320 : methodinfo *m;
1321 :
1322 : /* get exception */
1323 :
1324 3 : o = exceptions_get_and_clear_exception();
1325 :
1326 3 : assert(o);
1327 :
1328 : /* resolve methodinfo pointer from exception object */
1329 :
1330 3 : LLNI_class_get(o, c);
1331 :
1332 : #if defined(ENABLE_JAVASE)
1333 : m = class_resolvemethod(c,
1334 : utf8::fillInStackTrace,
1335 3 : utf8::void__java_lang_Throwable);
1336 : #elif defined(ENABLE_JAVAME_CLDC1_1)
1337 : m = class_resolvemethod(c,
1338 : utf8::fillInStackTrace,
1339 : utf8::void__void);
1340 : #else
1341 : #error IMPLEMENT ME!
1342 : #endif
1343 :
1344 : /* call function */
1345 :
1346 3 : (void) vm_call_method(m, o);
1347 :
1348 : /* return exception object */
1349 :
1350 3 : return o;
1351 : }
1352 :
1353 :
1354 : /* exceptions_handle_exception *************************************************
1355 :
1356 : Try to find an exception handler for the given exception and return it.
1357 : If no handler is found, exit the monitor of the method (if any)
1358 : and return NULL.
1359 :
1360 : IN:
1361 : xptr.........the exception object
1362 : xpc..........PC of where the exception was thrown
1363 : pv...........Procedure Value of the current method
1364 : sp...........current stack pointer
1365 :
1366 : RETURN VALUE:
1367 : the address of the first matching exception handler, or
1368 : NULL if no handler was found
1369 :
1370 : *******************************************************************************/
1371 :
1372 : #if defined(ENABLE_JIT)
1373 41546 : extern "C" void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
1374 : {
1375 : stackframeinfo_t sfi;
1376 : java_handle_t *xptr;
1377 : methodinfo *m;
1378 : codeinfo *code;
1379 : exceptiontable_t *et;
1380 : exceptiontable_entry_t *ete;
1381 : s4 i;
1382 : classref_or_classinfo cr;
1383 : classinfo *c;
1384 : void *result;
1385 :
1386 : #ifdef __S390__
1387 : /* Addresses are 31 bit integers */
1388 : # define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
1389 : #else
1390 : # define ADDR_MASK(x) (x)
1391 : #endif
1392 :
1393 41546 : xptr = LLNI_WRAP(xptro);
1394 41546 : xpc = ADDR_MASK(xpc);
1395 :
1396 : /* Fill and add a stackframeinfo (XPC is equal to RA). */
1397 :
1398 41546 : stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
1399 :
1400 41546 : result = NULL;
1401 :
1402 : /* Get the codeinfo for the current method. */
1403 :
1404 41546 : code = code_get_codeinfo_for_pv(pv);
1405 :
1406 : /* Get the methodinfo pointer from the codeinfo pointer. For
1407 : asm_vm_call_method the codeinfo pointer is NULL and we simply
1408 : can return the proper exception handler. */
1409 :
1410 41546 : if (code == NULL) {
1411 60 : result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
1412 60 : goto exceptions_handle_exception_return;
1413 : }
1414 :
1415 41486 : m = code->m;
1416 :
1417 : #if !defined(NDEBUG)
1418 : /* print exception trace */
1419 :
1420 41486 : if (opt_TraceExceptions)
1421 0 : trace_exception(LLNI_DIRECT(xptr), m, xpc);
1422 : #endif
1423 :
1424 : /* Get the exception table. */
1425 :
1426 41486 : et = code->exceptiontable;
1427 :
1428 41486 : if (et != NULL) {
1429 : /* Iterate over all exception table entries. */
1430 :
1431 21074 : ete = et->entries;
1432 :
1433 22501 : for (i = 0; i < et->length; i++, ete++) {
1434 : /* is the xpc is the current catch range */
1435 :
1436 22392 : if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
1437 20987 : cr = ete->catchtype;
1438 :
1439 : /* NULL catches everything */
1440 :
1441 20987 : if (cr.any == NULL) {
1442 : #if !defined(NDEBUG)
1443 : /* Print stacktrace of exception when caught. */
1444 :
1445 0 : if (opt_TraceExceptions) {
1446 0 : exceptions_print_exception(xptr);
1447 0 : stacktrace_print_exception(xptr);
1448 : }
1449 : #endif
1450 :
1451 0 : result = ete->handlerpc;
1452 0 : goto exceptions_handle_exception_return;
1453 : }
1454 :
1455 : /* resolve or load/link the exception class */
1456 :
1457 20987 : if (cr.is_classref()) {
1458 : /* The exception class reference is unresolved. */
1459 : /* We have to do _eager_ resolving here. While the
1460 : class of the exception object is guaranteed to be
1461 : loaded, it may well have been loaded by a different
1462 : loader than the defining loader of m's class, which
1463 : is the one we must use to resolve the catch
1464 : class. Thus lazy resolving might fail, even if the
1465 : result of the resolution would be an already loaded
1466 : class. */
1467 :
1468 121 : c = resolve_classref_eager(cr.ref);
1469 :
1470 121 : if (c == NULL) {
1471 : /* Exception resolving the exception class, argh! */
1472 0 : goto exceptions_handle_exception_return;
1473 : }
1474 :
1475 : /* Ok, we resolved it. Enter it in the table, so we
1476 : don't have to do this again. */
1477 : /* XXX this write should be atomic. Is it? */
1478 :
1479 121 : ete->catchtype.cls = c;
1480 : }
1481 : else {
1482 20866 : c = cr.cls;
1483 :
1484 : /* XXX I don't think this case can ever happen. -Edwin */
1485 20866 : if (!(c->state & CLASS_LOADED))
1486 : /* use the methods' classloader */
1487 0 : if (!load_class_from_classloader(c->name,
1488 : m->clazz->classloader))
1489 0 : goto exceptions_handle_exception_return;
1490 :
1491 : /* XXX I think, if it is not linked, we can be sure
1492 : that the exception object is no (indirect) instance
1493 : of it, no? -Edwin */
1494 20866 : if (!(c->state & CLASS_LINKED))
1495 0 : if (!link_class(c))
1496 0 : goto exceptions_handle_exception_return;
1497 : }
1498 :
1499 : /* is the thrown exception an instance of the catch class? */
1500 :
1501 20987 : if (builtin_instanceof(xptr, c)) {
1502 : #if !defined(NDEBUG)
1503 : /* Print stacktrace of exception when caught. */
1504 :
1505 20965 : if (opt_TraceExceptions) {
1506 0 : exceptions_print_exception(xptr);
1507 0 : stacktrace_print_exception(xptr);
1508 : }
1509 : #endif
1510 :
1511 20965 : result = ete->handlerpc;
1512 20965 : goto exceptions_handle_exception_return;
1513 : }
1514 : }
1515 : }
1516 : }
1517 :
1518 : /* Is this method realization synchronized? */
1519 :
1520 20521 : if (code_is_synchronized(code)) {
1521 : /* Get synchronization object. */
1522 :
1523 87 : java_object_t *o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
1524 :
1525 87 : assert(o != NULL);
1526 :
1527 87 : lock_monitor_exit(LLNI_QUICKWRAP(o));
1528 : }
1529 :
1530 : /* none of the exceptions catch this one */
1531 :
1532 : #if !defined(NDEBUG)
1533 :
1534 : # if defined(ENABLE_DEBUG_FILTER)
1535 20521 : if (show_filters_test_verbosecall_exit(m)) {
1536 : # endif
1537 :
1538 : /* outdent the log message */
1539 :
1540 0 : if (opt_verbosecall) {
1541 0 : if (TRACEJAVACALLINDENT)
1542 0 : TRACEJAVACALLINDENT--;
1543 : else
1544 0 : log_text("exceptions_handle_exception: WARNING: unmatched unindent");
1545 : }
1546 :
1547 : # if defined(ENABLE_DEBUG_FILTER)
1548 : }
1549 : # endif
1550 : #endif /* !defined(NDEBUG) */
1551 :
1552 20521 : result = NULL;
1553 :
1554 : exceptions_handle_exception_return:
1555 :
1556 : /* Remove the stackframeinfo. */
1557 :
1558 41546 : stacktrace_stackframeinfo_remove(&sfi);
1559 :
1560 41546 : return result;
1561 : }
1562 : #endif /* defined(ENABLE_JIT) */
1563 :
1564 :
1565 : /* exceptions_print_exception **************************************************
1566 :
1567 : Prints an exception, the detail message and the cause, if
1568 : available, with CACAO internal functions to stdout.
1569 :
1570 : *******************************************************************************/
1571 :
1572 0 : void exceptions_print_exception(java_handle_t *xptr)
1573 : {
1574 0 : java_lang_Throwable jlt(xptr);
1575 :
1576 0 : if (jlt.is_null()) {
1577 0 : puts("NULL\n");
1578 : return;
1579 : }
1580 :
1581 : #if defined(ENABLE_JAVASE)
1582 0 : java_lang_Throwable jltcause(jlt.get_cause());
1583 : #endif
1584 :
1585 : /* print the root exception */
1586 :
1587 0 : classinfo* c = jlt.get_Class();
1588 0 : utf_display_printable_ascii_classname(c->name);
1589 :
1590 0 : java_lang_String jls(jlt.get_detailMessage());
1591 :
1592 0 : if (!jls.is_null()) {
1593 0 : JavaString str = jls.get_handle();
1594 :
1595 0 : printf(": ");
1596 0 : str.fprint_printable_ascii(stdout);
1597 : }
1598 :
1599 0 : putc('\n', stdout);
1600 :
1601 : #if defined(ENABLE_JAVASE)
1602 : /* print the cause if available */
1603 :
1604 : // FIXME cause != t compare with operator override.
1605 0 : if ((!jltcause.is_null()) && (jltcause.get_handle() != jlt.get_handle())) {
1606 0 : printf("Caused by: ");
1607 :
1608 0 : c = jltcause.get_Class();
1609 0 : utf_display_printable_ascii_classname(c->name);
1610 :
1611 0 : java_lang_String jlscause(jlt.get_detailMessage());
1612 :
1613 0 : if (jlscause.get_handle() != NULL) {
1614 0 : JavaString str = jls.get_handle();
1615 :
1616 0 : printf(": ");
1617 0 : str.fprint_printable_ascii(stdout);
1618 : }
1619 :
1620 0 : putc('\n', stdout);
1621 0 : }
1622 : #endif
1623 : }
1624 :
1625 :
1626 : /* exceptions_print_current_exception ******************************************
1627 :
1628 : Prints the current pending exception, the detail message and the
1629 : cause, if available, with CACAO internal functions to stdout.
1630 :
1631 : *******************************************************************************/
1632 :
1633 0 : void exceptions_print_current_exception(void)
1634 : {
1635 : java_handle_t *o;
1636 :
1637 0 : o = exceptions_get_exception();
1638 :
1639 0 : exceptions_print_exception(o);
1640 0 : }
1641 :
1642 :
1643 : /* exceptions_print_stacktrace *************************************************
1644 :
1645 : Prints a pending exception with Throwable.printStackTrace(). If
1646 : there happens an exception during printStackTrace(), we print the
1647 : thrown exception and the original one.
1648 :
1649 : NOTE: This function calls Java code.
1650 :
1651 : *******************************************************************************/
1652 :
1653 41 : void exceptions_print_stacktrace(void)
1654 : {
1655 : java_handle_t *e;
1656 : java_handle_t *ne;
1657 : classinfo *c;
1658 : methodinfo *m;
1659 :
1660 : /* Get and clear exception because we are calling Java code
1661 : again. */
1662 :
1663 41 : e = exceptions_get_and_clear_exception();
1664 :
1665 41 : if (e == NULL)
1666 0 : return;
1667 :
1668 : #if 0
1669 : /* FIXME Enable me. */
1670 : if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
1671 : /* Don't print anything if we are being killed. */
1672 : }
1673 : else
1674 : #endif
1675 : {
1676 : /* Get the exception class. */
1677 :
1678 41 : LLNI_class_get(e, c);
1679 :
1680 : /* Find the printStackTrace() method. */
1681 :
1682 : m = class_resolveclassmethod(c,
1683 : utf8::printStackTrace,
1684 : utf8::void__void,
1685 : class_java_lang_Object,
1686 41 : false);
1687 :
1688 41 : if (m == NULL)
1689 0 : os::abort("exceptions_print_stacktrace: printStackTrace()V not found");
1690 :
1691 : /* Print message. */
1692 :
1693 41 : fprintf(stderr, "Exception ");
1694 :
1695 : /* Print thread name. We get the thread here explicitly as we
1696 : need it afterwards. */
1697 :
1698 41 : threadobject *t = thread_get_current();
1699 41 : java_lang_Thread *to = (java_lang_Thread *) LLNI_WRAP(t->object);
1700 :
1701 41 : if (to != NULL) {
1702 41 : fprintf(stderr, "in thread \"");
1703 41 : thread_fprint_name(t, stderr);
1704 41 : fprintf(stderr, "\" ");
1705 : }
1706 :
1707 : /* Print the stacktrace. */
1708 :
1709 41 : if (builtin_instanceof(e, class_java_lang_Throwable)) {
1710 41 : (void) vm_call_method(m, e);
1711 :
1712 : /* If this happens we are EXTREMLY out of memory or have a
1713 : serious problem while printStackTrace. But may be
1714 : another exception, so print it. */
1715 :
1716 41 : ne = exceptions_get_exception();
1717 :
1718 41 : if (ne != NULL) {
1719 0 : fprintf(stderr, "Exception while printStackTrace(): ");
1720 :
1721 : /* Print the current exception. */
1722 :
1723 0 : exceptions_print_exception(ne);
1724 0 : stacktrace_print_exception(ne);
1725 :
1726 : /* Now print the original exception. */
1727 :
1728 0 : fprintf(stderr, "Original exception was: ");
1729 0 : exceptions_print_exception(e);
1730 0 : stacktrace_print_exception(e);
1731 : }
1732 : }
1733 : else {
1734 0 : fprintf(stderr, ". Uncaught exception of type ");
1735 : #if !defined(NDEBUG)
1736 : /* FIXME This prints to stdout. */
1737 0 : class_print(c);
1738 : #else
1739 : fprintf(stderr, "UNKNOWN");
1740 : #endif
1741 0 : fprintf(stderr, ".");
1742 : }
1743 :
1744 41 : fflush(stderr);
1745 : }
1746 : }
1747 :
1748 10 : static inline Utf8String get_classname_for_exception(classinfo *c) {
1749 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1750 : return Utf8String::from_utf8_slash_to_dot(c->name.begin(), c->name.size());
1751 : #else
1752 10 : return c->name;
1753 : #endif
1754 : }
1755 :
1756 : /*
1757 : * These are local overrides for various environment variables in Emacs.
1758 : * Please do not remove this and leave it at the end of the file, where
1759 : * Emacs will automagically detect them.
1760 : * ---------------------------------------------------------------------
1761 : * Local variables:
1762 : * mode: c++
1763 : * indent-tabs-mode: t
1764 : * c-basic-offset: 4
1765 : * tab-width: 4
1766 : * End:
1767 : * vim:noexpandtab:sw=4:ts=4:
1768 : */
|